X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fdpms.c;h=a0dd7b87a2a37d507b808aabe0ee8ca00c732754;hb=39809ded547bdbb08207d3e514950425215b4410;hp=b45f4d2f2e130bb60174753cd945457eb37cb7c6;hpb=3f438031d610c7e15fd33876a879b97e290e05fb;p=xscreensaver diff --git a/driver/dpms.c b/driver/dpms.c index b45f4d2f..a0dd7b87 100644 --- a/driver/dpms.c +++ b/driver/dpms.c @@ -1,5 +1,5 @@ /* dpms.c --- syncing the X Display Power Management values - * xscreensaver, Copyright (c) 2001, 2005 Jamie Zawinski + * xscreensaver, Copyright (c) 2001-2017 Jamie Zawinski * * 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 # include -# include +/*# include */ /* Why this crap is not in a header file somewhere, I have no idea. Losers! */ @@ -86,8 +86,18 @@ #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")); } } @@ -234,6 +281,7 @@ monitor_power_on (saver_info *si) void 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) { @@ -248,7 +296,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; }