123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
#!/bin/sh
# x41t.sh by thurse93
# thurse93[at]gmx.de
# This script was released under public domain.
# Disclaimer: Use this script at your own risk! Some functions might not
# work as expected.
##########
# CONFIG #
##########
# The config section of the script. Make sure to fill out the variables
# and functions correctly.
##### PATHS AND VARIABLES
# Most of the values should be correct for an X41t running ArchLinux
# with thinkpad_acpi loaded (as of 1/2015).
# Path to the sysfs-brightness file. MUST BE WRITEABLE! [achieved for
# example through an entry in your rc.local-script (in case of such old
# machines with tons of tweaks and workarounds it's generally a good
# idea to reactivate rc.local via a systemd-service file)]
#(I know this is ugly but xbacklight's too slow...)
BRIGHTNESSFILE="/sys/devices/virtual/backlight/thinkpad_screen/brightness"
# Brightness minimum (better to keep it zero)
BRIGHTNESSMIN=0
# Brightness maximum (check max_brightness in $BRIGHTNESSFILE-folder)
BRIGHTNESSMAX=7
# Path to the file provided by thinkpad_acpi which gives us information about
# the position of the display.
TABLETMODEFILE="/sys/devices/platform/thinkpad_acpi/hotkey_tablet_mode"
# Name of the default laptop screen and path to the drm-data
LVDS="LVDS1"
LVDSDRMPATH="/sys/class/drm/card0-LVDS-1"
# Name of the VGA-Output and path to the drm-data
VGA="VGA1"
VGADRMPATH="/sys/class/drm/card0-VGA-1"
# A space separated list of the wacom devices to configure.
# Get the IDs with "xsetwacom --list devices"
WACOMIDS="12 13"
# Set the the resolution you need when giving presentations (1024x768 recommended!)
PRESENTATIONRES="1024x768"
##### CUSTOM EXECUTION COMMANDS
# Since these are one line functions make sure to end every command with
# semicolon and space!
# Wallpaper-change-command. Use one for horizontal and one for vertical pictures.
WPCHANGE_H(){ wallpaperchanger /path/to/horizontal/picture; }
WPCHANGE_V(){ wallpaperchanger /path/to/vertical/picture; }
# Additional execution commands for display rotation.
EXEC_NORMAL(){ }
EXEC_RIGHT(){ }
EXEC_INVERTED(){ }
EXEC_LEFT(){ }
# Example config for my x41t. I use them to remap the up and down display keys:
# EXEC_NORMAL(){ xmodmap -e "keycode 111 = Up NoSymbol Up"; xmodmap -e "keycode 116 = Down NoSymbol Down"; }
# EXEC_RIGHT(){ xmodmap -e "keycode 111 = Down NoSymbol Down"; modmap -e "keycode 116 = Up NoSymbol Up"; }
# EXEC_INVERTED(){ xmodmap -e "keycode 111 = Down NoSymbol Down"; xmodmap -e "keycode 116 = Up NoSymbol Up"; }
# EXEC_LEFT(){ xmodmap -e "keycode 111 = Up NoSymbol Up"; xmodmap -e "keycode 116 = Down NoSymbol Down"; }
# GUI program for custom xrandr configuration. arandr recommended.
XRANDRPROG(){ arandr; }
# tablet keyboard programm. onboard or cellwriter recommended.
KEYBOARDPROG(){ onboard; }
##############
# TEST BLOCK #
##############
# check 4 zenity, xsetwacom, xrandr
# brightnessfile writable?
[ ! -w "$BRIGHTNESSFILE" ] && \
{ echo "ERROR: "$BRIGHTNESSFILE" not writeable."; exit 1; }
for program in zenity xsetwacom xrandr
do
command -v $program > /dev/null 2>&1 || \
{ echo >&2 '"$program" not found. Aborting.'; exit 1; }
done
##################
# FUNCTION BLOCK #
##################
#### COMMAND LINE
errorargf(){
echo "ERROR: Wrong Argument. Execute x41t.sh without options for help."
exit 1
}
helpf(){
printf %s "\
BEFORE EXECUTING:
Check the configuration of x41t.sh at the beginning of the script!
SYNTAX:
x41t.sh [option] [argument]
the options and their arguments. [output when given no argument]
brightness: up, down, <brightness level integer>, [current brightness]
rotation: normal, right, inverted, left, [current rotation]
monitor: tablet, presentation, custom, [check for external screens]
keyboard: [executes tablet keyboard command]
zenity: brightness, rotation, monitor, keyboard
"
exit 0
}
# brightness
brightnessf(){
read brightness_current < "$BRIGHTNESSFILE"
case "$1" in
[$BRIGHTNESSMIN-$BRIGHTNESSMAX])
echo $1 > "$BRIGHTNESSFILE"
;;
up)
brightness_up=$((brightness_current+1))
[ "$brightness_up" -gt "$BRIGHTNESSMAX" ] && exit 0
echo $brightness_up > "$BRIGHTNESSFILE"
;;
down)
brightness_down=$((brightness_current-1))
[ "$brightness_down" -lt "$BRIGHTNESSMIN" ] && exit 0
echo $brightness_down > "$BRIGHTNESSFILE"
;;
"")
echo "$brightness_current"
;;
*)
errorargf
;;
esac
}
# rotation
rotationf(){
case "$1" in
normal)
xrandr --output "$LVDS" --auto
xrandr --output "$LVDS" --rotate normal
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i Rotate none; done
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i MapToOutput "$LVDS"; done
WPCHANGE_H
EXEC_NORMAL
;;
right)
xrandr --output "$LVDS" --rotate right
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i Rotate cw; done
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i MapToOutput "$LVDS"; done
WPCHANGE_V
EXEC_RIGHT
;;
inverted)
xrandr --output "$LVDS" --rotate inverted
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i Rotate Half; done
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i MapToOutput "$LVDS"; done
WPCHANGE_H
EXEC_INVERTED
;;
left)
xrandr --output "$LVDS" --rotate left
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i Rotate ccw; done
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i MapToOutput "$LVDS"; done
WPCHANGE_V
EXEC_LEFT
;;
"")
rot_cur=$(xrandr | grep "$LVDS" | cut -d " " -f 4)
case "$rot_cur" in
\(normal) rotation_current="normal";;
right) rotation_current="right";;
inverted) rotation_current="inverted";;
left) rotation_current="left";;
*) echo "ERROR: Couldn't get valid rotation value" && exit 1;;
esac
echo "$rotation_current"
;;
*)
errorargf
;;
esac
}
# monitor
monitorf(){
read vga_state < "$VGADRMPATH"/status
[ "$vga_state" == disconnected ] && { if [ "$2" == zenity ]; then
zenity --error --text "No external screen connected." --title "ERROR" && exit 1
else
echo "ERROR: No external screen connected." && exit 1
fi }
read tablet_mode < "$TABLETMODEFILE"
case "$1" in
presentation)
[ "$tablet_mode" == 1 ] && { if [ "$2" == zenity ]; then
zenity --error --text "Put your display in an upright position." \
--title "ERROR" && return 5
else
echo "ERROR: Put your display in an upright position" && exit 1
fi }
xrandr --output "$LVDS" --off
xrandr --output "$VGA" --mode "$PRESENTATIONRES"
xrandr --output "$LVDS" --auto
WPCHANGE_H
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i MapToOutput "$VGA"; done
;;
tablet)
[ "$tablet_mode" == 0 ] && { if [ "$2" == zenity ]; then
zenity --error --text "Put your display in the tablet position." \
--title "ERROR" && return 5
else
echo "ERROR: Put your display in the tablet position" && exit 1
fi }
[ -z "$XAUTHORITY" ] && { echo "ERROR: No .Xauthority-Path found. No X server running?"; exit 1; }
xrandr --output "$VGA" --off
xrandr --output "$LVDS" --off
xrandr --output "$VGA" --auto
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i Rotate Half; done
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i MapToOutput "$VGA"; done
EXEC_INVERTED
zenity --info --title "Graphics Tablet Mode" --text "Hit OK to return to normal mode"
xrandr --output "$VGA" --off
xrandr --output "$LVDS" --auto
for i in $WACOMIDS; do /usr/bin/xsetwacom --set $i MapToOutput "$LVDS"; done
;;
custom)
[ "$tablet_mode" == 1 ] && { if [ "$2" == zenity ]; then
zenity --error --text "Put your display in an upright position." \
--title "ERROR" && return 5
else
echo "ERROR: Put your display in an upright position" && exit 1
fi }
XRANDRPROG
;;
"")
echo "There's no \$monitor_current defined. Maybe in a later version of this script."
return 0
;;
*)
errorargf
;;
esac
}
# keyboard
keyboardf(){
KEYBOARDPROG
}
#### GRAPHICAL
# brightness
brightnessz(){
brightnessf
if ! brightness_new=$(zenity --scale --title="Set brightness level" \
--text="Brightness" --min-value="$BRIGHTNESSMIN" --max-value=$BRIGHTNESSMAX \
--step=1 --value="$brightness_current"); then
exit;
fi
echo $brightness_new
brightnessf $brightness_new
}
# rotation
rotationz(){
rotationf
SEL_RO_N=FALSE
SEL_RO_R=FALSE
SEL_RO_I=FALSE
SEL_RO_L=FALSE
case "$rotation_current" in
normal) SEL_RO_N=TRUE;;
right) SEL_RO_R=TRUE;;
inverted) SEL_RO_I=TRUE;;
left) SEL_RO_L=TRUE;;
*) zenity --error --text "Couldn't get valid rotation value." \
--title "ERROR" && exit 1;;
esac
if ! i_r=$(zenity --list --text="Choose a rotation" --title="Rotation" \
--radiolist --column="" --column="Rotation" \
$SEL_RO_N Normal \
$SEL_RO_R Right \
$SEL_RO_I Inverted \
$SEL_RO_L Left); then
exit
fi
case "$i_r" in
Normal) rotationf normal;;
Right) rotationf right;;
Inverted) rotationf inverted;;
Left) rotationf left;;
*) echo 'ERROR: Rotation selection "$i_r" not found && exit 1';;
esac
}
# monitor
monitorz(){
monitorf "" zenity # weiß nicht ob das klappt
if ! i_m=$(zenity --list --text="Choose a display mode" \
--title="External Screen" --radiolist \
--column="" --column="Mode" FALSE Presentation TRUE Graphics\ tablet FALSE Custom); then
exit;
fi
case "$i_m" in
Presentation)
monitorf presentation zenity
[ $? -eq 5 ] && monitorf presentation zenity
;;
Graphics\ tablet)
monitorf tablet zenity
[ $? -eq 5 ] && monitorf tablet zenity
;;
Custom)
monitorf custom zenity
[ $? -eq 5 ] && monitorf custom zenity
;;
*)
zenity --error --text "No correct argument '$i_m'." --title "ERROR" && exit 1
;;
esac
}
# zenity main
zenityf(){
case "$1" in
brightness)
brightnessz
;;
rotation)
rotationz
;;
monitor)
monitorz
;;
keyboard)
keyboardf
;;
*)
zenity --error --text "No correct argument '$1'." --title "ERROR" && exit 1
;;
esac
}
##################
# INPUT HANDLING #
##################
option="$1"
argument="$2"
##############
# EVAL BLOCK #
##############
case "$option" in
brightness)
brightnessf "$argument"
;;
rotation)
rotationf "$argument"
;;
monitor)
monitorf "$argument"
;;
keyboard)
keyboardf "$argument"
;;
zenity)
if [ ! -z "$argument" ]; then
zenityf "$argument"
else
if ! i=$(zenity --list --text="Choose an option" \
--title="X41 Tablet Preferences" --radiolist \
--column="" --column="Option" \
TRUE Brightness \
FALSE Rotation \
FALSE Monitor\ mode \
FALSE Keyboard); then
exit;
fi
case "$i" in
Brightness)
argument=brightness
;;
Rotation)
argument=rotation
;;
Monitor\ mode)
argument=monitor
;;
Keyboard)
argument=keyboard
;;
*)
zenity --error --text "No correct argument '$i'." --title "ERROR" && exit 1
;;
esac
zenityf "$argument"
fi
;;
*|-h|--help|help)
helpf
;;
esac