X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fxscreensaver.c;h=a70de0e4043a2eba2e497f7b36210824cd85c530;hb=6a1da724858673ac40aa13a9612340d8bed8c7b9;hp=0e60dfcc8599da4afdf6b01ab7c8e2eea4004eff;hpb=cccbddbc4140cf9a06d7d95cc5c0ca36eb5d6e28;p=xscreensaver diff --git a/driver/xscreensaver.c b/driver/xscreensaver.c index 0e60dfcc..a70de0e4 100644 --- a/driver/xscreensaver.c +++ b/driver/xscreensaver.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1991-2002 Jamie Zawinski +/* xscreensaver, Copyright (c) 1991-2003 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -127,6 +127,9 @@ #include #include #include + +#include + #include #include #include @@ -213,6 +216,12 @@ static XrmOptionDescRec options [] = { #endif /* 0 */ }; +#ifdef __GNUC__ + __extension__ /* shut up about "string length is greater than the length + ISO C89 compilers are required to support" when including + the .ad file... */ +#endif + static char *defaults[] = { #include "XScreenSaver_ad.h" 0 @@ -228,13 +237,15 @@ do_help (saver_info *si) fflush (stdout); fflush (stderr); fprintf (stdout, "\ -xscreensaver %s, copyright (c) 1991-2002 by Jamie Zawinski \n\ +xscreensaver %s, copyright (c) 1991-2003 by Jamie Zawinski \n\ \n\ All xscreensaver configuration is via the `~/.xscreensaver' file.\n\ Rather than editing that file by hand, just run `xscreensaver-demo':\n\ that program lets you configure the screen saver graphically,\n\ including timeouts, locking, and display modes.\n\ -\n\ +\n", + si->version); + fprintf (stdout, "\ Just getting started? Try this:\n\ \n\ xscreensaver &\n\ @@ -243,8 +254,8 @@ xscreensaver %s, copyright (c) 1991-2002 by Jamie Zawinski \n\ For updates, online manual, and FAQ, please see the web page:\n\ \n\ http://www.jwz.org/xscreensaver/\n\ -\n", - si->version); +\n"); + fflush (stdout); fflush (stderr); exit (1); @@ -289,6 +300,7 @@ saver_ehandler (Display *dpy, XErrorEvent *error) { saver_info *si = global_si_kludge; /* I hate C so much... */ int i; + Bool fatal_p; if (!real_stderr) real_stderr = stderr; @@ -301,17 +313,27 @@ saver_ehandler (Display *dpy, XErrorEvent *error) for (i = 0; i < si->nscreens; i++) fprintf (real_stderr, "%s: screen %d: 0x%x, 0x%x, 0x%x\n", blurb(), i, - RootWindowOfScreen (si->screens[i].screen), - si->screens[i].real_vroot, - si->screens[i].screensaver_window); + (unsigned int) RootWindowOfScreen (si->screens[i].screen), + (unsigned int) si->screens[i].real_vroot, + (unsigned int) si->screens[i].screensaver_window); fprintf (real_stderr, "\n" "#######################################" "#######################################\n\n"); - if (XmuPrintDefaultErrorMessage (dpy, error, real_stderr)) + fatal_p = XmuPrintDefaultErrorMessage (dpy, error, real_stderr); + + fatal_p = True; /* The only time I've ever seen a supposedly nonfatal error, + it has been BadImplementation / Xlib sequence lost, which + are in truth pretty damned fatal. + */ + + fprintf (real_stderr, "\n"); + + if (! fatal_p) + fprintf (real_stderr, "%s: nonfatal error.\n\n", blurb()); + else { - fprintf (real_stderr, "\n"); if (si->prefs.xsync_p) { saver_exit (si, -1, "because of synchronous X Error"); @@ -327,7 +349,8 @@ saver_ehandler (Display *dpy, XErrorEvent *error) " bug. That will cause xscreensaver to dump a `core' file to the\n" " current directory. Please include the stack trace from that core\n" " file in your bug report. *DO NOT* mail the core file itself!\n" - " That won't work.\n" + " That won't work.\n"); + fprintf (real_stderr, "\n" " http://www.jwz.org/xscreensaver/bugs.html explains how to create\n" " the most useful bug reports, and how to examine core files.\n" @@ -342,8 +365,7 @@ saver_ehandler (Display *dpy, XErrorEvent *error) saver_exit (si, -1, 0); } } - else - fprintf (real_stderr, " (nonfatal.)\n"); + return 0; } @@ -483,6 +505,37 @@ lock_initialization (saver_info *si, int *argc, char **argv) si->locking_disabled_p = True; si->nolock_reason = "running under GDM"; } + + /* If the server is XDarwin (MacOS X) then disable locking. + (X grabs only affect X programs, so you can use Command-Tab + to bring any other Mac program to the front, e.g., Terminal.) + */ + if (!si->locking_disabled_p) + { + int op = 0, event = 0, error = 0; + Bool macos_p = False; + +#ifdef __APPLE__ + /* Disable locking if *running* on Apple hardware, since we have no + reliable way to determine whether the server is running on MacOS. + Hopefully __APPLE__ means "MacOS" and not "Linux on Mac hardware" + but I'm not really sure about that. + */ + macos_p = True; +#endif + + if (!macos_p) + /* This extension exists on the Apple X11 server, but not + on earlier versions of the XDarwin server. */ + macos_p = XQueryExtension (si->dpy, "Apple-DRI", &op, &event, &error); + + if (macos_p) + { + si->locking_disabled_p = True; + si->nolock_reason = "Cannot lock securely on MacOS X"; + } + } + #endif /* NO_LOCKING */ } @@ -645,7 +698,7 @@ print_banner (saver_info *si) if (p->verbose_p) fprintf (stderr, - "%s %s, copyright (c) 1991-2002 " + "%s %s, copyright (c) 1991-2003 " "by Jamie Zawinski .\n", progname, si->version); @@ -678,11 +731,17 @@ print_banner (saver_info *si) fprintf (stderr, "%s: in process %lu.\n", blurb(), (unsigned long) getpid()); } +} + +static void +print_lock_failure_banner (saver_info *si) +{ + saver_preferences *p = &si->prefs; /* If locking was not able to be initalized for some reason, explain why. (This has to be done after we've read the lock_p resource.) */ - if (p->lock_p && si->locking_disabled_p) + if (si->locking_disabled_p) { p->lock_p = False; fprintf (stderr, "%s: locking is disabled (%s).\n", blurb(), @@ -697,6 +756,7 @@ print_banner (saver_info *si) "\t See the manual for details.\n", blurb()); } + } @@ -744,7 +804,7 @@ initialize_per_screen_info (saver_info *si, Widget toplevel_shell) XtNvisual, ssi->current_visual, XtNdepth, visual_depth (ssi->screen, ssi->current_visual), - 0); + NULL); if (! found_any_writable_cells) { @@ -1196,6 +1256,7 @@ main_loop (saver_info *si) } static void analyze_display (saver_info *si); +static void fix_fds (void); int main (int argc, char **argv) @@ -1209,6 +1270,8 @@ main (int argc, char **argv) memset(si, 0, sizeof(*si)); global_si_kludge = si; /* I hate C so much... */ + fix_fds(); + # undef ya_rand_init ya_rand_init (0); @@ -1237,6 +1300,7 @@ main (int argc, char **argv) exit (1); lock_initialization (si, &argc, argv); + print_lock_failure_banner (si); if (p->xsync_p) XSynchronize (si->dpy, True); @@ -1267,6 +1331,36 @@ main (int argc, char **argv) return 0; } +static void +fix_fds (void) +{ + /* Bad Things Happen if stdin, stdout, and stderr have been closed + (as by the `sh incantation "xscreensaver >&- 2>&-"). When you do + that, the X connection gets allocated to one of these fds, and + then some random library writes to stderr, and random bits get + stuffed down the X pipe, causing "Xlib: sequence lost" errors. + So, we cause the first three file descriptors to be open to + /dev/null if they aren't open to something else already. This + must be done before any other files are opened (or the closing + of that other file will again free up one of the "magic" first + three FDs.) + + We do this by opening /dev/null three times, and then closing + those fds, *unless* any of them got allocated as #0, #1, or #2, + in which case we leave them open. Gag. + + Really, this crap is technically required of *every* X program, + if you want it to be robust in the face of "2>&-". + */ + int fd0 = open ("/dev/null", O_RDWR); + int fd1 = open ("/dev/null", O_RDWR); + int fd2 = open ("/dev/null", O_RDWR); + if (fd0 > 2) close (fd0); + if (fd1 > 2) close (fd1); + if (fd2 > 2) close (fd2); +} + + /* Processing ClientMessage events. */ @@ -1306,7 +1400,7 @@ XGetAtomName_safe (Display *dpy, Atom atom) else { char buf[100]; - sprintf (buf, "<>", (unsigned long) atom); + sprintf (buf, "<>", (unsigned int) atom); return strdup (buf); } } @@ -1850,6 +1944,8 @@ analyze_display (saver_info *si) # endif }, { "XINERAMA", "Xinerama", True + }, { "Apple-DRI", "Apple-DRI (XDarwin)", + True }, };