diff --git a/contrib/rotate-screen/rotate-screen b/contrib/rotate-screen/rotate-screen index 99584b44f..44013bc28 100755 --- a/contrib/rotate-screen/rotate-screen +++ b/contrib/rotate-screen/rotate-screen @@ -16,33 +16,141 @@ # Run as root: NO # Run in alternate directory: NO # -# Anchestors: +# A possible .desktop file can look like this: +# [Desktop Entry] +# Encoding=UTF-8 +# Version=1.0 +# Name=Rotate +# Comment=Rotate Screen +# Type=Application +# Exec=rotate-screen +# Icon=rotation-allowed-symbolic +# Terminal=false +# Categories=Settings +# StartupNotify=true +# and could be saved in ~/.local/share/applications/rotate-screen.desktop +# +# Anchestors and ideas: # mildmojo # https://gist.github.com/mildmojo/48e9025070a2ba40795c # mbinnun: # https://gist.github.com/mildmojo/48e9025070a2ba40795c#gistcomment-2694429 -# +# frgomes: +# https://github.com/frgomes/bash-scripts/blob/develop/bin/rotate -# Check for commands needed -GDBUS=$(which gdbus) -if test -z $GDBUS; then - echo "Command 'gdbus' not found." - exit 1 -fi - -XINPUT=$(which xinput) -if test -z $XINPUT; then - echo "Command 'xinput' not found." - exit 2 -fi - -XRANDR=$(which xrandr) -if test -z $XRANDR; then - echo "Command 'xrandr' not found." -fi +GDBUS=gdbus +XINPUT=xinput +XRANDR=xrandr -get_orientation () { +usage () { + # Display the usage + # + # No options + + cat < left -> inverted + -> right -> normal (option "next") or in reversed order (option "previous") + with each call of this script. + Usage: + - Disable automatic screen rotation in the settings for your desktop + environment. + - Call this script with "$0 next|previous". + Pre-requisites: + Programs: $XINPUT, $XRANDR + Hardware: -- + Package: -- +4. One-shot rotation (manual): + Independent of the actual orientation of the device, the orientation is + set to the given orientation. + Usage: + - Disable automatic screen rotation in the settings for your desktop + environment. + - Call this script with "$0 normal|inverted|left|right". + Pre-requisites: + Programs: $XINPUT, $XRANDR + Hardware: -- + Package: -- + +Note: + Sometimes not all pointing devices are rotated. The reason is, that the + pointing device was not active at the time of rotation, as can happen with + e.g. bluetooth pens. In that case simply call the script again with the + same parameter. + + +Parameters: + -h, --help Display this help and exit. + screen, next, normal, left, inverted, right + The new orientation (optional). The default behaviour (no + option) is to use the orientation from the built-in + accelerometer. If 'screen' is given, use the screen's + current orientation. 'next' will switch to the next + orientation and any other option switches to the specified + orientation, regardless of the device's or the screen's + actual orientation. +EOF + +} + + +check_commands () { + # Check for commands needed + # + # $1: The required orientation + + if test $1 = auto; then + GDBUS=$(which $GDBUS) + if test -z $GDBUS; then + echo "Command 'gdbus' not found." + exit 10 + fi + fi + + XINPUT=$(which $XINPUT) + if test -z $XINPUT; then + echo "Command 'xinput' not found." + exit 11 + fi + + XRANDR=$(which $XRANDR) + if test -z $XRANDR; then + echo "Command 'xrandr' not found." + exit 12 + fi +} + + +get_dbus_orientation () { # Get the orientation from the DBus # # No options. @@ -54,10 +162,14 @@ get_orientation () { ORIENTATION=$($GDBUS call $DBUS \ --method org.freedesktop.DBus.Properties.Get \ net.hadess.SensorProxy HasAccelerometer) - if test "$ORIENTATION" != "(,)"; then - echo "No sensor available! " - echo "(Do you have the 'iio-sensor-proxy' package installed and enabled?)" - exit 10 + if test $? != 0; then + echo $ORIENTATION + echo " (Is the 'iio-sensor-proxy' package installed and enabled?)" + exit 20 + elif test "$ORIENTATION" != "(,)"; then + echo "No sensor available!" + echo " (Does the computer has a hardware accelerometer?)" + exit 21 fi # Get the orientation from the DBus @@ -84,7 +196,29 @@ get_orientation () { ;; *) echo "Orientation $ORIENTATION unknown!" - exit 11 + echo " (Known orientations are: normal, bottom-up, left-up and right-up.)" + exit 22 + esac + + # Return the orientation found + echo $ORIENTATION +} + + +get_screen_orientation () { + # Get the orientation from the current screen orientation + # + # $1: The screen + + ORIENTATION=$($XRANDR --current --verbose | grep $1 | cut --delimiter=" " -f6) + + case $ORIENTATION in + normal|inverted|left|right) + ;; + *) + echo "Current screen orientation $ORIENTATION unknown!" + exit 23 + ;; esac # Return the orientation found @@ -95,17 +229,24 @@ get_orientation () { do_rotate () { # Rotate screen and pointers # - # $1: The new orientation - # $2: The screen to rotate - # $3-: The pointers to rotate + # $1: The requested mode (only "screen" gets a special treatment) + # $2: The new orientation + # $3: The screen to rotate + # $4-: The pointers to rotate TRANSFORM='Coordinate Transformation Matrix' + MODE=$1 + shift + ORIENTATION=$1 shift # Rotate the screen - $XRANDR --output $1 --rotate $ORIENTATION + if test $MODE != screen; then + # Only rotate it, if we have not got the orientation from the screen + $XRANDR --output $1 --rotate $ORIENTATION + fi shift # Rotate all pointers @@ -129,20 +270,110 @@ do_rotate () { } +# Process the command line options +MODE=auto +while true; do + case $1 in + -h|--help) + usage + exit + ;; + *) + if test $# -eq 0; then + break + fi + MODE=$1 + shift + ;; + esac +done + +# Check, if all commands, which are needed, are available +check_commands $MODE + +# Get the display +XDISPLAY=$($XRANDR --current --verbose | grep primary | cut --delimiter=" " -f1) + # Get the tablet's orientation -ORIENTATION=$(get_orientation) -ret=$? -if test $ret != 0; then - echo $ORIENTATION - exit $ret -fi +case $MODE in + auto) + ORIENTATION=$(get_dbus_orientation) + ret=$? + if test $ret != 0; then + echo $ORIENTATION + echo "(To use this script, supply the orientation normal, inverted, left or right on the command line.)" + exit $ret + fi + ;; + screen) + ORIENTATION=$(get_screen_orientation $XDISPLAY) + ret=$? + if test $ret != 0; then + echo $ORIENTATION + exit $ret + fi + ;; + next) + ORIENTATION=$(get_screen_orientation $XDISPLAY) + ret=$? + if test $ret != 0; then + echo $ORIENTATION + exit $ret + fi + case $ORIENTATION in + normal) + ORIENTATION=left + ;; + left) + ORIENTATION=inverted + ;; + inverted) + ORIENTATION=right + ;; + right) + ORIENTATION=normal + ;; + *) + ORIENTATION=normal + ;; + esac + ;; + previous) + ORIENTATION=$(get_screen_orientation $XDISPLAY) + ret=$? + if test $ret != 0; then + echo $ORIENTATION + exit $ret + fi + case $ORIENTATION in + normal) + ORIENTATION=right + ;; + left) + ORIENTATION=normal + ;; + inverted) + ORIENTATION=left + ;; + right) + ORIENTATION=inverted + ;; + *) + ORIENTATION=normal + ;; + esac + ;; + normal|inverted|left|right) + ORIENTATION=$MODE + ;; + *) + echo "Unknown command line parameter orientation $MODE" + exit 1 +esac # Get all pointers POINTERS=$($XINPUT | grep slave | grep pointer | sed -e 's/^.*id=\([[:digit:]]\+\).*$/\1/') -# Get the display and its orientation -XDISPLAY=$($XRANDR --current --verbose | grep primary | cut --delimiter=" " -f1) - # Rotate the screen and pointers echo "Rotate display $XDISPLAY to $ORIENTATION orientation (Pointers: $(echo $POINTERS | sed 's/\n/ /g'))" -do_rotate $ORIENTATION $XDISPLAY $POINTERS +do_rotate $MODE $ORIENTATION $XDISPLAY $POINTERS