relay: allow for multiple input devices

This commit is contained in:
Danny Robson 2019-03-09 11:12:29 +11:00
parent 7ec912fe9f
commit 4a1e5090ec
2 changed files with 44 additions and 26 deletions

View File

@ -4,6 +4,7 @@ import evdev
import argparse import argparse
import os import os
import sys import sys
import selectors
scan_to_hid = { scan_to_hid = {
# Reserved: 0 # 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__': def __call__(self, event):
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():
if event.type != evdev.ecodes.EV_KEY: if event.type != evdev.ecodes.EV_KEY:
continue print("Not a key event", event)
return
data = evdev.categorize(event) data = evdev.categorize(event)
modifier = modifiers.get(data.scancode, None) modifier = modifiers.get(data.scancode, None)
if modifier: if modifier:
if data.keystate == data.key_down: if data.keystate == data.key_down:
modifier_state |= modifier self.modifier_state |= modifier
if data.keystate == data.key_up: if data.keystate == data.key_up:
modifier_state &= ~modifier self.modifier_state &= ~modifier
else: else:
code = scan_to_hid.get(data.scancode, None) code = scan_to_hid.get(data.scancode, None)
if code is None: if code is None:
print("Ignoring unknown key", data) print("Ignoring unknown key", data)
continue return
if data.keystate == data.key_down: if data.keystate == data.key_down:
if len(keys_down) >= 6: if len(self.keys_down) >= 6:
print("Ignoring key due to rollover") print("Ignoring key due to rollover")
continue return
keys_down.add(code) self.keys_down.add(code)
if data.keystate == data.key_up: if data.keystate == data.key_up:
keys_down.remove(code) self.keys_down.remove(code)
# Build the packet # 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)) packet += [0] * (8 - len(packet))
assert(len(packet) == 8) 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)

View File

@ -5,6 +5,6 @@ Requires=bluetooth.service
[Service] [Service]
Type=simple Type=simple
ExecStartPre=/usr/local/bin/quimby-setup quimby 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 ExecStop=/usr/local/bin/quimby-cleanup quimby