#include #include #include #include #include #include #include #include #include typedef unsigned char uchar; typedef unsigned long ulong; Slave eslave[MAXSLAVE]; int Skeyboard = -1; int Smouse = -1; int Stimer = -1; int logfid; extern int dontbexit; static int nslave; static int isparent; static int epipe[2]; static int eforkslave(ulong); static void extract(void); static void ekill(void); static void enote(int); static int empty_pipe(int); ulong event(Event *e) { return eread(~0UL, e); } ulong eread(ulong keys, Event *e) { Ebuf *eb; int i; if(keys == 0) return 0; for(;;){ for(i=0; imouse = emouse(); else if(i == Skeyboard) e->kbdc = ekbd(); else if(i == Stimer) eslave[i].head = 0; else{ eb = _ebread(&eslave[i]); e->n = eb->n; memmove(e->data, eb->buf, e->n); free(eb); } return 1< EMAXMSG) n = EMAXMSG; i = eforkslave(key); if(i < MAXSLAVE) return 1<0) if(write(epipe[1], buf, r+1)!=r+1) break; buf[0] = MAXSLAVE; write(epipe[1], buf, 1); _exit(0); return 0; } ulong etimer(ulong key, int n) { extern int _SLEEP(long); char t[2]; if(Stimer != -1) berror("events: timer started twice"); Stimer = eforkslave(key); if(Stimer < MAXSLAVE) return 1<>8; write(epipe[1], t, 3); } } void einit(ulong keys) { int ctl, fd; struct sigaction sa; isparent = 1; if(pipe(epipe) < 0) berror("events: einit pipe"); atexit(ekill); sa.sa_handler = enote; sa.sa_mask = 0; sa.sa_flags = 0; sigaction(SIGKILL, &sa, 0); if(keys&Ekeyboard){ fd = open("/dev/cons", O_RDONLY); ctl = open("/dev/consctl", O_WRONLY); if(fd < 0) berror("events: can't open /dev/cons"); if(ctl < 0) berror("events: can't open /dev/consctl"); write(ctl, "rawon", 5); for(Skeyboard=0; Ekeyboard & ~(1<head && empty_pipe(epipe[0])) break; extract(); } eb = s->head; s->head = s->head->next; if(s->head == 0) s->tail = 0; return eb; } static void extract(void) { Slave *s; Ebuf *eb; int i, n; uchar ebuf[EMAXMSG+1]; char msg[100]; bflush(); loop: if((n=read(epipe[0], (char *)ebuf, EMAXMSG+1)) <= 0) berror("eof on event pipe"); if(ebuf[0] >= MAXSLAVE){ sprintf(msg, "bad slave %d on event pipe", ebuf[0]); berror(msg); } if(n == 0) goto loop; i = ebuf[0]; if(i >= nslave || n <= 1) berror("events: protocol error"); s = &eslave[i]; if(i == Stimer){ s->head = (Ebuf *)1; return; } if(i == Skeyboard && n != 3) berror("events: protocol error"); if(i == Smouse){ if(n!=1+14 || ebuf[1]!='m') berror("events: protocol error"); if(ebuf[2] & 0x80) ereshaped(bscreenrect(&screen.clipr)); /* squash extraneous mouse events */ if((eb=s->tail) && eb->buf[1] == ebuf[2]){ memmove(eb->buf, &ebuf[1], n - 1); return; } } /* try to save space by only alloacting as much buffer as we need */ eb = malloc(sizeof(*eb) - sizeof(eb->buf) + n - 1); if(eb == 0) berror("events: protocol error"); eb->n = n - 1; memmove(eb->buf, &ebuf[1], n - 1); eb->next = 0; if(s->head) s->tail = s->tail->next = eb; else s->head = s->tail = eb; } static int eforkslave(ulong key) { int i; for(i=0; i