Ignore all generated/compiled files
[gwave-svn.git] / remote / xgclient.c
blob0f2a21f013d10fb01805664bd95bbc83a1e7d85f
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)
7 * any later version.
8 *
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>
22 #include <X11/X.h>
23 #include <X11/Xlib.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "xgexec.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)
41 Window root;
42 Atom type_ret;
43 int form_ret;
44 unsigned long nitems;
45 unsigned long bytes_after;
46 unsigned char *prop;
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);
59 nitems=1;
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) {
64 if (prop!=NULL) {
65 XFree(prop);
67 return (None);
70 XFree(prop);
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);
78 XFree (out);
79 XFree (err);
80 return result;
83 static Bool FPropertyNotifyOnWindow(Display *dpy, XEvent *ev, Window *w)
85 if (ev->type==PropertyNotify && ev->xproperty.window== *w) {
86 return True;
87 } else {
88 return False;
92 typedef Bool (*PredicateFn)();
94 char *xgexec_exec_full(Display *dpy, Window w, char *req,
95 char **output, char **error)
97 Atom type_ret;
98 int form_ret;
99 unsigned long nitems;
100 unsigned long bytes_after;
101 unsigned char *prop;
102 Window root=DefaultRootWindow(dpy);
103 XEvent ev;
104 int got_reply = 0;
105 int got_output = 0;
106 int got_error = 0;
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);
119 do {
120 XIfEvent (dpy, &ev, (PredicateFn) FPropertyNotifyOnWindow, (XPointer) &w);
121 if (ev.xproperty.state == PropertyNewValue) {
122 if (ev.xproperty.atom == XA_XGEXEC_REPLY) {
123 got_reply = 1;
124 } else if (ev.xproperty.atom == XA_XGEXEC_OUTPUT) {
125 got_output = 1;
126 } else if (ev.xproperty.atom == XA_XGEXEC_ERROR) {
127 got_error = 1;
130 #ifdef DEBUG_REPLIES
131 fprintf(stderr, "Got {reply,output,error} = {%d,%d,%d}\n",
132 got_reply, got_output, got_error);
133 #endif
134 } while (!got_reply || !got_output || !got_error);
136 *error=NULL;
137 *output=NULL;
139 /* FIXMS: Grabbing these in delete mode loses massively for some
140 reason. Need to find out why. The properties really should be
141 deleted.*/
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),
148 True, type_ret,
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),
158 True, type_ret,
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,
165 &prop);
166 XGetWindowProperty(dpy, w, XA_XGEXEC_REPLY,
167 0, (bytes_after / 4) + ((bytes_after % 4) ? 1 : 0),
168 True, type_ret,
169 &type_ret, &form_ret, &nitems, &bytes_after,
170 &prop);
172 return (char *) prop;