Ver código fonte

New command line options and functionality.

- Orientation can be get from the accelerometer or the current screen orientation (`rotate-screen` or `rotate-screen screen`).
- Orientation can be switched to the next orientation (`rotate-screen next`: normal->left->inverted->right->normal or `rotate-screen previous`).
- Orientation can be specified at the command line (`rotate-screen normal|left|inverted|right`).

I hope this covers most use cases!
sphh 4 anos atrás
pai
commit
3ed56ea599
1 arquivos alterados com 268 adições e 37 exclusões
  1. 268 37
      contrib/rotate-screen/rotate-screen

+ 268 - 37
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
+
+GDBUS=gdbus
+XINPUT=xinput
+XRANDR=xrandr
+
+
+usage () {
+    # Display the usage
+    #
+    # No options
+
+    cat <<EOF
+$(basename $0) [-h|--help] [screen|next|previous|normal|left|inverted|right]
+
+Rotate the screen and all pointing devices (touchscreens, pens, touchpads, ...)
+
+The script can handle the following typical use cases:
+1. One-shot rotation (automatic detection):
+   You hold the device in the new orientation desired and invoke this script.
+   The screen and all pointing devices rotate.
+   Usage:
+      - Disable automatic screen rotation in the settings for your desktop
+        environment.
+      - Hold the device in the new orientation and call this script with "$0".
+   Pre-requisites:
+      Programs: $GDBUS, $XINPUT, $XRANDR
+      Hardware: Accelerometer
+      Package: iio-sensor-proxy
+2. Automatic screen rotation, but pointing devices do not rotate:
+   The orientation of the screen is set by the desktop environment, but the
+   pointing devices are not.
+   Usage:
+      - Enable automatic screen rotation in the settings for your desktop
+        environment.
+      - Hold the device in the new orientation and call this script with
+        "$0 screen".
+   Pre-requisites:
+      Programs: $XINPUT, $XRANDR
+      Hardware: --
+      Package: --
+3. Cycle through screen rotations:
+   The orientation of the screen is cycled through normal -> 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: --
 
-# Check for commands needed
-GDBUS=$(which gdbus)
-if test -z $GDBUS; then
-    echo "Command 'gdbus' not found."
-    exit 1
-fi
+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 2
-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."
-fi
+    XRANDR=$(which $XRANDR)
+    if test -z $XRANDR; then
+        echo "Command 'xrandr' not found."
+        exit 12
+    fi
+}
 
 
-get_orientation () {
+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" != "(<true>,)"; 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" != "(<true>,)"; 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