From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / driver / dpms.c
index b45f4d2f2e130bb60174753cd945457eb37cb7c6..553e476ee0886597ff6bfd4453a0e6c61732d1ad 100644 (file)
@@ -1,5 +1,5 @@
 /* dpms.c --- syncing the X Display Power Management values
- * xscreensaver, Copyright (c) 2001, 2005 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
@@ -55,7 +55,7 @@
 
 # include <X11/Xproto.h>
 # include <X11/extensions/dpms.h>
-# include <X11/extensions/dpmsstr.h>
+/*# include <X11/extensions/dpmsstr.h>*/
 
   /* Why this crap is not in a header file somewhere, I have no idea.  Losers!
    */
 
 #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)
 {
@@ -97,6 +107,12 @@ sync_server_dpms_settings (Display *dpy, Bool enabled_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;
@@ -217,16 +233,47 @@ monitor_powered_on_p (saver_info *si)
 }
 
 void
-monitor_power_on (saver_info *si)
+monitor_power_on (saver_info *si, Bool on_p)
 {
-  if (!monitor_powered_on_p (si))
+  if ((!!on_p) != monitor_powered_on_p (si))
     {
-      DPMSForceLevel(si->dpy, DPMSModeOn);
-      XSync(si->dpy, False);
-      if (!monitor_powered_on_p (si))
+      XErrorHandler old_handler;
+      int event_number, error_number;
+      if (!DPMSQueryExtension(si->dpy, &event_number, &error_number) ||
+          !DPMSCapable(si->dpy))
+        {
+          if (si->prefs.verbose_p)
+            fprintf (stderr,
+                     "%s: unable to power %s monitor: no DPMS extension.\n",
+                     blurb(), (on_p ? "on" : "off"));
+          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);
+      XSetErrorHandler (old_handler);
+      /* Ignore error_handler_hit_p, just probe monitor instead */
+
+      if ((!!on_p) != monitor_powered_on_p (si))  /* double-check */
        fprintf (stderr,
-       "%s: DPMSForceLevel(dpy, DPMSModeOn) did not power the monitor on?\n",
-                blurb());
+       "%s: DPMSForceLevel(dpy, %s) did not change monitor power state.\n",
+                blurb(),
+                 (on_p ? "DPMSModeOn" : "DPMSModeOff"));
     }
 }
 
@@ -248,7 +295,7 @@ monitor_powered_on_p (saver_info *si)
 }
 
 void
-monitor_power_on (saver_info *si)
+monitor_power_on (saver_info *si, Bool on_p)
 {
   return; 
 }