diff --git a/quimby-relay b/quimby-relay index a48372e..1bdaa81 100755 --- a/quimby-relay +++ b/quimby-relay @@ -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) diff --git a/quimby-setup b/quimby-setup index 4341bd9..42ce553 100755 --- a/quimby-setup +++ b/quimby-setup @@ -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, } } diff --git a/systemd/system/quimby.service b/systemd/system/quimby.service index 9db745c..f211107 100644 --- a/systemd/system/quimby.service +++ b/systemd/system/quimby.service @@ -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