1.2.3
by Tormod Volden
Import upstream version 5.13 |
1 |
/* xscreensaver, Copyright (c) 1991-2011 Jamie Zawinski <jwz@jwz.org>
|
1
by Karl Ramm
Import upstream version 3.34 |
2 |
*
|
3 |
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
4 |
* documentation for any purpose is hereby granted without fee, provided that
|
|
5 |
* the above copyright notice appear in all copies and that both that
|
|
6 |
* copyright notice and this permission notice appear in supporting
|
|
7 |
* documentation. No representations are made about the suitability of this
|
|
8 |
* software for any purpose. It is provided "as is" without express or
|
|
9 |
* implied warranty.
|
|
10 |
*/
|
|
11 |
||
12 |
/* ========================================================================
|
|
13 |
* First we wait until the keyboard and mouse become idle for the specified
|
|
14 |
* amount of time. We do this in one of three different ways: periodically
|
|
15 |
* checking with the XIdle server extension; selecting key and mouse events
|
|
16 |
* on (nearly) all windows; or by waiting for the MIT-SCREEN-SAVER extension
|
|
17 |
* to send us a "you are idle" event.
|
|
18 |
*
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
19 |
* Then, we map a full screen black window.
|
1
by Karl Ramm
Import upstream version 3.34 |
20 |
*
|
21 |
* We place a __SWM_VROOT property on this window, so that newly-started
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
22 |
* clients will think that this window is a "virtual root" window (as per
|
23 |
* the logic in the historical "vroot.h" header.)
|
|
1
by Karl Ramm
Import upstream version 3.34 |
24 |
*
|
25 |
* If there is an existing "virtual root" window (one that already had
|
|
26 |
* an __SWM_VROOT property) then we remove that property from that window.
|
|
27 |
* Otherwise, clients would see that window (the real virtual root) instead
|
|
28 |
* of ours (the impostor.)
|
|
29 |
*
|
|
30 |
* Then we pick a random program to run, and start it. Two assumptions
|
|
31 |
* are made about this program: that it has been specified with whatever
|
|
32 |
* command-line options are necessary to make it run on the root window;
|
|
33 |
* and that it has been compiled with vroot.h, so that it is able to find
|
|
34 |
* the root window when a virtual-root window manager (or this program) is
|
|
35 |
* running.
|
|
36 |
*
|
|
37 |
* Then, we wait for keyboard or mouse events to be generated on the window.
|
|
38 |
* When they are, we kill the inferior process, unmap the window, and restore
|
|
39 |
* the __SWM_VROOT property to the real virtual root window if there was one.
|
|
40 |
*
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
41 |
* On multi-screen systems, we do the above on each screen, and start
|
42 |
* multiple programs, each with a different value of $DISPLAY.
|
|
43 |
*
|
|
44 |
* On Xinerama systems, we do a similar thing, but instead create multiple
|
|
45 |
* windows on the (only) display, and tell the subprocess which one to use
|
|
46 |
* via the $XSCREENSAVER_WINDOW environment variable -- this trick requires
|
|
47 |
* a recent (Aug 2003) revision of vroot.h.
|
|
48 |
*
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
49 |
* (See comments in screens.c for more details about Xinerama/RANDR stuff.)
|
50 |
*
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
51 |
* While we are waiting for user activity, we also set up timers so that,
|
52 |
* after a certain amount of time has passed, we can start a different
|
|
53 |
* screenhack. We do this by killing the running child process with
|
|
54 |
* SIGTERM, and then starting a new one in the same way.
|
|
1
by Karl Ramm
Import upstream version 3.34 |
55 |
*
|
56 |
* If there was a real virtual root, meaning that we removed the __SWM_VROOT
|
|
57 |
* property from it, meaning we must (absolutely must) restore it before we
|
|
58 |
* exit, then we set up signal handlers for most signals (SIGINT, SIGTERM,
|
|
59 |
* etc.) that do this. Most Xlib and Xt routines are not reentrant, so it
|
|
60 |
* is not generally safe to call them from signal handlers; however, this
|
|
61 |
* program spends most of its time waiting, so the window of opportunity
|
|
62 |
* when code could be called reentrantly is fairly small; and also, the worst
|
|
63 |
* that could happen is that the call would fail. If we've gotten one of
|
|
64 |
* these signals, then we're on our way out anyway. If we didn't restore the
|
|
65 |
* __SWM_VROOT property, that would be very bad, so it's worth a shot. Note
|
|
66 |
* that this means that, if you're using a virtual-root window manager, you
|
|
67 |
* can really fuck up the world by killing this process with "kill -9".
|
|
68 |
*
|
|
69 |
* This program accepts ClientMessages of type SCREENSAVER; these messages
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
70 |
* may contain the atoms ACTIVATE, DEACTIVATE, etc, meaning to turn the
|
1
by Karl Ramm
Import upstream version 3.34 |
71 |
* screensaver on or off now, regardless of the idleness of the user,
|
72 |
* and a few other things. The included "xscreensaver-command" program
|
|
73 |
* sends these messsages.
|
|
74 |
*
|
|
75 |
* If we don't have the XIdle, MIT-SCREEN-SAVER, or SGI SCREEN_SAVER
|
|
76 |
* extensions, then we do the XAutoLock trick: notice every window that
|
|
77 |
* gets created, and wait 30 seconds or so until its creating process has
|
|
78 |
* settled down, and then select KeyPress events on those windows which
|
|
79 |
* already select for KeyPress events. It's important that we not select
|
|
80 |
* KeyPress on windows which don't select them, because that would
|
|
81 |
* interfere with event propagation. This will break if any program
|
|
82 |
* changes its event mask to contain KeyRelease or PointerMotion more than
|
|
83 |
* 30 seconds after creating the window, but such programs do not seem to
|
|
84 |
* occur in nature (I've never seen it happen in all these years.)
|
|
85 |
*
|
|
86 |
* The reason that we can't select KeyPresses on windows that don't have
|
|
87 |
* them already is that, when dispatching a KeyPress event, X finds the
|
|
88 |
* lowest (leafmost) window in the hierarchy on which *any* client selects
|
|
89 |
* for KeyPress, and sends the event to that window. This means that if a
|
|
90 |
* client had a window with subwindows, and expected to receive KeyPress
|
|
91 |
* events on the parent window instead of the subwindows, then that client
|
|
92 |
* would malfunction if some other client selected KeyPress events on the
|
|
93 |
* subwindows. It is an incredible misdesign that one client can make
|
|
94 |
* another client malfunction in this way.
|
|
95 |
*
|
|
96 |
* To detect mouse motion, we periodically wake up and poll the mouse
|
|
97 |
* position and button/modifier state, and notice when something has
|
|
98 |
* changed. We make this check every five seconds by default, and since the
|
|
99 |
* screensaver timeout has a granularity of one minute, this makes the
|
|
100 |
* chance of a false positive very small. We could detect mouse motion in
|
|
101 |
* the same way as keyboard activity, but that would suffer from the same
|
|
102 |
* "client changing event mask" problem that the KeyPress events hack does.
|
|
103 |
* I think polling is more reliable.
|
|
104 |
*
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
105 |
* On systems with /proc/interrupts (Linux) we poll that file and note when
|
106 |
* the interrupt counter numbers on the "keyboard" and "PS/2" lines change.
|
|
107 |
* (There is no reliable way, using /proc/interrupts, to detect non-PS/2
|
|
108 |
* mice, so it doesn't help for serial or USB mice.)
|
|
109 |
*
|
|
110 |
* None of this crap happens if we're using one of the extensions. Sadly,
|
|
111 |
* the XIdle extension hasn't been available for many years; the SGI
|
|
112 |
* extension only exists on SGIs; and the MIT extension, while widely
|
|
113 |
* deployed, is garbage in several ways.
|
|
1
by Karl Ramm
Import upstream version 3.34 |
114 |
*
|
115 |
* A third idle-detection option could be implemented (but is not): when
|
|
116 |
* running on the console display ($DISPLAY is `localhost`:0) and we're on a
|
|
117 |
* machine where /dev/tty and /dev/mouse have reasonable last-modification
|
|
118 |
* times, we could just stat() those. But the incremental benefit of
|
|
119 |
* implementing this is really small, so forget I said anything.
|
|
120 |
*
|
|
121 |
* Debugging hints:
|
|
122 |
* - Have a second terminal handy.
|
|
123 |
* - Be careful where you set your breakpoints, you don't want this to
|
|
124 |
* stop under the debugger with the keyboard grabbed or the blackout
|
|
125 |
* window exposed.
|
|
126 |
* - If you run your debugger under XEmacs, try M-ESC (x-grab-keyboard)
|
|
127 |
* to keep your emacs window alive even when xscreensaver has grabbed.
|
|
128 |
* - Go read the code related to `debug_p'.
|
|
129 |
* - You probably can't set breakpoints in functions that are called on
|
|
130 |
* the other side of a call to fork() -- if your subprocesses are
|
|
131 |
* dying with signal 5, Trace/BPT Trap, you're losing in this way.
|
|
132 |
* - If you aren't using a server extension, don't leave this stopped
|
|
133 |
* under the debugger for very long, or the X input buffer will get
|
|
134 |
* huge because of the keypress events it's selecting for. This can
|
|
135 |
* make your X server wedge with "no more input buffers."
|
|
136 |
*
|
|
137 |
* ======================================================================== */
|
|
138 |
||
139 |
#ifdef HAVE_CONFIG_H
|
|
140 |
# include "config.h"
|
|
141 |
#endif
|
|
142 |
||
143 |
#include <stdio.h> |
|
144 |
#include <ctype.h> |
|
145 |
#include <X11/Xlib.h> |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
146 |
|
1.1.10
by Robert Ancell
Import upstream version 5.12 |
147 |
#ifdef ENABLE_NLS
|
148 |
# include <locale.h>
|
|
149 |
# include <libintl.h>
|
|
150 |
#endif /* ENABLE_NLS */ |
|
151 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
152 |
#include <X11/Xlibint.h> |
153 |
||
1
by Karl Ramm
Import upstream version 3.34 |
154 |
#include <X11/Xatom.h> |
155 |
#include <X11/Intrinsic.h> |
|
156 |
#include <X11/StringDefs.h> |
|
157 |
#include <X11/Shell.h> |
|
158 |
#include <X11/Xos.h> |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
159 |
#include <time.h> |
160 |
#include <sys/time.h> |
|
1
by Karl Ramm
Import upstream version 3.34 |
161 |
#include <netdb.h> /* for gethostbyname() */ |
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
162 |
#include <sys/types.h> |
163 |
#include <pwd.h> |
|
1
by Karl Ramm
Import upstream version 3.34 |
164 |
#ifdef HAVE_XMU
|
165 |
# ifndef VMS
|
|
166 |
# include <X11/Xmu/Error.h>
|
|
167 |
# else /* !VMS */ |
|
168 |
# include <Xmu/Error.h>
|
|
169 |
# endif /* !VMS */ |
|
170 |
#else /* !HAVE_XMU */ |
|
171 |
# include "xmu.h"
|
|
172 |
#endif /* !HAVE_XMU */ |
|
173 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
174 |
#ifdef HAVE_MIT_SAVER_EXTENSION
|
175 |
#include <X11/extensions/scrnsaver.h> |
|
176 |
#endif /* HAVE_MIT_SAVER_EXTENSION */ |
|
177 |
||
1
by Karl Ramm
Import upstream version 3.34 |
178 |
#ifdef HAVE_XIDLE_EXTENSION
|
179 |
# include <X11/extensions/xidle.h>
|
|
180 |
#endif /* HAVE_XIDLE_EXTENSION */ |
|
181 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
182 |
#ifdef HAVE_SGI_VC_EXTENSION
|
183 |
# include <X11/extensions/XSGIvc.h>
|
|
184 |
#endif /* HAVE_SGI_VC_EXTENSION */ |
|
185 |
||
186 |
#ifdef HAVE_READ_DISPLAY_EXTENSION
|
|
187 |
# include <X11/extensions/readdisplay.h>
|
|
188 |
#endif /* HAVE_READ_DISPLAY_EXTENSION */ |
|
189 |
||
190 |
#ifdef HAVE_XSHM_EXTENSION
|
|
191 |
# include <X11/extensions/XShm.h>
|
|
192 |
#endif /* HAVE_XSHM_EXTENSION */ |
|
193 |
||
194 |
#ifdef HAVE_DPMS_EXTENSION
|
|
195 |
# include <X11/extensions/dpms.h>
|
|
196 |
#endif /* HAVE_DPMS_EXTENSION */ |
|
197 |
||
198 |
||
199 |
#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
|
|
200 |
# include <X11/extensions/Xdbe.h>
|
|
201 |
#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ |
|
202 |
||
203 |
#ifdef HAVE_XF86VMODE
|
|
204 |
# include <X11/extensions/xf86vmode.h>
|
|
205 |
#endif /* HAVE_XF86VMODE */ |
|
206 |
||
207 |
#ifdef HAVE_XF86MISCSETGRABKEYSSTATE
|
|
208 |
# include <X11/extensions/xf86misc.h>
|
|
209 |
#endif /* HAVE_XF86MISCSETGRABKEYSSTATE */ |
|
210 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
211 |
#ifdef HAVE_XINERAMA
|
212 |
# include <X11/extensions/Xinerama.h>
|
|
213 |
#endif /* HAVE_XINERAMA */ |
|
214 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
215 |
#ifdef HAVE_RANDR
|
216 |
# include <X11/extensions/Xrandr.h>
|
|
217 |
#endif /* HAVE_RANDR */ |
|
218 |
||
219 |
||
1
by Karl Ramm
Import upstream version 3.34 |
220 |
#include "xscreensaver.h" |
221 |
#include "version.h" |
|
222 |
#include "yarandom.h" |
|
223 |
#include "resources.h" |
|
224 |
#include "visual.h" |
|
225 |
#include "usleep.h" |
|
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
226 |
#include "auth.h" |
1
by Karl Ramm
Import upstream version 3.34 |
227 |
|
228 |
saver_info *global_si_kludge = 0; /* I hate C so much... */ |
|
229 |
||
230 |
char *progname = 0; |
|
231 |
char *progclass = 0; |
|
232 |
XrmDatabase db = 0; |
|
233 |
||
234 |
||
235 |
static Atom XA_SCREENSAVER_RESPONSE; |
|
236 |
static Atom XA_ACTIVATE, XA_DEACTIVATE, XA_CYCLE, XA_NEXT, XA_PREV; |
|
237 |
static Atom XA_RESTART, XA_SELECT; |
|
238 |
static Atom XA_THROTTLE, XA_UNTHROTTLE; |
|
239 |
Atom XA_DEMO, XA_PREFS, XA_EXIT, XA_LOCK, XA_BLANK; |
|
240 |
||
241 |
||
242 |
static XrmOptionDescRec options [] = { |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
243 |
|
244 |
{ "-verbose", ".verbose", XrmoptionNoArg, "on" }, |
|
245 |
{ "-silent", ".verbose", XrmoptionNoArg, "off" }, |
|
246 |
||
247 |
/* xscreensaver-demo uses this one */
|
|
248 |
{ "-nosplash", ".splash", XrmoptionNoArg, "off" }, |
|
249 |
{ "-no-splash", ".splash", XrmoptionNoArg, "off" }, |
|
250 |
||
251 |
/* useful for debugging */
|
|
252 |
{ "-no-capture-stderr", ".captureStderr", XrmoptionNoArg, "off" }, |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
253 |
{ "-log", ".logFile", XrmoptionSepArg, 0 }, |
1
by Karl Ramm
Import upstream version 3.34 |
254 |
};
|
255 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
256 |
#ifdef __GNUC__
|
257 |
__extension__ /* shut up about "string length is greater than the length |
|
258 |
ISO C89 compilers are required to support" when including
|
|
259 |
the .ad file... */
|
|
260 |
#endif
|
|
261 |
||
1
by Karl Ramm
Import upstream version 3.34 |
262 |
static char *defaults[] = { |
263 |
#include "XScreenSaver_ad.h" |
|
264 |
0
|
|
265 |
};
|
|
266 |
||
267 |
#ifdef _VROOT_H_
|
|
268 |
ERROR! You must not include vroot.h in this file. |
|
269 |
#endif
|
|
270 |
||
271 |
static void |
|
272 |
do_help (saver_info *si) |
|
273 |
{
|
|
274 |
fflush (stdout); |
|
275 |
fflush (stderr); |
|
276 |
fprintf (stdout, "\ |
|
1.1.5
by Ted Gould
Import upstream version 5.05 |
277 |
xscreensaver %s, copyright (c) 1991-2008 by Jamie Zawinski <jwz@jwz.org>\n\ |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
278 |
\n\ |
279 |
All xscreensaver configuration is via the `~/.xscreensaver' file.\n\ |
|
280 |
Rather than editing that file by hand, just run `xscreensaver-demo':\n\ |
|
281 |
that program lets you configure the screen saver graphically,\n\ |
|
282 |
including timeouts, locking, and display modes.\n\ |
|
283 |
\n", |
|
284 |
si->version); |
|
285 |
fprintf (stdout, "\ |
|
286 |
Just getting started? Try this:\n\ |
|
1
by Karl Ramm
Import upstream version 3.34 |
287 |
\n\ |
288 |
xscreensaver &\n\ |
|
289 |
xscreensaver-demo\n\ |
|
290 |
\n\ |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
291 |
For updates, online manual, and FAQ, please see the web page:\n\ |
292 |
\n\ |
|
293 |
http://www.jwz.org/xscreensaver/\n\ |
|
294 |
\n"); |
|
295 |
||
1
by Karl Ramm
Import upstream version 3.34 |
296 |
fflush (stdout); |
297 |
fflush (stderr); |
|
298 |
exit (1); |
|
299 |
}
|
|
300 |
||
301 |
||
302 |
char * |
|
303 |
timestring (void) |
|
304 |
{
|
|
305 |
time_t now = time ((time_t *) 0); |
|
306 |
char *str = (char *) ctime (&now); |
|
307 |
char *nl = (char *) strchr (str, '\n'); |
|
308 |
if (nl) *nl = 0; /* take off that dang newline */ |
|
309 |
return str; |
|
310 |
}
|
|
311 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
312 |
static Bool blurb_timestamp_p = True; /* kludge */ |
1
by Karl Ramm
Import upstream version 3.34 |
313 |
|
314 |
const char * |
|
315 |
blurb (void) |
|
316 |
{
|
|
317 |
if (!blurb_timestamp_p) |
|
318 |
return progname; |
|
319 |
else
|
|
320 |
{
|
|
321 |
static char buf[255]; |
|
322 |
char *ct = timestring(); |
|
323 |
int n = strlen(progname); |
|
324 |
if (n > 100) n = 99; |
|
325 |
strncpy(buf, progname, n); |
|
326 |
buf[n++] = ':'; |
|
327 |
buf[n++] = ' '; |
|
328 |
strncpy(buf+n, ct+11, 8); |
|
329 |
strcpy(buf+n+9, ": "); |
|
330 |
return buf; |
|
331 |
}
|
|
332 |
}
|
|
333 |
||
334 |
||
335 |
int
|
|
336 |
saver_ehandler (Display *dpy, XErrorEvent *error) |
|
337 |
{
|
|
338 |
saver_info *si = global_si_kludge; /* I hate C so much... */ |
|
339 |
int i; |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
340 |
Bool fatal_p; |
1
by Karl Ramm
Import upstream version 3.34 |
341 |
|
342 |
if (!real_stderr) real_stderr = stderr; |
|
343 |
||
344 |
fprintf (real_stderr, "\n" |
|
345 |
"#######################################"
|
|
346 |
"#######################################\n\n" |
|
347 |
"%s: X Error! PLEASE REPORT THIS BUG.\n", |
|
348 |
blurb()); |
|
349 |
||
350 |
for (i = 0; i < si->nscreens; i++) |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
351 |
{
|
352 |
saver_screen_info *ssi = &si->screens[i]; |
|
353 |
fprintf (real_stderr, "%s: screen %d/%d: 0x%x, 0x%x, 0x%x\n", |
|
354 |
blurb(), ssi->real_screen_number, ssi->number, |
|
355 |
(unsigned int) RootWindowOfScreen (si->screens[i].screen), |
|
356 |
(unsigned int) si->screens[i].real_vroot, |
|
357 |
(unsigned int) si->screens[i].screensaver_window); |
|
358 |
}
|
|
1
by Karl Ramm
Import upstream version 3.34 |
359 |
|
360 |
fprintf (real_stderr, "\n" |
|
361 |
"#######################################"
|
|
362 |
"#######################################\n\n"); |
|
363 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
364 |
fatal_p = XmuPrintDefaultErrorMessage (dpy, error, real_stderr); |
365 |
||
366 |
fatal_p = True; /* The only time I've ever seen a supposedly nonfatal error, |
|
367 |
it has been BadImplementation / Xlib sequence lost, which
|
|
368 |
are in truth pretty damned fatal.
|
|
369 |
*/
|
|
370 |
||
371 |
fprintf (real_stderr, "\n"); |
|
372 |
||
373 |
if (! fatal_p) |
|
374 |
fprintf (real_stderr, "%s: nonfatal error.\n\n", blurb()); |
|
375 |
else
|
|
1
by Karl Ramm
Import upstream version 3.34 |
376 |
{
|
377 |
if (si->prefs.xsync_p) |
|
378 |
{
|
|
379 |
saver_exit (si, -1, "because of synchronous X Error"); |
|
380 |
}
|
|
381 |
else
|
|
382 |
{
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
383 |
#ifdef __GNUC__
|
384 |
__extension__ /* don't warn about "string length is greater than the |
|
385 |
length ISO C89 compilers are required to support". */
|
|
386 |
#endif
|
|
387 |
fprintf (real_stderr, |
|
388 |
"#######################################################################\n" |
|
389 |
"\n" |
|
1
by Karl Ramm
Import upstream version 3.34 |
390 |
" If at all possible, please re-run xscreensaver with the command\n" |
1.1.6
by Ted Gould
Import upstream version 5.07 |
391 |
" line arguments `-sync -verbose -log log.txt', and reproduce this\n" |
1
by Karl Ramm
Import upstream version 3.34 |
392 |
" bug. That will cause xscreensaver to dump a `core' file to the\n" |
393 |
" current directory. Please include the stack trace from that core\n" |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
394 |
" file in your bug report. *DO NOT* mail the core file itself! That\n" |
395 |
" won't work. A \"log.txt\" file will also be written. Please *do*\n" |
|
396 |
" include the complete \"log.txt\" file with your bug report.\n" |
|
1
by Karl Ramm
Import upstream version 3.34 |
397 |
"\n" |
398 |
" http://www.jwz.org/xscreensaver/bugs.html explains how to create\n" |
|
399 |
" the most useful bug reports, and how to examine core files.\n" |
|
400 |
"\n" |
|
401 |
" The more information you can provide, the better. But please\n" |
|
402 |
" report this bug, regardless!\n" |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
403 |
"\n" |
404 |
"#######################################################################\n" |
|
405 |
"\n" |
|
1
by Karl Ramm
Import upstream version 3.34 |
406 |
"\n"); |
407 |
||
408 |
saver_exit (si, -1, 0); |
|
409 |
}
|
|
410 |
}
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
411 |
|
1
by Karl Ramm
Import upstream version 3.34 |
412 |
return 0; |
413 |
}
|
|
414 |
||
415 |
||
416 |
/* This error handler is used only while the X connection is being set up;
|
|
417 |
after we've got a connection, we don't use this handler again. The only
|
|
418 |
reason for having this is so that we can present a more idiot-proof error
|
|
419 |
message than "cannot open display."
|
|
420 |
*/
|
|
421 |
static void |
|
422 |
startup_ehandler (String name, String type, String class, |
|
423 |
String defalt, /* one can't even spel properly |
|
424 |
in this joke of a language */
|
|
425 |
String *av, Cardinal *ac) |
|
426 |
{
|
|
427 |
char fmt[512]; |
|
428 |
String p[10]; |
|
429 |
saver_info *si = global_si_kludge; /* I hate C so much... */ |
|
430 |
XrmDatabase *db = XtAppGetErrorDatabase(si->app); |
|
431 |
*fmt = 0; |
|
432 |
XtAppGetErrorDatabaseText(si->app, name, type, class, defalt, |
|
433 |
fmt, sizeof(fmt)-1, *db); |
|
434 |
||
435 |
fprintf (stderr, "%s: ", blurb()); |
|
436 |
||
437 |
memset (p, 0, sizeof(p)); |
|
438 |
if (*ac > countof (p)) *ac = countof (p); |
|
439 |
memcpy ((char *) p, (char *) av, (*ac) * sizeof(*av)); |
|
440 |
fprintf (stderr, fmt, /* Did I mention that I hate C? */ |
|
441 |
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]); |
|
442 |
fprintf (stderr, "\n"); |
|
443 |
||
444 |
describe_uids (si, stderr); |
|
445 |
||
446 |
if (si->orig_uid && !strncmp (si->orig_uid, "root/", 5)) |
|
447 |
{
|
|
448 |
fprintf (stderr, "\n" |
|
449 |
"%s: This is probably because you're logging in as root. You\n" |
|
450 |
" shouldn't log in as root: you should log in as a normal user,\n" |
|
451 |
" and then `su' as needed. If you insist on logging in as\n" |
|
452 |
" root, you will have to turn off X's security features before\n" |
|
453 |
" xscreensaver will work.\n" |
|
454 |
"\n" |
|
455 |
" Please read the manual and FAQ for more information:\n", |
|
456 |
blurb()); |
|
457 |
}
|
|
458 |
else
|
|
459 |
{
|
|
460 |
fprintf (stderr, "\n" |
|
461 |
"%s: Errors at startup are usually authorization problems.\n" |
|
462 |
" But you're not logging in as root (good!) so something\n" |
|
463 |
" else must be wrong. Did you read the manual and the FAQ?\n", |
|
464 |
blurb()); |
|
465 |
}
|
|
466 |
||
467 |
fprintf (stderr, "\n" |
|
468 |
" http://www.jwz.org/xscreensaver/faq.html\n" |
|
469 |
" http://www.jwz.org/xscreensaver/man.html\n" |
|
470 |
"\n"); |
|
471 |
||
472 |
fflush (stderr); |
|
473 |
fflush (stdout); |
|
474 |
exit (1); |
|
475 |
}
|
|
476 |
||
477 |
||
478 |
/* The zillions of initializations.
|
|
479 |
*/
|
|
480 |
||
481 |
/* Set progname, version, etc. This is done very early.
|
|
482 |
*/
|
|
483 |
static void |
|
484 |
set_version_string (saver_info *si, int *argc, char **argv) |
|
485 |
{
|
|
486 |
progclass = "XScreenSaver"; |
|
487 |
||
488 |
/* progname is reset later, after we connect to X. */
|
|
489 |
progname = strrchr(argv[0], '/'); |
|
490 |
if (progname) progname++; |
|
491 |
else progname = argv[0]; |
|
492 |
||
493 |
if (strlen(progname) > 100) /* keep it short. */ |
|
494 |
progname[99] = 0; |
|
495 |
||
496 |
/* The X resource database blows up if argv[0] has a "." in it. */
|
|
497 |
{
|
|
498 |
char *s = argv[0]; |
|
499 |
while ((s = strchr (s, '.'))) |
|
500 |
*s = '_'; |
|
501 |
}
|
|
502 |
||
503 |
si->version = (char *) malloc (5); |
|
504 |
memcpy (si->version, screensaver_id + 17, 4); |
|
505 |
si->version [4] = 0; |
|
506 |
}
|
|
507 |
||
508 |
||
509 |
/* Initializations that potentially take place as a priveleged user:
|
|
510 |
If the xscreensaver executable is setuid root, then these initializations
|
|
511 |
are run as root, before discarding privileges.
|
|
512 |
*/
|
|
513 |
static void |
|
514 |
privileged_initialization (saver_info *si, int *argc, char **argv) |
|
515 |
{
|
|
516 |
#ifndef NO_LOCKING
|
|
517 |
/* before hack_uid() for proper permissions */
|
|
518 |
lock_priv_init (*argc, argv, si->prefs.verbose_p); |
|
519 |
#endif /* NO_LOCKING */ |
|
520 |
||
521 |
hack_uid (si); |
|
522 |
}
|
|
523 |
||
524 |
||
525 |
/* Figure out what locking mechanisms are supported.
|
|
526 |
*/
|
|
527 |
static void |
|
528 |
lock_initialization (saver_info *si, int *argc, char **argv) |
|
529 |
{
|
|
530 |
#ifdef NO_LOCKING
|
|
531 |
si->locking_disabled_p = True; |
|
532 |
si->nolock_reason = "not compiled with locking support"; |
|
533 |
#else /* !NO_LOCKING */ |
|
534 |
||
535 |
/* Finish initializing locking, now that we're out of privileged code. */
|
|
536 |
if (! lock_init (*argc, argv, si->prefs.verbose_p)) |
|
537 |
{
|
|
538 |
si->locking_disabled_p = True; |
|
539 |
si->nolock_reason = "error getting password"; |
|
540 |
}
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
541 |
|
542 |
/* If locking is currently enabled, but the environment indicates that
|
|
543 |
we have been launched as GDM's "Background" program, then disable
|
|
544 |
locking just in case.
|
|
545 |
*/
|
|
546 |
if (!si->locking_disabled_p && getenv ("RUNNING_UNDER_GDM")) |
|
547 |
{
|
|
548 |
si->locking_disabled_p = True; |
|
549 |
si->nolock_reason = "running under GDM"; |
|
550 |
}
|
|
551 |
||
552 |
/* If the server is XDarwin (MacOS X) then disable locking.
|
|
553 |
(X grabs only affect X programs, so you can use Command-Tab
|
|
554 |
to bring any other Mac program to the front, e.g., Terminal.)
|
|
555 |
*/
|
|
556 |
if (!si->locking_disabled_p) |
|
557 |
{
|
|
558 |
int op = 0, event = 0, error = 0; |
|
559 |
Bool macos_p = False; |
|
560 |
||
561 |
#ifdef __APPLE__
|
|
562 |
/* Disable locking if *running* on Apple hardware, since we have no
|
|
563 |
reliable way to determine whether the server is running on MacOS.
|
|
564 |
Hopefully __APPLE__ means "MacOS" and not "Linux on Mac hardware"
|
|
565 |
but I'm not really sure about that.
|
|
566 |
*/
|
|
567 |
macos_p = True; |
|
568 |
#endif
|
|
569 |
||
570 |
if (!macos_p) |
|
571 |
/* This extension exists on the Apple X11 server, but not
|
|
572 |
on earlier versions of the XDarwin server. */
|
|
573 |
macos_p = XQueryExtension (si->dpy, "Apple-DRI", &op, &event, &error); |
|
574 |
||
575 |
if (macos_p) |
|
576 |
{
|
|
577 |
si->locking_disabled_p = True; |
|
578 |
si->nolock_reason = "Cannot lock securely on MacOS X"; |
|
579 |
}
|
|
580 |
}
|
|
581 |
||
1.1.7
by Robert Ancell
Import upstream version 5.08 |
582 |
if (si->prefs.debug_p) /* But allow locking anyway in debug mode. */ |
583 |
si->locking_disabled_p = False; |
|
584 |
||
1
by Karl Ramm
Import upstream version 3.34 |
585 |
#endif /* NO_LOCKING */ |
586 |
}
|
|
587 |
||
588 |
||
589 |
/* Open the connection to the X server, and intern our Atoms.
|
|
590 |
*/
|
|
591 |
static Widget |
|
592 |
connect_to_server (saver_info *si, int *argc, char **argv) |
|
593 |
{
|
|
594 |
Widget toplevel_shell; |
|
595 |
||
596 |
#ifdef HAVE_PUTENV
|
|
597 |
char *d = getenv ("DISPLAY"); |
|
598 |
if (!d || !*d) |
|
599 |
{
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
600 |
char *ndpy = strdup("DISPLAY=:0.0"); |
1
by Karl Ramm
Import upstream version 3.34 |
601 |
/* if (si->prefs.verbose_p) */ /* sigh, too early to test this... */ |
602 |
fprintf (stderr, |
|
603 |
"%s: warning: $DISPLAY is not set: defaulting to \"%s\".\n", |
|
604 |
blurb(), ndpy+8); |
|
605 |
if (putenv (ndpy)) |
|
606 |
abort (); |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
607 |
/* don't free (ndpy) -- some implementations of putenv (BSD 4.4,
|
608 |
glibc 2.0) copy the argument, but some (libc4,5, glibc 2.1.2)
|
|
609 |
do not. So we must leak it (and/or the previous setting). Yay.
|
|
610 |
*/
|
|
1
by Karl Ramm
Import upstream version 3.34 |
611 |
}
|
612 |
#endif /* HAVE_PUTENV */ |
|
613 |
||
614 |
XSetErrorHandler (saver_ehandler); |
|
615 |
||
616 |
XtAppSetErrorMsgHandler (si->app, startup_ehandler); |
|
617 |
toplevel_shell = XtAppInitialize (&si->app, progclass, |
|
618 |
options, XtNumber (options), |
|
619 |
argc, argv, defaults, 0, 0); |
|
620 |
XtAppSetErrorMsgHandler (si->app, 0); |
|
621 |
||
622 |
si->dpy = XtDisplay (toplevel_shell); |
|
623 |
si->prefs.db = XtDatabase (si->dpy); |
|
624 |
XtGetApplicationNameAndClass (si->dpy, &progname, &progclass); |
|
625 |
||
626 |
if(strlen(progname) > 100) /* keep it short. */ |
|
627 |
progname [99] = 0; |
|
628 |
||
629 |
db = si->prefs.db; /* resources.c needs this */ |
|
630 |
||
631 |
XA_VROOT = XInternAtom (si->dpy, "__SWM_VROOT", False); |
|
632 |
XA_SCREENSAVER = XInternAtom (si->dpy, "SCREENSAVER", False); |
|
633 |
XA_SCREENSAVER_VERSION = XInternAtom (si->dpy, "_SCREENSAVER_VERSION",False); |
|
634 |
XA_SCREENSAVER_ID = XInternAtom (si->dpy, "_SCREENSAVER_ID", False); |
|
635 |
XA_SCREENSAVER_STATUS = XInternAtom (si->dpy, "_SCREENSAVER_STATUS", False); |
|
636 |
XA_SCREENSAVER_RESPONSE = XInternAtom (si->dpy, "_SCREENSAVER_RESPONSE", |
|
637 |
False); |
|
638 |
XA_XSETROOT_ID = XInternAtom (si->dpy, "_XSETROOT_ID", False); |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
639 |
XA_ESETROOT_PMAP_ID = XInternAtom (si->dpy, "ESETROOT_PMAP_ID", False); |
640 |
XA_XROOTPMAP_ID = XInternAtom (si->dpy, "_XROOTPMAP_ID", False); |
|
1
by Karl Ramm
Import upstream version 3.34 |
641 |
XA_ACTIVATE = XInternAtom (si->dpy, "ACTIVATE", False); |
642 |
XA_DEACTIVATE = XInternAtom (si->dpy, "DEACTIVATE", False); |
|
643 |
XA_RESTART = XInternAtom (si->dpy, "RESTART", False); |
|
644 |
XA_CYCLE = XInternAtom (si->dpy, "CYCLE", False); |
|
645 |
XA_NEXT = XInternAtom (si->dpy, "NEXT", False); |
|
646 |
XA_PREV = XInternAtom (si->dpy, "PREV", False); |
|
647 |
XA_SELECT = XInternAtom (si->dpy, "SELECT", False); |
|
648 |
XA_EXIT = XInternAtom (si->dpy, "EXIT", False); |
|
649 |
XA_DEMO = XInternAtom (si->dpy, "DEMO", False); |
|
650 |
XA_PREFS = XInternAtom (si->dpy, "PREFS", False); |
|
651 |
XA_LOCK = XInternAtom (si->dpy, "LOCK", False); |
|
652 |
XA_BLANK = XInternAtom (si->dpy, "BLANK", False); |
|
653 |
XA_THROTTLE = XInternAtom (si->dpy, "THROTTLE", False); |
|
654 |
XA_UNTHROTTLE = XInternAtom (si->dpy, "UNTHROTTLE", False); |
|
655 |
||
656 |
return toplevel_shell; |
|
657 |
}
|
|
658 |
||
659 |
||
660 |
/* Handle the command-line arguments that were not handled for us by Xt.
|
|
661 |
Issue an error message and exit if there are unknown options.
|
|
662 |
*/
|
|
663 |
static void |
|
664 |
process_command_line (saver_info *si, int *argc, char **argv) |
|
665 |
{
|
|
666 |
int i; |
|
667 |
for (i = 1; i < *argc; i++) |
|
668 |
{
|
|
669 |
if (!strcmp (argv[i], "-debug")) |
|
670 |
/* no resource for this one, out of paranoia. */
|
|
671 |
si->prefs.debug_p = True; |
|
672 |
||
673 |
else if (!strcmp (argv[i], "-h") || |
|
674 |
!strcmp (argv[i], "-help") || |
|
675 |
!strcmp (argv[i], "--help")) |
|
676 |
do_help (si); |
|
677 |
||
678 |
else
|
|
679 |
{
|
|
680 |
const char *s = argv[i]; |
|
681 |
fprintf (stderr, "%s: unknown option \"%s\". Try \"-help\".\n", |
|
682 |
blurb(), s); |
|
683 |
||
684 |
if (s[0] == '-' && s[1] == '-') s++; |
|
685 |
if (!strcmp (s, "-activate") || |
|
686 |
!strcmp (s, "-deactivate") || |
|
687 |
!strcmp (s, "-cycle") || |
|
688 |
!strcmp (s, "-next") || |
|
689 |
!strcmp (s, "-prev") || |
|
690 |
!strcmp (s, "-exit") || |
|
691 |
!strcmp (s, "-restart") || |
|
692 |
!strcmp (s, "-demo") || |
|
693 |
!strcmp (s, "-prefs") || |
|
694 |
!strcmp (s, "-preferences") || |
|
695 |
!strcmp (s, "-lock") || |
|
696 |
!strcmp (s, "-version") || |
|
697 |
!strcmp (s, "-time")) |
|
698 |
{
|
|
699 |
||
700 |
if (!strcmp (s, "-demo") || !strcmp (s, "-prefs")) |
|
701 |
fprintf (stderr, "\n\ |
|
702 |
Perhaps you meant to run the `xscreensaver-demo' program instead?\n"); |
|
703 |
else
|
|
704 |
fprintf (stderr, "\n\ |
|
705 |
However, `%s' is an option to the `xscreensaver-command' program.\n", s); |
|
706 |
||
707 |
fprintf (stderr, "\ |
|
708 |
The `xscreensaver' program is a daemon that runs in the background.\n\ |
|
709 |
You control a running xscreensaver process by sending it messages\n\ |
|
710 |
with `xscreensaver-demo' or `xscreensaver-command'.\n\ |
|
711 |
. See the man pages for details, or check the web page:\n\ |
|
712 |
http://www.jwz.org/xscreensaver/\n\n"); |
|
713 |
}
|
|
714 |
||
715 |
exit (1); |
|
716 |
}
|
|
717 |
}
|
|
718 |
}
|
|
719 |
||
720 |
||
721 |
/* Print out the xscreensaver banner to the tty if applicable;
|
|
722 |
Issue any other warnings that are called for at this point.
|
|
723 |
*/
|
|
724 |
static void |
|
725 |
print_banner (saver_info *si) |
|
726 |
{
|
|
727 |
saver_preferences *p = &si->prefs; |
|
728 |
||
729 |
/* This resource gets set some time before the others, so that we know
|
|
730 |
whether to print the banner (and so that the banner gets printed before
|
|
731 |
any resource-database-related error messages.)
|
|
732 |
*/
|
|
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
733 |
p->verbose_p = (p->debug_p || |
734 |
get_boolean_resource (si->dpy, "verbose", "Boolean")); |
|
1
by Karl Ramm
Import upstream version 3.34 |
735 |
|
736 |
/* Ditto, for the locking_disabled_p message. */
|
|
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
737 |
p->lock_p = get_boolean_resource (si->dpy, "lock", "Boolean"); |
1
by Karl Ramm
Import upstream version 3.34 |
738 |
|
739 |
if (p->verbose_p) |
|
740 |
fprintf (stderr, |
|
1.1.5
by Ted Gould
Import upstream version 5.05 |
741 |
"%s %s, copyright (c) 1991-2008 "
|
1
by Karl Ramm
Import upstream version 3.34 |
742 |
"by Jamie Zawinski <jwz@jwz.org>.\n", |
743 |
progname, si->version); |
|
744 |
||
745 |
if (p->debug_p) |
|
746 |
fprintf (stderr, "\n" |
|
747 |
"%s: Warning: running in DEBUG MODE. Be afraid.\n" |
|
748 |
"\n" |
|
749 |
"\tNote that in debug mode, the xscreensaver window will only\n" |
|
750 |
"\tcover the left half of the screen. (The idea is that you\n" |
|
751 |
"\tcan still see debugging output in a shell, if you position\n" |
|
752 |
"\tit on the right side of the screen.)\n" |
|
753 |
"\n" |
|
754 |
"\tDebug mode is NOT SECURE. Do not run with -debug in\n" |
|
755 |
"\tuntrusted environments.\n" |
|
756 |
"\n", |
|
757 |
blurb()); |
|
758 |
||
759 |
if (p->verbose_p) |
|
760 |
{
|
|
761 |
if (!si->uid_message || !*si->uid_message) |
|
762 |
describe_uids (si, stderr); |
|
763 |
else
|
|
764 |
{
|
|
765 |
if (si->orig_uid && *si->orig_uid) |
|
766 |
fprintf (stderr, "%s: initial effective uid/gid was %s.\n", |
|
767 |
blurb(), si->orig_uid); |
|
768 |
fprintf (stderr, "%s: %s\n", blurb(), si->uid_message); |
|
769 |
}
|
|
770 |
||
771 |
fprintf (stderr, "%s: in process %lu.\n", blurb(), |
|
772 |
(unsigned long) getpid()); |
|
773 |
}
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
774 |
}
|
775 |
||
776 |
static void |
|
777 |
print_lock_failure_banner (saver_info *si) |
|
778 |
{
|
|
779 |
saver_preferences *p = &si->prefs; |
|
1
by Karl Ramm
Import upstream version 3.34 |
780 |
|
781 |
/* If locking was not able to be initalized for some reason, explain why.
|
|
782 |
(This has to be done after we've read the lock_p resource.)
|
|
783 |
*/
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
784 |
if (si->locking_disabled_p) |
1
by Karl Ramm
Import upstream version 3.34 |
785 |
{
|
786 |
p->lock_p = False; |
|
787 |
fprintf (stderr, "%s: locking is disabled (%s).\n", blurb(), |
|
788 |
si->nolock_reason); |
|
789 |
if (strstr (si->nolock_reason, "passw")) |
|
790 |
fprintf (stderr, "%s: does xscreensaver need to be setuid? " |
|
791 |
"consult the manual.\n", blurb()); |
|
792 |
else if (strstr (si->nolock_reason, "running as ")) |
|
793 |
fprintf (stderr, |
|
794 |
"%s: locking only works when xscreensaver is launched\n" |
|
795 |
"\t by a normal, non-privileged user (e.g., not \"root\".)\n" |
|
796 |
"\t See the manual for details.\n", |
|
797 |
blurb()); |
|
798 |
}
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
799 |
|
1
by Karl Ramm
Import upstream version 3.34 |
800 |
}
|
801 |
||
802 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
803 |
/* called from screens.c so that all the Xt crud is here. */
|
804 |
void
|
|
805 |
initialize_screen_root_widget (saver_screen_info *ssi) |
|
806 |
{
|
|
807 |
saver_info *si = ssi->global; |
|
808 |
if (ssi->toplevel_shell) |
|
809 |
XtDestroyWidget (ssi->toplevel_shell); |
|
810 |
ssi->toplevel_shell = |
|
811 |
XtVaAppCreateShell (progname, progclass, |
|
812 |
applicationShellWidgetClass, |
|
813 |
si->dpy, |
|
814 |
XtNscreen, ssi->screen, |
|
815 |
XtNvisual, ssi->current_visual, |
|
816 |
XtNdepth, visual_depth (ssi->screen, |
|
817 |
ssi->current_visual), |
|
818 |
NULL); |
|
819 |
}
|
|
1.1.5
by Ted Gould
Import upstream version 5.05 |
820 |
|
821 |
||
1
by Karl Ramm
Import upstream version 3.34 |
822 |
/* Examine all of the display's screens, and populate the `saver_screen_info'
|
823 |
structures. Make sure this is called after hack_environment() sets $PATH.
|
|
824 |
*/
|
|
825 |
static void |
|
826 |
initialize_per_screen_info (saver_info *si, Widget toplevel_shell) |
|
827 |
{
|
|
828 |
int i; |
|
829 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
830 |
update_screen_layout (si); |
831 |
||
832 |
/* Check to see whether fading is ever possible -- if any of the
|
|
833 |
screens on the display has a PseudoColor visual, then fading can
|
|
834 |
work (on at least some screens.) If no screen has a PseudoColor
|
|
835 |
visual, then don't bother ever trying to fade, because it will
|
|
836 |
just cause a delay without causing any visible effect.
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
837 |
*/
|
1
by Karl Ramm
Import upstream version 3.34 |
838 |
for (i = 0; i < si->nscreens; i++) |
839 |
{
|
|
840 |
saver_screen_info *ssi = &si->screens[i]; |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
841 |
if (has_writable_cells (ssi->screen, ssi->current_visual) || |
842 |
get_visual (ssi->screen, "PseudoColor", True, False) || |
|
843 |
get_visual (ssi->screen, "GrayScale", True, False)) |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
844 |
{
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
845 |
si->fading_possible_p = True; |
846 |
break; |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
847 |
}
|
1
by Karl Ramm
Import upstream version 3.34 |
848 |
}
|
849 |
||
850 |
#ifdef HAVE_XF86VMODE_GAMMA
|
|
851 |
si->fading_possible_p = True; /* if we can gamma fade, go for it */ |
|
852 |
#endif
|
|
853 |
}
|
|
854 |
||
855 |
||
856 |
/* If any server extensions have been requested, try and initialize them.
|
|
857 |
Issue warnings if requests can't be honored.
|
|
858 |
*/
|
|
859 |
static void |
|
860 |
initialize_server_extensions (saver_info *si) |
|
861 |
{
|
|
862 |
saver_preferences *p = &si->prefs; |
|
863 |
||
864 |
Bool server_has_xidle_extension_p = False; |
|
865 |
Bool server_has_sgi_saver_extension_p = False; |
|
866 |
Bool server_has_mit_saver_extension_p = False; |
|
867 |
Bool system_has_proc_interrupts_p = False; |
|
1.1.10
by Robert Ancell
Import upstream version 5.12 |
868 |
Bool server_has_xinput_extension_p = False; |
1
by Karl Ramm
Import upstream version 3.34 |
869 |
const char *piwhy = 0; |
870 |
||
871 |
si->using_xidle_extension = p->use_xidle_extension; |
|
872 |
si->using_sgi_saver_extension = p->use_sgi_saver_extension; |
|
873 |
si->using_mit_saver_extension = p->use_mit_saver_extension; |
|
874 |
si->using_proc_interrupts = p->use_proc_interrupts; |
|
1.1.10
by Robert Ancell
Import upstream version 5.12 |
875 |
si->using_xinput_extension = p->use_xinput_extension; |
1
by Karl Ramm
Import upstream version 3.34 |
876 |
|
877 |
#ifdef HAVE_XIDLE_EXTENSION
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
878 |
{
|
879 |
int ev, er; |
|
880 |
server_has_xidle_extension_p = XidleQueryExtension (si->dpy, &ev, &er); |
|
881 |
}
|
|
1
by Karl Ramm
Import upstream version 3.34 |
882 |
#endif
|
883 |
#ifdef HAVE_SGI_SAVER_EXTENSION
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
884 |
server_has_sgi_saver_extension_p = |
885 |
XScreenSaverQueryExtension (si->dpy, |
|
886 |
&si->sgi_saver_ext_event_number, |
|
887 |
&si->sgi_saver_ext_error_number); |
|
1
by Karl Ramm
Import upstream version 3.34 |
888 |
#endif
|
889 |
#ifdef HAVE_MIT_SAVER_EXTENSION
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
890 |
server_has_mit_saver_extension_p = |
891 |
XScreenSaverQueryExtension (si->dpy, |
|
892 |
&si->mit_saver_ext_event_number, |
|
893 |
&si->mit_saver_ext_error_number); |
|
1
by Karl Ramm
Import upstream version 3.34 |
894 |
#endif
|
895 |
#ifdef HAVE_PROC_INTERRUPTS
|
|
896 |
system_has_proc_interrupts_p = query_proc_interrupts_available (si, &piwhy); |
|
897 |
#endif
|
|
898 |
||
1.1.10
by Robert Ancell
Import upstream version 5.12 |
899 |
#ifdef HAVE_XINPUT
|
900 |
server_has_xinput_extension_p = query_xinput_extension (si); |
|
901 |
#endif
|
|
902 |
||
1
by Karl Ramm
Import upstream version 3.34 |
903 |
if (!server_has_xidle_extension_p) |
904 |
si->using_xidle_extension = False; |
|
905 |
else if (p->verbose_p) |
|
906 |
{
|
|
907 |
if (si->using_xidle_extension) |
|
908 |
fprintf (stderr, "%s: using XIDLE extension.\n", blurb()); |
|
909 |
else
|
|
910 |
fprintf (stderr, "%s: not using server's XIDLE extension.\n", blurb()); |
|
911 |
}
|
|
912 |
||
913 |
if (!server_has_sgi_saver_extension_p) |
|
914 |
si->using_sgi_saver_extension = False; |
|
915 |
else if (p->verbose_p) |
|
916 |
{
|
|
917 |
if (si->using_sgi_saver_extension) |
|
918 |
fprintf (stderr, "%s: using SGI SCREEN_SAVER extension.\n", blurb()); |
|
919 |
else
|
|
920 |
fprintf (stderr, |
|
921 |
"%s: not using server's SGI SCREEN_SAVER extension.\n", |
|
922 |
blurb()); |
|
923 |
}
|
|
924 |
||
925 |
if (!server_has_mit_saver_extension_p) |
|
926 |
si->using_mit_saver_extension = False; |
|
927 |
else if (p->verbose_p) |
|
928 |
{
|
|
929 |
if (si->using_mit_saver_extension) |
|
930 |
fprintf (stderr, "%s: using lame MIT-SCREEN-SAVER extension.\n", |
|
931 |
blurb()); |
|
932 |
else
|
|
933 |
fprintf (stderr, |
|
934 |
"%s: not using server's lame MIT-SCREEN-SAVER extension.\n", |
|
935 |
blurb()); |
|
936 |
}
|
|
937 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
938 |
#ifdef HAVE_RANDR
|
939 |
if (XRRQueryExtension (si->dpy, |
|
940 |
&si->randr_event_number, &si->randr_error_number)) |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
941 |
{
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
942 |
int nscreens = ScreenCount (si->dpy); /* number of *real* screens */ |
943 |
int i; |
|
944 |
||
1.1.10
by Robert Ancell
Import upstream version 5.12 |
945 |
si->using_randr_extension = TRUE; |
946 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
947 |
if (p->verbose_p) |
1.1.6
by Ted Gould
Import upstream version 5.07 |
948 |
fprintf (stderr, "%s: selecting RANDR events\n", blurb()); |
949 |
for (i = 0; i < nscreens; i++) |
|
950 |
# ifdef RRScreenChangeNotifyMask /* randr.h 1.5, 2002/09/29 */ |
|
951 |
XRRSelectInput (si->dpy, RootWindow (si->dpy, i), |
|
952 |
RRScreenChangeNotifyMask); |
|
953 |
# else /* !RRScreenChangeNotifyMask */ /* Xrandr.h 1.4, 2001/06/07 */ |
|
954 |
XRRScreenChangeSelectInput (si->dpy, RootWindow (si->dpy, i), True); |
|
955 |
# endif /* !RRScreenChangeNotifyMask */ |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
956 |
}
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
957 |
# endif /* HAVE_RANDR */ |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
958 |
|
1.1.10
by Robert Ancell
Import upstream version 5.12 |
959 |
#ifdef HAVE_XINPUT
|
960 |
if (!server_has_xinput_extension_p) |
|
961 |
si->using_xinput_extension = False; |
|
962 |
else
|
|
963 |
{
|
|
964 |
if (si->using_xinput_extension) |
|
965 |
init_xinput_extension(si); |
|
966 |
||
967 |
if (p->verbose_p) |
|
968 |
{
|
|
969 |
if (si->using_xinput_extension) |
|
970 |
fprintf (stderr, |
|
971 |
"%s: selecting events from %d XInputExtension devices.\n", |
|
972 |
blurb(), si->num_xinput_devices); |
|
973 |
else
|
|
974 |
fprintf (stderr, |
|
975 |
"%s: not using XInputExtension.\n", |
|
976 |
blurb()); |
|
977 |
}
|
|
978 |
}
|
|
979 |
#endif
|
|
980 |
||
1
by Karl Ramm
Import upstream version 3.34 |
981 |
if (!system_has_proc_interrupts_p) |
982 |
{
|
|
983 |
si->using_proc_interrupts = False; |
|
984 |
if (p->verbose_p && piwhy) |
|
985 |
fprintf (stderr, "%s: not using /proc/interrupts: %s.\n", blurb(), |
|
986 |
piwhy); |
|
987 |
}
|
|
988 |
else if (p->verbose_p) |
|
989 |
{
|
|
990 |
if (si->using_proc_interrupts) |
|
991 |
fprintf (stderr, |
|
992 |
"%s: consulting /proc/interrupts for keyboard activity.\n", |
|
993 |
blurb()); |
|
994 |
else
|
|
995 |
fprintf (stderr, |
|
996 |
"%s: not consulting /proc/interrupts for keyboard activity.\n", |
|
997 |
blurb()); |
|
998 |
}
|
|
999 |
}
|
|
1000 |
||
1001 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
1002 |
#ifdef DEBUG_MULTISCREEN
|
1003 |
static void |
|
1004 |
debug_multiscreen_timer (XtPointer closure, XtIntervalId *id) |
|
1005 |
{
|
|
1006 |
saver_info *si = (saver_info *) closure; |
|
1007 |
saver_preferences *p = &si->prefs; |
|
1008 |
if (update_screen_layout (si)) |
|
1009 |
{
|
|
1010 |
if (p->verbose_p) |
|
1011 |
{
|
|
1012 |
fprintf (stderr, "%s: new layout:\n", blurb()); |
|
1013 |
describe_monitor_layout (si); |
|
1014 |
}
|
|
1015 |
resize_screensaver_window (si); |
|
1016 |
}
|
|
1017 |
XtAppAddTimeOut (si->app, 1000*4, debug_multiscreen_timer, (XtPointer) si); |
|
1018 |
}
|
|
1019 |
#endif /* DEBUG_MULTISCREEN */ |
|
1020 |
||
1021 |
||
1
by Karl Ramm
Import upstream version 3.34 |
1022 |
/* For the case where we aren't using an server extensions, select user events
|
1023 |
on all the existing windows, and launch timers to select events on
|
|
1024 |
newly-created windows as well.
|
|
1025 |
||
1026 |
If a server extension is being used, this does nothing.
|
|
1027 |
*/
|
|
1028 |
static void |
|
1029 |
select_events (saver_info *si) |
|
1030 |
{
|
|
1031 |
saver_preferences *p = &si->prefs; |
|
1032 |
int i; |
|
1033 |
||
1034 |
if (si->using_xidle_extension || |
|
1035 |
si->using_mit_saver_extension || |
|
1036 |
si->using_sgi_saver_extension) |
|
1037 |
return; |
|
1038 |
||
1039 |
if (p->initial_delay) |
|
1040 |
{
|
|
1041 |
if (p->verbose_p) |
|
1042 |
{
|
|
1043 |
fprintf (stderr, "%s: waiting for %d second%s...", blurb(), |
|
1044 |
(int) p->initial_delay/1000, |
|
1045 |
(p->initial_delay == 1000 ? "" : "s")); |
|
1046 |
fflush (stderr); |
|
1047 |
fflush (stdout); |
|
1048 |
}
|
|
1049 |
usleep (p->initial_delay); |
|
1050 |
if (p->verbose_p) |
|
1051 |
fprintf (stderr, " done.\n"); |
|
1052 |
}
|
|
1053 |
||
1054 |
if (p->verbose_p) |
|
1055 |
{
|
|
1056 |
fprintf (stderr, "%s: selecting events on extant windows...", blurb()); |
|
1057 |
fflush (stderr); |
|
1058 |
fflush (stdout); |
|
1059 |
}
|
|
1060 |
||
1061 |
/* Select events on the root windows of every screen. This also selects
|
|
1062 |
for window creation events, so that new subwindows will be noticed.
|
|
1063 |
*/
|
|
1064 |
for (i = 0; i < si->nscreens; i++) |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1065 |
{
|
1066 |
saver_screen_info *ssi = &si->screens[i]; |
|
1067 |
if (ssi->real_screen_p) |
|
1068 |
start_notice_events_timer (si, |
|
1069 |
RootWindowOfScreen (si->screens[i].screen), False); |
|
1070 |
}
|
|
1
by Karl Ramm
Import upstream version 3.34 |
1071 |
|
1072 |
if (p->verbose_p) |
|
1073 |
fprintf (stderr, " done.\n"); |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
1074 |
|
1075 |
# ifdef DEBUG_MULTISCREEN
|
|
1076 |
if (p->debug_p) debug_multiscreen_timer ((XtPointer) si, 0); |
|
1077 |
# endif
|
|
1
by Karl Ramm
Import upstream version 3.34 |
1078 |
}
|
1079 |
||
1080 |
||
1081 |
void
|
|
1082 |
maybe_reload_init_file (saver_info *si) |
|
1083 |
{
|
|
1084 |
saver_preferences *p = &si->prefs; |
|
1085 |
if (init_file_changed_p (p)) |
|
1086 |
{
|
|
1087 |
if (p->verbose_p) |
|
1088 |
fprintf (stderr, "%s: file \"%s\" has changed, reloading.\n", |
|
1089 |
blurb(), init_file_name()); |
|
1090 |
||
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
1091 |
load_init_file (si->dpy, p); |
1
by Karl Ramm
Import upstream version 3.34 |
1092 |
|
1093 |
/* If a server extension is in use, and p->timeout has changed,
|
|
1094 |
we need to inform the server of the new timeout. */
|
|
1095 |
disable_builtin_screensaver (si, False); |
|
1096 |
||
1097 |
/* If the DPMS settings in the init file have changed,
|
|
1098 |
change the settings on the server to match. */
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1099 |
sync_server_dpms_settings (si->dpy, |
1100 |
(p->dpms_enabled_p && |
|
1101 |
p->mode != DONT_BLANK), |
|
1
by Karl Ramm
Import upstream version 3.34 |
1102 |
p->dpms_standby / 1000, |
1103 |
p->dpms_suspend / 1000, |
|
1104 |
p->dpms_off / 1000, |
|
1105 |
False); |
|
1106 |
}
|
|
1107 |
}
|
|
1108 |
||
1109 |
||
1110 |
/* Loop forever:
|
|
1111 |
||
1112 |
- wait until the user is idle;
|
|
1113 |
- blank the screen;
|
|
1114 |
- wait until the user is active;
|
|
1115 |
- unblank the screen;
|
|
1116 |
- repeat.
|
|
1117 |
||
1118 |
*/
|
|
1119 |
static void |
|
1120 |
main_loop (saver_info *si) |
|
1121 |
{
|
|
1122 |
saver_preferences *p = &si->prefs; |
|
1123 |
Bool ok_to_unblank; |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
1124 |
int i; |
1
by Karl Ramm
Import upstream version 3.34 |
1125 |
|
1126 |
while (1) |
|
1127 |
{
|
|
1128 |
Bool was_locked = False; |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1129 |
|
1130 |
if (p->verbose_p) |
|
1131 |
fprintf (stderr, "%s: awaiting idleness.\n", blurb()); |
|
1132 |
||
1133 |
check_for_leaks ("unblanked A"); |
|
1
by Karl Ramm
Import upstream version 3.34 |
1134 |
sleep_until_idle (si, True); |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1135 |
check_for_leaks ("unblanked B"); |
1
by Karl Ramm
Import upstream version 3.34 |
1136 |
|
1137 |
if (p->verbose_p) |
|
1138 |
{
|
|
1139 |
if (si->demoing_p) |
|
1140 |
fprintf (stderr, "%s: demoing %d at %s.\n", blurb(), |
|
1141 |
si->selection_mode, timestring()); |
|
1142 |
else
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1143 |
fprintf (stderr, "%s: blanking screen at %s.\n", blurb(), |
1144 |
timestring()); |
|
1
by Karl Ramm
Import upstream version 3.34 |
1145 |
}
|
1146 |
||
1147 |
maybe_reload_init_file (si); |
|
1148 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1149 |
if (p->mode == DONT_BLANK) |
1150 |
{
|
|
1151 |
if (p->verbose_p) |
|
1152 |
fprintf (stderr, "%s: idle with blanking disabled at %s.\n", |
|
1153 |
blurb(), timestring()); |
|
1154 |
||
1155 |
/* Go around the loop and wait for the next bout of idleness,
|
|
1156 |
or for the init file to change, or for a remote command to
|
|
1157 |
come in, or something.
|
|
1158 |
||
1159 |
But, if locked_p is true, go ahead. This can only happen
|
|
1160 |
if we're in "disabled" mode but a "lock" clientmessage came
|
|
1161 |
in: in that case, we should go ahead and blank/lock the screen.
|
|
1162 |
*/
|
|
1163 |
if (!si->locked_p) |
|
1164 |
continue; |
|
1165 |
}
|
|
1166 |
||
1167 |
/* Since we're about to blank the screen, kill the de-race timer,
|
|
1168 |
if any. It might still be running if we have unblanked and then
|
|
1169 |
re-blanked in a short period (e.g., when using the "next" button
|
|
1170 |
in xscreensaver-demo.)
|
|
1171 |
*/
|
|
1172 |
if (si->de_race_id) |
|
1173 |
{
|
|
1174 |
if (p->verbose_p) |
|
1175 |
fprintf (stderr, "%s: stopping de-race timer (%d remaining.)\n", |
|
1176 |
blurb(), si->de_race_ticks); |
|
1177 |
XtRemoveTimeOut (si->de_race_id); |
|
1178 |
si->de_race_id = 0; |
|
1179 |
}
|
|
1180 |
||
1181 |
||
1182 |
/* Now, try to blank.
|
|
1183 |
*/
|
|
1184 |
||
1
by Karl Ramm
Import upstream version 3.34 |
1185 |
if (! blank_screen (si)) |
1186 |
{
|
|
1187 |
/* We were unable to grab either the keyboard or mouse.
|
|
1188 |
This means we did not (and must not) blank the screen.
|
|
1189 |
If we were to blank the screen while some other program
|
|
1190 |
is holding both the mouse and keyboard grabbed, then
|
|
1191 |
we would never be able to un-blank it! We would never
|
|
1192 |
see any events, and the display would be wedged.
|
|
1193 |
||
1194 |
So, just go around the loop again and wait for the
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1195 |
next bout of idleness. (If the user remains idle, we
|
1196 |
will next try to blank the screen again in no more than
|
|
1197 |
60 seconds.)
|
|
1
by Karl Ramm
Import upstream version 3.34 |
1198 |
*/
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1199 |
Time retry = 60 * 1000; |
1200 |
if (p->timeout < retry) |
|
1201 |
retry = p->timeout; |
|
1
by Karl Ramm
Import upstream version 3.34 |
1202 |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1203 |
if (p->debug_p) |
1204 |
{
|
|
1205 |
fprintf (stderr, |
|
1206 |
"%s: DEBUG MODE: unable to grab -- BLANKING ANYWAY.\n", |
|
1207 |
blurb()); |
|
1208 |
}
|
|
1209 |
else
|
|
1210 |
{
|
|
1211 |
fprintf (stderr, |
|
1
by Karl Ramm
Import upstream version 3.34 |
1212 |
"%s: unable to grab keyboard or mouse! Blanking aborted.\n", |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1213 |
blurb()); |
1214 |
||
1215 |
schedule_wakeup_event (si, retry, p->debug_p); |
|
1216 |
continue; |
|
1217 |
}
|
|
1
by Karl Ramm
Import upstream version 3.34 |
1218 |
}
|
1219 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
1220 |
for (i = 0; i < si->nscreens; i++) |
1221 |
kill_screenhack (&si->screens[i]); |
|
1
by Karl Ramm
Import upstream version 3.34 |
1222 |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
1223 |
raise_window (si, True, True, False); |
1224 |
if (si->throttled_p) |
|
1
by Karl Ramm
Import upstream version 3.34 |
1225 |
fprintf (stderr, "%s: not launching hack (throttled.)\n", blurb()); |
1.1.6
by Ted Gould
Import upstream version 5.07 |
1226 |
else
|
1227 |
for (i = 0; i < si->nscreens; i++) |
|
1228 |
spawn_screenhack (&si->screens[i]); |
|
1
by Karl Ramm
Import upstream version 3.34 |
1229 |
|
1.2.4
by Jose Luis Rivas
Import upstream version 5.14 |
1230 |
/* If we are blanking only, optionally power down monitor right now.
|
1231 |
To do this, we might need to temporarily re-enable DPMS first.
|
|
1232 |
*/
|
|
1233 |
if (p->mode == BLANK_ONLY && |
|
1234 |
p->dpms_enabled_p && |
|
1235 |
p->dpms_quickoff_p) |
|
1236 |
{
|
|
1237 |
sync_server_dpms_settings (si->dpy, True, |
|
1238 |
p->dpms_standby / 1000, |
|
1239 |
p->dpms_suspend / 1000, |
|
1240 |
(p->dpms_off |
|
1241 |
? (p->dpms_off / 1000) |
|
1242 |
: 0xFFFF), |
|
1243 |
False); |
|
1244 |
monitor_power_on (si, False); |
|
1245 |
}
|
|
1.2.3
by Tormod Volden
Import upstream version 5.13 |
1246 |
|
1
by Karl Ramm
Import upstream version 3.34 |
1247 |
/* Don't start the cycle timer in demo mode. */
|
1248 |
if (!si->demoing_p && p->cycle) |
|
1249 |
si->cycle_id = XtAppAddTimeOut (si->app, |
|
1250 |
(si->selection_mode |
|
1251 |
/* see comment in cycle_timer() */
|
|
1252 |
? 1000 * 60 * 60 |
|
1253 |
: p->cycle), |
|
1254 |
cycle_timer, |
|
1255 |
(XtPointer) si); |
|
1256 |
||
1257 |
||
1258 |
#ifndef NO_LOCKING
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1259 |
/* Maybe start locking the screen.
|
1260 |
*/
|
|
1
by Karl Ramm
Import upstream version 3.34 |
1261 |
{
|
1262 |
Time lock_timeout = p->lock_timeout; |
|
1263 |
||
1264 |
if (si->emergency_lock_p && p->lock_p && lock_timeout) |
|
1265 |
{
|
|
1266 |
int secs = p->lock_timeout / 1000; |
|
1267 |
if (p->verbose_p) |
|
1268 |
fprintf (stderr, |
|
1269 |
"%s: locking now, instead of waiting for %d:%02d:%02d.\n", |
|
1270 |
blurb(), |
|
1271 |
(secs / (60 * 60)), ((secs / 60) % 60), (secs % 60)); |
|
1272 |
lock_timeout = 0; |
|
1273 |
}
|
|
1274 |
||
1275 |
si->emergency_lock_p = False; |
|
1276 |
||
1277 |
if (!si->demoing_p && /* if not going into demo mode */ |
|
1278 |
p->lock_p && /* and locking is enabled */ |
|
1279 |
!si->locking_disabled_p && /* and locking is possible */ |
|
1280 |
lock_timeout == 0) /* and locking is not timer-deferred */ |
|
1281 |
set_locked_p (si, True); /* then lock right now. */ |
|
1282 |
||
1283 |
/* locked_p might be true already because of the above, or because of
|
|
1284 |
the LOCK ClientMessage. But if not, and if we're supposed to lock
|
|
1285 |
after some time, set up a timer to do so.
|
|
1286 |
*/
|
|
1287 |
if (p->lock_p && |
|
1288 |
!si->locked_p && |
|
1289 |
lock_timeout > 0) |
|
1290 |
si->lock_id = XtAppAddTimeOut (si->app, lock_timeout, |
|
1291 |
activate_lock_timer, |
|
1292 |
(XtPointer) si); |
|
1293 |
}
|
|
1294 |
#endif /* !NO_LOCKING */ |
|
1295 |
||
1296 |
||
1297 |
ok_to_unblank = True; |
|
1298 |
do { |
|
1299 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1300 |
check_for_leaks ("blanked A"); |
1
by Karl Ramm
Import upstream version 3.34 |
1301 |
sleep_until_idle (si, False); /* until not idle */ |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1302 |
check_for_leaks ("blanked B"); |
1303 |
||
1
by Karl Ramm
Import upstream version 3.34 |
1304 |
maybe_reload_init_file (si); |
1305 |
||
1306 |
#ifndef NO_LOCKING
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1307 |
/* Maybe unlock the screen.
|
1308 |
*/
|
|
1
by Karl Ramm
Import upstream version 3.34 |
1309 |
if (si->locked_p) |
1310 |
{
|
|
1311 |
saver_screen_info *ssi = si->default_screen; |
|
1312 |
if (si->locking_disabled_p) abort (); |
|
1313 |
||
1314 |
was_locked = True; |
|
1315 |
si->dbox_up_p = True; |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
1316 |
for (i = 0; i < si->nscreens; i++) |
1317 |
suspend_screenhack (&si->screens[i], True); /* suspend */ |
|
1
by Karl Ramm
Import upstream version 3.34 |
1318 |
XUndefineCursor (si->dpy, ssi->screensaver_window); |
1319 |
||
1320 |
ok_to_unblank = unlock_p (si); |
|
1321 |
||
1322 |
si->dbox_up_p = False; |
|
1323 |
XDefineCursor (si->dpy, ssi->screensaver_window, ssi->cursor); |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
1324 |
for (i = 0; i < si->nscreens; i++) |
1325 |
suspend_screenhack (&si->screens[i], False); /* resume */ |
|
1
by Karl Ramm
Import upstream version 3.34 |
1326 |
|
1327 |
if (!ok_to_unblank && |
|
1328 |
!screenhack_running_p (si)) |
|
1329 |
{
|
|
1330 |
/* If the lock dialog has been dismissed and we're not about to
|
|
1331 |
unlock the screen, and there is currently no hack running,
|
|
1332 |
then launch one. (There might be no hack running if DPMS
|
|
1333 |
had kicked in. But DPMS is off now, so bring back the hack)
|
|
1334 |
*/
|
|
1335 |
if (si->cycle_id) |
|
1336 |
XtRemoveTimeOut (si->cycle_id); |
|
1337 |
si->cycle_id = 0; |
|
1338 |
cycle_timer ((XtPointer) si, 0); |
|
1339 |
}
|
|
1340 |
}
|
|
1341 |
#endif /* !NO_LOCKING */ |
|
1342 |
||
1343 |
} while (!ok_to_unblank); |
|
1344 |
||
1345 |
||
1346 |
if (p->verbose_p) |
|
1347 |
fprintf (stderr, "%s: unblanking screen at %s.\n", |
|
1348 |
blurb(), timestring ()); |
|
1349 |
||
1350 |
/* Kill before unblanking, to stop drawing as soon as possible. */
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
1351 |
for (i = 0; i < si->nscreens; i++) |
1352 |
kill_screenhack (&si->screens[i]); |
|
1
by Karl Ramm
Import upstream version 3.34 |
1353 |
unblank_screen (si); |
1354 |
||
1355 |
set_locked_p (si, False); |
|
1356 |
si->emergency_lock_p = False; |
|
1357 |
si->demoing_p = 0; |
|
1358 |
si->selection_mode = 0; |
|
1359 |
||
1360 |
/* If we're throttled, and the user has explicitly unlocked the screen,
|
|
1361 |
then unthrottle. If we weren't locked, then don't unthrottle
|
|
1362 |
automatically, because someone might have just bumped the desk... */
|
|
1363 |
if (was_locked) |
|
1364 |
{
|
|
1365 |
if (si->throttled_p && p->verbose_p) |
|
1366 |
fprintf (stderr, "%s: unthrottled.\n", blurb()); |
|
1367 |
si->throttled_p = False; |
|
1368 |
}
|
|
1369 |
||
1370 |
if (si->cycle_id) |
|
1371 |
{
|
|
1372 |
XtRemoveTimeOut (si->cycle_id); |
|
1373 |
si->cycle_id = 0; |
|
1374 |
}
|
|
1375 |
||
1376 |
if (si->lock_id) |
|
1377 |
{
|
|
1378 |
XtRemoveTimeOut (si->lock_id); |
|
1379 |
si->lock_id = 0; |
|
1380 |
}
|
|
1381 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1382 |
/* Since we're unblanked now, break race conditions and make
|
1383 |
sure we stay that way (see comment in timers.c.) */
|
|
1384 |
if (! si->de_race_id) |
|
1385 |
de_race_timer ((XtPointer) si, 0); |
|
1
by Karl Ramm
Import upstream version 3.34 |
1386 |
}
|
1387 |
}
|
|
1388 |
||
1389 |
static void analyze_display (saver_info *si); |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1390 |
static void fix_fds (void); |
1
by Karl Ramm
Import upstream version 3.34 |
1391 |
|
1392 |
int
|
|
1393 |
main (int argc, char **argv) |
|
1394 |
{
|
|
1395 |
Widget shell; |
|
1396 |
saver_info the_si; |
|
1397 |
saver_info *si = &the_si; |
|
1398 |
saver_preferences *p = &si->prefs; |
|
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
1399 |
struct passwd *spasswd; |
1
by Karl Ramm
Import upstream version 3.34 |
1400 |
int i; |
1401 |
||
43
by Mathieu Trudel-Lapierre
* Merge with Debian testing, remaining Ubuntu changes: |
1402 |
/* It turns out that if we do setlocale (LC_ALL, "") here, people
|
1403 |
running in Japanese locales get font craziness on the password
|
|
1404 |
dialog, presumably because it is displaying Japanese characters
|
|
1405 |
in a non-Japanese font. However, if we don't call setlocale()
|
|
1406 |
at all, then XLookupString() never returns multi-byte UTF-8
|
|
1407 |
characters when people type non-Latin1 characters on the
|
|
1408 |
keyboard.
|
|
1409 |
||
1410 |
The current theory (and at this point, I'm really guessing!) is
|
|
1411 |
that using LC_CTYPE instead of LC_ALL will make XLookupString()
|
|
1412 |
behave usefully, without having the side-effect of screwing up
|
|
1413 |
the fonts on the unlock dialog.
|
|
1414 |
||
1415 |
See https://bugs.launchpad.net/ubuntu/+source/xscreensaver/+bug/671923
|
|
1416 |
from comment #20 onward.
|
|
1417 |
||
1418 |
-- jwz, 24-Sep-2011
|
|
1.2.3
by Tormod Volden
Import upstream version 5.13 |
1419 |
*/
|
1.1.10
by Robert Ancell
Import upstream version 5.12 |
1420 |
#ifdef ENABLE_NLS
|
43
by Mathieu Trudel-Lapierre
* Merge with Debian testing, remaining Ubuntu changes: |
1421 |
if (!setlocale (LC_CTYPE, "")) |
1422 |
fprintf (stderr, "%s: warning: could not set default locale\n", |
|
1423 |
progname); |
|
1.1.10
by Robert Ancell
Import upstream version 5.12 |
1424 |
|
1425 |
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); |
|
1426 |
textdomain (GETTEXT_PACKAGE); |
|
1427 |
#endif /* ENABLE_NLS */ |
|
1428 |
||
1
by Karl Ramm
Import upstream version 3.34 |
1429 |
memset(si, 0, sizeof(*si)); |
1430 |
global_si_kludge = si; /* I hate C so much... */ |
|
1431 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1432 |
fix_fds(); |
1433 |
||
1
by Karl Ramm
Import upstream version 3.34 |
1434 |
# undef ya_rand_init
|
1435 |
ya_rand_init (0); |
|
1436 |
||
1437 |
save_argv (argc, argv); |
|
1438 |
set_version_string (si, &argc, argv); |
|
1439 |
privileged_initialization (si, &argc, argv); |
|
1440 |
hack_environment (si); |
|
1441 |
||
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
1442 |
spasswd = getpwuid(getuid()); |
1443 |
if (!spasswd) |
|
1444 |
{
|
|
1445 |
fprintf(stderr, "Could not figure out who the current user is!\n"); |
|
1446 |
return 1; |
|
1447 |
}
|
|
1448 |
||
1449 |
si->user = strdup(spasswd->pw_name ? spasswd->pw_name : "(unknown)"); |
|
1450 |
||
1451 |
# ifndef NO_LOCKING
|
|
1452 |
si->unlock_cb = gui_auth_conv; |
|
1453 |
si->auth_finished_cb = auth_finished_cb; |
|
1454 |
# endif /* !NO_LOCKING */ |
|
1455 |
||
1
by Karl Ramm
Import upstream version 3.34 |
1456 |
shell = connect_to_server (si, &argc, argv); |
1457 |
process_command_line (si, &argc, argv); |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
1458 |
stderr_log_file (si); |
1
by Karl Ramm
Import upstream version 3.34 |
1459 |
print_banner (si); |
1460 |
||
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
1461 |
load_init_file(si->dpy, p); /* must be before initialize_per_screen_info() */ |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1462 |
blurb_timestamp_p = p->timestamp_p; /* kludge */ |
1
by Karl Ramm
Import upstream version 3.34 |
1463 |
initialize_per_screen_info (si, shell); /* also sets si->fading_possible_p */ |
1464 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1465 |
/* We can only issue this warning now. */
|
1
by Karl Ramm
Import upstream version 3.34 |
1466 |
if (p->verbose_p && !si->fading_possible_p && (p->fade_p || p->unfade_p)) |
1467 |
fprintf (stderr, |
|
1468 |
"%s: there are no PseudoColor or GrayScale visuals.\n" |
|
1469 |
"%s: ignoring the request for fading/unfading.\n", |
|
1470 |
blurb(), blurb()); |
|
1471 |
||
1472 |
for (i = 0; i < si->nscreens; i++) |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1473 |
{
|
1474 |
saver_screen_info *ssi = &si->screens[i]; |
|
1475 |
if (ssi->real_screen_p) |
|
1476 |
if (ensure_no_screensaver_running (si->dpy, si->screens[i].screen)) |
|
1477 |
exit (1); |
|
1478 |
}
|
|
1
by Karl Ramm
Import upstream version 3.34 |
1479 |
|
1480 |
lock_initialization (si, &argc, argv); |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1481 |
print_lock_failure_banner (si); |
1
by Karl Ramm
Import upstream version 3.34 |
1482 |
|
1483 |
if (p->xsync_p) XSynchronize (si->dpy, True); |
|
1484 |
||
1485 |
if (p->verbose_p) analyze_display (si); |
|
1486 |
initialize_server_extensions (si); |
|
1487 |
||
1488 |
si->blank_time = time ((time_t) 0); /* must be before ..._window */ |
|
1489 |
initialize_screensaver_window (si); |
|
1490 |
||
1491 |
select_events (si); |
|
1492 |
init_sigchld (); |
|
1493 |
||
1494 |
disable_builtin_screensaver (si, True); |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1495 |
sync_server_dpms_settings (si->dpy, |
1496 |
(p->dpms_enabled_p && |
|
1497 |
p->mode != DONT_BLANK), |
|
1
by Karl Ramm
Import upstream version 3.34 |
1498 |
p->dpms_standby / 1000, |
1499 |
p->dpms_suspend / 1000, |
|
1500 |
p->dpms_off / 1000, |
|
1501 |
False); |
|
1502 |
||
1503 |
initialize_stderr (si); |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1504 |
handle_signals (si); |
1
by Karl Ramm
Import upstream version 3.34 |
1505 |
|
1506 |
make_splash_dialog (si); |
|
1507 |
||
1508 |
main_loop (si); /* doesn't return */ |
|
1509 |
return 0; |
|
1510 |
}
|
|
1511 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1512 |
static void |
1513 |
fix_fds (void) |
|
1514 |
{
|
|
1515 |
/* Bad Things Happen if stdin, stdout, and stderr have been closed
|
|
1516 |
(as by the `sh incantation "xscreensaver >&- 2>&-"). When you do
|
|
1517 |
that, the X connection gets allocated to one of these fds, and
|
|
1518 |
then some random library writes to stderr, and random bits get
|
|
1519 |
stuffed down the X pipe, causing "Xlib: sequence lost" errors.
|
|
1520 |
So, we cause the first three file descriptors to be open to
|
|
1521 |
/dev/null if they aren't open to something else already. This
|
|
1522 |
must be done before any other files are opened (or the closing
|
|
1523 |
of that other file will again free up one of the "magic" first
|
|
1524 |
three FDs.)
|
|
1525 |
||
1526 |
We do this by opening /dev/null three times, and then closing
|
|
1527 |
those fds, *unless* any of them got allocated as #0, #1, or #2,
|
|
1528 |
in which case we leave them open. Gag.
|
|
1529 |
||
1530 |
Really, this crap is technically required of *every* X program,
|
|
1531 |
if you want it to be robust in the face of "2>&-".
|
|
1532 |
*/
|
|
1533 |
int fd0 = open ("/dev/null", O_RDWR); |
|
1534 |
int fd1 = open ("/dev/null", O_RDWR); |
|
1535 |
int fd2 = open ("/dev/null", O_RDWR); |
|
1536 |
if (fd0 > 2) close (fd0); |
|
1537 |
if (fd1 > 2) close (fd1); |
|
1538 |
if (fd2 > 2) close (fd2); |
|
1539 |
}
|
|
1540 |
||
1541 |
||
1
by Karl Ramm
Import upstream version 3.34 |
1542 |
|
1543 |
/* Processing ClientMessage events.
|
|
1544 |
*/
|
|
1545 |
||
1546 |
||
1547 |
static Bool error_handler_hit_p = False; |
|
1548 |
||
1549 |
static int |
|
1550 |
ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) |
|
1551 |
{
|
|
1552 |
error_handler_hit_p = True; |
|
1553 |
return 0; |
|
1554 |
}
|
|
1555 |
||
1556 |
/* Sometimes some systems send us ClientMessage events with bogus atoms in
|
|
1557 |
them. We only look up the atom names for printing warning messages,
|
|
1558 |
so don't bomb out when it happens...
|
|
1559 |
*/
|
|
1560 |
static char * |
|
1561 |
XGetAtomName_safe (Display *dpy, Atom atom) |
|
1562 |
{
|
|
1563 |
char *result; |
|
1564 |
XErrorHandler old_handler; |
|
1565 |
if (!atom) return 0; |
|
1566 |
||
1567 |
XSync (dpy, False); |
|
1568 |
error_handler_hit_p = False; |
|
1569 |
old_handler = XSetErrorHandler (ignore_all_errors_ehandler); |
|
1570 |
result = XGetAtomName (dpy, atom); |
|
1571 |
XSync (dpy, False); |
|
1572 |
XSetErrorHandler (old_handler); |
|
1573 |
XSync (dpy, False); |
|
1574 |
if (error_handler_hit_p) result = 0; |
|
1575 |
||
1576 |
if (result) |
|
1577 |
return result; |
|
1578 |
else
|
|
1579 |
{
|
|
1580 |
char buf[100]; |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1581 |
sprintf (buf, "<<undefined atom 0x%04X>>", (unsigned int) atom); |
1
by Karl Ramm
Import upstream version 3.34 |
1582 |
return strdup (buf); |
1583 |
}
|
|
1584 |
}
|
|
1585 |
||
1586 |
||
1587 |
static void |
|
1588 |
clientmessage_response (saver_info *si, Window w, Bool error, |
|
1589 |
const char *stderr_msg, |
|
1590 |
const char *protocol_msg) |
|
1591 |
{
|
|
1592 |
char *proto; |
|
1593 |
int L; |
|
1594 |
saver_preferences *p = &si->prefs; |
|
1595 |
XErrorHandler old_handler; |
|
1596 |
||
1597 |
if (error || p->verbose_p) |
|
1598 |
fprintf (stderr, "%s: %s\n", blurb(), stderr_msg); |
|
1599 |
||
1600 |
L = strlen(protocol_msg); |
|
1601 |
proto = (char *) malloc (L + 2); |
|
1602 |
proto[0] = (error ? '-' : '+'); |
|
1603 |
strcpy (proto+1, protocol_msg); |
|
1604 |
L++; |
|
1605 |
||
1606 |
/* Ignore all X errors while sending a response to a ClientMessage.
|
|
1607 |
Pretty much the only way we could get an error here is if the
|
|
1608 |
window we're trying to send the reply on has been deleted, in
|
|
1609 |
which case, the sender of the ClientMessage won't see our response
|
|
1610 |
anyway.
|
|
1611 |
*/
|
|
1612 |
XSync (si->dpy, False); |
|
1613 |
error_handler_hit_p = False; |
|
1614 |
old_handler = XSetErrorHandler (ignore_all_errors_ehandler); |
|
1615 |
||
1616 |
XChangeProperty (si->dpy, w, XA_SCREENSAVER_RESPONSE, XA_STRING, 8, |
|
1617 |
PropModeReplace, (unsigned char *) proto, L); |
|
1618 |
||
1619 |
XSync (si->dpy, False); |
|
1620 |
XSetErrorHandler (old_handler); |
|
1621 |
XSync (si->dpy, False); |
|
1622 |
||
1623 |
free (proto); |
|
1624 |
}
|
|
1625 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1626 |
|
1627 |
static void |
|
1628 |
bogus_clientmessage_warning (saver_info *si, XEvent *event) |
|
1629 |
{
|
|
1.1.5
by Ted Gould
Import upstream version 5.05 |
1630 |
#if 0 /* Oh, fuck it. GNOME likes to spew random ClientMessages at us |
1631 |
all the time. This is presumably indicative of an error in
|
|
1632 |
the sender of that ClientMessage: if we're getting it and
|
|
1633 |
ignoring it, then it's not reaching the intended recipient.
|
|
1634 |
But people complain to me about this all the time ("waaah!
|
|
1635 |
xscreensaver is printing to it's stderr and that gets my
|
|
1636 |
panties all in a bunch!") And I'm sick of hearing about it.
|
|
1637 |
So we'll just ignore these messages and let GNOME go right
|
|
1638 |
ahead and continue to stumble along in its malfunction.
|
|
1639 |
*/
|
|
1640 |
||
1.1.2
by Adam Conrad
Import upstream version 4.23 |
1641 |
saver_preferences *p = &si->prefs;
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1642 |
char *str = XGetAtomName_safe (si->dpy, event->xclient.message_type);
|
1643 |
Window w = event->xclient.window;
|
|
1644 |
char wdesc[255];
|
|
1645 |
int screen = 0;
|
|
1.1.2
by Adam Conrad
Import upstream version 4.23 |
1646 |
Bool root_p = False;
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1647 |
|
1648 |
*wdesc = 0;
|
|
1649 |
for (screen = 0; screen < si->nscreens; screen++)
|
|
1650 |
if (w == si->screens[screen].screensaver_window)
|
|
1651 |
{
|
|
1652 |
strcpy (wdesc, "xscreensaver");
|
|
1653 |
break;
|
|
1654 |
}
|
|
1655 |
else if (w == RootWindow (si->dpy, screen))
|
|
1656 |
{
|
|
1657 |
strcpy (wdesc, "root");
|
|
1.1.2
by Adam Conrad
Import upstream version 4.23 |
1658 |
root_p = True;
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1659 |
break;
|
1660 |
}
|
|
1661 |
||
1.1.2
by Adam Conrad
Import upstream version 4.23 |
1662 |
/* If this ClientMessage was sent to the real root window instead of to the
|
1663 |
xscreensaver window, then it might be intended for someone else who is
|
|
1664 |
listening on the root window (e.g., the window manager). So only print
|
|
1665 |
the warning if: we are in debug mode; or if the bogus message was
|
|
1666 |
actually sent to one of the xscreensaver-created windows.
|
|
1667 |
*/
|
|
1668 |
if (root_p && !p->debug_p)
|
|
1669 |
return;
|
|
1670 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1671 |
if (!*wdesc)
|
1672 |
{
|
|
1673 |
XErrorHandler old_handler;
|
|
1674 |
XClassHint hint;
|
|
1675 |
XWindowAttributes xgwa;
|
|
1676 |
memset (&hint, 0, sizeof(hint));
|
|
1677 |
memset (&xgwa, 0, sizeof(xgwa));
|
|
1678 |
||
1679 |
XSync (si->dpy, False);
|
|
1680 |
old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
|
|
1681 |
XGetClassHint (si->dpy, w, &hint);
|
|
1682 |
XGetWindowAttributes (si->dpy, w, &xgwa);
|
|
1683 |
XSync (si->dpy, False);
|
|
1684 |
XSetErrorHandler (old_handler);
|
|
1685 |
XSync (si->dpy, False);
|
|
1686 |
||
1687 |
screen = (xgwa.screen ? screen_number (xgwa.screen) : -1);
|
|
1688 |
||
1689 |
sprintf (wdesc, "%.20s / %.20s",
|
|
1690 |
(hint.res_name ? hint.res_name : "(null)"),
|
|
1691 |
(hint.res_class ? hint.res_class : "(null)"));
|
|
1692 |
if (hint.res_name) XFree (hint.res_name);
|
|
1693 |
if (hint.res_class) XFree (hint.res_class);
|
|
1694 |
}
|
|
1695 |
||
1696 |
fprintf (stderr, "%s: %d: unrecognised ClientMessage \"%s\" received\n",
|
|
1697 |
blurb(), screen, (str ? str : "(null)"));
|
|
1698 |
fprintf (stderr, "%s: %d: for window 0x%lx (%s)\n",
|
|
1699 |
blurb(), screen, (unsigned long) w, wdesc);
|
|
1700 |
if (str) XFree (str);
|
|
1.1.5
by Ted Gould
Import upstream version 5.05 |
1701 |
|
1702 |
#endif /* 0 */
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1703 |
}
|
1704 |
||
1.1.5
by Ted Gould
Import upstream version 5.05 |
1705 |
|
1
by Karl Ramm
Import upstream version 3.34 |
1706 |
Bool
|
1707 |
handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p) |
|
1708 |
{
|
|
1709 |
saver_preferences *p = &si->prefs; |
|
1710 |
Atom type = 0; |
|
1711 |
Window window = event->xclient.window; |
|
1712 |
||
1713 |
/* Preferences might affect our handling of client messages. */
|
|
1714 |
maybe_reload_init_file (si); |
|
1715 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1716 |
if (event->xclient.message_type != XA_SCREENSAVER || |
1717 |
event->xclient.format != 32) |
|
1718 |
{
|
|
1719 |
bogus_clientmessage_warning (si, event); |
|
1
by Karl Ramm
Import upstream version 3.34 |
1720 |
return False; |
1721 |
}
|
|
1722 |
||
1723 |
type = event->xclient.data.l[0]; |
|
1724 |
if (type == XA_ACTIVATE) |
|
1725 |
{
|
|
1726 |
if (until_idle_p) |
|
1727 |
{
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1728 |
if (p->mode == DONT_BLANK) |
1729 |
{
|
|
1730 |
clientmessage_response(si, window, True, |
|
1731 |
"ACTIVATE ClientMessage received in DONT_BLANK mode.", |
|
1732 |
"screen blanking is currently disabled."); |
|
1733 |
return False; |
|
1734 |
}
|
|
1735 |
||
1
by Karl Ramm
Import upstream version 3.34 |
1736 |
clientmessage_response(si, window, False, |
1737 |
"ACTIVATE ClientMessage received.", |
|
1738 |
"activating."); |
|
1739 |
si->selection_mode = 0; |
|
1740 |
si->demoing_p = False; |
|
1741 |
||
1742 |
if (si->throttled_p && p->verbose_p) |
|
1743 |
fprintf (stderr, "%s: unthrottled.\n", blurb()); |
|
1744 |
si->throttled_p = False; |
|
1745 |
||
1746 |
if (si->using_mit_saver_extension || si->using_sgi_saver_extension) |
|
1747 |
{
|
|
1748 |
XForceScreenSaver (si->dpy, ScreenSaverActive); |
|
1749 |
return False; |
|
1750 |
}
|
|
1751 |
else
|
|
1752 |
{
|
|
1753 |
return True; |
|
1754 |
}
|
|
1755 |
}
|
|
1756 |
clientmessage_response(si, window, True, |
|
1757 |
"ClientMessage ACTIVATE received while already active.", |
|
1758 |
"already active."); |
|
1759 |
}
|
|
1760 |
else if (type == XA_DEACTIVATE) |
|
1761 |
{
|
|
1762 |
if (! until_idle_p) |
|
1763 |
{
|
|
1764 |
if (si->throttled_p && p->verbose_p) |
|
1765 |
fprintf (stderr, "%s: unthrottled.\n", blurb()); |
|
1766 |
si->throttled_p = False; |
|
1767 |
||
1768 |
clientmessage_response(si, window, False, |
|
1769 |
"DEACTIVATE ClientMessage received.", |
|
1770 |
"deactivating."); |
|
1771 |
if (si->using_mit_saver_extension || si->using_sgi_saver_extension) |
|
1772 |
{
|
|
1773 |
XForceScreenSaver (si->dpy, ScreenSaverReset); |
|
1774 |
return False; |
|
1775 |
}
|
|
1776 |
else
|
|
1777 |
{
|
|
1778 |
return True; |
|
1779 |
}
|
|
1780 |
}
|
|
1781 |
clientmessage_response(si, window, False, |
|
1782 |
"ClientMessage DEACTIVATE received while inactive: resetting idle timer.", |
|
1783 |
"not active: idle timer reset."); |
|
1784 |
reset_timers (si); |
|
1785 |
}
|
|
1786 |
else if (type == XA_CYCLE) |
|
1787 |
{
|
|
1788 |
if (! until_idle_p) |
|
1789 |
{
|
|
1790 |
clientmessage_response(si, window, False, |
|
1791 |
"CYCLE ClientMessage received.", |
|
1792 |
"cycling."); |
|
1793 |
si->selection_mode = 0; /* 0 means randomize when its time. */ |
|
1794 |
si->demoing_p = False; |
|
1795 |
||
1796 |
if (si->throttled_p && p->verbose_p) |
|
1797 |
fprintf (stderr, "%s: unthrottled.\n", blurb()); |
|
1798 |
si->throttled_p = False; |
|
1799 |
||
1800 |
if (si->cycle_id) |
|
1801 |
XtRemoveTimeOut (si->cycle_id); |
|
1802 |
si->cycle_id = 0; |
|
1803 |
cycle_timer ((XtPointer) si, 0); |
|
1804 |
return False; |
|
1805 |
}
|
|
1806 |
clientmessage_response(si, window, True, |
|
1807 |
"ClientMessage CYCLE received while inactive.", |
|
1808 |
"not active."); |
|
1809 |
}
|
|
1810 |
else if (type == XA_NEXT || type == XA_PREV) |
|
1811 |
{
|
|
1812 |
clientmessage_response(si, window, False, |
|
1813 |
(type == XA_NEXT |
|
1814 |
? "NEXT ClientMessage received." |
|
1815 |
: "PREV ClientMessage received."), |
|
1816 |
"cycling."); |
|
1817 |
si->selection_mode = (type == XA_NEXT ? -1 : -2); |
|
1818 |
si->demoing_p = False; |
|
1819 |
||
1820 |
if (si->throttled_p && p->verbose_p) |
|
1821 |
fprintf (stderr, "%s: unthrottled.\n", blurb()); |
|
1822 |
si->throttled_p = False; |
|
1823 |
||
1824 |
if (! until_idle_p) |
|
1825 |
{
|
|
1826 |
if (si->cycle_id) |
|
1827 |
XtRemoveTimeOut (si->cycle_id); |
|
1828 |
si->cycle_id = 0; |
|
1829 |
cycle_timer ((XtPointer) si, 0); |
|
1830 |
}
|
|
1831 |
else
|
|
1832 |
return True; |
|
1833 |
}
|
|
1834 |
else if (type == XA_SELECT) |
|
1835 |
{
|
|
1836 |
char buf [255]; |
|
1837 |
char buf2 [255]; |
|
1838 |
long which = event->xclient.data.l[1]; |
|
1839 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1840 |
if (p->mode == DONT_BLANK) |
1841 |
{
|
|
1842 |
clientmessage_response(si, window, True, |
|
1843 |
"SELECT ClientMessage received in DONT_BLANK mode.", |
|
1844 |
"screen blanking is currently disabled."); |
|
1845 |
return False; |
|
1846 |
}
|
|
1847 |
||
1
by Karl Ramm
Import upstream version 3.34 |
1848 |
sprintf (buf, "SELECT %ld ClientMessage received.", which); |
1849 |
sprintf (buf2, "activating (%ld).", which); |
|
1850 |
clientmessage_response (si, window, False, buf, buf2); |
|
1851 |
||
1852 |
if (which < 0) which = 0; /* 0 == "random" */ |
|
1853 |
si->selection_mode = which; |
|
1854 |
si->demoing_p = False; |
|
1855 |
||
1856 |
if (si->throttled_p && p->verbose_p) |
|
1857 |
fprintf (stderr, "%s: unthrottled.\n", blurb()); |
|
1858 |
si->throttled_p = False; |
|
1859 |
||
1860 |
if (! until_idle_p) |
|
1861 |
{
|
|
1862 |
if (si->cycle_id) |
|
1863 |
XtRemoveTimeOut (si->cycle_id); |
|
1864 |
si->cycle_id = 0; |
|
1865 |
cycle_timer ((XtPointer) si, 0); |
|
1866 |
}
|
|
1867 |
else
|
|
1868 |
return True; |
|
1869 |
}
|
|
1870 |
else if (type == XA_EXIT) |
|
1871 |
{
|
|
1872 |
/* Ignore EXIT message if the screen is locked. */
|
|
1873 |
if (until_idle_p || !si->locked_p) |
|
1874 |
{
|
|
1875 |
clientmessage_response (si, window, False, |
|
1876 |
"EXIT ClientMessage received.", |
|
1877 |
"exiting."); |
|
1878 |
if (! until_idle_p) |
|
1879 |
{
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
1880 |
int i; |
1881 |
for (i = 0; i < si->nscreens; i++) |
|
1882 |
kill_screenhack (&si->screens[i]); |
|
1
by Karl Ramm
Import upstream version 3.34 |
1883 |
unblank_screen (si); |
1884 |
XSync (si->dpy, False); |
|
1885 |
}
|
|
1886 |
saver_exit (si, 0, 0); |
|
1887 |
}
|
|
1888 |
else
|
|
1889 |
clientmessage_response (si, window, True, |
|
1890 |
"EXIT ClientMessage received while locked.", |
|
1891 |
"screen is locked."); |
|
1892 |
}
|
|
1893 |
else if (type == XA_RESTART) |
|
1894 |
{
|
|
1895 |
/* The RESTART message works whether the screensaver is active or not,
|
|
1896 |
unless the screen is locked, in which case it doesn't work.
|
|
1897 |
*/
|
|
1898 |
if (until_idle_p || !si->locked_p) |
|
1899 |
{
|
|
1900 |
clientmessage_response (si, window, False, |
|
1901 |
"RESTART ClientMessage received.", |
|
1902 |
"restarting."); |
|
1903 |
if (! until_idle_p) |
|
1904 |
{
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
1905 |
int i; |
1906 |
for (i = 0; i < si->nscreens; i++) |
|
1907 |
kill_screenhack (&si->screens[i]); |
|
1
by Karl Ramm
Import upstream version 3.34 |
1908 |
unblank_screen (si); |
1909 |
XSync (si->dpy, False); |
|
1910 |
}
|
|
1911 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
1912 |
restart_process (si); /* does not return */ |
1913 |
abort(); |
|
1
by Karl Ramm
Import upstream version 3.34 |
1914 |
}
|
1915 |
else
|
|
1916 |
clientmessage_response (si, window, True, |
|
1917 |
"RESTART ClientMessage received while locked.", |
|
1918 |
"screen is locked."); |
|
1919 |
}
|
|
1920 |
else if (type == XA_DEMO) |
|
1921 |
{
|
|
1922 |
long arg = event->xclient.data.l[1]; |
|
1.1.4
by Oliver Grawert
Import upstream version 5.04 |
1923 |
Bool demo_one_hack_p = (arg == 5000); |
1
by Karl Ramm
Import upstream version 3.34 |
1924 |
|
1925 |
if (demo_one_hack_p) |
|
1926 |
{
|
|
1927 |
if (until_idle_p) |
|
1928 |
{
|
|
1929 |
long which = event->xclient.data.l[2]; |
|
1930 |
char buf [255]; |
|
1931 |
char buf2 [255]; |
|
1932 |
sprintf (buf, "DEMO %ld ClientMessage received.", which); |
|
1933 |
sprintf (buf2, "demoing (%ld).", which); |
|
1934 |
clientmessage_response (si, window, False, buf, buf2); |
|
1935 |
||
1936 |
if (which < 0) which = 0; /* 0 == "random" */ |
|
1937 |
si->selection_mode = which; |
|
1938 |
si->demoing_p = True; |
|
1939 |
||
1940 |
if (si->throttled_p && p->verbose_p) |
|
1941 |
fprintf (stderr, "%s: unthrottled.\n", blurb()); |
|
1942 |
si->throttled_p = False; |
|
1943 |
||
1944 |
return True; |
|
1945 |
}
|
|
1946 |
||
1947 |
clientmessage_response (si, window, True, |
|
1948 |
"DEMO ClientMessage received while active.", |
|
1949 |
"already active."); |
|
1950 |
}
|
|
1951 |
else
|
|
1952 |
{
|
|
1953 |
clientmessage_response (si, window, True, |
|
1954 |
"obsolete form of DEMO ClientMessage.", |
|
1955 |
"obsolete form of DEMO ClientMessage."); |
|
1956 |
}
|
|
1957 |
}
|
|
1958 |
else if (type == XA_PREFS) |
|
1959 |
{
|
|
1960 |
clientmessage_response (si, window, True, |
|
1961 |
"the PREFS client-message is obsolete.", |
|
1962 |
"the PREFS client-message is obsolete."); |
|
1963 |
}
|
|
1964 |
else if (type == XA_LOCK) |
|
1965 |
{
|
|
1966 |
#ifdef NO_LOCKING
|
|
1967 |
clientmessage_response (si, window, True, |
|
1968 |
"not compiled with support for locking.", |
|
1969 |
"locking not enabled."); |
|
1970 |
#else /* !NO_LOCKING */ |
|
1971 |
if (si->locking_disabled_p) |
|
1972 |
clientmessage_response (si, window, True, |
|
1973 |
"LOCK ClientMessage received, but locking is disabled.", |
|
1974 |
"locking not enabled."); |
|
1975 |
else if (si->locked_p) |
|
1976 |
clientmessage_response (si, window, True, |
|
1977 |
"LOCK ClientMessage received while already locked.", |
|
1978 |
"already locked."); |
|
1979 |
else
|
|
1980 |
{
|
|
1981 |
char buf [255]; |
|
1982 |
char *response = (until_idle_p |
|
1983 |
? "activating and locking." |
|
1984 |
: "locking."); |
|
1985 |
sprintf (buf, "LOCK ClientMessage received; %s", response); |
|
1986 |
clientmessage_response (si, window, False, buf, response); |
|
1987 |
set_locked_p (si, True); |
|
1988 |
si->selection_mode = 0; |
|
1989 |
si->demoing_p = False; |
|
1990 |
||
1991 |
if (si->lock_id) /* we're doing it now, so lose the timeout */ |
|
1992 |
{
|
|
1993 |
XtRemoveTimeOut (si->lock_id); |
|
1994 |
si->lock_id = 0; |
|
1995 |
}
|
|
1996 |
||
1997 |
if (until_idle_p) |
|
1998 |
{
|
|
1999 |
if (si->using_mit_saver_extension || |
|
2000 |
si->using_sgi_saver_extension) |
|
2001 |
{
|
|
2002 |
XForceScreenSaver (si->dpy, ScreenSaverActive); |
|
2003 |
return False; |
|
2004 |
}
|
|
2005 |
else
|
|
2006 |
{
|
|
2007 |
return True; |
|
2008 |
}
|
|
2009 |
}
|
|
2010 |
}
|
|
2011 |
#endif /* !NO_LOCKING */ |
|
2012 |
}
|
|
2013 |
else if (type == XA_THROTTLE) |
|
2014 |
{
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2015 |
/* The THROTTLE command is deprecated -- it predates the XDPMS
|
2016 |
extension. Instead of using -throttle, users should instead
|
|
2017 |
just power off the monitor (e.g., "xset dpms force off".)
|
|
2018 |
In a few minutes, xscreensaver will notice that the monitor
|
|
2019 |
is off, and cease running hacks.
|
|
2020 |
*/
|
|
1
by Karl Ramm
Import upstream version 3.34 |
2021 |
if (si->throttled_p) |
2022 |
clientmessage_response (si, window, True, |
|
2023 |
"THROTTLE ClientMessage received, but "
|
|
2024 |
"already throttled.", |
|
2025 |
"already throttled."); |
|
2026 |
else
|
|
2027 |
{
|
|
2028 |
char buf [255]; |
|
2029 |
char *response = "throttled."; |
|
2030 |
si->throttled_p = True; |
|
2031 |
si->selection_mode = 0; |
|
2032 |
si->demoing_p = False; |
|
2033 |
sprintf (buf, "THROTTLE ClientMessage received; %s", response); |
|
2034 |
clientmessage_response (si, window, False, buf, response); |
|
2035 |
||
2036 |
if (! until_idle_p) |
|
2037 |
{
|
|
2038 |
if (si->cycle_id) |
|
2039 |
XtRemoveTimeOut (si->cycle_id); |
|
2040 |
si->cycle_id = 0; |
|
2041 |
cycle_timer ((XtPointer) si, 0); |
|
2042 |
}
|
|
2043 |
}
|
|
2044 |
}
|
|
2045 |
else if (type == XA_UNTHROTTLE) |
|
2046 |
{
|
|
2047 |
if (! si->throttled_p) |
|
2048 |
clientmessage_response (si, window, True, |
|
2049 |
"UNTHROTTLE ClientMessage received, but "
|
|
2050 |
"not throttled.", |
|
2051 |
"not throttled."); |
|
2052 |
else
|
|
2053 |
{
|
|
2054 |
char buf [255]; |
|
2055 |
char *response = "unthrottled."; |
|
2056 |
si->throttled_p = False; |
|
2057 |
si->selection_mode = 0; |
|
2058 |
si->demoing_p = False; |
|
2059 |
sprintf (buf, "UNTHROTTLE ClientMessage received; %s", response); |
|
2060 |
clientmessage_response (si, window, False, buf, response); |
|
2061 |
||
2062 |
if (! until_idle_p) |
|
2063 |
{
|
|
2064 |
if (si->cycle_id) |
|
2065 |
XtRemoveTimeOut (si->cycle_id); |
|
2066 |
si->cycle_id = 0; |
|
2067 |
cycle_timer ((XtPointer) si, 0); |
|
2068 |
}
|
|
2069 |
}
|
|
2070 |
}
|
|
2071 |
else
|
|
2072 |
{
|
|
2073 |
char buf [1024]; |
|
2074 |
char *str; |
|
2075 |
str = XGetAtomName_safe (si->dpy, type); |
|
2076 |
||
2077 |
if (str) |
|
2078 |
{
|
|
2079 |
if (strlen (str) > 80) |
|
2080 |
strcpy (str+70, "..."); |
|
2081 |
sprintf (buf, "unrecognised screensaver ClientMessage %s received.", |
|
2082 |
str); |
|
2083 |
free (str); |
|
2084 |
}
|
|
2085 |
else
|
|
2086 |
{
|
|
2087 |
sprintf (buf, |
|
2088 |
"unrecognised screensaver ClientMessage 0x%x received.", |
|
2089 |
(unsigned int) event->xclient.data.l[0]); |
|
2090 |
}
|
|
2091 |
||
2092 |
clientmessage_response (si, window, True, buf, buf); |
|
2093 |
}
|
|
2094 |
return False; |
|
2095 |
}
|
|
2096 |
||
2097 |
||
2098 |
/* Some random diagnostics printed in -verbose mode.
|
|
2099 |
*/
|
|
2100 |
||
2101 |
static void |
|
2102 |
analyze_display (saver_info *si) |
|
2103 |
{
|
|
2104 |
int i, j; |
|
2105 |
static struct { |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2106 |
const char *name; const char *desc; |
2107 |
Bool useful_p; |
|
2108 |
Status (*version_fn) (Display *, int *majP, int *minP); |
|
1
by Karl Ramm
Import upstream version 3.34 |
2109 |
} exts[] = { |
2110 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2111 |
{ "SCREEN_SAVER", /* underscore */ "SGI Screen-Saver", |
1
by Karl Ramm
Import upstream version 3.34 |
2112 |
# ifdef HAVE_SGI_SAVER_EXTENSION
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2113 |
True, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2114 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2115 |
False, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2116 |
# endif
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2117 |
}, { "SCREEN-SAVER", /* dash */ "SGI Screen-Saver", |
1
by Karl Ramm
Import upstream version 3.34 |
2118 |
# ifdef HAVE_SGI_SAVER_EXTENSION
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2119 |
True, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2120 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2121 |
False, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2122 |
# endif
|
2123 |
}, { "MIT-SCREEN-SAVER", "MIT Screen-Saver", |
|
2124 |
# ifdef HAVE_MIT_SAVER_EXTENSION
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2125 |
True, XScreenSaverQueryVersion |
1
by Karl Ramm
Import upstream version 3.34 |
2126 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2127 |
False, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2128 |
# endif
|
2129 |
}, { "XIDLE", "XIdle", |
|
2130 |
# ifdef HAVE_XIDLE_EXTENSION
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2131 |
True, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2132 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2133 |
False, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2134 |
# endif
|
2135 |
}, { "SGI-VIDEO-CONTROL", "SGI Video-Control", |
|
2136 |
# ifdef HAVE_SGI_VC_EXTENSION
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2137 |
True, XSGIvcQueryVersion |
1
by Karl Ramm
Import upstream version 3.34 |
2138 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2139 |
False, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2140 |
# endif
|
2141 |
}, { "READDISPLAY", "SGI Read-Display", |
|
2142 |
# ifdef HAVE_READ_DISPLAY_EXTENSION
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2143 |
True, XReadDisplayQueryVersion |
1
by Karl Ramm
Import upstream version 3.34 |
2144 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2145 |
False, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2146 |
# endif
|
2147 |
}, { "MIT-SHM", "Shared Memory", |
|
2148 |
# ifdef HAVE_XSHM_EXTENSION
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2149 |
True, (Status (*) (Display*,int*,int*)) XShmQueryVersion /* 4 args */ |
1
by Karl Ramm
Import upstream version 3.34 |
2150 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2151 |
False, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2152 |
# endif
|
2153 |
}, { "DOUBLE-BUFFER", "Double-Buffering", |
|
2154 |
# ifdef HAVE_DOUBLE_BUFFER_EXTENSION
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2155 |
True, XdbeQueryExtension |
1
by Karl Ramm
Import upstream version 3.34 |
2156 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2157 |
False, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2158 |
# endif
|
2159 |
}, { "DPMS", "Power Management", |
|
2160 |
# ifdef HAVE_DPMS_EXTENSION
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2161 |
True, DPMSGetVersion |
1
by Karl Ramm
Import upstream version 3.34 |
2162 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2163 |
False, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2164 |
# endif
|
2165 |
}, { "GLX", "GLX", |
|
2166 |
# ifdef HAVE_GL
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2167 |
True, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2168 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2169 |
False, 0 |
1
by Karl Ramm
Import upstream version 3.34 |
2170 |
# endif
|
2171 |
}, { "XFree86-VidModeExtension", "XF86 Video-Mode", |
|
2172 |
# ifdef HAVE_XF86VMODE
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2173 |
True, XF86VidModeQueryVersion |
2174 |
# else
|
|
2175 |
False, 0 |
|
2176 |
# endif
|
|
2177 |
}, { "XC-VidModeExtension", "XC Video-Mode", |
|
2178 |
# ifdef HAVE_XF86VMODE
|
|
2179 |
True, XF86VidModeQueryVersion |
|
2180 |
# else
|
|
2181 |
False, 0 |
|
2182 |
# endif
|
|
2183 |
}, { "XFree86-MISC", "XF86 Misc", |
|
2184 |
# ifdef HAVE_XF86MISCSETGRABKEYSSTATE
|
|
2185 |
True, XF86MiscQueryVersion |
|
2186 |
# else
|
|
2187 |
False, 0 |
|
2188 |
# endif
|
|
2189 |
}, { "XC-MISC", "XC Misc", |
|
2190 |
# ifdef HAVE_XF86MISCSETGRABKEYSSTATE
|
|
2191 |
True, XF86MiscQueryVersion |
|
2192 |
# else
|
|
2193 |
False, 0 |
|
1
by Karl Ramm
Import upstream version 3.34 |
2194 |
# endif
|
2195 |
}, { "XINERAMA", "Xinerama", |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2196 |
# ifdef HAVE_XINERAMA
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2197 |
True, XineramaQueryVersion |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2198 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2199 |
False, 0 |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2200 |
# endif
|
2201 |
}, { "RANDR", "Resize-and-Rotate", |
|
2202 |
# ifdef HAVE_RANDR
|
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2203 |
True, XRRQueryVersion |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2204 |
# else
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2205 |
False, 0 |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2206 |
# endif
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2207 |
}, { "DRI", "DRI", |
2208 |
True, 0 |
|
1.1.7
by Robert Ancell
Import upstream version 5.08 |
2209 |
}, { "NV-CONTROL", "NVidia", |
2210 |
True, 0 |
|
2211 |
}, { "NV-GLX", "NVidia GLX", |
|
2212 |
True, 0 |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2213 |
}, { "Apple-DRI", "Apple-DRI (XDarwin)", |
1.1.6
by Ted Gould
Import upstream version 5.07 |
2214 |
True, 0 |
1.1.10
by Robert Ancell
Import upstream version 5.12 |
2215 |
}, { "XInputExtension", "XInput", |
2216 |
True, 0 |
|
1
by Karl Ramm
Import upstream version 3.34 |
2217 |
},
|
2218 |
};
|
|
2219 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
2220 |
fprintf (stderr, "%s: running on display \"%s\"\n", blurb(), |
2221 |
DisplayString(si->dpy)); |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2222 |
fprintf (stderr, "%s: vendor is %s, %d.\n", blurb(), |
1
by Karl Ramm
Import upstream version 3.34 |
2223 |
ServerVendor(si->dpy), VendorRelease(si->dpy)); |
2224 |
||
2225 |
fprintf (stderr, "%s: useful extensions:\n", blurb()); |
|
2226 |
for (i = 0; i < countof(exts); i++) |
|
2227 |
{
|
|
2228 |
int op = 0, event = 0, error = 0; |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2229 |
char buf [255]; |
1.1.6
by Ted Gould
Import upstream version 5.07 |
2230 |
int maj = 0, min = 0; |
2231 |
int dummy1, dummy2, dummy3; |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2232 |
int j; |
1.1.6
by Ted Gould
Import upstream version 5.07 |
2233 |
|
2234 |
/* Most of the extension version functions take 3 args,
|
|
2235 |
writing results into args 2 and 3, but some take more.
|
|
2236 |
We only ever care about the first two results, but we
|
|
2237 |
pass in three extra pointers just in case.
|
|
2238 |
*/
|
|
2239 |
Status (*version_fn_2) (Display*,int*,int*,int*,int*,int*) = |
|
2240 |
(Status (*) (Display*,int*,int*,int*,int*,int*)) exts[i].version_fn; |
|
2241 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2242 |
if (!XQueryExtension (si->dpy, exts[i].name, &op, &event, &error)) |
2243 |
continue; |
|
2244 |
sprintf (buf, "%s: ", blurb()); |
|
2245 |
j = strlen (buf); |
|
2246 |
strcat (buf, exts[i].desc); |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2247 |
|
2248 |
if (!version_fn_2) |
|
2249 |
;
|
|
2250 |
else if (version_fn_2 (si->dpy, &maj, &min, &dummy1, &dummy2, &dummy3)) |
|
2251 |
sprintf (buf+strlen(buf), " (%d.%d)", maj, min); |
|
2252 |
else
|
|
2253 |
strcat (buf, " (unavailable)"); |
|
2254 |
||
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2255 |
if (!exts[i].useful_p) |
1.1.5
by Ted Gould
Import upstream version 5.05 |
2256 |
strcat (buf, " (disabled at compile time)"); |
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2257 |
fprintf (stderr, "%s\n", buf); |
1
by Karl Ramm
Import upstream version 3.34 |
2258 |
}
|
2259 |
||
2260 |
for (i = 0; i < si->nscreens; i++) |
|
2261 |
{
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2262 |
saver_screen_info *ssi = &si->screens[i]; |
1
by Karl Ramm
Import upstream version 3.34 |
2263 |
unsigned long colormapped_depths = 0; |
2264 |
unsigned long non_mapped_depths = 0; |
|
2265 |
XVisualInfo vi_in, *vi_out; |
|
2266 |
int out_count; |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2267 |
|
2268 |
if (!ssi->real_screen_p) continue; |
|
2269 |
||
2270 |
vi_in.screen = ssi->real_screen_number; |
|
1
by Karl Ramm
Import upstream version 3.34 |
2271 |
vi_out = XGetVisualInfo (si->dpy, VisualScreenMask, &vi_in, &out_count); |
2272 |
if (!vi_out) continue; |
|
2273 |
for (j = 0; j < out_count; j++) |
|
2274 |
if (vi_out[j].class == PseudoColor) |
|
2275 |
colormapped_depths |= (1 << vi_out[j].depth); |
|
2276 |
else
|
|
2277 |
non_mapped_depths |= (1 << vi_out[j].depth); |
|
2278 |
XFree ((char *) vi_out); |
|
2279 |
||
2280 |
if (colormapped_depths) |
|
2281 |
{
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2282 |
fprintf (stderr, "%s: screen %d colormapped depths:", blurb(), |
2283 |
ssi->real_screen_number); |
|
1
by Karl Ramm
Import upstream version 3.34 |
2284 |
for (j = 0; j < 32; j++) |
2285 |
if (colormapped_depths & (1 << j)) |
|
2286 |
fprintf (stderr, " %d", j); |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2287 |
fprintf (stderr, ".\n"); |
1
by Karl Ramm
Import upstream version 3.34 |
2288 |
}
|
2289 |
if (non_mapped_depths) |
|
2290 |
{
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2291 |
fprintf (stderr, "%s: screen %d non-colormapped depths:", |
2292 |
blurb(), ssi->real_screen_number); |
|
1
by Karl Ramm
Import upstream version 3.34 |
2293 |
for (j = 0; j < 32; j++) |
2294 |
if (non_mapped_depths & (1 << j)) |
|
2295 |
fprintf (stderr, " %d", j); |
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2296 |
fprintf (stderr, ".\n"); |
1
by Karl Ramm
Import upstream version 3.34 |
2297 |
}
|
2298 |
}
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2299 |
|
1.1.6
by Ted Gould
Import upstream version 5.07 |
2300 |
describe_monitor_layout (si); |
1
by Karl Ramm
Import upstream version 3.34 |
2301 |
}
|
2302 |
||
1.1.6
by Ted Gould
Import upstream version 5.07 |
2303 |
|
1
by Karl Ramm
Import upstream version 3.34 |
2304 |
Bool
|
2305 |
display_is_on_console_p (saver_info *si) |
|
2306 |
{
|
|
2307 |
Bool not_on_console = True; |
|
2308 |
char *dpystr = DisplayString (si->dpy); |
|
2309 |
char *tail = (char *) strchr (dpystr, ':'); |
|
2310 |
if (! tail || strncmp (tail, ":0", 2)) |
|
2311 |
not_on_console = True; |
|
2312 |
else
|
|
2313 |
{
|
|
2314 |
char dpyname[255], localname[255]; |
|
2315 |
strncpy (dpyname, dpystr, tail-dpystr); |
|
2316 |
dpyname [tail-dpystr] = 0; |
|
2317 |
if (!*dpyname || |
|
2318 |
!strcmp(dpyname, "unix") || |
|
2319 |
!strcmp(dpyname, "localhost")) |
|
2320 |
not_on_console = False; |
|
2321 |
else if (gethostname (localname, sizeof (localname))) |
|
2322 |
not_on_console = True; /* can't find hostname? */ |
|
1.1.5
by Ted Gould
Import upstream version 5.05 |
2323 |
else if (!strncmp (dpyname, "/tmp/launch-", 12)) /* MacOS X launchd */ |
2324 |
not_on_console = False; |
|
1
by Karl Ramm
Import upstream version 3.34 |
2325 |
else
|
2326 |
{
|
|
2327 |
/* We have to call gethostbyname() on the result of gethostname()
|
|
2328 |
because the two aren't guarenteed to be the same name for the
|
|
2329 |
same host: on some losing systems, one is a FQDN and the other
|
|
2330 |
is not. Here in the wide wonderful world of Unix it's rocket
|
|
2331 |
science to obtain the local hostname in a portable fashion.
|
|
2332 |
|
|
2333 |
And don't forget, gethostbyname() reuses the structure it
|
|
2334 |
returns, so we have to copy the fucker before calling it again.
|
|
2335 |
Thank you master, may I have another.
|
|
2336 |
*/
|
|
2337 |
struct hostent *h = gethostbyname (dpyname); |
|
2338 |
if (!h) |
|
2339 |
not_on_console = True; |
|
2340 |
else
|
|
2341 |
{
|
|
2342 |
char hn [255]; |
|
2343 |
struct hostent *l; |
|
2344 |
strcpy (hn, h->h_name); |
|
2345 |
l = gethostbyname (localname); |
|
2346 |
not_on_console = (!l || !!(strcmp (l->h_name, hn))); |
|
2347 |
}
|
|
2348 |
}
|
|
2349 |
}
|
|
2350 |
return !not_on_console; |
|
2351 |
}
|
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2352 |
|
2353 |
||
2354 |
/* Do a little bit of heap introspection...
|
|
2355 |
*/
|
|
2356 |
void
|
|
2357 |
check_for_leaks (const char *where) |
|
2358 |
{
|
|
2.1.1
by Ralf Hildebrandt
Patch by Joachim Breitner to check more frequently if DPMS kicked in (closes: #303374, #286664). |
2359 |
#if defined(HAVE_SBRK) && defined(LEAK_PARANOIA)
|
1.1.1
by Ralf Hildebrandt
Import upstream version 4.21 |
2360 |
static unsigned long last_brk = 0; |
2361 |
int b = (unsigned long) sbrk(0); |
|
2362 |
if (last_brk && last_brk < b) |
|
2363 |
fprintf (stderr, "%s: %s: brk grew by %luK.\n", |
|
2364 |
blurb(), where, |
|
2365 |
(((b - last_brk) + 1023) / 1024)); |
|
2366 |
last_brk = b; |
|
2367 |
#endif /* HAVE_SBRK */ |
|
2368 |
}
|