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 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 is good for looking at a demo of\n\
45 each of the hacks in place.\n\
46 -prev Like -next, but goes in the other direction.\n\
47 -exit Causes the screensaver process to exit. It should be ok to\n\
48 just kill the process (NOT with -9!) but this is a slightly\n\
50 -restart Causes the screensaver process to exit and then restart with\n\
51 the same command line arguments. This is a good way of \n\
52 causing the screensaver to re-read the resource database.\n\
53 -lock Same as -activate, but with immediate locking.\n\
54 -version Prints the version of XScreenSaver that is running.\n\
55 -time Prints the time at which the screensaver turned on.\n\
57 See the man page for more details.\n\
58 For updates, check http://people.netscape.com/jwz/xscreensaver/\n\
62 find_screensaver_window (Display *dpy, char *progname, char **version)
65 Window root = RootWindowOfScreen (DefaultScreenOfDisplay (dpy));
66 Window root2, parent, *kids;
69 if (version) *version = 0;
71 if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids))
77 if (! (kids && nkids))
79 for (i = 0; i < nkids; i++)
83 unsigned long nitems, bytesafter;
86 if (XGetWindowProperty (dpy, kids[i],
87 XInternAtom (dpy, "_SCREENSAVER_VERSION", False),
88 0, 200, False, XA_STRING,
89 &type, &format, &nitems, &bytesafter,
90 (unsigned char **) &v)
99 fprintf (stderr, "%s: no screensaver is running on display %s\n", progname,
100 DisplayString (dpy));
106 { fprintf (stderr, usage, argv[0], screensaver_version); exit (1); }
109 main (int argc, char **argv)
117 char *message = 0, *dpyname = 0;
120 screensaver_version = (char *) malloc (5);
121 memcpy (screensaver_version, screensaver_id + 17, 4);
122 screensaver_version [4] = 0;
123 for (i = 1; i < argc; i++)
128 if (!strncmp (s, "-display", L)) dpyname = argv [++i];
129 else if (message) USAGE ()
130 else if (!strncmp (s, "-activate", L)) message = "ACTIVATE";
131 else if (!strncmp (s, "-deactivate", L)) message = "DEACTIVATE";
132 else if (!strncmp (s, "-cycle", L)) message = "CYCLE";
133 else if (!strncmp (s, "-next", L)) message = "NEXT";
134 else if (!strncmp (s, "-prev", L)) message = "PREV";
135 else if (!strncmp (s, "-exit", L)) message = "EXIT";
136 else if (!strncmp (s, "-restart", L)) message = "RESTART";
137 else if (!strncmp (s, "-demo", L)) message = "DEMO";
138 else if (!strncmp (s, "-lock", L)) message = "LOCK";
139 else if (!strncmp (s, "-version", L)) query = Q_version;
140 else if (!strncmp (s, "-time", L)) query = Q_time;
143 if (!message && !query) USAGE ();
144 if (!dpyname) dpyname = (char *) getenv ("DISPLAY");
145 dpy = XOpenDisplay (dpyname);
148 fprintf (stderr, "%s: can't open display %s\n", argv[0],
149 (dpyname ? dpyname : "(null)"));
152 window = find_screensaver_window (dpy, argv[0], &v);
157 event.xany.type = ClientMessage;
158 event.xclient.display = dpy;
159 event.xclient.window = window;
160 event.xclient.message_type = XInternAtom (dpy, "SCREENSAVER", False);
161 event.xclient.format = 32;
162 event.xclient.data.l[0] = (long) XInternAtom (dpy, message, False);
163 if (! XSendEvent (dpy, window, False, 0L, &event))
165 fprintf (stderr, "%s: XSendEvent(dpy, 0x%x ...) failed.\n", argv [0],
166 (unsigned int) window);
173 memset (&hint, 0, sizeof(hint));
176 fprintf (stderr, "%s: version property not set on window 0x%x?\n",
177 argv [0], (unsigned int) window);
181 XGetClassHint(dpy, window, &hint);
184 fprintf (stderr, "%s: class hints not set on window 0x%x?\n",
185 argv [0], (unsigned int) window);
189 fprintf (stdout, "%s %s", hint.res_class, v);
193 fprintf (stdout, "\n");
199 unsigned long nitems, bytesafter;
200 unsigned char *data = 0;
201 XWindowAttributes xgwa;
202 Bool active_p = False;
204 xgwa.map_state = IsViewable;
205 XGetWindowAttributes (dpy, window, &xgwa);
207 if (XGetWindowProperty (dpy, window,
208 XInternAtom (dpy, "__SWM_VROOT", False),
209 0, 0, False, XA_WINDOW,
210 &type, &format, &nitems, &bytesafter,
216 if (data) free (data);
219 if (XGetWindowProperty (dpy, window,
220 XInternAtom (dpy, "_SCREENSAVER_TIME",False),
221 0, 1, False, XA_INTEGER,
222 &type, &format, &nitems, &bytesafter,
225 && type == XA_INTEGER
228 CARD32 time32 = *((CARD32 *)data);
229 time_t tt = (time_t) time32;
232 fprintf (stdout, ": active since ");
234 fprintf (stdout, ": inactive since ");
235 fprintf (stdout, "%s", ctime(&tt));
236 if (data) free (data);
240 if (data) free (data);
241 fprintf (stdout, "\n");
243 fprintf (stderr, "%s: no time on window 0x%x (%s %s).\n",
244 argv[0], (unsigned int) window,
245 hint.res_class, (v ? v : "???"));