#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2021-22 pkegg
# Copyright (C) 2022-24 JELOS (https://github.com/JustEnoughLinuxOS)
# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R)

. /etc/profile

# Remove or comment out 'set -e' so the script doesn't exit on a single error:
# set -e
set -o pipefail

### Summary
#   This script listens to input events and takes actions.
###

### Enable logging
case $(get_setting system.loglevel) in
  verbose)
    DEBUG=true
  ;;
  *)
    DEBUG=false
  ;;
esac

### Define matching values from evtest, but allow them to be overridden in system.cfg.
KEY_VOLUME_UP=$(get_setting key.volume.up)
[ -z "${KEY_VOLUME_UP}" ] && KEY_VOLUME_UP='KEY_VOLUME*UP'

KEY_VOLUME_DOWN=$(get_setting key.volume.down)
[ -z "${KEY_VOLUME_DOWN}" ] && KEY_VOLUME_DOWN='KEY_VOLUME*DOWN'

FUNCTION_VOLUME_UP_EVENT='*('${KEY_VOLUME_UP}'), value *'
FUNCTION_VOLUME_DOWN_EVENT='*('${KEY_VOLUME_DOWN}'), value *'

FUNCTION_POWER_RELEASED_EVENT='*(KEY_POWER), value 0'
FUNCTION_POWER_PRESSED_EVENT='*(KEY_POWER), value 1'

FUNCTION_LID_OPEN_EVENT='*(SW_LID), value 0'
FUNCTION_LID_CLOSE_EVENT='*(SW_LID), value 1'

### Define matching function hotkeys from controller values, but allow them to be overridden in system.cfg.
KEYA_MODIFIER=$(get_setting key.function.a)
[ -z "${KEYA_MODIFIER}" ] && KEYA_MODIFIER="${DEVICE_FUNC_KEYA_MODIFIER}"

KEYB_MODIFIER=$(get_setting key.function.b)
[ -z "${KEYB_MODIFIER}" ] && KEYB_MODIFIER="${DEVICE_FUNC_KEYB_MODIFIER}"

FUNCTION_MODIFIER_A_EVENT='*('${KEYA_MODIFIER}'), value *'
FUNCTION_MODIFIER_B_EVENT='*('${KEYB_MODIFIER}'), value *'

BTN_HOTKEY_A_MODIFIER=$(get_setting key.hotkey.a)
[ -z "${BTN_HOTKEY_A_MODIFIER}" ] && BTN_HOTKEY_A_MODIFIER="BTN_TL"

BTN_HOTKEY_B_MODIFIER=$(get_setting key.hotkey.b)
[ -z "${BTN_HOTKEY_B_MODIFIER}" ] && BTN_HOTKEY_B_MODIFIER="BTN_SELECT"

BTN_HOTKEY_C_MODIFIER=$(get_setting key.hotkey.c)
[ -z "${BTN_HOTKEY_C_MODIFIER}" ] && BTN_HOTKEY_C_MODIFIER="BTN_START"

HOTKEY_A_PRESSED=false
HOTKEY_B_PRESSED=false
HOTKEY_C_PRESSED=false

FUNCTION_HOTKEY_A_EVENT='*('${BTN_HOTKEY_A_MODIFIER}'), value *'
FUNCTION_HOTKEY_B_EVENT='*('${BTN_HOTKEY_B_MODIFIER}'), value *'
FUNCTION_HOTKEY_C_EVENT='*('${BTN_HOTKEY_C_MODIFIER}'), value *'

FUNCTION_HOTKEY_BTN_NORTH_EVENT="*(BTN_NORTH), value 1*"
FUNCTION_HOTKEY_BTN_SOUTH_EVENT="*(BTN_SOUTH), value 1*"
FUNCTION_HOTKEY_BTN_WEST_EVENT="*(BTN_WEST), value 1*"
FUNCTION_HOTKEY_BTN_EAST_EVENT="*(BTN_EAST), value 1*"
FUNCTION_HOTKEY_BTN_BACK_EVENT="*(BTN_BACK), value 1*"
FUNCTION_HOTKEY_KEY_RECORD_EVENT="*(KEY_RECORD), value 1*"

FUNCTION_HOTKEY_TOUCH_EVENT="*(BTN_TOUCH), value 1*"

TOUCHSCREEN_EVENTS=$(get_setting key.touchscreen.events)
if [ -z "${TOUCHSCREEN_EVENTS}" ] || [ "${TOUCHSCREEN_EVENTS}" = "0" ]; then
  TOUCHSCREEN_EVENTS=false
else
  TOUCHSCREEN_EVENTS=true
fi

### Define static values for dpad buttons and as a hat.
FUNCTION_HOTKEY_DPAD_UP_EVENT="*(BTN_DPAD_UP), value 1*"
FUNCTION_HOTKEY_DPAD_DOWN_EVENT="*(BTN_DPAD_DOWN), value 1*"
FUNCTION_HOTKEY_DPAD_RIGHT_EVENT="*(BTN_DPAD_RIGHT), value 1*"
FUNCTION_HOTKEY_DPAD_LEFT_EVENT="*(BTN_DPAD_LEFT), value 1*"

FUNCTION_HOTKEY_HAT_UP_EVENT="*(ABS_HAT0Y), value -1*"
FUNCTION_HOTKEY_HAT_DOWN_EVENT="*(ABS_HAT0Y), value 1*"
FUNCTION_HOTKEY_HAT_RIGHT_EVENT="*(ABS_HAT0X), value 1*"
FUNCTION_HOTKEY_HAT_LEFT_EVENT="*(ABS_HAT0X), value -1*"

DPAD_EVENTS=$(get_setting key.dpad.events)
if [ -z "${DPAD_EVENTS}" ] || [ "${DPAD_EVENTS}" = "0" ]; then
  DPAD_EVENTS=false
else
  DPAD_EVENTS=true
fi

CONTROLLER_DISCONNECTED="*error reading: No such device"
DEVICE_DISCONNECTED="*error reading: No such device"

### Matches if a button was pressed (1), released (0) or held down (2)
PRESS='value 1'
REPEAT='value 2'
RELEASE='value 0'

### Function buttons should be defined as not pressed for later matching.
FN_A_PRESSED=false
FN_B_PRESSED=false

### Volume repeat variables
VOLUME_REPEAT_DELAY=0.3  # Initial delay before repeating starts (seconds)
VOLUME_REPEAT_INTERVAL=0.1  # Interval between repeats (seconds)
VOLUME_UP_PRESSED=false
VOLUME_DOWN_PRESSED=false
VOLUME_REPEAT_PID=""

### Allow actions to be overridden in system.cfg
FN_A_ACTION_UP="$(get_setting key.function.a.up)"
FN_A_ACTION_DOWN="$(get_setting key.function.a.down)"
FN_B_ACTION_UP="$(get_setting key.function.b.up)"
FN_B_ACTION_DOWN="$(get_setting key.function.b.down)"
FN_AB_ACTION_UP="$(get_setting key.function.ab.up)"
FN_AB_ACTION_DOWN="$(get_setting key.function.ab.down)"

### Set sane defaults to manage volume, brightness, wireless on/off, and led on/off.
[ -z "${FN_A_ACTION_UP}" ]    && FN_A_ACTION_UP="brightness up"
[ -z "${FN_A_ACTION_DOWN}" ]  && FN_A_ACTION_DOWN="brightness down"
[ -z "${FN_B_ACTION_UP}" ]    && FN_B_ACTION_UP="ledcontrol"
[ -z "${FN_B_ACTION_DOWN}" ]  && FN_B_ACTION_DOWN="ledcontrol poweroff"
[ -z "${FN_AB_ACTION_UP}" ]   && FN_AB_ACTION_UP="wifictl enable"
[ -z "${FN_AB_ACTION_DOWN}" ] && FN_AB_ACTION_DOWN="wifictl disable"

### Volume repeat function
start_volume_repeat() {
    local direction=$1

    # Stop any existing volume repeat
    stop_volume_repeat

    # Initial volume adjustment
    volume ${direction}

    # Start background process for repeating volume adjustments
    (
        sleep ${VOLUME_REPEAT_DELAY}
        while true; do
            # Check if button is still pressed before adjusting
            if { [ "${direction}" = "up" ] && [ "${VOLUME_UP_PRESSED}" = true ]; } || \
               { [ "${direction}" = "down" ] && [ "${VOLUME_DOWN_PRESSED}" = true ]; }; then
                volume ${direction}
                sleep ${VOLUME_REPEAT_INTERVAL}
            else
                break
            fi
        done
    ) &

    VOLUME_REPEAT_PID=$!
    ${DEBUG} && log $0 "Started volume repeat (${direction}) with PID: ${VOLUME_REPEAT_PID}"
}

stop_volume_repeat() {
    if [ -n "${VOLUME_REPEAT_PID}" ]; then
        kill ${VOLUME_REPEAT_PID} 2>/dev/null
        wait ${VOLUME_REPEAT_PID} 2>/dev/null
        ${DEBUG} && log $0 "Stopped volume repeat with PID: ${VOLUME_REPEAT_PID}"
    fi
    VOLUME_REPEAT_PID=""
}

### Simple functions to execute button actions, including global kill.
execute_kill() {
  if [ -e "/tmp/.process-kill-data" ]; then
    TO_KILL="$(cat /tmp/.process-kill-data)"
    ${DEBUG} && log $0 "Execute: killall ${TO_KILL}"
    killall ${TO_KILL} 2>/dev/null
  fi
}

execute_action() {
  ${DEBUG} && log $0 "${1}|${FN_A_PRESSED}|${FN_B_PRESSED}|${DPAD_UP_PRESSED}|${DPAD_DOWN_PRESSED}|${DPAD_RIGHT_PRESSED}|${DPAD_LEFT_PRESSED}"
  if [ "${FN_A_PRESSED}" = true ] && [ "${FN_B_PRESSED}" = true ]; then
    ${DEBUG} && log $0 "Executing FN_AB action"
    case ${1} in
      up)
        ${DEBUG} && log $0 "FN_AB (${FN_AB_ACTION_UP})"
        ${FN_AB_ACTION_UP}
        ;;
      down)
        ${DEBUG} && log $0 "FN_AB (${FN_AB_ACTION_DOWN})"
        ${FN_AB_ACTION_DOWN}
        ;;
    esac
  elif [ "${FN_A_PRESSED}" = true ] && [ "${FN_B_PRESSED}" = false ]; then
    ${DEBUG} && log $0 "Executing FN_A action"
    case ${1} in
      up)
        ${DEBUG} && log $0 "FN_A (${FN_A_ACTION_UP})"
        ${FN_A_ACTION_UP}
        if [ "${FN_A_ACTION_UP}" == "brightness up" ]; then
          CUR_BRIGHTNESS=$(get_setting "display.brightness")
          /usr/bin/mako-notify "Brightness: ${CUR_BRIGHTNESS}%" -no-es
        fi
        ;;
      down)
        ${DEBUG} && log $0 "FN_A (${FN_A_ACTION_DOWN})"
        ${FN_A_ACTION_DOWN}
        if [ "${FN_A_ACTION_DOWN}" == "brightness down" ]; then
          CUR_BRIGHTNESS=$(get_setting "display.brightness")
          /usr/bin/mako-notify "Brightness: ${CUR_BRIGHTNESS}%" -no-es
        fi
        ;;
    esac
  elif [ "${FN_A_PRESSED}" = false ] && [ "${FN_B_PRESSED}" = true ]; then
    ${DEBUG} && log $0 "Executing FN_B action"
    case ${1} in
      up)
        ${DEBUG} && log $0 "FN_B (${FN_B_ACTION_UP})"
        ${FN_B_ACTION_UP}
        ;;
      down)
        ${DEBUG} && log $0 "FN_B (${FN_B_ACTION_DOWN})"
        ${FN_B_ACTION_DOWN}
        ;;
    esac
  else
    # If neither FN_A nor FN_B is pressed, treat it as a volume control
    volume ${1}
  fi
}

### Search the system for useful devices to monitor for inputs.
INPUT_DEVICES=()

get_devices() {
  local KJDEVS=false
  local FOUNDKEYS=false
  local FOUNDJOY=false
  local FOUNDTOUCH=false
  local RETRY=5

  while [ ${KJDEVS} = false ]; do
    for DEV in /dev/input/ev*
    do
      unset SUPPORTS
      SUPPORTS=$(udevadm info ${DEV} | awk '/ID_INPUT_KEY=|ID_INPUT_JOYSTICK=|ID_INPUT_TOUCHSCREEN=/ {print $2}')
      if [ -n "${SUPPORTS}" ]; then
        DEVICE=$(udevadm info ${DEV} | awk 'BEGIN {FS="="} /DEVNAME=/ {print $2}')
        INPUT_DEVICES+=("${DEVICE}")
        if [[ "${SUPPORTS}" =~ ID_INPUT_KEY ]]; then
          ${DEBUG} && log $0 "Found Keyboard: ${DEVICE}"
          FOUNDKEYS=true
        elif [[ "${SUPPORTS}" =~ ID_INPUT_TOUCHSCREEN ]]; then
          ${DEBUG} && log $0 "Found Touchscreen: ${DEVICE}"
          FOUNDTOUCH=true
        elif [[ "${SUPPORTS}" =~ ID_INPUT_JOYSTICK ]]; then
          ${DEBUG} && log $0 "Found Joystick: ${DEVICE}"
          FOUNDJOY=true
        fi
      fi
    done

    if [ "${FOUNDKEYS}" = "true" ] && [ "${FOUNDJOY}" = "true" ]; then
      ${DEBUG} && log $0 "Found all needed devices."
      KJDEVS=true
      break
    fi

    if [ "${RETRY}" -ge 5 ]; then
      ${DEBUG} && log $0 "Did not find all needed devices, but continuing anyway."
      ${DEBUG} && log $0 "Did not find all of the needed devices, but that may be OK.  Breaking."
      break
    else
      RETRY=$(( RETRY + 1 ))
    fi

    sleep 1
  done
}

get_devices

# If the input devices change, it may be a new controller
# so handle it here.
mkcontroller 2>/dev/null || :

# ------------------------------------------------------------------
# Turn OFF 'exit on error' *now* so a single evtest crash won't kill
# the entire script. We still keep 'pipefail' for partial debugging.
# ------------------------------------------------------------------
set +e

### Start multiple evtest loops, each continuously restarted on failure. Take action when a known pattern of keys are pressed together.
(
  for INPUT_DEVICE in "${INPUT_DEVICES[@]}"; do
    (
      while true
      do
        evtest "${INPUT_DEVICE}" 2>&1
        # If evtest exits, wait briefly and restart
        echo "evtest for ${INPUT_DEVICE} died; restarting in 1 second..." >&2
        sleep 1
      done
    ) &
  done

  wait  # Wait for all background loops (they never end unless forcibly stopped)
) | while read line; do

    # Parse lines from any evtest instance:
    case ${line} in
      (${CONTROLLER_DISCONNECTED})
        ${DEBUG} && log $0 "Reloading due to ${CONTROLLER_DEVICE} reattach..."
        get_devices
      ;;
      (${DEVICE_DISCONNECTED})
        ${DEBUG} && log $0 "Reloading due to ${DEVICE} reattach..."
        get_devices
      ;;
      (${FUNCTION_MODIFIER_A_EVENT})
        if [[ "${line}" =~ ${PRESS} ]]; then
          ${DEBUG} && log $0 "${FUNCTION_MODIFIER_A_EVENT}: Pressed"
          FN_A_PRESSED=true
        elif [[ "${line}" =~ ${RELEASE} ]]; then
          ${DEBUG} && log $0 "${FUNCTION_MODIFIER_A_EVENT}: Released"
          FN_A_PRESSED=false
        fi
      ;;
      (${FUNCTION_MODIFIER_B_EVENT})
        if [[ "${line}" =~ ${PRESS} ]]; then
          ${DEBUG} && log $0 "${FUNCTION_MODIFIER_B_EVENT}: Pressed"
          FN_B_PRESSED=true
        elif [[ "${line}" =~ ${RELEASE} ]]; then
          ${DEBUG} && log $0 "${FUNCTION_MODIFIER_B_EVENT}: Released"
          FN_B_PRESSED=false
        fi
      ;;
      (${FUNCTION_VOLUME_UP_EVENT})
        if [[ "${line}" =~ ${PRESS} ]]; then
          ${DEBUG} && log $0 "Volume Up: Pressed"
          VOLUME_UP_PRESSED=true
          # Only start volume repeat if no function keys are pressed
          if [ "${FN_A_PRESSED}" = false ] && [ "${FN_B_PRESSED}" = false ]; then
            start_volume_repeat up
          else
            # If function keys are pressed, use the original behavior
            execute_action up
          fi
        elif [[ "${line}" =~ ${RELEASE} ]]; then
          ${DEBUG} && log $0 "Volume Up: Released"
          VOLUME_UP_PRESSED=false
          stop_volume_repeat
          if [ "${FN_A_PRESSED}" = false ] && [ "${FN_B_PRESSED}" = false ]; then
            CUR_VOLUME=$(get_setting "audio.volume")
            /usr/bin/mako-notify "Volume: ${CUR_VOLUME}%" -no-es
          fi
        fi
      ;;
      (${FUNCTION_VOLUME_DOWN_EVENT})
        if [[ "${line}" =~ ${PRESS} ]]; then
          ${DEBUG} && log $0 "Volume Down: Pressed"
          VOLUME_DOWN_PRESSED=true
          # Only start volume repeat if no function keys are pressed
          if [ "${FN_A_PRESSED}" = false ] && [ "${FN_B_PRESSED}" = false ]; then
            start_volume_repeat down
          else
            # If function keys are pressed, use the original behavior
            execute_action down
          fi
        elif [[ "${line}" =~ ${RELEASE} ]]; then
          ${DEBUG} && log $0 "Volume Down: Released"
          VOLUME_DOWN_PRESSED=false
          stop_volume_repeat
          if [ "${FN_A_PRESSED}" = false ] && [ "${FN_B_PRESSED}" = false ]; then
            CUR_VOLUME=$(get_setting "audio.volume")
            /usr/bin/mako-notify "Volume: ${CUR_VOLUME}%" -no-es
          fi
        fi
      ;;
      (${FUNCTION_POWER_PRESSED_EVENT})
        ${DEBUG} && log $0 "${FUNCTION_POWER_PRESSED_EVENT}: Pressed"
        /usr/bin/archr-fake-suspend power &
      ;;
      (${FUNCTION_LID_CLOSE_EVENT})
        ${DEBUG} && log $0 "${FUNCTION_LID_CLOSE_EVENT}: Close"
        /usr/bin/archr-fake-suspend lid close &
      ;;
      (${FUNCTION_LID_OPEN_EVENT})
        ${DEBUG} && log $0 "${FUNCTION_LID_OPEN_EVENT}: Open"
        /usr/bin/archr-fake-suspend lid open &
      ;;
    esac

    # Hotkey logic
    case ${line} in
      (${FUNCTION_HOTKEY_A_EVENT})
        if [[ "${line}" =~ ${PRESS} ]]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_A_EVENT}: Pressed"
          HOTKEY_A_PRESSED=true
        elif [[ "${line}" =~ ${RELEASE} ]]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_A_EVENT}: Released"
          HOTKEY_A_PRESSED=false
        fi
      ;;
      (${FUNCTION_HOTKEY_B_EVENT})
        if [[ "${line}" =~ ${PRESS} ]]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_B_EVENT}: Pressed"
          HOTKEY_B_PRESSED=true
          # Example: if A and C are also pressed => kill something
          if [ "${HOTKEY_A_PRESSED}" = true ] && [ "${HOTKEY_C_PRESSED}" = true ]; then
            execute_kill
          fi
        elif [[ "${line}" =~ ${RELEASE} ]]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_B_EVENT}: Released"
          HOTKEY_B_PRESSED=false
        fi
      ;;
      (${FUNCTION_HOTKEY_C_EVENT})
        if [[ "${line}" =~ ${PRESS} ]]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_C_EVENT}: Pressed"
          HOTKEY_C_PRESSED=true
          # Example: if A and B are also pressed => kill something
          if [ "${HOTKEY_A_PRESSED}" = true ] && [ "${HOTKEY_B_PRESSED}" = true ]; then
            execute_kill
          fi
        elif [[ "${line}" =~ ${RELEASE} ]]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_C_EVENT}: Released"
          HOTKEY_C_PRESSED=false
        fi
      ;;
      (${FUNCTION_HOTKEY_DPAD_UP_EVENT}|${FUNCTION_HOTKEY_HAT_UP_EVENT})
        if [ "${FN_A_PRESSED}" = true ] && [ "${DPAD_EVENTS}" = true ]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_DPAD_UP_EVENT}${FUNCTION_HOTKEY_HAT_UP_EVENT}: Volume Up"
          volume up
        fi
      ;;
      (${FUNCTION_HOTKEY_DPAD_DOWN_EVENT}|${FUNCTION_HOTKEY_HAT_DOWN_EVENT})
        if [ "${FN_A_PRESSED}" = true ] && [ "${DPAD_EVENTS}" = true ]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_DPAD_DOWN_EVENT}${FUNCTION_HOTKEY_HAT_DOWN_EVENT}: Volume Down"
          volume down
        fi
      ;;
      (${FUNCTION_HOTKEY_DPAD_RIGHT_EVENT}|${FUNCTION_HOTKEY_HAT_RIGHT_EVENT})
        if [ "${FN_A_PRESSED}" = true ] && [ "${DPAD_EVENTS}" = true ]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_DPAD_RIGHT_EVENT}${FUNCTION_HOTKEY_HAT_RIGHT_EVENT}: Brightness Up"
          brightness up
          CUR_BRIGHTNESS=$(get_setting "display.brightness")
          /usr/bin/mako-notify "Brightness: ${CUR_BRIGHTNESS}%" -no-es
        fi
      ;;
      (${FUNCTION_HOTKEY_DPAD_LEFT_EVENT}|${FUNCTION_HOTKEY_HAT_LEFT_EVENT})
        if [ "${FN_A_PRESSED}" = true ] && [ "${DPAD_EVENTS}" = true ]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_DPAD_LEFT_EVENT}${FUNCTION_HOTKEY_HAT_LEFT_EVENT}: Brightness Down"
          brightness down
          CUR_BRIGHTNESS=$(get_setting "display.brightness")
          /usr/bin/mako-notify "Brightness: ${CUR_BRIGHTNESS}%" -no-es
        fi
      ;;
      (${FUNCTION_HOTKEY_TOUCH_EVENT})
        if [ "${FN_A_PRESSED}" = true ] && [ "${TOUCHSCREEN_EVENTS}" = true ]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_TOUCH_EVENT}: Toggle Touchscreen Keyboard"
          kill -34 $(pidof wvkbd-mobintl)
        fi
      ;;
      (${FUNCTION_HOTKEY_BTN_EAST_EVENT})
        if [ "${HOTKEY_A_PRESSED}" = true ]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_BTN_EAST_EVENT}: Screenshot"
          /usr/bin/archr-screenshot
          # Display notification if 'success' exit code
          SCREENSHOT_SUCCESS=$?
          [ "$SCREENSHOT_SUCCESS" -eq 0 ] && /usr/bin/mako-notify "Screenshot Saved" -no-ra
        fi
      ;;
     (${FUNCTION_HOTKEY_BTN_WEST_EVENT})
        if [ "${HOTKEY_A_PRESSED}" = true ]; then
          ${DEBUG} && log $0 "${FUNCTION_HOTKEY_BTN_WEST_EVENT}: Config MangoHud"
          /usr/bin/mangohud_set toggle
        fi
      ;;
     (${FUNCTION_HOTKEY_BTN_BACK_EVENT}|${FUNCTION_HOTKEY_KEY_RECORD_EVENT})
       if [ "${HOTKEY_A_PRESSED}" = true ]; then
         ${DEBUG} && log $0 "${FUNCTION_HOTKEY_BTN_BACK_EVENT}: Switch Screen Output"
         /usr/bin/screen_switch
       fi
     ;;
     (${FUNCTION_HOTKEY_BTN_NORTH_EVENT})
       if [ "${HOTKEY_A_PRESSED}" = true ]; then
         ${DEBUG} && log $0 "${FUNCTION_HOTKEY_BTN_NORTH_EVENT}: Opening Game Guide"
         /usr/bin/game-guides-tool
       fi
     ;;
  esac
done
