]> git.donarmstrong.com Git - deb_pkgs/autorandr.git/blobdiff - autorandr
removed trailing slash
[deb_pkgs/autorandr.git] / autorandr
index 90d110831ba0a9efe1c3f2aeefdeb3aa1ae799e0..ef750e2b2aba218d86287f4e67e2337c876f4377 100755 (executable)
--- a/autorandr
+++ b/autorandr
 XRANDR=/usr/bin/xrandr
 DISPER=/usr/bin/disper
 XDPYINFO=/usr/bin/xdpyinfo
-PROFILES=~/.autorandr/
+PROFILES=~/.autorandr
 CONFIG=~/.autorandr.conf
+RESERVED_PROFILE_NAMES=`cat <<EOF
+ common     Clone all connected outputs at the largest common resolution
+ horizontal Stack all connected outputs horizontally at their largest resolution
+ vertical   Stack all connected outputs vertically at their largest resolution
+EOF`
 
 CHANGE_PROFILE=0
 FORCE_LOAD=0
@@ -159,6 +164,95 @@ current_cfg_disper() {
        $DISPER -p
 }
 
+common_cfg_xrandr() {
+       $XRANDR -q | awk '
+       # variables:
+       #   output: current output
+       #   outputlist: space sep list of all outputs
+       #   outputarr: array of all connected outputs
+       #   outputarrsize: number of connected outputs
+       #   modelist[800x600]: space sep list of outputs supporting mode
+       # display is connected
+       /^[^ ]+ connected / {
+           output=$1;
+           outputlist=outputlist " " output
+           outputarr[outputarrsize++]=output
+       }
+       # disconnected or disabled displays
+       /^[^ ]+ disconnected / ||
+       /^[^ ]+ unknown connection / {
+           print "output " $1;
+           print "off";
+       }
+       # modes available on a screen
+       /^   [0-9]+x[0-9]+/ {
+           modelist[$1]=modelist[$1] " " output
+       }
+       END {
+           # find common mode with largest screen area
+           for (m in modelist) {
+               if (modelist[m] == outputlist) {
+                   # calculate area of resolution
+                   split(m, wh, "x");
+                   if (wh[1]*wh[2] >= maxdim) {
+                       maxdim=wh[1]*wh[2]
+                       maxmode=m
+                   }
+               }
+           }
+           if (maxmode) {
+               for (i in outputarr) {
+                   print "output " outputarr[i];
+                   print "mode " maxmode;
+                   print "pos 0x0";
+                   if (i > 0) {
+                       print "same-as " outputarr[0]
+                   }
+               }
+           }
+       }' \
+               | load_cfg_xrandr -
+}
+
+stack_cfg_xrandr() {
+       $XRANDR -q | awk -v stack="${STACK}" '
+       # variables:
+       #   stack: "horizontal" (anything except vertical) or "vertical"
+       #   output: current output
+       #   firstmode: pick first mode after output
+       #   posX,posY: position of the next output
+       BEGIN {
+           posX=posY=0
+       }
+       # display is connected
+       /^[^ ]+ connected / {
+           output=$1;
+           print "output " $1;
+           firstmode=1
+       }
+       # disconnected or disabled displays
+       /^[^ ]+ disconnected / ||
+       /^[^ ]+ unknown connection / {
+           print "output " $1;
+           print "off";
+       }
+       # modes available on a screen, but pick only the first
+       /^   [0-9]+x[0-9]+/ {
+           if (!firstmode) next;
+           firstmode=0
+           # output mode at current virtual desktop pos
+           print "mode " $1;
+           print "pos " posX "x" posY;
+           # calculate position of next output
+           split($1, wh, "x");
+           if (stack == "vertical")
+               posY += wh[2];
+           else
+               posX += wh[1];
+       }' \
+               | load_cfg_xrandr -
+}
+
 current_cfg() {
        $CURRENT_CFG_METHOD;
 }
@@ -212,7 +306,13 @@ load_cfg_disper() {
 load() {
        local PROFILE="$1"
        local CONF="$PROFILES/$PROFILE/config"
-       [ -f "$CONF" ] || return 1
+       local IS_VIRTUAL_PROFILE=`echo "$RESERVED_PROFILE_NAMES" | grep -c "^ $PROFILE "`
+
+       if [ ! -f "$CONF" -a $IS_VIRTUAL_PROFILE -eq 0 ]; then
+               echo " -> Error: Profile '$PROFILE' does not exist." >&2
+               return
+       fi
+
        if [ -x "$PROFILES/preswitch" ]; then
                "$PROFILES/preswitch" "$PROFILE"
        fi
@@ -220,8 +320,25 @@ load() {
                "$PROFILES/$PROFILE/preswitch" "$PROFILE"
        fi
 
-       echo " -> loading profile $PROFILE"
-       $LOAD_METHOD "$CONF"
+       if [ -f "$CONF" ]; then
+               echo " -> loading profile $PROFILE"
+               if [ $IS_VIRTUAL_PROFILE -ne 0 ]; then
+                       echo " -> Warning: Existing profile overrides virtual profile with same name" >&2
+               fi
+               $LOAD_METHOD "$CONF"
+       else
+               # Virtual profiles
+               if [ $PROFILE = "common" ]; then
+                       echo " -> setting largest common mode in cloned mode"
+                       common_cfg_xrandr
+               elif [ $PROFILE = "horizontal" ]; then
+                       echo " -> stacking all outputs horizontally at their largest modes"
+                       STACK="horizontal" stack_cfg_xrandr
+               elif [ $PROFILE = "vertical" ]; then
+                       echo " -> stacking all outputs vertically at their largest modes"
+                       STACK="vertical" stack_cfg_xrandr
+               fi
+       fi
 
        if [ -x "$PROFILES/$PROFILE/postswitch" ]; then
                "$PROFILES/$PROFILE/postswitch" "$PROFILE"
@@ -260,6 +377,9 @@ Usage: $SCRIPTNAME [options]
  When called by the name "autodisper" or "auto-disper", the script uses "disper"
  instead of "xrandr" to detect, configure and save the display configuration.
 
+ If xrandr is used, the following virtual configurations are available:
+${RESERVED_PROFILE_NAMES}
+
 EOH
        exit
 }
@@ -286,6 +406,10 @@ done
 CURRENT_SETUP="$(setup_fp)"
 
 if [ -n "$SAVE_PROFILE" ]; then
+       if echo "$RESERVED_PROFILE_NAMES" | grep -q "^ $SAVE_PROFILE "; then
+               echo "Cannot save current configuration as profile '${SAVE_PROFILE}': This configuration name is a reserved virtual configuration."
+               exit 1
+       fi
        echo "Saving current configuration as profile '${SAVE_PROFILE}'"
        mkdir -p "$PROFILES/$SAVE_PROFILE"
        echo "$CURRENT_SETUP" > "$PROFILES/$SAVE_PROFILE/setup"
@@ -331,3 +455,10 @@ if [ -n "$DEFAULT_PROFILE" ]; then
        load "$DEFAULT_PROFILE"
 fi
 exit 1
+
+# Local Variables:
+# tab-width: 8
+# sh-basic-offset: 8
+# sh-indentation: 8
+# indent-tabs-mode: t
+# End: