hedgehog/software/ RawLinuxEventsToOsc001
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.
sudo ./input_to_osc.py m:/dev/input/event16
The code
#!/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()