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