Skip to content

Instantly share code, notes, and snippets.

@openglfreak
Last active January 28, 2019 13:39
Show Gist options
  • Save openglfreak/6279d136b2021109e1967c724e99a5d5 to your computer and use it in GitHub Desktop.
Save openglfreak/6279d136b2021109e1967c724e99a5d5 to your computer and use it in GitHub Desktop.
Script that sets the openrazer driver device mode of connected Razer devices to 'driver'.
#!/bin/sh
:<<'EOF'
Copyright © 2018 Torge Matthies <openglfreak@googlemail.com>
This work is free. You can redistribute it and/or modify it under the
terms of the Do What The Fuck You Want To Public License, Version 2,
as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.
EOF
LOG_DEBUG="${LOG_DEBUG:-0}"
LOG_INFO="${LOG_INFO:-1}"
LOG_WARN="${LOG_INFO:-1}"
LOG_ERROR="${LOG_INFO:-1}"
debug() {
[ -n "$LOG_DEBUG" ] && [ 0 \!= "$LOG_DEBUG" ] && printf '[DEBUG] ' && printf '%s\n' "$*"
}
info() {
[ -n "$LOG_INFO" ] && [ 0 \!= "$LOG_INFO" ] && printf '[INFO] ' && printf '%s\n' "$*"
}
warn() {
[ -n "$LOG_WARN" ] && [ 0 \!= "$LOG_WARN" ] && printf '[WARNING] ' && printf '%s\n' "$*"
}
error() {
[ -n "$LOG_ERROR" ] && [ 0 \!= "$LOG_ERROR" ] && printf '[ERROR] ' && printf '%s\n' "$*"
}
# Sets the device mode of a Razer device
#
# params:
# string device_serial
# The serial number of the device.
# string device_mode
# The new device mode. One of ('normal', 'driver').
#
# stdout:
# Output of dbus-send.
#
# stderr:
# Errors from dbus-send.
#
# exit code:
# 1 if not enough parameters were passed,
# 2 if too many parameters were passed,
# 16 if an invalid device_mode was passed,
# the exit code of dbus-send otherwise.
set_device_mode() {
if [ $# -ne 2 ]; then
if [ $# -lt 2 ]; then
# Not enough parameters
return 1
else
# Too many parameters
return 2
fi
fi
# Translate device_mode parameter into mode id
case "$2" in
normal)
# Mode 'normal' is mode id 0
set -- "$1" byte:0;;
driver)
# Mode 'driver' is mode id 3
set -- "$1" byte:3;;
*)
# Invalid mode
return 16;;
esac
dbus-send --session --dest=org.razer --type=method_call /org/razer/device/"$1" razer.device.misc.setDeviceMode "$2" byte:0
}
# Lists the connected Razer devices
#
# stdout:
# Newline-separated list of device serial numbers.
#
# stderr:
# Errors from dbus-send.
#
# exit code:
# 2 if parameters were passed,
# the exit code of dbus-send otherwise.
_list_devices() {
if [ $# -ne 0 ]; then
# Too many parameters
return 2
fi
# qdbus --session org.razer /org/razer razer.devices.getDevices
dbus-send --session --dest=org.razer --type=method_call --print-reply /org/razer razer.devices.getDevices |\
# Cut off array header and footer
tail -n +3 | head -n -1 |\
# Cut off ' string "' part of line
cut -c15- |\
# Cut off closing quotes
rev | cut -c2- | rev
}
# The main method of the program
main() {
__main_device_list_file="$(mktemp)"
__main_device_list_file_new="$(mktemp)"
# Start listening for device_added signals
debug 'Starting dbus-monitor'
exec sh -c 'printf "%s\\n" "$$"; LINES= COLUMNS= LC_ALL=C exec dbus-monitor --session --profile "type=signal,path=/org/razer,interface=razer.devices"' 2>/dev/null |\
{
# Read dbus-monitor pid
IFS= read -r __dbus_wait_for_signal_mpid
debug "dbus-monitor pid: $__dbus_wait_for_signal_mpid"
# Set the device mode for all currently connected Razer devices
info 'Setting device mode for all connected devices'
_list_devices | sort -u | tee "$__main_device_list_file" |\
while IFS= read -r serial; do
debug "Setting device mode of device $serial"
set_device_mode "$serial" driver
done
# Skip table header
IFS= read -r _
IFS= read -r _
# Set the device mode when a new Razer device is connected
info 'Waiting for new devices'
while IFS= read -r line; do
case "$line" in
*[[:space:]]/org/razer[[:space:]]razer.devices[[:space:]]device_added)
# A device was added
info 'New device detected, setting device mode'
# Write all devices to __main_device_list_file_new
_list_devices | sort -u > "$__main_device_list_file_new"
# Process new devices
comm -13 "$__main_device_list_file" "$__main_device_list_file_new" |\
while IFS= read -r serial; do
debug "Setting device mode of device $serial"
set_device_mode "$serial" driver
done
# Exchange __main_device_list_file and __main_device_list_file_new
__main_tmp="$__main_device_list_file"
__main_device_list_file="$__main_device_list_file_new"
__main_device_list_file_new="$__main_tmp"
unset __main_tmp
;;
*[[:space:]]/org/razer[[:space:]]razer.devices[[:space:]]device_removed)
# A device was removed
info 'Device removed'
if [ -n "$LOG_DEBUG" ] && [ "$LOG_DEBUG" \!= 0 ]; then
# Write all devices to __main_device_list_file_new
_list_devices | sort -u > "$__main_device_list_file_new"
# Process removed devices
comm -23 "$__main_device_list_file" "$__main_device_list_file_new" |\
while IFS= read -r serial; do
debug "Serial number of removed device: $serial"
done
# Exchange __main_device_list_file and __main_device_list_file_new
__main_tmp="$__main_device_list_file"
__main_device_list_file="$__main_device_list_file_new"
__main_device_list_file_new="$__main_tmp"
unset __main_tmp
else
# Write all devices to __main_device_list_file
_list_devices | sort -u | tee "$__main_device_list_file"
fi
;;
esac
done
# Kill dbus-monitor
kill "$__dbus_wait_for_signal_mpid"
}
}
main ${1+"$@"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment