16
16
* on (nearly) all windows; or by waiting for the MIT-SCREEN-SAVER extension
17
17
* to send us a "you are idle" event.
19
* Then, we map a full screen black window (or, in the case of the
20
* MIT-SCREEN-SAVER extension, use the one it gave us.)
19
* Then, we map a full screen black window.
22
21
* We place a __SWM_VROOT property on this window, so that newly-started
23
* clients will think that this window is a "virtual root" window.
22
* clients will think that this window is a "virtual root" window (as per
23
* the logic in the historical "vroot.h" header.)
25
25
* If there is an existing "virtual root" window (one that already had
26
26
* an __SWM_VROOT property) then we remove that property from that window.
38
38
* When they are, we kill the inferior process, unmap the window, and restore
39
39
* the __SWM_VROOT property to the real virtual root window if there was one.
41
* While we are waiting, we also set up timers so that, after a certain
42
* amount of time has passed, we can start a different screenhack. We do
43
* this by killing the running child process with SIGTERM, and then starting
44
* a new one in the same way.
41
* On multi-screen systems, we do the above on each screen, and start
42
* multiple programs, each with a different value of $DISPLAY.
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.
49
* While we are waiting for user activity, we also set up timers so that,
50
* after a certain amount of time has passed, we can start a different
51
* screenhack. We do this by killing the running child process with
52
* SIGTERM, and then starting a new one in the same way.
46
54
* If there was a real virtual root, meaning that we removed the __SWM_VROOT
47
55
* property from it, meaning we must (absolutely must) restore it before we
92
100
* "client changing event mask" problem that the KeyPress events hack does.
93
101
* I think polling is more reliable.
95
* None of this crap happens if we're using one of the extensions, so install
96
* one of them if the description above sounds just too flaky to live. It
97
* is, but those are your choices.
103
* On systems with /proc/interrupts (Linux) we poll that file and note when
104
* the interrupt counter numbers on the "keyboard" and "PS/2" lines change.
105
* (There is no reliable way, using /proc/interrupts, to detect non-PS/2
106
* mice, so it doesn't help for serial or USB mice.)
108
* None of this crap happens if we're using one of the extensions. Sadly,
109
* the XIdle extension hasn't been available for many years; the SGI
110
* extension only exists on SGIs; and the MIT extension, while widely
111
* deployed, is garbage in several ways.
99
113
* A third idle-detection option could be implemented (but is not): when
100
114
* running on the console display ($DISPLAY is `localhost`:0) and we're on a
171
194
static XrmOptionDescRec options [] = {
196
{ "-verbose", ".verbose", XrmoptionNoArg, "on" },
197
{ "-silent", ".verbose", XrmoptionNoArg, "off" },
199
/* xscreensaver-demo uses this one */
200
{ "-nosplash", ".splash", XrmoptionNoArg, "off" },
201
{ "-no-splash", ".splash", XrmoptionNoArg, "off" },
203
/* useful for debugging */
204
{ "-no-capture-stderr", ".captureStderr", XrmoptionNoArg, "off" },
206
/* There's really no reason to have these command-line args; they just
207
lead to confusion when the .xscreensaver file has conflicting values.
210
{ "-splash", ".splash", XrmoptionNoArg, "on" },
211
{ "-capture-stderr", ".captureStderr", XrmoptionNoArg, "on" },
172
212
{ "-timeout", ".timeout", XrmoptionSepArg, 0 },
173
213
{ "-cycle", ".cycle", XrmoptionSepArg, 0 },
174
214
{ "-lock-mode", ".lock", XrmoptionNoArg, "on" },
180
220
{ "-visual", ".visualID", XrmoptionSepArg, 0 },
181
221
{ "-install", ".installColormap", XrmoptionNoArg, "on" },
182
222
{ "-no-install", ".installColormap", XrmoptionNoArg, "off" },
183
{ "-verbose", ".verbose", XrmoptionNoArg, "on" },
184
{ "-silent", ".verbose", XrmoptionNoArg, "off" },
185
223
{ "-timestamp", ".timestamp", XrmoptionNoArg, "on" },
186
{ "-capture-stderr", ".captureStderr", XrmoptionNoArg, "on" },
187
{ "-no-capture-stderr", ".captureStderr", XrmoptionNoArg, "off" },
188
224
{ "-xidle-extension", ".xidleExtension", XrmoptionNoArg, "on" },
189
225
{ "-no-xidle-extension", ".xidleExtension", XrmoptionNoArg, "off" },
190
226
{ "-mit-extension", ".mitSaverExtension",XrmoptionNoArg, "on" },
193
229
{ "-no-sgi-extension", ".sgiSaverExtension",XrmoptionNoArg, "off" },
194
230
{ "-proc-interrupts", ".procInterrupts", XrmoptionNoArg, "on" },
195
231
{ "-no-proc-interrupts", ".procInterrupts", XrmoptionNoArg, "off" },
196
{ "-splash", ".splash", XrmoptionNoArg, "on" },
197
{ "-no-splash", ".splash", XrmoptionNoArg, "off" },
198
{ "-nosplash", ".splash", XrmoptionNoArg, "off" },
199
232
{ "-idelay", ".initialDelay", XrmoptionSepArg, 0 },
200
233
{ "-nice", ".nice", XrmoptionSepArg, 0 },
202
/* Actually these are built in to Xt, but just to be sure... */
203
{ "-synchronous", ".synchronous", XrmoptionNoArg, "on" },
204
{ "-xrm", NULL, XrmoptionResArg, NULL }
238
__extension__ /* shut up about "string length is greater than the length
239
ISO C89 compilers are required to support" when including
207
243
static char *defaults[] = {
208
244
#include "XScreenSaver_ad.h"
221
257
fprintf (stdout, "\
222
xscreensaver %s, copyright (c) 1991-2001 by Jamie Zawinski <jwz@jwz.org>\n\
223
The standard Xt command-line options are accepted; other options include:\n\
225
-timeout <minutes> When the screensaver should activate.\n\
226
-cycle <minutes> How long to let each hack run before switching.\n\
227
-lock-mode Require a password before deactivating.\n\
228
-lock-timeout <minutes> Grace period before locking; default 0.\n\
229
-visual <id-or-class> Which X visual to run on.\n\
230
-install Install a private colormap.\n\
232
-no-splash Don't display a splash-screen at startup.\n\
233
-help This message.\n\
235
See the manual for other options and X resources.\n\
237
The `xscreensaver' program should be left running in the background.\n\
238
Use the `xscreensaver-demo' and `xscreensaver-command' programs to\n\
239
manipulate a running xscreensaver.\n\
241
The `*programs' resource controls which graphics demos will be launched by\n\
242
the screensaver. See `man xscreensaver' or the web page for more details.\n\
244
Just getting started? Try this:\n\
258
xscreensaver %s, copyright (c) 1991-2005 by Jamie Zawinski <jwz@jwz.org>\n\
260
All xscreensaver configuration is via the `~/.xscreensaver' file.\n\
261
Rather than editing that file by hand, just run `xscreensaver-demo':\n\
262
that program lets you configure the screen saver graphically,\n\
263
including timeouts, locking, and display modes.\n\
267
Just getting started? Try this:\n\
246
269
xscreensaver &\n\
247
270
xscreensaver-demo\n\
249
For updates, check http://www.jwz.org/xscreensaver/\n\
272
For updates, online manual, and FAQ, please see the web page:\n\
274
http://www.jwz.org/xscreensaver/\n\
305
331
for (i = 0; i < si->nscreens; i++)
306
fprintf (real_stderr, "%s: screen %d: 0x%x, 0x%x, 0x%x\n",
308
RootWindowOfScreen (si->screens[i].screen),
309
si->screens[i].real_vroot,
310
si->screens[i].screensaver_window);
333
saver_screen_info *ssi = &si->screens[i];
334
fprintf (real_stderr, "%s: screen %d/%d: 0x%x, 0x%x, 0x%x\n",
335
blurb(), ssi->real_screen_number, ssi->number,
336
(unsigned int) RootWindowOfScreen (si->screens[i].screen),
337
(unsigned int) si->screens[i].real_vroot,
338
(unsigned int) si->screens[i].screensaver_window);
312
341
fprintf (real_stderr, "\n"
313
342
"#######################################"
314
343
"#######################################\n\n");
316
if (XmuPrintDefaultErrorMessage (dpy, error, real_stderr))
345
fatal_p = XmuPrintDefaultErrorMessage (dpy, error, real_stderr);
347
fatal_p = True; /* The only time I've ever seen a supposedly nonfatal error,
348
it has been BadImplementation / Xlib sequence lost, which
349
are in truth pretty damned fatal.
352
fprintf (real_stderr, "\n");
355
fprintf (real_stderr, "%s: nonfatal error.\n\n", blurb());
318
fprintf (real_stderr, "\n");
319
358
if (si->prefs.xsync_p)
321
360
saver_exit (si, -1, "because of synchronous X Error");
477
516
si->locking_disabled_p = True;
478
517
si->nolock_reason = "error getting password";
520
/* If locking is currently enabled, but the environment indicates that
521
we have been launched as GDM's "Background" program, then disable
522
locking just in case.
524
if (!si->locking_disabled_p && getenv ("RUNNING_UNDER_GDM"))
526
si->locking_disabled_p = True;
527
si->nolock_reason = "running under GDM";
530
/* If the server is XDarwin (MacOS X) then disable locking.
531
(X grabs only affect X programs, so you can use Command-Tab
532
to bring any other Mac program to the front, e.g., Terminal.)
534
if (!si->locking_disabled_p)
536
int op = 0, event = 0, error = 0;
537
Bool macos_p = False;
540
/* Disable locking if *running* on Apple hardware, since we have no
541
reliable way to determine whether the server is running on MacOS.
542
Hopefully __APPLE__ means "MacOS" and not "Linux on Mac hardware"
543
but I'm not really sure about that.
549
/* This extension exists on the Apple X11 server, but not
550
on earlier versions of the XDarwin server. */
551
macos_p = XQueryExtension (si->dpy, "Apple-DRI", &op, &event, &error);
555
si->locking_disabled_p = True;
556
si->nolock_reason = "Cannot lock securely on MacOS X";
480
560
#endif /* NO_LOCKING */
494
572
char *d = getenv ("DISPLAY");
497
char ndpy[] = "DISPLAY=:0.0";
575
char *ndpy = strdup("DISPLAY=:0.0");
498
576
/* if (si->prefs.verbose_p) */ /* sigh, too early to test this... */
500
578
"%s: warning: $DISPLAY is not set: defaulting to \"%s\".\n",
501
579
blurb(), ndpy+8);
502
580
if (putenv (ndpy))
582
/* don't free (ndpy) -- some implementations of putenv (BSD 4.4,
583
glibc 2.0) copy the argument, but some (libc4,5, glibc 2.1.2)
584
do not. So we must leak it (and/or the previous setting). Yay.
505
587
#endif /* HAVE_PUTENV */
529
611
XA_SCREENSAVER_RESPONSE = XInternAtom (si->dpy, "_SCREENSAVER_RESPONSE",
531
613
XA_XSETROOT_ID = XInternAtom (si->dpy, "_XSETROOT_ID", False);
614
XA_ESETROOT_PMAP_ID = XInternAtom (si->dpy, "ESETROOT_PMAP_ID", False);
615
XA_XROOTPMAP_ID = XInternAtom (si->dpy, "_XROOTPMAP_ID", False);
532
616
XA_ACTIVATE = XInternAtom (si->dpy, "ACTIVATE", False);
533
617
XA_DEACTIVATE = XInternAtom (si->dpy, "DEACTIVATE", False);
534
618
XA_RESTART = XInternAtom (si->dpy, "RESTART", False);
668
752
fprintf (stderr, "%s: in process %lu.\n", blurb(),
669
753
(unsigned long) getpid());
758
print_lock_failure_banner (saver_info *si)
760
saver_preferences *p = &si->prefs;
672
762
/* If locking was not able to be initalized for some reason, explain why.
673
763
(This has to be done after we've read the lock_p resource.)
675
if (p->lock_p && si->locking_disabled_p)
765
if (si->locking_disabled_p)
677
767
p->lock_p = False;
678
768
fprintf (stderr, "%s: locking is disabled (%s).\n", blurb(),
699
790
Bool found_any_writable_cells = False;
702
si->nscreens = ScreenCount(si->dpy);
703
si->screens = (saver_screen_info *)
704
calloc(sizeof(saver_screen_info), si->nscreens);
706
si->default_screen = &si->screens[DefaultScreen(si->dpy)];
793
# ifdef HAVE_XINERAMA
796
si->xinerama_p = (XineramaQueryExtension (si->dpy, &event, &error) &&
797
XineramaIsActive (si->dpy));
800
if (si->xinerama_p && ScreenCount (si->dpy) != 1)
802
si->xinerama_p = False;
803
if (si->prefs.verbose_p)
805
"%s: Xinerama AND %d screens? Disabling Xinerama support!\n",
806
blurb(), ScreenCount(si->dpy));
811
XineramaScreenInfo *xsi = XineramaQueryScreens (si->dpy, &si->nscreens);
813
si->xinerama_p = False;
816
si->screens = (saver_screen_info *)
817
calloc(sizeof(saver_screen_info), si->nscreens);
818
for (i = 0; i < si->nscreens; i++)
820
si->screens[i].x = xsi[i].x_org;
821
si->screens[i].y = xsi[i].y_org;
822
si->screens[i].width = xsi[i].width;
823
si->screens[i].height = xsi[i].height;
827
si->default_screen = &si->screens[0];
828
si->default_screen->real_screen_p = True;
830
# endif /* !HAVE_XINERAMA */
834
si->nscreens = ScreenCount(si->dpy);
835
si->screens = (saver_screen_info *)
836
calloc(sizeof(saver_screen_info), si->nscreens);
837
si->default_screen = &si->screens[DefaultScreen(si->dpy)];
839
for (i = 0; i < si->nscreens; i++)
841
saver_screen_info *ssi = &si->screens[i];
842
ssi->width = DisplayWidth (si->dpy, i);
843
ssi->height = DisplayHeight (si->dpy, i);
844
ssi->real_screen_p = True;
845
ssi->real_screen_number = i;
850
/* In "quad mode", we use the Xinerama code to pretend that there are 4
851
screens for every physical screen, and run four times as many hacks...
853
if (si->prefs.quad_p)
855
int ns2 = si->nscreens * 4;
856
saver_screen_info *ssi2 = (saver_screen_info *)
857
calloc(sizeof(saver_screen_info), ns2);
859
for (i = 0; i < si->nscreens; i++)
861
saver_screen_info *old = &si->screens[i];
863
if (si->prefs.debug_p) old->width = old->width / 2;
870
ssi2[i*4 ].width /= 2;
871
ssi2[i*4 ].height /= 2;
873
ssi2[i*4+1].x += ssi2[i*4 ].width;
874
ssi2[i*4+1].width -= ssi2[i*4 ].width;
875
ssi2[i*4+1].height /= 2;
877
ssi2[i*4+2].y += ssi2[i*4 ].height;
878
ssi2[i*4+2].width /= 2;
879
ssi2[i*4+2].height -= ssi2[i*4 ].height;
881
ssi2[i*4+3].x += ssi2[i*4+2].width;
882
ssi2[i*4+3].y += ssi2[i*4+2].height;
883
ssi2[i*4+3].width -= ssi2[i*4+2].width;
884
ssi2[i*4+3].height -= ssi2[i*4+2].height;
886
ssi2[i*4+1].real_screen_p = False;
887
ssi2[i*4+2].real_screen_p = False;
888
ssi2[i*4+3].real_screen_p = False;
894
si->default_screen = &si->screens[DefaultScreen(si->dpy) * 4];
895
si->xinerama_p = True;
898
/* finish initializing the screens.
708
900
for (i = 0; i < si->nscreens; i++)
710
902
saver_screen_info *ssi = &si->screens[i];
711
903
ssi->global = si;
712
ssi->screen = ScreenOfDisplay (si->dpy, i);
906
ssi->screen = ScreenOfDisplay (si->dpy, ssi->real_screen_number);
907
ssi->poll_mouse_last_root_x = -1;
908
ssi->poll_mouse_last_root_y = -1;
912
ssi->width = WidthOfScreen (ssi->screen);
913
ssi->height = HeightOfScreen (ssi->screen);
714
916
/* Note: we can't use the resource ".visual" because Xt is SO FUCKED. */
715
917
ssi->default_visual =
950
1177
fprintf (stderr, "%s: demoing %d at %s.\n", blurb(),
951
1178
si->selection_mode, timestring());
954
fprintf (stderr, "%s: blanking screen at %s.\n", blurb(),
1180
fprintf (stderr, "%s: blanking screen at %s.\n", blurb(),
958
1184
maybe_reload_init_file (si);
1186
if (p->mode == DONT_BLANK)
1189
fprintf (stderr, "%s: idle with blanking disabled at %s.\n",
1190
blurb(), timestring());
1192
/* Go around the loop and wait for the next bout of idleness,
1193
or for the init file to change, or for a remote command to
1194
come in, or something.
1196
But, if locked_p is true, go ahead. This can only happen
1197
if we're in "disabled" mode but a "lock" clientmessage came
1198
in: in that case, we should go ahead and blank/lock the screen.
1204
/* Since we're about to blank the screen, kill the de-race timer,
1205
if any. It might still be running if we have unblanked and then
1206
re-blanked in a short period (e.g., when using the "next" button
1207
in xscreensaver-demo.)
1212
fprintf (stderr, "%s: stopping de-race timer (%d remaining.)\n",
1213
blurb(), si->de_race_ticks);
1214
XtRemoveTimeOut (si->de_race_id);
1219
/* Now, try to blank.
960
1222
if (! blank_screen (si))
962
1224
/* We were unable to grab either the keyboard or mouse.
967
1229
see any events, and the display would be wedged.
969
1231
So, just go around the loop again and wait for the
970
next bout of idleness.
1232
next bout of idleness. (If the user remains idle, we
1233
will next try to blank the screen again in no more than
1236
Time retry = 60 * 1000;
1237
if (p->timeout < retry)
1243
"%s: DEBUG MODE: unable to grab -- BLANKING ANYWAY.\n",
974
1249
"%s: unable to grab keyboard or mouse! Blanking aborted.\n",
1252
schedule_wakeup_event (si, retry, p->debug_p);
979
1257
kill_screenhack (si);
1150
1441
blurb(), blurb());
1152
1443
for (i = 0; i < si->nscreens; i++)
1153
if (ensure_no_screensaver_running (si->dpy, si->screens[i].screen))
1445
saver_screen_info *ssi = &si->screens[i];
1446
if (ssi->real_screen_p)
1447
if (ensure_no_screensaver_running (si->dpy, si->screens[i].screen))
1156
1451
lock_initialization (si, &argc, argv);
1452
print_lock_failure_banner (si);
1158
1454
if (p->xsync_p) XSynchronize (si->dpy, True);
1159
blurb_timestamp_p = p->timestamp_p; /* kludge */
1161
1456
if (p->verbose_p) analyze_display (si);
1162
1457
initialize_server_extensions (si);
1486
/* Bad Things Happen if stdin, stdout, and stderr have been closed
1487
(as by the `sh incantation "xscreensaver >&- 2>&-"). When you do
1488
that, the X connection gets allocated to one of these fds, and
1489
then some random library writes to stderr, and random bits get
1490
stuffed down the X pipe, causing "Xlib: sequence lost" errors.
1491
So, we cause the first three file descriptors to be open to
1492
/dev/null if they aren't open to something else already. This
1493
must be done before any other files are opened (or the closing
1494
of that other file will again free up one of the "magic" first
1497
We do this by opening /dev/null three times, and then closing
1498
those fds, *unless* any of them got allocated as #0, #1, or #2,
1499
in which case we leave them open. Gag.
1501
Really, this crap is technically required of *every* X program,
1502
if you want it to be robust in the face of "2>&-".
1504
int fd0 = open ("/dev/null", O_RDWR);
1505
int fd1 = open ("/dev/null", O_RDWR);
1506
int fd2 = open ("/dev/null", O_RDWR);
1507
if (fd0 > 2) close (fd0);
1508
if (fd1 > 2) close (fd1);
1509
if (fd2 > 2) close (fd2);
1186
1514
/* Processing ClientMessage events.
1599
bogus_clientmessage_warning (saver_info *si, XEvent *event)
1601
char *str = XGetAtomName_safe (si->dpy, event->xclient.message_type);
1602
Window w = event->xclient.window;
1607
for (screen = 0; screen < si->nscreens; screen++)
1608
if (w == si->screens[screen].screensaver_window)
1610
strcpy (wdesc, "xscreensaver");
1613
else if (w == RootWindow (si->dpy, screen))
1615
strcpy (wdesc, "root");
1621
XErrorHandler old_handler;
1623
XWindowAttributes xgwa;
1624
memset (&hint, 0, sizeof(hint));
1625
memset (&xgwa, 0, sizeof(xgwa));
1627
XSync (si->dpy, False);
1628
old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
1629
XGetClassHint (si->dpy, w, &hint);
1630
XGetWindowAttributes (si->dpy, w, &xgwa);
1631
XSync (si->dpy, False);
1632
XSetErrorHandler (old_handler);
1633
XSync (si->dpy, False);
1635
screen = (xgwa.screen ? screen_number (xgwa.screen) : -1);
1637
sprintf (wdesc, "%.20s / %.20s",
1638
(hint.res_name ? hint.res_name : "(null)"),
1639
(hint.res_class ? hint.res_class : "(null)"));
1640
if (hint.res_name) XFree (hint.res_name);
1641
if (hint.res_class) XFree (hint.res_class);
1644
fprintf (stderr, "%s: %d: unrecognised ClientMessage \"%s\" received\n",
1645
blurb(), screen, (str ? str : "(null)"));
1646
fprintf (stderr, "%s: %d: for window 0x%lx (%s)\n",
1647
blurb(), screen, (unsigned long) w, wdesc);
1648
if (str) XFree (str);
1270
1652
handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p)
1276
1658
/* Preferences might affect our handling of client messages. */
1277
1659
maybe_reload_init_file (si);
1279
if (event->xclient.message_type != XA_SCREENSAVER)
1282
str = XGetAtomName_safe (si->dpy, event->xclient.message_type);
1284
fprintf (stderr, "%s: unrecognised ClientMessage type %s received\n",
1285
blurb(), (str ? str : "(null)"));
1287
if (str) XFree (str);
1290
if (event->xclient.format != 32)
1292
fprintf (stderr, "%s: ClientMessage of format %d received, not 32\n",
1293
blurb(), event->xclient.format);
1661
if (event->xclient.message_type != XA_SCREENSAVER ||
1662
event->xclient.format != 32)
1664
bogus_clientmessage_warning (si, event);
1403
1782
char buf2 [255];
1404
1783
long which = event->xclient.data.l[1];
1785
if (p->mode == DONT_BLANK)
1787
clientmessage_response(si, window, True,
1788
"SELECT ClientMessage received in DONT_BLANK mode.",
1789
"screen blanking is currently disabled.");
1406
1793
sprintf (buf, "SELECT %ld ClientMessage received.", which);
1407
1794
sprintf (buf2, "activating (%ld).", which);
1408
1795
clientmessage_response (si, window, False, buf, buf2);
1463
1850
XSync (si->dpy, False);
1468
if (real_stdout) fflush (real_stdout);
1469
if (real_stderr) fflush (real_stderr);
1470
/* make sure error message shows up before exit. */
1471
if (real_stderr && stderr != real_stderr)
1472
dup2 (fileno(real_stderr), fileno(stderr));
1474
restart_process (si);
1475
exit (1); /* shouldn't get here; but if restarting didn't work,
1476
make this command be the same as EXIT. */
1853
restart_process (si); /* does not return */
1479
1857
clientmessage_response (si, window, True,
1576
1954
else if (type == XA_THROTTLE)
1956
/* The THROTTLE command is deprecated -- it predates the XDPMS
1957
extension. Instead of using -throttle, users should instead
1958
just power off the monitor (e.g., "xset dpms force off".)
1959
In a few minutes, xscreensaver will notice that the monitor
1960
is off, and cease running hacks.
1578
1962
if (si->throttled_p)
1579
1963
clientmessage_response (si, window, True,
1580
1964
"THROTTLE ClientMessage received, but "
1663
2047
const char *name; const char *desc; Bool useful_p;
1666
{ "SCREEN_SAVER", "SGI Screen-Saver",
2050
{ "SCREEN_SAVER", /* underscore */ "SGI Screen-Saver",
1667
2051
# ifdef HAVE_SGI_SAVER_EXTENSION
1672
}, { "SCREEN-SAVER", "SGI Screen-Saver",
2056
}, { "SCREEN-SAVER", /* dash */ "SGI Screen-Saver",
1673
2057
# ifdef HAVE_SGI_SAVER_EXTENSION
1732
2116
}, { "XINERAMA", "Xinerama",
2117
# ifdef HAVE_XINERAMA
2122
}, { "RANDR", "Resize-and-Rotate",
2128
}, { "Apple-DRI", "Apple-DRI (XDarwin)",
1737
fprintf (stderr, "%s: running on display \"%s\"\n", blurb(),
1738
DisplayString(si->dpy));
1739
fprintf (stderr, "%s: vendor is %s, %d\n", blurb(),
2133
fprintf (stderr, "%s: running on display \"%s\" (%d %sscreen%s).\n",
2135
DisplayString(si->dpy),
2137
(si->xinerama_p ? "Xinerama " : ""),
2138
(si->nscreens == 1 ? "" : "s"));
2139
fprintf (stderr, "%s: vendor is %s, %d.\n", blurb(),
1740
2140
ServerVendor(si->dpy), VendorRelease(si->dpy));
1742
2142
fprintf (stderr, "%s: useful extensions:\n", blurb());
1743
2143
for (i = 0; i < countof(exts); i++)
1745
2145
int op = 0, event = 0, error = 0;
1746
if (XQueryExtension (si->dpy, exts[i].name, &op, &event, &error))
1747
fprintf (stderr, "%s: %s%s\n", blurb(),
1749
(exts[i].useful_p ? "" :
1750
" \t<== unsupported at compile-time!"));
2148
if (!XQueryExtension (si->dpy, exts[i].name, &op, &event, &error))
2150
sprintf (buf, "%s: ", blurb());
2152
strcat (buf, exts[i].desc);
2153
if (!exts[i].useful_p)
2156
while (strlen (buf) < k) strcat (buf, " ");
2157
strcat (buf, "<-- not supported at compile time!");
2159
fprintf (stderr, "%s\n", buf);
1753
2162
for (i = 0; i < si->nscreens; i++)
2164
saver_screen_info *ssi = &si->screens[i];
1755
2165
unsigned long colormapped_depths = 0;
1756
2166
unsigned long non_mapped_depths = 0;
1757
2167
XVisualInfo vi_in, *vi_out;
2170
if (!ssi->real_screen_p) continue;
2172
vi_in.screen = ssi->real_screen_number;
1760
2173
vi_out = XGetVisualInfo (si->dpy, VisualScreenMask, &vi_in, &out_count);
1761
2174
if (!vi_out) continue;
1762
2175
for (j = 0; j < out_count; j++)
1769
2182
if (colormapped_depths)
1771
fprintf (stderr, "%s: screen %d colormapped depths:", blurb(), i);
2184
fprintf (stderr, "%s: screen %d colormapped depths:", blurb(),
2185
ssi->real_screen_number);
1772
2186
for (j = 0; j < 32; j++)
1773
2187
if (colormapped_depths & (1 << j))
1774
2188
fprintf (stderr, " %d", j);
1775
fprintf (stderr, "\n");
2189
fprintf (stderr, ".\n");
1777
2191
if (non_mapped_depths)
1779
fprintf (stderr, "%s: screen %d non-mapped depths:", blurb(), i);
2193
fprintf (stderr, "%s: screen %d non-colormapped depths:",
2194
blurb(), ssi->real_screen_number);
1780
2195
for (j = 0; j < 32; j++)
1781
2196
if (non_mapped_depths & (1 << j))
1782
2197
fprintf (stderr, " %d", j);
1783
fprintf (stderr, "\n");
2198
fprintf (stderr, ".\n");
2204
fprintf (stderr, "%s: Xinerama layout:\n", blurb());
2205
for (i = 0; i < si->nscreens; i++)
2207
saver_screen_info *ssi = &si->screens[i];
2208
fprintf (stderr, "%s: %c %d/%d: %dx%d+%d+%d\n",
2210
(ssi->real_screen_p ? '+' : ' '),
2211
ssi->number, ssi->real_screen_number,
2212
ssi->width, ssi->height, ssi->x, ssi->y);