2 9142d362 2008-06-30 rsc * Window system protocol server.
5 9142d362 2008-06-30 rsc #include <u.h>
6 9142d362 2008-06-30 rsc #include <errno.h>
7 9142d362 2008-06-30 rsc #include <sys/select.h>
8 9142d362 2008-06-30 rsc #include <libc.h>
9 9142d362 2008-06-30 rsc #include <thread.h>
10 9142d362 2008-06-30 rsc #include <draw.h>
11 9142d362 2008-06-30 rsc #include <memdraw.h>
12 9142d362 2008-06-30 rsc #include <memlayer.h>
13 9142d362 2008-06-30 rsc #include <keyboard.h>
14 9142d362 2008-06-30 rsc #include <mouse.h>
15 9142d362 2008-06-30 rsc #include <cursor.h>
16 9142d362 2008-06-30 rsc #include <drawfcall.h>
17 9142d362 2008-06-30 rsc #include "osx-screen.h"
18 9142d362 2008-06-30 rsc #include "devdraw.h"
22 9142d362 2008-06-30 rsc #define MouseMask (\
23 9142d362 2008-06-30 rsc ButtonPressMask|\
24 9142d362 2008-06-30 rsc ButtonReleaseMask|\
25 9142d362 2008-06-30 rsc PointerMotionMask|\
26 9142d362 2008-06-30 rsc Button1MotionMask|\
27 9142d362 2008-06-30 rsc Button2MotionMask|\
28 9142d362 2008-06-30 rsc Button3MotionMask)
30 9142d362 2008-06-30 rsc #define Mask MouseMask|ExposureMask|StructureNotifyMask|KeyPressMask|EnterWindowMask|LeaveWindowMask
32 9142d362 2008-06-30 rsc typedef struct Kbdbuf Kbdbuf;
33 9142d362 2008-06-30 rsc typedef struct Mousebuf Mousebuf;
34 9142d362 2008-06-30 rsc typedef struct Fdbuf Fdbuf;
35 9142d362 2008-06-30 rsc typedef struct Tagbuf Tagbuf;
37 9142d362 2008-06-30 rsc struct Kbdbuf
45 9142d362 2008-06-30 rsc struct Mousebuf
54 9142d362 2008-06-30 rsc struct Tagbuf
62 9142d362 2008-06-30 rsc Mousebuf mouse;
63 9142d362 2008-06-30 rsc Tagbuf kbdtags;
64 9142d362 2008-06-30 rsc Tagbuf mousetags;
66 9142d362 2008-06-30 rsc void fdslide(Fdbuf*);
67 9142d362 2008-06-30 rsc void runmsg(Wsysmsg*);
68 9142d362 2008-06-30 rsc void replymsg(Wsysmsg*);
69 9142d362 2008-06-30 rsc void matchkbd(void);
70 9142d362 2008-06-30 rsc void matchmouse(void);
71 9142d362 2008-06-30 rsc int fdnoblock(int);
72 9142d362 2008-06-30 rsc Rectangle mouserect;
73 9142d362 2008-06-30 rsc int mouseresized;
84 9142d362 2008-06-30 rsc zunlock(void)
86 9142d362 2008-06-30 rsc qunlock(&lk);
90 9142d362 2008-06-30 rsc int drawsleep;
96 9142d362 2008-06-30 rsc fprint(2, "usage: devdraw (don't run directly)\n");
97 9142d362 2008-06-30 rsc threadexitsall("usage");
101 9142d362 2008-06-30 rsc bell(void *v, char *msg)
103 9142d362 2008-06-30 rsc if(strcmp(msg, "alarm") == 0)
104 9142d362 2008-06-30 rsc drawsleep = drawsleep ? 0 : 1000;
105 9142d362 2008-06-30 rsc noted(NCONT);
109 9142d362 2008-06-30 rsc threadmain(int argc, char **argv)
111 9142d362 2008-06-30 rsc uchar buf[4], *mbuf;
112 9142d362 2008-06-30 rsc int nmbuf, n, nn;
116 9142d362 2008-06-30 rsc * Move the protocol off stdin/stdout so that
117 9142d362 2008-06-30 rsc * any inadvertent prints don't screw things up.
123 9142d362 2008-06-30 rsc open("/dev/null", OREAD);
124 9142d362 2008-06-30 rsc open("/dev/null", OWRITE);
126 9142d362 2008-06-30 rsc //trace = 1;
127 9142d362 2008-06-30 rsc fmtinstall('W', drawfcallfmt);
138 9142d362 2008-06-30 rsc * Ignore arguments. They're only for good ps -a listings.
141 9142d362 2008-06-30 rsc notify(bell);
145 9142d362 2008-06-30 rsc while((n = read(3, buf, 4)) == 4){
146 9142d362 2008-06-30 rsc GET(buf, n);
147 9142d362 2008-06-30 rsc if(n > nmbuf){
149 9142d362 2008-06-30 rsc mbuf = malloc(4+n);
150 9142d362 2008-06-30 rsc if(mbuf == nil)
151 9142d362 2008-06-30 rsc sysfatal("malloc: %r");
154 9142d362 2008-06-30 rsc memmove(mbuf, buf, 4);
155 9142d362 2008-06-30 rsc nn = readn(3, mbuf+4, n-4);
156 9142d362 2008-06-30 rsc if(nn != n-4)
157 9142d362 2008-06-30 rsc sysfatal("eof during message");
159 9142d362 2008-06-30 rsc /* pick off messages one by one */
160 9142d362 2008-06-30 rsc if(convM2W(mbuf, nn+4, &m) <= 0)
161 9142d362 2008-06-30 rsc sysfatal("cannot convert message");
162 9142d362 2008-06-30 rsc if(trace) fprint(2, "<- %W\n", &m);
165 9142d362 2008-06-30 rsc threadexitsall(0);
169 9142d362 2008-06-30 rsc replyerror(Wsysmsg *m)
171 9142d362 2008-06-30 rsc char err[256];
173 9142d362 2008-06-30 rsc rerrstr(err, sizeof err);
174 9142d362 2008-06-30 rsc m->type = Rerror;
175 9142d362 2008-06-30 rsc m->error = err;
176 9142d362 2008-06-30 rsc replymsg(m);
180 9142d362 2008-06-30 rsc * Handle a single wsysmsg.
181 9142d362 2008-06-30 rsc * Might queue for later (kbd, mouse read)
184 9142d362 2008-06-30 rsc runmsg(Wsysmsg *m)
186 9142d362 2008-06-30 rsc static uchar buf[65536];
188 9142d362 2008-06-30 rsc Memimage *i;
190 9142d362 2008-06-30 rsc switch(m->type){
192 9142d362 2008-06-30 rsc memimageinit();
193 9142d362 2008-06-30 rsc i = attachscreen(m->label, m->winsize);
194 9142d362 2008-06-30 rsc _initdisplaymemimage(i);
195 9142d362 2008-06-30 rsc replymsg(m);
198 9142d362 2008-06-30 rsc case Trdmouse:
200 9142d362 2008-06-30 rsc mousetags.t[mousetags.wi++] = m->tag;
201 9142d362 2008-06-30 rsc if(mousetags.wi == nelem(mousetags.t))
202 9142d362 2008-06-30 rsc mousetags.wi = 0;
203 9142d362 2008-06-30 rsc if(mousetags.wi == mousetags.ri)
204 9142d362 2008-06-30 rsc sysfatal("too many queued mouse reads");
205 9142d362 2008-06-30 rsc mouse.stall = 0;
206 9142d362 2008-06-30 rsc matchmouse();
210 9142d362 2008-06-30 rsc case Trdkbd:
212 9142d362 2008-06-30 rsc kbdtags.t[kbdtags.wi++] = m->tag;
213 9142d362 2008-06-30 rsc if(kbdtags.wi == nelem(kbdtags.t))
214 9142d362 2008-06-30 rsc kbdtags.wi = 0;
215 9142d362 2008-06-30 rsc if(kbdtags.wi == kbdtags.ri)
216 9142d362 2008-06-30 rsc sysfatal("too many queued keyboard reads");
217 9142d362 2008-06-30 rsc kbd.stall = 0;
222 9142d362 2008-06-30 rsc case Tmoveto:
223 9142d362 2008-06-30 rsc setmouse(m->mouse.xy);
224 9142d362 2008-06-30 rsc replymsg(m);
227 9142d362 2008-06-30 rsc case Tcursor:
228 9142d362 2008-06-30 rsc if(m->arrowcursor)
229 9142d362 2008-06-30 rsc setcursor(nil);
231 9142d362 2008-06-30 rsc setcursor(&m->cursor);
232 9142d362 2008-06-30 rsc replymsg(m);
235 9142d362 2008-06-30 rsc case Tbouncemouse:
236 9142d362 2008-06-30 rsc // _xbouncemouse(&m->mouse);
237 9142d362 2008-06-30 rsc replymsg(m);
240 9142d362 2008-06-30 rsc case Tlabel:
241 4a34106c 2009-06-16 rsc kicklabel(m->label);
242 9142d362 2008-06-30 rsc replymsg(m);
245 9142d362 2008-06-30 rsc case Trdsnarf:
246 9142d362 2008-06-30 rsc m->snarf = getsnarf();
247 9142d362 2008-06-30 rsc replymsg(m);
248 9142d362 2008-06-30 rsc free(m->snarf);
251 9142d362 2008-06-30 rsc case Twrsnarf:
252 9142d362 2008-06-30 rsc putsnarf(m->snarf);
253 9142d362 2008-06-30 rsc replymsg(m);
256 9142d362 2008-06-30 rsc case Trddraw:
257 9142d362 2008-06-30 rsc n = m->count;
258 9142d362 2008-06-30 rsc if(n > sizeof buf)
259 9142d362 2008-06-30 rsc n = sizeof buf;
260 9142d362 2008-06-30 rsc n = _drawmsgread(buf, n);
262 9142d362 2008-06-30 rsc replyerror(m);
264 9142d362 2008-06-30 rsc m->count = n;
265 9142d362 2008-06-30 rsc m->data = buf;
266 9142d362 2008-06-30 rsc replymsg(m);
270 9142d362 2008-06-30 rsc case Twrdraw:
271 9142d362 2008-06-30 rsc if(_drawmsgwrite(m->data, m->count) < 0)
272 9142d362 2008-06-30 rsc replyerror(m);
274 9142d362 2008-06-30 rsc replymsg(m);
278 9142d362 2008-06-30 rsc // _xtopwindow();
279 9142d362 2008-06-30 rsc replymsg(m);
282 9142d362 2008-06-30 rsc case Tresize:
283 9142d362 2008-06-30 rsc // _xresizewindow(m->rect);
284 9142d362 2008-06-30 rsc replymsg(m);
290 9142d362 2008-06-30 rsc * Reply to m.
292 607880ce 2008-10-08 rsc QLock replylock;
294 9142d362 2008-06-30 rsc replymsg(Wsysmsg *m)
297 9142d362 2008-06-30 rsc static uchar *mbuf;
298 9142d362 2008-06-30 rsc static int nmbuf;
300 9142d362 2008-06-30 rsc /* T -> R msg */
301 9142d362 2008-06-30 rsc if(m->type%2 == 0)
304 9142d362 2008-06-30 rsc if(trace) fprint(2, "-> %W\n", m);
305 9142d362 2008-06-30 rsc /* copy to output buffer */
306 9142d362 2008-06-30 rsc n = sizeW2M(m);
308 607880ce 2008-10-08 rsc qlock(&replylock);
309 9142d362 2008-06-30 rsc if(n > nmbuf){
311 9142d362 2008-06-30 rsc mbuf = malloc(n);
312 9142d362 2008-06-30 rsc if(mbuf == nil)
313 9142d362 2008-06-30 rsc sysfatal("out of memory");
316 9142d362 2008-06-30 rsc convW2M(m, mbuf, n);
317 962d5a8b 2008-07-04 rsc if(write(4, mbuf, n) != n)
318 962d5a8b 2008-07-04 rsc sysfatal("write: %r");
319 607880ce 2008-10-08 rsc qunlock(&replylock);
323 9142d362 2008-06-30 rsc * Match queued kbd reads with queued kbd characters.
326 9142d362 2008-06-30 rsc matchkbd(void)
330 9142d362 2008-06-30 rsc if(kbd.stall)
332 9142d362 2008-06-30 rsc while(kbd.ri != kbd.wi && kbdtags.ri != kbdtags.wi){
333 9142d362 2008-06-30 rsc m.type = Rrdkbd;
334 9142d362 2008-06-30 rsc m.tag = kbdtags.t[kbdtags.ri++];
335 9142d362 2008-06-30 rsc if(kbdtags.ri == nelem(kbdtags.t))
336 9142d362 2008-06-30 rsc kbdtags.ri = 0;
337 9142d362 2008-06-30 rsc m.rune = kbd.r[kbd.ri++];
338 9142d362 2008-06-30 rsc if(kbd.ri == nelem(kbd.r))
340 9142d362 2008-06-30 rsc replymsg(&m);
345 9142d362 2008-06-30 rsc * Match queued mouse reads with queued mouse events.
348 9142d362 2008-06-30 rsc matchmouse(void)
352 9142d362 2008-06-30 rsc while(mouse.ri != mouse.wi && mousetags.ri != mousetags.wi){
353 9142d362 2008-06-30 rsc m.type = Rrdmouse;
354 9142d362 2008-06-30 rsc m.tag = mousetags.t[mousetags.ri++];
355 9142d362 2008-06-30 rsc if(mousetags.ri == nelem(mousetags.t))
356 9142d362 2008-06-30 rsc mousetags.ri = 0;
357 9142d362 2008-06-30 rsc m.mouse = mouse.m[mouse.ri];
358 9142d362 2008-06-30 rsc m.resized = mouseresized;
360 9142d362 2008-06-30 rsc if(m.resized)
361 9142d362 2008-06-30 rsc fprint(2, "sending resize\n");
363 9142d362 2008-06-30 rsc mouseresized = 0;
365 9142d362 2008-06-30 rsc if(mouse.ri == nelem(mouse.m))
366 9142d362 2008-06-30 rsc mouse.ri = 0;
367 9142d362 2008-06-30 rsc replymsg(&m);
372 9142d362 2008-06-30 rsc mousetrack(int x, int y, int b, int ms)
376 9142d362 2008-06-30 rsc if(x < mouserect.min.x)
377 9142d362 2008-06-30 rsc x = mouserect.min.x;
378 9142d362 2008-06-30 rsc if(x > mouserect.max.x)
379 9142d362 2008-06-30 rsc x = mouserect.max.x;
380 9142d362 2008-06-30 rsc if(y < mouserect.min.y)
381 9142d362 2008-06-30 rsc y = mouserect.min.y;
382 9142d362 2008-06-30 rsc if(y > mouserect.max.y)
383 9142d362 2008-06-30 rsc y = mouserect.max.y;
386 1f74e1b7 2008-07-10 rsc // If reader has stopped reading, don't bother.
387 1f74e1b7 2008-07-10 rsc // If reader is completely caught up, definitely queue.
388 1f74e1b7 2008-07-10 rsc // Otherwise, queue only button change events.
389 1f74e1b7 2008-07-10 rsc if(!mouse.stall)
390 1f74e1b7 2008-07-10 rsc if(mouse.wi == mouse.ri || mouse.last.buttons != b){
391 1f74e1b7 2008-07-10 rsc m = &mouse.last;
392 1f74e1b7 2008-07-10 rsc m->xy.x = x;
393 1f74e1b7 2008-07-10 rsc m->xy.y = y;
394 1f74e1b7 2008-07-10 rsc m->buttons = b;
395 1f74e1b7 2008-07-10 rsc m->msec = ms;
397 1f74e1b7 2008-07-10 rsc mouse.m[mouse.wi] = *m;
398 1f74e1b7 2008-07-10 rsc if(++mouse.wi == nelem(mouse.m))
399 1f74e1b7 2008-07-10 rsc mouse.wi = 0;
400 1f74e1b7 2008-07-10 rsc if(mouse.wi == mouse.ri){
401 1f74e1b7 2008-07-10 rsc mouse.stall = 1;
402 1f74e1b7 2008-07-10 rsc mouse.ri = 0;
403 1f74e1b7 2008-07-10 rsc mouse.wi = 1;
404 1f74e1b7 2008-07-10 rsc mouse.m[0] = *m;
406 1f74e1b7 2008-07-10 rsc matchmouse();
412 81a90f89 2008-07-02 rsc kputc(int c)
415 9142d362 2008-06-30 rsc kbd.r[kbd.wi++] = c;
416 9142d362 2008-06-30 rsc if(kbd.wi == nelem(kbd.r))
418 9142d362 2008-06-30 rsc if(kbd.ri == kbd.wi)
419 9142d362 2008-06-30 rsc kbd.stall = 1;
425 81a90f89 2008-07-02 rsc keystroke(int c)
427 81a90f89 2008-07-02 rsc static Rune k[10];
428 81a90f89 2008-07-02 rsc static int alting, nk;
431 81a90f89 2008-07-02 rsc if(c == Kalt){
432 81a90f89 2008-07-02 rsc alting = !alting;
435 81a90f89 2008-07-02 rsc if(!alting){
439 81a90f89 2008-07-02 rsc if(nk >= nelem(k)) // should not happen
441 81a90f89 2008-07-02 rsc k[nk++] = c;
442 81a90f89 2008-07-02 rsc c = _latin1(k, nk);
449 81a90f89 2008-07-02 rsc if(c == -1){
451 81a90f89 2008-07-02 rsc for(i=0; i<nk; i++)
452 81a90f89 2008-07-02 rsc kputc(k[i]);
456 81a90f89 2008-07-02 rsc // need more input