chiark / gitweb /
Initial versions.
[xtoys] / xwait.c
1 /* -*-c-*-
2  *
3  * $Id: xwait.c,v 1.1 1998/11/16 23:00:49 mdw Exp $
4  *
5  * Wait until prodded by another X client
6  *
7  * (c) 1998 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of the Edgeware X tools collection.
13  *
14  * X tools is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  * 
19  * X tools is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with X tools; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 /*----- Revision history --------------------------------------------------* 
30  *
31  * $Log: xwait.c,v $
32  * Revision 1.1  1998/11/16 23:00:49  mdw
33  * Initial versions.
34  *
35  */
36
37 /*----- Header files ------------------------------------------------------*/
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include <unistd.h>
44
45 #include <X11/Xlib.h>
46 #include <X11/Xutil.h>
47
48 #include "xwait.h"
49
50 /*----- Main code ---------------------------------------------------------*/
51
52 int main(int argc, char *argv[])
53 {
54   char *display = 0;
55   Display *dpy;
56   Atom xwait_die;
57   XEvent ev;
58   char *atom = XWAIT_DIE;
59   char *msg = XWAIT_DIE_MSG;
60   unsigned f = 0;
61
62   enum {
63     f_force = 1
64   };
65
66   /* --- Parse options --- */
67
68   for (;;) {
69     int i = getopt(argc, argv, "d:a:m:f");
70     if (i < 0)
71       break;
72     switch (i) {
73       case 'd':
74         display = optarg;
75         break;
76       case 'a':
77         atom = optarg;
78         break;
79       case 'm':
80         msg = optarg;
81         break;
82       case 'f':
83         f |= f_force;
84         break;
85       default:
86         fprintf(stderr,
87                 "Usage: xwait [-f] [-d DISPLAY] [-a ATOM] [-m MSG]\n");
88         exit(EXIT_FAILURE);
89         break;
90     }
91   }
92
93   /* --- Connect to the X display --- */
94
95   dpy = XOpenDisplay(display);
96   if (!dpy) {
97     fprintf(stderr, "xwait: couldn't open display\n");
98     exit(EXIT_FAILURE);
99   }
100
101   /* --- Fetch the property name atom --- */
102
103   xwait_die = XInternAtom(dpy, atom, False);
104
105   /* --- Mark ourselves as listening to all the screens --- */
106
107   {
108     int i;
109     int nsc = ScreenCount(dpy);
110
111     /* --- First pass: make sure there's not a process already here --- */
112
113     if ((f & f_force) == 0) {
114       for (i = 0; i < nsc; i++) {
115         Window win = RootWindow(dpy, i);
116         XTextProperty prop;
117
118         if (XGetTextProperty(dpy, win, &prop, xwait_die)) {
119           fprintf(stderr, "xwait: already waiting for `%s'\n", atom);
120           exit(EXIT_FAILURE);
121         }
122       }
123     }
124
125     /* --- Second pass: set up listening to the property --- */
126
127     for (i = 0; i < nsc; i++) {
128       Window win = RootWindow(dpy, i);
129       XTextProperty prop;
130       char *imsg = "XWAIT_READY";
131
132       XStringListToTextProperty(&imsg, 1, &prop);
133       XSetTextProperty(dpy, win, &prop, xwait_die);
134       XSelectInput(dpy, win, PropertyChangeMask);
135     }
136   }
137
138   /* --- Now wait for an event --- */
139
140   for (;;) {
141     XNextEvent(dpy, &ev);
142     switch (ev.type) {
143       case PropertyNotify:
144         if (ev.xproperty.atom == xwait_die) {
145           XTextProperty prop;
146           char **sl;
147           int c;
148
149           if (XGetTextProperty(dpy, ev.xproperty.window, &prop, xwait_die)) {
150             XTextPropertyToStringList(&prop, &sl, &c);
151             if (strcmp(sl[0], msg) == 0)
152               goto exit;
153             XFreeStringList(sl);
154           }
155         }
156     }
157   }
158
159   /* --- Finished: remove the property from all the screens --- */
160
161 exit:
162   {
163     int i;
164     int nsc = ScreenCount(dpy);
165
166     for (i = 0; i < nsc; i++)
167       XDeleteProperty(dpy, RootWindow(dpy, i), xwait_die);
168   }
169
170   /* --- Go away --- */
171
172   XCloseDisplay(dpy);
173   return (0);
174 }
175
176 /*----- That's all, folks -------------------------------------------------*/