I think mouse input in linux is generally awful. It always feels terrible in any window manager and I have begun digging into the whys. It seems mostly related with X adding acceleration. In my ventures I learned how to read from a mouse device without X. Lets read the mouse input from linux!
In UNIX'y operating systems everything is a file which many people seem to enjoy shouting off at irrelevant times with no context. For our purposes, this means the mouse will be represented as a file somewhere.
If you only have one mouse (why would you have two? freak) you can check /dev/input/mouse0
$ file /dev/input/mouse0
/dev/input/mouse0: character special (13/32)
With that we can see the mouse is a so called 'special' which is short for a 'special file', aka device file
A quick and dirty example in go to get the relative x/y update and whether or not left/right/middle is down would look something like this. Note this is blocking and could be drastically better
package main
import (
"os"
"log"
"fmt"
)
// TODO https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/input.h#n28
func main() {
f, err := os.OpenFile("/dev/input/mouse0", os.O_RDONLY, 0600)
if err != nil {
log.Fatal(err)
}
data := make([]byte, 3)
for {
nr, err := f.Read(data)
if err != nil {
log.Fatal(err)
}
if nr == 0 {
break
}
left := data[0] & 0x1 != 0;
right := data[0] & 0x2 != 0;
middle := data[0] & 0x4 != 0;
x := int8(data[1])
y := int8(data[2])
fmt.Printf("\r x=%d y=%d left=%v right=%v middle=%v ",
x, y, left, right, middle)
}
}
Assuming you have your GOPATH
setup correctly (or use the default of ~/go), save this in a package called eg,
linux-mouse-events
.
Then you can test it like so (CTRL-C to exit):
$ go install linux-mouse-events
$ sudo ~/go/bin/linux-mouse-events
x=1 y=0 left=false right=false middle=false ^C
Amazing! Next we will move to timing evdev events to see if anything mucks with raw mouse report rate