dtwm: Remove define MOTIF_ONE_DOT_ONE, backwards compatibility for motif 1.1, CDE...
[oweals/cde.git] / cde / programs / dtscreen / dtscreen.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $TOG: dtscreen.c /main/6 1998/04/20 12:58:46 mgreess $ */
24 /*
25  */
26
27 /*-
28  * dtscreen.c - X11 client to lock a display and show a screen saver.
29  *
30  * Copyright (c) 1988-91 by Patrick J. Naughton.
31  *
32  * Permission to use, copy, modify, and distribute this software and its
33  * documentation for any purpose and without fee is hereby granted,
34  * provided that the above copyright notice appear in all copies and that
35  * both that copyright notice and this permission notice appear in
36  * supporting documentation.
37  *
38  * This file is provided AS IS with no warranties of any kind.  The author
39  * shall have no liability with respect to the infringement of copyrights,
40  * trade secrets or any patents by this file or any part thereof.  In no
41  * event will the author be liable for any lost revenue or profits or
42  * other special, indirect and consequential damages.
43  *
44  * Comments and additions should be sent to the author:
45  *
46  *                     naughton@eng.sun.com
47  *
48  *                     Patrick J. Naughton
49  *                     MS 21-14
50  *                     Sun Laboritories, Inc.
51  *                     2550 Garcia Ave
52  *                     Mountain View, CA  94043
53  *
54  * Revision History:
55  * 16-May-91: added pyro and random modes.
56  *            ripped big comment block out of all other files.
57  * 29-Oct-90: added cast to XFree() arg.
58  *            added volume arg to call to XBell().
59  * 31-Aug-90: added blank mode.
60  *            added swarm mode.
61  *            moved usleep() and seconds() out to usleep.c.
62  *            added SVR4 defines to dtscreen.h
63  * 29-Jul-90: added support for multiple screens to be locked by one dtscreen.
64  *            moved global defines to dtscreen.h
65  *            removed use of allowsig().
66  * 07-Jul-90: reworked commandline args and resources to use Xrm.
67  *            moved resource processing out to resource.c
68  * 02-Jul-90: reworked colors to not use dynamic colormap.
69  * 23-May-90: added autoraise when obscured.
70  * 18-Feb-90: added SunOS3.5 fix.
71  *            changed -mono -> -color, and -saver -> -lock.
72  *            allow non-locking screensavers to display on remote machine.
73  *            added -echokeys to disable echoing of '?'s on input.
74  *            cleaned up all of the parameters and defaults.
75  * 23-Sep-89: Added fix to allow local hostname:0 as a display.
76  *            Put empty case for Enter/Leave events.
77  *            Moved colormap installation later in startup.
78  * 19-Sep-89: Added '?'s on input.
79  * 27-Mar-89: Added -qix mode.
80  *            Fixed GContext->GC.
81  * 08-Mar-89: Added -nice, -mode and -display, built vector for life and hop.
82  * 24-Feb-89: Replaced hopalong display with life display from SunView1.
83  * 22-Feb-89: Added fix for color servers with n < 8 planes.
84  * 16-Feb-89: Updated calling conventions for XCreateHsbColormap();
85  *            Added -count for number of iterations per color.
86  *            Fixed defaulting mechanism.
87  *            Ripped out VMS hacks.
88  *            Sent to expo for X11R3 contrib.
89  * 19-Jan-89: Fixed monochrome gc bug.
90  * 19-Sep-88: Changed -color to -mono. (default is color on color displays).
91  *            Added -saver option. (just do display... don't lock.)
92  * 01-Apr-88: Added XGrabServer/XUngrabServer for more security.
93  * 27-Mar-88: Rotate fractal by 45 degrees clockwise.
94  * 24-Mar-88: Added color support. [-color]
95  *            wrote the man page.
96  * 23-Mar-88: Added HOPALONG routines from Scientific American Sept. 86 p. 14.
97  *            added requirement for display to be "unix:0".
98  * 22-Mar-88: Recieved Walter Milliken's comp.windows.x posting.
99  *
100  */
101
102 /*              include file for message texts          */
103 #include <limits.h>
104 #include <nl_types.h>
105 #define MF_DTSCREEN "dtscreen"
106
107 #include <nl_types.h>
108 #include <locale.h>
109 nl_catd  scmc_catd;   /* Cat descriptor for scmc conversion */
110
111 #include <stdio.h>
112 #include <stdlib.h>
113 #include <signal.h>
114 #include <string.h>
115 #include <errno.h>
116
117 #include <X11/Intrinsic.h> /* For Boolean */
118 #include <X11/Shell.h>
119 #include "dtscreen.h"
120 #ifdef NEVER
121 /* We'd like to include DtP.h, but it interferes with dtscreen.h */
122 # include <Dt/DtP.h>
123 #endif /* NEVER */
124 #include <Dt/EnvControlP.h>
125 #include <Dt/Saver.h>
126
127 #if !defined(NL_CAT_LOCALE)
128 #define NL_CAT_LOCALE 0
129 #endif
130
131 char       *ProgramName;        /* argv[0] */
132 Display    *dsp = NULL;         /* server display connection */
133 void        (*callback) () = NULL;
134 void        (*init) () = NULL;
135
136 static perwindow *Win; /* perwindow information */
137 static int  windows;            /* number of windows */
138 static Window *winprop = NULL;  /* dtsession cover windows */
139
140 /* VARARGS1 */
141 void
142 error(s1, s2)
143     char       *s1, *s2;
144 {
145     fprintf(stderr, s1, ProgramName, s2);
146     exit(1);
147 }
148
149 /*
150  * Restore all grabs, reset screensaver, restore colormap, close connection.
151  */
152 static void
153 finish(void)
154 {
155     XSync(dsp, False);
156     if (winprop) 
157       XFree((char *)winprop);
158     XFlush(dsp);
159     XCloseDisplay(dsp);
160 }
161
162
163 static void
164 justDisplay(void)
165 {
166     XEvent      event;
167     int window;
168
169     for (window = 0; window < windows; window++)
170         init(Win+window);
171     do {
172         while (!XPending(dsp)) {
173             for (window = 0; window < windows; window++)
174                 callback(Win+window);
175             XSync(dsp, False);
176             usleep(delay);
177         }
178         XNextEvent(dsp, &event);
179
180 #ifndef DEBUG
181         if (event.type == VisibilityNotify)
182             XRaiseWindow(dsp, event.xany.window);
183 #endif
184     } while (1);
185 }
186
187
188 long
189 allocpixel(Colormap cmap, char *name, char *def)
190 {
191     XColor      col;
192     XColor      tmp;
193     XParseColor(dsp, cmap, name, &col);
194     if (!XAllocColor(dsp, cmap, &col)) {
195 #ifdef MIT_R5
196
197         fprintf(stderr, 
198              "couldn't allocate: %s, using %s instead\n",
199                 name, def);
200
201 #else
202         fprintf(stderr, catgets(scmc_catd, 2, 35, 
203              "couldn't allocate: %s, using %s instead\n"),
204                 name, def);
205 #endif
206
207         XAllocNamedColor(dsp, cmap, def, &col, &tmp);
208     }
209     return col.pixel;
210 }
211
212
213 int
214 main(int argc, char *argv[])
215 {
216     XSetWindowAttributes xswa;
217     XGCValues   xgcv;
218     int         nitems = 0;
219     int         window;
220     int i;
221
222    /*
223     * So we can find the app-defaults file.
224     */
225     _DtEnvControl(DT_ENV_SET);
226
227     /* set locale to what is defined by local environment */
228     setlocale(LC_ALL,"");
229     scmc_catd = catopen(MF_DTSCREEN, NL_CAT_LOCALE);
230
231     ProgramName = strrchr(argv[0], '/');
232     if (ProgramName)
233         ProgramName++;
234     else
235         ProgramName = argv[0];
236
237     srandom(time((time_t *) 0));  /* random mode needs the seed set. */
238
239     GetResources(argc, argv);
240
241     CheckResources();
242
243    if (!create)
244    {
245      /* Make sure DtSvc is initialized properly. */
246      XtAppContext appContext;
247      Widget shellWidget;
248      int dummyArgc = 1;
249      char *dummyArgv[1];
250
251      dummyArgv[0] = ProgramName;
252      XtToolkitInitialize();
253      appContext = XtCreateApplicationContext();
254      XtDisplayInitialize(appContext, dsp, ProgramName, ProgramName,
255                          NULL, 0, &dummyArgc, dummyArgv);
256      shellWidget = XtAppCreateShell(ProgramName, ProgramName,
257                                     applicationShellWidgetClass,
258                                     dsp, NULL, 0);
259      DtAppInitialize(appContext, dsp, shellWidget,
260                      ProgramName, ProgramName);
261
262      /*
263       * Try to get array of window ids from desktop. Also returned is
264       * a property identifier whose change will tell us when to terminate.
265       */
266       if (!DtSaverGetWindows(dsp, &winprop, &nitems))
267       {
268         fprintf(stderr, catgets(scmc_catd, 2, 40,
269              "%s: Cannot locate window in which to draw. Using the -create\n"
270              "option will cause %s to create its own window.\n"),
271              ProgramName, ProgramName);
272
273         exit(1);
274       }
275
276       Win = (perwindow *)malloc(nitems * sizeof(perwindow));
277       windows = nitems;
278       for (window = 0; window < windows; window++)
279       {
280         Win[window].w = winprop[window];
281         Win[window].perscreen = NULL;
282         Win[window].data = NULL;
283       }
284     }
285     else
286     {
287       Screen     *scr = ScreenOfDisplay(dsp, 0);
288
289       Win = (perwindow *)malloc(sizeof(perwindow));
290       windows = 1;
291       xswa.override_redirect = True;
292       xswa.background_pixel = BlackPixelOfScreen(scr);
293       xswa.event_mask = VisibilityChangeMask;
294
295       Win[0].w = XCreateWindow(
296                       dsp,
297                       RootWindowOfScreen(scr),
298                       0, 0,
299                       WidthOfScreen(scr) - 100, HeightOfScreen(scr) - 100,
300                       0, CopyFromParent, InputOutput, CopyFromParent,
301                       CWBackPixel | CWEventMask, &xswa);
302       Win[0].perscreen = NULL;
303       Win[0].data = NULL;
304       XMapWindow(dsp, Win[0].w);
305       XRaiseWindow(dsp, Win[0].w);
306     }
307
308     for (window = 0; window < windows; window++)
309     {
310       XWindowAttributes attr;
311
312       XGetWindowAttributes(dsp, Win[window].w, &attr);
313
314       for (i = 0; i < window; i++)
315       {
316         if (Win[i].perscreen && Win[i].perscreen->screen == attr.screen)
317         {
318           Win[window].perscreen = Win[i].perscreen;
319           break;
320         }
321       }
322
323       if (Win[window].perscreen == NULL)
324       {
325         Colormap cmap;
326         perscreen *pscreen;
327
328         pscreen = (perscreen *)malloc(sizeof(perscreen));
329         Win[window].perscreen = pscreen;
330
331         pscreen->screen = attr.screen;
332         cmap = DefaultColormapOfScreen(pscreen->screen);
333         
334         pscreen->pixels[0] = allocpixel(cmap, "White", "White");
335         pscreen->pixels[1] = allocpixel(cmap, "Black", "Black");
336         if (mono || CellsOfScreen(pscreen->screen) == 2)
337         {
338           pscreen->npixels = 2;
339         }
340         else
341         {
342           int         colorcount = NUMCOLORS;
343           u_char      red[NUMCOLORS];
344           u_char      green[NUMCOLORS];
345           u_char      blue[NUMCOLORS];
346   
347           hsbramp(0.0, saturation, 1.0, 1.0, saturation, 1.0, colorcount,
348                       red, green, blue);
349           pscreen->npixels = 0;
350           for (i = 0; i < colorcount; i++)
351           {
352             XColor      xcolor;
353
354             xcolor.red = red[i] << 8;
355             xcolor.green = green[i] << 8;
356             xcolor.blue = blue[i] << 8;
357             xcolor.flags = DoRed | DoGreen | DoBlue;
358
359             if (!XAllocColor(dsp, cmap, &xcolor))
360                 break;
361
362             pscreen->pixels[i] = xcolor.pixel;
363             pscreen->npixels++;
364           }
365         }
366       }
367
368       xgcv.foreground = WhitePixelOfScreen(Win[window].perscreen->screen);
369       xgcv.background = BlackPixelOfScreen(Win[window].perscreen->screen);
370       Win[window].gc = XCreateGC(dsp, Win[window].w,
371                          GCForeground | GCBackground, &xgcv);
372     }
373     if(-1 == nice(nicelevel)) {
374       fprintf(stderr, "dtscreen: failed to set nice() level '%s'\n", strerror(errno));
375     }
376
377     justDisplay();
378
379     finish();
380
381     return 0;
382 }