From d8fdc47628e4fda11c18a704b075b9a9cdc4cb95 Mon Sep 17 00:00:00 2001 From: clsr Date: Mon, 30 Dec 2019 22:37:38 +0100 Subject: Complete rewrite: make percentage changes more accurate --- bl | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 147 insertions(+), 47 deletions(-) diff --git a/bl b/bl index d75ad3d..84f14d7 100755 --- a/bl +++ b/bl @@ -4,52 +4,152 @@ # It is provided "as is", without warranties or conditions of any kind. # Anyone is free to use, modify, redistribute and do anything with this software. -set -e - -if [ -n "$BACKLIGHT" ]; then - bldir="/sys/class/backlight/$BACKLIGHT" -else - for f in /sys/class/backlight/*; do - if [ -n "$bldir" ]; then - echo "too many backlights found, choose one with \$BACKLIGHT" >&2 - exit 1 +# backlight brightness configuration utility +# +# Requirements: POSIX sh, backlight in /sys/class/backlight/*, +# write permission for $BACKLIGHT/brightness + +set -eu + +sys_backlight="/sys/class/backlight" + +get_bldir() { + bldir= + if [ -n "${BACKLIGHT:-}" ]; then + bldir="$sys_backlight/$BACKLIGHT" + else + for f in "$sys_backlight"/*; do + if [ "$f" = "$sys_backlight/*" ]; then + printf "cannot find a backlight in %s\n" "$sys_backlight" >&2 + exit 1 + elif [ -n "$bldir" ]; then + printf "multiple backlights found, choose one with \$BACKLIGHT\n" >&2 + exit 1 + fi + bldir="$f" + done + fi +} + +read_num() { + read -r data <"$1" + if ! is_num "$data"; then + printf "expected a number reading '%s', but got '%s'\n" "$1" "$data" >&2 + exit 1 + fi + printf %d "$data" +} + +is_num() { + case "$1" in + [0-9]) return 0 ;; + [0-9][0-9]) return 0 ;; + [0-9][0-9][0-9]) return 0 ;; + [0-9][0-9][0-9][0-9]) return 0 ;; + [0-9][0-9][0-9][0-9][0-9]) return 0 ;; + [0-9][0-9][0-9][0-9][0-9][0-9][0-9]) return 0 ;; + [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]) return 0 ;; + [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]) return 0 ;; + # hopefully it's not a >2^32 number + esac + return 1 +} + +get_brightness() { + raw_max="$(read_num "$bldir/max_brightness")" + raw_curr="$(read_num "$bldir/brightness")" + max=100 + curr=$(( (raw_curr + (raw_max / 2 / max)) * max / raw_max )) +} + +get_raw_new() { + op="$1" + val="$2" + raw_new= + new= + + if ! is_num "$val"; then + printf "expected a number for brightness, but got '%s'\n" "$val" >&2 + exit 2 + fi + + case "$op" in + +) : $(( new = curr + val )) ;; + -) : $(( new = curr - val )) ;; + "") : $(( new = val )) ;; + =+) : $(( raw_new = raw_curr + val )) ;; + =-) : $(( raw_new = raw_curr - val )) ;; + =) : $(( raw_new = val )) ;; + *) + printf "invalid operator '%s'\n" "$op" >&2 + exit 2 + ;; + esac + if [ -n "$new" ]; then + : $(( raw_new = new * raw_max / max )) + fi + if [ -n "$raw_new" ]; then + if [ "$raw_new" -gt "$raw_max" ]; then + raw_new="$raw_max" fi - bldir="$f" - done -fi -if [ -z "$bldir" ] || ! [ -d "$bldir" ]; then - echo "no backlight found" >&1 - exit 1 -fi -curr=$(($(cat "$bldir/brightness")+0)) -max=$(($(cat "$bldir/max_brightness")+0)) -mod="$1" -case "$mod" in - +|-) - new="$((curr${mod}max/100))" - ;; - +[1-9]*|-[1-9]*) - new="$((curr$mod*max/100))" - ;; - [0-9]*) - new="$((mod*max/100+1))" - ;; - =[0-9]*) - new="${mod#=*}" - ;; - =) - echo "$curr" - exit - ;; - '') - echo "$((curr*100/max))" - exit - ;; - *) - echo "usage: $(basename "$0") [ +-=][0-100]" >&2 + if [ "$raw_new" -le 0 ]; then + # brightness 0 tends to completely turn off the backlight + raw_new=1 + fi + fi +} + +set_brightness() { + get_raw_new "$1" "$2" + printf %d "$raw_new" > "$bldir/brightness" +} + +usage() { + prog="$(basename "$0")" + printf "%s: usage: %s OPERATOR\n" "$prog" "$prog" + printf "\n" + printf "Operators:\n" + printf " (none) print current brightness in percentages\n" + printf " PERC set brightness to PERC percentages of max\n" + printf " +PERC increase brightness by PERC percentage points\n" + printf " -PERC decrease brightness by PERC percentage points\n" + printf " = print current brightness raw value\n" + printf " VAL set brightness to VAL raw value\n" + printf " =+VAL increase brightness by VAL raw value\n" + printf " =-VAL decrease brightness by VAL raw value\n" + printf "\n" + printf "Environment variables:\n" + printf " BACKLIGHT the backlight in %s/ to use\n" "$sys_backlight" + printf " (unnecessary if only one exists)\n" +} + +main() { + if [ $# -gt 1 ]; then + usage >&2 exit 2 - ;; -esac -[ "$new" -gt "$max" ] && new="$max" -[ "$new" -lt 1 ] && new=1 -echo "$new" > "$bldir/brightness" + fi + if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then + usage + exit + fi + get_bldir + get_brightness + op="${1:-}" + case "$op" in + "") printf "%d\n" "$curr" ;; + +[0-9]*) set_brightness + "${op#+}" ;; + -[0-9]*) set_brightness - "${op#-}" ;; + [0-9]*) set_brightness "" "$op" ;; + =) printf "%d\n" "$raw_curr" ;; + =+[0-9]*) set_brightness "=+" "${op#=+}" ;; + #+=[0-9]*) set_brightness "=+" "${op#+=}" ;; + =-[0-9]*) set_brightness "=-" "${op#=-}" ;; + #-=[0-9]*) set_brightness "=-" "${op#-=}" ;; + =[0-9]*) set_brightness "=" "${op#=}" ;; + *) + printf "invalid operator: '%s'\n" "$op" >&2 + exit 2 + esac +} + +main "$@" -- cgit