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);
205 if(eforkslave(Ekeyboard) < MAXSLAVE)
210 while(!fullrune(k, kn)){
211 kr = read(fd, k+kn, sizeof k - kn);
216 w = chartorune(&r, k);
218 memmove(k, &k[w], kn);
221 if(write(epipe[1], t, 3) != 3)
226 write(epipe[1], t, 1);
236 parentpid = getpid();
238 drawerror(display, "events: einit pipe");
241 snprint(buf, sizeof buf, "%s/mouse", display->devdir);
242 mousefd = open(buf, ORDWR|OCEXEC);
244 drawerror(display, "einit: can't open mouse\n");
245 snprint(buf, sizeof buf, "%s/cursor", display->devdir);
246 cursorfd = open(buf, ORDWR|OCEXEC);
248 drawerror(display, "einit: can't open cursor\n");
250 snprint(buf, sizeof buf, "%s/cons", display->devdir);
251 fd = open(buf, OREAD);
253 drawerror(display, "events: can't open console");
254 snprint(buf, sizeof buf, "%s/consctl", display->devdir);
255 ctl = open("/dev/consctl", OWRITE|OCEXEC);
257 drawerror(display, "events: can't open consctl");
258 write(ctl, "rawon", 5);
259 for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++)
264 estart(Emouse, mousefd, 1+4*12);
265 for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++)
276 uchar ebuf[EMAXMSG+1];
278 /* avoid generating a message if there's nothing to show. */
279 /* this test isn't perfect, though; could do flushimage(display, 0) then call extract */
280 /* also: make sure we don't interfere if we're multiprocessing the display */
281 if(display->locking){
282 /* if locking is being done by program, this means it can't depend on automatic flush in emouse() etc. */
283 if(canqlock(&display->qlock)){
284 if(display->bufp > display->buf)
285 flushimage(display, 1);
286 unlockdisplay(display);
289 if(display->bufp > display->buf)
290 flushimage(display, 1);
292 if((n=read(epipe[0], ebuf, EMAXMSG+1)) < 0
293 || ebuf[0] >= MAXSLAVE)
294 drawerror(display, "eof on event pipe");
298 if(i >= nslave || n <= 1)
299 drawerror(display, "events: protocol error: short read");
305 if(i == Skeyboard && n != 3)
306 drawerror(display, "events: protocol error: keyboard");
309 drawerror(display, "events: protocol error: mouse");
312 /* squash extraneous mouse events */
313 if((eb=s->tail) && memcmp(eb->buf+1+2*12, ebuf+1+1+2*12, 12)==0){
314 memmove(eb->buf, &ebuf[1], n - 1);
318 /* try to save space by only allocating as much buffer as we need */
319 eb = malloc(sizeof(*eb) - sizeof(eb->buf) + n - 1);
321 drawerror(display, "events: protocol error 4");
323 memmove(eb->buf, &ebuf[1], n - 1);
326 s->tail = s->tail->next = eb;
328 s->head = s->tail = eb;
332 eforkslave(ulong key)
336 for(i=0; i<MAXSLAVE; i++)
337 if((key & ~(1<<i)) == 0 && eslave[i].pid == 0){
341 * share the file descriptors so the last child
342 * out closes all connections to the window server.
344 switch(pid = rfork(RFPROC)){
348 fprint(2, "events: fork error\n");
352 eslave[i].head = eslave[i].tail = 0;
355 drawerror(display, "events: bad slave assignment");
360 enote(void *v, char *s)
367 if(pid != parentpid){
368 for(i=0; i<nslave; i++){
369 if(pid == eslave[i].pid){
371 write(epipe[1], t, 1);
381 for(i=0; i<nslave; i++){
382 if(pid == eslave[i].pid)
383 continue; /* don't kill myself */
384 postnote(PNPROC, eslave[i].pid, "die");
404 drawerror(display, "events: mouse not initialized");
405 eb = ebread(&eslave[Smouse]);
406 m.xy.x = atoi((char*)eb->buf+1+0*12);
407 m.xy.y = atoi((char*)eb->buf+1+1*12);
408 b = atoi((char*)eb->buf+1+2*12);
410 m.msec = atoi((char*)eb->buf+1+3*12);
412 fprint(logfid, "b: %d xy: %P\n", m.buttons, m.xy);
424 drawerror(display, "events: keyboard not initialzed");
425 eb = ebread(&eslave[Skeyboard]);
426 c = eb->buf[0] + (eb->buf[1]<<8);
437 n = sprint(buf, "m%d %d", pt.x, pt.y);
438 write(mousefd, buf, n);
442 esetcursor(Cursor *c)
444 uchar curs[2*4+2*2*16];
447 write(cursorfd, curs, 0);
449 BPLONG(curs+0*4, c->offset.x);
450 BPLONG(curs+1*4, c->offset.y);
451 memmove(curs+2*4, c->clr, 2*2*16);
452 write(cursorfd, curs, sizeof curs);
463 n = read(mousefd, buf, sizeof(buf));
464 if(n < 0) /* probably interrupted */
466 n = eatomouse(m, buf, n);
472 eatomouse(Mouse *m, char *buf, int n)
475 werrstr("atomouse: bad count");
481 m->xy.x = atoi(buf+1+0*12);
482 m->xy.y = atoi(buf+1+1*12);
483 m->buttons = atoi(buf+1+2*12);
484 m->msec = atoi(buf+1+3*12);