1 /* $Id: xgclient.c,v 1.1 2000-11-06 06:39:09 sgt Exp $
2 * Copyright (C) 1997-1999, Maciej Stachowiak and Greg J. Badros
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this software; see the file COPYING.GPL. If not, write to
16 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307 USA
21 #include <X11/Xatom.h>
29 #define XGNAME "GWAVE"
31 static Atom XA_XGEXEC_LISTENER
;
32 static Atom XA_XGEXEC_REQUEST
;
33 static Atom XA_XGEXEC_REQWIN
;
34 static Atom XA_XGEXEC_REPLY
;
35 static Atom XA_XGEXEC_NOTIFY
;
36 static Atom XA_XGEXEC_OUTPUT
;
37 static Atom XA_XGEXEC_ERROR
;
39 Window
xgexec_init(Display
*dpy
)
45 unsigned long bytes_after
;
48 /* intern our atoms */
49 XA_XGEXEC_LISTENER
=XInternAtom(dpy
, XGNAME
"EXEC_LISTENER", False
);
50 XA_XGEXEC_REQWIN
=XInternAtom(dpy
, XGNAME
"EXEC_REQWIN", False
);
51 XA_XGEXEC_REQUEST
=XInternAtom(dpy
, XGNAME
"EXEC_REQUEST", False
);
52 XA_XGEXEC_REPLY
=XInternAtom(dpy
, XGNAME
"EXEC_REPLY", False
);
53 XA_XGEXEC_NOTIFY
=XInternAtom(dpy
, XGNAME
"EXEC_NOTIFY", False
);
54 XA_XGEXEC_OUTPUT
=XInternAtom(dpy
, XGNAME
"EXEC_OUTPUT", False
);
55 XA_XGEXEC_ERROR
=XInternAtom(dpy
, XGNAME
"EXEC_ERROR", False
);
57 root
=DefaultRootWindow(dpy
);
60 if (XGetWindowProperty(dpy
, root
, XA_XGEXEC_LISTENER
,
61 0,1, False
, AnyPropertyType
,
62 &type_ret
, &form_ret
, &nitems
, &bytes_after
,
63 &prop
) != Success
|| prop
== NULL
|| nitems
==0) {
71 return(XCreateSimpleWindow(dpy
, root
, 3, 4, 2, 2, 1, 0, 0));
74 char *xgexec_exec(Display
*dpy
, Window w
, char *req
)
76 char *result
, *out
, *err
;
77 result
= xgexec_exec_full(dpy
, w
, req
, &out
, &err
);
83 static Bool
FPropertyNotifyOnWindow(Display
*dpy
, XEvent
*ev
, Window
*w
)
85 if (ev
->type
==PropertyNotify
&& ev
->xproperty
.window
== *w
) {
92 typedef Bool (*PredicateFn
)();
94 char *xgexec_exec_full(Display
*dpy
, Window w
, char *req
,
95 char **output
, char **error
)
100 unsigned long bytes_after
;
102 Window root
=DefaultRootWindow(dpy
);
108 /* X event handling - wait for XA_XGEXEC_REPLY on w
109 This needs to be before the ChangeProperty, otherwise
110 there is a race condition. --09/15/98 gjb*/
111 XSelectInput(dpy
,w
,PropertyChangeMask
);
113 XChangeProperty(dpy
, w
, XA_XGEXEC_REQUEST
, XA_STRING
,
114 8, PropModeReplace
, req
, strlen(req
)+1);
116 XChangeProperty(dpy
, root
, XA_XGEXEC_REQWIN
, 1,
117 32, PropModeAppend
, (unsigned char *) &w
, 1);
120 XIfEvent (dpy
, &ev
, (PredicateFn
) FPropertyNotifyOnWindow
, (XPointer
) &w
);
121 if (ev
.xproperty
.state
== PropertyNewValue
) {
122 if (ev
.xproperty
.atom
== XA_XGEXEC_REPLY
) {
124 } else if (ev
.xproperty
.atom
== XA_XGEXEC_OUTPUT
) {
126 } else if (ev
.xproperty
.atom
== XA_XGEXEC_ERROR
) {
131 fprintf(stderr
, "Got {reply,output,error} = {%d,%d,%d}\n",
132 got_reply
, got_output
, got_error
);
134 } while (!got_reply
|| !got_output
|| !got_error
);
139 /* FIXMS: Grabbing these in delete mode loses massively for some
140 reason. Need to find out why. The properties really should be
142 XGetWindowProperty(dpy
, w
, XA_XGEXEC_OUTPUT
,
143 0,0, False
, AnyPropertyType
,
144 &type_ret
, &form_ret
, &nitems
, &bytes_after
,
145 (unsigned char **) output
);
146 XGetWindowProperty(dpy
, w
, XA_XGEXEC_OUTPUT
,
147 0, (bytes_after
/ 4) + ((bytes_after
% 4) ? 1 : 0),
149 &type_ret
, &form_ret
, &nitems
, &bytes_after
,
150 (unsigned char **) output
);
152 XGetWindowProperty(dpy
, w
, XA_XGEXEC_ERROR
,
153 0,0, False
, AnyPropertyType
,
154 &type_ret
, &form_ret
, &nitems
, &bytes_after
,
155 (unsigned char **) error
);
156 XGetWindowProperty(dpy
, w
, XA_XGEXEC_ERROR
,
157 0, (bytes_after
/ 4) + ((bytes_after
% 4) ? 1 : 0),
159 &type_ret
, &form_ret
, &nitems
, &bytes_after
,
160 (unsigned char **) error
);
162 XGetWindowProperty(dpy
, w
, XA_XGEXEC_REPLY
,
163 0,0, False
, AnyPropertyType
,
164 &type_ret
, &form_ret
, &nitems
, &bytes_after
,
166 XGetWindowProperty(dpy
, w
, XA_XGEXEC_REPLY
,
167 0, (bytes_after
/ 4) + ((bytes_after
% 4) ? 1 : 0),
169 &type_ret
, &form_ret
, &nitems
, &bytes_after
,
172 return (char *) prop
;