You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.6 KiB
Python
133 lines
3.6 KiB
Python
#!/usr/bin/python3
|
|
|
|
import time
|
|
import os
|
|
import evdev
|
|
from evdev import ecodes, UInput
|
|
|
|
DEVICE_NAME = "XING WEI 2.4G USB USB Composite Device Consumer Control"
|
|
|
|
|
|
def kodi_running():
|
|
for pid in os.listdir("/proc"):
|
|
if not pid.isdigit():
|
|
continue
|
|
|
|
try:
|
|
with open(f"/proc/{pid}/comm") as f:
|
|
if f.read().strip() in ("kodi", "kodi.bin"):
|
|
return True
|
|
except (OSError, PermissionError):
|
|
pass
|
|
|
|
return False
|
|
|
|
|
|
def find_device():
|
|
while True:
|
|
for path in evdev.list_devices():
|
|
try:
|
|
dev = evdev.InputDevice(path)
|
|
|
|
if dev.name == DEVICE_NAME:
|
|
if ecodes.KEY_BACK in dev.capabilities().get(ecodes.EV_KEY, []):
|
|
print(f"Found device: {path}", flush=True)
|
|
return dev
|
|
|
|
dev.close()
|
|
|
|
except (OSError, PermissionError):
|
|
pass
|
|
|
|
print("Waiting for device...", flush=True)
|
|
time.sleep(2)
|
|
|
|
|
|
def run():
|
|
while True:
|
|
dev = find_device()
|
|
ui = None
|
|
|
|
try:
|
|
# Create a clean virtual keyboard
|
|
ui = UInput(
|
|
events={
|
|
ecodes.EV_KEY: [
|
|
ecodes.KEY_ESC,
|
|
ecodes.KEY_BACKSPACE,
|
|
ecodes.KEY_LEFTSHIFT,
|
|
ecodes.KEY_TAB,
|
|
] + [
|
|
key for key in dev.capabilities().get(ecodes.EV_KEY, [])
|
|
if key not in (
|
|
ecodes.KEY_BACK,
|
|
ecodes.KEY_HOMEPAGE,
|
|
)
|
|
]
|
|
},
|
|
name="XING WEI Remapped Keyboard",
|
|
bustype=0x03,
|
|
vendor=0x1915,
|
|
product=0x1025,
|
|
version=0x0201
|
|
)
|
|
|
|
dev.grab()
|
|
|
|
print("Device grabbed successfully!", flush=True)
|
|
print("BACK: ESC / BACKSPACE (Kodi)", flush=True)
|
|
print("HOME: SHIFT + TAB", flush=True)
|
|
|
|
for event in dev.read_loop():
|
|
|
|
if event.type == ecodes.EV_KEY:
|
|
|
|
if event.code == ecodes.KEY_BACK:
|
|
key = (
|
|
ecodes.KEY_BACKSPACE
|
|
if kodi_running()
|
|
else ecodes.KEY_ESC
|
|
)
|
|
|
|
ui.write(ecodes.EV_KEY, key, event.value)
|
|
ui.syn()
|
|
|
|
elif event.code == ecodes.KEY_HOMEPAGE:
|
|
|
|
if event.value == 1:
|
|
ui.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 1)
|
|
ui.write(ecodes.EV_KEY, ecodes.KEY_TAB, 1)
|
|
ui.syn()
|
|
|
|
ui.write(ecodes.EV_KEY, ecodes.KEY_TAB, 0)
|
|
ui.write(ecodes.EV_KEY, ecodes.KEY_LEFTSHIFT, 0)
|
|
ui.syn()
|
|
|
|
else:
|
|
ui.write_event(event)
|
|
|
|
else:
|
|
# Ignore non-key events from the consumer-control device
|
|
pass
|
|
|
|
except (OSError, IOError) as e:
|
|
print(f"Device error: {e}", flush=True)
|
|
|
|
finally:
|
|
if dev:
|
|
try:
|
|
dev.ungrab()
|
|
except OSError:
|
|
pass
|
|
dev.close()
|
|
|
|
if ui:
|
|
ui.close()
|
|
|
|
print("Reconnecting in 2 seconds...", flush=True)
|
|
time.sleep(2)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run()
|