From 895b9b5588e3614b4e313f347b69c8fb7cdc456c Mon Sep 17 00:00:00 2001 From: John Mertz Date: Sun, 15 Nov 2020 23:55:20 -0500 Subject: [PATCH] Thinkpad control scripts SystemD unit file to give ownership or necessary sys files to user toggle_outputs.sh simply swaps between two most common layouts with sway/displays.pl kbd_backlight.pl simply increments the current backlight brightness then %3 to cycle between off, low, high blc.pl is an overly complicated screen backlight control --- thinkpad/blc.pl | 305 +++++++++++++++++++++++ thinkpad/kbd_backlight.pl | 39 +++ thinkpad/toggle_outputs.sh | 9 + thinkpad/user-thinkpad-controls@.service | 8 + 4 files changed, 361 insertions(+) create mode 100755 thinkpad/blc.pl create mode 100755 thinkpad/kbd_backlight.pl create mode 100755 thinkpad/toggle_outputs.sh create mode 100644 thinkpad/user-thinkpad-controls@.service diff --git a/thinkpad/blc.pl b/thinkpad/blc.pl new file mode 100755 index 0000000..d9a4f0e --- /dev/null +++ b/thinkpad/blc.pl @@ -0,0 +1,305 @@ +#!/usr/bin/perl -w + +# Files containing current and max brightness values +my $cur_file = "/sys/class/backlight/intel_backlight/brightness"; +my $max_file = "/sys/class/backlight/intel_backlight/max_brightness"; +my $last_file = "/home/jpm/.config/blc.last"; + +sub to_percent { + my $value = shift; + if ($value eq "Permission Denied") { + return $value; + } else { + $value = int($value/get_max()*100); + return $value . '%'; + } +} + +sub get_offset { + return int(get_max()/100); +} + +sub get_current { + open(my $c,'<',"$cur_file"); + my $current = <$c>; + close $c; + chomp $current; + return $current; +} + +sub get_max { + open(my $m,'<',"$max_file"); + my $max = <$m>; + close $m; + chomp $max; + return $max; +} + +sub get_min { + return int((get_max()/100)+2); +} + +sub writable { + if (! -w $cur_file) { + return 0; + } else { + return 1; + } +} + +sub increment { + if (writable()) { + my $current = get_current(); + my $max = get_max(); + my $target = $current+get_offset(); + if ($target > $max) { + $target = $max; + } + open(my $c,'>',"$cur_file"); + print $c $target; + close $c; + return $target; + } else { + return "Permission Denied"; + } +} + +sub decrement { + if (writable()) { + my $current = get_current(); + my $min = get_min(); + my $target = $current-get_offset(); + if ($target < $min) { + $target = $min; + } + open(my $c,'>',"$cur_file"); + print $c $target; + close $c; + return $target; + } else { + return "Permission Denied"; + } +} + +sub set { + my $value = shift; + if (writable()) { + $current = get_current(); + if ($value > $current) { + for (my $i=$current;$i<=$value;$i++) { + open(my $c,'>',"$cur_file"); + print $c $i; + close $c; + } + } else { + for (my $i=$current;$i>=$value;$i--) { + open(my $c,'>',"$cur_file"); + print $c $i; + close $c; + } + } + return $value; + } else { + return "Permission Denied"; + } +} + +sub help { + print " +Backlight Control + +Usage: blc.pl [--silent|--notify] [OPTION] [VALUE] + +With no option the backlight information is printed as JSON. + +Output printed to STDOUT unless: + +--silent Do not display output (overrides --notify) +--notify Send output to notification daemon. --notify=N will + change the display duration in ms. Default is 200ms + +Output option must preceed the first Action option. + +Actions: + += VALUE Set backlight to specific value. VALUE greater than + 100 will be treated as absolute value. VALUE eqaul to + or less than 100 will be treated as a percentage +++ Increment by 1% ++= VALUE Increment by VALUE percent +-- Decrement by 1% +-= VALUE Decrement by VALUE percent + +Actions corrected to 1% or 100% if over or under. All actions +provide output as a percentage, with the % symbol. + +Final percentage printed as below, skipping other options. + +Print: + +== Print current absolute value +^ Print maximum absolute value +% Print current percentage (does not include % symbol) +--help Help (not impacted by --silent or --notify) +--HELP Advanced help (same as above) + +Any other option will be printed literally"; +} + +sub advanced { + $current = get_current(); + $max = get_max(); + print ". + +Print functions can be strung together but command will exit +with the first non-print option. eg. + + \$ blc.pl == / ^ + 21/100 + \$ blc.pl == ++ + ('==' ignored) + (Backlight incremented) + +Escape options with \\ in quotes to display them literally. eg. + + \$ blc.pl == / ^ '\\=' % \'\\%\' + " . $current . "/" . $max . "=" . int($current/$max*100) . "% + +Only one \'\\' is removed per block. eg. + + \$ blc.pl '\\% \\' + % \\ + +"; +} + +my $current = get_current(); +my (@output, $target, $silent, $notify); + +if (scalar @ARGV) { + for (my $i=0;$i get_max()) { + $target = set(get_max()); + } elsif ($target > 100) { + $target = set($target); + } else { + $target = set(int((get_max()*$target/100)+1)); + } + if ($target eq "Permission Denied") { + @output = $target; + } else { + @output = to_percent($target); + } + last; + } else { + @output = ("No value after $ARGV[$i]"); + last; + } + } elsif ($ARGV[$i] eq '%') { + push @output,int(get_current()/get_max()*100); + } elsif ($ARGV[$i] eq '^') { + push @output,get_max(); + } elsif ($ARGV[$i] eq '==') { + push @output,get_current(); + } elsif ($ARGV[$i] eq '--help') { + help(); + print " (see --HELP).\n\n"; + exit(); + } elsif ($ARGV[$i] eq '--HELP') { + help(); + advanced(); + exit(); + } elsif ($ARGV[$i] eq '--silent') { + $silent = 'TRUE'; + } elsif ($ARGV[$i] =~ /^--notify/) { + $notify = 'TRUE'; + if ($ARGV[$i] =~ /=[0-9]+$/) { + $duration = $ARGV[$i]; + $duration =~ s/.*=([0-9]+)/$1/; + } else { + $duration = 200; + } + } else { + my $add = $ARGV[$i]; + $add =~ s/\\//; + push @output,$add; + } + } +} else { + @output = ('{"Backlight":{"Max":"' . get_max() . '","Current":"' . get_current() . '","Percentage","' . int(get_current()/get_max()*100) . '%"}}'); +} + + +open(my $fh,'>',$last_file); +print $fh get_current(); +close($fh); + +if ($silent) { + exit(); +} elsif ($notify) { + # Don't output anything if the value didn't change + if ($current == get_current()) { + exit(); + } + my $concat; + foreach (@output) { + $concat .= $_; + } + system "notify-send --urgency=normal -i /usr/share/icons/Papirus-Dark-Grey/48x48/status/notification-display-brightness.svg -t $duration \"$concat\""; + exit(); +} else { + print foreach @output; + print "\n"; + exit(); +} diff --git a/thinkpad/kbd_backlight.pl b/thinkpad/kbd_backlight.pl new file mode 100755 index 0000000..e195341 --- /dev/null +++ b/thinkpad/kbd_backlight.pl @@ -0,0 +1,39 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my $maxfile = "/sys/class/leds/tpacpi\:\:kbd_backlight/max_brightness"; +my $current = "/sys/class/leds/tpacpi\:\:kbd_backlight/brightness"; + +my ($max, $now, $new); +if (open(my $m, '<', $maxfile)) { + $max = readline($m); + chomp $max; + close($m); +} else { + print "Failed to read $maxfile\n"; + exit; +} +print STDERR "max = $max\n"; + +if (open(my $c, '<', $current)) { + $now = readline($c); + chomp $now; + close($c); +} else { + print "Failed to read $current\n"; + exit; +} +print STDERR "now = $now\n"; + +if (open(my $fh, '>', $current)) { + $new = (($now+1) % ($max+1)); + chomp $new; + print $fh $new; + close($fh); +} else { + print "Failed to write $current\n"; + exit; +} +print STDERR "new = $new\n"; diff --git a/thinkpad/toggle_outputs.sh b/thinkpad/toggle_outputs.sh new file mode 100755 index 0000000..072718c --- /dev/null +++ b/thinkpad/toggle_outputs.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +CURRENT=`cat /home/jpm/.config/last_display` + +if [ "$CURRENT" == "detached" ]; then + /home/jpm/scripts/sway/displays.pl stacked +else + /home/jpm/scripts/sway/displays.pl detached +fi diff --git a/thinkpad/user-thinkpad-controls@.service b/thinkpad/user-thinkpad-controls@.service new file mode 100644 index 0000000..7d10487 --- /dev/null +++ b/thinkpad/user-thinkpad-controls@.service @@ -0,0 +1,8 @@ +[Unit] +Description=Give ownership of backlight to %I + +[Service] +ExecStart=chown %i:%i /sys/class/backlight/intel_backlight/brightness /sys/class/leds/tpacpi::kbd_backlight/brightness + +[Install] +WantedBy=multi-user.target