Last active
October 5, 2021 15:40
-
-
Save TonyWhite/78477d76517461916e7fd98b54f20ff4 to your computer and use it in GitHub Desktop.
Clevo XSM Keyboard's led
This file contains hidden or 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/bash | |
| # Backlight - Clevo XSM Keyboard's led | |
| # Copyright (C) 2019-2021 Antonio Bianco | |
| # | |
| # This program is free software: you can redistribute it and/or modify | |
| # it under the terms of the GNU General Public License as published by | |
| # the Free Software Foundation, either version 3 of the License, or | |
| # any later version. | |
| # | |
| # This program is distributed in the hope that it will be useful, | |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| # GNU General Public License for more details. | |
| # | |
| # You should have received a copy of the GNU General Public License | |
| # along with this program. If not, see <https://www.gnu.org/licenses/>. | |
| # Constants DEVICE | |
| STATE="/sys/devices/platform/clevo_xsm_wmi/kb_state" | |
| BRIGHTNESS="/sys/devices/platform/clevo_xsm_wmi/kb_brightness" | |
| ANIMATION="/sys/devices/platform/clevo_xsm_wmi/kb_mode" | |
| COLORS="/sys/devices/platform/clevo_xsm_wmi/kb_color" | |
| MIN_BRIGHTNESS=0 | |
| MAX_BRIGHTNESS=9 | |
| DEFAULT_BRIGHTNESS=9 | |
| MIN_ANIMATION=0 | |
| MAX_ANIMATION=7 | |
| DEFAULT_ANIMATION=1 | |
| # Constants ACTIONS for main menu | |
| ACT_DEVICE_ON="DEVICE_ON" | |
| ACT_DEVICE_OFF="DEVICE_OFF" | |
| ACT_CHANGE_COLOR="CHANGE_COLOR" | |
| ACT_CHANGE_BRIGHTNESS="CHANGE_BRIGHTNESS" | |
| ACT_CHANGE_ANIMATION="CHANGE_ANIMATION" | |
| ########################## | |
| # LOCALIZATION WITH # | |
| # zen-sudo LITE EMBEDDED # | |
| ########################## | |
| # Default language: en_US | |
| # zen-sudo strings | |
| ZEN_SUDO_NAME="zen-sudo LITE EMBEDDED" | |
| THIS_COMMAND_REQUIRE_ROOT_PERMISSIONS="This command require root permissions" | |
| WORKING_FOLDER="Working folder" | |
| COMMAND_NOT_EXECUTED="Command not executed." | |
| # Colors | |
| DRIVER_COLORS=("black" "red" "yellow" "green" "cyan" "blue" "magenta" "white") | |
| ACCEPTED_COLORS=("Black" "Red" "Yellow" "Green" "Cyan" "Blue" "Magenta" "White") | |
| # Constants ACTIONS for color menu | |
| ACT_CHANGE_LEFT_COLOR="LEFT_COLOR" | |
| ACT_CHANGE_CENTER_COLOR="CENTER_COLOR" | |
| ACT_CHANGE_RIGHT_COLOR="RIGHT_COLOR" | |
| ACT_CHANGE_TOUCHPAD_COLOR="TOUCHPAD_COLOR" | |
| # Text | |
| TXT_TITLE="Keyboard Backlight" | |
| TXT_MUST_BE_ROOT="You must be root!" | |
| TXT_SELECT_ACTION="Select Action" | |
| TXT_BACK="Back" | |
| TXT_EXIT="Exit" | |
| TXT_QUESTION_QUIT="Do you want to exit?" | |
| TXT_DEVICE_ON="Turn ON" | |
| TXT_DEVICE_OFF="Turn OFF" | |
| TXT_CHANGE="Change" | |
| TXT_COLOR="Color" | |
| TXT_CURRENT="Current" | |
| TXT_BRIGHTNESS="Brightness" | |
| TXT_ANIMATION="Animation" | |
| TXT_CHANGE_COLOR="${TXT_CHANGE} ${TXT_COLOR}" | |
| TXT_CHANGE_BRIGHTNESS="${TXT_CHANGE} ${TXT_BRIGHTNESS}" | |
| TXT_CHANGE_ANIMATION="${TXT_CHANGE} ${TXT_ANIMATION}" | |
| TXT_CHANGE_LEFT_COLOR="Left ${TXT_COLOR}" | |
| TXT_CHANGE_CENTER_COLOR="Center ${TXT_COLOR}" | |
| TXT_CHANGE_RIGHT_COLOR="Right ${TXT_COLOR}" | |
| TXT_CHANGE_TOUCHPAD_COLOR="Touchpad ${TXT_COLOR}" | |
| # Import current language. If it fails, en_US will be used | |
| case "`echo ${LANG} | cut -f1 -d ' ' | cut -f1 -d '.'`" in | |
| "it_IT") | |
| # zen-sudo strings | |
| THIS_COMMAND_REQUIRE_ROOT_PERMISSIONS="Questo comando richiede i permessi di root" | |
| WORKING_FOLDER="Cartella di lavoro" | |
| COMMAND_NOT_EXECUTED="Comando non eseguito." | |
| # Colors | |
| ACCEPTED_COLORS=("Nero" "Rosso" "Giallo" "Verde" "Ciano" "Blu" "Magenta" "Bianco") | |
| # Constants ACTIONS for color menu | |
| ACT_CHANGE_LEFT_COLOR="LEFT_COLOR" | |
| ACT_CHANGE_CENTER_COLOR="CENTER_COLOR" | |
| ACT_CHANGE_RIGHT_COLOR="RIGHT_COLOR" | |
| ACT_CHANGE_TOUCHPAD_COLOR="TOUCHPAD_COLOR" | |
| # Text | |
| TXT_TITLE="Retroilluminazione della tastiera" | |
| TXT_MUST_BE_ROOT="Devi essere root!" | |
| TXT_SELECT_ACTION="Scegli l'azione" | |
| TXT_BACK="Indietro" | |
| TXT_EXIT="Esci" | |
| TXT_QUESTION_QUIT="Vuoi uscire dal programma?" | |
| TXT_DEVICE_ON="Accendi" | |
| TXT_DEVICE_OFF="Spegni" | |
| TXT_CHANGE="Cambia" | |
| TXT_COLOR="Colore" | |
| TXT_CURRENT="Corrente" | |
| TXT_BRIGHTNESS="Luminosità" | |
| TXT_ANIMATION="Animazione" | |
| TXT_CHANGE_COLOR="${TXT_CHANGE} ${TXT_COLOR}" | |
| TXT_CHANGE_BRIGHTNESS="${TXT_CHANGE} ${TXT_BRIGHTNESS}" | |
| TXT_CHANGE_ANIMATION="${TXT_CHANGE} ${TXT_ANIMATION}" | |
| TXT_CHANGE_LEFT_COLOR="${TXT_COLOR} a sinistra" | |
| TXT_CHANGE_CENTER_COLOR="${TXT_COLOR} centrale" | |
| TXT_CHANGE_RIGHT_COLOR="${TXT_COLOR} di destra" | |
| TXT_CHANGE_TOUCHPAD_COLOR="${TXT_COLOR} del touchpad" | |
| ;; | |
| esac | |
| ################# | |
| # MANAGE DEVICE # | |
| ################# | |
| function device_on() | |
| { | |
| echo 1 > "${STATE}" | |
| } | |
| function device_off() | |
| { | |
| echo 0 > "${STATE}" | |
| } | |
| # 0 -> OFF | |
| # 1 -> ON | |
| function get_state() | |
| { | |
| cat "${STATE}" | |
| } | |
| # 0 -> MIN | |
| # 9 -> MAX | |
| # Default 9: max brightness | |
| function set_brightness() | |
| { | |
| echo "$1" > "${BRIGHTNESS}" | |
| } | |
| function get_brightness() | |
| { | |
| cat "${BRIGHTNESS}" | |
| } | |
| # From 0 to 7 | |
| # Default 1: no animation | |
| function set_animation() | |
| { | |
| echo "$1" > "${ANIMATION}" | |
| } | |
| # Get animation | |
| function get_animation() | |
| { | |
| cat "${ANIMATION}" | |
| } | |
| # Set colors | |
| function set_colors() | |
| { | |
| echo "$1 $2 $3 $4" > "${COLORS}" | |
| } | |
| # Get colors | |
| function get_colors() | |
| { | |
| cat "${COLORS}" | |
| } | |
| ####### | |
| # GUI # | |
| ####### | |
| function main_menu() | |
| { | |
| while true; do | |
| ACTION="" | |
| if [[ `get_state` == "1" ]]; then | |
| ACTION=`menu_for_device_on` | |
| else | |
| ACTION=`menu_for_device_off` | |
| fi | |
| case "${ACTION}" in | |
| "${ACT_DEVICE_ON}") | |
| device_on | |
| ;; | |
| "${ACT_DEVICE_OFF}") | |
| device_off | |
| ;; | |
| "${ACT_CHANGE_COLOR}") | |
| menu_change_color | |
| ;; | |
| "${ACT_CHANGE_BRIGHTNESS}") | |
| menu_change_brightness | |
| ;; | |
| "${ACT_CHANGE_ANIMATION}") | |
| menu_change_animation | |
| ;; | |
| "") # Cancel OR window closed | |
| if [[ `exit_question` == true ]]; then | |
| break | |
| fi | |
| ;; | |
| *) | |
| `bad_nerd` | |
| ;; | |
| esac | |
| done | |
| } | |
| function exit_question() | |
| { | |
| zenity --question \ | |
| --ellipsize \ | |
| --title="${TXT_TITLE}" \ | |
| --text="${TXT_QUESTION_QUIT}" | |
| RESPONSE=`echo $?` | |
| if [[ ${RESPONSE} == 0 ]]; then | |
| echo true | |
| else | |
| echo false | |
| fi | |
| } | |
| # This is main menu when device is on | |
| function menu_for_device_on() | |
| { | |
| ACTION=$(zenity --list \ | |
| --title="${TXT_TITLE}" \ | |
| --text="${TXT_SELECT_ACTION}" \ | |
| --cancel-label="${TXT_EXIT}"\ | |
| --hide-header \ | |
| --hide-column=1 \ | |
| --column="Value" --column="Description" \ | |
| "${ACT_CHANGE_COLOR}" "${TXT_CHANGE_COLOR}" \ | |
| "${ACT_CHANGE_BRIGHTNESS}" "${TXT_CHANGE_BRIGHTNESS}" \ | |
| "${ACT_CHANGE_ANIMATION}" "${TXT_CHANGE_ANIMATION}" \ | |
| "${ACT_DEVICE_OFF}" "${TXT_DEVICE_OFF}") | |
| echo "${ACTION}" | |
| } | |
| # This is main menu when device is off | |
| function menu_for_device_off() | |
| { | |
| ACTION=$(zenity --list \ | |
| --title="${TXT_TITLE}" \ | |
| --text="${TXT_SELECT_ACTION}" \ | |
| --cancel-label="${TXT_EXIT}"\ | |
| --hide-header \ | |
| --hide-column=1 \ | |
| --column="Value" --column="Description" \ | |
| "${ACT_DEVICE_ON}" "${TXT_DEVICE_ON}") | |
| echo "${ACTION}" | |
| } | |
| # Menu to change color | |
| function menu_change_color() | |
| { | |
| while true; do | |
| ACTION=$(zenity --forms \ | |
| --title="${TXT_TITLE}" \ | |
| --text="${TXT_CHANGE_COLOR}" \ | |
| --cancel-label="${TXT_BACK}"\ | |
| --add-combo="${TXT_CHANGE_LEFT_COLOR}" \ | |
| --combo-values=`colors_to_combo_values` \ | |
| --add-combo="${TXT_CHANGE_CENTER_COLOR}" \ | |
| --combo-values=`colors_to_combo_values` \ | |
| --add-combo="${TXT_CHANGE_RIGHT_COLOR}" \ | |
| --combo-values=`colors_to_combo_values` \ | |
| --add-combo="${TXT_CHANGE_TOUCHPAD_COLOR}" \ | |
| --combo-values=`colors_to_combo_values`) | |
| if [[ $? == "0" ]]; then | |
| # Read colors from driver | |
| L_COLOR=`echo $(get_colors) | cut -d " " -f 1` | |
| C_COLOR=`echo $(get_colors) | cut -d " " -f 2` | |
| R_COLOR=`echo $(get_colors) | cut -d " " -f 3` | |
| T_COLOR=`echo $(get_colors) | cut -d " " -f 4` | |
| # Read colors from user input and translate for driver | |
| NEW_L_COLOR=`is_accepted_color "$(echo ${ACTION} | cut -d "|" -f 1)"` | |
| NEW_C_COLOR=`is_accepted_color "$(echo ${ACTION} | cut -d "|" -f 2)"` | |
| NEW_R_COLOR=`is_accepted_color "$(echo ${ACTION} | cut -d "|" -f 3)"` | |
| NEW_T_COLOR=`is_accepted_color "$(echo ${ACTION} | cut -d "|" -f 4)"` | |
| if [[ "${NEW_L_COLOR}" != "" ]]; then | |
| L_COLOR="${NEW_L_COLOR}" | |
| fi | |
| if [[ "${NEW_C_COLOR}" != "" ]]; then | |
| C_COLOR="${NEW_C_COLOR}" | |
| fi | |
| if [[ "${NEW_R_COLOR}" != "" ]]; then | |
| R_COLOR="${NEW_R_COLOR}" | |
| fi | |
| if [[ "${NEW_T_COLOR}" != "" ]]; then | |
| C_COLOR="${NEW_T_COLOR}" | |
| fi | |
| set_colors "${L_COLOR}" "${C_COLOR}" "${R_COLOR}" "${T_COLOR}" | |
| else | |
| break | |
| fi | |
| done | |
| } | |
| # Return driver color if $1 is accepted color | |
| function is_accepted_color() | |
| { | |
| PROBE="$1" | |
| RESULT="" | |
| for ((INDEX = 0 ; INDEX < ${#ACCEPTED_COLORS[@]}; INDEX++)); do | |
| COLOR="${ACCEPTED_COLORS[${INDEX}]}" | |
| if [[ "${PROBE}" == "${COLOR}" ]]; then | |
| RESULT="${DRIVER_COLORS[${INDEX}]}" | |
| break | |
| fi | |
| done | |
| echo ${RESULT} | |
| } | |
| # Convert array to zenity combo box values | |
| function colors_to_combo_values() | |
| { | |
| STRING_FOR_ZENITY="${ACCEPTED_COLORS[0]}" | |
| for INDEX in 1 2 3 4 5 6 7; do | |
| STRING_FOR_ZENITY+="|${ACCEPTED_COLORS[$INDEX]}" | |
| done | |
| echo "${STRING_FOR_ZENITY}" | |
| } | |
| # Menu to change brightness | |
| function menu_change_brightness() | |
| { | |
| while true; do | |
| ACTION=$(zenity --forms \ | |
| --title="${TXT_TITLE}" \ | |
| --text="${TXT_CHANGE_BRIGHTNESS}" \ | |
| --cancel-label="${TXT_BACK}"\ | |
| --add-combo="${TXT_CURRENT}: `get_brightness`" \ | |
| --combo-values=`brightness_to_combo_values`) | |
| if [[ $? == "0" ]]; then | |
| if [[ `is_accepted_brightness "${ACTION}"` == true ]]; then | |
| set_brightness "${ACTION}" | |
| fi | |
| else | |
| break | |
| fi | |
| done | |
| } | |
| # Return true if $1 is accepted brightness value | |
| function is_accepted_brightness() | |
| { | |
| PROBE="$1" | |
| RESULT=false | |
| for ((VALUE = ${MIN_BRIGHTNESS} ; VALUE <= ${MAX_BRIGHTNESS}; VALUE++)); do | |
| if [[ "${PROBE}" == "${VALUE}" ]]; then | |
| RESULT=true | |
| break | |
| fi | |
| done | |
| echo $RESULT | |
| } | |
| # Return zenity combo box values | |
| function brightness_to_combo_values() | |
| { | |
| STRING_FOR_ZENITY="${MIN_BRIGHTNESS}" | |
| for ((VALUE = ${MIN_BRIGHTNESS}+1 ; VALUE <= ${MAX_BRIGHTNESS}; VALUE++)); do | |
| STRING_FOR_ZENITY+="|${VALUE}" | |
| done | |
| echo "${STRING_FOR_ZENITY}" | |
| } | |
| # Menu to change animation | |
| function menu_change_animation() | |
| { | |
| while true; do | |
| ACTION=$(zenity --forms \ | |
| --title="${TXT_TITLE}" \ | |
| --text="${TXT_CHANGE_ANIMATION}" \ | |
| --cancel-label="${TXT_BACK}"\ | |
| --add-combo="${TXT_CURRENT}: `get_animation`" \ | |
| --combo-values=`animation_to_combo_values`) | |
| if [[ $? == "0" ]]; then | |
| if [[ `is_accepted_animation "${ACTION}"` == true ]]; then | |
| set_animation "${ACTION}" | |
| fi | |
| else | |
| break | |
| fi | |
| done | |
| } | |
| # Return true if $1 is accepted animation value | |
| function is_accepted_animation() | |
| { | |
| PROBE="$1" | |
| RESULT=false | |
| for ((VALUE = ${MIN_ANIMATION} ; VALUE <= ${MAX_ANIMATION}; VALUE++)); do | |
| if [[ "${PROBE}" == "${VALUE}" ]]; then | |
| RESULT=true | |
| break | |
| fi | |
| done | |
| echo $RESULT | |
| } | |
| # Return zenity combo box values | |
| function animation_to_combo_values() | |
| { | |
| STRING_FOR_ZENITY="${MIN_ANIMATION}" | |
| for ((VALUE = ${MIN_ANIMATION}+1 ; VALUE <= ${MAX_ANIMATION}; VALUE++)); do | |
| STRING_FOR_ZENITY+="|${VALUE}" | |
| done | |
| echo "${STRING_FOR_ZENITY}" | |
| } | |
| # Show this for stupid lamers (or drunken developer) | |
| function bad_nerd() | |
| { | |
| zenity --warning \ | |
| --ellipsize \ | |
| --title="Yo nerd!" \ | |
| --text="You have won an IP address to attack!\n127.0.0.1\n\nRemember: It has firewall!" | |
| } | |
| ########################## | |
| # zen-sudo LITE EMBEDDED # | |
| ########################## | |
| if [[ `whoami` == "root" ]]; then | |
| main_menu | |
| else | |
| if [[ "`cat /proc/${PPID}/comm`" == "sudo" ]]; then # If called from sudo... | |
| COMMAND="$(cat /proc/${PPID}/cmdline | tr '\0' ' ')" # Detect command line | |
| # └────────────┬──────────┘ └────┬────┘ | |
| # │ └───────────→ Translate all zero bytes with spaces | |
| # └───────────────────────────────→ Print comand line from parent process | |
| zenity --entry \ | |
| --hide-text \ | |
| --title="${ZEN_SUDO_NAME}" \ | |
| --text="${THIS_COMMAND_REQUIRE_ROOT_PERMISSIONS}:\ | |
| \n${COMMAND}\ | |
| \n\n${WORKING_FOLDER}:\ | |
| \n${PWD}\ | |
| \n\n$1" # Showing request with command and current folder | |
| else # If called from user... | |
| export SUDO_ASKPASS="$(realpath "$0")" # I am the guy for the GUI | |
| sudo -A "$(realpath "$0")" "$@" # Request root permissions to myself | |
| SUCCESS="$?" # Read result of sudo: 0 should be great | |
| if [[ "${SUCCESS}" != "0" ]]; then # If wrong with sudo... | |
| zenity --warning\ | |
| --ellipsize\ | |
| --title="${ZEN_SUDO_NAME}" \ | |
| --text="${COMMAND_NOT_EXECUTED}" | |
| fi | |
| fi | |
| fi |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Santech is a rebrand of Clevo laptops. Santech keyboard's backlight needs clevo driver to control leds.
You need to:
makecp clevo-xsm-wmi.ko /lib/modules/$(uname -r)/kernel/drivers/platform/x86/clevo-xsm-wmi.koecho clevo-xsm-wmi > /etc/modules-load.d/clevo-xsm-wmi.confdepmod -arebootNow you can use the script to manage your keyboard's backlight.