diff --git a/g534-sink-switcher/auto-switch-to-headphones.sh b/g534-sink-switcher/auto-switch-to-headphones.sh index 5cb2c07..47bd7a7 100755 --- a/g534-sink-switcher/auto-switch-to-headphones.sh +++ b/g534-sink-switcher/auto-switch-to-headphones.sh @@ -14,13 +14,17 @@ RAPID_WINDOW=3 # seconds # Find the G435 Consumer Control input device automatically # ================================================================= find_g435_event() { - for link in /dev/input/by-id/*G435*event*; do - if [ -e "$link" ]; then - readlink -f "$link" - return 0 + for dev in /dev/input/event*; do + event=${dev##*/} + name_file="/sys/class/input/$event/device/name" + + if [[ -r "$name_file" ]] && [[ "$(<"$name_file")" == "Logitech G series G435 Wireless Gaming Headset Consumer Control" ]]; then + echo "$dev" + break 2 fi done - return 1 + + sleep 1 } DEVICE="" @@ -53,6 +57,7 @@ up_timestamps=() exec 3< <(stdbuf -oL evtest "$DEVICE") while read -u 3 line; do + echo "$line"; # Volume UP press (115) if [[ "$line" == *"code 115 (KEY_VOLUMEUP)"*"value 1"* ]]; then now=$(date +%s) diff --git a/g534-sink-switcher/setup.sh b/g534-sink-switcher/setup.sh index 18a51a1..7d9414b 100755 --- a/g534-sink-switcher/setup.sh +++ b/g534-sink-switcher/setup.sh @@ -19,3 +19,6 @@ Environment=XDG_RUNTIME_DIR=%t [Install] WantedBy=default.target EOF + +sudo systemctl --user daemon-reload +systemctl enable --now --user g435-sink-switch.service diff --git a/setup.sh b/setup.sh index 9a89128..14dcb95 100755 --- a/setup.sh +++ b/setup.sh @@ -9,3 +9,4 @@ source ./env ./g534-sink-switcher/setup.sh ./game-runner/setup.sh ./sshfs/setup.sh kuba@192.168.1.90:/mnt/hdd /var/mnt/hdd +./xing-wei-remap/remap.sh diff --git a/xing-wei-remap/remap.py b/xing-wei-remap/remap.py new file mode 100755 index 0000000..c30b307 --- /dev/null +++ b/xing-wei-remap/remap.py @@ -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() diff --git a/xing-wei-remap/setup.sh b/xing-wei-remap/setup.sh new file mode 100755 index 0000000..63fddfe --- /dev/null +++ b/xing-wei-remap/setup.sh @@ -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 <