Last active
January 28, 2019 13:39
-
-
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'.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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