static void sendmouse(Mouse m) { m.buttons |= kbuttons; mouse.m[mouse.wi] = m; mouse.wi++; if(mouse.wi == nelem(mouse.m)) mouse.wi = 0; if(mouse.wi == mouse.ri){ mouse.stall = 1; mouse.ri = 0; mouse.wi = 1; mouse.m[0] = m; /* fprint(2, "mouse stall\n"); */ } matchmouse(); }
void mousetrack(int x, int y, int b, int ms) { Mouse *m; if(x < mouserect.min.x) x = mouserect.min.x; if(x > mouserect.max.x) x = mouserect.max.x; if(y < mouserect.min.y) y = mouserect.min.y; if(y > mouserect.max.y) y = mouserect.max.y; zlock(); // If reader has stopped reading, don't bother. // If reader is completely caught up, definitely queue. // Otherwise, queue only button change events. if(!mouse.stall) if(mouse.wi == mouse.ri || mouse.last.buttons != b){ m = &mouse.last; m->xy.x = x; m->xy.y = y; m->buttons = b; m->msec = ms; mouse.m[mouse.wi] = *m; if(++mouse.wi == nelem(mouse.m)) mouse.wi = 0; if(mouse.wi == mouse.ri){ mouse.stall = 1; mouse.ri = 0; mouse.wi = 1; mouse.m[0] = *m; } matchmouse(); } zunlock(); }
/* * Handle a single wsysmsg. * Might queue for later (kbd, mouse read) */ void runmsg(Wsysmsg *m) { uchar buf[65536]; int n; Memimage *i; switch(m->type){ case Tinit: memimageinit(); i = _xattach(m->label, m->winsize); _initdisplaymemimage(i); replymsg(m); break; case Trdmouse: mousetags.t[mousetags.wi++] = m->tag; if(mousetags.wi == nelem(mousetags.t)) mousetags.wi = 0; if(mousetags.wi == mousetags.ri) sysfatal("too many queued mouse reads"); /* fprint(2, "mouse unstall\n"); */ mouse.stall = 0; matchmouse(); break; case Trdkbd: kbdtags.t[kbdtags.wi++] = m->tag; if(kbdtags.wi == nelem(kbdtags.t)) kbdtags.wi = 0; if(kbdtags.wi == kbdtags.ri) sysfatal("too many queued keyboard reads"); kbd.stall = 0; matchkbd(); break; case Tmoveto: _xmoveto(m->mouse.xy); replymsg(m); break; case Tcursor: if(m->arrowcursor) _xsetcursor(nil); else _xsetcursor(&m->cursor); replymsg(m); break; case Tbouncemouse: _xbouncemouse(&m->mouse); replymsg(m); break; case Tlabel: _xsetlabel(m->label); replymsg(m); break; case Trdsnarf: m->snarf = _xgetsnarf(); replymsg(m); free(m->snarf); break; case Twrsnarf: _xputsnarf(m->snarf); replymsg(m); break; case Trddraw: n = m->count; if(n > sizeof buf) n = sizeof buf; n = _drawmsgread(buf, n); if(n < 0) replyerror(m); else{ m->count = n; m->data = buf; replymsg(m); } break; case Twrdraw: if(_drawmsgwrite(m->data, m->count) < 0) replyerror(m); else replymsg(m); break; case Ttop: _xtopwindow(); replymsg(m); break; case Tresize: _xresizewindow(m->rect); replymsg(m); break; } }