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

#!/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()