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 *);
49 while((eb = s->head) == 0)
60 return eread(~0UL, e);
64 eread(ulong keys, Event *e)
72 for(i=0; i<nslave; i++)
73 if((keys & (1<<i)) && eslave[i].head){
77 else if(i == Skeyboard)
82 eb = ebread(&eslave[i]);
85 id = (*eslave[i].fn)(id, e, eb->buf, eb->n);
87 memmove(e->data, eb->buf, eb->n);
100 drawerror(display, "events: mouse not initialized");
101 return ecanread(Emouse);
108 drawerror(display, "events: keyboard not initialzed");
109 return ecanread(Ekeyboard);
120 for(i=0; i<nslave; i++)
121 if((keys & (1<<i)) && eslave[i].head)
123 d = dirfstat(epipe[0]);
125 drawerror(display, "events: ecanread stat error");
135 estartfn(ulong key, int fd, int n, int (*fn)(int, Event*, uchar*, int))
141 drawerror(display, "events: bad file descriptor");
142 if(n <= 0 || n > EMAXMSG)
149 buf[0] = i - MAXSLAVE;
150 while((r = read(fd, buf+1, n))>0)
151 if(write(epipe[1], buf, r+1)!=r+1)
154 write(epipe[1], buf, 1);
160 estart(ulong key, int fd, int n)
162 return estartfn(key, fd, n, nil);
166 etimer(ulong key, int n)
171 drawerror(display, "events: timer started twice");
172 Stimer = eforkslave(key);
173 if(Stimer < MAXSLAVE)
177 t[0] = t[1] = Stimer - MAXSLAVE;
180 while(write(epipe[1], t, 2) == 2);
182 write(epipe[1], t, 1);
191 char t[1+UTFmax], k[10];
194 if(eforkslave(Ekeyboard) < MAXSLAVE)
199 while(!fullrune(k, kn)){
200 kr = read(fd, k+kn, sizeof k - kn);
205 w = chartorune(&r, k);
208 memmove(k, &k[w], kn);
209 if(write(epipe[1], t, sizeof(t)) != sizeof(t))
214 write(epipe[1], t, 1);
224 parentpid = getpid();
226 drawerror(display, "events: einit pipe");
229 snprint(buf, sizeof buf, "%s/mouse", display->devdir);
230 mousefd = open(buf, ORDWR|OCEXEC);
232 drawerror(display, "einit: can't open mouse\n");
233 snprint(buf, sizeof buf, "%s/cursor", display->devdir);
234 cursorfd = open(buf, ORDWR|OCEXEC);
236 drawerror(display, "einit: can't open cursor\n");
238 snprint(buf, sizeof buf, "%s/cons", display->devdir);
239 fd = open(buf, OREAD);
241 drawerror(display, "events: can't open console");
242 snprint(buf, sizeof buf, "%s/consctl", display->devdir);
243 ctl = open("/dev/consctl", OWRITE|OCEXEC);
245 drawerror(display, "events: can't open consctl");
246 write(ctl, "rawon", 5);
247 for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++)
252 estart(Emouse, mousefd, 1+4*12);
253 for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++)
264 uchar ebuf[EMAXMSG+1];
266 /* avoid generating a message if there's nothing to show. */
267 /* this test isn't perfect, though; could do flushimage(display, 0) then call extract */
268 /* also: make sure we don't interfere if we're multiprocessing the display */
269 if(display->locking){
270 /* if locking is being done by program, this means it can't depend on automatic flush in emouse() etc. */
271 if(canqlock(&display->qlock)){
272 if(display->bufp > display->buf)
273 flushimage(display, 1);
274 unlockdisplay(display);
277 if(display->bufp > display->buf)
278 flushimage(display, 1);
280 if((n=read(epipe[0], ebuf, EMAXMSG+1)) < 0
281 || ebuf[0] >= MAXSLAVE)
282 drawerror(display, "eof on event pipe");
286 if(i >= nslave || n <= 1)
287 drawerror(display, "events: protocol error: short read");
293 if(i == Skeyboard && n != (1+UTFmax))
294 drawerror(display, "events: protocol error: keyboard");
297 drawerror(display, "events: protocol error: mouse");
300 /* squash extraneous mouse events */
301 if((eb=s->tail) && memcmp(eb->buf+1+2*12, ebuf+1+1+2*12, 12)==0){
302 memmove(eb->buf, &ebuf[1], n - 1);
306 /* try to save space by only allocating as much buffer as we need */
307 eb = malloc(sizeof(*eb) - sizeof(eb->buf) + n - 1);
309 drawerror(display, "events: protocol error 4");
311 memmove(eb->buf, &ebuf[1], n - 1);
321 eforkslave(ulong key)
325 for(i=0; i<MAXSLAVE; i++)
326 if((key & ~(1<<i)) == 0 && eslave[i].pid == 0){
330 * share the file descriptors so the last child
331 * out closes all connections to the window server.
333 switch(pid = rfork(RFPROC)){
337 fprint(2, "events: fork error\n");
341 eslave[i].head = eslave[i].tail = 0;
344 drawerror(display, "events: bad slave assignment");
349 enote(void*, char *s)
353 if(strncmp(s, "sys:", 4) == 0 || strcmp(s, "alarm") == 0)
356 for(i=0; i<nslave; i++)
357 if(pid == eslave[i].pid)
371 for(i=0; i<nslave; i++){
372 if(eslave[i].pid == 0 || pid == eslave[i].pid)
373 continue; /* don't kill myself */
374 postnote(PNPROC, eslave[i].pid, "die");
387 drawerror(display, "events: mouse not initialized");
389 eb = ebread(&eslave[Smouse]);
390 b = atoi((char*)eb->buf+1+2*12);
391 if(b != lastb || !ecanmouse())
393 free(eb); /* drop queued mouse events */
397 m.xy.x = atoi((char*)eb->buf+1+0*12);
398 m.xy.y = atoi((char*)eb->buf+1+1*12);
399 m.msec = atoi((char*)eb->buf+1+3*12);
401 fprint(logfid, "b: %d xy: %P\n", m.buttons, m.xy);
413 drawerror(display, "events: keyboard not initialzed");
414 eb = ebread(&eslave[Skeyboard]);
415 chartorune(&r, (char*)eb->buf);
426 n = sprint(buf, "m%d %d", pt.x, pt.y);
427 write(mousefd, buf, n);
431 esetcursor(Cursor *c)
433 uchar curs[2*4+2*2*16];
436 write(cursorfd, curs, 0);
438 BPLONG(curs+0*4, c->offset.x);
439 BPLONG(curs+1*4, c->offset.y);
440 memmove(curs+2*4, c->clr, 2*2*16);
441 write(cursorfd, curs, sizeof curs);
452 n = read(mousefd, buf, sizeof(buf));
453 if(n < 0) /* probably interrupted */
455 n = eatomouse(m, buf, n);
461 eatomouse(Mouse *m, char *buf, int n)
464 werrstr("eatomouse: bad count");
470 m->xy.x = atoi(buf+1+0*12);
471 m->xy.y = atoi(buf+1+1*12);
472 m->buttons = atoi(buf+1+2*12);
473 m->msec = atoi(buf+1+3*12);