Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env bash
- # tivasyk <[email protected]>
- # License: GPU GPL v3
- # Settings
- # --------
- # It's probably a good idea to verify these prior to first use of the script and
- # modify if necessary.
- # IIO devices path (Linux industrial I/O subsystem)
- # One probably does not need to change this
- # iio_devices_path - path to the iio devices buffer tree
- # iio_devices_name - the file containing device name
- iio_devices_path="/sys/bus/iio/devices/iio:device"
- iio_devices_name="name"
- # Accelerometer device path and sensor files
- # accel_device_name - what we expect to find in the ../iio:deviceX/name file
- # accel_device_path - will be populated by identify_device(), may be set to override
- # accel_sensor_x - the channel file of the axis to check for screen rotation (x,y,z)
- accel_device_name="accel_3d"
- accel_device_path=""
- accel_sensor_x="in_accel_x_raw"
- accel_sensor_y="in_accel_y_raw"
- accel_sensor_z="in_accel_z_raw"
- # Current display that will be rotated. This will be populated automatically
- # with the name of connected output (xrandr) by the script if left empty.
- # Otherwise one can fill this in manually to omit automatical detection
- xdisplay=""
- # Input devices (touchpad and touchscreen)
- # One probably needs to run xinput --list to verify the names of the input devices
- # actually present and modify these variables accordingly. Leaving one of them blank
- # will omit rotation for that device.
- touchpad=''
- touchscreen='SYNAPTICS Synaptics Touch Digitizer V04'
- # Error codes
- error_arguments=1 # Incorrect argument(s) either to the script or a function
- error_device=2 # Accelerometer device path or folder structure not found?
- error_sensor=3 # Accelerometer sensor channel file $accel_sensor not found?
- # Functions
- # ---------
- show_help() {
- local NAME
- NAME=$(basename "$0")
- cat <<EOF
- $NAME is a shell script that will check the IIO accelerometer sensor and turn to tablet or laptop mode: set the screen and touchscreen orientation according to rotation, launch onboard keyboard.
- Usage: $NAME [--cont [<interval>]] [--help]
- -h, --help Print this help and quit
- -c, --cont Run continuously at specified interval (default 1s)
- Example: $NAME --cont 2 & # Run the script in the background at 2s intervals
- NOTE: The script has only been tested on Acer Aspire R13 (R7-371T) transformer laptop.
- EOF
- }
- identify_device() {
- # Will look for the device whose name is given as the only argument,
- # by comparing the devices names in /sys/bus/iio/devices/iio:deviceX/name
- # file and return the path to the device folder.
- # Relies on the devices_path variable set in the Setting section.
- # Process arguments:
- if [[ $# -eq 0 ]]; then
- # Incorrect arguments
- exit ${error_arguments}
- else
- local device_name="${1}"
- fi
- # Loop through all devices and check names:
- local device
- for device in "${iio_devices_path}"* ; do
- if [[ $(cat "${device}/${iio_devices_name}") == "${device_name}" ]]; then
- echo "${device}"
- fi
- done
- }
- read_accelerometer() {
- # The first argument is obligatory and should specify one axis
- # of the accelerometer device: -x, -y or -z
- # Also --raw will not try to decode the reading.
- # Process arguments:
- if [[ $# -eq 0 ]]; then
- # Incorrect arguments
- exit ${error_arguments}
- else
- while [[ "$*" != "" ]]; do
- local accel_sensor=${accel_sensor_x}
- case "$1" in
- # Check for --raw option
- "-r"|"--raw" ) local option_raw=1 ; shift ;;
- # Select accelerometer axis (-x is default)
- "-x" ) shift ;;
- "-y" ) accel_sensor=${accel_sensor_y} ; shift ;;
- "-z" ) accel_sensor=${accel_sensor_z} ; shift ;;
- # Ignore any other options
- * ) shift ;;
- esac
- done
- fi
- # Read the sensor:
- if [[ -f "${accel_device_path}/${accel_sensor}" ]]; then
- local reading ; reading=$(cat "${accel_device_path}/${accel_sensor}")
- else
- # No sensor file found?
- exit ${error_sensor}
- fi
- # Decode the reading
- # It's a 16-bit signed integer, but reads as a string
- # 1..1000 : positive angle (0-90°)
- # 65575..54576 : negative angle (0-90°)
- local max_reading=1000
- local max_positive=32767
- local max_integer=65535
- # Decode reading into degrees (unless option_raw in set)
- if [[ -z ${option_raw} ]]; then
- if [[ ${reading} -gt ${max_positive} ]]; then
- echo "$(((reading - max_integer) / (max_reading / 90)))"
- else
- echo "$((reading / (max_reading / 90)))"
- fi
- else
- echo "${reading}"
- fi
- }
- rotate_screen() {
- # Will try to rotate the display and input devices, using:
- # xrandr to rotate the display picture;
- # xinput to rotate the touchpad and touchscreen (via Coordinate Transformation Matrix).
- # Relies on touchpad and touchscreen variables set in the Settings section.
- # Rotate the display:
- xrandr --output $1 --rotate $2
- # Rotate the input devices
- transform='Coordinate Transformation Matrix'
- case "$2" in
- normal)
- [ ! -z "$touchpad" ] && xinput set-prop "$touchpad" "$transform" 1 0 0 0 1 0 0 0 1
- [ ! -z "$touchscreen" ] && xinput set-prop "$touchscreen" "$transform" 1 0 0 0 1 0 0 0 1
- ;;
- inverted)
- [ ! -z "$touchpad" ] && xinput set-prop "$touchpad" "$transform" -1 0 1 0 -1 1 0 0 1
- [ ! -z "$touchscreen" ] && xinput set-prop "$touchscreen" "$transform" -1 0 1 0 -1 1 0 0 1
- ;;
- left)
- [ ! -z "$touchpad" ] && xinput set-prop "$touchpad" "$transform" 0 -1 1 1 0 0 0 0 1
- [ ! -z "$touchscreen" ] && xinput set-prop "$touchscreen" "$transform" 0 -1 1 1 0 0 0 0 1
- ;;
- right)
- [ ! -z "$touchpad" ] && xinput set-prop "$touchpad" "$transform" 0 1 0 -1 0 1 0 0 1
- [ ! -z "$touchscreen" ] && xinput set-prop "$touchscreen" "$transform" 0 1 0 -1 0 1 0 0 1
- ;;
- esac
- }
- main() {
- # Process arguments
- while [[ "$*" != "" ]]; do
- case "$1" in
- "-h"|"--help" )
- show_help
- exit 0
- ;;
- "-c"|"--cont" )
- # Check next argument for repeat interval
- option_cont=1
- shift
- if [[ ! -z "$1" && -z "${1//[0-9.]/}" ]]; then
- option_cont="$1"
- shift
- fi
- ;;
- * )
- ;;
- esac
- done
- # Identify the current display to be rotated
- if [[ "${xdisplay}" == "" ]]; then
- xdisplay=`xrandr --current | grep " connected" | sed -e 's/ .*//g'`
- fi
- # Identify the accelerometer device, unless the accel_device_path has been set manually
- if [[ "${accel_device_path}" == "" ]]; then
- accel_device_path=$(identify_device ${accel_device_name})
- fi
- # Run the test
- while true ; do
- # Get the screen rotation angle from the accelerometer sensor
- angle_x=$(read_accelerometer -x)
- angle_y=$(read_accelerometer -y)
- angle_z=$(read_accelerometer -z)
- # Check orientation
- if [[ ${angle_z//-/} -lt 80 && ${angle_x} -gt 20 ]]; then
- echo "Screen orientation: left (x=${angle_x}, y=${angle_y}, z=${angle_z})"
- rotate_screen ${xdisplay} left
- elif [[ ${angle_z//-/} -lt 80 && ${angle_x} -lt -20 ]]; then
- echo "Screen orientation: right (x=${angle_x}, y=${angle_y}, z=${angle_z})"
- rotate_screen ${xdisplay} right
- elif [[ ${angle_y//-/} -gt 20 && ${angle_x//-/} -lt 20 ]]; then
- echo "Screen orientation: normal (x=${angle_x}, y=${angle_y}, z=${angle_z})"
- rotate_screen ${xdisplay} normal
- else
- echo "Screen orientation: keep (x=${angle_x}, y=${angle_y}, z=${angle_z})"
- fi
- # Run continuously (option_cont)?
- if [[ "${option_cont}" == "" ]]; then
- exit 0
- else
- sleep ${option_cont}
- fi
- done
- }
- main "$@"
Advertisement
Add Comment
Please, Sign In to add comment