This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the unix category.
Last Updated: 2024-11-21
I wanted to understand how my mouse and power button worked with my machine
By viewing /proc/bus/input/devices
I could see all my devices (including the
mouse) along with some event handlers:
$ cat /proc/bus/input/devices
I: Bus=0019 Vendor=0000 Product=0001 Version=0000
N: Name="Power Button"
P: Phys=LNXPWRBN/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
U: Uniq=
H: Handlers=kbd event0
B: PROP=0
B: EV=3
B: KEY=10000000000000 0
I: Bus=0019 Vendor=0000 Product=0003 Version=0000
N: Name="Sleep Button"
P: Phys=LNXSLPBN/button/input0
S: Sysfs=/devices/LNXSYSTM:00/LNXSLPBN:00/input/input1
U: Uniq=
H: Handlers=kbd event1
B: PROP=0
B: EV=3
B: KEY=4000 0 0
I: Bus=0011 Vendor=0001 Product=0001 Version=ab41
N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
S: Sysfs=/devices/platform/i8042/serio0/input/input2
U: Uniq=
H: Handlers=sysrq kbd event2 leds
B: PROP=0
B: EV=120013
B: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=7
I: Bus=0011 Vendor=0002 Product=0006 Version=0000
N: Name="ImExPS/2 Generic Explorer Mouse"
P: Phys=isa0060/serio1/input0
S: Sysfs=/devices/platform/i8042/serio1/input/input5
U: Uniq=
H: Handlers=mouse0 event4
B: PROP=1
B: EV=7
B: KEY=1f0000 0 0 0 0
B: REL=143
I: Bus=0001 Vendor=80ee Product=cafe Version=0600
N: Name="VirtualBox mouse integration"
P: Phys=
S: Sysfs=/devices/pci0000:00/0000:00:04.0/input/input6
U: Uniq=
H: Handlers=event5
B: PROP=0
B: EV=b
B: KEY=10000 0 0 0 0
B: ABS=3
The handlers are in /dev/input
e.g mouse0
was mentioned in Generic Explorer
Mouse
. So I inspect this data next:
$ sudo cat /dev/input/mouse0
S3
E(B�(�(%�("�(�(
�(�(�8��8��8��8����
�!�)��
�+$)
This just dumps a stream of data onto the screen
According to linux docs, all input events have a certain format: https://www.kernel.org/doc/Documentation/input/input.txt
struct input_event {
// assuming a standard number of bytes for 64 bit system compiler: https://stackoverflow.com/questions/11438794/is-the-size-of-c-int-2-bytes-or-4-bytes
struct timeval time; / 16 bytes
unsigned short type; / 2 bytes
unsigned short code; / 2 bytes
unsigned int value; / 4 bytes
};
time
is the timestamp, it returns the time at which the event happened.
type
is for example EV_REL
for relative movement, EV_KEY
for a keypress or
release. More types are defined in include/uapi/linux/input-event-codes.h
.
code
is event code, for example REL_X
or KEY_BACKSPACE
, again a complete
list is in include/uapi/linux/input-event-codes.h
.
value
is the value the event carries. Either a relative change for EV_REL
,
absolute new value for EV_ABS
(joysticks ...), or 0 for EV_KEY
for
release, 1 for key-press and 2 for autorepeat.
The mouse event is much simpler, just three bytes. I'll demo this in Python instead:
import struct
f = open( "/dev/input/mice", "rb" );
# Open the file in the read-binary mode
while True:
data = f.read(3) # Reads 3 byte message at a time
print(struct.unpack('3b',data)) # Unpacks bytes to python ints - https://docs.python.org/3/library/struct.html
(8, 0, 0) # left click down
(9, 0, 0) # left click up
(8, 0, 0) # left click down again
(10, 0, 0) # right click down
When I first ran this program it failed because the open
on the /dev/input
required sudo
permissions. Therefore I started again with sudo python3
and it worked.