7 typedef struct Slave Slave;
8 typedef struct Ebuf Ebuf;
13 Ebuf *head; /* queue of messages for this descriptor */
15 int (*fn)(int, Event*, uchar*, int);
21 int n; /* number of bytes in buf */
25 static Slave eslave[MAXSLAVE];
26 static int Skeyboard = -1;
27 static int Smouse = -1;
28 static int Stimer = -1;
35 static int eforkslave(ulong);
36 static void extract(void);
37 static void ekill(void);
38 static int enote(void *, char *);
52 d = dirfstat(epipe[0]);
54 drawerror(display, "events: eread stat error");
62 s->head = s->head->next;
71 return eread(~0UL, e);
75 eread(ulong keys, Event *e)
83 for(i=0; i<nslave; i++)
84 if((keys & (1<<i)) && eslave[i].head){
88 else if(i == Skeyboard)
93 eb = ebread(&eslave[i]);
96 id = (*eslave[i].fn)(id, e, eb->buf, eb->n);
98 memmove(e->data, eb->buf, eb->n);
111 drawerror(display, "events: mouse not initialized");
112 return ecanread(Emouse);
119 drawerror(display, "events: keyboard not initialzed");
120 return ecanread(Ekeyboard);
131 for(i=0; i<nslave; i++)
132 if((keys & (1<<i)) && eslave[i].head)
134 d = dirfstat(epipe[0]);
136 drawerror(display, "events: ecanread stat error");
146 estartfn(ulong key, int fd, int n, int (*fn)(int, Event*, uchar*, int))
152 drawerror(display, "events: bad file descriptor");
153 if(n <= 0 || n > EMAXMSG)
160 buf[0] = i - MAXSLAVE;
161 while((r = read(fd, buf+1, n))>0)
162 if(write(epipe[1], buf, r+1)!=r+1)
165 write(epipe[1], buf, 1);
171 estart(ulong key, int fd, int n)
173 return estartfn(key, fd, n, nil);
177 etimer(ulong key, int n)
182 drawerror(display, "events: timer started twice");
183 Stimer = eforkslave(key);
184 if(Stimer < MAXSLAVE)
188 t[0] = t[1] = Stimer - MAXSLAVE;
191 while(write(epipe[1], t, 2) == 2);
193 write(epipe[1], t, 1);
202 char t[1+UTFmax], k[10];
205 if(eforkslave(Ekeyboard) < MAXSLAVE)
210 while(!fullrune(k, kn)){
211 kr = read(fd, k+kn, sizeof k - kn);
216 w = chartorune(&r, k);
219 memmove(k, &k[w], kn);
220 if(write(epipe[1], t, sizeof(t)) != sizeof(t))
225 write(epipe[1], t, 1);
235 parentpid = getpid();
237 drawerror(display, "events: einit pipe");
240 snprint(buf, sizeof buf, "%s/mouse", display->devdir);
241 mousefd = open(buf, ORDWR|OCEXEC);
243 drawerror(display, "einit: can't open mouse\n");
244 snprint(buf, sizeof buf, "%s/cursor", display->devdir);
245 cursorfd = open(buf, ORDWR|OCEXEC);
247 drawerror(display, "einit: can't open cursor\n");
249 snprint(buf, sizeof buf, "%s/cons", display->devdir);
250 fd = open(buf, OREAD);
252 drawerror(display, "events: can't open console");
253 snprint(buf, sizeof buf, "%s/consctl", display->devdir);
254 ctl = open("/dev/consctl", OWRITE|OCEXEC);
256 drawerror(display, "events: can't open consctl");
257 write(ctl, "rawon", 5);
258 for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++)
263 estart(Emouse, mousefd, 1+4*12);
264 for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++)
275 uchar ebuf[EMAXMSG+1];
277 /* avoid generating a message if there's nothing to show. */
278 /* this test isn't perfect, though; could do flushimage(display, 0) then call extract */
279 /* also: make sure we don't interfere if we're multiprocessing the display */
280 if(display->locking){
281 /* if locking is being done by program, this means it can't depend on automatic flush in emouse() etc. */
282 if(canqlock(&display->qlock)){
283 if(display->bufp > display->buf)
284 flushimage(display, 1);
285 unlockdisplay(display);
288 if(display->bufp > display->buf)
289 flushimage(display, 1);
291 if((n=read(epipe[0], ebuf, EMAXMSG+1)) < 0
292 || ebuf[0] >= MAXSLAVE)
293 drawerror(display, "eof on event pipe");
297 if(i >= nslave || n <= 1)
298 drawerror(display, "events: protocol error: short read");
304 if(i == Skeyboard && n != (1+UTFmax))
305 drawerror(display, "events: protocol error: keyboard");
308 drawerror(display, "events: protocol error: mouse");
311 /* squash extraneous mouse events */
312 if((eb=s->tail) && memcmp(eb->buf+1+2*12, ebuf+1+1+2*12, 12)==0){
313 memmove(eb->buf, &ebuf[1], n - 1);
317 /* try to save space by only allocating as much buffer as we need */
318 eb = malloc(sizeof(*eb) - sizeof(eb->buf) + n - 1);
320 drawerror(display, "events: protocol error 4");
322 memmove(eb->buf, &ebuf[1], n - 1);
325 s->tail = s->tail->next = eb;
327 s->head = s->tail = eb;
331 eforkslave(ulong key)
335 for(i=0; i<MAXSLAVE; i++)
336 if((key & ~(1<<i)) == 0 && eslave[i].pid == 0){
340 * share the file descriptors so the last child
341 * out closes all connections to the window server.
343 switch(pid = rfork(RFPROC)){
347 fprint(2, "events: fork error\n");
351 eslave[i].head = eslave[i].tail = 0;
354 drawerror(display, "events: bad slave assignment");
359 enote(void *v, char *s)
366 if(pid != parentpid){
367 for(i=0; i<nslave; i++){
368 if(pid == eslave[i].pid){
370 write(epipe[1], t, 1);
380 for(i=0; i<nslave; i++){
381 if(pid == eslave[i].pid)
382 continue; /* don't kill myself */
383 postnote(PNPROC, eslave[i].pid, "die");
403 drawerror(display, "events: mouse not initialized");
404 eb = ebread(&eslave[Smouse]);
405 m.xy.x = atoi((char*)eb->buf+1+0*12);
406 m.xy.y = atoi((char*)eb->buf+1+1*12);
407 b = atoi((char*)eb->buf+1+2*12);
409 m.msec = atoi((char*)eb->buf+1+3*12);
411 fprint(logfid, "b: %d xy: %P\n", m.buttons, m.xy);
423 drawerror(display, "events: keyboard not initialzed");
424 eb = ebread(&eslave[Skeyboard]);
425 chartorune(&r, (char*)eb->buf);
435 n = sprint(buf, "m%d %d", pt.x, pt.y);
436 write(mousefd, buf, n);
440 esetcursor(Cursor *c)
442 uchar curs[2*4+2*2*16];
445 write(cursorfd, curs, 0);
447 BPLONG(curs+0*4, c->offset.x);
448 BPLONG(curs+1*4, c->offset.y);
449 memmove(curs+2*4, c->clr, 2*2*16);
450 write(cursorfd, curs, sizeof curs);
461 n = read(mousefd, buf, sizeof(buf));
462 if(n < 0) /* probably interrupted */
464 n = eatomouse(m, buf, n);
470 eatomouse(Mouse *m, char *buf, int n)
473 werrstr("atomouse: bad count");
479 m->xy.x = atoi(buf+1+0*12);
480 m->xy.y = atoi(buf+1+1*12);
481 m->buttons = atoi(buf+1+2*12);
482 m->msec = atoi(buf+1+3*12);