205 lines
5.8 KiB
Bash
Executable file
205 lines
5.8 KiB
Bash
Executable file
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
|
|
# 2021-present pkegg
|
|
|
|
. /etc/profile
|
|
|
|
set -e
|
|
set -o pipefail
|
|
|
|
LOG="/var/log/$(basename "$0").log"
|
|
|
|
### Summary
|
|
# This script listens to volume keys and adjusts volume
|
|
# Fn + Volume up/down will adjust brightness
|
|
###
|
|
|
|
# Event examples for reference
|
|
# type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 1
|
|
# type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 1
|
|
|
|
VOL_EVENT='*(KEY_VOLUME*, value *' # This matches all volume events
|
|
|
|
VOL_UP='*UP), value *' # Differentiate 'up' volume event
|
|
VOL_DOWN='*DOWN), value *' #Differentiate 'down' volume event
|
|
|
|
V_FUNC_KEYA_EVENT='*('${DEVICE_FUNC_KEYA_MODIFIER}'), value *'
|
|
V_FUNC_KEYB_EVENT='*('${DEVICE_FUNC_KEYB_MODIFIER}'), value *'
|
|
|
|
# Matches if a button was pressed (1), released (0) or held down (2)
|
|
PRESS='value [1-9]'
|
|
RELEASE='value 0'
|
|
|
|
# Volume repeat
|
|
VOLUME_REPEAT_MOD=4
|
|
|
|
# Brightness repeat
|
|
BRIGHTNESS_REPEAT_MOD=4
|
|
|
|
# Variable to keep track of Fn being currently pressed
|
|
FUNCA_PRESSED=no
|
|
FUNCB_PRESSED=no
|
|
|
|
CONTROLLER_DISCONNECTED="*error reading: No such device"
|
|
DEVICE_DISCONNECTED="*error reading: No such device"
|
|
|
|
get_devices() {
|
|
KJDEVS=false
|
|
FOUNDKEYS=false
|
|
FOUNDJOY=false
|
|
RETRY=5
|
|
while [ ${KJDEVS} = false ]
|
|
do
|
|
# Detect input devices automatically
|
|
for DEV in /dev/input/ev*
|
|
do
|
|
unset SUPPORTS
|
|
SUPPORTS=$(udevadm info ${DEV} | awk '/ID_INPUT_KEY=|ID_INPUT_JOYSTICK=/ {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
|
|
echo "Found Keyboard: ${DEVICE}" 2>&1 >${LOG}
|
|
FOUNDKEYS=true
|
|
elif [[ "${SUPPORTS}" =~ ID_INPUT_JOYSTICK ]]
|
|
then
|
|
echo "Found Joystick: ${DEVICE}" 2>&1 >${LOG}
|
|
FOUNDJOY=true
|
|
fi
|
|
fi
|
|
done
|
|
if [ "${FOUNDKEYS}" = "true" ] &&
|
|
[ "${FOUNDJOY}" = "true" ]
|
|
then
|
|
echo "Found all of the needed devices." 2>&1 >${LOG}
|
|
KJDEVS=true
|
|
break
|
|
fi
|
|
if [ "${RETRY}" -ge 5 ]
|
|
then
|
|
echo "Did not find all of the needed devices, but that may be OK. Breaking." 2>&1 >${LOG}
|
|
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 ||:
|
|
|
|
# Logic:
|
|
# - Listen to any input device events to get volume keys (not part of the joystick api)
|
|
# - Switch statement keeps high level cases to only 'volume' and 'V function key'
|
|
# this is to avoid processing for other events or creating a lot of cases as this will be called
|
|
# for all button pushes
|
|
# - Using 'read' means the loop is idle when no button is pressed
|
|
|
|
(
|
|
for INPUT_DEVICE in ${INPUT_DEVICES[@]}
|
|
do
|
|
evtest "${INPUT_DEVICE}" 2>&1 &
|
|
done
|
|
wait
|
|
) | while read line; do
|
|
case $line in
|
|
(${CONTROLLER_DISCONNECTED})
|
|
echo "Reloading due to ${CONTROLLER_DEVICE} reattach..." >${LOG} 2>&1
|
|
get_devices
|
|
;;
|
|
(${DEVICE_DISCONNECTED})
|
|
echo "Reloading due to ${DEVICE} reattach..." >${LOG} 2>&1
|
|
get_devices
|
|
;;
|
|
(${VOL_EVENT})
|
|
# We don't care when you 'let go' ('release') the volume button
|
|
if [[ "$line" =~ ${RELEASE} ]]; then
|
|
REPEAT_NUM=0
|
|
continue
|
|
fi
|
|
# Setup for 'brightness' if Fn pressed
|
|
if [[ "${FUNCA_PRESSED}" == "yes" ]]; then
|
|
COMMAND="/usr/bin/brightness"
|
|
UP="up"
|
|
DOWN="down"
|
|
REPEAT_MOD=${BRIGHTNESS_REPEAT_MOD}
|
|
elif [[ "${FUNCB_PRESSED}" == "yes" ]]; then
|
|
if [[ "${line}" == ${VOL_UP} ]]; then
|
|
COMMAND="/usr/bin/say"
|
|
UP="-b"
|
|
else
|
|
COMMAND="/usr/bin/wifictl"
|
|
WIFISTATE=$(get_setting network.enabled)
|
|
if [ "${WIFISTATE}" = 0 ]
|
|
then
|
|
DOWN="reconnect"
|
|
/usr/bin/say "WIFI On"
|
|
else
|
|
DOWN="disable"
|
|
/usr/bin/say "WIFI Off"
|
|
fi
|
|
fi
|
|
else
|
|
# Default to 'volume' if Fn a or b is not pressed
|
|
COMMAND="/usr/bin/volume"
|
|
UP="+"
|
|
DOWN="-"
|
|
REPEAT_MOD=${VOLUME_REPEAT_MOD}
|
|
fi
|
|
|
|
REPEAT_NUM=$(( ${REPEAT_NUM} + 1 ))
|
|
|
|
# This isn't time to evaluate repeat so just skip
|
|
if [[ "$line" == ${REPEAT_PRESS} && $(( ${REPEAT_NUM} % ${REPEAT_MOD} )) != "0" ]]; then
|
|
continue
|
|
fi
|
|
|
|
INCREMENT_AMOUNT=5
|
|
if [[ "${REPEAT_NUM}" -gt "20" ]]; then
|
|
INCREMENT_AMOUNT=10
|
|
fi
|
|
|
|
# Run the commands to adjust volume/brightness
|
|
if [[ "${line}" == ${VOL_UP} ]]; then
|
|
${COMMAND} ${UP} ${INCREMENT_AMOUNT} > /dev/null
|
|
read -t 0.1
|
|
elif [[ "${line}" == ${VOL_DOWN} ]]; then
|
|
${COMMAND} ${DOWN} ${INCREMENT_AMOUNT} > /dev/null
|
|
read -t 0.1
|
|
fi
|
|
;;
|
|
|
|
(${V_FUNC_KEYA_EVENT})
|
|
|
|
#Reset the number of repeats when Fn is pressed/release
|
|
# as repeat speed is different between volume/brightness
|
|
REPEAT_NUM=0
|
|
|
|
if [[ "${line}" =~ ${PRESS} ]]; then
|
|
FUNCA_PRESSED=yes
|
|
elif [[ "${line}" =~ ${RELEASE} ]]; then
|
|
FUNCA_PRESSED=no
|
|
fi
|
|
;;
|
|
|
|
(${V_FUNC_KEYB_EVENT})
|
|
|
|
#Reset the number of repeats when Fn is pressed/release
|
|
# as repeat speed is different between volume/brightness
|
|
REPEAT_NUM=0
|
|
|
|
if [[ "${line}" =~ ${PRESS} ]]; then
|
|
FUNCB_PRESSED=yes
|
|
elif [[ "${line}" =~ ${RELEASE} ]]; then
|
|
FUNCB_PRESSED=no
|
|
fi
|
|
;;
|
|
esac
|
|
done
|