ref: 705885553cced0300ed72722b20bad405af2bdce
parent: ba66d8f69edd895682f2661524a1d07612cb9ba8
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jan 1 13:37:08 EST 2023
mouse: Make /dev/mousein readable to get mouse status without blocking There is currently no way to get the current mouse position and button states without blocking.
--- a/sys/man/3/mouse
+++ b/sys/man/3/mouse
@@ -56,23 +56,30 @@
.B mousein
file are processed as if they were generated by the
mouse hardware itself,
-as extra mouse events to be processed and passed back via
-the
+as extra mouse events to be processed and passed back via the
.B mouse
file.
+Reading the
+.B mousein
+file returns the current mouse status without waiting.
The
.B mousein
file, which may be opened
-only by the host owner, is intended for controlling devices, such as USB mice,
+only by the host owner, is intended for controlling devices,
+such as USB mice and tablets,
that are managed by user-level software.
Each event should consist of
the letter
.B m
-followed by delta
-.IR x ,
-delta
-.IR y ,
+(for relative delta coordinates)
+or
+.B A
+(for absolute screen coordinates)
+followed by the
+.I x
and
+.I y
+coordinates and
.IR buttons
as space-separated decimal numbers.
.PP
--- a/sys/src/9/port/devmouse.c
+++ b/sys/src/9/port/devmouse.c
@@ -88,7 +88,7 @@
".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
"cursor", {Qcursor}, 0, 0666,
"mouse", {Qmouse}, 0, 0666,
- "mousein", {Qmousein}, 0, 0220,
+ "mousein", {Qmousein}, 0, 0660,
"mousectl", {Qmousectl}, 0, 0220,
};
@@ -207,7 +207,9 @@
return;
switch((ulong)c->qid.path){
case Qmousein:
+ ilock(&mouse);
mouse.inbuttons &= ~((Mousestate*)c->aux)->buttons;
+ iunlock(&mouse);
free(c->aux); /* Mousestate */
c->aux = nil;
return;
@@ -232,6 +234,7 @@
Cursor curs;
Mousestate m;
int b;
+ char t;
p = va;
switch((ulong)c->qid.path){
@@ -272,23 +275,39 @@
m = mouse.Mousestate;
iunlock(&mouse);
+ if(0){
+ case Qmousein:
+ if(offset != 0)
+ return 0;
+
+ ilock(&mouse);
+ m = mouse.Mousestate;
+ iunlock(&mouse);
+
+ t = 'm';
+ } else {
+ /* Qmouse */
+ mouse.lastcounter = m.counter;
+ if(mouse.resize){
+ mouse.resize = 0;
+ t = 'r';
+ } else {
+ t = 'm';
+ }
+ }
+
b = buttonmap[m.buttons&7];
/* put buttons 4 and 5 back in */
b |= m.buttons & (3<<3);
+
if (scrollswap)
if (b == 8)
b = 16;
else if (b == 16)
b = 8;
- sprint(buf, "m%11d %11d %11d %11ld ",
- m.xy.x, m.xy.y, b, m.msec);
- mouse.lastcounter = m.counter;
- if(mouse.resize){
- mouse.resize = 0;
- buf[0] = 'r';
- }
-
+ snprint(buf, sizeof(buf), "%c%11d %11d %11d %11ld ",
+ t, m.xy.x, m.xy.y, b, m.msec);
if(n > 1+4*12)
n = 1+4*12;
memmove(va, buf, n);
@@ -446,8 +465,11 @@
m->msec = msec;
b ^= m->buttons;
m->buttons ^= b;
+
+ ilock(&mouse);
mouse.inbuttons = (m->buttons & b) | (mouse.inbuttons & ~b);
b = mouse.buttons & ~b;
+ iunlock(&mouse);
/* include wheel */
b &= ~(8|16);