Checkpoint
parent
fe4cd8835b
commit
1d5f74d2c0
@ -0,0 +1,132 @@
|
||||
#!/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()
|
||||
@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
echo $SCRIPT_DIR
|
||||
|
||||
sudo tee /etc/systemd/system/xing-wei-remap.service <<EOF
|
||||
[Unit]
|
||||
Description=XING WEI USB KEY_BACK to KEY_ESC Remapper
|
||||
After=systemd-modules-load.service
|
||||
Wants=systemd-modules-load.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/python3 $SCRIPT_DIR/remap.py
|
||||
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
|
||||
User=root
|
||||
|
||||
# Allow access to input and uinput devices
|
||||
PrivateDevices=no
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
sudo systemctl enable --now xing-wei-remap.service
|
||||
|
||||
echo "done"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue