12 typedef struct Mouseinfo Mouseinfo;
13 typedef struct Mousestate Mousestate;
17 Point xy; /* mouse.xy */
18 int buttons; /* mouse.buttons */
19 ulong counter; /* increments every update */
20 ulong msec; /* time of last event */
27 ulong lastcounter; /* value when /dev/mouse read */
32 Mousestate queue[16]; /* circular buffer of click events */
33 ulong ri; /* read index into queue */
34 ulong wi; /* write index into queue */
41 void Cursortocursor(Cursor*);
42 int mousechanged(void*);
52 static Dirtab mousedir[]={
53 ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
54 "cursor", {Qcursor}, 0, 0666,
55 "mouse", {Qmouse}, 0, 0666,
56 "mousein", {Qmousein}, 0, 0222,
57 "mousectl", {Qmousectl}, 0, 0222,
62 { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
63 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
64 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04,
65 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40,
67 { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0,
68 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8,
69 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8,
70 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,
74 extern Memimage* gscreen;
75 extern void mousewarpnote(Point);
81 Cursortocursor(&arrow);
88 Cursortocursor(&arrow);
93 mouseattach(char *spec)
95 return devattach('m', spec);
99 mousewalk(Chan *c, Chan *nc, char **name, int nname)
101 return devwalk(c, nc, name, nname, mousedir, nelem(mousedir), devgen);
105 mousestat(Chan *c, uchar *db, int n)
107 return devstat(c, db, n, mousedir, nelem(mousedir), devgen);
111 mouseopen(Chan *c, int omode)
115 mode = openmode(omode);
116 switch((ulong)c->qid.path){
126 if(_tas(&mouse.open) != 0)
128 mouse.lastcounter = mouse.counter;
142 if((c->qid.type&QTDIR)!=0 || (c->flag&COPEN)==0)
144 switch((ulong)c->qid.path){
149 if(decref(&mouse) != 0)
153 Cursortocursor(&arrow);
160 mouseread(Chan *c, void *va, long n, vlong off)
168 switch((ulong)c->qid.path){
170 return devdirread(c, va, n, mousedir, nelem(mousedir), devgen);
178 BPLONG(p+0, curs.offset.x);
179 BPLONG(p+4, curs.offset.y);
180 memmove(p+8, curs.clr, 2*16);
181 memmove(p+40, curs.set, 2*16);
185 while(mousechanged(0) == 0)
186 rendsleep(&mouse.r, mousechanged, 0);
189 if(mouse.ri != mouse.wi)
190 m = mouse.queue[mouse.ri++ % nelem(mouse.queue)];
192 m = mouse.Mousestate;
195 sprint(buf, "m%11d %11d %11d %11ld ",
196 m.xy.x, m.xy.y, m.buttons, m.msec);
198 mouse.lastcounter = m.counter;
213 mousewrite(Chan *c, void *va, long n, vlong)
220 switch((ulong)c->qid.path){
228 Cursortocursor(&arrow);
231 curs.offset.x = BGLONG(p+0);
232 curs.offset.y = BGLONG(p+4);
233 memmove(curs.clr, p+8, 2*16);
234 memmove(curs.set, p+40, 2*16);
235 Cursortocursor(&curs);
246 pt.x = strtol(buf+1, &p, 0);
249 pt.y = strtol(p, 0, 0);
250 absmousetrack(pt.x, pt.y, mouse.buttons, nsec()/(1000*1000LL));
280 Cursortocursor(Cursor *c)
283 memmove(&cursor.Cursor, c, sizeof(Cursor));
289 absmousetrack(int x, int y, int b, ulong msec)
296 if(x < gscreen->clipr.min.x)
297 x = gscreen->clipr.min.x;
298 if(x >= gscreen->clipr.max.x)
299 x = gscreen->clipr.max.x-1;
300 if(y < gscreen->clipr.min.y)
301 y = gscreen->clipr.min.y;
302 if(y >= gscreen->clipr.max.y)
303 y = gscreen->clipr.max.y-1;
308 lastb = mouse.buttons;
314 * if the queue fills, don't queue any more events until a
315 * reader polls the mouse.
317 if(b != lastb && (mouse.wi-mouse.ri) < nelem(mouse.queue))
318 mouse.queue[mouse.wi++ % nelem(mouse.queue)] = mouse.Mousestate;
321 rendwakeup(&mouse.r);
329 return mouse.lastcounter != mouse.counter || mouse.resize != 0;
339 * notify reader that screen has been resized
345 rendwakeup(&mouse.r);