1 /* xset.c --- interacting with server extensions and the builtin screensaver.
2 * xscreensaver, Copyright (c) 1991-1997 Jamie Zawinski <jwz@netscape.com>
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 /* MIT SCREEN-SAVER server extension hackery.
37 #ifdef HAVE_MIT_SAVER_EXTENSION
39 # include <X11/extensions/scrnsaver.h>
42 query_mit_saver_extension (saver_info *si)
44 return XScreenSaverQueryExtension (si->dpy,
45 &si->mit_saver_ext_event_number,
46 &si->mit_saver_ext_error_number);
50 ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
56 init_mit_saver_extension (saver_info *si)
59 Pixmap *blank_pix = (Pixmap *) calloc (sizeof(Pixmap), si->nscreens);
61 for (i = 0; i < si->nscreens; i++)
63 saver_screen_info *ssi = &si->screens[i];
66 Window root = RootWindowOfScreen (ssi->screen);
67 blank_pix[i] = XCreatePixmap (si->dpy, root, 1, 1, 1);
69 /* Kill off the old MIT-SCREEN-SAVER client if there is one.
70 This tends to generate X errors, though (possibly due to a bug
71 in the server extension itself?) so just ignore errors here. */
72 if (XScreenSaverGetRegistered (si->dpy,
73 XScreenNumberOfScreen (ssi->screen),
75 && kill_id != blank_pix[i])
77 XErrorHandler old_handler =
78 XSetErrorHandler (ignore_all_errors_ehandler);
79 XKillClient (si->dpy, kill_id);
80 XSync (si->dpy, False);
81 XSetErrorHandler (old_handler);
83 XScreenSaverSelectInput (si->dpy, root, ScreenSaverNotifyMask);
84 XScreenSaverRegister (si->dpy,
85 XScreenNumberOfScreen (ssi->screen),
86 (XID) blank_pix[i], XA_PIXMAP);
90 #endif /* HAVE_MIT_SAVER_EXTENSION */
93 /* SGI SCREEN_SAVER server extension hackery.
96 #ifdef HAVE_SGI_SAVER_EXTENSION
98 # include <X11/extensions/XScreenSaver.h>
101 query_sgi_saver_extension (saver_info *si)
103 return XScreenSaverQueryExtension (si->dpy,
104 &si->sgi_saver_ext_event_number,
105 &si->sgi_saver_ext_error_number);
109 init_sgi_saver_extension (saver_info *si)
111 saver_preferences *p = &si->prefs;
113 if (si->screen_blanked_p)
114 /* If you mess with this while the server thinks it's active,
115 the server crashes. */
118 for (i = 0; i < si->nscreens; i++)
120 saver_screen_info *ssi = &si->screens[i];
121 XScreenSaverDisable (si->dpy, XScreenNumberOfScreen(ssi->screen));
122 if (! XScreenSaverEnable (si->dpy, XScreenNumberOfScreen(ssi->screen)))
125 "%s: SGI SCREEN_SAVER extension exists, but can't be initialized;\n\
126 perhaps some other screensaver program is already running?\n",
128 p->use_sgi_saver_extension = False;
134 #endif /* HAVE_SGI_SAVER_EXTENSION */
137 /* Figuring out what the appropriate XSetScreenSaver() paramters are
138 (one wouldn't expect this to be rocket science.)
142 disable_builtin_screensaver (saver_info *si, Bool turn_off_p)
144 saver_preferences *p = &si->prefs;
145 int current_server_timeout, current_server_interval;
146 int current_prefer_blank, current_allow_exp;
147 int desired_server_timeout, desired_server_interval;
148 int desired_prefer_blank, desired_allow_exp;
150 XGetScreenSaver (si->dpy, ¤t_server_timeout, ¤t_server_interval,
151 ¤t_prefer_blank, ¤t_allow_exp);
153 desired_server_timeout = current_server_timeout;
154 desired_server_interval = current_server_interval;
155 desired_prefer_blank = current_prefer_blank;
156 desired_allow_exp = current_allow_exp;
158 /* On SGIs, if interval is non-zero, it is the number of seconds after
159 screen saving starts at which the monitor should be powered down.
160 Obviously I don't want that, so make sure it's a large positive number.
162 Power saving is disabled if DontPreferBlanking, but in that case,
163 we don't get extension events either. So we can't turn it off that way.
165 The man page for `XSetScreenSaver' says that setting interval to 0 will
166 disable powering down of the monitor, but this turns out not to be the
167 case on Irix 6.3 (O2); the monitor powers down anyway. It didn't do
168 this on 6.2, so someone screwed up.
170 Extra Sucky Factoid #2: the number can't be more than 15 bits, which
171 is only a bit over nine hours. So there's just *no fucking way* to make
172 an SGI O2 leave its monitor powered on and idle for more than nine hours.
175 [...Later...] Ok, it's worse than that. The above doesn't work either.
176 Setting it to a small number will cause it to power down early; but even
177 if you set it to a large number, it still seems to power down in about
178 an hour. You fucking fucking fucking losers!
180 #ifdef HAVE_SGI_SAVER_EXTENSION
181 if (p->use_sgi_saver_extension)
182 desired_server_interval = 32767;
185 desired_server_interval = 0;
187 /* I suspect (but am not sure) that DontAllowExposures might have
188 something to do with powering off the monitor as well. */
189 desired_allow_exp = AllowExposures;
191 #if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
192 if (p->use_mit_saver_extension || p->use_sgi_saver_extension)
194 desired_server_timeout = (p->timeout / 1000);
196 /* The SGI extension won't give us events unless blanking is on.
197 I think (unsure right now) that the MIT extension is the opposite. */
198 if (p->use_sgi_saver_extension)
199 desired_prefer_blank = PreferBlanking;
201 desired_prefer_blank = DontPreferBlanking;
204 #endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
206 desired_server_timeout = 0;
209 if (desired_server_timeout != current_server_timeout ||
210 desired_server_interval != current_server_interval ||
211 desired_prefer_blank != current_prefer_blank ||
212 desired_allow_exp != current_allow_exp)
214 if (desired_server_timeout == 0)
215 printf ("%s%sisabling server builtin screensaver.\n\
216 You can re-enable it with \"xset s on\".\n",
217 (p->verbose_p ? "" : progname),
218 (p->verbose_p ? "\n\tD" : ": d"));
221 fprintf (stderr, "%s: (xset s %d %d %s %s)\n", progname,
222 desired_server_timeout, desired_server_interval,
223 (desired_prefer_blank ? "blank" : "noblank"),
224 (desired_allow_exp ? "noexpose" : "expose"));
226 XSetScreenSaver (si->dpy,
227 desired_server_timeout, desired_server_interval,
228 desired_prefer_blank, desired_allow_exp);
229 XSync(si->dpy, False);
233 #if defined(HAVE_MIT_SAVER_EXTENSION) || defined(HAVE_SGI_SAVER_EXTENSION)
235 static Bool extension_initted = False;
236 if (!extension_initted)
238 extension_initted = True;
239 # ifdef HAVE_MIT_SAVER_EXTENSION
240 if (p->use_mit_saver_extension) init_mit_saver_extension(si);
242 # ifdef HAVE_SGI_SAVER_EXTENSION
243 if (p->use_sgi_saver_extension) init_sgi_saver_extension(si);
247 #endif /* HAVE_MIT_SAVER_EXTENSION || HAVE_SGI_SAVER_EXTENSION */
250 /* Turn off the server builtin saver if it is now running. */
251 XForceScreenSaver (si->dpy, ScreenSaverReset);