1*45e6af3bSDavid du Colombier #include "u.h"
2*45e6af3bSDavid du Colombier #include "../port/lib.h"
3*45e6af3bSDavid du Colombier #include "mem.h"
4*45e6af3bSDavid du Colombier #include "dat.h"
5*45e6af3bSDavid du Colombier #include "fns.h"
6*45e6af3bSDavid du Colombier #include "../port/error.h"
7*45e6af3bSDavid du Colombier
8*45e6af3bSDavid du Colombier #define Image IMAGE
9*45e6af3bSDavid du Colombier #include <draw.h>
10*45e6af3bSDavid du Colombier #include <memdraw.h>
11*45e6af3bSDavid du Colombier #include <cursor.h>
12*45e6af3bSDavid du Colombier #include "screen.h"
13*45e6af3bSDavid du Colombier
14*45e6af3bSDavid du Colombier enum {
15*45e6af3bSDavid du Colombier ScrollUp = 0x08,
16*45e6af3bSDavid du Colombier ScrollDown = 0x10,
17*45e6af3bSDavid du Colombier ScrollLeft = 0x20,
18*45e6af3bSDavid du Colombier ScrollRight = 0x40,
19*45e6af3bSDavid du Colombier };
20*45e6af3bSDavid du Colombier
21*45e6af3bSDavid du Colombier typedef struct Mouseinfo Mouseinfo;
22*45e6af3bSDavid du Colombier typedef struct Mousestate Mousestate;
23*45e6af3bSDavid du Colombier
24*45e6af3bSDavid du Colombier struct Mousestate
25*45e6af3bSDavid du Colombier {
26*45e6af3bSDavid du Colombier Point xy; /* mouse.xy */
27*45e6af3bSDavid du Colombier int buttons; /* mouse.buttons */
28*45e6af3bSDavid du Colombier ulong counter; /* increments every update */
29*45e6af3bSDavid du Colombier ulong msec; /* time of last event */
30*45e6af3bSDavid du Colombier };
31*45e6af3bSDavid du Colombier
32*45e6af3bSDavid du Colombier struct Mouseinfo
33*45e6af3bSDavid du Colombier {
34*45e6af3bSDavid du Colombier Lock;
35*45e6af3bSDavid du Colombier Mousestate;
36*45e6af3bSDavid du Colombier int dx;
37*45e6af3bSDavid du Colombier int dy;
38*45e6af3bSDavid du Colombier int track; /* dx & dy updated */
39*45e6af3bSDavid du Colombier int redraw; /* update cursor on screen */
40*45e6af3bSDavid du Colombier ulong lastcounter; /* value when /dev/mouse read */
41*45e6af3bSDavid du Colombier ulong lastresize;
42*45e6af3bSDavid du Colombier ulong resize;
43*45e6af3bSDavid du Colombier Rendez r;
44*45e6af3bSDavid du Colombier Ref;
45*45e6af3bSDavid du Colombier QLock;
46*45e6af3bSDavid du Colombier int open;
47*45e6af3bSDavid du Colombier int acceleration;
48*45e6af3bSDavid du Colombier int maxacc;
49*45e6af3bSDavid du Colombier Mousestate queue[16]; /* circular buffer of click events */
50*45e6af3bSDavid du Colombier int ri; /* read index into queue */
51*45e6af3bSDavid du Colombier int wi; /* write index into queue */
52*45e6af3bSDavid du Colombier uchar qfull; /* queue is full */
53*45e6af3bSDavid du Colombier };
54*45e6af3bSDavid du Colombier
55*45e6af3bSDavid du Colombier enum
56*45e6af3bSDavid du Colombier {
57*45e6af3bSDavid du Colombier CMbuttonmap,
58*45e6af3bSDavid du Colombier CMscrollswap,
59*45e6af3bSDavid du Colombier CMswap,
60*45e6af3bSDavid du Colombier CMwildcard,
61*45e6af3bSDavid du Colombier };
62*45e6af3bSDavid du Colombier
63*45e6af3bSDavid du Colombier static Cmdtab mousectlmsg[] =
64*45e6af3bSDavid du Colombier {
65*45e6af3bSDavid du Colombier CMbuttonmap, "buttonmap", 0,
66*45e6af3bSDavid du Colombier CMscrollswap, "scrollswap", 0,
67*45e6af3bSDavid du Colombier CMswap, "swap", 1,
68*45e6af3bSDavid du Colombier CMwildcard, "*", 0,
69*45e6af3bSDavid du Colombier };
70*45e6af3bSDavid du Colombier
71*45e6af3bSDavid du Colombier Mouseinfo mouse;
72*45e6af3bSDavid du Colombier Cursorinfo cursor;
73*45e6af3bSDavid du Colombier int mouseshifted;
74*45e6af3bSDavid du Colombier int kbdbuttons;
75*45e6af3bSDavid du Colombier void (*kbdmouse)(int);
76*45e6af3bSDavid du Colombier Cursor curs;
77*45e6af3bSDavid du Colombier
78*45e6af3bSDavid du Colombier void Cursortocursor(Cursor*);
79*45e6af3bSDavid du Colombier int mousechanged(void*);
80*45e6af3bSDavid du Colombier
81*45e6af3bSDavid du Colombier static void mouseclock(void);
82*45e6af3bSDavid du Colombier
83*45e6af3bSDavid du Colombier enum{
84*45e6af3bSDavid du Colombier Qdir,
85*45e6af3bSDavid du Colombier Qcursor,
86*45e6af3bSDavid du Colombier Qmouse,
87*45e6af3bSDavid du Colombier Qmousein,
88*45e6af3bSDavid du Colombier Qmousectl,
89*45e6af3bSDavid du Colombier };
90*45e6af3bSDavid du Colombier
91*45e6af3bSDavid du Colombier static Dirtab mousedir[]={
92*45e6af3bSDavid du Colombier ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
93*45e6af3bSDavid du Colombier "cursor", {Qcursor}, 0, 0666,
94*45e6af3bSDavid du Colombier "mouse", {Qmouse}, 0, 0666,
95*45e6af3bSDavid du Colombier "mousein", {Qmousein}, 0, 0220,
96*45e6af3bSDavid du Colombier "mousectl", {Qmousectl}, 0, 0220,
97*45e6af3bSDavid du Colombier };
98*45e6af3bSDavid du Colombier
99*45e6af3bSDavid du Colombier static uchar buttonmap[8] = {
100*45e6af3bSDavid du Colombier 0, 1, 2, 3, 4, 5, 6, 7,
101*45e6af3bSDavid du Colombier };
102*45e6af3bSDavid du Colombier static int mouseswap;
103*45e6af3bSDavid du Colombier static int scrollswap;
104*45e6af3bSDavid du Colombier static ulong mousetime;
105*45e6af3bSDavid du Colombier
106*45e6af3bSDavid du Colombier extern Memimage* gscreen;
107*45e6af3bSDavid du Colombier extern ulong kerndate;
108*45e6af3bSDavid du Colombier
109*45e6af3bSDavid du Colombier static void
mousereset(void)110*45e6af3bSDavid du Colombier mousereset(void)
111*45e6af3bSDavid du Colombier {
112*45e6af3bSDavid du Colombier curs = arrow;
113*45e6af3bSDavid du Colombier Cursortocursor(&arrow);
114*45e6af3bSDavid du Colombier /* redraw cursor about 30 times per second */
115*45e6af3bSDavid du Colombier addclock0link(mouseclock, 33);
116*45e6af3bSDavid du Colombier }
117*45e6af3bSDavid du Colombier
118*45e6af3bSDavid du Colombier static void
mousefromkbd(int buttons)119*45e6af3bSDavid du Colombier mousefromkbd(int buttons)
120*45e6af3bSDavid du Colombier {
121*45e6af3bSDavid du Colombier kbdbuttons = buttons;
122*45e6af3bSDavid du Colombier mousetrack(0, 0, 0, TK2MS(sys->ticks));
123*45e6af3bSDavid du Colombier }
124*45e6af3bSDavid du Colombier
125*45e6af3bSDavid du Colombier static int
mousedevgen(Chan * c,char * name,Dirtab * tab,int ntab,int i,Dir * dp)126*45e6af3bSDavid du Colombier mousedevgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
127*45e6af3bSDavid du Colombier {
128*45e6af3bSDavid du Colombier int rc;
129*45e6af3bSDavid du Colombier
130*45e6af3bSDavid du Colombier rc = devgen(c, name, tab, ntab, i, dp);
131*45e6af3bSDavid du Colombier if(rc != -1)
132*45e6af3bSDavid du Colombier dp->atime = mousetime;
133*45e6af3bSDavid du Colombier return rc;
134*45e6af3bSDavid du Colombier }
135*45e6af3bSDavid du Colombier
136*45e6af3bSDavid du Colombier static void
mouseinit(void)137*45e6af3bSDavid du Colombier mouseinit(void)
138*45e6af3bSDavid du Colombier {
139*45e6af3bSDavid du Colombier curs = arrow;
140*45e6af3bSDavid du Colombier Cursortocursor(&arrow);
141*45e6af3bSDavid du Colombier cursoron(1);
142*45e6af3bSDavid du Colombier kbdmouse = mousefromkbd;
143*45e6af3bSDavid du Colombier mousetime = seconds();
144*45e6af3bSDavid du Colombier }
145*45e6af3bSDavid du Colombier
146*45e6af3bSDavid du Colombier static Chan*
mouseattach(char * spec)147*45e6af3bSDavid du Colombier mouseattach(char *spec)
148*45e6af3bSDavid du Colombier {
149*45e6af3bSDavid du Colombier return devattach('m', spec);
150*45e6af3bSDavid du Colombier }
151*45e6af3bSDavid du Colombier
152*45e6af3bSDavid du Colombier static Walkqid*
mousewalk(Chan * c,Chan * nc,char ** name,int nname)153*45e6af3bSDavid du Colombier mousewalk(Chan *c, Chan *nc, char **name, int nname)
154*45e6af3bSDavid du Colombier {
155*45e6af3bSDavid du Colombier Walkqid *wq;
156*45e6af3bSDavid du Colombier
157*45e6af3bSDavid du Colombier /*
158*45e6af3bSDavid du Colombier * We use devgen() and not mousedevgen() here
159*45e6af3bSDavid du Colombier * see "Ugly problem" in dev.c/devwalk()
160*45e6af3bSDavid du Colombier */
161*45e6af3bSDavid du Colombier wq = devwalk(c, nc, name, nname, mousedir, nelem(mousedir), devgen);
162*45e6af3bSDavid du Colombier if(wq != nil && wq->clone != c && wq->clone != nil && (wq->clone->qid.type&QTDIR)==0)
163*45e6af3bSDavid du Colombier incref(&mouse);
164*45e6af3bSDavid du Colombier return wq;
165*45e6af3bSDavid du Colombier }
166*45e6af3bSDavid du Colombier
167*45e6af3bSDavid du Colombier long int
mousestat(Chan * c,uchar * db,long n)168*45e6af3bSDavid du Colombier mousestat(Chan *c, uchar *db, long n)
169*45e6af3bSDavid du Colombier {
170*45e6af3bSDavid du Colombier return devstat(c, db, n, mousedir, nelem(mousedir), mousedevgen);
171*45e6af3bSDavid du Colombier }
172*45e6af3bSDavid du Colombier
173*45e6af3bSDavid du Colombier static Chan*
mouseopen(Chan * c,int omode)174*45e6af3bSDavid du Colombier mouseopen(Chan *c, int omode)
175*45e6af3bSDavid du Colombier {
176*45e6af3bSDavid du Colombier switch((ulong)c->qid.path){
177*45e6af3bSDavid du Colombier case Qdir:
178*45e6af3bSDavid du Colombier if(omode != OREAD)
179*45e6af3bSDavid du Colombier error(Eperm);
180*45e6af3bSDavid du Colombier break;
181*45e6af3bSDavid du Colombier case Qmouse:
182*45e6af3bSDavid du Colombier lock(&mouse);
183*45e6af3bSDavid du Colombier if(mouse.open){
184*45e6af3bSDavid du Colombier unlock(&mouse);
185*45e6af3bSDavid du Colombier error(Einuse);
186*45e6af3bSDavid du Colombier }
187*45e6af3bSDavid du Colombier mouse.open = 1;
188*45e6af3bSDavid du Colombier mouse.ref++;
189*45e6af3bSDavid du Colombier mouse.lastresize = mouse.resize;
190*45e6af3bSDavid du Colombier unlock(&mouse);
191*45e6af3bSDavid du Colombier break;
192*45e6af3bSDavid du Colombier case Qmousein:
193*45e6af3bSDavid du Colombier if(!iseve())
194*45e6af3bSDavid du Colombier error(Eperm);
195*45e6af3bSDavid du Colombier break;
196*45e6af3bSDavid du Colombier default:
197*45e6af3bSDavid du Colombier incref(&mouse);
198*45e6af3bSDavid du Colombier }
199*45e6af3bSDavid du Colombier c->mode = openmode(omode);
200*45e6af3bSDavid du Colombier c->flag |= COPEN;
201*45e6af3bSDavid du Colombier c->offset = 0;
202*45e6af3bSDavid du Colombier return c;
203*45e6af3bSDavid du Colombier }
204*45e6af3bSDavid du Colombier
205*45e6af3bSDavid du Colombier static void
mousecreate(Chan *,char *,int,int)206*45e6af3bSDavid du Colombier mousecreate(Chan*, char*, int, int)
207*45e6af3bSDavid du Colombier {
208*45e6af3bSDavid du Colombier error(Eperm);
209*45e6af3bSDavid du Colombier }
210*45e6af3bSDavid du Colombier
211*45e6af3bSDavid du Colombier static void
mouseclose(Chan * c)212*45e6af3bSDavid du Colombier mouseclose(Chan *c)
213*45e6af3bSDavid du Colombier {
214*45e6af3bSDavid du Colombier if((c->qid.type&QTDIR)==0 && (c->flag&COPEN)){
215*45e6af3bSDavid du Colombier if(c->qid.path == Qmousein)
216*45e6af3bSDavid du Colombier return;
217*45e6af3bSDavid du Colombier lock(&mouse);
218*45e6af3bSDavid du Colombier if(c->qid.path == Qmouse)
219*45e6af3bSDavid du Colombier mouse.open = 0;
220*45e6af3bSDavid du Colombier if(--mouse.ref == 0){
221*45e6af3bSDavid du Colombier cursoroff(1);
222*45e6af3bSDavid du Colombier curs = arrow;
223*45e6af3bSDavid du Colombier Cursortocursor(&arrow);
224*45e6af3bSDavid du Colombier cursoron(1);
225*45e6af3bSDavid du Colombier }
226*45e6af3bSDavid du Colombier unlock(&mouse);
227*45e6af3bSDavid du Colombier }
228*45e6af3bSDavid du Colombier }
229*45e6af3bSDavid du Colombier
230*45e6af3bSDavid du Colombier
231*45e6af3bSDavid du Colombier static long
mouseread(Chan * c,void * va,long n,vlong off)232*45e6af3bSDavid du Colombier mouseread(Chan *c, void *va, long n, vlong off)
233*45e6af3bSDavid du Colombier {
234*45e6af3bSDavid du Colombier char buf[1+4*12+1];
235*45e6af3bSDavid du Colombier uchar *p;
236*45e6af3bSDavid du Colombier ulong offset = off;
237*45e6af3bSDavid du Colombier Mousestate m;
238*45e6af3bSDavid du Colombier int b;
239*45e6af3bSDavid du Colombier
240*45e6af3bSDavid du Colombier p = va;
241*45e6af3bSDavid du Colombier switch((ulong)c->qid.path){
242*45e6af3bSDavid du Colombier case Qdir:
243*45e6af3bSDavid du Colombier return devdirread(c, va, n, mousedir, nelem(mousedir), mousedevgen);
244*45e6af3bSDavid du Colombier
245*45e6af3bSDavid du Colombier case Qcursor:
246*45e6af3bSDavid du Colombier if(offset != 0)
247*45e6af3bSDavid du Colombier return 0;
248*45e6af3bSDavid du Colombier if(n < 2*4+2*2*16)
249*45e6af3bSDavid du Colombier error(Eshort);
250*45e6af3bSDavid du Colombier n = 2*4+2*2*16;
251*45e6af3bSDavid du Colombier lock(&cursor);
252*45e6af3bSDavid du Colombier BPLONG(p+0, curs.offset.x);
253*45e6af3bSDavid du Colombier BPLONG(p+4, curs.offset.y);
254*45e6af3bSDavid du Colombier memmove(p+8, curs.clr, 2*16);
255*45e6af3bSDavid du Colombier memmove(p+40, curs.set, 2*16);
256*45e6af3bSDavid du Colombier unlock(&cursor);
257*45e6af3bSDavid du Colombier return n;
258*45e6af3bSDavid du Colombier
259*45e6af3bSDavid du Colombier case Qmouse:
260*45e6af3bSDavid du Colombier while(mousechanged(0) == 0)
261*45e6af3bSDavid du Colombier sleep(&mouse.r, mousechanged, 0);
262*45e6af3bSDavid du Colombier
263*45e6af3bSDavid du Colombier mouse.qfull = 0;
264*45e6af3bSDavid du Colombier mousetime = seconds();
265*45e6af3bSDavid du Colombier
266*45e6af3bSDavid du Colombier /*
267*45e6af3bSDavid du Colombier * No lock of the indices is necessary here, because ri is only
268*45e6af3bSDavid du Colombier * updated by us, and there is only one mouse reader
269*45e6af3bSDavid du Colombier * at a time. I suppose that more than one process
270*45e6af3bSDavid du Colombier * could try to read the fd at one time, but such behavior
271*45e6af3bSDavid du Colombier * is degenerate and already violates the calling
272*45e6af3bSDavid du Colombier * conventions for sleep above.
273*45e6af3bSDavid du Colombier */
274*45e6af3bSDavid du Colombier if(mouse.ri != mouse.wi) {
275*45e6af3bSDavid du Colombier m = mouse.queue[mouse.ri];
276*45e6af3bSDavid du Colombier if(++mouse.ri == nelem(mouse.queue))
277*45e6af3bSDavid du Colombier mouse.ri = 0;
278*45e6af3bSDavid du Colombier } else {
279*45e6af3bSDavid du Colombier while(!canlock(&cursor))
280*45e6af3bSDavid du Colombier tsleep(&up->sleep, return0, 0, TK2MS(1));
281*45e6af3bSDavid du Colombier
282*45e6af3bSDavid du Colombier m = mouse.Mousestate;
283*45e6af3bSDavid du Colombier unlock(&cursor);
284*45e6af3bSDavid du Colombier }
285*45e6af3bSDavid du Colombier
286*45e6af3bSDavid du Colombier b = buttonmap[m.buttons&7];
287*45e6af3bSDavid du Colombier /* put buttons 4 and 5 back in */
288*45e6af3bSDavid du Colombier b |= m.buttons & (3<<3);
289*45e6af3bSDavid du Colombier if (scrollswap)
290*45e6af3bSDavid du Colombier if (b == 8)
291*45e6af3bSDavid du Colombier b = 16;
292*45e6af3bSDavid du Colombier else if (b == 16)
293*45e6af3bSDavid du Colombier b = 8;
294*45e6af3bSDavid du Colombier snprint(buf, sizeof buf, "m%11d %11d %11d %11lud ",
295*45e6af3bSDavid du Colombier m.xy.x, m.xy.y,
296*45e6af3bSDavid du Colombier b,
297*45e6af3bSDavid du Colombier m.msec);
298*45e6af3bSDavid du Colombier mouse.lastcounter = m.counter;
299*45e6af3bSDavid du Colombier if(n > 1+4*12)
300*45e6af3bSDavid du Colombier n = 1+4*12;
301*45e6af3bSDavid du Colombier if(mouse.lastresize != mouse.resize){
302*45e6af3bSDavid du Colombier mouse.lastresize = mouse.resize;
303*45e6af3bSDavid du Colombier buf[0] = 'r';
304*45e6af3bSDavid du Colombier }
305*45e6af3bSDavid du Colombier memmove(va, buf, n);
306*45e6af3bSDavid du Colombier return n;
307*45e6af3bSDavid du Colombier }
308*45e6af3bSDavid du Colombier return 0;
309*45e6af3bSDavid du Colombier }
310*45e6af3bSDavid du Colombier
311*45e6af3bSDavid du Colombier static void
setbuttonmap(char * map)312*45e6af3bSDavid du Colombier setbuttonmap(char* map)
313*45e6af3bSDavid du Colombier {
314*45e6af3bSDavid du Colombier int i, x, one, two, three;
315*45e6af3bSDavid du Colombier
316*45e6af3bSDavid du Colombier one = two = three = 0;
317*45e6af3bSDavid du Colombier for(i = 0; i < 3; i++){
318*45e6af3bSDavid du Colombier if(map[i] == 0)
319*45e6af3bSDavid du Colombier error(Ebadarg);
320*45e6af3bSDavid du Colombier if(map[i] == '1'){
321*45e6af3bSDavid du Colombier if(one)
322*45e6af3bSDavid du Colombier error(Ebadarg);
323*45e6af3bSDavid du Colombier one = 1<<i;
324*45e6af3bSDavid du Colombier }
325*45e6af3bSDavid du Colombier else if(map[i] == '2'){
326*45e6af3bSDavid du Colombier if(two)
327*45e6af3bSDavid du Colombier error(Ebadarg);
328*45e6af3bSDavid du Colombier two = 1<<i;
329*45e6af3bSDavid du Colombier }
330*45e6af3bSDavid du Colombier else if(map[i] == '3'){
331*45e6af3bSDavid du Colombier if(three)
332*45e6af3bSDavid du Colombier error(Ebadarg);
333*45e6af3bSDavid du Colombier three = 1<<i;
334*45e6af3bSDavid du Colombier }
335*45e6af3bSDavid du Colombier else
336*45e6af3bSDavid du Colombier error(Ebadarg);
337*45e6af3bSDavid du Colombier }
338*45e6af3bSDavid du Colombier if(map[i])
339*45e6af3bSDavid du Colombier error(Ebadarg);
340*45e6af3bSDavid du Colombier
341*45e6af3bSDavid du Colombier memset(buttonmap, 0, 8);
342*45e6af3bSDavid du Colombier for(i = 0; i < 8; i++){
343*45e6af3bSDavid du Colombier x = 0;
344*45e6af3bSDavid du Colombier if(i & 1)
345*45e6af3bSDavid du Colombier x |= one;
346*45e6af3bSDavid du Colombier if(i & 2)
347*45e6af3bSDavid du Colombier x |= two;
348*45e6af3bSDavid du Colombier if(i & 4)
349*45e6af3bSDavid du Colombier x |= three;
350*45e6af3bSDavid du Colombier buttonmap[x] = i;
351*45e6af3bSDavid du Colombier }
352*45e6af3bSDavid du Colombier }
353*45e6af3bSDavid du Colombier
354*45e6af3bSDavid du Colombier static long
mousewrite(Chan * c,void * va,long n,vlong)355*45e6af3bSDavid du Colombier mousewrite(Chan *c, void *va, long n, vlong)
356*45e6af3bSDavid du Colombier {
357*45e6af3bSDavid du Colombier char *p;
358*45e6af3bSDavid du Colombier Point pt;
359*45e6af3bSDavid du Colombier Cmdbuf *cb;
360*45e6af3bSDavid du Colombier Cmdtab *ct;
361*45e6af3bSDavid du Colombier char buf[64];
362*45e6af3bSDavid du Colombier int b, msec;
363*45e6af3bSDavid du Colombier
364*45e6af3bSDavid du Colombier p = va;
365*45e6af3bSDavid du Colombier switch((ulong)c->qid.path){
366*45e6af3bSDavid du Colombier case Qdir:
367*45e6af3bSDavid du Colombier error(Eisdir);
368*45e6af3bSDavid du Colombier
369*45e6af3bSDavid du Colombier case Qcursor:
370*45e6af3bSDavid du Colombier cursoroff(1);
371*45e6af3bSDavid du Colombier if(n < 2*4+2*2*16){
372*45e6af3bSDavid du Colombier curs = arrow;
373*45e6af3bSDavid du Colombier Cursortocursor(&arrow);
374*45e6af3bSDavid du Colombier }else{
375*45e6af3bSDavid du Colombier n = 2*4+2*2*16;
376*45e6af3bSDavid du Colombier curs.offset.x = BGLONG(p+0);
377*45e6af3bSDavid du Colombier curs.offset.y = BGLONG(p+4);
378*45e6af3bSDavid du Colombier memmove(curs.clr, p+8, 2*16);
379*45e6af3bSDavid du Colombier memmove(curs.set, p+40, 2*16);
380*45e6af3bSDavid du Colombier Cursortocursor(&curs);
381*45e6af3bSDavid du Colombier }
382*45e6af3bSDavid du Colombier qlock(&mouse);
383*45e6af3bSDavid du Colombier mouse.redraw = 1;
384*45e6af3bSDavid du Colombier mouseclock();
385*45e6af3bSDavid du Colombier qunlock(&mouse);
386*45e6af3bSDavid du Colombier cursoron(1);
387*45e6af3bSDavid du Colombier return n;
388*45e6af3bSDavid du Colombier
389*45e6af3bSDavid du Colombier case Qmousectl:
390*45e6af3bSDavid du Colombier cb = parsecmd(va, n);
391*45e6af3bSDavid du Colombier if(waserror()){
392*45e6af3bSDavid du Colombier free(cb);
393*45e6af3bSDavid du Colombier nexterror();
394*45e6af3bSDavid du Colombier }
395*45e6af3bSDavid du Colombier
396*45e6af3bSDavid du Colombier ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
397*45e6af3bSDavid du Colombier
398*45e6af3bSDavid du Colombier switch(ct->index){
399*45e6af3bSDavid du Colombier case CMswap:
400*45e6af3bSDavid du Colombier if(mouseswap)
401*45e6af3bSDavid du Colombier setbuttonmap("123");
402*45e6af3bSDavid du Colombier else
403*45e6af3bSDavid du Colombier setbuttonmap("321");
404*45e6af3bSDavid du Colombier mouseswap ^= 1;
405*45e6af3bSDavid du Colombier break;
406*45e6af3bSDavid du Colombier
407*45e6af3bSDavid du Colombier case CMscrollswap:
408*45e6af3bSDavid du Colombier scrollswap ^= 1;
409*45e6af3bSDavid du Colombier break;
410*45e6af3bSDavid du Colombier
411*45e6af3bSDavid du Colombier case CMbuttonmap:
412*45e6af3bSDavid du Colombier if(cb->nf == 1)
413*45e6af3bSDavid du Colombier setbuttonmap("123");
414*45e6af3bSDavid du Colombier else
415*45e6af3bSDavid du Colombier setbuttonmap(cb->f[1]);
416*45e6af3bSDavid du Colombier break;
417*45e6af3bSDavid du Colombier
418*45e6af3bSDavid du Colombier case CMwildcard:
419*45e6af3bSDavid du Colombier mousectl(cb);
420*45e6af3bSDavid du Colombier break;
421*45e6af3bSDavid du Colombier }
422*45e6af3bSDavid du Colombier
423*45e6af3bSDavid du Colombier free(cb);
424*45e6af3bSDavid du Colombier poperror();
425*45e6af3bSDavid du Colombier return n;
426*45e6af3bSDavid du Colombier
427*45e6af3bSDavid du Colombier case Qmousein:
428*45e6af3bSDavid du Colombier if(n > sizeof buf-1)
429*45e6af3bSDavid du Colombier n = sizeof buf -1;
430*45e6af3bSDavid du Colombier memmove(buf, va, n);
431*45e6af3bSDavid du Colombier buf[n] = 0;
432*45e6af3bSDavid du Colombier p = 0;
433*45e6af3bSDavid du Colombier pt.x = strtol(buf+1, &p, 0);
434*45e6af3bSDavid du Colombier if(p == 0)
435*45e6af3bSDavid du Colombier error(Eshort);
436*45e6af3bSDavid du Colombier pt.y = strtol(p, &p, 0);
437*45e6af3bSDavid du Colombier if(p == 0)
438*45e6af3bSDavid du Colombier error(Eshort);
439*45e6af3bSDavid du Colombier b = strtol(p, &p, 0);
440*45e6af3bSDavid du Colombier msec = strtol(p, &p, 0);
441*45e6af3bSDavid du Colombier if(msec == 0)
442*45e6af3bSDavid du Colombier msec = TK2MS(sys->ticks);
443*45e6af3bSDavid du Colombier mousetrack(pt.x, pt.y, b, msec);
444*45e6af3bSDavid du Colombier return n;
445*45e6af3bSDavid du Colombier
446*45e6af3bSDavid du Colombier case Qmouse:
447*45e6af3bSDavid du Colombier if(n > sizeof buf-1)
448*45e6af3bSDavid du Colombier n = sizeof buf -1;
449*45e6af3bSDavid du Colombier memmove(buf, va, n);
450*45e6af3bSDavid du Colombier buf[n] = 0;
451*45e6af3bSDavid du Colombier p = 0;
452*45e6af3bSDavid du Colombier pt.x = strtoul(buf+1, &p, 0);
453*45e6af3bSDavid du Colombier if(p == 0)
454*45e6af3bSDavid du Colombier error(Eshort);
455*45e6af3bSDavid du Colombier pt.y = strtoul(p, 0, 0);
456*45e6af3bSDavid du Colombier qlock(&mouse);
457*45e6af3bSDavid du Colombier if(ptinrect(pt, gscreen->r)){
458*45e6af3bSDavid du Colombier mouse.xy = pt;
459*45e6af3bSDavid du Colombier mouse.redraw = 1;
460*45e6af3bSDavid du Colombier mouse.track = 1;
461*45e6af3bSDavid du Colombier mouseclock();
462*45e6af3bSDavid du Colombier }
463*45e6af3bSDavid du Colombier qunlock(&mouse);
464*45e6af3bSDavid du Colombier return n;
465*45e6af3bSDavid du Colombier }
466*45e6af3bSDavid du Colombier
467*45e6af3bSDavid du Colombier error(Egreg);
468*45e6af3bSDavid du Colombier return -1;
469*45e6af3bSDavid du Colombier }
470*45e6af3bSDavid du Colombier
471*45e6af3bSDavid du Colombier Dev mousedevtab = {
472*45e6af3bSDavid du Colombier 'm',
473*45e6af3bSDavid du Colombier "mouse",
474*45e6af3bSDavid du Colombier
475*45e6af3bSDavid du Colombier mousereset,
476*45e6af3bSDavid du Colombier mouseinit,
477*45e6af3bSDavid du Colombier devshutdown,
478*45e6af3bSDavid du Colombier mouseattach,
479*45e6af3bSDavid du Colombier mousewalk,
480*45e6af3bSDavid du Colombier mousestat,
481*45e6af3bSDavid du Colombier mouseopen,
482*45e6af3bSDavid du Colombier mousecreate,
483*45e6af3bSDavid du Colombier mouseclose,
484*45e6af3bSDavid du Colombier mouseread,
485*45e6af3bSDavid du Colombier devbread,
486*45e6af3bSDavid du Colombier mousewrite,
487*45e6af3bSDavid du Colombier devbwrite,
488*45e6af3bSDavid du Colombier devremove,
489*45e6af3bSDavid du Colombier devwstat,
490*45e6af3bSDavid du Colombier };
491*45e6af3bSDavid du Colombier
492*45e6af3bSDavid du Colombier void
Cursortocursor(Cursor * c)493*45e6af3bSDavid du Colombier Cursortocursor(Cursor *c)
494*45e6af3bSDavid du Colombier {
495*45e6af3bSDavid du Colombier lock(&cursor);
496*45e6af3bSDavid du Colombier memmove(&cursor.Cursor, c, sizeof(Cursor));
497*45e6af3bSDavid du Colombier setcursor(c);
498*45e6af3bSDavid du Colombier unlock(&cursor);
499*45e6af3bSDavid du Colombier }
500*45e6af3bSDavid du Colombier
501*45e6af3bSDavid du Colombier
502*45e6af3bSDavid du Colombier /*
503*45e6af3bSDavid du Colombier * called by the clock routine to redraw the cursor
504*45e6af3bSDavid du Colombier */
505*45e6af3bSDavid du Colombier static void
mouseclock(void)506*45e6af3bSDavid du Colombier mouseclock(void)
507*45e6af3bSDavid du Colombier {
508*45e6af3bSDavid du Colombier if(mouse.track){
509*45e6af3bSDavid du Colombier mousetrack(mouse.dx, mouse.dy, mouse.buttons, TK2MS(sys->ticks));
510*45e6af3bSDavid du Colombier mouse.track = 0;
511*45e6af3bSDavid du Colombier mouse.dx = 0;
512*45e6af3bSDavid du Colombier mouse.dy = 0;
513*45e6af3bSDavid du Colombier }
514*45e6af3bSDavid du Colombier if(mouse.redraw && canlock(&cursor)){
515*45e6af3bSDavid du Colombier mouse.redraw = 0;
516*45e6af3bSDavid du Colombier cursoroff(0);
517*45e6af3bSDavid du Colombier mouse.redraw = cursoron(0);
518*45e6af3bSDavid du Colombier unlock(&cursor);
519*45e6af3bSDavid du Colombier }
520*45e6af3bSDavid du Colombier drawactive(0);
521*45e6af3bSDavid du Colombier }
522*45e6af3bSDavid du Colombier
523*45e6af3bSDavid du Colombier static int
scale(int x)524*45e6af3bSDavid du Colombier scale(int x)
525*45e6af3bSDavid du Colombier {
526*45e6af3bSDavid du Colombier int sign = 1;
527*45e6af3bSDavid du Colombier
528*45e6af3bSDavid du Colombier if(x < 0){
529*45e6af3bSDavid du Colombier sign = -1;
530*45e6af3bSDavid du Colombier x = -x;
531*45e6af3bSDavid du Colombier }
532*45e6af3bSDavid du Colombier switch(x){
533*45e6af3bSDavid du Colombier case 0:
534*45e6af3bSDavid du Colombier case 1:
535*45e6af3bSDavid du Colombier case 2:
536*45e6af3bSDavid du Colombier case 3:
537*45e6af3bSDavid du Colombier break;
538*45e6af3bSDavid du Colombier case 4:
539*45e6af3bSDavid du Colombier x = 6 + (mouse.acceleration>>2);
540*45e6af3bSDavid du Colombier break;
541*45e6af3bSDavid du Colombier case 5:
542*45e6af3bSDavid du Colombier x = 9 + (mouse.acceleration>>1);
543*45e6af3bSDavid du Colombier break;
544*45e6af3bSDavid du Colombier default:
545*45e6af3bSDavid du Colombier x *= mouse.maxacc;
546*45e6af3bSDavid du Colombier break;
547*45e6af3bSDavid du Colombier }
548*45e6af3bSDavid du Colombier return sign*x;
549*45e6af3bSDavid du Colombier }
550*45e6af3bSDavid du Colombier
551*45e6af3bSDavid du Colombier /*
552*45e6af3bSDavid du Colombier * called at interrupt level to update the structure and
553*45e6af3bSDavid du Colombier * awaken any waiting procs.
554*45e6af3bSDavid du Colombier */
555*45e6af3bSDavid du Colombier void
mousetrack(int dx,int dy,int b,int msec)556*45e6af3bSDavid du Colombier mousetrack(int dx, int dy, int b, int msec)
557*45e6af3bSDavid du Colombier {
558*45e6af3bSDavid du Colombier int x, y, lastb;
559*45e6af3bSDavid du Colombier
560*45e6af3bSDavid du Colombier if(gscreen==nil)
561*45e6af3bSDavid du Colombier return;
562*45e6af3bSDavid du Colombier
563*45e6af3bSDavid du Colombier if(mouse.acceleration){
564*45e6af3bSDavid du Colombier dx = scale(dx);
565*45e6af3bSDavid du Colombier dy = scale(dy);
566*45e6af3bSDavid du Colombier }
567*45e6af3bSDavid du Colombier x = mouse.xy.x + dx;
568*45e6af3bSDavid du Colombier if(x < gscreen->clipr.min.x)
569*45e6af3bSDavid du Colombier x = gscreen->clipr.min.x;
570*45e6af3bSDavid du Colombier if(x >= gscreen->clipr.max.x)
571*45e6af3bSDavid du Colombier x = gscreen->clipr.max.x;
572*45e6af3bSDavid du Colombier y = mouse.xy.y + dy;
573*45e6af3bSDavid du Colombier if(y < gscreen->clipr.min.y)
574*45e6af3bSDavid du Colombier y = gscreen->clipr.min.y;
575*45e6af3bSDavid du Colombier if(y >= gscreen->clipr.max.y)
576*45e6af3bSDavid du Colombier y = gscreen->clipr.max.y;
577*45e6af3bSDavid du Colombier
578*45e6af3bSDavid du Colombier lastb = mouse.buttons;
579*45e6af3bSDavid du Colombier mouse.xy = Pt(x, y);
580*45e6af3bSDavid du Colombier mouse.buttons = b|kbdbuttons;
581*45e6af3bSDavid du Colombier mouse.redraw = 1;
582*45e6af3bSDavid du Colombier mouse.counter++;
583*45e6af3bSDavid du Colombier mouse.msec = msec;
584*45e6af3bSDavid du Colombier
585*45e6af3bSDavid du Colombier /*
586*45e6af3bSDavid du Colombier * if the queue fills, we discard the entire queue and don't
587*45e6af3bSDavid du Colombier * queue any more events until a reader polls the mouse.
588*45e6af3bSDavid du Colombier */
589*45e6af3bSDavid du Colombier if(!mouse.qfull && lastb != b) { /* add to ring */
590*45e6af3bSDavid du Colombier mouse.queue[mouse.wi] = mouse.Mousestate;
591*45e6af3bSDavid du Colombier if(++mouse.wi == nelem(mouse.queue))
592*45e6af3bSDavid du Colombier mouse.wi = 0;
593*45e6af3bSDavid du Colombier if(mouse.wi == mouse.ri)
594*45e6af3bSDavid du Colombier mouse.qfull = 1;
595*45e6af3bSDavid du Colombier }
596*45e6af3bSDavid du Colombier wakeup(&mouse.r);
597*45e6af3bSDavid du Colombier drawactive(1);
598*45e6af3bSDavid du Colombier }
599*45e6af3bSDavid du Colombier
600*45e6af3bSDavid du Colombier /*
601*45e6af3bSDavid du Colombier * microsoft 3 button, 7 bit bytes
602*45e6af3bSDavid du Colombier *
603*45e6af3bSDavid du Colombier * byte 0 - 1 L R Y7 Y6 X7 X6
604*45e6af3bSDavid du Colombier * byte 1 - 0 X5 X4 X3 X2 X1 X0
605*45e6af3bSDavid du Colombier * byte 2 - 0 Y5 Y4 Y3 Y2 Y1 Y0
606*45e6af3bSDavid du Colombier * byte 3 - 0 M x x x x x (optional)
607*45e6af3bSDavid du Colombier *
608*45e6af3bSDavid du Colombier * shift & right button is the same as middle button (for 2 button mice)
609*45e6af3bSDavid du Colombier */
610*45e6af3bSDavid du Colombier int
m3mouseputc(Queue *,int c)611*45e6af3bSDavid du Colombier m3mouseputc(Queue*, int c)
612*45e6af3bSDavid du Colombier {
613*45e6af3bSDavid du Colombier static uchar msg[3];
614*45e6af3bSDavid du Colombier static int nb;
615*45e6af3bSDavid du Colombier static int middle;
616*45e6af3bSDavid du Colombier static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 3 };
617*45e6af3bSDavid du Colombier short x;
618*45e6af3bSDavid du Colombier int dx, dy, newbuttons;
619*45e6af3bSDavid du Colombier static ulong lasttick;
620*45e6af3bSDavid du Colombier ulong m;
621*45e6af3bSDavid du Colombier
622*45e6af3bSDavid du Colombier /* Resynchronize in stream with timing. */
623*45e6af3bSDavid du Colombier m = sys->ticks;
624*45e6af3bSDavid du Colombier if(TK2SEC(m - lasttick) > 2)
625*45e6af3bSDavid du Colombier nb = 0;
626*45e6af3bSDavid du Colombier lasttick = m;
627*45e6af3bSDavid du Colombier
628*45e6af3bSDavid du Colombier if(nb==0){
629*45e6af3bSDavid du Colombier /*
630*45e6af3bSDavid du Colombier * an extra byte comes for middle button motion.
631*45e6af3bSDavid du Colombier * only two possible values for the extra byte.
632*45e6af3bSDavid du Colombier */
633*45e6af3bSDavid du Colombier if(c == 0x00 || c == 0x20){
634*45e6af3bSDavid du Colombier /* an extra byte gets sent for the middle button */
635*45e6af3bSDavid du Colombier middle = (c&0x20) ? 2 : 0;
636*45e6af3bSDavid du Colombier newbuttons = (mouse.buttons & ~2) | middle;
637*45e6af3bSDavid du Colombier mousetrack(0, 0, newbuttons, TK2MS(sys->ticks));
638*45e6af3bSDavid du Colombier return 0;
639*45e6af3bSDavid du Colombier }
640*45e6af3bSDavid du Colombier }
641*45e6af3bSDavid du Colombier msg[nb] = c;
642*45e6af3bSDavid du Colombier if(++nb == 3){
643*45e6af3bSDavid du Colombier nb = 0;
644*45e6af3bSDavid du Colombier newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)];
645*45e6af3bSDavid du Colombier x = (msg[0]&0x3)<<14;
646*45e6af3bSDavid du Colombier dx = (x>>8) | msg[1];
647*45e6af3bSDavid du Colombier x = (msg[0]&0xc)<<12;
648*45e6af3bSDavid du Colombier dy = (x>>8) | msg[2];
649*45e6af3bSDavid du Colombier mousetrack(dx, dy, newbuttons, TK2MS(sys->ticks));
650*45e6af3bSDavid du Colombier }
651*45e6af3bSDavid du Colombier return 0;
652*45e6af3bSDavid du Colombier }
653*45e6af3bSDavid du Colombier
654*45e6af3bSDavid du Colombier /*
655*45e6af3bSDavid du Colombier * microsoft intellimouse 3 buttons + scroll
656*45e6af3bSDavid du Colombier * byte 0 - 1 L R Y7 Y6 X7 X6
657*45e6af3bSDavid du Colombier * byte 1 - 0 X5 X4 X3 X2 X1 X0
658*45e6af3bSDavid du Colombier * byte 2 - 0 Y5 Y4 Y3 Y2 Y1 Y0
659*45e6af3bSDavid du Colombier * byte 3 - 0 0 M % % % %
660*45e6af3bSDavid du Colombier *
661*45e6af3bSDavid du Colombier * %: 0xf => U , 0x1 => D
662*45e6af3bSDavid du Colombier *
663*45e6af3bSDavid du Colombier * L: left
664*45e6af3bSDavid du Colombier * R: right
665*45e6af3bSDavid du Colombier * U: up
666*45e6af3bSDavid du Colombier * D: down
667*45e6af3bSDavid du Colombier */
668*45e6af3bSDavid du Colombier int
m5mouseputc(Queue *,int c)669*45e6af3bSDavid du Colombier m5mouseputc(Queue*, int c)
670*45e6af3bSDavid du Colombier {
671*45e6af3bSDavid du Colombier static uchar msg[3];
672*45e6af3bSDavid du Colombier static int nb;
673*45e6af3bSDavid du Colombier static ulong lasttick;
674*45e6af3bSDavid du Colombier ulong m;
675*45e6af3bSDavid du Colombier
676*45e6af3bSDavid du Colombier /* Resynchronize in stream with timing. */
677*45e6af3bSDavid du Colombier m = sys->ticks;
678*45e6af3bSDavid du Colombier if(TK2SEC(m - lasttick) > 2)
679*45e6af3bSDavid du Colombier nb = 0;
680*45e6af3bSDavid du Colombier lasttick = m;
681*45e6af3bSDavid du Colombier
682*45e6af3bSDavid du Colombier msg[nb++] = c & 0x7f;
683*45e6af3bSDavid du Colombier if (nb == 4) {
684*45e6af3bSDavid du Colombier schar dx,dy,newbuttons;
685*45e6af3bSDavid du Colombier dx = msg[1] | (msg[0] & 0x3) << 6;
686*45e6af3bSDavid du Colombier dy = msg[2] | (msg[0] & 0xc) << 4;
687*45e6af3bSDavid du Colombier newbuttons =
688*45e6af3bSDavid du Colombier (msg[0] & 0x10) >> (mouseshifted ? 3 : 2)
689*45e6af3bSDavid du Colombier | (msg[0] & 0x20) >> 5
690*45e6af3bSDavid du Colombier | ( msg[3] == 0x10 ? 0x02 :
691*45e6af3bSDavid du Colombier msg[3] == 0x0f ? ScrollUp :
692*45e6af3bSDavid du Colombier msg[3] == 0x01 ? ScrollDown : 0 );
693*45e6af3bSDavid du Colombier mousetrack(dx, dy, newbuttons, TK2MS(sys->ticks));
694*45e6af3bSDavid du Colombier nb = 0;
695*45e6af3bSDavid du Colombier }
696*45e6af3bSDavid du Colombier return 0;
697*45e6af3bSDavid du Colombier }
698*45e6af3bSDavid du Colombier
699*45e6af3bSDavid du Colombier /*
700*45e6af3bSDavid du Colombier * Logitech 5 byte packed binary mouse format, 8 bit bytes
701*45e6af3bSDavid du Colombier *
702*45e6af3bSDavid du Colombier * shift & right button is the same as middle button (for 2 button mice)
703*45e6af3bSDavid du Colombier */
704*45e6af3bSDavid du Colombier int
mouseputc(Queue *,int c)705*45e6af3bSDavid du Colombier mouseputc(Queue*, int c)
706*45e6af3bSDavid du Colombier {
707*45e6af3bSDavid du Colombier static short msg[5];
708*45e6af3bSDavid du Colombier static int nb;
709*45e6af3bSDavid du Colombier static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 3, 3, 7};
710*45e6af3bSDavid du Colombier int dx, dy, newbuttons;
711*45e6af3bSDavid du Colombier static ulong lasttick;
712*45e6af3bSDavid du Colombier ulong m;
713*45e6af3bSDavid du Colombier
714*45e6af3bSDavid du Colombier /* Resynchronize in stream with timing. */
715*45e6af3bSDavid du Colombier m = sys->ticks;
716*45e6af3bSDavid du Colombier if(TK2SEC(m - lasttick) > 2)
717*45e6af3bSDavid du Colombier nb = 0;
718*45e6af3bSDavid du Colombier lasttick = m;
719*45e6af3bSDavid du Colombier
720*45e6af3bSDavid du Colombier if((c&0xF0) == 0x80)
721*45e6af3bSDavid du Colombier nb=0;
722*45e6af3bSDavid du Colombier msg[nb] = c;
723*45e6af3bSDavid du Colombier if(c & 0x80)
724*45e6af3bSDavid du Colombier msg[nb] |= ~0xFF; /* sign extend */
725*45e6af3bSDavid du Colombier if(++nb == 5){
726*45e6af3bSDavid du Colombier newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
727*45e6af3bSDavid du Colombier dx = msg[1]+msg[3];
728*45e6af3bSDavid du Colombier dy = -(msg[2]+msg[4]);
729*45e6af3bSDavid du Colombier mousetrack(dx, dy, newbuttons, TK2MS(sys->ticks));
730*45e6af3bSDavid du Colombier nb = 0;
731*45e6af3bSDavid du Colombier }
732*45e6af3bSDavid du Colombier return 0;
733*45e6af3bSDavid du Colombier }
734*45e6af3bSDavid du Colombier
735*45e6af3bSDavid du Colombier int
mousechanged(void *)736*45e6af3bSDavid du Colombier mousechanged(void*)
737*45e6af3bSDavid du Colombier {
738*45e6af3bSDavid du Colombier return mouse.lastcounter != mouse.counter ||
739*45e6af3bSDavid du Colombier mouse.lastresize != mouse.resize;
740*45e6af3bSDavid du Colombier }
741*45e6af3bSDavid du Colombier
742*45e6af3bSDavid du Colombier Point
mousexy(void)743*45e6af3bSDavid du Colombier mousexy(void)
744*45e6af3bSDavid du Colombier {
745*45e6af3bSDavid du Colombier return mouse.xy;
746*45e6af3bSDavid du Colombier }
747*45e6af3bSDavid du Colombier
748*45e6af3bSDavid du Colombier void
mouseaccelerate(int x)749*45e6af3bSDavid du Colombier mouseaccelerate(int x)
750*45e6af3bSDavid du Colombier {
751*45e6af3bSDavid du Colombier mouse.acceleration = x;
752*45e6af3bSDavid du Colombier if(mouse.acceleration < 3)
753*45e6af3bSDavid du Colombier mouse.maxacc = 2;
754*45e6af3bSDavid du Colombier else
755*45e6af3bSDavid du Colombier mouse.maxacc = mouse.acceleration;
756*45e6af3bSDavid du Colombier }
757*45e6af3bSDavid du Colombier
758*45e6af3bSDavid du Colombier /*
759*45e6af3bSDavid du Colombier * notify reader that screen has been resized
760*45e6af3bSDavid du Colombier */
761*45e6af3bSDavid du Colombier void
mouseresize(void)762*45e6af3bSDavid du Colombier mouseresize(void)
763*45e6af3bSDavid du Colombier {
764*45e6af3bSDavid du Colombier mouse.resize++;
765*45e6af3bSDavid du Colombier wakeup(&mouse.r);
766*45e6af3bSDavid du Colombier }
767*45e6af3bSDavid du Colombier
768