Skip to content

Commit

Permalink
Merge pull request batocera-linux#12683 from batocera-linux/hotkeygen…
Browse files Browse the repository at this point in the history
…commands

hotkeygen: add command keys. still need a way to add custom commands …
  • Loading branch information
nadenislamarre authored Oct 17, 2024
2 parents e885782 + da2f2c9 commit aec6055
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEUP 2 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_VOLUMEDOWN 2 batocera-audio setSystemVolume -5
KEY_MUTE 1 batocera-audio setSystemVolume mute-toggle
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
KEY_F2 1 /usr/bin/batocera-info --short | LANG=en_US HOME=/userdata/system XAUTHORITY=/var/lib/.Xauthority DISPLAY=:0.0 osd_cat -f -*-*-bold-*-*-*-38-120-*-*-*-*-*-* -cred -s 3 -d 4
KEY_F10+KEY_LEFTCTRL+KEY_LEFTALT 1 /etc/init.d/S31emulationstation stop
KEY_F11+KEY_LEFTCTRL+KEY_LEFTALT 1 chvt 1
KEY_LEFTMETA 1 batocera-brightness cycle
KEY_SYSRQ 1 batocera-screenshot
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEUP 2 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_VOLUMEDOWN 2 batocera-audio setSystemVolume -5
KEY_MUTE 1 batocera-audio setSystemVolume mute-toogle
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEUP 2 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_VOLUMEDOWN 2 batocera-audio setSystemVolume -5
KEY_MUTE 1 batocera-audio setSystemVolume mute-toogle
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEUP 2 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_VOLUMEDOWN 2 batocera-audio setSystemVolume -5
KEY_MUTE 1 batocera-audio setSystemVolume mute-toogle
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ BTN_TRIGGER_HAPPY2 1 batocera-audio setSystemVolume -5
BTN_TRIGGER_HAPPY3 1 batocera-audio setSystemVolume +5
BTN_TRIGGER_HAPPY4 1 batocera-brightness - 5
BTN_TRIGGER_HAPPY5 1 batocera-brightness + 5
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEUP 2 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_VOLUMEDOWN 2 batocera-audio setSystemVolume -5
KEY_MUTE 1 batocera-audio setSystemVolume mute-toogle
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
BTN_TRIGGER_HAPPY3 1 batocera-brightness - 5
BTN_TRIGGER_HAPPY4 1 batocera-brightness + 5
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ BTN_TRIGGER_HAPPY2 1 batocera-audio setSystemVolume -5
BTN_TRIGGER_HAPPY3 1 batocera-audio setSystemVolume +5
BTN_TRIGGER_HAPPY4 1 batocera-brightness - 5
BTN_TRIGGER_HAPPY5 1 batocera-brightness + 5
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEUP 2 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_VOLUMEDOWN 2 batocera-audio setSystemVolume -5
KEY_MUTE 1 batocera-audio setSystemVolume mute-toogle
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ BTN_TRIGGER_HAPPY2 1 batocera-audio setSystemVolume -5
BTN_TRIGGER_HAPPY3 1 batocera-audio setSystemVolume +5
BTN_TRIGGER_HAPPY4 1 batocera-brightness - 5
BTN_TRIGGER_HAPPY5 1 batocera-brightness + 5
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEUP 2 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_VOLUMEDOWN 2 batocera-audio setSystemVolume -5
KEY_MUTE 1 batocera-audio setSystemVolume mute-toogle
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
BTN_TRIGGER_HAPPY3 1 batocera-brightness - 5
BTN_TRIGGER_HAPPY4 1 batocera-brightness + 5
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEUP 2 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_VOLUMEDOWN 2 batocera-audio setSystemVolume -5
KEY_MUTE 1 batocera-audio setSystemVolume mute-toogle
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEUP 2 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_VOLUMEDOWN 2 batocera-audio setSystemVolume -5
KEY_MUTE 1 batocera-audio setSystemVolume mute-toggle
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
KEY_RIGHTCTRL 1 /usr/bin/batocera-info --short | LANG=en_US HOME=/userdata/system XAUTHORITY=/var/lib/.Xauthority DISPLAY=:0.0 osd_cat -f -*-*-bold-*-*-*-38-120-*-*-*-*-*-* -cred -s 3 -d 4
KEY_F10+KEY_LEFTCTRL+KEY_LEFTALT 1 /etc/init.d/S31emulationstation stop
KEY_F11+KEY_LEFTCTRL+KEY_LEFTALT 1 chvt 1
KEY_LEFTMETA 1 batocera-brightness cycle
KEY_SYSRQ 1 batocera-screenshot
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
KEY_VOLUMEUP 1 batocera-audio setSystemVolume +5
KEY_VOLUMEUP 2 batocera-audio setSystemVolume +5
KEY_VOLUMEDOWN 1 batocera-audio setSystemVolume -5
KEY_VOLUMEDOWN 2 batocera-audio setSystemVolume -5
KEY_MUTE 1 batocera-audio setSystemVolume mute-toggle
KEY_POWER 1 batocera-shutdown 1
KEY_POWER 0 batocera-shutdown 0
# display some information on X displays
KEY_F2 1 /usr/bin/batocera-info --short | LANG=en_US HOME=/userdata/system XAUTHORITY=/var/lib/.Xauthority DISPLAY=:0.0 osd_cat -f -*-*-bold-*-*-*-38-120-*-*-*-*-*-* -cred -s 3 -d 4
KEY_F10+KEY_LEFTCTRL+KEY_LEFTALT 1 /etc/init.d/S31emulationstation stop
KEY_F11+KEY_LEFTCTRL+KEY_LEFTALT 1 chvt 1
KEY_LEFTMETA 1 batocera-brightness cycle
KEY_SYSRQ 1 batocera-screenshot
BTN_MODE 1 /usr/bin/batocera-info --short | LANG=en_US HOME=/userdata/system XAUTHORITY=/var/lib/.Xauthority DISPLAY=:0.0 osd_cat -f -*-*-bold-*-*-*-38-120-*-*-*-*-*-* -cred -s 3 -d 4
SW_HEADPHONE_INSERT 1 /usr/bin/batocera-audio set-profile output:stereo-fallback@alsa_card.pci-0000_04_00.5-platform-acp5x_mach.0
SW_HEADPHONE_INSERT 0 /usr/bin/batocera-audio set-profile pro-audio@alsa_card.pci-0000_04_00.5-platform-acp5x_mach.0
83 changes: 57 additions & 26 deletions package/batocera/utils/hotkeygen/hotkeygen.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

class HotkeysContext(TypedDict):
name: str
keys: dict[str, list[int] | int]
keys: dict[str, list[int] | int | str]


class JsonHotkeysContext(TypedDict):
Expand All @@ -45,7 +45,7 @@ class JsonHotkeysContext(TypedDict):
}

KNOWN_ACTIONS: Final = {
"exit", "coin", "menu", "pause", "files", "save_state", "restore_state", "next_slot", "previous_slot", "screenshot"
"exit", "coin", "menu", "pause", "files", "save_state", "restore_state", "next_slot", "previous_slot", "screenshot", "volumeup", "volumedown", "volumemute", "brightness-cycle"
}

# default context is for es
Expand All @@ -59,19 +59,31 @@ def get_default_context() -> HotkeysContext:
}
}

def get_common_context_keys() -> dict[str, int|str]:
return {
"screenshot": "batocera-screenshot",
"volumeup": "batocera-audio setSystemVolume +5",
"volumedown": "batocera-audio setSystemVolume -5",
"volumemute": "batocera-audio setSystemVolume mute-toggle",
"brightness-cycle": "batocera-brightness cycle"
}

def get_context() -> HotkeysContext | None:
if GCONTEXT_FILE.exists():
try:
if gdebug:
print(f"using default context {GCONTEXT_FILE}")
with GCONTEXT_FILE.open() as file:
data = json.load(file)
return load_context(data)
context = load_context(data)
context["keys"] |= get_common_context_keys()
return context
except Exception as e:
print(f"fail to load context file : {e}")
return None
else:
context = get_default_context()
context["keys"] |= get_common_context_keys()
if gdebug:
print("using default context")
print_context(context)
Expand All @@ -95,10 +107,15 @@ def load_context(data: JsonHotkeysContext) -> HotkeysContext:
else:
raise Exception(f"invalid key {x!r}")
else:
if key_code_names in ecodes.ecodes:
context["keys"][action] = ecodes.ecodes[key_code_names]
# string are key if starting by KEY_ else commands (maybe not the best choice, but simple)
if key_code_names[:4] == "KEY_":
if key_code_names in ecodes.ecodes:
context["keys"][action] = ecodes.ecodes[key_code_names]
else:
raise Exception(f"invalid key {data['keys'][action]!r}")
else:
raise Exception(f"invalid key {data['keys'][action]!r}")
# command
context["keys"][action] = key_code_names
else:
raise Exception(f"invalid entry '{action}'")

Expand All @@ -111,6 +128,8 @@ def save_context(context: HotkeysContext, gcontext_file: Path) -> None:
for action, key_codes in context["keys"].items():
if isinstance(key_codes, list):
save["keys"][action] = [ECODES_NAMES[key] for key in key_codes]
elif isinstance(key_codes, str):
save["keys"][action] = key_codes
else:
save["keys"][action] = ECODES_NAMES[key_codes]

Expand All @@ -121,9 +140,11 @@ def print_context(context: HotkeysContext) -> None:
print(f"Context [{context['name']}]:")
for action, keys in context["keys"].items():
if isinstance(keys, list):
print(f" {action:-<15}-> {[ECODES_NAMES[key] for key in keys]}")
print(f" {action:-<20}-> {[ECODES_NAMES[key] for key in keys]}")
elif isinstance(keys, str):
print(f" {action:-<20}-> command [{keys}]")
else:
print(f" {action:-<15}-> {ECODES_NAMES[keys]}")
print(f" {action:-<20}-> {ECODES_NAMES[keys]}")

def get_device_config_filename(device: evdev.InputDevice) -> str:
name = re.sub('[^a-zA-Z0-9_]', '', device.name.replace(' ', '_'))
Expand Down Expand Up @@ -152,16 +173,20 @@ def get_mapping(device: evdev.InputDevice) -> dict[int, str]:
else:
# default for all inputs
return {
ecodes.KEY_EXIT: "exit",
ecodes.KEY_EURO: "coin",
ecodes.KEY_MENU: "menu",
ecodes.KEY_PAUSE: "pause",
ecodes.KEY_FILE: "files",
ecodes.KEY_SAVE: "save_state",
ecodes.KEY_SEND: "restore_state",
ecodes.KEY_NEXT: "next_slot",
ecodes.KEY_PREVIOUS: "previous_slot",
ecodes.KEY_SCREEN: "screenshot"
ecodes.KEY_EXIT: "exit",
ecodes.KEY_EURO: "coin",
ecodes.KEY_MENU: "menu",
ecodes.KEY_PAUSE: "pause",
ecodes.KEY_FILE: "files",
ecodes.KEY_SAVE: "save_state",
ecodes.KEY_SEND: "restore_state",
ecodes.KEY_NEXT: "next_slot",
ecodes.KEY_PREVIOUS: "previous_slot",
ecodes.KEY_SYSRQ: "screenshot",
ecodes.KEY_VOLUMEUP: "volumeup",
ecodes.KEY_VOLUMEDOWN: "volumedown",
ecodes.KEY_MUTE: "volumemute",
ecodes.KEY_BRIGHTNESS_CYCLE: "brightness-cycle"
}

def load_mapping(data: dict[str, str]) -> dict[int, str]:
Expand Down Expand Up @@ -205,7 +230,7 @@ def print_mapping(
print(f" {ECODES_NAMES[k]:-<15}-> {associations[k]:15}")


def send_keys(target: evdev.UInput, keys: int | list[int]) -> None:
def send_keys(target: evdev.UInput, keys: int | list[int] | str) -> None:
if isinstance(keys, list):
for x in keys:
target.write(ecodes.EV_KEY, x, 1)
Expand All @@ -225,7 +250,6 @@ def send_keys(target: evdev.UInput, keys: int | list[int]) -> None:
target.write(ecodes.EV_KEY, keys, 0)
target.syn()


def do_send(key: str) -> None:
if key not in KNOWN_ACTIONS:
print(f"unknown action {KNOWN_ACTIONS}")
Expand All @@ -235,12 +259,15 @@ def do_send(key: str) -> None:
sender_keys: list[int] = []
if context is not None and key in context["keys"]:
keys = context["keys"][key]
if isinstance(keys, list):
sender_keys.extend(keys)
if isinstance(keys, str):
os.system(keys)
else:
sender_keys.append(keys)
sender = evdev.UInput(name="virtual keyboard", events={ ecodes.EV_KEY: sender_keys })
send_keys(sender, sender_keys)
if isinstance(keys, list):
sender_keys.extend(keys)
else:
sender_keys.append(keys)
sender = evdev.UInput(name="virtual keyboard", events={ ecodes.EV_KEY: sender_keys })
send_keys(sender, sender_keys)

def read_pid() -> str:
with GPID_FILE.open() as fd:
Expand Down Expand Up @@ -350,9 +377,13 @@ def __handle_actions(self, action: str, device: pyudev.Device) -> None:

def __handle_event(self, event: evdev.InputEvent, action: str) -> None:
if self.context is not None and action in self.context["keys"]:
keys = self.context["keys"][action]
if gdebug:
print(f"code:{event.code}, value:{event.value}, action:{action}")
send_keys(self.target, self.context["keys"][action])
if isinstance(keys, str):
os.system(keys)
else:
send_keys(self.target, keys)

def __write_pid(self) -> None:
with GPID_FILE.open("w") as fd:
Expand Down

0 comments on commit aec6055

Please sign in to comment.