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.

128 lines
3.2 KiB
Python

#!/usr/bin/env python3
import socket
import json
from evdev import UInput, ecodes as e
# Capabilities for both gamepad and keyboard
capabilities = {
e.EV_KEY: [
e.BTN_A, e.BTN_B, e.BTN_START,
e.BTN_DPAD_UP, e.BTN_DPAD_DOWN, e.BTN_DPAD_LEFT, e.BTN_DPAD_RIGHT,
e.KEY_LEFTCTRL, e.KEY_1
]
}
# Mapping CEC keys to gamepad buttons or keyboard keys
key_map = {
'SELECT': e.BTN_A,
'EXIT': e.BTN_B,
'PLAY': e.BTN_START,
'PAUSE': e.BTN_START,
'UP': e.BTN_DPAD_UP,
'DOWN': e.BTN_DPAD_DOWN,
'LEFT': e.BTN_DPAD_LEFT,
'RIGHT': e.BTN_DPAD_RIGHT
# 'CLEAR' handled separately
}
import time
from evdev import InputDevice, ecodes, list_devices, UInput
# Define key codes for Ctrl and 1
SHIFT = ecodes.KEY_LEFTSHIFT
TAB = ecodes.KEY_TAB
# Define virtual keyboard capabilities (DO NOT include EV_SYN)
keyboard_events = {
ecodes.EV_KEY: [SHIFT,TAB],
}
# Create the virtual input device
keyboard_ui = UInput(events=keyboard_events, name="Virtual Ctrl+1 Injector", bustype=ecodes.BUS_USB)
def home():
print("Sending shift+home")
keyboard_ui.write(ecodes.EV_KEY, SHIFT, 1) # Press Ctrl
keyboard_ui.write(ecodes.EV_KEY, TAB, 1) # Press 1
keyboard_ui.syn()
time.sleep(0.1)
keyboard_ui.write(ecodes.EV_KEY, SHIFT, 0) # Release 1
keyboard_ui.write(ecodes.EV_KEY, TAB, 0) # Release Ctrl
keyboard_ui.syn()
last_pressed = None # Track last key to release
def create_virtual_device():
return UInput(capabilities, name='CEC Virtual Input', bustype=e.BUS_USB)
def handle_press(ui, key):
global last_pressed
if key == 'CLEAR':
home()
return
code = key_map.get(key)
if not code:
print(f"Unknown key: {key}")
return
if code == last_pressed:
return
handle_release(ui)
ui.write(e.EV_KEY, code, 1)
ui.syn()
last_pressed = code
print(f"Pressed {key} ({code})")
def handle_release(ui):
global last_pressed
if last_pressed is None:
return
if isinstance(last_pressed, tuple):
# Release both Ctrl and 1
for code in last_pressed:
ui.write(e.EV_KEY, code, 0)
print("Released Ctrl+1")
else:
ui.write(e.EV_KEY, last_pressed, 0)
print(f"Released {last_pressed}")
ui.syn()
last_pressed = None
def start_udp_listener():
ui = create_virtual_device()
print("Virtual input device ready")
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('0.0.0.0', 41234))
print("Listening for UDP input...")
while True:
data, _ = sock.recvfrom(1024)
try:
print("new payload")
payload = json.loads(data.decode())
if payload['type'] == 'key':
event_type = payload.get('event')
key_name = payload.get('key', '').upper()
if event_type == 'press':
handle_press(ui, key_name)
elif event_type == 'release':
handle_release(ui)
except Exception as ex:
print(f"Error: {ex}")
if __name__ == "__main__":
try:
start_udp_listener()
except KeyboardInterrupt:
print("Shutting down...")