## Trackball/Mouse This needs to be run as root. Arguments are of the form `t:/dev/input/eventXX` where `t` is either `k` for keyboard or `m` for mouse. e.g. ```bash sudo ./input_to_osc.py m:/dev/input/event16 ``` The code ```python #!/usr/bin/env python import struct import time import sys import os from glob import glob from threading import Thread from pythonosc import udp_client # python -m pip install python-osc 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) class InputToOsc: def __init__(self,host,port,inputdev): self.host = host self.port = port self.inputdev = inputdev self.client = udp_client.SimpleUDPClient(host,port) self.thread = None def start(self): self.thread = Thread(target=self.listen0,args=()) self.thread.start() def listen0(self): try: self.listen1() except KeyboardInterrupt: print("Ctrl-C") exit(0) def listen1(self): FORMAT = 'llHHI' EVENT_SIZE = struct.calcsize(FORMAT) #open file in binary mode try: in_file = open(self.inputdev, "rb") except PermissionError: print(f"Permission error with: {self.inputdev} (do we need to run as root?)") exit(1) 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: self.handle(ty,code,value,tv_sec,tv_usec) else: self.sep() event = in_file.read(EVENT_SIZE) in_file.close() def sep(self): print("===========================================") def send(self,addr,args): self.client.send_message(addr,args) def handle(self,ty,code,value,tv_sec,tv_usec): print(f"Input event from {self.inputdev}: type={ty} {code=} {value=} {tv_sec=} {tv_usec=}") class KeyboardToOsc(InputToOsc): def handle(self,ty,code,value,tv_sec,tv_usec): print(f"Keyboard input event from {self.inputdev}: type={ty} {code=} {value=} {tv_sec=} {tv_usec=}") class MouseToOsc(InputToOsc): def handle(self,ty,code,value,tv_sec,tv_usec): print(f"Mouse input event from {self.inputdev}: type={ty} {code=} {value=} {tv_sec=} {tv_usec=}") if ty == 2: if value >= 2**31: value -= 2**32 # uint to int self.send(f"/hh/a/mouse/0/axis/{code}/dx",(value,)) type_to_class = { "k": KeyboardToOsc, "m": MouseToOsc } def main(): listeners = {} host = os.getenv('host','turnipland') port = int(os.getenv('port',4567)) args = sys.argv[1:] nodes = {} for arg in args: t,n = arg.split(":",1) nodes[n] = t for n,t in nodes.items(): if not t in type_to_class: print(f"Unknown input type: {t}") exit(1) c = type_to_class[t] x = c(host,port,n) listeners[n] = x x.start() if __name__ == "__main__": main() ```