2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $TOG: dtscreen.c /main/6 1998/04/20 12:58:46 mgreess $ */
28 * dtscreen.c - X11 client to lock a display and show a screen saver.
30 * Copyright (c) 1988-91 by Patrick J. Naughton.
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.
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.
44 * Comments and additions should be sent to the author:
46 * naughton@eng.sun.com
50 * Sun Laboritories, Inc.
52 * Mountain View, CA 94043
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.
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.
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]
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.
102 /* include file for message texts */
104 #include <nl_types.h>
105 #define MF_DTSCREEN "dtscreen"
107 #include <nl_types.h>
109 nl_catd scmc_catd; /* Cat descriptor for scmc conversion */
117 #include <X11/Intrinsic.h> /* For Boolean */
118 #include <X11/Shell.h>
119 #include "dtscreen.h"
121 /* We'd like to include DtP.h, but it interferes with dtscreen.h */
124 #include <Dt/EnvControlP.h>
125 #include <Dt/Saver.h>
127 #if !defined(NL_CAT_LOCALE)
128 #define NL_CAT_LOCALE 0
131 char *ProgramName; /* argv[0] */
132 Display *dsp = NULL; /* server display connection */
133 void (*callback) () = NULL;
134 void (*init) () = NULL;
136 static perwindow *Win; /* perwindow information */
137 static int windows; /* number of windows */
138 static Window *winprop = NULL; /* dtsession cover windows */
145 fprintf(stderr, s1, ProgramName, s2);
150 * Restore all grabs, reset screensaver, restore colormap, close connection.
157 XFree((char *)winprop);
169 for (window = 0; window < windows; window++)
172 while (!XPending(dsp)) {
173 for (window = 0; window < windows; window++)
174 callback(Win+window);
178 XNextEvent(dsp, &event);
181 if (event.type == VisibilityNotify)
182 XRaiseWindow(dsp, event.xany.window);
189 allocpixel(Colormap cmap, char *name, char *def)
193 XParseColor(dsp, cmap, name, &col);
194 if (!XAllocColor(dsp, cmap, &col)) {
198 "couldn't allocate: %s, using %s instead\n",
202 fprintf(stderr, catgets(scmc_catd, 2, 35,
203 "couldn't allocate: %s, using %s instead\n"),
207 XAllocNamedColor(dsp, cmap, def, &col, &tmp);
214 main(int argc, char *argv[])
216 XSetWindowAttributes xswa;
223 * So we can find the app-defaults file.
225 _DtEnvControl(DT_ENV_SET);
227 /* set locale to what is defined by local environment */
228 setlocale(LC_ALL,"");
229 scmc_catd = catopen(MF_DTSCREEN, NL_CAT_LOCALE);
231 ProgramName = strrchr(argv[0], '/');
235 ProgramName = argv[0];
237 srandom(time((time_t *) 0)); /* random mode needs the seed set. */
239 GetResources(argc, argv);
245 /* Make sure DtSvc is initialized properly. */
246 XtAppContext appContext;
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,
259 DtAppInitialize(appContext, dsp, shellWidget,
260 ProgramName, ProgramName);
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.
266 if (!DtSaverGetWindows(dsp, &winprop, &nitems))
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);
276 Win = (perwindow *)malloc(nitems * sizeof(perwindow));
278 for (window = 0; window < windows; window++)
280 Win[window].w = winprop[window];
281 Win[window].perscreen = NULL;
282 Win[window].data = NULL;
287 Screen *scr = ScreenOfDisplay(dsp, 0);
289 Win = (perwindow *)malloc(sizeof(perwindow));
291 xswa.override_redirect = True;
292 xswa.background_pixel = BlackPixelOfScreen(scr);
293 xswa.event_mask = VisibilityChangeMask;
295 Win[0].w = XCreateWindow(
297 RootWindowOfScreen(scr),
299 WidthOfScreen(scr) - 100, HeightOfScreen(scr) - 100,
300 0, CopyFromParent, InputOutput, CopyFromParent,
301 CWBackPixel | CWEventMask, &xswa);
302 Win[0].perscreen = NULL;
304 XMapWindow(dsp, Win[0].w);
305 XRaiseWindow(dsp, Win[0].w);
308 for (window = 0; window < windows; window++)
310 XWindowAttributes attr;
312 XGetWindowAttributes(dsp, Win[window].w, &attr);
314 for (i = 0; i < window; i++)
316 if (Win[i].perscreen && Win[i].perscreen->screen == attr.screen)
318 Win[window].perscreen = Win[i].perscreen;
323 if (Win[window].perscreen == NULL)
328 pscreen = (perscreen *)malloc(sizeof(perscreen));
329 Win[window].perscreen = pscreen;
331 pscreen->screen = attr.screen;
332 cmap = DefaultColormapOfScreen(pscreen->screen);
334 pscreen->pixels[0] = allocpixel(cmap, "White", "White");
335 pscreen->pixels[1] = allocpixel(cmap, "Black", "Black");
336 if (mono || CellsOfScreen(pscreen->screen) == 2)
338 pscreen->npixels = 2;
342 int colorcount = NUMCOLORS;
343 u_char red[NUMCOLORS];
344 u_char green[NUMCOLORS];
345 u_char blue[NUMCOLORS];
347 hsbramp(0.0, saturation, 1.0, 1.0, saturation, 1.0, colorcount,
349 pscreen->npixels = 0;
350 for (i = 0; i < colorcount; i++)
354 xcolor.red = red[i] << 8;
355 xcolor.green = green[i] << 8;
356 xcolor.blue = blue[i] << 8;
357 xcolor.flags = DoRed | DoGreen | DoBlue;
359 if (!XAllocColor(dsp, cmap, &xcolor))
362 pscreen->pixels[i] = xcolor.pixel;
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);
373 if(-1 == nice(nicelevel)) {
374 fprintf(stderr, "dtscreen: failed to set nice() level '%s'\n", strerror(errno));