17dd7cddfSDavid du Colombier #include "u.h"
27dd7cddfSDavid du Colombier #include "../port/lib.h"
37dd7cddfSDavid du Colombier #include "mem.h"
47dd7cddfSDavid du Colombier #include "dat.h"
57dd7cddfSDavid du Colombier #include "fns.h"
67dd7cddfSDavid du Colombier #include "../port/error.h"
77dd7cddfSDavid du Colombier
87dd7cddfSDavid du Colombier #define Image IMAGE
97dd7cddfSDavid du Colombier #include <draw.h>
107dd7cddfSDavid du Colombier #include <memdraw.h>
117dd7cddfSDavid du Colombier #include <cursor.h>
127dd7cddfSDavid du Colombier #include "screen.h"
137dd7cddfSDavid du Colombier
1415174232SDavid du Colombier enum {
1515174232SDavid du Colombier ScrollUp = 0x08,
1615174232SDavid du Colombier ScrollDown = 0x10,
1715174232SDavid du Colombier ScrollLeft = 0x20,
1815174232SDavid du Colombier ScrollRight = 0x40,
1915174232SDavid du Colombier };
2015174232SDavid du Colombier
217dd7cddfSDavid du Colombier typedef struct Mouseinfo Mouseinfo;
227dd7cddfSDavid du Colombier typedef struct Mousestate Mousestate;
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier struct Mousestate
257dd7cddfSDavid du Colombier {
267dd7cddfSDavid du Colombier Point xy; /* mouse.xy */
277dd7cddfSDavid du Colombier int buttons; /* mouse.buttons */
287dd7cddfSDavid du Colombier ulong counter; /* increments every update */
297dd7cddfSDavid du Colombier ulong msec; /* time of last event */
307dd7cddfSDavid du Colombier };
317dd7cddfSDavid du Colombier
327dd7cddfSDavid du Colombier struct Mouseinfo
337dd7cddfSDavid du Colombier {
34e288d156SDavid du Colombier Lock;
357dd7cddfSDavid du Colombier Mousestate;
367dd7cddfSDavid du Colombier int dx;
377dd7cddfSDavid du Colombier int dy;
387dd7cddfSDavid du Colombier int track; /* dx & dy updated */
397dd7cddfSDavid du Colombier int redraw; /* update cursor on screen */
407dd7cddfSDavid du Colombier ulong lastcounter; /* value when /dev/mouse read */
41e29df7b0SDavid du Colombier ulong lastresize;
42e29df7b0SDavid du Colombier ulong resize;
437dd7cddfSDavid du Colombier Rendez r;
447dd7cddfSDavid du Colombier Ref;
457dd7cddfSDavid du Colombier QLock;
467dd7cddfSDavid du Colombier int open;
477dd7cddfSDavid du Colombier int acceleration;
487dd7cddfSDavid du Colombier int maxacc;
497dd7cddfSDavid du Colombier Mousestate queue[16]; /* circular buffer of click events */
507dd7cddfSDavid du Colombier int ri; /* read index into queue */
517dd7cddfSDavid du Colombier int wi; /* write index into queue */
527dd7cddfSDavid du Colombier uchar qfull; /* queue is full */
537dd7cddfSDavid du Colombier };
547dd7cddfSDavid du Colombier
559a747e4fSDavid du Colombier enum
569a747e4fSDavid du Colombier {
579a747e4fSDavid du Colombier CMbuttonmap,
5849eeb88aSDavid du Colombier CMscrollswap,
599a747e4fSDavid du Colombier CMswap,
609a747e4fSDavid du Colombier CMwildcard,
619a747e4fSDavid du Colombier };
629a747e4fSDavid du Colombier
639a747e4fSDavid du Colombier static Cmdtab mousectlmsg[] =
649a747e4fSDavid du Colombier {
659a747e4fSDavid du Colombier CMbuttonmap, "buttonmap", 0,
6649eeb88aSDavid du Colombier CMscrollswap, "scrollswap", 0,
679a747e4fSDavid du Colombier CMswap, "swap", 1,
689a747e4fSDavid du Colombier CMwildcard, "*", 0,
699a747e4fSDavid du Colombier };
709a747e4fSDavid du Colombier
717dd7cddfSDavid du Colombier Mouseinfo mouse;
727dd7cddfSDavid du Colombier Cursorinfo cursor;
737dd7cddfSDavid du Colombier int mouseshifted;
74e29df7b0SDavid du Colombier int kbdbuttons;
753039af76SDavid du Colombier void (*kbdmouse)(int);
767dd7cddfSDavid du Colombier Cursor curs;
777dd7cddfSDavid du Colombier
787dd7cddfSDavid du Colombier void Cursortocursor(Cursor*);
797dd7cddfSDavid du Colombier int mousechanged(void*);
8026b166b7SDavid du Colombier
817dd7cddfSDavid du Colombier static void mouseclock(void);
823039af76SDavid du Colombier static void xkbdmouse(int);
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du Colombier enum{
857dd7cddfSDavid du Colombier Qdir,
867dd7cddfSDavid du Colombier Qcursor,
877dd7cddfSDavid du Colombier Qmouse,
887dd7cddfSDavid du Colombier Qmousein,
897dd7cddfSDavid du Colombier Qmousectl,
907dd7cddfSDavid du Colombier };
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier static Dirtab mousedir[]={
939a747e4fSDavid du Colombier ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
947dd7cddfSDavid du Colombier "cursor", {Qcursor}, 0, 0666,
957dd7cddfSDavid du Colombier "mouse", {Qmouse}, 0, 0666,
967dd7cddfSDavid du Colombier "mousein", {Qmousein}, 0, 0220,
977dd7cddfSDavid du Colombier "mousectl", {Qmousectl}, 0, 0220,
987dd7cddfSDavid du Colombier };
997dd7cddfSDavid du Colombier
1007dd7cddfSDavid du Colombier static uchar buttonmap[8] = {
1017dd7cddfSDavid du Colombier 0, 1, 2, 3, 4, 5, 6, 7,
1027dd7cddfSDavid du Colombier };
1037dd7cddfSDavid du Colombier static int mouseswap;
10449eeb88aSDavid du Colombier static int scrollswap;
10526b166b7SDavid du Colombier static ulong mousetime;
10626b166b7SDavid du Colombier
1077dd7cddfSDavid du Colombier extern Memimage* gscreen;
10826b166b7SDavid du Colombier extern ulong kerndate;
1097dd7cddfSDavid du Colombier
1107dd7cddfSDavid du Colombier static void
mousereset(void)1117dd7cddfSDavid du Colombier mousereset(void)
1127dd7cddfSDavid du Colombier {
1137dd7cddfSDavid du Colombier if(!conf.monitor)
1147dd7cddfSDavid du Colombier return;
1157dd7cddfSDavid du Colombier
1167dd7cddfSDavid du Colombier curs = arrow;
1177dd7cddfSDavid du Colombier Cursortocursor(&arrow);
118d9306527SDavid du Colombier /* redraw cursor about 30 times per second */
119d9306527SDavid du Colombier addclock0link(mouseclock, 33);
1207dd7cddfSDavid du Colombier }
1217dd7cddfSDavid du Colombier
1227dd7cddfSDavid du Colombier static void
mousefromkbd(int buttons)1233039af76SDavid du Colombier mousefromkbd(int buttons)
1243039af76SDavid du Colombier {
1253039af76SDavid du Colombier kbdbuttons = buttons;
1263039af76SDavid du Colombier mousetrack(0, 0, 0, TK2MS(MACHP(0)->ticks));
1273039af76SDavid du Colombier }
1283039af76SDavid du Colombier
12926b166b7SDavid du Colombier static int
mousedevgen(Chan * c,char * name,Dirtab * tab,int ntab,int i,Dir * dp)13026b166b7SDavid du Colombier mousedevgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
13126b166b7SDavid du Colombier {
13226b166b7SDavid du Colombier int rc;
13326b166b7SDavid du Colombier
13426b166b7SDavid du Colombier rc = devgen(c, name, tab, ntab, i, dp);
13526b166b7SDavid du Colombier if(rc != -1)
13626b166b7SDavid du Colombier dp->atime = mousetime;
13726b166b7SDavid du Colombier return rc;
13826b166b7SDavid du Colombier }
13926b166b7SDavid du Colombier
1403039af76SDavid du Colombier static void
mouseinit(void)1417dd7cddfSDavid du Colombier mouseinit(void)
1427dd7cddfSDavid du Colombier {
1437dd7cddfSDavid du Colombier if(!conf.monitor)
1447dd7cddfSDavid du Colombier return;
1457dd7cddfSDavid du Colombier
146fb7f0c93SDavid du Colombier curs = arrow;
147fb7f0c93SDavid du Colombier Cursortocursor(&arrow);
1487dd7cddfSDavid du Colombier cursoron(1);
1493039af76SDavid du Colombier kbdmouse = mousefromkbd;
15026b166b7SDavid du Colombier mousetime = seconds();
1517dd7cddfSDavid du Colombier }
1527dd7cddfSDavid du Colombier
1537dd7cddfSDavid du Colombier static Chan*
mouseattach(char * spec)1547dd7cddfSDavid du Colombier mouseattach(char *spec)
1557dd7cddfSDavid du Colombier {
1567dd7cddfSDavid du Colombier if(!conf.monitor)
1577dd7cddfSDavid du Colombier error(Egreg);
1587dd7cddfSDavid du Colombier return devattach('m', spec);
1597dd7cddfSDavid du Colombier }
1607dd7cddfSDavid du Colombier
1619a747e4fSDavid du Colombier static Walkqid*
mousewalk(Chan * c,Chan * nc,char ** name,int nname)1629a747e4fSDavid du Colombier mousewalk(Chan *c, Chan *nc, char **name, int nname)
1637dd7cddfSDavid du Colombier {
1649a747e4fSDavid du Colombier Walkqid *wq;
1659a747e4fSDavid du Colombier
16626b166b7SDavid du Colombier /*
16726b166b7SDavid du Colombier * We use devgen() and not mousedevgen() here
16826b166b7SDavid du Colombier * see "Ugly problem" in dev.c/devwalk()
16926b166b7SDavid du Colombier */
1709a747e4fSDavid du Colombier wq = devwalk(c, nc, name, nname, mousedir, nelem(mousedir), devgen);
171d9306527SDavid du Colombier if(wq != nil && wq->clone != c && wq->clone != nil && (wq->clone->qid.type&QTDIR)==0)
1727dd7cddfSDavid du Colombier incref(&mouse);
1739a747e4fSDavid du Colombier return wq;
1747dd7cddfSDavid du Colombier }
1757dd7cddfSDavid du Colombier
1767dd7cddfSDavid du Colombier static int
mousestat(Chan * c,uchar * db,int n)1779a747e4fSDavid du Colombier mousestat(Chan *c, uchar *db, int n)
1787dd7cddfSDavid du Colombier {
17926b166b7SDavid du Colombier return devstat(c, db, n, mousedir, nelem(mousedir), mousedevgen);
1807dd7cddfSDavid du Colombier }
1817dd7cddfSDavid du Colombier
1827dd7cddfSDavid du Colombier static Chan*
mouseopen(Chan * c,int omode)1837dd7cddfSDavid du Colombier mouseopen(Chan *c, int omode)
1847dd7cddfSDavid du Colombier {
1859a747e4fSDavid du Colombier switch((ulong)c->qid.path){
1869a747e4fSDavid du Colombier case Qdir:
1877dd7cddfSDavid du Colombier if(omode != OREAD)
1887dd7cddfSDavid du Colombier error(Eperm);
1897dd7cddfSDavid du Colombier break;
1907dd7cddfSDavid du Colombier case Qmouse:
1917dd7cddfSDavid du Colombier lock(&mouse);
1927dd7cddfSDavid du Colombier if(mouse.open){
1937dd7cddfSDavid du Colombier unlock(&mouse);
1947dd7cddfSDavid du Colombier error(Einuse);
1957dd7cddfSDavid du Colombier }
1967dd7cddfSDavid du Colombier mouse.open = 1;
1977dd7cddfSDavid du Colombier mouse.ref++;
198e29df7b0SDavid du Colombier mouse.lastresize = mouse.resize;
1997dd7cddfSDavid du Colombier unlock(&mouse);
2007dd7cddfSDavid du Colombier break;
2017dd7cddfSDavid du Colombier case Qmousein:
202b7b24591SDavid du Colombier if(!iseve())
203b7b24591SDavid du Colombier error(Eperm);
2047dd7cddfSDavid du Colombier break;
2057dd7cddfSDavid du Colombier default:
2067dd7cddfSDavid du Colombier incref(&mouse);
2077dd7cddfSDavid du Colombier }
2087dd7cddfSDavid du Colombier c->mode = openmode(omode);
2097dd7cddfSDavid du Colombier c->flag |= COPEN;
2107dd7cddfSDavid du Colombier c->offset = 0;
2117dd7cddfSDavid du Colombier return c;
2127dd7cddfSDavid du Colombier }
2137dd7cddfSDavid du Colombier
2147dd7cddfSDavid du Colombier static void
mousecreate(Chan *,char *,int,ulong)2157dd7cddfSDavid du Colombier mousecreate(Chan*, char*, int, ulong)
2167dd7cddfSDavid du Colombier {
2177dd7cddfSDavid du Colombier if(!conf.monitor)
2187dd7cddfSDavid du Colombier error(Egreg);
2197dd7cddfSDavid du Colombier error(Eperm);
2207dd7cddfSDavid du Colombier }
2217dd7cddfSDavid du Colombier
2227dd7cddfSDavid du Colombier static void
mouseclose(Chan * c)2237dd7cddfSDavid du Colombier mouseclose(Chan *c)
2247dd7cddfSDavid du Colombier {
2259a747e4fSDavid du Colombier if((c->qid.type&QTDIR)==0 && (c->flag&COPEN)){
2266f8e93f6SDavid du Colombier if(c->qid.path == Qmousein)
2276f8e93f6SDavid du Colombier return;
2287dd7cddfSDavid du Colombier lock(&mouse);
2297dd7cddfSDavid du Colombier if(c->qid.path == Qmouse)
2307dd7cddfSDavid du Colombier mouse.open = 0;
2317dd7cddfSDavid du Colombier if(--mouse.ref == 0){
2327dd7cddfSDavid du Colombier cursoroff(1);
2337dd7cddfSDavid du Colombier curs = arrow;
2347dd7cddfSDavid du Colombier Cursortocursor(&arrow);
2357dd7cddfSDavid du Colombier cursoron(1);
2367dd7cddfSDavid du Colombier }
2377dd7cddfSDavid du Colombier unlock(&mouse);
2387dd7cddfSDavid du Colombier }
2397dd7cddfSDavid du Colombier }
2407dd7cddfSDavid du Colombier
2417dd7cddfSDavid du Colombier
2427dd7cddfSDavid du Colombier static long
mouseread(Chan * c,void * va,long n,vlong off)2437dd7cddfSDavid du Colombier mouseread(Chan *c, void *va, long n, vlong off)
2447dd7cddfSDavid du Colombier {
24549eeb88aSDavid du Colombier char buf[1+4*12+1];
2467dd7cddfSDavid du Colombier uchar *p;
2477dd7cddfSDavid du Colombier static int map[8] = {0, 4, 2, 6, 1, 5, 3, 7 };
2487dd7cddfSDavid du Colombier ulong offset = off;
2497dd7cddfSDavid du Colombier Mousestate m;
25059cc4ca5SDavid du Colombier int b;
2517dd7cddfSDavid du Colombier
2527dd7cddfSDavid du Colombier p = va;
2539a747e4fSDavid du Colombier switch((ulong)c->qid.path){
2549a747e4fSDavid du Colombier case Qdir:
25526b166b7SDavid du Colombier return devdirread(c, va, n, mousedir, nelem(mousedir), mousedevgen);
2567dd7cddfSDavid du Colombier
2577dd7cddfSDavid du Colombier case Qcursor:
2587dd7cddfSDavid du Colombier if(offset != 0)
2597dd7cddfSDavid du Colombier return 0;
2607dd7cddfSDavid du Colombier if(n < 2*4+2*2*16)
2617dd7cddfSDavid du Colombier error(Eshort);
2627dd7cddfSDavid du Colombier n = 2*4+2*2*16;
2637dd7cddfSDavid du Colombier lock(&cursor);
2647dd7cddfSDavid du Colombier BPLONG(p+0, curs.offset.x);
2657dd7cddfSDavid du Colombier BPLONG(p+4, curs.offset.y);
2667dd7cddfSDavid du Colombier memmove(p+8, curs.clr, 2*16);
2677dd7cddfSDavid du Colombier memmove(p+40, curs.set, 2*16);
2687dd7cddfSDavid du Colombier unlock(&cursor);
2697dd7cddfSDavid du Colombier return n;
2707dd7cddfSDavid du Colombier
2717dd7cddfSDavid du Colombier case Qmouse:
2727dd7cddfSDavid du Colombier while(mousechanged(0) == 0)
2737dd7cddfSDavid du Colombier sleep(&mouse.r, mousechanged, 0);
2747dd7cddfSDavid du Colombier
2757dd7cddfSDavid du Colombier mouse.qfull = 0;
27626b166b7SDavid du Colombier mousetime = seconds();
2777dd7cddfSDavid du Colombier
2787dd7cddfSDavid du Colombier /*
27926b166b7SDavid du Colombier * No lock of the indices is necessary here, because ri is only
2807dd7cddfSDavid du Colombier * updated by us, and there is only one mouse reader
2817dd7cddfSDavid du Colombier * at a time. I suppose that more than one process
2827dd7cddfSDavid du Colombier * could try to read the fd at one time, but such behavior
2837dd7cddfSDavid du Colombier * is degenerate and already violates the calling
2847dd7cddfSDavid du Colombier * conventions for sleep above.
2857dd7cddfSDavid du Colombier */
2867dd7cddfSDavid du Colombier if(mouse.ri != mouse.wi) {
2877dd7cddfSDavid du Colombier m = mouse.queue[mouse.ri];
2887dd7cddfSDavid du Colombier if(++mouse.ri == nelem(mouse.queue))
2897dd7cddfSDavid du Colombier mouse.ri = 0;
2907dd7cddfSDavid du Colombier } else {
2917dd7cddfSDavid du Colombier while(!canlock(&cursor))
2927dd7cddfSDavid du Colombier tsleep(&up->sleep, return0, 0, TK2MS(1));
2937dd7cddfSDavid du Colombier
2947dd7cddfSDavid du Colombier m = mouse.Mousestate;
2957dd7cddfSDavid du Colombier unlock(&cursor);
2967dd7cddfSDavid du Colombier }
2977dd7cddfSDavid du Colombier
29859cc4ca5SDavid du Colombier b = buttonmap[m.buttons&7];
29959cc4ca5SDavid du Colombier /* put buttons 4 and 5 back in */
30059cc4ca5SDavid du Colombier b |= m.buttons & (3<<3);
30149eeb88aSDavid du Colombier if (scrollswap)
30249eeb88aSDavid du Colombier if (b == 8)
30349eeb88aSDavid du Colombier b = 16;
30449eeb88aSDavid du Colombier else if (b == 16)
30549eeb88aSDavid du Colombier b = 8;
306*4e3613abSDavid du Colombier snprint(buf, sizeof buf, "m%11d %11d %11d %11lud ",
3077dd7cddfSDavid du Colombier m.xy.x, m.xy.y,
30859cc4ca5SDavid du Colombier b,
3097dd7cddfSDavid du Colombier m.msec);
3107dd7cddfSDavid du Colombier mouse.lastcounter = m.counter;
3117dd7cddfSDavid du Colombier if(n > 1+4*12)
3127dd7cddfSDavid du Colombier n = 1+4*12;
313e29df7b0SDavid du Colombier if(mouse.lastresize != mouse.resize){
314e29df7b0SDavid du Colombier mouse.lastresize = mouse.resize;
315e29df7b0SDavid du Colombier buf[0] = 'r';
316e29df7b0SDavid du Colombier }
3177dd7cddfSDavid du Colombier memmove(va, buf, n);
3187dd7cddfSDavid du Colombier return n;
3197dd7cddfSDavid du Colombier }
3207dd7cddfSDavid du Colombier return 0;
3217dd7cddfSDavid du Colombier }
3227dd7cddfSDavid du Colombier
3237dd7cddfSDavid du Colombier static void
setbuttonmap(char * map)3247dd7cddfSDavid du Colombier setbuttonmap(char* map)
3257dd7cddfSDavid du Colombier {
3267dd7cddfSDavid du Colombier int i, x, one, two, three;
3277dd7cddfSDavid du Colombier
3287dd7cddfSDavid du Colombier one = two = three = 0;
3297dd7cddfSDavid du Colombier for(i = 0; i < 3; i++){
3307dd7cddfSDavid du Colombier if(map[i] == 0)
3317dd7cddfSDavid du Colombier error(Ebadarg);
3327dd7cddfSDavid du Colombier if(map[i] == '1'){
3337dd7cddfSDavid du Colombier if(one)
3347dd7cddfSDavid du Colombier error(Ebadarg);
3357dd7cddfSDavid du Colombier one = 1<<i;
3367dd7cddfSDavid du Colombier }
3377dd7cddfSDavid du Colombier else if(map[i] == '2'){
3387dd7cddfSDavid du Colombier if(two)
3397dd7cddfSDavid du Colombier error(Ebadarg);
3407dd7cddfSDavid du Colombier two = 1<<i;
3417dd7cddfSDavid du Colombier }
3427dd7cddfSDavid du Colombier else if(map[i] == '3'){
3437dd7cddfSDavid du Colombier if(three)
3447dd7cddfSDavid du Colombier error(Ebadarg);
3457dd7cddfSDavid du Colombier three = 1<<i;
3467dd7cddfSDavid du Colombier }
3477dd7cddfSDavid du Colombier else
3487dd7cddfSDavid du Colombier error(Ebadarg);
3497dd7cddfSDavid du Colombier }
3507dd7cddfSDavid du Colombier if(map[i])
3517dd7cddfSDavid du Colombier error(Ebadarg);
3527dd7cddfSDavid du Colombier
3537dd7cddfSDavid du Colombier memset(buttonmap, 0, 8);
3547dd7cddfSDavid du Colombier for(i = 0; i < 8; i++){
3557dd7cddfSDavid du Colombier x = 0;
3567dd7cddfSDavid du Colombier if(i & 1)
3577dd7cddfSDavid du Colombier x |= one;
3587dd7cddfSDavid du Colombier if(i & 2)
3597dd7cddfSDavid du Colombier x |= two;
3607dd7cddfSDavid du Colombier if(i & 4)
3617dd7cddfSDavid du Colombier x |= three;
3627dd7cddfSDavid du Colombier buttonmap[x] = i;
3637dd7cddfSDavid du Colombier }
3647dd7cddfSDavid du Colombier }
3657dd7cddfSDavid du Colombier
3667dd7cddfSDavid du Colombier static long
mousewrite(Chan * c,void * va,long n,vlong)3677dd7cddfSDavid du Colombier mousewrite(Chan *c, void *va, long n, vlong)
3687dd7cddfSDavid du Colombier {
3697dd7cddfSDavid du Colombier char *p;
3707dd7cddfSDavid du Colombier Point pt;
3719a747e4fSDavid du Colombier Cmdbuf *cb;
3729a747e4fSDavid du Colombier Cmdtab *ct;
3739a747e4fSDavid du Colombier char buf[64];
3749a747e4fSDavid du Colombier int b, msec;
3757dd7cddfSDavid du Colombier
3767dd7cddfSDavid du Colombier p = va;
3779a747e4fSDavid du Colombier switch((ulong)c->qid.path){
3789a747e4fSDavid du Colombier case Qdir:
3797dd7cddfSDavid du Colombier error(Eisdir);
3807dd7cddfSDavid du Colombier
3817dd7cddfSDavid du Colombier case Qcursor:
3827dd7cddfSDavid du Colombier cursoroff(1);
3837dd7cddfSDavid du Colombier if(n < 2*4+2*2*16){
3847dd7cddfSDavid du Colombier curs = arrow;
3857dd7cddfSDavid du Colombier Cursortocursor(&arrow);
3867dd7cddfSDavid du Colombier }else{
3877dd7cddfSDavid du Colombier n = 2*4+2*2*16;
3887dd7cddfSDavid du Colombier curs.offset.x = BGLONG(p+0);
3897dd7cddfSDavid du Colombier curs.offset.y = BGLONG(p+4);
3907dd7cddfSDavid du Colombier memmove(curs.clr, p+8, 2*16);
3917dd7cddfSDavid du Colombier memmove(curs.set, p+40, 2*16);
3927dd7cddfSDavid du Colombier Cursortocursor(&curs);
3937dd7cddfSDavid du Colombier }
3947dd7cddfSDavid du Colombier qlock(&mouse);
3957dd7cddfSDavid du Colombier mouse.redraw = 1;
3967dd7cddfSDavid du Colombier mouseclock();
3977dd7cddfSDavid du Colombier qunlock(&mouse);
3987dd7cddfSDavid du Colombier cursoron(1);
3997dd7cddfSDavid du Colombier return n;
4007dd7cddfSDavid du Colombier
4017dd7cddfSDavid du Colombier case Qmousectl:
4029a747e4fSDavid du Colombier cb = parsecmd(va, n);
4039a747e4fSDavid du Colombier if(waserror()){
4049a747e4fSDavid du Colombier free(cb);
4059a747e4fSDavid du Colombier nexterror();
4069a747e4fSDavid du Colombier }
4079a747e4fSDavid du Colombier
4089a747e4fSDavid du Colombier ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
4099a747e4fSDavid du Colombier
4109a747e4fSDavid du Colombier switch(ct->index){
4119a747e4fSDavid du Colombier case CMswap:
4127dd7cddfSDavid du Colombier if(mouseswap)
4137dd7cddfSDavid du Colombier setbuttonmap("123");
4147dd7cddfSDavid du Colombier else
4157dd7cddfSDavid du Colombier setbuttonmap("321");
4167dd7cddfSDavid du Colombier mouseswap ^= 1;
4179a747e4fSDavid du Colombier break;
4189a747e4fSDavid du Colombier
41949eeb88aSDavid du Colombier case CMscrollswap:
42049eeb88aSDavid du Colombier scrollswap ^= 1;
42149eeb88aSDavid du Colombier break;
42249eeb88aSDavid du Colombier
4239a747e4fSDavid du Colombier case CMbuttonmap:
4249a747e4fSDavid du Colombier if(cb->nf == 1)
4257dd7cddfSDavid du Colombier setbuttonmap("123");
4267dd7cddfSDavid du Colombier else
4279a747e4fSDavid du Colombier setbuttonmap(cb->f[1]);
4289a747e4fSDavid du Colombier break;
4299a747e4fSDavid du Colombier
4309a747e4fSDavid du Colombier case CMwildcard:
4319a747e4fSDavid du Colombier mousectl(cb);
4329a747e4fSDavid du Colombier break;
4337dd7cddfSDavid du Colombier }
4349a747e4fSDavid du Colombier
4359a747e4fSDavid du Colombier free(cb);
4369a747e4fSDavid du Colombier poperror();
4377dd7cddfSDavid du Colombier return n;
4387dd7cddfSDavid du Colombier
4397dd7cddfSDavid du Colombier case Qmousein:
4407dd7cddfSDavid du Colombier if(n > sizeof buf-1)
4417dd7cddfSDavid du Colombier n = sizeof buf -1;
4427dd7cddfSDavid du Colombier memmove(buf, va, n);
4437dd7cddfSDavid du Colombier buf[n] = 0;
4447dd7cddfSDavid du Colombier p = 0;
4457dd7cddfSDavid du Colombier pt.x = strtol(buf+1, &p, 0);
4467dd7cddfSDavid du Colombier if(p == 0)
4477dd7cddfSDavid du Colombier error(Eshort);
4487dd7cddfSDavid du Colombier pt.y = strtol(p, &p, 0);
4497dd7cddfSDavid du Colombier if(p == 0)
4507dd7cddfSDavid du Colombier error(Eshort);
4517dd7cddfSDavid du Colombier b = strtol(p, &p, 0);
4529a747e4fSDavid du Colombier msec = strtol(p, &p, 0);
4539a747e4fSDavid du Colombier if(msec == 0)
4549a747e4fSDavid du Colombier msec = TK2MS(MACHP(0)->ticks);
4559a747e4fSDavid du Colombier mousetrack(pt.x, pt.y, b, msec);
4567dd7cddfSDavid du Colombier return n;
4577dd7cddfSDavid du Colombier
4587dd7cddfSDavid du Colombier case Qmouse:
4597dd7cddfSDavid du Colombier if(n > sizeof buf-1)
4607dd7cddfSDavid du Colombier n = sizeof buf -1;
4617dd7cddfSDavid du Colombier memmove(buf, va, n);
4627dd7cddfSDavid du Colombier buf[n] = 0;
4637dd7cddfSDavid du Colombier p = 0;
4647dd7cddfSDavid du Colombier pt.x = strtoul(buf+1, &p, 0);
4657dd7cddfSDavid du Colombier if(p == 0)
4667dd7cddfSDavid du Colombier error(Eshort);
4677dd7cddfSDavid du Colombier pt.y = strtoul(p, 0, 0);
4687dd7cddfSDavid du Colombier qlock(&mouse);
4697dd7cddfSDavid du Colombier if(ptinrect(pt, gscreen->r)){
4707dd7cddfSDavid du Colombier mouse.xy = pt;
4717dd7cddfSDavid du Colombier mouse.redraw = 1;
4727dd7cddfSDavid du Colombier mouse.track = 1;
4737dd7cddfSDavid du Colombier mouseclock();
4747dd7cddfSDavid du Colombier }
4757dd7cddfSDavid du Colombier qunlock(&mouse);
4767dd7cddfSDavid du Colombier return n;
4777dd7cddfSDavid du Colombier }
4787dd7cddfSDavid du Colombier
4797dd7cddfSDavid du Colombier error(Egreg);
4807dd7cddfSDavid du Colombier return -1;
4817dd7cddfSDavid du Colombier }
4827dd7cddfSDavid du Colombier
4837dd7cddfSDavid du Colombier Dev mousedevtab = {
4847dd7cddfSDavid du Colombier 'm',
4857dd7cddfSDavid du Colombier "mouse",
4867dd7cddfSDavid du Colombier
4877dd7cddfSDavid du Colombier mousereset,
4887dd7cddfSDavid du Colombier mouseinit,
4899a747e4fSDavid du Colombier devshutdown,
4907dd7cddfSDavid du Colombier mouseattach,
4917dd7cddfSDavid du Colombier mousewalk,
4927dd7cddfSDavid du Colombier mousestat,
4937dd7cddfSDavid du Colombier mouseopen,
4947dd7cddfSDavid du Colombier mousecreate,
4957dd7cddfSDavid du Colombier mouseclose,
4967dd7cddfSDavid du Colombier mouseread,
4977dd7cddfSDavid du Colombier devbread,
4987dd7cddfSDavid du Colombier mousewrite,
4997dd7cddfSDavid du Colombier devbwrite,
5007dd7cddfSDavid du Colombier devremove,
5017dd7cddfSDavid du Colombier devwstat,
5027dd7cddfSDavid du Colombier };
5037dd7cddfSDavid du Colombier
5047dd7cddfSDavid du Colombier void
Cursortocursor(Cursor * c)5057dd7cddfSDavid du Colombier Cursortocursor(Cursor *c)
5067dd7cddfSDavid du Colombier {
5077dd7cddfSDavid du Colombier lock(&cursor);
5087dd7cddfSDavid du Colombier memmove(&cursor.Cursor, c, sizeof(Cursor));
5097dd7cddfSDavid du Colombier setcursor(c);
5107dd7cddfSDavid du Colombier unlock(&cursor);
5117dd7cddfSDavid du Colombier }
5127dd7cddfSDavid du Colombier
5137dd7cddfSDavid du Colombier
5147dd7cddfSDavid du Colombier /*
5157dd7cddfSDavid du Colombier * called by the clock routine to redraw the cursor
5167dd7cddfSDavid du Colombier */
5177dd7cddfSDavid du Colombier static void
mouseclock(void)5187dd7cddfSDavid du Colombier mouseclock(void)
5197dd7cddfSDavid du Colombier {
5207dd7cddfSDavid du Colombier if(mouse.track){
5219a747e4fSDavid du Colombier mousetrack(mouse.dx, mouse.dy, mouse.buttons, TK2MS(MACHP(0)->ticks));
5227dd7cddfSDavid du Colombier mouse.track = 0;
5237dd7cddfSDavid du Colombier mouse.dx = 0;
5247dd7cddfSDavid du Colombier mouse.dy = 0;
5257dd7cddfSDavid du Colombier }
5267dd7cddfSDavid du Colombier if(mouse.redraw && canlock(&cursor)){
5277dd7cddfSDavid du Colombier mouse.redraw = 0;
5287dd7cddfSDavid du Colombier cursoroff(0);
5297dd7cddfSDavid du Colombier mouse.redraw = cursoron(0);
5307dd7cddfSDavid du Colombier unlock(&cursor);
5317dd7cddfSDavid du Colombier }
5327dd7cddfSDavid du Colombier drawactive(0);
5337dd7cddfSDavid du Colombier }
5347dd7cddfSDavid du Colombier
5357dd7cddfSDavid du Colombier static int
scale(int x)5367dd7cddfSDavid du Colombier scale(int x)
5377dd7cddfSDavid du Colombier {
5387dd7cddfSDavid du Colombier int sign = 1;
5397dd7cddfSDavid du Colombier
5407dd7cddfSDavid du Colombier if(x < 0){
5417dd7cddfSDavid du Colombier sign = -1;
5427dd7cddfSDavid du Colombier x = -x;
5437dd7cddfSDavid du Colombier }
5447dd7cddfSDavid du Colombier switch(x){
5457dd7cddfSDavid du Colombier case 0:
5467dd7cddfSDavid du Colombier case 1:
5477dd7cddfSDavid du Colombier case 2:
5487dd7cddfSDavid du Colombier case 3:
5497dd7cddfSDavid du Colombier break;
5507dd7cddfSDavid du Colombier case 4:
5517dd7cddfSDavid du Colombier x = 6 + (mouse.acceleration>>2);
5527dd7cddfSDavid du Colombier break;
5537dd7cddfSDavid du Colombier case 5:
5547dd7cddfSDavid du Colombier x = 9 + (mouse.acceleration>>1);
5557dd7cddfSDavid du Colombier break;
5567dd7cddfSDavid du Colombier default:
5577dd7cddfSDavid du Colombier x *= mouse.maxacc;
5587dd7cddfSDavid du Colombier break;
5597dd7cddfSDavid du Colombier }
5607dd7cddfSDavid du Colombier return sign*x;
5617dd7cddfSDavid du Colombier }
5627dd7cddfSDavid du Colombier
5637dd7cddfSDavid du Colombier /*
5647dd7cddfSDavid du Colombier * called at interrupt level to update the structure and
5657dd7cddfSDavid du Colombier * awaken any waiting procs.
5667dd7cddfSDavid du Colombier */
5677dd7cddfSDavid du Colombier void
mousetrack(int dx,int dy,int b,int msec)5689a747e4fSDavid du Colombier mousetrack(int dx, int dy, int b, int msec)
5697dd7cddfSDavid du Colombier {
5707dd7cddfSDavid du Colombier int x, y, lastb;
5717dd7cddfSDavid du Colombier
5727dd7cddfSDavid du Colombier if(gscreen==nil)
5737dd7cddfSDavid du Colombier return;
5747dd7cddfSDavid du Colombier
5757dd7cddfSDavid du Colombier if(mouse.acceleration){
5767dd7cddfSDavid du Colombier dx = scale(dx);
5777dd7cddfSDavid du Colombier dy = scale(dy);
5787dd7cddfSDavid du Colombier }
5797dd7cddfSDavid du Colombier x = mouse.xy.x + dx;
5809a747e4fSDavid du Colombier if(x < gscreen->clipr.min.x)
5819a747e4fSDavid du Colombier x = gscreen->clipr.min.x;
5829a747e4fSDavid du Colombier if(x >= gscreen->clipr.max.x)
5839a747e4fSDavid du Colombier x = gscreen->clipr.max.x;
5847dd7cddfSDavid du Colombier y = mouse.xy.y + dy;
5859a747e4fSDavid du Colombier if(y < gscreen->clipr.min.y)
5869a747e4fSDavid du Colombier y = gscreen->clipr.min.y;
5879a747e4fSDavid du Colombier if(y >= gscreen->clipr.max.y)
5889a747e4fSDavid du Colombier y = gscreen->clipr.max.y;
5897dd7cddfSDavid du Colombier
5907dd7cddfSDavid du Colombier lastb = mouse.buttons;
5917dd7cddfSDavid du Colombier mouse.xy = Pt(x, y);
592e29df7b0SDavid du Colombier mouse.buttons = b|kbdbuttons;
5937dd7cddfSDavid du Colombier mouse.redraw = 1;
5947dd7cddfSDavid du Colombier mouse.counter++;
5959a747e4fSDavid du Colombier mouse.msec = msec;
5967dd7cddfSDavid du Colombier
5977dd7cddfSDavid du Colombier /*
5987dd7cddfSDavid du Colombier * if the queue fills, we discard the entire queue and don't
5997dd7cddfSDavid du Colombier * queue any more events until a reader polls the mouse.
6007dd7cddfSDavid du Colombier */
6017dd7cddfSDavid du Colombier if(!mouse.qfull && lastb != b) { /* add to ring */
6027dd7cddfSDavid du Colombier mouse.queue[mouse.wi] = mouse.Mousestate;
6037dd7cddfSDavid du Colombier if(++mouse.wi == nelem(mouse.queue))
6047dd7cddfSDavid du Colombier mouse.wi = 0;
6057dd7cddfSDavid du Colombier if(mouse.wi == mouse.ri)
6067dd7cddfSDavid du Colombier mouse.qfull = 1;
6077dd7cddfSDavid du Colombier }
6087dd7cddfSDavid du Colombier wakeup(&mouse.r);
6097dd7cddfSDavid du Colombier drawactive(1);
6107dd7cddfSDavid du Colombier }
6117dd7cddfSDavid du Colombier
6127dd7cddfSDavid du Colombier /*
6137dd7cddfSDavid du Colombier * microsoft 3 button, 7 bit bytes
6147dd7cddfSDavid du Colombier *
6157dd7cddfSDavid du Colombier * byte 0 - 1 L R Y7 Y6 X7 X6
6167dd7cddfSDavid du Colombier * byte 1 - 0 X5 X4 X3 X2 X1 X0
6177dd7cddfSDavid du Colombier * byte 2 - 0 Y5 Y4 Y3 Y2 Y1 Y0
6187dd7cddfSDavid du Colombier * byte 3 - 0 M x x x x x (optional)
6197dd7cddfSDavid du Colombier *
6207dd7cddfSDavid du Colombier * shift & right button is the same as middle button (for 2 button mice)
6217dd7cddfSDavid du Colombier */
6227dd7cddfSDavid du Colombier int
m3mouseputc(Queue *,int c)6237dd7cddfSDavid du Colombier m3mouseputc(Queue*, int c)
6247dd7cddfSDavid du Colombier {
6257dd7cddfSDavid du Colombier static uchar msg[3];
6267dd7cddfSDavid du Colombier static int nb;
6277dd7cddfSDavid du Colombier static int middle;
62859cc4ca5SDavid du Colombier static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 3 };
6297dd7cddfSDavid du Colombier short x;
6307dd7cddfSDavid du Colombier int dx, dy, newbuttons;
63124c25b93SDavid du Colombier static ulong lasttick;
63224c25b93SDavid du Colombier ulong m;
63324c25b93SDavid du Colombier
63424c25b93SDavid du Colombier /* Resynchronize in stream with timing. */
63524c25b93SDavid du Colombier m = MACHP(0)->ticks;
63624c25b93SDavid du Colombier if(TK2SEC(m - lasttick) > 2)
63724c25b93SDavid du Colombier nb = 0;
63824c25b93SDavid du Colombier lasttick = m;
6397dd7cddfSDavid du Colombier
6407dd7cddfSDavid du Colombier if(nb==0){
6417dd7cddfSDavid du Colombier /*
6427dd7cddfSDavid du Colombier * an extra byte comes for middle button motion.
6437dd7cddfSDavid du Colombier * only two possible values for the extra byte.
6447dd7cddfSDavid du Colombier */
6457dd7cddfSDavid du Colombier if(c == 0x00 || c == 0x20){
6467dd7cddfSDavid du Colombier /* an extra byte gets sent for the middle button */
6477dd7cddfSDavid du Colombier middle = (c&0x20) ? 2 : 0;
6487dd7cddfSDavid du Colombier newbuttons = (mouse.buttons & ~2) | middle;
6499a747e4fSDavid du Colombier mousetrack(0, 0, newbuttons, TK2MS(MACHP(0)->ticks));
6507dd7cddfSDavid du Colombier return 0;
6517dd7cddfSDavid du Colombier }
6527dd7cddfSDavid du Colombier }
6537dd7cddfSDavid du Colombier msg[nb] = c;
6547dd7cddfSDavid du Colombier if(++nb == 3){
6557dd7cddfSDavid du Colombier nb = 0;
6567dd7cddfSDavid du Colombier newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)];
6577dd7cddfSDavid du Colombier x = (msg[0]&0x3)<<14;
6587dd7cddfSDavid du Colombier dx = (x>>8) | msg[1];
6597dd7cddfSDavid du Colombier x = (msg[0]&0xc)<<12;
6607dd7cddfSDavid du Colombier dy = (x>>8) | msg[2];
6619a747e4fSDavid du Colombier mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks));
6627dd7cddfSDavid du Colombier }
6637dd7cddfSDavid du Colombier return 0;
6647dd7cddfSDavid du Colombier }
6657dd7cddfSDavid du Colombier
6667dd7cddfSDavid du Colombier /*
667aa46331bSDavid du Colombier * microsoft intellimouse 3 buttons + scroll
668aa46331bSDavid du Colombier * byte 0 - 1 L R Y7 Y6 X7 X6
669aa46331bSDavid du Colombier * byte 1 - 0 X5 X4 X3 X2 X1 X0
670aa46331bSDavid du Colombier * byte 2 - 0 Y5 Y4 Y3 Y2 Y1 Y0
671aa46331bSDavid du Colombier * byte 3 - 0 0 M % % % %
672aa46331bSDavid du Colombier *
673aa46331bSDavid du Colombier * %: 0xf => U , 0x1 => D
674aa46331bSDavid du Colombier *
675aa46331bSDavid du Colombier * L: left
676aa46331bSDavid du Colombier * R: right
677aa46331bSDavid du Colombier * U: up
678aa46331bSDavid du Colombier * D: down
679aa46331bSDavid du Colombier */
680aa46331bSDavid du Colombier int
m5mouseputc(Queue *,int c)681aa46331bSDavid du Colombier m5mouseputc(Queue*, int c)
682aa46331bSDavid du Colombier {
683aa46331bSDavid du Colombier static uchar msg[3];
684aa46331bSDavid du Colombier static int nb;
68524c25b93SDavid du Colombier static ulong lasttick;
68624c25b93SDavid du Colombier ulong m;
68724c25b93SDavid du Colombier
68824c25b93SDavid du Colombier /* Resynchronize in stream with timing. */
68924c25b93SDavid du Colombier m = MACHP(0)->ticks;
69024c25b93SDavid du Colombier if(TK2SEC(m - lasttick) > 2)
69124c25b93SDavid du Colombier nb = 0;
69224c25b93SDavid du Colombier lasttick = m;
69324c25b93SDavid du Colombier
694aa46331bSDavid du Colombier msg[nb++] = c & 0x7f;
695aa46331bSDavid du Colombier if (nb == 4) {
696aa46331bSDavid du Colombier schar dx,dy,newbuttons;
697aa46331bSDavid du Colombier dx = msg[1] | (msg[0] & 0x3) << 6;
698aa46331bSDavid du Colombier dy = msg[2] | (msg[0] & 0xc) << 4;
699aa46331bSDavid du Colombier newbuttons =
700aa46331bSDavid du Colombier (msg[0] & 0x10) >> (mouseshifted ? 3 : 2)
701aa46331bSDavid du Colombier | (msg[0] & 0x20) >> 5
702aa46331bSDavid du Colombier | ( msg[3] == 0x10 ? 0x02 :
70315174232SDavid du Colombier msg[3] == 0x0f ? ScrollUp :
70415174232SDavid du Colombier msg[3] == 0x01 ? ScrollDown : 0 );
705aa46331bSDavid du Colombier mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks));
706aa46331bSDavid du Colombier nb = 0;
707aa46331bSDavid du Colombier }
708aa46331bSDavid du Colombier return 0;
709aa46331bSDavid du Colombier }
710aa46331bSDavid du Colombier
711aa46331bSDavid du Colombier /*
7127dd7cddfSDavid du Colombier * Logitech 5 byte packed binary mouse format, 8 bit bytes
7137dd7cddfSDavid du Colombier *
7147dd7cddfSDavid du Colombier * shift & right button is the same as middle button (for 2 button mice)
7157dd7cddfSDavid du Colombier */
7167dd7cddfSDavid du Colombier int
mouseputc(Queue *,int c)7177dd7cddfSDavid du Colombier mouseputc(Queue*, int c)
7187dd7cddfSDavid du Colombier {
7197dd7cddfSDavid du Colombier static short msg[5];
7207dd7cddfSDavid du Colombier static int nb;
72159cc4ca5SDavid du Colombier static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 3, 3, 7};
7227dd7cddfSDavid du Colombier int dx, dy, newbuttons;
72324c25b93SDavid du Colombier static ulong lasttick;
72424c25b93SDavid du Colombier ulong m;
72524c25b93SDavid du Colombier
72624c25b93SDavid du Colombier /* Resynchronize in stream with timing. */
72724c25b93SDavid du Colombier m = MACHP(0)->ticks;
72824c25b93SDavid du Colombier if(TK2SEC(m - lasttick) > 2)
72924c25b93SDavid du Colombier nb = 0;
73024c25b93SDavid du Colombier lasttick = m;
7317dd7cddfSDavid du Colombier
7327dd7cddfSDavid du Colombier if((c&0xF0) == 0x80)
7337dd7cddfSDavid du Colombier nb=0;
7347dd7cddfSDavid du Colombier msg[nb] = c;
7357dd7cddfSDavid du Colombier if(c & 0x80)
7367dd7cddfSDavid du Colombier msg[nb] |= ~0xFF; /* sign extend */
7377dd7cddfSDavid du Colombier if(++nb == 5){
7387dd7cddfSDavid du Colombier newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
7397dd7cddfSDavid du Colombier dx = msg[1]+msg[3];
7407dd7cddfSDavid du Colombier dy = -(msg[2]+msg[4]);
7419a747e4fSDavid du Colombier mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks));
7427dd7cddfSDavid du Colombier nb = 0;
7437dd7cddfSDavid du Colombier }
7447dd7cddfSDavid du Colombier return 0;
7457dd7cddfSDavid du Colombier }
7467dd7cddfSDavid du Colombier
7477dd7cddfSDavid du Colombier int
mousechanged(void *)7487dd7cddfSDavid du Colombier mousechanged(void*)
7497dd7cddfSDavid du Colombier {
750e29df7b0SDavid du Colombier return mouse.lastcounter != mouse.counter ||
751e29df7b0SDavid du Colombier mouse.lastresize != mouse.resize;
7527dd7cddfSDavid du Colombier }
7537dd7cddfSDavid du Colombier
7547dd7cddfSDavid du Colombier Point
mousexy(void)7557dd7cddfSDavid du Colombier mousexy(void)
7567dd7cddfSDavid du Colombier {
7577dd7cddfSDavid du Colombier return mouse.xy;
7587dd7cddfSDavid du Colombier }
7597dd7cddfSDavid du Colombier
7607dd7cddfSDavid du Colombier void
mouseaccelerate(int x)7617dd7cddfSDavid du Colombier mouseaccelerate(int x)
7627dd7cddfSDavid du Colombier {
7637dd7cddfSDavid du Colombier mouse.acceleration = x;
7647dd7cddfSDavid du Colombier if(mouse.acceleration < 3)
7657dd7cddfSDavid du Colombier mouse.maxacc = 2;
7667dd7cddfSDavid du Colombier else
7677dd7cddfSDavid du Colombier mouse.maxacc = mouse.acceleration;
7687dd7cddfSDavid du Colombier }
769e29df7b0SDavid du Colombier
770e29df7b0SDavid du Colombier /*
771e29df7b0SDavid du Colombier * notify reader that screen has been resized
772e29df7b0SDavid du Colombier */
773e29df7b0SDavid du Colombier void
mouseresize(void)774e29df7b0SDavid du Colombier mouseresize(void)
775e29df7b0SDavid du Colombier {
776e29df7b0SDavid du Colombier mouse.resize++;
777e29df7b0SDavid du Colombier wakeup(&mouse.r);
778e29df7b0SDavid du Colombier }
779e29df7b0SDavid du Colombier
780