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 */
31 Mousestate queue[16]; /* circular buffer of click events */
32 ulong ri; /* read index into queue */
33 ulong wi; /* write index into queue */
40 void Cursortocursor(Cursor*);
41 int mousechanged(void*);
51 static Dirtab mousedir[]={
52 ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
53 "cursor", {Qcursor}, 0, 0666,
54 "mouse", {Qmouse}, 0, 0666,
55 "mousein", {Qmousein}, 0, 0222,
56 "mousectl", {Qmousectl}, 0, 0222,
61 { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C,
62 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04,
63 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04,
64 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40,
66 { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0,
67 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8,
68 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8,
69 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00,
73 extern Memimage* gscreen;
74 extern void mousewarpnote(Point);
80 Cursortocursor(&arrow);
87 Cursortocursor(&arrow);
92 mouseattach(char *spec)
94 return devattach('m', spec);
98 mousewalk(Chan *c, Chan *nc, char **name, int nname)
100 return devwalk(c, nc, name, nname, mousedir, nelem(mousedir), devgen);
104 mousestat(Chan *c, uchar *db, int n)
106 return devstat(c, db, n, mousedir, nelem(mousedir), devgen);
110 mouseopen(Chan *c, int omode)
114 mode = openmode(omode);
115 switch((ulong)c->qid.path){
125 if(_tas(&mouse.open) != 0)
127 mouse.lastcounter = mouse.counter;
141 if((c->qid.type&QTDIR)!=0 || (c->flag&COPEN)==0)
143 switch((ulong)c->qid.path){
148 if(decref(&mouse) != 0)
152 Cursortocursor(&arrow);
159 mouseread(Chan *c, void *va, long n, vlong off)
167 switch((ulong)c->qid.path){
169 return devdirread(c, va, n, mousedir, nelem(mousedir), devgen);
177 BPLONG(p+0, curs.offset.x);
178 BPLONG(p+4, curs.offset.y);
179 memmove(p+8, curs.clr, 2*16);
180 memmove(p+40, curs.set, 2*16);
184 while(mousechanged(0) == 0)
185 rendsleep(&mouse.r, mousechanged, 0);
188 if(mouse.ri != mouse.wi)
189 m = mouse.queue[mouse.ri++ % nelem(mouse.queue)];
191 m = mouse.Mousestate;
194 sprint(buf, "m%11d %11d %11d %11lud ",
195 m.xy.x, m.xy.y, m.buttons, m.msec);
197 mouse.lastcounter = m.counter;
208 mousewrite(Chan *c, void *va, long n, vlong)
215 switch((ulong)c->qid.path){
223 Cursortocursor(&arrow);
226 curs.offset.x = BGLONG(p+0);
227 curs.offset.y = BGLONG(p+4);
228 memmove(curs.clr, p+8, 2*16);
229 memmove(curs.set, p+40, 2*16);
230 Cursortocursor(&curs);
241 pt.x = strtol(buf+1, &p, 0);
244 pt.y = strtol(p, 0, 0);
245 absmousetrack(pt.x, pt.y, mouse.buttons, nsec()/(1000*1000LL));
275 Cursortocursor(Cursor *c)
278 memmove(&cursor.Cursor, c, sizeof(Cursor));
284 absmousetrack(int x, int y, int b, ulong msec)
291 if(x < gscreen->clipr.min.x)
292 x = gscreen->clipr.min.x;
293 if(x >= gscreen->clipr.max.x)
294 x = gscreen->clipr.max.x-1;
295 if(y < gscreen->clipr.min.y)
296 y = gscreen->clipr.min.y;
297 if(y >= gscreen->clipr.max.y)
298 y = gscreen->clipr.max.y-1;
303 lastb = mouse.buttons;
309 * if the queue fills, don't queue any more events until a
310 * reader polls the mouse.
312 if(b != lastb && (mouse.wi-mouse.ri) < nelem(mouse.queue))
313 mouse.queue[mouse.wi++ % nelem(mouse.queue)] = mouse.Mousestate;
316 rendwakeup(&mouse.r);
324 return mouse.lastcounter != mouse.counter;