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;
92 100ec44e 2010-01-04 rsc int multitouch = 1;
97 9142d362 2008-06-30 rsc fprint(2, "usage: devdraw (don't run directly)\n");
98 9142d362 2008-06-30 rsc threadexitsall("usage");
102 9142d362 2008-06-30 rsc bell(void *v, char *msg)
104 9142d362 2008-06-30 rsc if(strcmp(msg, "alarm") == 0)
105 9142d362 2008-06-30 rsc drawsleep = drawsleep ? 0 : 1000;
106 9142d362 2008-06-30 rsc noted(NCONT);
110 9142d362 2008-06-30 rsc threadmain(int argc, char **argv)
112 9142d362 2008-06-30 rsc uchar buf[4], *mbuf;
113 9142d362 2008-06-30 rsc int nmbuf, n, nn;
117 9142d362 2008-06-30 rsc * Move the protocol off stdin/stdout so that
118 9142d362 2008-06-30 rsc * any inadvertent prints don't screw things up.
124 9142d362 2008-06-30 rsc open("/dev/null", OREAD);
125 9142d362 2008-06-30 rsc open("/dev/null", OWRITE);
127 9142d362 2008-06-30 rsc //trace = 1;
128 9142d362 2008-06-30 rsc fmtinstall('W', drawfcallfmt);
135 100ec44e 2010-01-04 rsc multitouch = 0;
142 9142d362 2008-06-30 rsc * Ignore arguments. They're only for good ps -a listings.
145 9142d362 2008-06-30 rsc notify(bell);
149 9142d362 2008-06-30 rsc while((n = read(3, buf, 4)) == 4){
150 9142d362 2008-06-30 rsc GET(buf, n);
151 9142d362 2008-06-30 rsc if(n > nmbuf){
153 9142d362 2008-06-30 rsc mbuf = malloc(4+n);
154 9142d362 2008-06-30 rsc if(mbuf == nil)
155 9142d362 2008-06-30 rsc sysfatal("malloc: %r");
158 9142d362 2008-06-30 rsc memmove(mbuf, buf, 4);
159 9142d362 2008-06-30 rsc nn = readn(3, mbuf+4, n-4);
160 9142d362 2008-06-30 rsc if(nn != n-4)
161 9142d362 2008-06-30 rsc sysfatal("eof during message");
163 9142d362 2008-06-30 rsc /* pick off messages one by one */
164 9142d362 2008-06-30 rsc if(convM2W(mbuf, nn+4, &m) <= 0)
165 9142d362 2008-06-30 rsc sysfatal("cannot convert message");
166 9142d362 2008-06-30 rsc if(trace) fprint(2, "<- %W\n", &m);
169 9142d362 2008-06-30 rsc threadexitsall(0);
173 9142d362 2008-06-30 rsc replyerror(Wsysmsg *m)
175 9142d362 2008-06-30 rsc char err[256];
177 9142d362 2008-06-30 rsc rerrstr(err, sizeof err);
178 9142d362 2008-06-30 rsc m->type = Rerror;
179 9142d362 2008-06-30 rsc m->error = err;
180 9142d362 2008-06-30 rsc replymsg(m);
184 9142d362 2008-06-30 rsc * Handle a single wsysmsg.
185 9142d362 2008-06-30 rsc * Might queue for later (kbd, mouse read)
188 9142d362 2008-06-30 rsc runmsg(Wsysmsg *m)
190 9142d362 2008-06-30 rsc static uchar buf[65536];
192 9142d362 2008-06-30 rsc Memimage *i;
194 9142d362 2008-06-30 rsc switch(m->type){
196 9142d362 2008-06-30 rsc memimageinit();
197 9142d362 2008-06-30 rsc i = attachscreen(m->label, m->winsize);
198 9142d362 2008-06-30 rsc _initdisplaymemimage(i);
199 9142d362 2008-06-30 rsc replymsg(m);
202 9142d362 2008-06-30 rsc case Trdmouse:
204 9142d362 2008-06-30 rsc mousetags.t[mousetags.wi++] = m->tag;
205 9142d362 2008-06-30 rsc if(mousetags.wi == nelem(mousetags.t))
206 9142d362 2008-06-30 rsc mousetags.wi = 0;
207 9142d362 2008-06-30 rsc if(mousetags.wi == mousetags.ri)
208 9142d362 2008-06-30 rsc sysfatal("too many queued mouse reads");
209 9142d362 2008-06-30 rsc mouse.stall = 0;
210 9142d362 2008-06-30 rsc matchmouse();
214 9142d362 2008-06-30 rsc case Trdkbd:
216 9142d362 2008-06-30 rsc kbdtags.t[kbdtags.wi++] = m->tag;
217 9142d362 2008-06-30 rsc if(kbdtags.wi == nelem(kbdtags.t))
218 9142d362 2008-06-30 rsc kbdtags.wi = 0;
219 9142d362 2008-06-30 rsc if(kbdtags.wi == kbdtags.ri)
220 9142d362 2008-06-30 rsc sysfatal("too many queued keyboard reads");
221 9142d362 2008-06-30 rsc kbd.stall = 0;
226 9142d362 2008-06-30 rsc case Tmoveto:
227 9142d362 2008-06-30 rsc setmouse(m->mouse.xy);
228 9142d362 2008-06-30 rsc replymsg(m);
231 9142d362 2008-06-30 rsc case Tcursor:
232 9142d362 2008-06-30 rsc if(m->arrowcursor)
233 9142d362 2008-06-30 rsc setcursor(nil);
235 9142d362 2008-06-30 rsc setcursor(&m->cursor);
236 9142d362 2008-06-30 rsc replymsg(m);
239 9142d362 2008-06-30 rsc case Tbouncemouse:
240 9142d362 2008-06-30 rsc // _xbouncemouse(&m->mouse);
241 9142d362 2008-06-30 rsc replymsg(m);
244 9142d362 2008-06-30 rsc case Tlabel:
245 4a34106c 2009-06-16 rsc kicklabel(m->label);
246 9142d362 2008-06-30 rsc replymsg(m);
249 9142d362 2008-06-30 rsc case Trdsnarf:
250 9142d362 2008-06-30 rsc m->snarf = getsnarf();
251 9142d362 2008-06-30 rsc replymsg(m);
252 9142d362 2008-06-30 rsc free(m->snarf);
255 9142d362 2008-06-30 rsc case Twrsnarf:
256 9142d362 2008-06-30 rsc putsnarf(m->snarf);
257 9142d362 2008-06-30 rsc replymsg(m);
260 9142d362 2008-06-30 rsc case Trddraw:
261 9142d362 2008-06-30 rsc n = m->count;
262 9142d362 2008-06-30 rsc if(n > sizeof buf)
263 9142d362 2008-06-30 rsc n = sizeof buf;
264 9142d362 2008-06-30 rsc n = _drawmsgread(buf, n);
266 9142d362 2008-06-30 rsc replyerror(m);
268 9142d362 2008-06-30 rsc m->count = n;
269 9142d362 2008-06-30 rsc m->data = buf;
270 9142d362 2008-06-30 rsc replymsg(m);
274 9142d362 2008-06-30 rsc case Twrdraw:
275 9142d362 2008-06-30 rsc if(_drawmsgwrite(m->data, m->count) < 0)
276 9142d362 2008-06-30 rsc replyerror(m);
278 9142d362 2008-06-30 rsc replymsg(m);
282 9142d362 2008-06-30 rsc // _xtopwindow();
283 9142d362 2008-06-30 rsc replymsg(m);
286 9142d362 2008-06-30 rsc case Tresize:
287 9142d362 2008-06-30 rsc // _xresizewindow(m->rect);
288 9142d362 2008-06-30 rsc replymsg(m);
294 9142d362 2008-06-30 rsc * Reply to m.
296 607880ce 2008-10-08 rsc QLock replylock;
298 9142d362 2008-06-30 rsc replymsg(Wsysmsg *m)
301 9142d362 2008-06-30 rsc static uchar *mbuf;
302 9142d362 2008-06-30 rsc static int nmbuf;
304 9142d362 2008-06-30 rsc /* T -> R msg */
305 9142d362 2008-06-30 rsc if(m->type%2 == 0)
308 9142d362 2008-06-30 rsc if(trace) fprint(2, "-> %W\n", m);
309 9142d362 2008-06-30 rsc /* copy to output buffer */
310 9142d362 2008-06-30 rsc n = sizeW2M(m);
312 607880ce 2008-10-08 rsc qlock(&replylock);
313 9142d362 2008-06-30 rsc if(n > nmbuf){
315 9142d362 2008-06-30 rsc mbuf = malloc(n);
316 9142d362 2008-06-30 rsc if(mbuf == nil)
317 9142d362 2008-06-30 rsc sysfatal("out of memory");
320 9142d362 2008-06-30 rsc convW2M(m, mbuf, n);
321 962d5a8b 2008-07-04 rsc if(write(4, mbuf, n) != n)
322 962d5a8b 2008-07-04 rsc sysfatal("write: %r");
323 607880ce 2008-10-08 rsc qunlock(&replylock);
327 9142d362 2008-06-30 rsc * Match queued kbd reads with queued kbd characters.
330 9142d362 2008-06-30 rsc matchkbd(void)
334 9142d362 2008-06-30 rsc if(kbd.stall)
336 9142d362 2008-06-30 rsc while(kbd.ri != kbd.wi && kbdtags.ri != kbdtags.wi){
337 9142d362 2008-06-30 rsc m.type = Rrdkbd;
338 9142d362 2008-06-30 rsc m.tag = kbdtags.t[kbdtags.ri++];
339 9142d362 2008-06-30 rsc if(kbdtags.ri == nelem(kbdtags.t))
340 9142d362 2008-06-30 rsc kbdtags.ri = 0;
341 9142d362 2008-06-30 rsc m.rune = kbd.r[kbd.ri++];
342 9142d362 2008-06-30 rsc if(kbd.ri == nelem(kbd.r))
344 9142d362 2008-06-30 rsc replymsg(&m);
349 9142d362 2008-06-30 rsc * Match queued mouse reads with queued mouse events.
352 9142d362 2008-06-30 rsc matchmouse(void)
356 9142d362 2008-06-30 rsc while(mouse.ri != mouse.wi && mousetags.ri != mousetags.wi){
357 9142d362 2008-06-30 rsc m.type = Rrdmouse;
358 9142d362 2008-06-30 rsc m.tag = mousetags.t[mousetags.ri++];
359 9142d362 2008-06-30 rsc if(mousetags.ri == nelem(mousetags.t))
360 9142d362 2008-06-30 rsc mousetags.ri = 0;
361 9142d362 2008-06-30 rsc m.mouse = mouse.m[mouse.ri];
362 9142d362 2008-06-30 rsc m.resized = mouseresized;
364 9142d362 2008-06-30 rsc if(m.resized)
365 9142d362 2008-06-30 rsc fprint(2, "sending resize\n");
367 9142d362 2008-06-30 rsc mouseresized = 0;
369 9142d362 2008-06-30 rsc if(mouse.ri == nelem(mouse.m))
370 9142d362 2008-06-30 rsc mouse.ri = 0;
371 9142d362 2008-06-30 rsc replymsg(&m);
376 9142d362 2008-06-30 rsc mousetrack(int x, int y, int b, int ms)
380 9142d362 2008-06-30 rsc if(x < mouserect.min.x)
381 9142d362 2008-06-30 rsc x = mouserect.min.x;
382 9142d362 2008-06-30 rsc if(x > mouserect.max.x)
383 9142d362 2008-06-30 rsc x = mouserect.max.x;
384 9142d362 2008-06-30 rsc if(y < mouserect.min.y)
385 9142d362 2008-06-30 rsc y = mouserect.min.y;
386 9142d362 2008-06-30 rsc if(y > mouserect.max.y)
387 9142d362 2008-06-30 rsc y = mouserect.max.y;
390 1f74e1b7 2008-07-10 rsc // If reader has stopped reading, don't bother.
391 1f74e1b7 2008-07-10 rsc // If reader is completely caught up, definitely queue.
392 1f74e1b7 2008-07-10 rsc // Otherwise, queue only button change events.
393 1f74e1b7 2008-07-10 rsc if(!mouse.stall)
394 1f74e1b7 2008-07-10 rsc if(mouse.wi == mouse.ri || mouse.last.buttons != b){
395 1f74e1b7 2008-07-10 rsc m = &mouse.last;
396 1f74e1b7 2008-07-10 rsc m->xy.x = x;
397 1f74e1b7 2008-07-10 rsc m->xy.y = y;
398 1f74e1b7 2008-07-10 rsc m->buttons = b;
399 1f74e1b7 2008-07-10 rsc m->msec = ms;
401 1f74e1b7 2008-07-10 rsc mouse.m[mouse.wi] = *m;
402 1f74e1b7 2008-07-10 rsc if(++mouse.wi == nelem(mouse.m))
403 1f74e1b7 2008-07-10 rsc mouse.wi = 0;
404 1f74e1b7 2008-07-10 rsc if(mouse.wi == mouse.ri){
405 1f74e1b7 2008-07-10 rsc mouse.stall = 1;
406 1f74e1b7 2008-07-10 rsc mouse.ri = 0;
407 1f74e1b7 2008-07-10 rsc mouse.wi = 1;
408 1f74e1b7 2008-07-10 rsc mouse.m[0] = *m;
410 1f74e1b7 2008-07-10 rsc matchmouse();
416 81a90f89 2008-07-02 rsc kputc(int c)
419 9142d362 2008-06-30 rsc kbd.r[kbd.wi++] = c;
420 9142d362 2008-06-30 rsc if(kbd.wi == nelem(kbd.r))
422 9142d362 2008-06-30 rsc if(kbd.ri == kbd.wi)
423 9142d362 2008-06-30 rsc kbd.stall = 1;
429 81a90f89 2008-07-02 rsc keystroke(int c)
431 81a90f89 2008-07-02 rsc static Rune k[10];
432 81a90f89 2008-07-02 rsc static int alting, nk;
435 81a90f89 2008-07-02 rsc if(c == Kalt){
436 81a90f89 2008-07-02 rsc alting = !alting;
439 81a90f89 2008-07-02 rsc if(!alting){
443 81a90f89 2008-07-02 rsc if(nk >= nelem(k)) // should not happen
445 81a90f89 2008-07-02 rsc k[nk++] = c;
446 81a90f89 2008-07-02 rsc c = _latin1(k, nk);
453 81a90f89 2008-07-02 rsc if(c == -1){
455 81a90f89 2008-07-02 rsc for(i=0; i<nk; i++)
456 81a90f89 2008-07-02 rsc kputc(k[i]);
460 81a90f89 2008-07-02 rsc // need more input