add consumer device relay
This commit is contained in:
parent
4a1e5090ec
commit
0c8f85b899
45
quimby-relay
45
quimby-relay
@ -179,7 +179,7 @@ modifiers = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class forwarder(object):
|
class Keyboard(object):
|
||||||
def __init__(self, dst):
|
def __init__(self, dst):
|
||||||
self.modifier_state = 0
|
self.modifier_state = 0
|
||||||
self.keys_down = set()
|
self.keys_down = set()
|
||||||
@ -187,7 +187,6 @@ class forwarder(object):
|
|||||||
|
|
||||||
def __call__(self, event):
|
def __call__(self, event):
|
||||||
if event.type != evdev.ecodes.EV_KEY:
|
if event.type != evdev.ecodes.EV_KEY:
|
||||||
print("Not a key event", event)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
data = evdev.categorize(event)
|
data = evdev.categorize(event)
|
||||||
@ -218,20 +217,51 @@ class forwarder(object):
|
|||||||
packet += [0] * (8 - len(packet))
|
packet += [0] * (8 - len(packet))
|
||||||
|
|
||||||
assert(len(packet) == 8)
|
assert(len(packet) == 8)
|
||||||
|
|
||||||
print(bytes(packet))
|
|
||||||
os.write(self.dst, 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__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description='Forward input events to a USB descriptor')
|
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('-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()
|
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]
|
src = [evdev.InputDevice(i) for i in args.input]
|
||||||
|
|
||||||
selector = selectors.DefaultSelector()
|
selector = selectors.DefaultSelector()
|
||||||
@ -244,4 +274,5 @@ if __name__ == '__main__':
|
|||||||
for key, mask in selector.select():
|
for key, mask in selector.select():
|
||||||
device = key.fileobj
|
device = key.fileobj
|
||||||
for event in device.read():
|
for event in device.read():
|
||||||
fwd(event)
|
kbd(event)
|
||||||
|
con(event)
|
||||||
|
38
quimby-setup
38
quimby-setup
@ -5,8 +5,8 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
keyboard = {
|
keyboard = {
|
||||||
'protocol': 1,
|
'protocol': 1, # keyboard
|
||||||
'subclass': 1,
|
'subclass': 1, # boot interface
|
||||||
'report_length': 8,
|
'report_length': 8,
|
||||||
'report_desc': bytes([
|
'report_desc': bytes([
|
||||||
0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
|
0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
|
||||||
@ -48,7 +48,7 @@ keyboard = {
|
|||||||
0x25, 0x65, # Logical Maximum (101)
|
0x25, 0x65, # Logical Maximum (101)
|
||||||
0x05, 0x07, # Usage Page (Kbrd/Keypad)
|
0x05, 0x07, # Usage Page (Kbrd/Keypad)
|
||||||
0x19, 0x00, # Usage Minimum (0x00)
|
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)
|
0x81, 0x00, # Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||||
|
|
||||||
0xC0, # End Collection
|
0xC0, # End Collection
|
||||||
@ -57,8 +57,8 @@ keyboard = {
|
|||||||
|
|
||||||
|
|
||||||
mouse = {
|
mouse = {
|
||||||
'protocol': 2,
|
'protocol': 2, # mouse
|
||||||
'subclass': 1,
|
'subclass': 1, # boot interface
|
||||||
'report_length': 4,
|
'report_length': 4,
|
||||||
'report_desc': bytes([
|
'report_desc': bytes([
|
||||||
0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
|
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:
|
try:
|
||||||
UDC = os.listdir('/sys/class/udc')
|
UDC = os.listdir('/sys/class/udc')
|
||||||
if len(UDC) != 1:
|
if len(UDC) != 1:
|
||||||
@ -132,6 +159,7 @@ files = {
|
|||||||
'functions': {
|
'functions': {
|
||||||
'hid.usb0': keyboard,
|
'hid.usb0': keyboard,
|
||||||
'hid.usb1': mouse,
|
'hid.usb1': mouse,
|
||||||
|
'hid.usb2': media,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,10 @@ Requires=bluetooth.service
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
|
#After=bluetooth.service
|
||||||
ExecStartPre=/usr/local/bin/quimby-setup quimby
|
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
|
ExecStop=/usr/local/bin/quimby-cleanup quimby
|
||||||
|
|
||||||
|
#[Install]
|
||||||
|
#WantedBy=bluetooth.target
|
||||||
|
Loading…
Reference in New Issue
Block a user