See [here](/aw/os/linux/RawInput). RawLinuxEventsToOsc001 ## 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](/aw/os/x11) this is achieved using the `xinput` command. How this is done with [Windows](/aw/os/windows), [Macos](/aw/os/macos) or [Wayland](/aw/os/wayland) is something I don't know at present. To list devices ```plaintext $ 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 ```plaintext ⎜ ↳ Kensington USB/PS2 Orbit id=14 [slave pointer (2)] ``` from which we get the `id=14` and use **float** via ```bash xinput float 14 ``` and to undo this we note `id=2` from the `xinput` list the following ```plaintext Virtual core pointer id=2 [master pointer (3)] ``` so to **reattach** we do ```bash xinput reattach 14 2 ``` ## Simple event listener ```python #!/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() ```