/* xset.c --- interacting with server extensions and the builtin screensaver.
- * xscreensaver, Copyright (c) 1991-1997 Jamie Zawinski <jwz@netscape.com>
+ * xscreensaver, Copyright (c) 1991-2004 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
#include "xscreensaver.h"
+#ifdef _VROOT_H_
+ERROR! You must not include vroot.h in this file.
+#endif
+
\f
/* MIT SCREEN-SAVER server extension hackery.
*/
fprintf (stderr,
"%s: SGI SCREEN_SAVER extension exists, but can't be initialized;\n\
perhaps some other screensaver program is already running?\n",
- progname);
- p->use_sgi_saver_extension = False;
+ blurb());
+ si->using_sgi_saver_extension = False;
return;
}
}
#endif /* HAVE_SGI_SAVER_EXTENSION */
\f
-/* Figuring out what the appropriate XSetScreenSaver() paramters are
+/* XIDLE server extension hackery.
+ */
+
+#ifdef HAVE_XIDLE_EXTENSION
+
+# include <X11/extensions/xidle.h>
+
+Bool
+query_xidle_extension (saver_info *si)
+{
+ int event_number;
+ int error_number;
+ return XidleQueryExtension (si->dpy, &event_number, &error_number);
+}
+
+#endif /* HAVE_XIDLE_EXTENSION */
+
+
+\f
+/* Resize and Rotate server extension hackery.
+ */
+
+#ifdef HAVE_RANDR
+
+# include <X11/extensions/Xrandr.h>
+
+Bool
+query_randr_extension (saver_info *si)
+{
+ saver_preferences *p = &si->prefs;
+ Bool ok = XRRQueryExtension (si->dpy,
+ &si->randr_event_number,
+ &si->randr_error_number);
+ if (ok)
+ {
+ int nscreens = ScreenCount (si->dpy); /* number of *real* screens */
+ int i;
+
+ if (p->verbose_p)
+ fprintf (stderr, "%s: selecting RANDR events\n", blurb());
+ for (i = 0; i < nscreens; i++)
+ XRRSelectInput (si->dpy, RootWindow (si->dpy, i),
+ RRScreenChangeNotifyMask);
+ }
+
+ return ok;
+}
+
+#endif /* HAVE_XIDLE_EXTENSION */
+
+
+\f
+/* Figuring out what the appropriate XSetScreenSaver() parameters are
(one wouldn't expect this to be rocket science.)
*/
void
-disable_builtin_screensaver (saver_info *si, Bool turn_off_p)
+disable_builtin_screensaver (saver_info *si, Bool unblank_screen_p)
{
saver_preferences *p = &si->prefs;
int current_server_timeout, current_server_interval;
/* On SGIs, if interval is non-zero, it is the number of seconds after
screen saving starts at which the monitor should be powered down.
- Obviously I don't want that, so make sure it's 0.
+ Obviously I don't want that, so set it to 0 (meaning "never".)
Power saving is disabled if DontPreferBlanking, but in that case,
we don't get extension events either. So we can't turn it off that way.
+
+ Note: if you're running Irix 6.3 (O2), you may find that your monitor is
+ powering down anyway, regardless of the xset settings. This is fixed by
+ installing SGI patches 2447 and 2537.
*/
desired_server_interval = 0;
/* I suspect (but am not sure) that DontAllowExposures might have
- something to do with powering off the monitor as well. */
+ something to do with powering off the monitor as well, at least
+ on some systems that don't support XDPMS? Who know... */
desired_allow_exp = AllowExposures;
-#if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
- if (p->use_mit_saver_extension || p->use_sgi_saver_extension)
+ if (si->using_mit_saver_extension || si->using_sgi_saver_extension)
{
desired_server_timeout = (p->timeout / 1000);
/* The SGI extension won't give us events unless blanking is on.
I think (unsure right now) that the MIT extension is the opposite. */
- if (p->use_sgi_saver_extension)
+ if (si->using_sgi_saver_extension)
desired_prefer_blank = PreferBlanking;
else
desired_prefer_blank = DontPreferBlanking;
}
else
-#endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
{
+ /* When we're not using an extension, set the server-side timeout to 0,
+ so that the server never gets involved with screen blanking, and we
+ do it all ourselves. (However, when we *are* using an extension,
+ we tell the server when to notify us, and rather than blanking the
+ screen, the server will send us an X event telling us to blank.)
+ */
desired_server_timeout = 0;
}
desired_prefer_blank != current_prefer_blank ||
desired_allow_exp != current_allow_exp)
{
- if (desired_server_timeout == 0)
- printf ("%s%sisabling server builtin screensaver.\n\
- You can re-enable it with \"xset s on\".\n",
- (p->verbose_p ? "" : progname),
- (p->verbose_p ? "\n\tD" : ": d"));
-
if (p->verbose_p)
- fprintf (stderr, "%s: (xset s %d %d %s %s)\n", progname,
+ fprintf (stderr,
+ "%s: disabling server builtin screensaver:\n"
+ "%s: (xset s %d %d; xset s %s; xset s %s)\n",
+ blurb(), blurb(),
desired_server_timeout, desired_server_interval,
(desired_prefer_blank ? "blank" : "noblank"),
- (desired_allow_exp ? "noexpose" : "expose"));
+ (desired_allow_exp ? "expose" : "noexpose"));
XSetScreenSaver (si->dpy,
desired_server_timeout, desired_server_interval,
{
extension_initted = True;
# ifdef HAVE_MIT_SAVER_EXTENSION
- if (p->use_mit_saver_extension) init_mit_saver_extension(si);
+ if (si->using_mit_saver_extension) init_mit_saver_extension(si);
# endif
# ifdef HAVE_SGI_SAVER_EXTENSION
- if (p->use_sgi_saver_extension) init_sgi_saver_extension(si);
+ if (si->using_sgi_saver_extension) init_sgi_saver_extension(si);
# endif
}
}
#endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
- if (turn_off_p)
+ if (unblank_screen_p)
/* Turn off the server builtin saver if it is now running. */
XForceScreenSaver (si->dpy, ScreenSaverReset);
}
+
+\f
+/* 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_DPMS_EXTENSION
+
+#include <X11/Xproto.h> /* for CARD16 */
+#include <X11/extensions/dpms.h>
+#include <X11/extensions/dpmsstr.h>
+
+extern Bool DPMSQueryExtension (Display *dpy, int *event_ret, int *error_ret);
+extern Bool DPMSCapable (Display *dpy);
+extern Status DPMSForceLevel (Display *dpy, CARD16 level);
+extern Status DPMSInfo (Display *dpy, CARD16 *power_level, BOOL *state);
+
+#if 0 /* others we don't use */
+extern Status DPMSGetVersion (Display *dpy, int *major_ret, int *minor_ret);
+extern Status DPMSSetTimeouts (Display *dpy,
+ CARD16 standby, CARD16 suspend, CARD16 off);
+extern Bool DPMSGetTimeouts (Display *dpy,
+ CARD16 *standby, CARD16 *suspend, CARD16 *off);
+extern Status DPMSEnable (Display *dpy);
+extern Status DPMSDisable (Display *dpy);
+#endif /* 0 */
+
+
+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? */
+ }
+ }
+
+ 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 */
+
+Bool
+monitor_powered_on_p (saver_info *si)
+{
+ return True;
+}
+
+void
+monitor_power_on (saver_info *si)
+{
+ return;
+}
+
+#endif /* !HAVE_DPMS_EXTENSION */