1*7dd7cddfSDavid du Colombier #include <u.h> 2*7dd7cddfSDavid du Colombier #include <libc.h> 3*7dd7cddfSDavid du Colombier #include <draw.h> 4*7dd7cddfSDavid du Colombier #include <cursor.h> 5*7dd7cddfSDavid du Colombier #include <event.h> 6*7dd7cddfSDavid du Colombier 7*7dd7cddfSDavid du Colombier typedef struct Slave Slave; 8*7dd7cddfSDavid du Colombier typedef struct Ebuf Ebuf; 9*7dd7cddfSDavid du Colombier 10*7dd7cddfSDavid du Colombier struct Slave 11*7dd7cddfSDavid du Colombier { 12*7dd7cddfSDavid du Colombier int pid; 13*7dd7cddfSDavid du Colombier Ebuf *head; /* queue of messages for this descriptor */ 14*7dd7cddfSDavid du Colombier Ebuf *tail; 15*7dd7cddfSDavid du Colombier int (*fn)(int, Event*, uchar*, int); 16*7dd7cddfSDavid du Colombier }; 17*7dd7cddfSDavid du Colombier 18*7dd7cddfSDavid du Colombier struct Ebuf 19*7dd7cddfSDavid du Colombier { 20*7dd7cddfSDavid du Colombier Ebuf *next; 21*7dd7cddfSDavid du Colombier int n; /* number of bytes in buf */ 22*7dd7cddfSDavid du Colombier uchar buf[EMAXMSG]; 23*7dd7cddfSDavid du Colombier }; 24*7dd7cddfSDavid du Colombier 25*7dd7cddfSDavid du Colombier static Slave eslave[MAXSLAVE]; 26*7dd7cddfSDavid du Colombier static int Skeyboard = -1; 27*7dd7cddfSDavid du Colombier static int Smouse = -1; 28*7dd7cddfSDavid du Colombier static int Stimer = -1; 29*7dd7cddfSDavid du Colombier static int logfid; 30*7dd7cddfSDavid du Colombier 31*7dd7cddfSDavid du Colombier static int nslave; 32*7dd7cddfSDavid du Colombier static int parentpid; 33*7dd7cddfSDavid du Colombier static int epipe[2]; 34*7dd7cddfSDavid du Colombier static int eforkslave(ulong); 35*7dd7cddfSDavid du Colombier static void extract(void); 36*7dd7cddfSDavid du Colombier static void ekill(void); 37*7dd7cddfSDavid du Colombier static int enote(void *, char *); 38*7dd7cddfSDavid du Colombier static int mousefd; 39*7dd7cddfSDavid du Colombier static int cursorfd; 40*7dd7cddfSDavid du Colombier 41*7dd7cddfSDavid du Colombier static 42*7dd7cddfSDavid du Colombier Ebuf* 43*7dd7cddfSDavid du Colombier ebread(Slave *s) 44*7dd7cddfSDavid du Colombier { 45*7dd7cddfSDavid du Colombier Ebuf *eb; 46*7dd7cddfSDavid du Colombier Dir d; 47*7dd7cddfSDavid du Colombier 48*7dd7cddfSDavid du Colombier for(;;){ 49*7dd7cddfSDavid du Colombier if(dirfstat(epipe[0], &d) < 0) 50*7dd7cddfSDavid du Colombier drawerror(display, "events: eread stat error"); 51*7dd7cddfSDavid du Colombier if(s->head && d.length == 0) 52*7dd7cddfSDavid du Colombier break; 53*7dd7cddfSDavid du Colombier extract(); 54*7dd7cddfSDavid du Colombier } 55*7dd7cddfSDavid du Colombier eb = s->head; 56*7dd7cddfSDavid du Colombier s->head = s->head->next; 57*7dd7cddfSDavid du Colombier if(s->head == 0) 58*7dd7cddfSDavid du Colombier s->tail = 0; 59*7dd7cddfSDavid du Colombier return eb; 60*7dd7cddfSDavid du Colombier } 61*7dd7cddfSDavid du Colombier 62*7dd7cddfSDavid du Colombier ulong 63*7dd7cddfSDavid du Colombier event(Event *e) 64*7dd7cddfSDavid du Colombier { 65*7dd7cddfSDavid du Colombier return eread(~0UL, e); 66*7dd7cddfSDavid du Colombier } 67*7dd7cddfSDavid du Colombier 68*7dd7cddfSDavid du Colombier ulong 69*7dd7cddfSDavid du Colombier eread(ulong keys, Event *e) 70*7dd7cddfSDavid du Colombier { 71*7dd7cddfSDavid du Colombier Ebuf *eb; 72*7dd7cddfSDavid du Colombier int i, id; 73*7dd7cddfSDavid du Colombier 74*7dd7cddfSDavid du Colombier if(keys == 0) 75*7dd7cddfSDavid du Colombier return 0; 76*7dd7cddfSDavid du Colombier for(;;){ 77*7dd7cddfSDavid du Colombier for(i=0; i<nslave; i++) 78*7dd7cddfSDavid du Colombier if((keys & (1<<i)) && eslave[i].head){ 79*7dd7cddfSDavid du Colombier id = 1<<i; 80*7dd7cddfSDavid du Colombier if(i == Smouse) 81*7dd7cddfSDavid du Colombier e->mouse = emouse(); 82*7dd7cddfSDavid du Colombier else if(i == Skeyboard) 83*7dd7cddfSDavid du Colombier e->kbdc = ekbd(); 84*7dd7cddfSDavid du Colombier else if(i == Stimer) 85*7dd7cddfSDavid du Colombier eslave[i].head = 0; 86*7dd7cddfSDavid du Colombier else{ 87*7dd7cddfSDavid du Colombier eb = ebread(&eslave[i]); 88*7dd7cddfSDavid du Colombier e->n = eb->n; 89*7dd7cddfSDavid du Colombier if(eslave[i].fn) 90*7dd7cddfSDavid du Colombier id = (*eslave[i].fn)(id, e, eb->buf, eb->n); 91*7dd7cddfSDavid du Colombier else 92*7dd7cddfSDavid du Colombier memmove(e->data, eb->buf, eb->n); 93*7dd7cddfSDavid du Colombier free(eb); 94*7dd7cddfSDavid du Colombier } 95*7dd7cddfSDavid du Colombier return id; 96*7dd7cddfSDavid du Colombier } 97*7dd7cddfSDavid du Colombier extract(); 98*7dd7cddfSDavid du Colombier } 99*7dd7cddfSDavid du Colombier return 0; 100*7dd7cddfSDavid du Colombier } 101*7dd7cddfSDavid du Colombier 102*7dd7cddfSDavid du Colombier int 103*7dd7cddfSDavid du Colombier ecanmouse(void) 104*7dd7cddfSDavid du Colombier { 105*7dd7cddfSDavid du Colombier if(Smouse < 0) 106*7dd7cddfSDavid du Colombier drawerror(display, "events: mouse not initialized"); 107*7dd7cddfSDavid du Colombier return ecanread(Emouse); 108*7dd7cddfSDavid du Colombier } 109*7dd7cddfSDavid du Colombier 110*7dd7cddfSDavid du Colombier int 111*7dd7cddfSDavid du Colombier ecankbd(void) 112*7dd7cddfSDavid du Colombier { 113*7dd7cddfSDavid du Colombier if(Skeyboard < 0) 114*7dd7cddfSDavid du Colombier drawerror(display, "events: keyboard not initialzed"); 115*7dd7cddfSDavid du Colombier return ecanread(Ekeyboard); 116*7dd7cddfSDavid du Colombier } 117*7dd7cddfSDavid du Colombier 118*7dd7cddfSDavid du Colombier int 119*7dd7cddfSDavid du Colombier ecanread(ulong keys) 120*7dd7cddfSDavid du Colombier { 121*7dd7cddfSDavid du Colombier Dir d; 122*7dd7cddfSDavid du Colombier int i; 123*7dd7cddfSDavid du Colombier 124*7dd7cddfSDavid du Colombier for(;;){ 125*7dd7cddfSDavid du Colombier for(i=0; i<nslave; i++) 126*7dd7cddfSDavid du Colombier if((keys & (1<<i)) && eslave[i].head) 127*7dd7cddfSDavid du Colombier return 1; 128*7dd7cddfSDavid du Colombier if(dirfstat(epipe[0], &d) < 0) 129*7dd7cddfSDavid du Colombier drawerror(display, "events: ecanread stat error"); 130*7dd7cddfSDavid du Colombier if(d.length == 0) 131*7dd7cddfSDavid du Colombier return 0; 132*7dd7cddfSDavid du Colombier extract(); 133*7dd7cddfSDavid du Colombier } 134*7dd7cddfSDavid du Colombier return -1; 135*7dd7cddfSDavid du Colombier } 136*7dd7cddfSDavid du Colombier 137*7dd7cddfSDavid du Colombier ulong 138*7dd7cddfSDavid du Colombier estartfn(ulong key, int fd, int n, int (*fn)(int, Event*, uchar*, int)) 139*7dd7cddfSDavid du Colombier { 140*7dd7cddfSDavid du Colombier char buf[EMAXMSG+1]; 141*7dd7cddfSDavid du Colombier int i, r; 142*7dd7cddfSDavid du Colombier 143*7dd7cddfSDavid du Colombier if(fd < 0) 144*7dd7cddfSDavid du Colombier drawerror(display, "events: bad file descriptor"); 145*7dd7cddfSDavid du Colombier if(n <= 0 || n > EMAXMSG) 146*7dd7cddfSDavid du Colombier n = EMAXMSG; 147*7dd7cddfSDavid du Colombier i = eforkslave(key); 148*7dd7cddfSDavid du Colombier if(i < MAXSLAVE){ 149*7dd7cddfSDavid du Colombier eslave[i].fn = fn; 150*7dd7cddfSDavid du Colombier return 1<<i; 151*7dd7cddfSDavid du Colombier } 152*7dd7cddfSDavid du Colombier buf[0] = i - MAXSLAVE; 153*7dd7cddfSDavid du Colombier while((r = read(fd, buf+1, n))>0) 154*7dd7cddfSDavid du Colombier if(write(epipe[1], buf, r+1)!=r+1) 155*7dd7cddfSDavid du Colombier break; 156*7dd7cddfSDavid du Colombier buf[0] = MAXSLAVE; 157*7dd7cddfSDavid du Colombier write(epipe[1], buf, 1); 158*7dd7cddfSDavid du Colombier _exits(0); 159*7dd7cddfSDavid du Colombier return 0; 160*7dd7cddfSDavid du Colombier } 161*7dd7cddfSDavid du Colombier 162*7dd7cddfSDavid du Colombier ulong 163*7dd7cddfSDavid du Colombier estart(ulong key, int fd, int n) 164*7dd7cddfSDavid du Colombier { 165*7dd7cddfSDavid du Colombier return estartfn(key, fd, n, nil); 166*7dd7cddfSDavid du Colombier } 167*7dd7cddfSDavid du Colombier 168*7dd7cddfSDavid du Colombier ulong 169*7dd7cddfSDavid du Colombier etimer(ulong key, int n) 170*7dd7cddfSDavid du Colombier { 171*7dd7cddfSDavid du Colombier char t[2]; 172*7dd7cddfSDavid du Colombier 173*7dd7cddfSDavid du Colombier if(Stimer != -1) 174*7dd7cddfSDavid du Colombier drawerror(display, "events: timer started twice"); 175*7dd7cddfSDavid du Colombier Stimer = eforkslave(key); 176*7dd7cddfSDavid du Colombier if(Stimer < MAXSLAVE) 177*7dd7cddfSDavid du Colombier return 1<<Stimer; 178*7dd7cddfSDavid du Colombier if(n <= 0) 179*7dd7cddfSDavid du Colombier n = 1000; 180*7dd7cddfSDavid du Colombier t[0] = t[1] = Stimer - MAXSLAVE; 181*7dd7cddfSDavid du Colombier do 182*7dd7cddfSDavid du Colombier sleep(n); 183*7dd7cddfSDavid du Colombier while(write(epipe[1], t, 2) == 2); 184*7dd7cddfSDavid du Colombier t[0] = MAXSLAVE; 185*7dd7cddfSDavid du Colombier write(epipe[1], t, 1); 186*7dd7cddfSDavid du Colombier _exits(0); 187*7dd7cddfSDavid du Colombier return 0; 188*7dd7cddfSDavid du Colombier } 189*7dd7cddfSDavid du Colombier 190*7dd7cddfSDavid du Colombier static void 191*7dd7cddfSDavid du Colombier ekeyslave(int fd) 192*7dd7cddfSDavid du Colombier { 193*7dd7cddfSDavid du Colombier Rune r; 194*7dd7cddfSDavid du Colombier char t[3], k[10]; 195*7dd7cddfSDavid du Colombier int kr, kn, w; 196*7dd7cddfSDavid du Colombier 197*7dd7cddfSDavid du Colombier if(eforkslave(Ekeyboard) < MAXSLAVE) 198*7dd7cddfSDavid du Colombier return; 199*7dd7cddfSDavid du Colombier kn = 0; 200*7dd7cddfSDavid du Colombier t[0] = Skeyboard; 201*7dd7cddfSDavid du Colombier for(;;){ 202*7dd7cddfSDavid du Colombier while(!fullrune(k, kn)){ 203*7dd7cddfSDavid du Colombier kr = read(fd, k+kn, sizeof k - kn); 204*7dd7cddfSDavid du Colombier if(kr <= 0){ 205*7dd7cddfSDavid du Colombier t[0] = MAXSLAVE; 206*7dd7cddfSDavid du Colombier write(epipe[1], t, 1); 207*7dd7cddfSDavid du Colombier _exits(0); 208*7dd7cddfSDavid du Colombier } 209*7dd7cddfSDavid du Colombier kn += kr; 210*7dd7cddfSDavid du Colombier } 211*7dd7cddfSDavid du Colombier w = chartorune(&r, k); 212*7dd7cddfSDavid du Colombier kn -= w; 213*7dd7cddfSDavid du Colombier memmove(k, &k[w], kn); 214*7dd7cddfSDavid du Colombier t[1] = r; 215*7dd7cddfSDavid du Colombier t[2] = r>>8; 216*7dd7cddfSDavid du Colombier write(epipe[1], t, 3); 217*7dd7cddfSDavid du Colombier } 218*7dd7cddfSDavid du Colombier } 219*7dd7cddfSDavid du Colombier 220*7dd7cddfSDavid du Colombier void 221*7dd7cddfSDavid du Colombier einit(ulong keys) 222*7dd7cddfSDavid du Colombier { 223*7dd7cddfSDavid du Colombier int ctl, fd; 224*7dd7cddfSDavid du Colombier char buf[256]; 225*7dd7cddfSDavid du Colombier 226*7dd7cddfSDavid du Colombier parentpid = getpid(); 227*7dd7cddfSDavid du Colombier if(pipe(epipe) < 0) 228*7dd7cddfSDavid du Colombier drawerror(display, "events: einit pipe"); 229*7dd7cddfSDavid du Colombier atexit(ekill); 230*7dd7cddfSDavid du Colombier atnotify(enote, 1); 231*7dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/mouse", display->devdir); 232*7dd7cddfSDavid du Colombier mousefd = open(buf, ORDWR|OCEXEC); 233*7dd7cddfSDavid du Colombier if(mousefd < 0) 234*7dd7cddfSDavid du Colombier drawerror(display, "einit: can't open mouse\n"); 235*7dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/cursor", display->devdir); 236*7dd7cddfSDavid du Colombier cursorfd = open(buf, ORDWR|OCEXEC); 237*7dd7cddfSDavid du Colombier if(cursorfd < 0) 238*7dd7cddfSDavid du Colombier drawerror(display, "einit: can't open cursor\n"); 239*7dd7cddfSDavid du Colombier if(keys&Ekeyboard){ 240*7dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/cons", display->devdir); 241*7dd7cddfSDavid du Colombier fd = open(buf, OREAD); 242*7dd7cddfSDavid du Colombier if(fd < 0) 243*7dd7cddfSDavid du Colombier drawerror(display, "events: can't open console"); 244*7dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/consctl", display->devdir); 245*7dd7cddfSDavid du Colombier ctl = open("/dev/consctl", OWRITE|OCEXEC); 246*7dd7cddfSDavid du Colombier if(ctl < 0) 247*7dd7cddfSDavid du Colombier drawerror(display, "events: can't open consctl"); 248*7dd7cddfSDavid du Colombier write(ctl, "rawon", 5); 249*7dd7cddfSDavid du Colombier for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++) 250*7dd7cddfSDavid du Colombier ; 251*7dd7cddfSDavid du Colombier ekeyslave(fd); 252*7dd7cddfSDavid du Colombier } 253*7dd7cddfSDavid du Colombier if(keys&Emouse){ 254*7dd7cddfSDavid du Colombier estart(Emouse, mousefd, 1+4*12); 255*7dd7cddfSDavid du Colombier for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++) 256*7dd7cddfSDavid du Colombier ; 257*7dd7cddfSDavid du Colombier } 258*7dd7cddfSDavid du Colombier } 259*7dd7cddfSDavid du Colombier 260*7dd7cddfSDavid du Colombier static void 261*7dd7cddfSDavid du Colombier extract(void) 262*7dd7cddfSDavid du Colombier { 263*7dd7cddfSDavid du Colombier Slave *s; 264*7dd7cddfSDavid du Colombier Ebuf *eb; 265*7dd7cddfSDavid du Colombier int i, n; 266*7dd7cddfSDavid du Colombier uchar ebuf[EMAXMSG+1]; 267*7dd7cddfSDavid du Colombier 268*7dd7cddfSDavid du Colombier /* avoid generating a message if there's nothing to show. */ 269*7dd7cddfSDavid du Colombier /* this test isn't perfect, though; could do flushimage(display, 0) then call extract */ 270*7dd7cddfSDavid du Colombier /* also: make sure we don't interfere if we're multiprocessing the display */ 271*7dd7cddfSDavid du Colombier if(display->locking){ 272*7dd7cddfSDavid du Colombier /* if locking is being done by program, this means it can't depend on automatic flush in emouse() etc. */ 273*7dd7cddfSDavid du Colombier if(canqlock(&display->qlock)){ 274*7dd7cddfSDavid du Colombier if(display->bufp > display->buf) 275*7dd7cddfSDavid du Colombier flushimage(display, 1); 276*7dd7cddfSDavid du Colombier unlockdisplay(display); 277*7dd7cddfSDavid du Colombier } 278*7dd7cddfSDavid du Colombier }else 279*7dd7cddfSDavid du Colombier if(display->bufp > display->buf) 280*7dd7cddfSDavid du Colombier flushimage(display, 1); 281*7dd7cddfSDavid du Colombier loop: 282*7dd7cddfSDavid du Colombier if((n=read(epipe[0], ebuf, EMAXMSG+1)) < 0 283*7dd7cddfSDavid du Colombier || ebuf[0] >= MAXSLAVE) 284*7dd7cddfSDavid du Colombier drawerror(display, "eof on event pipe"); 285*7dd7cddfSDavid du Colombier if(n == 0) 286*7dd7cddfSDavid du Colombier goto loop; 287*7dd7cddfSDavid du Colombier i = ebuf[0]; 288*7dd7cddfSDavid du Colombier if(i >= nslave || n <= 1) 289*7dd7cddfSDavid du Colombier drawerror(display, "events: protocol error: short read"); 290*7dd7cddfSDavid du Colombier s = &eslave[i]; 291*7dd7cddfSDavid du Colombier if(i == Stimer){ 292*7dd7cddfSDavid du Colombier s->head = (Ebuf *)1; 293*7dd7cddfSDavid du Colombier return; 294*7dd7cddfSDavid du Colombier } 295*7dd7cddfSDavid du Colombier if(i == Skeyboard && n != 3) 296*7dd7cddfSDavid du Colombier drawerror(display, "events: protocol error: keyboard"); 297*7dd7cddfSDavid du Colombier if(i == Smouse){ 298*7dd7cddfSDavid du Colombier if(n < 1+1+2*12) 299*7dd7cddfSDavid du Colombier drawerror(display, "events: protocol error: mouse"); 300*7dd7cddfSDavid du Colombier if(ebuf[1] == 'r') 301*7dd7cddfSDavid du Colombier eresized(1); 302*7dd7cddfSDavid du Colombier /* squash extraneous mouse events */ 303*7dd7cddfSDavid du Colombier if((eb=s->tail) && memcmp(eb->buf+1+2*12, ebuf+1+1+2*12, 12)==0){ 304*7dd7cddfSDavid du Colombier memmove(eb->buf, &ebuf[1], n - 1); 305*7dd7cddfSDavid du Colombier return; 306*7dd7cddfSDavid du Colombier } 307*7dd7cddfSDavid du Colombier } 308*7dd7cddfSDavid du Colombier /* try to save space by only allocating as much buffer as we need */ 309*7dd7cddfSDavid du Colombier eb = malloc(sizeof(*eb) - sizeof(eb->buf) + n - 1); 310*7dd7cddfSDavid du Colombier if(eb == 0) 311*7dd7cddfSDavid du Colombier drawerror(display, "events: protocol error 4"); 312*7dd7cddfSDavid du Colombier eb->n = n - 1; 313*7dd7cddfSDavid du Colombier memmove(eb->buf, &ebuf[1], n - 1); 314*7dd7cddfSDavid du Colombier eb->next = 0; 315*7dd7cddfSDavid du Colombier if(s->head) 316*7dd7cddfSDavid du Colombier s->tail = s->tail->next = eb; 317*7dd7cddfSDavid du Colombier else 318*7dd7cddfSDavid du Colombier s->head = s->tail = eb; 319*7dd7cddfSDavid du Colombier } 320*7dd7cddfSDavid du Colombier 321*7dd7cddfSDavid du Colombier static int 322*7dd7cddfSDavid du Colombier eforkslave(ulong key) 323*7dd7cddfSDavid du Colombier { 324*7dd7cddfSDavid du Colombier int i, pid; 325*7dd7cddfSDavid du Colombier 326*7dd7cddfSDavid du Colombier for(i=0; i<MAXSLAVE; i++) 327*7dd7cddfSDavid du Colombier if((key & ~(1<<i)) == 0 && eslave[i].pid == 0){ 328*7dd7cddfSDavid du Colombier if(nslave <= i) 329*7dd7cddfSDavid du Colombier nslave = i + 1; 330*7dd7cddfSDavid du Colombier /* 331*7dd7cddfSDavid du Colombier * share the file descriptors so the last child 332*7dd7cddfSDavid du Colombier * out closes all connections to the window server. 333*7dd7cddfSDavid du Colombier */ 334*7dd7cddfSDavid du Colombier switch(pid = rfork(RFPROC)){ 335*7dd7cddfSDavid du Colombier case 0: 336*7dd7cddfSDavid du Colombier return MAXSLAVE+i; 337*7dd7cddfSDavid du Colombier case -1: 338*7dd7cddfSDavid du Colombier fprint(2, "events: fork error\n"); 339*7dd7cddfSDavid du Colombier exits("fork"); 340*7dd7cddfSDavid du Colombier } 341*7dd7cddfSDavid du Colombier eslave[i].pid = pid; 342*7dd7cddfSDavid du Colombier eslave[i].head = eslave[i].tail = 0; 343*7dd7cddfSDavid du Colombier return i; 344*7dd7cddfSDavid du Colombier } 345*7dd7cddfSDavid du Colombier drawerror(display, "events: bad slave assignment"); 346*7dd7cddfSDavid du Colombier return 0; 347*7dd7cddfSDavid du Colombier } 348*7dd7cddfSDavid du Colombier 349*7dd7cddfSDavid du Colombier static int 350*7dd7cddfSDavid du Colombier enote(void *v, char *s) 351*7dd7cddfSDavid du Colombier { 352*7dd7cddfSDavid du Colombier int i, pid; 353*7dd7cddfSDavid du Colombier 354*7dd7cddfSDavid du Colombier USED(v, s); 355*7dd7cddfSDavid du Colombier pid = getpid(); 356*7dd7cddfSDavid du Colombier if(pid != parentpid) 357*7dd7cddfSDavid du Colombier return 1; 358*7dd7cddfSDavid du Colombier for(i=0; i<nslave; i++){ 359*7dd7cddfSDavid du Colombier if(pid == eslave[i].pid) 360*7dd7cddfSDavid du Colombier continue; /* don't kill myself */ 361*7dd7cddfSDavid du Colombier postnote(PNPROC, eslave[i].pid, "die"); 362*7dd7cddfSDavid du Colombier } 363*7dd7cddfSDavid du Colombier close(epipe[0]); 364*7dd7cddfSDavid du Colombier close(epipe[1]); 365*7dd7cddfSDavid du Colombier return 0; 366*7dd7cddfSDavid du Colombier } 367*7dd7cddfSDavid du Colombier 368*7dd7cddfSDavid du Colombier static void 369*7dd7cddfSDavid du Colombier ekill(void) 370*7dd7cddfSDavid du Colombier { 371*7dd7cddfSDavid du Colombier enote(0, 0); 372*7dd7cddfSDavid du Colombier } 373*7dd7cddfSDavid du Colombier 374*7dd7cddfSDavid du Colombier Mouse 375*7dd7cddfSDavid du Colombier emouse(void) 376*7dd7cddfSDavid du Colombier { 377*7dd7cddfSDavid du Colombier Mouse m; 378*7dd7cddfSDavid du Colombier Ebuf *eb; 379*7dd7cddfSDavid du Colombier static but[2]; 380*7dd7cddfSDavid du Colombier int b; 381*7dd7cddfSDavid du Colombier 382*7dd7cddfSDavid du Colombier if(Smouse < 0) 383*7dd7cddfSDavid du Colombier drawerror(display, "events: mouse not initialized"); 384*7dd7cddfSDavid du Colombier eb = ebread(&eslave[Smouse]); 385*7dd7cddfSDavid du Colombier m.xy.x = atoi((char*)eb->buf+1+0*12); 386*7dd7cddfSDavid du Colombier m.xy.y = atoi((char*)eb->buf+1+1*12); 387*7dd7cddfSDavid du Colombier b = atoi((char*)eb->buf+1+2*12); 388*7dd7cddfSDavid du Colombier m.buttons = b&7; 389*7dd7cddfSDavid du Colombier m.msec = atoi((char*)eb->buf+1+3*12); 390*7dd7cddfSDavid du Colombier if (logfid) 391*7dd7cddfSDavid du Colombier fprint(logfid, "b: %d xy: %P\n", m.buttons, m.xy); 392*7dd7cddfSDavid du Colombier free(eb); 393*7dd7cddfSDavid du Colombier return m; 394*7dd7cddfSDavid du Colombier } 395*7dd7cddfSDavid du Colombier 396*7dd7cddfSDavid du Colombier int 397*7dd7cddfSDavid du Colombier ekbd(void) 398*7dd7cddfSDavid du Colombier { 399*7dd7cddfSDavid du Colombier Ebuf *eb; 400*7dd7cddfSDavid du Colombier int c; 401*7dd7cddfSDavid du Colombier 402*7dd7cddfSDavid du Colombier if(Skeyboard < 0) 403*7dd7cddfSDavid du Colombier drawerror(display, "events: keyboard not initialzed"); 404*7dd7cddfSDavid du Colombier eb = ebread(&eslave[Skeyboard]); 405*7dd7cddfSDavid du Colombier c = eb->buf[0] + (eb->buf[1]<<8); 406*7dd7cddfSDavid du Colombier free(eb); 407*7dd7cddfSDavid du Colombier return c; 408*7dd7cddfSDavid du Colombier } 409*7dd7cddfSDavid du Colombier 410*7dd7cddfSDavid du Colombier void 411*7dd7cddfSDavid du Colombier emoveto(Point pt) 412*7dd7cddfSDavid du Colombier { 413*7dd7cddfSDavid du Colombier char buf[2*12+2]; 414*7dd7cddfSDavid du Colombier int n; 415*7dd7cddfSDavid du Colombier 416*7dd7cddfSDavid du Colombier n = sprint(buf, "m%d %d", pt.x, pt.y); 417*7dd7cddfSDavid du Colombier write(mousefd, buf, n); 418*7dd7cddfSDavid du Colombier } 419*7dd7cddfSDavid du Colombier 420*7dd7cddfSDavid du Colombier void 421*7dd7cddfSDavid du Colombier esetcursor(Cursor *c) 422*7dd7cddfSDavid du Colombier { 423*7dd7cddfSDavid du Colombier uchar curs[2*4+2*2*16]; 424*7dd7cddfSDavid du Colombier 425*7dd7cddfSDavid du Colombier if(c == 0) 426*7dd7cddfSDavid du Colombier write(cursorfd, curs, 0); 427*7dd7cddfSDavid du Colombier else{ 428*7dd7cddfSDavid du Colombier BPLONG(curs+0*4, c->offset.x); 429*7dd7cddfSDavid du Colombier BPLONG(curs+1*4, c->offset.y); 430*7dd7cddfSDavid du Colombier memmove(curs+2*4, c->clr, 2*2*16); 431*7dd7cddfSDavid du Colombier write(cursorfd, curs, sizeof curs); 432*7dd7cddfSDavid du Colombier } 433*7dd7cddfSDavid du Colombier } 434*7dd7cddfSDavid du Colombier 435*7dd7cddfSDavid du Colombier int 436*7dd7cddfSDavid du Colombier ereadmouse(Mouse *m) 437*7dd7cddfSDavid du Colombier { 438*7dd7cddfSDavid du Colombier int n; 439*7dd7cddfSDavid du Colombier char buf[128]; 440*7dd7cddfSDavid du Colombier 441*7dd7cddfSDavid du Colombier do{ 442*7dd7cddfSDavid du Colombier n = read(mousefd, buf, sizeof(buf)); 443*7dd7cddfSDavid du Colombier if(n < 0) /* probably interrupted */ 444*7dd7cddfSDavid du Colombier return -1; 445*7dd7cddfSDavid du Colombier n = eatomouse(m, buf, n); 446*7dd7cddfSDavid du Colombier }while(n == 0); 447*7dd7cddfSDavid du Colombier return n; 448*7dd7cddfSDavid du Colombier } 449*7dd7cddfSDavid du Colombier 450*7dd7cddfSDavid du Colombier int 451*7dd7cddfSDavid du Colombier eatomouse(Mouse *m, char *buf, int n) 452*7dd7cddfSDavid du Colombier { 453*7dd7cddfSDavid du Colombier if(n != 1+4*12){ 454*7dd7cddfSDavid du Colombier werrstr("atomouse: bad count"); 455*7dd7cddfSDavid du Colombier return -1; 456*7dd7cddfSDavid du Colombier } 457*7dd7cddfSDavid du Colombier 458*7dd7cddfSDavid du Colombier if(buf[0] == 'r') 459*7dd7cddfSDavid du Colombier eresized(1); 460*7dd7cddfSDavid du Colombier m->xy.x = atoi(buf+1+0*12); 461*7dd7cddfSDavid du Colombier m->xy.y = atoi(buf+1+1*12); 462*7dd7cddfSDavid du Colombier m->buttons = atoi(buf+1+2*12); 463*7dd7cddfSDavid du Colombier m->msec = atoi(buf+1+3*12); 464*7dd7cddfSDavid du Colombier return n; 465*7dd7cddfSDavid du Colombier } 466