void readmouse(Vnc *v) { int cursorfd, len, n; char buf[10*EventSize], *start, *end; uchar curs[2*4+2*2*16]; Cursor *cs; Mouse m; cs = &dotcursor; snprint(buf, sizeof buf, "%s/cursor", display->devdir); if((cursorfd = open(buf, OWRITE)) < 0) sysfatal("open %s: %r", buf); BPLONG(curs+0*4, cs->offset.x); BPLONG(curs+1*4, cs->offset.y); memmove(curs+2*4, cs->clr, 2*2*16); write(cursorfd, curs, sizeof curs); resize(v, 1); requestupdate(vnc, 0); start = end = buf; len = 0; for(;;) { if((n = read(mousefd, end, sizeof(buf) - (end - buf))) < 0) sysfatal("read mouse failed"); len += n; end += n; while(len >= EventSize) { if(*start == 'm') { m.xy.x = atoi(start+1); m.xy.y = atoi(start+1+12); m.buttons = atoi(start+1+2*12) & 0x1F; m.xy = subpt(m.xy, screen->r.min); if(ptinrect(m.xy, Rpt(ZP, v->dim))) { mouseevent(v, m); /* send wheel button *release* */ if ((m.buttons & 0x7) != m.buttons) { m.buttons &= 0x7; mouseevent(v, m); } } } else eresized(); start += EventSize; len -= EventSize; } if(start - buf > sizeof(buf) - EventSize) { memmove(buf, start, len); start = buf; end = start+len; } } }
void readmach(Machine *m, int init) { int n, i; uint64_t a[nelem(m->devsysstat)]; char buf[32]; if(m->remote && (m->disable || setjmp(catchalarm))){ if (m->disable++ >= 5) m->disable = 0; /* give it another chance */ memmove(m->devsysstat, m->prevsysstat, sizeof m->devsysstat); memmove(m->netetherstats, m->prevetherstats, sizeof m->netetherstats); return; } snprint(buf, sizeof buf, "%s", m->name); if (strcmp(m->name, buf) != 0){ free(m->name); m->name = estrdup(buf); free(m->shortname); m->shortname = shortname(buf); if(display != nil) /* else we're still initializing */ eresized(0); } if(m->remote){ notify(alarmed); alarm(5000); } if(needswap(init) && loadbuf(m, &m->swapfd) && readswap(m, a)) memmove(m->devswap, a, sizeof m->devswap); if(needstat(init) && loadbuf(m, &m->statsfd)){ memmove(m->prevsysstat, m->devsysstat, sizeof m->devsysstat); memset(m->devsysstat, 0, sizeof m->devsysstat); for(n=0; n<m->nproc && readnums(m, nelem(m->devsysstat), a, 0); n++) for(i=0; i<nelem(m->devsysstat); i++) m->devsysstat[i] += a[i]; } if(needether(init) && loadbuf(m, &m->etherfd) && readnums(m, nelem(m->netetherstats), a, 1)){ memmove(m->prevetherstats, m->netetherstats, sizeof m->netetherstats); memmove(m->netetherstats, a, sizeof m->netetherstats); } if(needsignal(init) && loadbuf(m, &m->ifstatsfd) && strncmp(m->buf, "Signal: ", 8)==0 && readnums(m, nelem(m->netetherifstats), a, 1)){ memmove(m->netetherifstats, a, sizeof m->netetherifstats); } if(needbattery(init) && loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0)) memmove(m->batterystats, a, sizeof(m->batterystats)); if(needbattery(init) && loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0)) memmove(m->batterystats, a, sizeof(m->batterystats)); if(needtemp(init) && loadbuf(m, &m->tempfd)) for(n=0; n < nelem(m->temp) && readnums(m, 2, a, 0); n++) m->temp[n] = a[0]; if(m->remote){ alarm(0); notify(nil); } }
int ereadmouse(Mouse *m) { int resized; resized = 0; if(_displayrdmouse(display, m, &resized) < 0) return -1; if(resized) eresized(1); return 1; }
int eatomouse(Mouse *m, char *buf, int n) { if(n != 1+4*12){ werrstr("eatomouse: bad count"); return -1; } if(buf[0] == 'r') eresized(1); m->xy.x = atoi(buf+1+0*12); m->xy.y = atoi(buf+1+1*12); m->buttons = atoi(buf+1+2*12); m->msec = atoi(buf+1+3*12); return n; }
void addface(Face *f) /* always adds at 0 */ { Face **ofaces; Rectangle r0, r1, r; int y, nx, ny; if(f == nil) return; if(first != 0){ first = 0; eresized(0); } findbit(f); nx = nacross; ny = (nfaces+(nx-1)) / nx; lockdisplay(display); for(y=ny; y>=0; y--){ /* move them along */ r0 = facerect(y*nx+0); r1 = facerect(y*nx+1); r = r1; r.max.x = r.min.x + (nx - 1)*(Facesize+Facesep); draw(screen, r, screen, nil, r0.min); /* copy one down from row above */ if(y != 0){ r = facerect((y-1)*nx+nx-1); draw(screen, r0, screen, nil, r.min); } } ofaces = faces; faces = emalloc((nfaces+1)*sizeof(Face*)); memmove(faces+1, ofaces, nfaces*(sizeof(Face*))); free(ofaces); nfaces++; setlast(); drawarrows(); faces[0] = f; drawface(f, 0); flushimage(display, 1); unlockdisplay(display); }
static void extract(void) { Slave *s; Ebuf *eb; int i, n; uchar ebuf[EMAXMSG+1]; /* avoid generating a message if there's nothing to show. */ /* this test isn't perfect, though; could do flushimage(display, 0) then call extract */ /* also: make sure we don't interfere if we're multiprocessing the display */ if(display->locking){ /* if locking is being done by program, this means it can't depend on automatic flush in emouse() etc. */ if(canqlock(&display->qlock)){ if(display->bufp > display->buf) flushimage(display, 1); unlockdisplay(display); } }else if(display->bufp > display->buf) flushimage(display, 1); loop: if((n=read(epipe[0], ebuf, EMAXMSG+1)) < 0 || ebuf[0] >= MAXSLAVE) drawerror(display, "eof on event pipe"); if(n == 0) goto loop; i = ebuf[0]; if(i >= nslave || n <= 1) drawerror(display, "events: protocol error: short read"); s = &eslave[i]; if(i == Stimer){ s->head = (Ebuf *)1; return; } if(i == Skeyboard && n != (1+UTFmax)) drawerror(display, "events: protocol error: keyboard"); if(i == Smouse){ if(n < 1+1+2*12) drawerror(display, "events: protocol error: mouse"); if(ebuf[1] == 'r') eresized(1); /* squash extraneous mouse events */ if((eb=s->tail) && memcmp(eb->buf+1+2*12, ebuf+1+1+2*12, 12)==0){ memmove(eb->buf, &ebuf[1], n - 1); return; } } /* try to save space by only allocating as much buffer as we need */ eb = malloc(sizeof(*eb) - sizeof(eb->buf) + n - 1); if(eb == 0) drawerror(display, "events: protocol error 4"); eb->n = n - 1; memmove(eb->buf, &ebuf[1], n - 1); eb->next = 0; if(s->head) s->tail->next = eb; else s->head = eb; s->tail = eb; }
static int extract(int canblock) { Ebuf *eb; int i, n, max; fd_set rset, wset, xset; struct timeval tv, *timeout; Wsysmsg w; vlong t0; /* * Flush draw buffer before waiting for responses. * Avoid doing so if buffer is empty. * Also make sure that we don't interfere with app-specific locking. */ if(display->locking){ /* * if locking is being done by program, * this means it can't depend on automatic * flush in emouse() etc. */ if(canqlock(&display->qlock)){ if(display->bufp > display->buf) flushimage(display, 1); unlockdisplay(display); } }else if(display->bufp > display->buf) flushimage(display, 1); /* * Set up for select. */ FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&xset); max = -1; timeout = nil; for(i=0; i<nslave; i++){ if(!eslave[i].inuse) continue; if(i == Smouse){ if(eslave[i].rpc == nil) eslave[i].rpc = startrpc(Trdmouse); if(eslave[i].rpc){ /* if ready, don't block in select */ if(eslave[i].rpc->p) canblock = 0; FD_SET(display->srvfd, &rset); FD_SET(display->srvfd, &xset); if(display->srvfd > max) max = display->srvfd; } }else if(i == Skeyboard){ if(eslave[i].rpc == nil) eslave[i].rpc = startrpc(Trdkbd); if(eslave[i].rpc){ /* if ready, don't block in select */ if(eslave[i].rpc->p) canblock = 0; FD_SET(display->srvfd, &rset); FD_SET(display->srvfd, &xset); if(display->srvfd > max) max = display->srvfd; } }else if(i == Stimer){ t0 = nsec(); if(t0 >= eslave[i].nexttick){ tv.tv_sec = 0; tv.tv_usec = 0; }else{ tv.tv_sec = (eslave[i].nexttick-t0)/1000000000; tv.tv_usec = (eslave[i].nexttick-t0)%1000000000 / 1000; } timeout = &tv; }else{ FD_SET(eslave[i].fd, &rset); FD_SET(eslave[i].fd, &xset); if(eslave[i].fd > max) max = eslave[i].fd; } } if(!canblock){ tv.tv_sec = 0; tv.tv_usec = 0; timeout = &tv; } if(select(max+1, &rset, &wset, &xset, timeout) < 0) drawerror(display, "select failure"); /* * Look to see what can proceed. */ n = 0; for(i=0; i<nslave; i++){ if(!eslave[i].inuse) continue; if(i == Smouse){ if(finishrpc(eslave[i].rpc, &w)){ eslave[i].rpc = nil; eb = newebuf(&eslave[i], sizeof(Mouse)); _drawmouse = w.mouse; eb->u.mouse = w.mouse; if(w.resized) eresized(1); n++; } }else if(i == Skeyboard){ if(finishrpc(eslave[i].rpc, &w)){ eslave[i].rpc = nil; eb = newebuf(&eslave[i], sizeof(Rune)+2); /* +8: alignment */ eb->u.rune = w.rune; n++; } }else if(i == Stimer){ t0 = nsec(); while(t0 > eslave[i].nexttick){ eslave[i].nexttick += eslave[i].n*1000000LL; eslave[i].head = (Ebuf*)1; n++; } }else{ if(FD_ISSET(eslave[i].fd, &rset)){ eb = newebuf(&eslave[i], eslave[i].n); eb->n = read(eslave[i].fd, eb->u.buf, eslave[i].n); n++; } } } return n; }
void main(int argc, char *argv[]) { Mouse m; int i, j; unsigned short ran, score, attempt, prev, br[2]; Image *c[2]; char *fmt; level = 16; fmt = "win in %d attempts!"; ARGBEGIN{ default: goto Usage; case 'h': level=36; break; }ARGEND if(argc){ Usage: fprint(2, "usage: %s [-h]\n", argv0); exits("usage"); } if(initdraw(0,0,"memo") < 0) sysfatal("initdraw failed: %r"); srand(time(0)); memoinit(); einit(Emouse); Start: afaces(); winflag=0; prev=level+1; score=attempt=0; for(i=0;i!=level;i++) block[i].flag = Eninit; for(i=0;i!=level/2;i++){ for(j=0;j!=2;){ ran = rand()%level; if(block[ran].flag == Eninit){ block[ran].face = face[i]; block[ran].flag = Eshow; j++; } } } eresized(0); for(;;m=emouse()) if(m.buttons) break; for(i=0;i!=level;i++) block[i].flag = Ehide; redraw(); j = 0; for(;; m=emouse()){ switch(m.buttons){ case 1: while(m.buttons){ for(i=0;i!=level;i++){ if(i!=prev && ptinrect(m.xy,block[i].r)){ if(block[i].flag==Ehide && j<2){ block[i].flag = Eshow; draw(screen, block[i].r, block[i].face, nil, ZP); c[j] = block[i].face; br[j] = prev = i; j++; } break; } } m=emouse(); } break; case 4: switch(emenuhit(3, &m, &menu)) { case 0: /* restart */ goto Start; break; case 1: level=16; goto Start; break; case 2: level=36; goto Start; break; case 3: exits(0); break; } } if(j==2){ attempt++; prev = level+1; j = 0; if(c[0] == c[1]){ score++; block[br[0]].flag = Edisc; block[br[1]].flag = Edisc; } else{ block[br[0]].flag = Ehide; block[br[1]].flag = Ehide; } redraw(); continue; } if(score == level/2){ winflag = 1; sprint(buf, fmt, attempt); redraw(); for(;;m=emouse()) if(m.buttons&1 || m.buttons&4) break; goto Start; } } }