Blob Blame History Raw
diff -ur /tmp/xscreensaver-5.13/driver/XScreenSaver.ad.in ./driver/XScreenSaver.ad.in
--- /tmp/xscreensaver-5.13/driver/XScreenSaver.ad.in	2011-04-18 13:36:18.000000000 -0700
+++ ./driver/XScreenSaver.ad.in	2011-05-14 18:01:17.000000000 -0700
@@ -34,6 +34,7 @@
 *lockTimeout:		0:00:00
 *passwdTimeout:		0:00:30
 *dpmsEnabled:		False
+*dpmsQuickoffEnabled:	False
 *dpmsStandby:		2:00:00
 *dpmsSuspend:		2:00:00
 *dpmsOff:		4:00:00
diff -ur /tmp/xscreensaver-5.13/driver/XScreenSaver_ad.h ./driver/XScreenSaver_ad.h
--- /tmp/xscreensaver-5.13/driver/XScreenSaver_ad.h	2011-04-18 13:47:50.000000000 -0700
+++ ./driver/XScreenSaver_ad.h	2011-05-14 18:56:00.000000000 -0700
@@ -7,6 +7,7 @@
 "*lockTimeout:		0:00:00",
 "*passwdTimeout:		0:00:30",
 "*dpmsEnabled:		False",
+"*dpmsQuickoffEnabled:	False",
 "*dpmsStandby:		2:00:00",
 "*dpmsSuspend:		2:00:00",
 "*dpmsOff:		4:00:00",
diff -ur /tmp/xscreensaver-5.13/driver/demo-Gtk.c ./driver/demo-Gtk.c
--- /tmp/xscreensaver-5.13/driver/demo-Gtk.c	2011-01-09 17:45:07.000000000 -0800
+++ ./driver/demo-Gtk.c	2011-05-14 19:38:09.000000000 -0700
@@ -1,5 +1,5 @@
 /* demo-Gtk.c --- implements the interactive demo-mode and options dialogs.
- * xscreensaver, Copyright (c) 1993-2008 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1993-2011 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
@@ -1548,7 +1548,8 @@
   CHECKBOX (p2->lock_p,           "lock_button");
   MINUTES  (&p2->lock_timeout,    "lock_spinbutton");
 
-  CHECKBOX (p2->dpms_enabled_p,  "dpms_button");
+  CHECKBOX (p2->dpms_enabled_p,   "dpms_button");
+  CHECKBOX (p2->dpms_quickoff_p,  "dpms_quickoff_button");
   MINUTES  (&p2->dpms_standby,    "dpms_standby_spinbutton");
   MINUTES  (&p2->dpms_suspend,    "dpms_suspend_spinbutton");
   MINUTES  (&p2->dpms_off,        "dpms_off_spinbutton");
@@ -1647,10 +1648,11 @@
   COPY(lock_p,         "lock_p");
   COPY(lock_timeout,   "lock_timeout");
 
-  COPY(dpms_enabled_p, "dpms_enabled_p");
-  COPY(dpms_standby,   "dpms_standby");
-  COPY(dpms_suspend,   "dpms_suspend");
-  COPY(dpms_off,       "dpms_off");
+  COPY(dpms_enabled_p,  "dpms_enabled_p");
+  COPY(dpms_quickoff_p, "dpms_quickoff_enabled_p");
+  COPY(dpms_standby,    "dpms_standby");
+  COPY(dpms_suspend,    "dpms_suspend");
+  COPY(dpms_off,        "dpms_off");
 
 #if 0
   COPY(verbose_p,        "verbose_p");
@@ -2795,6 +2797,7 @@
   TOGGLE_ACTIVE ("splash_button",     p->splash_p);
 #endif
   TOGGLE_ACTIVE ("dpms_button",       p->dpms_enabled_p);
+  TOGGLE_ACTIVE ("dpms_quickoff_button", p->dpms_quickoff_p);
   TOGGLE_ACTIVE ("grab_desk_button",  p->grab_desktop_p);
   TOGGLE_ACTIVE ("grab_video_button", p->grab_video_p);
   TOGGLE_ACTIVE ("grab_image_button", p->random_image_p);
@@ -2898,8 +2901,11 @@
 
     /* DPMS
      */
+dpms_supported=1;
     SENSITIZE ("dpms_frame",              dpms_supported);
     SENSITIZE ("dpms_button",             dpms_supported);
+    SENSITIZE ("dpms_quickoff_button",    dpms_supported);
+
     SENSITIZE ("dpms_standby_label",      dpms_supported && p->dpms_enabled_p);
     SENSITIZE ("dpms_standby_mlabel",     dpms_supported && p->dpms_enabled_p);
     SENSITIZE ("dpms_standby_spinbutton", dpms_supported && p->dpms_enabled_p);
diff -ur /tmp/xscreensaver-5.13/driver/dpms.c ./driver/dpms.c
--- /tmp/xscreensaver-5.13/driver/dpms.c	2011-01-09 17:41:44.000000000 -0800
+++ ./driver/dpms.c	2011-05-14 18:01:17.000000000 -0700
@@ -86,6 +86,16 @@
 
 #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,
                            int standby_secs, int suspend_secs, int off_secs,
@@ -221,6 +231,7 @@
 {
   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))
@@ -232,8 +243,24 @@
           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);
+      /* Ignore error_handler_hit_p, just probe monitor instead */
 
       if ((!!on_p) != monitor_powered_on_p (si))  /* double-check */
 	fprintf (stderr,
diff -ur /tmp/xscreensaver-5.13/driver/prefs.c ./driver/prefs.c
--- /tmp/xscreensaver-5.13/driver/prefs.c	2011-01-11 02:30:20.000000000 -0800
+++ ./driver/prefs.c	2011-05-14 18:50:47.000000000 -0700
@@ -276,6 +276,7 @@
   "ignoreUninstalledPrograms",
   "font",
   "dpmsEnabled",
+  "dpmsQuickOff",
   "dpmsStandby",
   "dpmsSuspend",
   "dpmsOff",
@@ -817,6 +818,7 @@
       CHECK("font")		type = pref_str,  s =    stderr_font;
 
       CHECK("dpmsEnabled")	type = pref_bool, b = p->dpms_enabled_p;
+      CHECK("dpmsQuickOff")	type = pref_bool, b = p->dpms_quickoff_p;
       CHECK("dpmsStandby")	type = pref_time, t = p->dpms_standby;
       CHECK("dpmsSuspend")	type = pref_time, t = p->dpms_suspend;
       CHECK("dpmsOff")		type = pref_time, t = p->dpms_off;
@@ -1073,6 +1075,7 @@
 						       "Time");
 
   p->dpms_enabled_p  = get_boolean_resource (dpy, "dpmsEnabled", "Boolean");
+  p->dpms_quickoff_p = get_boolean_resource (dpy, "dpmsQuickOff", "Boolean");
   p->dpms_standby    = 1000 * get_minutes_resource (dpy, "dpmsStandby", "Time");
   p->dpms_suspend    = 1000 * get_minutes_resource (dpy, "dpmsSuspend", "Time");
   p->dpms_off        = 1000 * get_minutes_resource (dpy, "dpmsOff",     "Time");
diff -ur /tmp/xscreensaver-5.13/driver/test-xdpms.c ./driver/test-xdpms.c
--- /tmp/xscreensaver-5.13/driver/test-xdpms.c	2002-03-18 15:57:42.000000000 -0800
+++ ./driver/test-xdpms.c	2011-05-10 11:35:50.000000000 -0700
@@ -1,5 +1,5 @@
 /* test-xdpms.c --- playing with the XDPMS extension.
- * xscreensaver, Copyright (c) 1998 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1998-2011 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
@@ -65,6 +65,16 @@
 }
 
 
+static Bool error_handler_hit_p = False;
+
+static int
+ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
+{
+  error_handler_hit_p = True;
+  return 0;
+}
+
+
 int
 main (int argc, char **argv)
 {
@@ -148,11 +158,20 @@
 	  state == DPMSModeSuspend ||
 	  state == DPMSModeOff)
 	{
-	  Status st;
+          XErrorHandler old_handler;
+	  int st;
 	  fprintf(stderr, "%s: monitor is off; turning it on.\n", blurb());
+
+          XSync (dpy, False);
+          error_handler_hit_p = False;
+          old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
+          XSync (dpy, False);
 	  st = DPMSForceLevel (dpy, DPMSModeOn);
+          XSync (dpy, False);
+          if (error_handler_hit_p) st = -666;
+
 	  fprintf (stderr, "%s: DPMSForceLevel (dpy, DPMSModeOn) ==> %s\n",
-		   blurb(), (st ? "Ok" : "Error"));
+		   blurb(), (st == -666 ? "X Error" : st ? "Ok" : "Error"));
 	}
 
       sleep (delay);
diff -ur /tmp/xscreensaver-5.13/driver/types.h ./driver/types.h
--- /tmp/xscreensaver-5.13/driver/types.h	2010-09-15 01:43:27.000000000 -0700
+++ ./driver/types.h	2011-05-14 18:09:45.000000000 -0700
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1993-2008 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1993-2011 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
@@ -112,6 +112,8 @@
   int pointer_hysteresis;	/* mouse motions less than N/sec are ignored */
 
   Bool dpms_enabled_p;		/* Whether to power down the monitor */
+  Bool dpms_quickoff_p;		/* Whether to power down monitor immediately
+				   in "Blank Only" mode */
   Time dpms_standby;		/* how long until monitor goes black */
   Time dpms_suspend;		/* how long until monitor power-saves */
   Time dpms_off;		/* how long until monitor powers down */
diff -ur /tmp/xscreensaver-5.13/driver/xscreensaver-demo.glade2 ./driver/xscreensaver-demo.glade2
--- /tmp/xscreensaver-5.13/driver/xscreensaver-demo.glade2	2010-10-27 16:04:04.000000000 -0700
+++ ./driver/xscreensaver-demo.glade2	2011-05-14 19:39:13.000000000 -0700
@@ -2034,10 +2034,32 @@
 				</widget>
 				<packing>
 				  <property name="padding">0</property>
-				  <property name="expand">True</property>
+				  <property name="expand">False</property>
 				  <property name="fill">True</property>
 				</packing>
 			      </child>
+
+			      <child>
+				<widget class="GtkCheckButton" id="dpms_quickoff_button">
+				  <property name="visible">True</property>
+				  <property name="tooltip" translatable="yes">Whether the monitor should be powered off immediately in "Blank Screen Only" mode, regardless of the above power-management timeouts.</property>
+				  <property name="can_focus">True</property>
+				  <property name="label" translatable="yes">_Quick Power-off in Blank Only Mode</property>
+				  <property name="use_underline">True</property>
+				  <property name="relief">GTK_RELIEF_NORMAL</property>
+				  <property name="focus_on_click">True</property>
+				  <property name="active">False</property>
+				  <property name="inconsistent">False</property>
+				  <property name="draw_indicator">True</property>
+				  <signal name="toggled" handler="pref_changed_cb"/>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
+				</packing>
+			      </child>
+
 			    </widget>
 			    <packing>
 			      <property name="padding">0</property>
diff -ur /tmp/xscreensaver-5.13/driver/xscreensaver-demo.man ./driver/xscreensaver-demo.man
--- /tmp/xscreensaver-5.13/driver/xscreensaver-demo.man	2005-06-21 16:39:27.000000000 -0700
+++ ./driver/xscreensaver-demo.man	2011-05-14 18:50:20.000000000 -0700
@@ -256,6 +256,14 @@
 power down after this much idle time.  This duration should be greater
 than or equal to \fISuspend\fP.
 .TP 4
+.B Quick Power-off in "Blank Only" Mode
+If the display mode is set to \fIBlank Screen Only\fP and this is
+checked, then the monitor will be powered off immediately upon
+blanking, regardless of the other power-management settings.  In this
+way, the power management idle-timers can be completely disabled, but
+the screen will be powered off when black.  (This might be preferable
+on laptops.)
+.TP 4
 .B Fade To Black When Blanking
 If selected, then when the screensaver activates, the current contents
 of the screen will fade to black instead of simply winking out.  (Note:
diff -ur /tmp/xscreensaver-5.13/driver/xscreensaver.c ./driver/xscreensaver.c
--- /tmp/xscreensaver-5.13/driver/xscreensaver.c	2011-01-09 17:43:26.000000000 -0800
+++ ./driver/xscreensaver.c	2011-05-14 18:09:42.000000000 -0700
@@ -1227,10 +1227,22 @@
         for (i = 0; i < si->nscreens; i++)
           spawn_screenhack (&si->screens[i]);
 
-      /* If we are blanking only, we might as well power down the monitor
-         right now, regardless of what the DPMS settings are. */
-      if (p->mode == BLANK_ONLY)
-        monitor_power_on (si, False);
+      /* If we are blanking only, optionally power down monitor right now.
+         To do this, we might need to temporarily re-enable DPMS first.
+       */
+      if (p->mode == BLANK_ONLY &&
+          p->dpms_enabled_p && 
+          p->dpms_quickoff_p)
+        {
+          sync_server_dpms_settings (si->dpy, True,
+                                     p->dpms_standby / 1000,
+                                     p->dpms_suspend / 1000,
+                                     (p->dpms_off
+                                      ? (p->dpms_off / 1000)
+                                      : 0xFFFF),
+                                     False);
+          monitor_power_on (si, False);
+        }
 
       /* Don't start the cycle timer in demo mode. */
       if (!si->demoing_p && p->cycle)
diff -ur /tmp/xscreensaver-5.13/driver/xscreensaver.man ./driver/xscreensaver.man
--- /tmp/xscreensaver-5.13/driver/xscreensaver.man	2011-01-11 02:27:16.000000000 -0800
+++ ./driver/xscreensaver.man	2011-05-14 18:50:19.000000000 -0700
@@ -503,6 +503,11 @@
 all do.  See the \fIPower Management\fP section, below, for more 
 information.
 .TP 8
+.B dpmsQuickOff\fP (class \fBBoolean\fP)
+If \fImode\fP is \fIblank\fP and this is true, then the screen will be
+powered down immediately upon blanking, regardless of other
+power-management settings.
+.TP 8
 .B visualID\fP (class \fBVisualID\fP)
 Specify which X visual to use by default.  (Note carefully that this resource
 is called \fBvisualID\fP, not merely \fBvisual\fP; if you set the \fBvisual\fP