1 /* xscreensaver-command, Copyright (c) 1991-1997
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
18 #include <X11/Xproto.h> /* for CARD32 */
20 #include <X11/Xatom.h>
21 #include <X11/Xutil.h> /* for XGetClassHint() */
28 ERROR! you must not include vroot.h in this file
31 static char *screensaver_version;
32 static char *usage = "usage: %s -<switch>\n\
34 This program provides external control of a running xscreensaver process.\n\
35 Version %s, copyright (c) 1991-1997 Jamie Zawinski <jwz@netscape.com>.\n\
37 -demo Enter interactive demo mode.\n\
38 -deactivate Turns off the screensaver if it is on, as user input would.\n\
39 -activate Turns it on as if the user had been idle for long enough.\n\
40 -cycle Stops the current graphics hack and runs a new one.\n\
41 -next Like either -activate or -cycle, depending on which is more\n\
42 appropriate, except that the screenhack that will be run is\n\
43 the next one in the list of hacks, instead of a randomly-\n\
44 chosen one. This option could be used for looking at a demo\n\
45 of each of the configured hacks.\n\
46 -prev Like -next, but goes in the other direction.\n\
47 -exit Causes the screensaver process to exit. This is the same as\n\
48 killing the process with `kill', but it's easier, since you\n\
49 don't need to first figure out the pid. (Note that one\n\
50 must *never* kill xscreensaver with -9!)\n\
51 -restart Causes the screensaver process to exit and then restart with\n\
52 the same command line arguments. Do this after you've\n\
53 changed the resource database, to cause the screensaver to\n\
54 notice the changes.\n\
55 -lock Same as -activate, but with immediate locking.\n\
56 -version Prints the version of XScreenSaver that is currently running\n\
58 -time Prints the time at which the screensaver last activated or\n\
59 deactivated (roughly, how long the user has been idle or\n\
62 See the man page for more details.\n\
63 For updates, check http://people.netscape.com/jwz/xscreensaver/\n\
67 find_screensaver_window (Display *dpy, char *progname, char **version)
70 Window root = RootWindowOfScreen (DefaultScreenOfDisplay (dpy));
71 Window root2, parent, *kids;
74 if (version) *version = 0;
76 if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids))
82 if (! (kids && nkids))
84 for (i = 0; i < nkids; i++)
88 unsigned long nitems, bytesafter;
91 if (XGetWindowProperty (dpy, kids[i],
92 XInternAtom (dpy, "_SCREENSAVER_VERSION", False),
93 0, 200, False, XA_STRING,
94 &type, &format, &nitems, &bytesafter,
95 (unsigned char **) &v)
104 fprintf (stderr, "%s: no screensaver is running on display %s\n", progname,
105 DisplayString (dpy));
111 { fprintf (stderr, usage, argv[0], screensaver_version); exit (1); }
114 main (int argc, char **argv)
122 char *message = 0, *dpyname = 0;
125 screensaver_version = (char *) malloc (5);
126 memcpy (screensaver_version, screensaver_id + 17, 4);
127 screensaver_version [4] = 0;
128 for (i = 1; i < argc; i++)
133 if (!strncmp (s, "-display", L)) dpyname = argv [++i];
134 else if (message) USAGE ()
135 else if (!strncmp (s, "-activate", L)) message = "ACTIVATE";
136 else if (!strncmp (s, "-deactivate", L)) message = "DEACTIVATE";
137 else if (!strncmp (s, "-cycle", L)) message = "CYCLE";
138 else if (!strncmp (s, "-next", L)) message = "NEXT";
139 else if (!strncmp (s, "-prev", L)) message = "PREV";
140 else if (!strncmp (s, "-exit", L)) message = "EXIT";
141 else if (!strncmp (s, "-restart", L)) message = "RESTART";
142 else if (!strncmp (s, "-demo", L)) message = "DEMO";
143 else if (!strncmp (s, "-lock", L)) message = "LOCK";
144 else if (!strncmp (s, "-version", L)) query = Q_version;
145 else if (!strncmp (s, "-time", L)) query = Q_time;
148 if (!message && !query) USAGE ();
149 if (!dpyname) dpyname = (char *) getenv ("DISPLAY");
150 dpy = XOpenDisplay (dpyname);
153 fprintf (stderr, "%s: can't open display %s\n", argv[0],
154 (dpyname ? dpyname : "(null)"));
157 window = find_screensaver_window (dpy, argv[0], &v);
162 event.xany.type = ClientMessage;
163 event.xclient.display = dpy;
164 event.xclient.window = window;
165 event.xclient.message_type = XInternAtom (dpy, "SCREENSAVER", False);
166 event.xclient.format = 32;
167 event.xclient.data.l[0] = (long) XInternAtom (dpy, message, False);
168 if (! XSendEvent (dpy, window, False, 0L, &event))
170 fprintf (stderr, "%s: XSendEvent(dpy, 0x%x ...) failed.\n", argv [0],
171 (unsigned int) window);
178 memset (&hint, 0, sizeof(hint));
181 fprintf (stderr, "%s: version property not set on window 0x%x?\n",
182 argv [0], (unsigned int) window);
186 XGetClassHint(dpy, window, &hint);
189 fprintf (stderr, "%s: class hints not set on window 0x%x?\n",
190 argv [0], (unsigned int) window);
194 fprintf (stdout, "%s %s", hint.res_class, v);
198 fprintf (stdout, "\n");
204 unsigned long nitems, bytesafter;
205 unsigned char *data = 0;
206 XWindowAttributes xgwa;
207 Bool active_p = False;
209 xgwa.map_state = IsViewable;
210 XGetWindowAttributes (dpy, window, &xgwa);
212 if (XGetWindowProperty (dpy, window,
213 XInternAtom (dpy, "__SWM_VROOT", False),
214 0, 0, False, XA_WINDOW,
215 &type, &format, &nitems, &bytesafter,
221 if (data) free (data);
224 if (XGetWindowProperty (dpy, window,
225 XInternAtom (dpy, "_SCREENSAVER_TIME",False),
226 0, 1, False, XA_INTEGER,
227 &type, &format, &nitems, &bytesafter,
230 && type == XA_INTEGER
233 CARD32 time32 = *((CARD32 *)data);
234 time_t tt = (time_t) time32;
237 fprintf (stdout, ": active since ");
239 fprintf (stdout, ": inactive since ");
240 fprintf (stdout, "%s", ctime(&tt));
241 if (data) free (data);
245 if (data) free (data);
246 fprintf (stdout, "\n");
248 fprintf (stderr, "%s: no time on window 0x%x (%s %s).\n",
249 argv[0], (unsigned int) window,
250 hint.res_class, (v ? v : "???"));