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