/* dpms.c --- syncing the X Display Power Management values
- * xscreensaver, Copyright (c) 2001-2011 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 2001-2017 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#ifdef HAVE_DPMS_EXTENSION
+static Bool error_handler_hit_p = False;
+
+static int
+ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
+{
+ error_handler_hit_p = True;
+ return 0;
+}
+
+
void
-sync_server_dpms_settings (Display *dpy, Bool enabled_p,
+sync_server_dpms_settings (Display *dpy, Bool enabled_p, Bool dpms_quickoff_p,
int standby_secs, int suspend_secs, int off_secs,
Bool verbose_p)
{
CARD16 o_standby = 0, o_suspend = 0, o_off = 0;
Bool bogus_p = False;
+ if (dpms_quickoff_p && !off_secs)
+ {
+ /* To do this, we might need to temporarily re-enable DPMS first. */
+ off_secs = 0xFFFF;
+ }
+
if (standby_secs == 0 && suspend_secs == 0 && off_secs == 0)
/* all zero implies "DPMS disabled" */
enabled_p = False;
{
if ((!!on_p) != monitor_powered_on_p (si))
{
+ XErrorHandler old_handler;
int event_number, error_number;
if (!DPMSQueryExtension(si->dpy, &event_number, &error_number) ||
!DPMSCapable(si->dpy))
return;
}
+ /* The manual for DPMSForceLevel() says that it throws BadMatch if
+ "DPMS is disabled on the specified display."
+
+ The manual for DPMSCapable() says that it "returns True if the X
+ server is capable of DPMS."
+
+ Apparently they consider "capable of DPMS" and "DPMS is enabled"
+ to be different things, and so even if DPMSCapable() returns
+ True, DPMSForceLevel() *might* throw an X Error. Isn't that
+ just fucking special.
+ */
+ XSync (si->dpy, False);
+ error_handler_hit_p = False;
+ old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
+ XSync (si->dpy, False);
DPMSForceLevel(si->dpy, (on_p ? DPMSModeOn : DPMSModeOff));
- XSync(si->dpy, False);
+ XSync (si->dpy, False);
+ XSetErrorHandler (old_handler);
+ /* Ignore error_handler_hit_p, just probe monitor instead */
if ((!!on_p) != monitor_powered_on_p (si)) /* double-check */
fprintf (stderr,