From 4a1e5090ecbf0bb4003b658d40278afe79a2172f Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Sat, 9 Mar 2019 11:12:29 +1100 Subject: [PATCH] relay: allow for multiple input devices --- quimby-relay | 68 ++++++++++++++++++++++------------- systemd/system/quimby.service | 2 +- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/quimby-relay b/quimby-relay index 0e29ca0..a48372e 100755 --- a/quimby-relay +++ b/quimby-relay @@ -4,6 +4,7 @@ import evdev import argparse import os import sys +import selectors scan_to_hid = { # Reserved: 0 @@ -178,52 +179,69 @@ modifiers = { } +class forwarder(object): + def __init__(self, dst): + self.modifier_state = 0 + self.keys_down = set() + self.dst = dst -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Forward input events to a USB descriptor') - parser.add_argument('input', type=str, help='The source evdev device') - parser.add_argument('output', type=str, help='The output HID device') - - args = parser.parse_args() - - dst = os.open(args.output, os.O_WRONLY) - src = evdev.InputDevice(args.input) - src.grab() - - modifier_state = 0 - keys_down = set() - - for event in src.read_loop(): + def __call__(self, event): if event.type != evdev.ecodes.EV_KEY: - continue + print("Not a key event", event) + return data = evdev.categorize(event) modifier = modifiers.get(data.scancode, None) if modifier: if data.keystate == data.key_down: - modifier_state |= modifier + self.modifier_state |= modifier if data.keystate == data.key_up: - modifier_state &= ~modifier + self.modifier_state &= ~modifier else: code = scan_to_hid.get(data.scancode, None) if code is None: print("Ignoring unknown key", data) - continue + return if data.keystate == data.key_down: - if len(keys_down) >= 6: + if len(self.keys_down) >= 6: print("Ignoring key due to rollover") - continue - keys_down.add(code) + return + self.keys_down.add(code) if data.keystate == data.key_up: - keys_down.remove(code) + self.keys_down.remove(code) # Build the packet - packet = [modifier_state, 0] + [k for k in keys_down] + packet = [self.modifier_state, 0] + [k for k in self.keys_down] packet += [0] * (8 - len(packet)) assert(len(packet) == 8) - os.write(dst, bytes(packet)) + print(bytes(packet)) + os.write(self.dst, bytes(packet)) + + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Forward input events to a USB descriptor') + parser.add_argument('-i', '--input', type=str, action='append', help='A source evdev device') + parser.add_argument('-o', '--output', type=str, help='The output HID device') + + args = parser.parse_args() + + fwd = forwarder(os.open(args.output, os.O_WRONLY)) + src = [evdev.InputDevice(i) for i in args.input] + + selector = selectors.DefaultSelector() + for i in src: + i.grab() + selector.register(i, selectors.EVENT_READ) + + print("Waiting for events") + while True: + for key, mask in selector.select(): + device = key.fileobj + for event in device.read(): + fwd(event) diff --git a/systemd/system/quimby.service b/systemd/system/quimby.service index 0d4f5a9..9db745c 100644 --- a/systemd/system/quimby.service +++ b/systemd/system/quimby.service @@ -5,6 +5,6 @@ Requires=bluetooth.service [Service] Type=simple ExecStartPre=/usr/local/bin/quimby-setup quimby -ExecStart=/usr/local/bin/quimby-relay /dev/input/event0 /dev/hidg0 +ExecStart=/usr/local/bin/quimby-relay --input /dev/input/event0 --output /dev/hidg0 ExecStop=/usr/local/bin/quimby-cleanup quimby