Blame


1 257fb626 2006-06-25 devnull /* Copyright (c) 2006 Russ Cox */
2 257fb626 2006-06-25 devnull
3 257fb626 2006-06-25 devnull #include <u.h>
4 150f8802 2006-06-25 devnull #include <sys/select.h>
5 257fb626 2006-06-25 devnull #include <libc.h>
6 257fb626 2006-06-25 devnull #include <draw.h>
7 257fb626 2006-06-25 devnull #include <mouse.h>
8 257fb626 2006-06-25 devnull #include <cursor.h>
9 257fb626 2006-06-25 devnull #include <drawfcall.h>
10 257fb626 2006-06-25 devnull #include <mux.h>
11 257fb626 2006-06-25 devnull
12 54bebe6a 2012-09-17 rsc extern Mouse _drawmouse;
13 b65a69c1 2008-06-30 rsc int chattydrawclient = 0;
14 257fb626 2006-06-25 devnull
15 257fb626 2006-06-25 devnull static int drawgettag(Mux *mux, void *vmsg);
16 257fb626 2006-06-25 devnull static void* drawrecv(Mux *mux);
17 3a194702 2006-11-04 devnull static int drawnbrecv(Mux *mux, void**);
18 257fb626 2006-06-25 devnull static int drawsend(Mux *mux, void *vmsg);
19 257fb626 2006-06-25 devnull static int drawsettag(Mux *mux, void *vmsg, uint tag);
20 150f8802 2006-06-25 devnull static int canreadfd(int);
21 257fb626 2006-06-25 devnull
22 257fb626 2006-06-25 devnull int
23 257fb626 2006-06-25 devnull _displayconnect(Display *d)
24 257fb626 2006-06-25 devnull {
25 257fb626 2006-06-25 devnull int pid, p[2];
26 257fb626 2006-06-25 devnull
27 257fb626 2006-06-25 devnull fmtinstall('W', drawfcallfmt);
28 257fb626 2006-06-25 devnull fmtinstall('H', encodefmt);
29 257fb626 2006-06-25 devnull
30 257fb626 2006-06-25 devnull if(pipe(p) < 0)
31 257fb626 2006-06-25 devnull return -1;
32 257fb626 2006-06-25 devnull if((pid=fork()) < 0){
33 257fb626 2006-06-25 devnull close(p[0]);
34 257fb626 2006-06-25 devnull close(p[1]);
35 257fb626 2006-06-25 devnull return -1;
36 257fb626 2006-06-25 devnull }
37 257fb626 2006-06-25 devnull if(pid == 0){
38 e6c837d6 2009-07-15 rsc char *devdraw;
39 257fb626 2006-06-25 devnull close(p[0]);
40 257fb626 2006-06-25 devnull dup(p[1], 0);
41 257fb626 2006-06-25 devnull dup(p[1], 1);
42 257fb626 2006-06-25 devnull /* execl("strace", "strace", "-o", "drawsrv.out", "drawsrv", nil); */
43 19f4cef5 2006-06-26 devnull /*
44 19f4cef5 2006-06-26 devnull * The argv0 has no meaning to devdraw.
45 19f4cef5 2006-06-26 devnull * Pass it along only so that the various
46 19f4cef5 2006-06-26 devnull * devdraws in psu -a can be distinguished.
47 b61a5ce8 2008-07-01 rsc * The NOLIBTHREADDAEMONIZE keeps devdraw from
48 b61a5ce8 2008-07-01 rsc * forking before threadmain. OS X hates it when
49 b61a5ce8 2008-07-01 rsc * guis fork.
50 4aad1a32 2009-04-30 rsc *
51 4aad1a32 2009-04-30 rsc * If client didn't use ARGBEGIN, argv0 == nil.
52 4aad1a32 2009-04-30 rsc * Can't send nil through because OS X expects
53 4aad1a32 2009-04-30 rsc * argv[0] to be non-nil. Also, OS X apparently
54 4aad1a32 2009-04-30 rsc * expects argv[0] to be a valid executable name,
55 4aad1a32 2009-04-30 rsc * so "(argv0)" is not okay. Use "devdraw"
56 4aad1a32 2009-04-30 rsc * instead.
57 19f4cef5 2006-06-26 devnull */
58 b61a5ce8 2008-07-01 rsc putenv("NOLIBTHREADDAEMONIZE", "1");
59 e6c837d6 2009-07-15 rsc devdraw = getenv("DEVDRAW");
60 e6c837d6 2009-07-15 rsc if(devdraw == nil)
61 e6c837d6 2009-07-15 rsc devdraw = "devdraw";
62 4aad1a32 2009-04-30 rsc if(argv0 == nil)
63 e6c837d6 2009-07-15 rsc argv0 = devdraw;
64 e6c837d6 2009-07-15 rsc execl(devdraw, argv0, argv0, "(devdraw)", nil);
65 150f8802 2006-06-25 devnull sysfatal("exec devdraw: %r");
66 257fb626 2006-06-25 devnull }
67 257fb626 2006-06-25 devnull close(p[1]);
68 257fb626 2006-06-25 devnull d->srvfd = p[0];
69 257fb626 2006-06-25 devnull return 0;
70 257fb626 2006-06-25 devnull }
71 257fb626 2006-06-25 devnull
72 257fb626 2006-06-25 devnull int
73 257fb626 2006-06-25 devnull _displaymux(Display *d)
74 257fb626 2006-06-25 devnull {
75 257fb626 2006-06-25 devnull if((d->mux = mallocz(sizeof(*d->mux), 1)) == nil)
76 257fb626 2006-06-25 devnull return -1;
77 257fb626 2006-06-25 devnull
78 257fb626 2006-06-25 devnull d->mux->mintag = 1;
79 257fb626 2006-06-25 devnull d->mux->maxtag = 255;
80 257fb626 2006-06-25 devnull d->mux->send = drawsend;
81 257fb626 2006-06-25 devnull d->mux->recv = drawrecv;
82 150f8802 2006-06-25 devnull d->mux->nbrecv = drawnbrecv;
83 257fb626 2006-06-25 devnull d->mux->gettag = drawgettag;
84 257fb626 2006-06-25 devnull d->mux->settag = drawsettag;
85 257fb626 2006-06-25 devnull d->mux->aux = d;
86 257fb626 2006-06-25 devnull muxinit(d->mux);
87 257fb626 2006-06-25 devnull
88 257fb626 2006-06-25 devnull return 0;
89 257fb626 2006-06-25 devnull }
90 257fb626 2006-06-25 devnull
91 257fb626 2006-06-25 devnull static int
92 257fb626 2006-06-25 devnull drawsend(Mux *mux, void *vmsg)
93 257fb626 2006-06-25 devnull {
94 257fb626 2006-06-25 devnull int n;
95 257fb626 2006-06-25 devnull uchar *msg;
96 257fb626 2006-06-25 devnull Display *d;
97 257fb626 2006-06-25 devnull
98 257fb626 2006-06-25 devnull msg = vmsg;
99 257fb626 2006-06-25 devnull GET(msg, n);
100 257fb626 2006-06-25 devnull d = mux->aux;
101 257fb626 2006-06-25 devnull return write(d->srvfd, msg, n);
102 257fb626 2006-06-25 devnull }
103 257fb626 2006-06-25 devnull
104 3a194702 2006-11-04 devnull static int
105 3a194702 2006-11-04 devnull _drawrecv(Mux *mux, int canblock, void **vp)
106 257fb626 2006-06-25 devnull {
107 257fb626 2006-06-25 devnull int n;
108 257fb626 2006-06-25 devnull uchar buf[4], *p;
109 257fb626 2006-06-25 devnull Display *d;
110 150f8802 2006-06-25 devnull
111 257fb626 2006-06-25 devnull d = mux->aux;
112 3a194702 2006-11-04 devnull *vp = nil;
113 3a194702 2006-11-04 devnull if(!canblock && !canreadfd(d->srvfd))
114 3a194702 2006-11-04 devnull return 0;
115 150f8802 2006-06-25 devnull if((n=readn(d->srvfd, buf, 4)) != 4)
116 3a194702 2006-11-04 devnull return 1;
117 257fb626 2006-06-25 devnull GET(buf, n);
118 257fb626 2006-06-25 devnull p = malloc(n);
119 257fb626 2006-06-25 devnull if(p == nil){
120 257fb626 2006-06-25 devnull fprint(2, "out of memory allocating %d in drawrecv\n", n);
121 3a194702 2006-11-04 devnull return 1;
122 257fb626 2006-06-25 devnull }
123 257fb626 2006-06-25 devnull memmove(p, buf, 4);
124 3a194702 2006-11-04 devnull if(readn(d->srvfd, p+4, n-4) != n-4){
125 3a194702 2006-11-04 devnull free(p);
126 3a194702 2006-11-04 devnull return 1;
127 3a194702 2006-11-04 devnull }
128 3a194702 2006-11-04 devnull *vp = p;
129 3a194702 2006-11-04 devnull return 1;
130 257fb626 2006-06-25 devnull }
131 257fb626 2006-06-25 devnull
132 150f8802 2006-06-25 devnull static void*
133 150f8802 2006-06-25 devnull drawrecv(Mux *mux)
134 150f8802 2006-06-25 devnull {
135 3a194702 2006-11-04 devnull void *p;
136 3a194702 2006-11-04 devnull _drawrecv(mux, 1, &p);
137 3a194702 2006-11-04 devnull return p;
138 150f8802 2006-06-25 devnull }
139 150f8802 2006-06-25 devnull
140 3a194702 2006-11-04 devnull static int
141 3a194702 2006-11-04 devnull drawnbrecv(Mux *mux, void **vp)
142 150f8802 2006-06-25 devnull {
143 3a194702 2006-11-04 devnull return _drawrecv(mux, 0, vp);
144 150f8802 2006-06-25 devnull }
145 150f8802 2006-06-25 devnull
146 257fb626 2006-06-25 devnull static int
147 257fb626 2006-06-25 devnull drawgettag(Mux *mux, void *vmsg)
148 257fb626 2006-06-25 devnull {
149 257fb626 2006-06-25 devnull uchar *msg;
150 40227f1f 2006-07-04 devnull USED(mux);
151 257fb626 2006-06-25 devnull
152 257fb626 2006-06-25 devnull msg = vmsg;
153 257fb626 2006-06-25 devnull return msg[4];
154 257fb626 2006-06-25 devnull }
155 257fb626 2006-06-25 devnull
156 257fb626 2006-06-25 devnull static int
157 257fb626 2006-06-25 devnull drawsettag(Mux *mux, void *vmsg, uint tag)
158 257fb626 2006-06-25 devnull {
159 257fb626 2006-06-25 devnull uchar *msg;
160 40227f1f 2006-07-04 devnull USED(mux);
161 257fb626 2006-06-25 devnull
162 257fb626 2006-06-25 devnull msg = vmsg;
163 257fb626 2006-06-25 devnull msg[4] = tag;
164 257fb626 2006-06-25 devnull return 0;
165 257fb626 2006-06-25 devnull }
166 257fb626 2006-06-25 devnull
167 257fb626 2006-06-25 devnull static int
168 257fb626 2006-06-25 devnull displayrpc(Display *d, Wsysmsg *tx, Wsysmsg *rx, void **freep)
169 257fb626 2006-06-25 devnull {
170 257fb626 2006-06-25 devnull int n, nn;
171 257fb626 2006-06-25 devnull void *tpkt, *rpkt;
172 257fb626 2006-06-25 devnull
173 257fb626 2006-06-25 devnull n = sizeW2M(tx);
174 257fb626 2006-06-25 devnull tpkt = malloc(n);
175 257fb626 2006-06-25 devnull if(freep)
176 257fb626 2006-06-25 devnull *freep = nil;
177 257fb626 2006-06-25 devnull if(tpkt == nil)
178 257fb626 2006-06-25 devnull return -1;
179 257fb626 2006-06-25 devnull tx->tag = 0;
180 257fb626 2006-06-25 devnull if(chattydrawclient)
181 257fb626 2006-06-25 devnull fprint(2, "<- %W\n", tx);
182 257fb626 2006-06-25 devnull nn = convW2M(tx, tpkt, n);
183 257fb626 2006-06-25 devnull if(nn != n){
184 257fb626 2006-06-25 devnull free(tpkt);
185 257fb626 2006-06-25 devnull werrstr("drawclient: sizeW2M convW2M mismatch");
186 257fb626 2006-06-25 devnull fprint(2, "%r\n");
187 257fb626 2006-06-25 devnull return -1;
188 257fb626 2006-06-25 devnull }
189 19f4cef5 2006-06-26 devnull /*
190 19f4cef5 2006-06-26 devnull * This is the only point where we might reschedule.
191 19f4cef5 2006-06-26 devnull * Muxrpc might need to acquire d->mux->lk, which could
192 19f4cef5 2006-06-26 devnull * be held by some other proc (e.g., the one reading from
193 19f4cef5 2006-06-26 devnull * the keyboard via Trdkbd messages). If we need to wait
194 19f4cef5 2006-06-26 devnull * for the lock, don't let other threads from this proc
195 19f4cef5 2006-06-26 devnull * run. This keeps up the appearance that writes to /dev/draw
196 19f4cef5 2006-06-26 devnull * don't cause rescheduling. If you *do* allow rescheduling
197 19f4cef5 2006-06-26 devnull * here, then flushimage(display, 1) happening in two different
198 19f4cef5 2006-06-26 devnull * threads in the same proc can cause a buffer of commands
199 19f4cef5 2006-06-26 devnull * to be written out twice, leading to interesting results
200 19f4cef5 2006-06-26 devnull * on the screen.
201 19f4cef5 2006-06-26 devnull *
202 19f4cef5 2006-06-26 devnull * Threadpin and threadunpin were added to the thread library
203 19f4cef5 2006-06-26 devnull * to solve exactly this problem. Be careful! They are dangerous.
204 19f4cef5 2006-06-26 devnull *
205 19f4cef5 2006-06-26 devnull * _pin and _unpin are aliases for threadpin and threadunpin
206 19f4cef5 2006-06-26 devnull * in a threaded program and are no-ops in unthreaded programs.
207 19f4cef5 2006-06-26 devnull */
208 19f4cef5 2006-06-26 devnull _pin();
209 257fb626 2006-06-25 devnull rpkt = muxrpc(d->mux, tpkt);
210 19f4cef5 2006-06-26 devnull _unpin();
211 257fb626 2006-06-25 devnull free(tpkt);
212 257fb626 2006-06-25 devnull if(rpkt == nil){
213 257fb626 2006-06-25 devnull werrstr("muxrpc: %r");
214 257fb626 2006-06-25 devnull return -1;
215 257fb626 2006-06-25 devnull }
216 257fb626 2006-06-25 devnull GET((uchar*)rpkt, n);
217 257fb626 2006-06-25 devnull nn = convM2W(rpkt, n, rx);
218 257fb626 2006-06-25 devnull if(nn != n){
219 257fb626 2006-06-25 devnull free(rpkt);
220 257fb626 2006-06-25 devnull werrstr("drawclient: convM2W packet size mismatch %d %d %.*H", n, nn, n, rpkt);
221 257fb626 2006-06-25 devnull fprint(2, "%r\n");
222 257fb626 2006-06-25 devnull return -1;
223 257fb626 2006-06-25 devnull }
224 257fb626 2006-06-25 devnull if(chattydrawclient)
225 257fb626 2006-06-25 devnull fprint(2, "-> %W\n", rx);
226 257fb626 2006-06-25 devnull if(rx->type == Rerror){
227 257fb626 2006-06-25 devnull werrstr("%s", rx->error);
228 257fb626 2006-06-25 devnull free(rpkt);
229 257fb626 2006-06-25 devnull return -1;
230 257fb626 2006-06-25 devnull }
231 257fb626 2006-06-25 devnull if(rx->type != tx->type+1){
232 257fb626 2006-06-25 devnull werrstr("packet type mismatch -- tx %d rx %d",
233 257fb626 2006-06-25 devnull tx->type, rx->type);
234 257fb626 2006-06-25 devnull free(rpkt);
235 257fb626 2006-06-25 devnull return -1;
236 257fb626 2006-06-25 devnull }
237 257fb626 2006-06-25 devnull if(freep)
238 257fb626 2006-06-25 devnull *freep = rpkt;
239 257fb626 2006-06-25 devnull else
240 257fb626 2006-06-25 devnull free(rpkt);
241 257fb626 2006-06-25 devnull return 0;
242 257fb626 2006-06-25 devnull }
243 257fb626 2006-06-25 devnull
244 257fb626 2006-06-25 devnull int
245 257fb626 2006-06-25 devnull _displayinit(Display *d, char *label, char *winsize)
246 257fb626 2006-06-25 devnull {
247 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
248 257fb626 2006-06-25 devnull
249 257fb626 2006-06-25 devnull tx.type = Tinit;
250 150f8802 2006-06-25 devnull tx.label = label;
251 150f8802 2006-06-25 devnull tx.winsize = winsize;
252 257fb626 2006-06-25 devnull return displayrpc(d, &tx, &rx, nil);
253 257fb626 2006-06-25 devnull }
254 257fb626 2006-06-25 devnull
255 257fb626 2006-06-25 devnull int
256 257fb626 2006-06-25 devnull _displayrdmouse(Display *d, Mouse *m, int *resized)
257 257fb626 2006-06-25 devnull {
258 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
259 257fb626 2006-06-25 devnull
260 257fb626 2006-06-25 devnull tx.type = Trdmouse;
261 257fb626 2006-06-25 devnull if(displayrpc(d, &tx, &rx, nil) < 0)
262 257fb626 2006-06-25 devnull return -1;
263 54bebe6a 2012-09-17 rsc _drawmouse = rx.mouse;
264 257fb626 2006-06-25 devnull *m = rx.mouse;
265 257fb626 2006-06-25 devnull *resized = rx.resized;
266 257fb626 2006-06-25 devnull return 0;
267 257fb626 2006-06-25 devnull }
268 257fb626 2006-06-25 devnull
269 257fb626 2006-06-25 devnull int
270 257fb626 2006-06-25 devnull _displayrdkbd(Display *d, Rune *r)
271 257fb626 2006-06-25 devnull {
272 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
273 257fb626 2006-06-25 devnull
274 257fb626 2006-06-25 devnull tx.type = Trdkbd;
275 257fb626 2006-06-25 devnull if(displayrpc(d, &tx, &rx, nil) < 0)
276 257fb626 2006-06-25 devnull return -1;
277 257fb626 2006-06-25 devnull *r = rx.rune;
278 257fb626 2006-06-25 devnull return 0;
279 257fb626 2006-06-25 devnull }
280 257fb626 2006-06-25 devnull
281 257fb626 2006-06-25 devnull int
282 257fb626 2006-06-25 devnull _displaymoveto(Display *d, Point p)
283 257fb626 2006-06-25 devnull {
284 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
285 257fb626 2006-06-25 devnull
286 257fb626 2006-06-25 devnull tx.type = Tmoveto;
287 257fb626 2006-06-25 devnull tx.mouse.xy = p;
288 54bebe6a 2012-09-17 rsc if(displayrpc(d, &tx, &rx, nil) < 0)
289 54bebe6a 2012-09-17 rsc return -1;
290 54bebe6a 2012-09-17 rsc _drawmouse.xy = p;
291 54bebe6a 2012-09-17 rsc return flushimage(d, 1);
292 257fb626 2006-06-25 devnull }
293 257fb626 2006-06-25 devnull
294 257fb626 2006-06-25 devnull int
295 257fb626 2006-06-25 devnull _displaycursor(Display *d, Cursor *c)
296 257fb626 2006-06-25 devnull {
297 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
298 257fb626 2006-06-25 devnull
299 257fb626 2006-06-25 devnull tx.type = Tcursor;
300 257fb626 2006-06-25 devnull if(c == nil){
301 257fb626 2006-06-25 devnull memset(&tx.cursor, 0, sizeof tx.cursor);
302 257fb626 2006-06-25 devnull tx.arrowcursor = 1;
303 257fb626 2006-06-25 devnull }else{
304 257fb626 2006-06-25 devnull tx.arrowcursor = 0;
305 257fb626 2006-06-25 devnull tx.cursor = *c;
306 257fb626 2006-06-25 devnull }
307 257fb626 2006-06-25 devnull return displayrpc(d, &tx, &rx, nil);
308 257fb626 2006-06-25 devnull }
309 257fb626 2006-06-25 devnull
310 257fb626 2006-06-25 devnull int
311 257fb626 2006-06-25 devnull _displaybouncemouse(Display *d, Mouse *m)
312 257fb626 2006-06-25 devnull {
313 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
314 257fb626 2006-06-25 devnull
315 257fb626 2006-06-25 devnull tx.type = Tbouncemouse;
316 257fb626 2006-06-25 devnull tx.mouse = *m;
317 257fb626 2006-06-25 devnull return displayrpc(d, &tx, &rx, nil);
318 257fb626 2006-06-25 devnull }
319 257fb626 2006-06-25 devnull
320 257fb626 2006-06-25 devnull int
321 257fb626 2006-06-25 devnull _displaylabel(Display *d, char *label)
322 257fb626 2006-06-25 devnull {
323 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
324 257fb626 2006-06-25 devnull
325 257fb626 2006-06-25 devnull tx.type = Tlabel;
326 257fb626 2006-06-25 devnull tx.label = label;
327 257fb626 2006-06-25 devnull return displayrpc(d, &tx, &rx, nil);
328 257fb626 2006-06-25 devnull }
329 257fb626 2006-06-25 devnull
330 257fb626 2006-06-25 devnull char*
331 257fb626 2006-06-25 devnull _displayrdsnarf(Display *d)
332 257fb626 2006-06-25 devnull {
333 257fb626 2006-06-25 devnull void *p;
334 257fb626 2006-06-25 devnull char *s;
335 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
336 257fb626 2006-06-25 devnull
337 257fb626 2006-06-25 devnull tx.type = Trdsnarf;
338 257fb626 2006-06-25 devnull if(displayrpc(d, &tx, &rx, &p) < 0)
339 257fb626 2006-06-25 devnull return nil;
340 257fb626 2006-06-25 devnull s = strdup(rx.snarf);
341 257fb626 2006-06-25 devnull free(p);
342 257fb626 2006-06-25 devnull return s;
343 257fb626 2006-06-25 devnull }
344 257fb626 2006-06-25 devnull
345 257fb626 2006-06-25 devnull int
346 257fb626 2006-06-25 devnull _displaywrsnarf(Display *d, char *snarf)
347 257fb626 2006-06-25 devnull {
348 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
349 257fb626 2006-06-25 devnull
350 257fb626 2006-06-25 devnull tx.type = Twrsnarf;
351 257fb626 2006-06-25 devnull tx.snarf = snarf;
352 257fb626 2006-06-25 devnull return displayrpc(d, &tx, &rx, nil);
353 257fb626 2006-06-25 devnull }
354 257fb626 2006-06-25 devnull
355 257fb626 2006-06-25 devnull int
356 257fb626 2006-06-25 devnull _displayrddraw(Display *d, void *v, int n)
357 257fb626 2006-06-25 devnull {
358 257fb626 2006-06-25 devnull void *p;
359 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
360 257fb626 2006-06-25 devnull
361 257fb626 2006-06-25 devnull tx.type = Trddraw;
362 257fb626 2006-06-25 devnull tx.count = n;
363 257fb626 2006-06-25 devnull if(displayrpc(d, &tx, &rx, &p) < 0)
364 257fb626 2006-06-25 devnull return -1;
365 257fb626 2006-06-25 devnull memmove(v, rx.data, rx.count);
366 257fb626 2006-06-25 devnull free(p);
367 257fb626 2006-06-25 devnull return rx.count;
368 257fb626 2006-06-25 devnull }
369 257fb626 2006-06-25 devnull
370 257fb626 2006-06-25 devnull int
371 257fb626 2006-06-25 devnull _displaywrdraw(Display *d, void *v, int n)
372 257fb626 2006-06-25 devnull {
373 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
374 257fb626 2006-06-25 devnull
375 257fb626 2006-06-25 devnull tx.type = Twrdraw;
376 257fb626 2006-06-25 devnull tx.count = n;
377 257fb626 2006-06-25 devnull tx.data = v;
378 257fb626 2006-06-25 devnull if(displayrpc(d, &tx, &rx, nil) < 0)
379 257fb626 2006-06-25 devnull return -1;
380 257fb626 2006-06-25 devnull return rx.count;
381 257fb626 2006-06-25 devnull }
382 257fb626 2006-06-25 devnull
383 257fb626 2006-06-25 devnull int
384 257fb626 2006-06-25 devnull _displaytop(Display *d)
385 257fb626 2006-06-25 devnull {
386 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
387 257fb626 2006-06-25 devnull
388 257fb626 2006-06-25 devnull tx.type = Ttop;
389 257fb626 2006-06-25 devnull return displayrpc(d, &tx, &rx, nil);
390 257fb626 2006-06-25 devnull }
391 257fb626 2006-06-25 devnull
392 257fb626 2006-06-25 devnull int
393 257fb626 2006-06-25 devnull _displayresize(Display *d, Rectangle r)
394 257fb626 2006-06-25 devnull {
395 257fb626 2006-06-25 devnull Wsysmsg tx, rx;
396 257fb626 2006-06-25 devnull
397 257fb626 2006-06-25 devnull tx.type = Tresize;
398 257fb626 2006-06-25 devnull tx.rect = r;
399 257fb626 2006-06-25 devnull return displayrpc(d, &tx, &rx, nil);
400 257fb626 2006-06-25 devnull }
401 257fb626 2006-06-25 devnull
402 150f8802 2006-06-25 devnull static int
403 150f8802 2006-06-25 devnull canreadfd(int fd)
404 150f8802 2006-06-25 devnull {
405 150f8802 2006-06-25 devnull fd_set rs, ws, xs;
406 150f8802 2006-06-25 devnull struct timeval tv;
407 150f8802 2006-06-25 devnull
408 150f8802 2006-06-25 devnull FD_ZERO(&rs);
409 150f8802 2006-06-25 devnull FD_ZERO(&ws);
410 150f8802 2006-06-25 devnull FD_ZERO(&xs);
411 150f8802 2006-06-25 devnull FD_SET(fd, &rs);
412 150f8802 2006-06-25 devnull FD_SET(fd, &xs);
413 150f8802 2006-06-25 devnull tv.tv_sec = 0;
414 150f8802 2006-06-25 devnull tv.tv_usec = 0;
415 150f8802 2006-06-25 devnull if(select(fd+1, &rs, &ws, &xs, &tv) < 0)
416 150f8802 2006-06-25 devnull return 0;
417 150f8802 2006-06-25 devnull if(FD_ISSET(fd, &rs) || FD_ISSET(fd, &xs))
418 150f8802 2006-06-25 devnull return 1;
419 150f8802 2006-06-25 devnull return 0;
420 150f8802 2006-06-25 devnull }
421 150f8802 2006-06-25 devnull