1 /* xscreensaver-command, Copyright (c) 1991-1998
2 * by 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
26 #include <X11/Xproto.h> /* for CARD32 */
28 #include <X11/Xatom.h>
29 #include <X11/Xutil.h> /* for XGetClassHint() */
32 #include <X11/Intrinsic.h> /* only needed to get through xscreensaver.h */
37 static char *progname;
39 static Atom XA_SCREENSAVER, XA_SCREENSAVER_VERSION, XA_SCREENSAVER_TIME;
40 #else /* !STANDALONE */
41 # include "xscreensaver.h"
42 #endif /* !STANDALONE */
46 ERROR! you must not include vroot.h in this file
50 find_screensaver_window (Display *dpy, char **version)
53 Window root = RootWindowOfScreen (DefaultScreenOfDisplay (dpy));
54 Window root2, parent, *kids;
57 if (version) *version = 0;
59 if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids))
65 if (! (kids && nkids))
67 for (i = 0; i < nkids; i++)
71 unsigned long nitems, bytesafter;
74 if (XGetWindowProperty (dpy, kids[i],
75 XA_SCREENSAVER_VERSION,
76 0, 200, False, XA_STRING,
77 &type, &format, &nitems, &bytesafter,
78 (unsigned char **) &v)
87 fprintf (stderr, "%s: no screensaver is running on display %s\n", progname,
94 xscreensaver_command (Display *dpy, Atom command)
97 Window window = find_screensaver_window (dpy, &v);
99 if (command == XA_SCREENSAVER_TIME ||
100 command == XA_SCREENSAVER_VERSION)
103 memset (&hint, 0, sizeof(hint));
106 fprintf (stderr, "%s: version property not set on window 0x%x?\n",
107 progname, (unsigned int) window);
111 XGetClassHint(dpy, window, &hint);
114 fprintf (stderr, "%s: class hints not set on window 0x%x?\n",
115 progname, (unsigned int) window);
119 fprintf (stdout, "%s %s", hint.res_class, v);
121 if (command != XA_SCREENSAVER_TIME)
123 fprintf (stdout, "\n");
129 unsigned long nitems, bytesafter;
130 unsigned char *data = 0;
131 XWindowAttributes xgwa;
132 Bool active_p = False;
134 xgwa.map_state = IsViewable;
135 XGetWindowAttributes (dpy, window, &xgwa);
137 if (XGetWindowProperty (dpy, window, XA_VROOT,
138 0, 0, False, XA_WINDOW,
139 &type, &format, &nitems, &bytesafter,
145 if (data) free (data);
148 if (XGetWindowProperty (dpy, window,
150 0, 1, False, XA_INTEGER,
151 &type, &format, &nitems, &bytesafter,
154 && type == XA_INTEGER
157 CARD32 time32 = *((CARD32 *)data);
158 time_t tt = (time_t) time32;
161 fprintf (stdout, ": screen blanked since ");
163 /* suggestions for a better way to phrase this are welcome. */
164 fprintf (stdout, ": screen non-blanked since ");
165 fprintf (stdout, "%s", ctime(&tt));
166 if (data) free (data);
170 if (data) free (data);
171 fprintf (stdout, "\n");
173 fprintf (stderr, "%s: no time on window 0x%x (%s %s).\n",
174 progname, (unsigned int) window,
175 hint.res_class, (v ? v : "???"));
183 event.xany.type = ClientMessage;
184 event.xclient.display = dpy;
185 event.xclient.window = window;
186 event.xclient.message_type = XA_SCREENSAVER;
187 event.xclient.format = 32;
188 event.xclient.data.l[0] = (long) command;
189 if (! XSendEvent (dpy, window, False, 0L, &event))
191 fprintf (stderr, "%s: XSendEvent(dpy, 0x%x ...) failed.\n",
192 progname, (unsigned int) window);
202 static Atom XA_ACTIVATE, XA_DEACTIVATE, XA_CYCLE, XA_NEXT, XA_PREV;
203 static Atom XA_EXIT, XA_RESTART, XA_DEMO, XA_LOCK;
205 static char *progname;
206 static char *screensaver_version;
207 static char *usage = "\n\
208 usage: %s -<switch>\n\
210 This program provides external control of a running xscreensaver process.\n\
211 Version %s, copyright (c) 1991-1997 Jamie Zawinski <jwz@netscape.com>.\n\
213 The xscreensaver program is a daemon that runs in the background.\n\
214 You control a running xscreensaver process by sending it messages\n\
215 with this program, xscreensaver-command. See the man pages for\n\
216 details. These are the arguments understood by xscreensaver-command:\n\
218 -demo Ask the xscreensaver process to enter interactive demo mode.\n\
220 -activate Turn on the screensaver (blank the screen), as if the user\n\
221 had been idle for long enough.\n\
223 -deactivate Turns off the screensaver (un-blank the screen), as if user\n\
224 activity had been detected.\n\
226 -cycle If the screensaver is active (the screen is blanked), then\n\
227 stop the current graphics demo and run a new one (chosen\n\
230 -next Like either -activate or -cycle, depending on which is more\n\
231 appropriate, except that the graphics hack that will be run\n\
232 is the next one in the list, instead of a randomly-chosen\n\
233 one. In other words, repeatedly executing -next will cause\n\
234 the xscreensaver process to invoke each graphics demo\n\
235 sequentially. (Though using the -demo option is probably\n\
236 an easier way to accomplish that.)\n\
238 -prev Like -next, but goes in the other direction.\n\
240 -exit Causes the xscreensaver process to exit gracefully. This is\n\
241 roughly the same as killing the process with `kill', but it\n\
242 is easier, since you don't need to first figure out the pid.\n\
243 (Note that one must *never* kill xscreensaver with -9!)\n\
245 -restart Causes the screensaver process to exit and then restart with\n\
246 the same command line arguments as last time. Do this after\n\
247 you've changed your X resource settings, to cause\n\
248 xscreensaver to notice the changes.\n\
250 -lock Tells the running xscreensaver process to lock the screen\n\
251 immediately. This is like -activate, but forces locking as\n\
252 well, even if locking is not the default.\n\
254 -version Prints the version of xscreensaver that is currently running\n\
255 on the display -- that is, the actual version number of the\n\
256 running xscreensaver background process, rather than the\n\
257 version number of xscreensaver-command.\n\
259 -time Prints the time at which the screensaver last activated or\n\
260 deactivated (roughly, how long the user has been idle or\n\
261 non-idle -- but not quite, since it only tells you when the\n\
262 screen became blanked or un-blanked.)\n\
264 See the man page for more details.\n\
265 For updates, check http://people.netscape.com/jwz/xscreensaver/\n\
269 { fprintf (stderr, usage, progname, screensaver_version); exit (1); }
272 main (int argc, char **argv)
280 screensaver_version = (char *) malloc (5);
281 memcpy (screensaver_version, screensaver_id + 17, 4);
282 screensaver_version [4] = 0;
284 for (i = 1; i < argc; i++)
286 const char *s = argv [i];
288 if (s[0] == '-' && s[1] == '-') s++;
291 if (!strncmp (s, "-display", L)) dpyname = argv [++i];
292 else if (cmd) USAGE ()
293 else if (!strncmp (s, "-activate", L)) cmd = &XA_ACTIVATE;
294 else if (!strncmp (s, "-deactivate", L)) cmd = &XA_DEACTIVATE;
295 else if (!strncmp (s, "-cycle", L)) cmd = &XA_CYCLE;
296 else if (!strncmp (s, "-next", L)) cmd = &XA_NEXT;
297 else if (!strncmp (s, "-prev", L)) cmd = &XA_PREV;
298 else if (!strncmp (s, "-exit", L)) cmd = &XA_EXIT;
299 else if (!strncmp (s, "-restart", L)) cmd = &XA_RESTART;
300 else if (!strncmp (s, "-demo", L)) cmd = &XA_DEMO;
301 else if (!strncmp (s, "-lock", L)) cmd = &XA_LOCK;
302 else if (!strncmp (s, "-version", L)) cmd = &XA_SCREENSAVER_VERSION;
303 else if (!strncmp (s, "-time", L)) cmd = &XA_SCREENSAVER_TIME;
309 if (!dpyname) dpyname = (char *) getenv ("DISPLAY");
310 dpy = XOpenDisplay (dpyname);
313 fprintf (stderr, "%s: can't open display %s\n", progname,
314 (dpyname ? dpyname : "(null)"));
318 XA_VROOT = XInternAtom (dpy, "__SWM_VROOT", False);
319 XA_SCREENSAVER = XInternAtom (dpy, "SCREENSAVER", False);
320 XA_SCREENSAVER_VERSION = XInternAtom (dpy, "_SCREENSAVER_VERSION",False);
321 XA_SCREENSAVER_TIME = XInternAtom (dpy, "_SCREENSAVER_TIME", False);
322 XA_ACTIVATE = XInternAtom (dpy, "ACTIVATE", False);
323 XA_DEACTIVATE = XInternAtom (dpy, "DEACTIVATE", False);
324 XA_RESTART = XInternAtom (dpy, "RESTART", False);
325 XA_CYCLE = XInternAtom (dpy, "CYCLE", False);
326 XA_NEXT = XInternAtom (dpy, "NEXT", False);
327 XA_PREV = XInternAtom (dpy, "PREV", False);
328 XA_EXIT = XInternAtom (dpy, "EXIT", False);
329 XA_DEMO = XInternAtom (dpy, "DEMO", False);
330 XA_LOCK = XInternAtom (dpy, "LOCK", False);
332 xscreensaver_command(dpy, *cmd);
339 #endif /* STANDALONE */