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");
"#######################################"
"#######################################\n\n");
fprintf (real_stderr,
- " If at all possible, please re-run xscreensaver with the command\ e\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"
char *d = getenv ("DISPLAY");
if (!d || !*d)
{
- const char ndpy[] = "DISPLAY=:0.0";
+ 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",
}
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
}
/* 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);
}
}
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);
/* 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, "<<undefined atom 0x%04X>>", (unsigned long) atom);
+ return strdup (buf);
+ }
+}
+
+
static void
clientmessage_response (saver_info *si, Window w, Bool error,
const char *stderr_msg,
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);
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);
}
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);
return True;
}
}
- clientmessage_response(si, window, True,
- "ClientMessage DEACTIVATE received while inactive.",
- "not active.");
+ clientmessage_response(si, window, False,
+ "ClientMessage DEACTIVATE received while inactive: resetting idle timer.",
+ "not active: idle timer reset.");
+ reset_timers (si);
}
else if (type == XA_CYCLE)
{
{
char buf [1024];
char *str;
- str = (type ? XGetAtomName(si->dpy, type) : 0);
+ str = XGetAtomName_safe (si->dpy, type);
if (str)
{