X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fxscreensaver.c;h=63a63c83da2360cdc70ff06e59bb905210abeb57;hb=3c58fb6311db49c46f1670922933b27c6ea0c065;hp=9b26390bd6b40c092003ed5e65d192cac371fa42;hpb=06e9a7886a77cad92f9ddbc169d6d199a4d8b76d;p=xscreensaver diff --git a/driver/xscreensaver.c b/driver/xscreensaver.c index 9b26390b..63a63c83 100644 --- a/driver/xscreensaver.c +++ b/driver/xscreensaver.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1991-1999 Jamie Zawinski +/* xscreensaver, Copyright (c) 1991-2001 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 @@ -219,7 +219,7 @@ do_help (saver_info *si) fflush (stdout); fflush (stderr); fprintf (stdout, "\ -xscreensaver %s, copyright (c) 1991-1999 by Jamie Zawinski \n\ +xscreensaver %s, copyright (c) 1991-2001 by Jamie Zawinski \n\ The standard Xt command-line options are accepted; other options include:\n\ \n\ -timeout When the screensaver should activate.\n\ @@ -292,16 +292,27 @@ int saver_ehandler (Display *dpy, XErrorEvent *error) { saver_info *si = global_si_kludge; /* I hate C so much... */ + int i; if (!real_stderr) real_stderr = stderr; fprintf (real_stderr, "\n" "#######################################" "#######################################\n\n" - "%s: X Error! PLEASE REPORT THIS BUG.\n\n" - "#######################################" - "#######################################\n\n", + "%s: X Error! PLEASE REPORT THIS BUG.\n", blurb()); + + 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); + + fprintf (real_stderr, "\n" + "#######################################" + "#######################################\n\n"); + if (XmuPrintDefaultErrorMessage (dpy, error, real_stderr)) { fprintf (real_stderr, "\n"); @@ -315,7 +326,7 @@ saver_ehandler (Display *dpy, XErrorEvent *error) "#######################################" "#######################################\n\n"); fprintf (real_stderr, - " If at all possible, please re-run xscreensaver with the command\n" + " If at all possible, please re-run xscreensaver with the command\n" " line arguments `-sync -verbose -no-capture', and reproduce this\n" " bug. That will cause xscreensaver to dump a `core' file to the\n" " current directory. Please include the stack trace from that core\n" @@ -370,15 +381,32 @@ startup_ehandler (String name, String type, String class, fprintf (stderr, "\n"); describe_uids (si, stderr); - fprintf (stderr, "\n" + + if (si->orig_uid && !strncmp (si->orig_uid, "root/", 5)) + { + fprintf (stderr, "\n" + "%s: This is probably because you're logging in as root. You\n" +" shouldn't log in as root: you should log in as a normal user,\n" +" and then `su' as needed. If you insist on logging in as\n" +" root, you will have to turn off X's security features before\n" +" xscreensaver will work.\n" + "\n" +" Please read the manual and FAQ for more information:\n", + blurb()); + } + else + { + fprintf (stderr, "\n" "%s: Errors at startup are usually authorization problems.\n" - " Did you read the manual and the FAQ? Specifically,\n" - " the parts of the manual that talk about XAUTH, XDM,\n" - " and root logins?\n" - "\n" - " http://www.jwz.org/xscreensaver/man.html\n" - "\n", +" But you're not logging in as root (good!) so something\n" +" else must be wrong. Did you read the manual and the FAQ?\n", blurb()); + } + + fprintf (stderr, "\n" + " http://www.jwz.org/xscreensaver/faq.html\n" + " http://www.jwz.org/xscreensaver/man.html\n" + "\n"); fflush (stderr); fflush (stdout); @@ -462,6 +490,20 @@ connect_to_server (saver_info *si, int *argc, char **argv) { Widget toplevel_shell; +#ifdef HAVE_PUTENV + char *d = getenv ("DISPLAY"); + if (!d || !*d) + { + char ndpy[] = "DISPLAY=:0.0"; + /* if (si->prefs.verbose_p) */ /* sigh, too early to test this... */ + fprintf (stderr, + "%s: warning: $DISPLAY is not set: defaulting to \"%s\".\n", + blurb(), ndpy+8); + if (putenv (ndpy)) + abort (); + } +#endif /* HAVE_PUTENV */ + XSetErrorHandler (saver_ehandler); XtAppSetErrorMsgHandler (si->app, startup_ehandler); @@ -593,7 +635,7 @@ print_banner (saver_info *si) if (p->verbose_p) fprintf (stderr, - "%s %s, copyright (c) 1991-1999 " + "%s %s, copyright (c) 1991-2001 " "by Jamie Zawinski .\n", progname, si->version); @@ -649,7 +691,7 @@ print_banner (saver_info *si) /* Examine all of the display's screens, and populate the `saver_screen_info' - structures. + structures. Make sure this is called after hack_environment() sets $PATH. */ static void initialize_per_screen_info (saver_info *si, Widget toplevel_shell) @@ -676,6 +718,9 @@ initialize_per_screen_info (saver_info *si, Widget toplevel_shell) ssi->current_visual = ssi->default_visual; ssi->current_depth = visual_depth (ssi->screen, ssi->current_visual); + /* Execute a subprocess to find the GL visual. */ + ssi->best_gl_visual = get_best_gl_visual (ssi); + if (ssi == si->default_screen) /* Since this is the default screen, use the one already created. */ ssi->toplevel_shell = toplevel_shell; @@ -706,6 +751,10 @@ initialize_per_screen_info (saver_info *si, Widget toplevel_shell) } si->fading_possible_p = found_any_writable_cells; + +#ifdef HAVE_XF86VMODE_GAMMA + si->fading_possible_p = True; /* if we can gamma fade, go for it */ +#endif } @@ -863,6 +912,14 @@ maybe_reload_init_file (saver_info *si) /* If a server extension is in use, and p->timeout has changed, we need to inform the server of the new timeout. */ disable_builtin_screensaver (si, False); + + /* If the DPMS settings in the init file have changed, + change the settings on the server to match. */ + sync_server_dpms_settings (si->dpy, p->dpms_enabled_p, + p->dpms_standby / 1000, + p->dpms_suspend / 1000, + p->dpms_off / 1000, + False); } } @@ -1071,7 +1128,7 @@ main (int argc, char **argv) global_si_kludge = si; /* I hate C so much... */ # undef ya_rand_init - ya_rand_init ((int) time ((time_t *) 0)); + ya_rand_init (0); save_argv (argc, argv); set_version_string (si, &argc, argv); @@ -1109,7 +1166,14 @@ main (int argc, char **argv) select_events (si); init_sigchld (); + disable_builtin_screensaver (si, True); + sync_server_dpms_settings (si->dpy, p->dpms_enabled_p, + p->dpms_standby / 1000, + p->dpms_suspend / 1000, + p->dpms_off / 1000, + False); + initialize_stderr (si); make_splash_dialog (si); @@ -1122,6 +1186,47 @@ main (int argc, char **argv) /* Processing ClientMessage events. */ + +static Bool error_handler_hit_p = False; + +static int +ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) +{ + error_handler_hit_p = True; + return 0; +} + +/* Sometimes some systems send us ClientMessage events with bogus atoms in + them. We only look up the atom names for printing warning messages, + so don't bomb out when it happens... + */ +static char * +XGetAtomName_safe (Display *dpy, Atom atom) +{ + char *result; + XErrorHandler old_handler; + if (!atom) return 0; + + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + result = XGetAtomName (dpy, atom); + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + if (error_handler_hit_p) result = 0; + + if (result) + return result; + else + { + char buf[100]; + sprintf (buf, "<>", (unsigned long) atom); + return strdup (buf); + } +} + + static void clientmessage_response (saver_info *si, Window w, Bool error, const char *stderr_msg, @@ -1130,6 +1235,8 @@ clientmessage_response (saver_info *si, Window w, Bool error, char *proto; int L; saver_preferences *p = &si->prefs; + XErrorHandler old_handler; + if (error || p->verbose_p) fprintf (stderr, "%s: %s\n", blurb(), stderr_msg); @@ -1139,9 +1246,23 @@ clientmessage_response (saver_info *si, Window w, Bool error, strcpy (proto+1, protocol_msg); L++; + /* Ignore all X errors while sending a response to a ClientMessage. + Pretty much the only way we could get an error here is if the + window we're trying to send the reply on has been deleted, in + which case, the sender of the ClientMessage won't see our response + anyway. + */ + XSync (si->dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + XChangeProperty (si->dpy, w, XA_SCREENSAVER_RESPONSE, XA_STRING, 8, PropModeReplace, (unsigned char *) proto, L); + + XSync (si->dpy, False); + XSetErrorHandler (old_handler); XSync (si->dpy, False); + free (proto); } @@ -1158,7 +1279,7 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p) if (event->xclient.message_type != XA_SCREENSAVER) { char *str; - str = XGetAtomName (si->dpy, event->xclient.message_type); + str = XGetAtomName_safe (si->dpy, event->xclient.message_type); fprintf (stderr, "%s: unrecognised ClientMessage type %s received\n", blurb(), (str ? str : "(null)")); if (str) XFree (str); @@ -1505,7 +1626,7 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p) { char buf [1024]; char *str; - str = (type ? XGetAtomName(si->dpy, type) : 0); + str = XGetAtomName_safe (si->dpy, type); if (str) { @@ -1535,19 +1656,79 @@ static void analyze_display (saver_info *si) { int i, j; - static const char *exts[][2] = { - { "SCREEN_SAVER", "SGI Screen-Saver" }, - { "SCREEN-SAVER", "SGI Screen-Saver" }, - { "MIT-SCREEN-SAVER", "MIT Screen-Saver" }, - { "XIDLE", "XIdle" }, - { "SGI-VIDEO-CONTROL", "SGI Video-Control" }, - { "READDISPLAY", "SGI Read-Display" }, - { "MIT-SHM", "Shared Memory" }, - { "DOUBLE-BUFFER", "Double-Buffering" }, - { "DPMS", "Power Management" }, - { "GLX", "GLX" }, - { "XFree86-VidModeExtension", "XF86 Video-Mode" }, - { "XINERAMA", "Xinerama" } + static struct { + const char *name; const char *desc; Bool useful_p; + } exts[] = { + + { "SCREEN_SAVER", "SGI Screen-Saver", +# ifdef HAVE_SGI_SAVER_EXTENSION + True +# else + False +# endif + }, { "SCREEN-SAVER", "SGI Screen-Saver", +# ifdef HAVE_SGI_SAVER_EXTENSION + True +# else + False +# endif + }, { "MIT-SCREEN-SAVER", "MIT Screen-Saver", +# ifdef HAVE_MIT_SAVER_EXTENSION + True +# else + False +# endif + }, { "XIDLE", "XIdle", +# ifdef HAVE_XIDLE_EXTENSION + True +# else + False +# endif + }, { "SGI-VIDEO-CONTROL", "SGI Video-Control", +# ifdef HAVE_SGI_VC_EXTENSION + True +# else + False +# endif + }, { "READDISPLAY", "SGI Read-Display", +# ifdef HAVE_READ_DISPLAY_EXTENSION + True +# else + False +# endif + }, { "MIT-SHM", "Shared Memory", +# ifdef HAVE_XSHM_EXTENSION + True +# else + False +# endif + }, { "DOUBLE-BUFFER", "Double-Buffering", +# ifdef HAVE_DOUBLE_BUFFER_EXTENSION + True +# else + False +# endif + }, { "DPMS", "Power Management", +# ifdef HAVE_DPMS_EXTENSION + True +# else + False +# endif + }, { "GLX", "GLX", +# ifdef HAVE_GL + True +# else + False +# endif + }, { "XFree86-VidModeExtension", "XF86 Video-Mode", +# ifdef HAVE_XF86VMODE + True +# else + False +# endif + }, { "XINERAMA", "Xinerama", + True + }, }; fprintf (stderr, "%s: running on display \"%s\"\n", blurb(), @@ -1559,8 +1740,11 @@ analyze_display (saver_info *si) for (i = 0; i < countof(exts); i++) { int op = 0, event = 0, error = 0; - if (XQueryExtension (si->dpy, exts[i][0], &op, &event, &error)) - fprintf (stderr, "%s: %s\n", blurb(), exts[i][1]); + if (XQueryExtension (si->dpy, exts[i].name, &op, &event, &error)) + fprintf (stderr, "%s: %s%s\n", blurb(), + exts[i].desc, + (exts[i].useful_p ? "" : + " \t<== unsupported at compile-time!")); } for (i = 0; i < si->nscreens; i++)