ref: b168e70e99b9376220b15677d95ba3339515c6f5
dir: /event.c/
#include <u.h> #include <libc.h> #include <thread.h> #include <bio.h> #include "acme.h" static int aeventgetnum(Biobuf *bio) { int c, n; n = 0; while('0' <= (c = Bgetc(bio)) && c <= '9') n = n*10+(c-'0'); if(c != ' ') { werrstr("event number syntax: %c", c); return -1; } return n; } static int aeventgetdata(Biobuf *bio, AEvent *ev) { int i, runes, len; Rune r; len = 0; runes = aeventgetnum(bio); for(i = 0; i < runes; i++) { if((r = Bgetrune(bio)) == -1) break; len += runetochar(ev->text + len, &r); } ev->text[len] = '\0'; return len; } static int aeventnext(Biobuf *bio, AEvent *ev) { int flags; flags = 0; Again: ev->origin = Bgetc(bio); ev->type = Bgetc(bio); ev->q0 = aeventgetnum(bio); ev->q1 = aeventgetnum(bio); ev->flags = aeventgetnum(bio); ev->ntext = aeventgetdata(bio, ev); if(Bgetc(bio) != '\n') { werrstr("unterminated mesage"); return -1; } if(ev->flags & 0x2) { ev->p = ev->q0; flags = ev->flags; goto Again; } ev->flags |= flags; return ev->origin; } static void aeventproc(void *aux) { AWin *w; Channel *c; Biobuf bio; AEvent ev; w = aux; c = w->eventc; Binit(&bio, w->eventfd, OREAD); while(aeventnext(&bio, &ev)) { if(send(c, &ev) < 0) { Bterm(&bio); exits(nil); } } } Channel * aeventlisten(AWin *w) { if(w->eventc) return w->eventc; w->eventc = chancreate(sizeof(AEvent), 0); proccreate(aeventproc, w, 4096); return w->eventc; } void aeventstop(AWin *w) { if(w->eventc) { chanclose(w->eventc); w->eventc = nil; } } void aeventsend(AWin *w, AEvent *ev) { if(ev->flags & 0x2) fprint(w->eventfd, "%c%c%d %d\n", ev->origin, ev->type, ev->p, ev->p); else fprint(w->eventfd, "%c%c%d %d\n", ev->origin, ev->type, ev->q0, ev->q1); }