#!/bin/sh
# Rotates the XO screen 90 degrees on every invocation

# fifo where commands to rotate the touchpad may be written
CMD_FIFO=/var/run/olpc-kbdshim_command

case $1 in
    # -e and -n enable/disable axis reflection for the touchpad.  this
    # allows "normal" use of the touchpad when you're in ebook mode
    # and crack open the laptop slightly to use the touchpad.  otherwise
    # the both directions are reversed.
-e) echo Z >$CMD_FIFO; exit 0;;
-n) echo z >$CMD_FIFO; exit 0;;

    # -r resets touchpad rotation to "normal" (unrotated)
-r) echo n >$CMD_FIFO; exit 0;;

    # usual case -- just rotate
"") ;;

*) echo "usage: $0 [-e|-n|-r]" >&2 ; exit 1;;
esac

get_x_credentials()
{
    # fetch the local X server's XAUTHORITY variable
    eval "$( xargs -n 1 -0 < /proc/$(pidof X)/environ | grep '^XAUTHORITY=')"
    export XAUTHORITY
    export DISPLAY=:0

}

test "$XAUTHORITY" || get_x_credentials

# get current screen orientation
if ! xrandrout=$(xrandr --query)
then
    echo xrandr query failed >&2
    exit 1
fi

# pick up the output device and its current rotation from the same line.
# the line looks like:
#  LCD connected 900x1200+0+0 right (normal left inverted right x axis y axis) 0mm x 0mm
# the first word ("LCD") is the output device, "right" is the current
# rotation, but in the "normal" case, the word "right" will be missing
# entirely.

set -- $(echo "$xrandrout" |
    sed -n 's/^\([a-zA-Z0-9]\+\) *connected .*[0-9] \([a-z]*\) *(.*/\1 \2/p')

output="$1"
now="$2"


# some xrandr/X11-driver implementations will rotate the screen
# the wrong way:
# - xorg-x11-drv-geode library in F9-based OLPC releases 
# - SWRandR in F11-based OLPC releases
#
# in those cases, we allow olpc-utils to set a flag so we can
# reverse what we tell xrandr to do.  note that in this case
# xrandr will be reporting the wrong thing too in $now.

if [ -e /var/run/olpc-rotate-reverse ]
then  # assume xrand reports and performs mirrored rotation.
    case $now in
    left)       scrnew=normal;   new=normal;;
    inverted)   scrnew=left;     new=right;;
    right)      scrnew=inverted; new=inverted;;
    ""|normal)  scrnew=right;    new=left;;
    *)          scrnew=normal;   new=normal;;
    esac
else
    # we always want to cycle the screen counterclockwise
    case $now in
    left)       new=inverted;;
    inverted)   new=right;;
    right)      new=normal;;
    ""|normal)  new=left;;
    *)          new=normal;;
    esac

    scrnew="$new" 
fi

# set the new rotation, and inform kbdshim to rotate the touchpad.
xrandr --output $output --rotate $scrnew && \
    test -e $CMD_FIFO && echo $new >$CMD_FIFO


