Yawn
[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 -------------------------------------------------*/