Friday, August 28, 2026

logitech f310 macros, shutdown, copy paste


from evdev import InputDevice, UInput, ecodes
import subprocess
import threading
import time

GAMEPAD = "/dev/input/by-id/usb-Logitech_Logitech_Dual_Action_DF5CB332-event-joystick"

device = InputDevice(GAMEPAD)

# Virtual keyboard
ui = UInput({
    ecodes.EV_KEY: [
        ecodes.KEY_LEFTCTRL,
        ecodes.KEY_C,
        ecodes.KEY_V,
    ]
}, name="Gamepad Virtual Keyboard")

button_292 = False
button_293 = False
shutdown_timer = None
lock = threading.Lock()


def ctrl_key(key):
    print(f"Sending Ctrl+{key}", flush=True)

    ui.write(ecodes.EV_KEY, ecodes.KEY_LEFTCTRL, 1)
    ui.write(ecodes.EV_KEY, key, 1)
    ui.write(ecodes.EV_KEY, key, 0)
    ui.write(ecodes.EV_KEY, ecodes.KEY_LEFTCTRL, 0)
    ui.syn()


def shutdown():
    time.sleep(1)

    with lock:
        if button_292 and button_293:
            print("\nBoth buttons held for 1 second — SHUTTING DOWN!", flush=True)
            subprocess.run(["systemctl", "poweroff"])


print(f"Gamepad: {device.name}", flush=True)
print("291 = Ctrl+C", flush=True)
print("290 = Ctrl+V", flush=True)
print("292 + 293 for 1 second = Shutdown", flush=True)
print("Waiting for input...\n", flush=True)


for event in device.read_loop():

    if event.type != ecodes.EV_KEY:
        continue

    with lock:

        # BTN_TOP = 291 -> Ctrl+C
        if event.code == 291 and event.value == 1:
            print("291: Ctrl+C", flush=True)
            ctrl_key(ecodes.KEY_C)

        # BTN_THUMB2 = 290 -> Ctrl+V
        elif event.code == 290 and event.value == 1:
            print("290: Ctrl+V", flush=True)
            ctrl_key(ecodes.KEY_V)

        # BTN_TOP2 = 292
        elif event.code == 292:
            button_292 = event.value == 1
            print(
                f"292: {'PRESSED' if button_292 else 'RELEASED'}",
                flush=True
            )

        # BTN_PINKIE = 293
        elif event.code == 293:
            button_293 = event.value == 1
            print(
                f"293: {'PRESSED' if button_293 else 'RELEASED'}",
                flush=True
            )

        # Start shutdown timer
        if button_292 and button_293 and shutdown_timer is None:
            print("Both shoulder buttons held — 1 second timer started.", flush=True)
            shutdown_timer = threading.Thread(
                target=shutdown,
                daemon=True
            )
            shutdown_timer.start()

        # Cancel shutdown
        elif not (button_292 and button_293):
            shutdown_timer = None

No comments:

Post a Comment