hedgehog/software/ RawLinuxEvents001
See here.
Floating XInputs
So that devices intended to be used as Hedgehogs don't generate normal input (i.e. if we want to use a trackball as a Hedgehog,
we don't want it to also move the mouse pointer), we can float
them. With X11 this is achieved using
the xinput
command. How this is done with Windows, Macos or Wayland is
something I don't know at present.
To list devices
$ xinput
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ SynPS/2 Synaptics TouchPad id=11 [slave pointer (2)]
⎜ ↳ TPPS/2 IBM TrackPoint id=12 [slave pointer (2)]
⎜ ↳ Kensington USB/PS2 Orbit id=14 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Sleep Button id=8 [slave keyboard (3)]
↳ Integrated Camera: Integrated C id=9 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=10 [slave keyboard (3)]
↳ ThinkPad Extra Buttons id=13 [slave keyboard (3)]
To float e.g. the KensingtonOrbit with the above, note the line
⎜ ↳ Kensington USB/PS2 Orbit id=14 [slave pointer (2)]
from which we get the id=14
and use float via
xinput float 14
and to undo this we note id=2
from the xinput
list the following
Virtual core pointer id=2 [master pointer (3)]
so to reattach we do
xinput reattach 14 2
Simple event listener
#!/usr/bin/python
import struct
import time
import sys
from glob import glob
from threading import Thread
import socket
def send_message(host,port,message):
with socket.socket(socket.AF_INET,socket.SOCK_DGRAM) as s:
s.connect(("localhost",4005))
s.send(message)
def main():
threads = {}
args = sys.argv[1:]
if len(args) > 0:
nodes = args
else:
nodes = glob("/dev/input/event*")+glob("/dev/input/mouse*")+glob("/dev/input/mice")
print(nodes)
for node in nodes:
print(node)
threads[node] = start_thread(node)
try:
for t in threads.values():
t.join()
except KeyboardInterrupt:
print("Ctrl-C")
exit(0)
def start_thread(node):
print(node)
thread = Thread(target=listen,args=(node,))
thread.start()
return thread
def listen(node):
try:
listen1(node)
except KeyboardInterrupt:
print("Ctrl-C")
exit(0)
def listen1(node):
"""
FORMAT represents the format used by linux kernel input event struct
See https://github.com/torvalds/linux/blob/v5.5-rc5/include/uapi/linux/input.h#L28
Stands for: long int, long int, unsigned short, unsigned short, unsigned int
"""
FORMAT = 'llHHI'
EVENT_SIZE = struct.calcsize(FORMAT)
#open file in binary mode
in_file = open(node, "rb")
event = in_file.read(EVENT_SIZE)
while event:
(tv_sec, tv_usec, ty, code, value) = struct.unpack(FORMAT, event)
if ty != 0 or code != 0 or value != 0:
print("%s: Event type %u, code %u, value %u at %d.%d" % \
(node, ty, code, value, tv_sec, tv_usec))
msg = "%s,%u,%u,%u@%d.%d" % (node, ty, code, value, tv_sec, tv_usec)
else:
# Events with code, type and value == 0 are "separator" events
print("===========================================")
event = in_file.read(EVENT_SIZE)
in_file.close()
if __name__ == "__main__":
main()