X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fdpms.c;h=526c4bdedb84a3bcd30b6dea84db6b95f4807df3;hb=f0261d8acab611f3433160e4f07367b870439739;hp=570c2348083f1d11f02ac24413252ae03c55681a;hpb=ebc241816cc8e3eec7270a594bb1a607df32bcd6;p=xscreensaver diff --git a/driver/dpms.c b/driver/dpms.c index 570c2348..526c4bde 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 Jamie Zawinski + * xscreensaver, Copyright (c) 2001-2009 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 @@ -10,6 +10,40 @@ * implied warranty. */ +/* Display Power Management System (DPMS.) + + On XFree86 systems, "man xset" reports: + + -dpms The -dpms option disables DPMS (Energy Star) features. + +dpms The +dpms option enables DPMS (Energy Star) features. + + dpms flags... + The dpms option allows the DPMS (Energy Star) + parameters to be set. The option can take up to three + numerical values, or the `force' flag followed by a + DPMS state. The `force' flags forces the server to + immediately switch to the DPMS state specified. The + DPMS state can be one of `standby', `suspend', or + `off'. When numerical values are given, they set the + inactivity period before the three modes are activated. + The first value given is for the `standby' mode, the + second is for the `suspend' mode, and the third is for + the `off' mode. Setting these values implicitly + enables the DPMS features. A value of zero disables a + particular mode. + + However, note that the implementation is more than a little bogus, + in that there is code in /usr/X11R6/lib/libXdpms.a to implement all + the usual server-extension-querying utilities -- but there are no + prototypes in any header file! Thus, the prototypes here. (The + stuff in X11/extensions/dpms.h and X11/extensions/dpmsstr.h define + the raw X protcol, they don't define the API to libXdpms.a.) + + Some documentation: + Library: ftp://ftp.x.org/pub/R6.4/xc/doc/specs/Xext/DPMSLib.ms + Protocol: ftp://ftp.x.org/pub/R6.4/xc/doc/specs/Xext/DPMS.ms + */ + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -17,23 +51,25 @@ #include #include -#ifdef HAVE_DPMS_EXTENSION +#ifdef HAVE_DPMS_EXTENSION /* almost the whole file */ # include # include -# include +/*# include */ /* Why this crap is not in a header file somewhere, I have no idea. Losers! */ - extern Bool DPMSQueryExtension (Display *dpy, int *event_ret, int *err_ret); - extern Bool DPMSCapable (Display *dpy); - extern Status DPMSInfo (Display *dpy, CARD16 *power_level, BOOL *state); - extern Status DPMSSetTimeouts (Display *dpy, - CARD16 standby, CARD16 suspend, CARD16 off); - extern Bool DPMSGetTimeouts (Display *dpy, - CARD16 *standby, CARD16 *suspend, CARD16 *off); + extern Bool DPMSQueryExtension (Display *, int *event_ret, int *err_ret); + extern Status DPMSGetVersion (Display *, int *major_ret, int *minor_ret); + extern Bool DPMSCapable (Display *); + extern Status DPMSInfo (Display *, CARD16 *power_level, BOOL *state); extern Status DPMSEnable (Display *dpy); extern Status DPMSDisable (Display *dpy); + extern Status DPMSForceLevel (Display *, CARD16 level); + extern Status DPMSSetTimeouts (Display *, CARD16 standby, CARD16 suspend, + CARD16 off); + extern Bool DPMSGetTimeouts (Display *, CARD16 *standby, + CARD16 *suspend, CARD16 *off); #endif /* HAVE_DPMS_EXTENSION */ @@ -48,22 +84,38 @@ #include "xscreensaver.h" +#ifdef HAVE_DPMS_EXTENSION + void sync_server_dpms_settings (Display *dpy, Bool enabled_p, int standby_secs, int suspend_secs, int off_secs, Bool verbose_p) { -# ifdef HAVE_DPMS_EXTENSION - int event = 0, error = 0; BOOL o_enabled = False; CARD16 o_power = 0; CARD16 o_standby = 0, o_suspend = 0, o_off = 0; + Bool bogus_p = False; - Bool bogus_p = (standby_secs == 0 || suspend_secs == 0 || off_secs == 0); + if (standby_secs == 0 && suspend_secs == 0 && off_secs == 0) + /* all zero implies "DPMS disabled" */ + enabled_p = False; + + else if ((standby_secs != 0 && standby_secs < 10) || + (suspend_secs != 0 && suspend_secs < 10) || + (off_secs != 0 && off_secs < 10)) + /* any negative, or any positive-and-less-than-10-seconds, is crazy. */ + bogus_p = True; if (bogus_p) enabled_p = False; + /* X protocol sends these values in a CARD16, so truncate them to 16 bits. + This means that the maximum timeout is 18:12:15. + */ + if (standby_secs > 0xFFFF) standby_secs = 0xFFFF; + if (suspend_secs > 0xFFFF) suspend_secs = 0xFFFF; + if (off_secs > 0xFFFF) off_secs = 0xFFFF; + if (! DPMSQueryExtension (dpy, &event, &error)) { if (verbose_p) @@ -127,11 +179,78 @@ sync_server_dpms_settings (Display *dpy, Bool enabled_p, fprintf (stderr, "%s: set DPMS timeouts: %d %d %d.\n", blurb(), standby_secs, suspend_secs, off_secs); } +} + +Bool +monitor_powered_on_p (saver_info *si) +{ + Bool result; + int event_number, error_number; + BOOL onoff = False; + CARD16 state; + + if (!DPMSQueryExtension(si->dpy, &event_number, &error_number)) + /* Server doesn't know -- assume the monitor is on. */ + result = True; + + else if (!DPMSCapable(si->dpy)) + /* Server says the monitor doesn't do power management -- so it's on. */ + result = True; + + else + { + DPMSInfo(si->dpy, &state, &onoff); + if (!onoff) + /* Server says DPMS is disabled -- so the monitor is on. */ + result = True; + else + switch (state) { + case DPMSModeOn: result = True; break; /* really on */ + case DPMSModeStandby: result = False; break; /* kinda off */ + case DPMSModeSuspend: result = False; break; /* pretty off */ + case DPMSModeOff: result = False; break; /* really off */ + default: result = True; break; /* protocol error? */ + } + } -# else /* !HAVE_DPMS_EXTENSION */ + return result; +} +void +monitor_power_on (saver_info *si) +{ + if (!monitor_powered_on_p (si)) + { + DPMSForceLevel(si->dpy, DPMSModeOn); + XSync(si->dpy, False); + if (!monitor_powered_on_p (si)) + fprintf (stderr, + "%s: DPMSForceLevel(dpy, DPMSModeOn) did not power the monitor on?\n", + blurb()); + } +} + +#else /* !HAVE_DPMS_EXTENSION */ + +void +sync_server_dpms_settings (Display *dpy, Bool enabled_p, + int standby_secs, int suspend_secs, int off_secs, + Bool verbose_p) +{ if (verbose_p) fprintf (stderr, "%s: DPMS support not compiled in.\n", blurb()); +} + +Bool +monitor_powered_on_p (saver_info *si) +{ + return True; +} -# endif /* HAVE_DPMS_EXTENSION */ +void +monitor_power_on (saver_info *si) +{ + return; } + +#endif /* !HAVE_DPMS_EXTENSION */