1 /* xset.c --- interacting with server extensions and the builtin screensaver.
2 * xscreensaver, Copyright (c) 1991-2008 Jamie Zawinski <jwz@jwz.org>
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation. No representations are made about the suitability of this
9 * software for any purpose. It is provided "as is" without express or
19 #include <X11/Xutil.h>
20 #include <X11/Xatom.h>
23 /* This file doesn't need the Xt headers, so stub these types out... */
25 #define XtAppContext void*
26 #define XrmDatabase void*
27 #define XtIntervalId void*
28 #define XtPointer void*
31 #include "xscreensaver.h"
34 ERROR! You must not include vroot.h in this file.
38 /* MIT SCREEN-SAVER server extension hackery.
41 #ifdef HAVE_MIT_SAVER_EXTENSION
43 # include <X11/extensions/scrnsaver.h>
46 ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
52 init_mit_saver_extension (saver_info *si)
55 Pixmap *blank_pix = (Pixmap *) calloc (sizeof(Pixmap), si->nscreens);
57 for (i = 0; i < si->nscreens; i++)
59 saver_screen_info *ssi = &si->screens[i];
62 Window root = RootWindowOfScreen (ssi->screen);
63 blank_pix[i] = XCreatePixmap (si->dpy, root, 1, 1, 1);
65 /* Kill off the old MIT-SCREEN-SAVER client if there is one.
66 This tends to generate X errors, though (possibly due to a bug
67 in the server extension itself?) so just ignore errors here. */
68 if (XScreenSaverGetRegistered (si->dpy,
69 XScreenNumberOfScreen (ssi->screen),
71 && kill_id != blank_pix[i])
73 XErrorHandler old_handler =
74 XSetErrorHandler (ignore_all_errors_ehandler);
75 XKillClient (si->dpy, kill_id);
76 XSync (si->dpy, False);
77 XSetErrorHandler (old_handler);
79 XScreenSaverSelectInput (si->dpy, root, ScreenSaverNotifyMask);
80 XScreenSaverRegister (si->dpy,
81 XScreenNumberOfScreen (ssi->screen),
82 (XID) blank_pix[i], XA_PIXMAP);
86 #endif /* HAVE_MIT_SAVER_EXTENSION */
89 /* SGI SCREEN_SAVER server extension hackery.
92 #ifdef HAVE_SGI_SAVER_EXTENSION
94 # include <X11/extensions/XScreenSaver.h>
97 init_sgi_saver_extension (saver_info *si)
99 saver_preferences *p = &si->prefs;
101 if (si->screen_blanked_p)
102 /* If you mess with this while the server thinks it's active,
103 the server crashes. */
106 for (i = 0; i < si->nscreens; i++)
108 saver_screen_info *ssi = &si->screens[i];
109 XScreenSaverDisable (si->dpy, XScreenNumberOfScreen(ssi->screen));
110 if (! XScreenSaverEnable (si->dpy, XScreenNumberOfScreen(ssi->screen)))
113 "%s: SGI SCREEN_SAVER extension exists, but can't be initialized;\n\
114 perhaps some other screensaver program is already running?\n",
116 si->using_sgi_saver_extension = False;
122 #endif /* HAVE_SGI_SAVER_EXTENSION */
126 /* Figuring out what the appropriate XSetScreenSaver() parameters are
127 (one wouldn't expect this to be rocket science.)
131 disable_builtin_screensaver (saver_info *si, Bool unblank_screen_p)
133 saver_preferences *p = &si->prefs;
134 int current_server_timeout, current_server_interval;
135 int current_prefer_blank, current_allow_exp;
136 int desired_server_timeout, desired_server_interval;
137 int desired_prefer_blank, desired_allow_exp;
139 XGetScreenSaver (si->dpy, ¤t_server_timeout, ¤t_server_interval,
140 ¤t_prefer_blank, ¤t_allow_exp);
142 desired_server_timeout = current_server_timeout;
143 desired_server_interval = current_server_interval;
144 desired_prefer_blank = current_prefer_blank;
145 desired_allow_exp = current_allow_exp;
147 /* On SGIs, if interval is non-zero, it is the number of seconds after
148 screen saving starts at which the monitor should be powered down.
149 Obviously I don't want that, so set it to 0 (meaning "never".)
151 Power saving is disabled if DontPreferBlanking, but in that case,
152 we don't get extension events either. So we can't turn it off that way.
154 Note: if you're running Irix 6.3 (O2), you may find that your monitor is
155 powering down anyway, regardless of the xset settings. This is fixed by
156 installing SGI patches 2447 and 2537.
158 desired_server_interval = 0;
160 /* I suspect (but am not sure) that DontAllowExposures might have
161 something to do with powering off the monitor as well, at least
162 on some systems that don't support XDPMS? Who knows... */
163 desired_allow_exp = AllowExposures;
165 if (si->using_mit_saver_extension || si->using_sgi_saver_extension)
167 desired_server_timeout = (p->timeout / 1000);
169 /* The SGI extension won't give us events unless blanking is on.
170 I think (unsure right now) that the MIT extension is the opposite. */
171 if (si->using_sgi_saver_extension)
172 desired_prefer_blank = PreferBlanking;
174 desired_prefer_blank = DontPreferBlanking;
178 /* When we're not using an extension, set the server-side timeout to 0,
179 so that the server never gets involved with screen blanking, and we
180 do it all ourselves. (However, when we *are* using an extension,
181 we tell the server when to notify us, and rather than blanking the
182 screen, the server will send us an X event telling us to blank.)
184 desired_server_timeout = 0;
187 /* XSetScreenSaver() generates BadValue if either timeout parameter
188 exceeds 15 bits (signed short.) That is 09:06:07.
190 if (desired_server_timeout > 0x7FFF) desired_server_timeout = 0x7FFF;
191 if (desired_server_interval > 0x7FFF) desired_server_interval = 0x7FFF;
193 if (desired_server_timeout != current_server_timeout ||
194 desired_server_interval != current_server_interval ||
195 desired_prefer_blank != current_prefer_blank ||
196 desired_allow_exp != current_allow_exp)
200 "%s: disabling server builtin screensaver:\n"
201 "%s: (xset s %d %d; xset s %s; xset s %s)\n",
203 desired_server_timeout, desired_server_interval,
204 (desired_prefer_blank ? "blank" : "noblank"),
205 (desired_allow_exp ? "expose" : "noexpose"));
207 XSetScreenSaver (si->dpy,
208 desired_server_timeout, desired_server_interval,
209 desired_prefer_blank, desired_allow_exp);
210 XSync(si->dpy, False);
214 #if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
216 static Bool extension_initted = False;
217 if (!extension_initted)
219 extension_initted = True;
220 # ifdef HAVE_MIT_SAVER_EXTENSION
221 if (si->using_mit_saver_extension) init_mit_saver_extension(si);
223 # ifdef HAVE_SGI_SAVER_EXTENSION
224 if (si->using_sgi_saver_extension) init_sgi_saver_extension(si);
228 #endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
230 if (unblank_screen_p)
231 /* Turn off the server builtin saver if it is now running. */
232 XForceScreenSaver (si->dpy, ScreenSaverReset);