add consumer device relay

This commit is contained in:
Danny Robson 2019-03-09 14:58:15 +11:00
parent 4a1e5090ec
commit 0c8f85b899
3 changed files with 75 additions and 13 deletions

View File

@ -179,7 +179,7 @@ modifiers = {
}
class forwarder(object):
class Keyboard(object):
def __init__(self, dst):
self.modifier_state = 0
self.keys_down = set()
@ -187,7 +187,6 @@ class forwarder(object):
def __call__(self, event):
if event.type != evdev.ecodes.EV_KEY:
print("Not a key event", event)
return
data = evdev.categorize(event)
@ -218,20 +217,51 @@ class forwarder(object):
packet += [0] * (8 - len(packet))
assert(len(packet) == 8)
print(bytes(packet))
os.write(self.dst, bytes(packet))
class Consumer(object):
BITS = {
evdev.ecodes.KEY_NEXTSONG: (1 << 0),
evdev.ecodes.KEY_PREVIOUSSONG: (1 << 1),
# STOP key: 2
# EJECT key: 3
evdev.ecodes.KEY_PLAYPAUSE: (1 << 4),
evdev.ecodes.KEY_MUTE: (1 << 5),
evdev.ecodes.KEY_MUTE: (1 << 5),
evdev.ecodes.KEY_VOLUMEUP: (1 << 6),
evdev.ecodes.KEY_VOLUMEDOWN: (1 << 7),
}
def __init__(self, dst):
self.state = 0
self.dst = dst
def __call__(self, event):
if event.type != evdev.ecodes.EV_KEY:
return
data = evdev.categorize(event)
bit = self.BITS.get(data.scancode, None)
if bit is None:
return
self.state ^= bit
payload=bytes([self.state])
os.write(self.dst, payload)
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')
parser.add_argument('-k', '--keyboard', type=str, help='The keyboard output HID device')
parser.add_argument('-m', '--mouse', type=str, help='The mouse output HID device')
parser.add_argument('-c', '--consumer', type=str, help='The consumer output HID device')
args = parser.parse_args()
fwd = forwarder(os.open(args.output, os.O_WRONLY))
kbd = Keyboard(os.open(args.keyboard, os.O_WRONLY))
con = Consumer(os.open(args.consumer, os.O_WRONLY))
src = [evdev.InputDevice(i) for i in args.input]
selector = selectors.DefaultSelector()
@ -244,4 +274,5 @@ if __name__ == '__main__':
for key, mask in selector.select():
device = key.fileobj
for event in device.read():
fwd(event)
kbd(event)
con(event)

View File

@ -5,8 +5,8 @@ import os
import sys
keyboard = {
'protocol': 1,
'subclass': 1,
'protocol': 1, # keyboard
'subclass': 1, # boot interface
'report_length': 8,
'report_desc': bytes([
0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
@ -48,7 +48,7 @@ keyboard = {
0x25, 0x65, # Logical Maximum (101)
0x05, 0x07, # Usage Page (Kbrd/Keypad)
0x19, 0x00, # Usage Minimum (0x00)
0x29, 0x65, # Usage Maximum (0x65)
0x29, 0x9a, # Usage Maximum (0x9a)
0x81, 0x00, # Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, # End Collection
@ -57,8 +57,8 @@ keyboard = {
mouse = {
'protocol': 2,
'subclass': 1,
'protocol': 2, # mouse
'subclass': 1, # boot interface
'report_length': 4,
'report_desc': bytes([
0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
@ -92,6 +92,33 @@ mouse = {
}
media = {
'protocol': 1, # Keyboard
'subclass': 0, # None
'report_length': 1,
'report_desc': bytes([
0x05, 0x0C, # Usage Page (Consumer)
0x09, 0x01, # Usage (Consumer Control)
0xA1, 0x01, # Collection (Application)
0x05, 0x0C, # Usage Page (Consumer)
0x15, 0x00, # Logical Minimum (0)
0x25, 0x01, # Logical Maximum (1)
0x75, 0x01, # Report Size (1)
0x95, 0x08, # Report Count (8)
0x09, 0xB5, # Usage (Scan Next Track)
0x09, 0xB6, # Usage (Scan Previous Track)
0x09, 0xB7, # Usage (Stop)
0x09, 0xB8, # Usage (Eject)
0x09, 0xCD, # Usage (Play/Pause)
0x09, 0xE2, # Usage (Mute)
0x09, 0xE9, # Usage (Volume Increment)
0x09, 0xEA, # Usage (Volume Decrement)
0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, # End Collection
])
}
try:
UDC = os.listdir('/sys/class/udc')
if len(UDC) != 1:
@ -132,6 +159,7 @@ files = {
'functions': {
'hid.usb0': keyboard,
'hid.usb1': mouse,
'hid.usb2': media,
}
}

View File

@ -4,7 +4,10 @@ Requires=bluetooth.service
[Service]
Type=simple
#After=bluetooth.service
ExecStartPre=/usr/local/bin/quimby-setup quimby
ExecStart=/usr/local/bin/quimby-relay --input /dev/input/event0 --output /dev/hidg0
ExecStart=/usr/local/bin/quimby-relay --input /dev/input/event0 --input /dev/input/event1 --keyboard /dev/hidg0 --consumer /dev/hidg2
ExecStop=/usr/local/bin/quimby-cleanup quimby
#[Install]
#WantedBy=bluetooth.target