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