diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/unix/drawterm/kern/devmouse.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/unix/drawterm/kern/devmouse.c')
-rwxr-xr-x | sys/src/cmd/unix/drawterm/kern/devmouse.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/sys/src/cmd/unix/drawterm/kern/devmouse.c b/sys/src/cmd/unix/drawterm/kern/devmouse.c new file mode 100755 index 000000000..3ee0c8b6b --- /dev/null +++ b/sys/src/cmd/unix/drawterm/kern/devmouse.c @@ -0,0 +1,237 @@ +#include "u.h" +#include "lib.h" +#include "dat.h" +#include "fns.h" +#include "error.h" + +#include "draw.h" +#include "memdraw.h" +#include "screen.h" + +int mousequeue = 1; + +Mouseinfo mouse; +Cursorinfo cursor; + +static int mousechanged(void*); + +enum{ + Qdir, + Qcursor, + Qmouse +}; + +Dirtab mousedir[]={ + ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, + "cursor", {Qcursor}, 0, 0666, + "mouse", {Qmouse}, 0, 0666, +}; + +#define NMOUSE (sizeof(mousedir)/sizeof(Dirtab)) + +static Chan* +mouseattach(char *spec) +{ + return devattach('m', spec); +} + +static Walkqid* +mousewalk(Chan *c, Chan *nc, char **name, int nname) +{ + return devwalk(c, nc, name, nname, mousedir, NMOUSE, devgen); +} + +static int +mousestat(Chan *c, uchar *db, int n) +{ + return devstat(c, db, n, mousedir, NMOUSE, devgen); +} + +static Chan* +mouseopen(Chan *c, int omode) +{ + switch((long)c->qid.path){ + case Qdir: + if(omode != OREAD) + error(Eperm); + break; + case Qmouse: + lock(&mouse.lk); + if(mouse.open){ + unlock(&mouse.lk); + error(Einuse); + } + mouse.open = 1; + unlock(&mouse.lk); + break; + } + c->mode = openmode(omode); + c->flag |= COPEN; + c->offset = 0; + return c; +} + +void +mouseclose(Chan *c) +{ + if(!(c->flag&COPEN)) + return; + + switch((long)c->qid.path) { + case Qmouse: + lock(&mouse.lk); + mouse.open = 0; + unlock(&mouse.lk); + cursorarrow(); + } +} + + +long +mouseread(Chan *c, void *va, long n, vlong offset) +{ + char buf[4*12+1]; + uchar *p; + int i, nn; + ulong msec; +/* static int map[8] = {0, 4, 2, 6, 1, 5, 3, 7 }; */ + + p = va; + switch((long)c->qid.path){ + case Qdir: + return devdirread(c, va, n, mousedir, NMOUSE, devgen); + + case Qcursor: + if(offset != 0) + return 0; + if(n < 2*4+2*2*16) + error(Eshort); + n = 2*4+2*2*16; + lock(&cursor.lk); + BPLONG(p+0, cursor.offset.x); + BPLONG(p+4, cursor.offset.y); + memmove(p+8, cursor.clr, 2*16); + memmove(p+40, cursor.set, 2*16); + unlock(&cursor.lk); + return n; + + case Qmouse: + while(mousechanged(0) == 0) + sleep(&mouse.r, mousechanged, 0); + + lock(&screen.lk); + if(screen.reshaped) { + screen.reshaped = 0; + sprint(buf, "t%11d %11d", 0, ticks()); + if(n > 1+2*12) + n = 1+2*12; + memmove(va, buf, n); + unlock(&screen.lk); + return n; + } + unlock(&screen.lk); + + lock(&mouse.lk); + i = mouse.ri; + nn = (mouse.wi + Mousequeue - i) % Mousequeue; + if(nn < 1) + panic("empty mouse queue"); + msec = ticks(); + while(nn > 1) { + if(mouse.queue[i].msec + Mousewindow > msec) + break; + i = (i+1)%Mousequeue; + nn--; + } + sprint(buf, "m%11d %11d %11d %11d", + mouse.queue[i].xy.x, + mouse.queue[i].xy.y, + mouse.queue[i].buttons, + mouse.queue[i].msec); + mouse.ri = (i+1)%Mousequeue; + unlock(&mouse.lk); + if(n > 1+4*12) + n = 1+4*12; + memmove(va, buf, n); + return n; + } + return 0; +} + +long +mousewrite(Chan *c, void *va, long n, vlong offset) +{ + char *p; + Point pt; + char buf[64]; + + USED(offset); + + p = va; + switch((long)c->qid.path){ + case Qdir: + error(Eisdir); + + case Qcursor: + if(n < 2*4+2*2*16){ + cursorarrow(); + }else{ + n = 2*4+2*2*16; + lock(&cursor.lk); + cursor.offset.x = BGLONG(p+0); + cursor.offset.y = BGLONG(p+4); + memmove(cursor.clr, p+8, 2*16); + memmove(cursor.set, p+40, 2*16); + unlock(&cursor.lk); + setcursor(); + } + return n; + + case Qmouse: + if(n > sizeof buf-1) + n = sizeof buf -1; + memmove(buf, va, n); + buf[n] = 0; + p = 0; + pt.x = strtoul(buf+1, &p, 0); + if(p == 0) + error(Eshort); + pt.y = strtoul(p, 0, 0); + if(ptinrect(pt, gscreen->r)) + mouseset(pt); + return n; + } + + error(Egreg); + return -1; +} + +int +mousechanged(void *a) +{ + USED(a); + + return mouse.ri != mouse.wi || screen.reshaped; +} + +Dev mousedevtab = { + 'm', + "mouse", + + devreset, + devinit, + devshutdown, + mouseattach, + mousewalk, + mousestat, + mouseopen, + devcreate, + mouseclose, + mouseread, + devbread, + mousewrite, + devbwrite, + devremove, + devwstat, +}; + |