http://se.aminet.net/pub/X11/ftp.x.org/contrib/vms/xscreensaver-124.zip
[xscreensaver] / driver / xscreensaver-command.c
1 /* xscreensaver-command, Copyright (c) 1991-1994 Jamie Zawinski <jwz@mcom.com>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  */
11
12 #include "version.h"
13 #include <stdio.h>
14 #include <X11/Xlib.h>
15 #include <X11/Xatom.h>
16 #include <X11/Xos.h>
17 #if __STDC__
18 # include <stdlib.h>
19 #endif
20
21 #ifdef _VROOT_H_
22 ERROR! you must not include vroot.h in this file
23 #endif
24
25 static char *screensaver_version;
26 static char *usage = "usage: %s -<switch>\n\
27 \n\
28   This program provides external control of a running xscreensaver process.\n\
29   Version %s, copyright (c) 1991-1994 Jamie Zawinski <jwz@mcom.com>.\n\
30 \n\
31   -demo         Enter interactive demo mode.\n\
32   -deactivate   Turns off the screensaver if it is on, as user input would.\n\
33   -activate     Turns it on as if the user had been idle for long enough.\n\
34   -cycle        Stops the current hack and runs a new one.\n\
35   -next         Like either -activate or -cycle, depending on which is more\n\
36                 appropriate, except that the screenhack that will be run is\n\
37                 the next one in the list of hacks, instead of a randomly-\n\
38                 chosen one.  This option is good for looking at a demo of\n\
39                 each of the hacks in place.\n\
40   -prev         Like -next, but goes in the other direction.\n\
41   -exit         Causes the screensaver process to exit.  It should be ok to\n\
42                 just kill the process (NOT with -9!) but this is a slightly\n\
43                 easier way.\n\
44   -restart      Causes the screensaver process to exit and then restart with\n\
45                 the same command line arguments.  This is a good way of \n\
46                 causing the screensaver to re-read the resource database.\n\
47   -lock         Same as -activate, but with immediate locking.\n\
48 \n\
49   See the man page for more details.\n\n";
50
51 static Window
52 find_screensaver_window (dpy, progname)
53      Display *dpy;
54      char *progname;
55 {
56   int i;
57   Window root = RootWindowOfScreen (DefaultScreenOfDisplay (dpy));
58   Window root2, parent, *kids;
59   unsigned int nkids;
60
61   if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids))
62     abort ();
63   if (root != root2)
64     abort ();
65   if (parent)
66     abort ();
67   if (! (kids && nkids))
68     abort ();
69   for (i = 0; i < nkids; i++)
70     {
71       Atom type;
72       int format;
73       unsigned long nitems, bytesafter;
74       char *version;
75
76       if (XGetWindowProperty (dpy, kids[i],
77                               XInternAtom (dpy, "_SCREENSAVER_VERSION", False),
78                               0, 1, False, XA_STRING,
79                               &type, &format, &nitems, &bytesafter,
80                               (unsigned char **) &version)
81           == Success
82           && type != None)
83         return kids[i];
84     }
85   fprintf (stderr, "%s: no screensaver is running on display %s", progname,
86            DisplayString (dpy));
87   exit (1);
88 }
89
90
91 #define USAGE() \
92  { fprintf (stderr, usage, argv[0], screensaver_version); exit (1); }
93
94 #ifndef VMS
95 void
96 #else
97 int
98 #endif
99 main (argc, argv)
100      int argc;
101      char **argv;
102 {
103   Display *dpy;
104   Window window;
105   XEvent event;
106   int i;
107   char *message = 0, *dpyname = 0;
108   screensaver_version = (char *) malloc (5);
109   memcpy (screensaver_version, screensaver_id + 17, 4);
110   screensaver_version [4] = 0;
111   for (i = 1; i < argc; i++)
112     {
113       char *s = argv [i];
114       int L = strlen (s);
115       if (L < 2) USAGE ();
116       if (!strncmp (s, "-display", L))          dpyname = argv [++i];
117       else if (message) USAGE ()
118       else if (!strncmp (s, "-activate", L))    message = "ACTIVATE";
119       else if (!strncmp (s, "-deactivate", L))  message = "DEACTIVATE";
120       else if (!strncmp (s, "-cycle", L))       message = "CYCLE";
121       else if (!strncmp (s, "-next", L))        message = "NEXT";
122       else if (!strncmp (s, "-prev", L))        message = "PREV";
123       else if (!strncmp (s, "-exit", L))        message = "EXIT";
124       else if (!strncmp (s, "-restart", L))     message = "RESTART";
125       else if (!strncmp (s, "-demo", L))        message = "DEMO";
126       else if (!strncmp (s, "-lock", L))        message = "LOCK";
127       else USAGE ();
128     }
129   if (! message) USAGE ();
130   if (!dpyname) dpyname = (char *) getenv ("DISPLAY");
131   dpy = XOpenDisplay (dpyname);
132   if (!dpy)
133     {
134       fprintf (stderr, "%s: can't open display %s\n", argv[0],
135                (dpyname ? dpyname : "(null)"));
136       exit (1);
137     }
138   window = find_screensaver_window (dpy, argv[0]);
139
140   event.xany.type = ClientMessage;
141   event.xclient.display = dpy;
142   event.xclient.window = window;
143   event.xclient.message_type = XInternAtom (dpy, "SCREENSAVER", False);
144   event.xclient.format = 32;
145   event.xclient.data.l[0] = (long) XInternAtom (dpy, message, False);
146   if (! XSendEvent (dpy, window, False, 0L, &event))
147     {
148       fprintf (stderr, "%s: XSendEvent(dpy, 0x%x ...) failed.\n", argv [0],
149                (unsigned int) window);
150       exit (1);
151     }
152   XSync (dpy, 0);
153   exit (0);
154 }