commit ab49ee4cee9d4afe134f723521de74634e6e429a Author: Matthias Janetschek Date: Tue Oct 2 20:14:20 2018 +0200 Initial commit. diff --git a/etc/acpi/events/thinkpad-favbutton b/etc/acpi/events/thinkpad-favbutton new file mode 100644 index 0000000..b7df187 --- /dev/null +++ b/etc/acpi/events/thinkpad-favbutton @@ -0,0 +1,2 @@ +event=ibm/hotkey LEN0268:00 00000080 00001315 +action=/etc/acpi/thinkpad-favbutton.sh diff --git a/etc/acpi/events/thinkpad-kdb-backlight b/etc/acpi/events/thinkpad-kdb-backlight new file mode 100644 index 0000000..df6cbef --- /dev/null +++ b/etc/acpi/events/thinkpad-kdb-backlight @@ -0,0 +1,2 @@ +event=ibm/hotkey LEN0268:00 00000080 00001315 +action=/etc/acpi/thinkpad-kdb-backlight.sh diff --git a/etc/acpi/events/thinkpad-tabletmode b/etc/acpi/events/thinkpad-tabletmode new file mode 100644 index 0000000..97d54eb --- /dev/null +++ b/etc/acpi/events/thinkpad-tabletmode @@ -0,0 +1,2 @@ +event=video/tabletmode +action=/etc/acpi/thinkpad-tabletmode.sh %e diff --git a/etc/acpi/thinkpad-autorotate.py b/etc/acpi/thinkpad-autorotate.py new file mode 100755 index 0000000..1646e34 --- /dev/null +++ b/etc/acpi/thinkpad-autorotate.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python2 +""" +thinkpad-rotate.py + +Rotates any detected screen, wacom digitizers, touchscreens, +touchpad/trackpoint based on orientation gathered from accelerometer. + +Tested with Lenovo Thinkpad Yoga S1 + +https://github.com/admiralakber/thinkpad-yoga-scripts + +Acknowledgements: +Modified from source: +https://gist.githubusercontent.com/ei-grad/4d9d23b1463a99d24a8d/raw/rotate.py + +""" + +### BEGIN Configurables + +rotate_pens = True # Set false if your DE rotates pen for you +disable_touchpads = False # Don't use in conjunction with tablet-mode +ignore_touchpads = True +grace_time = 3 + +### END Configurables + + +from time import sleep, time +from os import path as op +import sys +from subprocess import check_call, check_output +from glob import glob +from os import environ + +def bdopen(fname): + return open(op.join(basedir, fname)) + + +def read(fname): + return bdopen(fname).read() + + +for basedir in glob('/sys/bus/iio/devices/iio:device*'): + if 'accel' in read('name'): + break +else: + sys.stderr.write("Can't find an accellerator device!\n") + sys.exit(1) + + +env = environ.copy() + +scale = float(read('in_accel_scale')) + +g = 7.0 # (m^2 / s) sensibility, gravity trigger + +STATES = [ + {'rot': 'normal', 'pen': 'none', 'coord': '1 0 0 0 1 0 0 0 1', 'touchpad': 'enable', + 'check': lambda x, y: y <= -g}, + {'rot': 'inverted', 'pen': 'half', 'coord': '-1 0 1 0 -1 1 0 0 1', 'touchpad': 'disable', + 'check': lambda x, y: y >= g}, + {'rot': 'left', 'pen': 'ccw', 'coord': '0 -1 1 1 0 0 0 0 1', 'touchpad': 'disable', + 'check': lambda x, y: x >= g}, + {'rot': 'right', 'pen': 'cw', 'coord': '0 1 0 -1 0 1 0 0 1', 'touchpad': 'disable', + 'check': lambda x, y: x <= -g}, +] + + +def rotate(state): + s = STATES[state] + check_call(['/usr/local/bin/thinkpad-rotate.rb', s['rot']], env=env) + +def read_accel(fp): + fp.seek(0) + return float(fp.read()) * scale + + +if __name__ == '__main__': + + accel_x = bdopen('in_accel_x_raw') + accel_y = bdopen('in_accel_y_raw') + + current_state = None + + next_state=None + next_ts=0.0 + + while True: + x = read_accel(accel_x) + y = read_accel(accel_y) + for i in range(4): + if i == current_state: + continue + if STATES[i]['check'](x, y): + ts = time() + if not next_state == i: + next_state = i + next_ts = ts + elif ts - next_ts >= grace_time: + current_state = i + rotate(i) + break + sleep(1) + diff --git a/etc/acpi/thinkpad-favbutton.sh b/etc/acpi/thinkpad-favbutton.sh new file mode 100755 index 0000000..fb81d95 --- /dev/null +++ b/etc/acpi/thinkpad-favbutton.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +# ToDo diff --git a/etc/acpi/thinkpad-kdb-backlight.sh b/etc/acpi/thinkpad-kdb-backlight.sh new file mode 100755 index 0000000..236d18b --- /dev/null +++ b/etc/acpi/thinkpad-kdb-backlight.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +DEVICE=/sys/devices/platform/thinkpad_acpi/leds/tpacpi\:\:kbd_backlight/brightness +CUR_VAL=$(cat $DEVICE) + +case $CUR_VAL in + 0) + echo "1" > $DEVICE + ;; + 1) + echo "2" > $DEVICE + ;; + 2) + echo "0" > $DEVICE + ;; +esac diff --git a/etc/acpi/thinkpad-tabletmode.sh b/etc/acpi/thinkpad-tabletmode.sh new file mode 100755 index 0000000..1e339f2 --- /dev/null +++ b/etc/acpi/thinkpad-tabletmode.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +MODE=$4 +USER=$(ps aux | grep startkde | grep -v sddm | grep -v grep | awk '{print $1}') + +export DISPLAY=:0 + +case $MODE in + 00000001) + # Tabletmode ON + sudo -u $USER xinput set-prop "SynPS/2 Synaptics TouchPad" "Device Enabled" 0 + sudo -u $USER xinput set-prop "TPPS/2 Elan TrackPoint" "Device Enabled" 0 + sudo -u $USER /etc/acpi/thinkpad-autorotate.py & + sudo -u $USER /usr/bin/onboard & + ;; + 00000000) + # Tabletmode OFF + sudo -u $USER xinput set-prop "SynPS/2 Synaptics TouchPad" "Device Enabled" 1 + sudo -u $USER xinput set-prop "TPPS/2 Elan TrackPoint" "Device Enabled" 1 + pkill -f thinkpad-autorotate.py + pkill -f /usr/bin/onboard + sudo -u $USER /usr/local/bin/thinkpad-rotate.rb normal + ;; +esac diff --git a/usr/local/bin/thinkpad-rotate.rb b/usr/local/bin/thinkpad-rotate.rb new file mode 100755 index 0000000..18e4ac4 --- /dev/null +++ b/usr/local/bin/thinkpad-rotate.rb @@ -0,0 +1,116 @@ +#!/usr/bin/ruby + +# ./grox.rb +# +left, +right, flip: relative movement +# left, right, normal, inverted: absolute movement + +# devices to manipulate +$screen = 'eDP-1' +$touchscreen1 = 'Wacom Pen and multitouch sensor Pen stylus' +$touchscreen2 = 'Wacom Pen and multitouch sensor Pen eraser' +$touchscreen3 = 'Wacom Pen and multitouch sensor Finger touch' +$touchpad = '' +$keyboard = 'AT Translated Set 2 keyboard' + +# disable keypad and touchpad on all but normal orientation +#$controlKeys = true +$controlKeys = false + +# runs cmd and greps output to find orientation +$orientationCmd = 'xrandr' +$orientationRE = /\s*#{$screen}\s+\w+\s+\w+\s+\d+x\d+\+\d+\+\d+\s+(|left|right|inverted)\s*\(/ + +# default direction +$defaultDirection = '+right' + + +# CODE + +def main() + direction = $defaultDirection + + if ARGV.length > 0 + direction = ARGV[0] + end + + doOrientate(getNewOrientation(direction)) +end + + +def orientateCmd(orientation, transform) + rotateScreen = "xrandr --output #{$screen}" + + " --rotate #{orientation}"; + rotateTouchscreen1 = "xsetwacom --set '#{$touchscreen1}' Rotate #{transform}" + rotateTouchscreen2 = "xsetwacom --set '#{$touchscreen2}' Rotate #{transform}" + rotateTouchscreen3 = "xsetwacom --set '#{$touchscreen3}' Rotate #{transform}" + + + controlKeys = "" + if $controlKeys + setCmd = orientation == 'normal' ? 'xinput --enable ' + : 'xinput --disable ' + controlKeys = "#{setCmd} '#{$touchpad}'; #{setCmd} '#{$keyboard}';" + end + + return controlKeys + + rotateScreen + ';' + + rotateTouchscreen1 + ';' + + rotateTouchscreen2 + ';' + + rotateTouchscreen3 + ';' +end + + +def doOrientate(orientation) + case orientation + when 'normal' + `#{orientateCmd('normal', 'none')}` + when 'left' + `#{orientateCmd('left', 'ccw')}` + when 'right' + `#{orientateCmd('right', 'cw')}` + when 'inverted' + `#{orientateCmd('inverted', 'half')}` + else + raise "Don't know how to orientate to #{orientation}" + end +end + + +# returns direction of $screen: left, right, normal or invert +def getOrientation() + if `#{$orientationCmd}` =~ $orientationRE + return $1 == '' ? 'normal' : $1 + else + raise "Could not determine orientation of #{$screen} from #{$orientationCmd}" + end +end + + +# direction should be +left, +right, flip, left, right, normal, or inverted +def getNewOrientation(direction) + clockwise = ['normal', 'right', 'inverted', 'left'] + + if clockwise.include?(direction) + return direction + else + curdir = clockwise.find_index(getOrientation()) + + shift = case direction + when '+left' then -1 + when '+right' then 1 + when 'flip' then 2 + else + raise "Unrecognised rotate direction #{direction}" + end + + newdir = (curdir + shift) % 4 + + return clockwise[newdir] + end +end + + +# DO +main() + +