From 016e1ceef560a72b5780c34b921bff1ba1f9b2c2 Mon Sep 17 00:00:00 2001 From: Stefan Tomanek Date: Tue, 26 Oct 2010 16:33:34 +0200 Subject: [PATCH] implement autorandr script --- autorandr | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ conf.awk | 18 ------- fp.awk | 15 ------ 3 files changed, 145 insertions(+), 33 deletions(-) create mode 100755 autorandr delete mode 100644 conf.awk delete mode 100644 fp.awk diff --git a/autorandr b/autorandr new file mode 100755 index 0000000..680a5ae --- /dev/null +++ b/autorandr @@ -0,0 +1,145 @@ +#!/bin/sh +# +# Automatically select a display configuration based on connected devives +# +# Stefan Tomanek +# +# How to use: +# +# Save your current display configuration and setup with +# autorandr --save mobile +# +# Connect an additional display, configure your setup and save it +# autorand --save docked +# +# Now autorandr can detect which hardware setup is active: +# # autorandr +# mobile +# docked (detected) +# +# To automatically reload your setup, just append --change to the command line +# +# To manually load a profile, you can use the --load option. +# +# To prevent a profile from being loaded, place a script call "block" in its +# directory. The script is evaluated before the screen setup is inspected, and +# in case of it returning a value of 0 the profile is skipped. This can be used +# to query the status of a docking station you are about to leave. +# +# If no suitable profile can be identified, the current configuration is kept. +# To change this behaviour and switch to a fallback configuration, specify +# --default +# +# Another script called "postswitch "can be placed in the directory +# ~/.auto-disper as well as in all profile directories: The scripts are +# executed after a mode switch has taken place and can notify window managers +# or other applications about it. + +XRANDR=/usr/bin/xrandr +PROFILES=~/.autorandr/ + +CHANGE_PROFILE=0 +DEFAULT_PROFILE="" +SAVE_PROFILE="" + +setup_fp() { + $XRANDR -q --verbose | awk ' + /^[^ ]+ (dis)?connected / { DEV=$1; ID[DEV] = ""; } + $1 ~ /^[a-f0-9]+$/ { ID[DEV] = ID[DEV] $1 } + END { for (X in ID) { print X " " ID[X]; } }' +} + +current_cfg() { + $XRANDR -q | awk ' + /^[^ ]+ disconnected / { + print "output "$1; + print "off"; + } + /^[^ ]+ connected / { + split($3, A, "+"); + print "output "$1; + print "mode "A[1]; + print "pos "A[2]"x"A[3]; + }' +} + +blocked() { + local PROFILE="$1" + [ ! -x "$PROFILES/$PROFILE/block" ] && return 1 + + "$PROFILES/$PROFILE/block" "$PROFILE" +} + +load() { + local PROFILE="$1" + if [ "$CHANGE_PROFILE" -eq 1 ]; then + echo " -> loading profile $PROFILE" + sed 's!^!--!' "$PROFILES/$PROFILE/config" | xargs xrandr + + [ -x "$PROFILES/$PROFILE/postswitch" ] && \ + "$PROFILES/$PROFILE/postswitch" "$PROFILE" + [ -x "$PROFILES/postswitch" ] && \ + "$PROFILES/postswitch" "$PROFILE" + fi +} + +# process parameters +OPTS=$(getopt -n autorandr -o s:l:d:c --long change,default:,save:,load: -- "$@") +if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi +eval set -- "$OPTS" + +while true; do + case "$1" in + -c|--change) CHANGE_PROFILE=1; shift ;; + -d|--default) DEFAULT_PROFILE="$2"; shift 2 ;; + -s|--save) SAVE_PROFILE="$2"; shift 2 ;; + -l|--load) LOAD_PROFILE="$2"; shift 2 ;; + --) shift; break ;; + *) echo "Error: $1"; exit 1;; + esac +done + +CURRENT_SETUP="$(setup_fp)" + +if [ -n "$SAVE_PROFILE" ]; then + echo "Saving current configuration as profile '${SAVE_PROFILE}'" + mkdir -p "$PROFILES/$SAVE_PROFILE" + echo "$CURRENT_SETUP" > "$PROFILES/$SAVE_PROFILE/setup" + current_cfg > "$PROFILES/$SAVE_PROFILE/config" + exit 0 +fi + +if [ -n "$LOAD_PROFILE" ]; then + CHANGE_PROFILE=1 load "$LOAD_PROFILE" + exit $? +fi + +for SETUP_FILE in $PROFILES/*/setup; do + if ! [ -e $SETUP_FILE ]; then + break + fi + PROFILE="$(basename $(dirname "$SETUP_FILE"))" + echo -n "$PROFILE" + + if blocked "$PROFILE"; then + echo " (blocked)" + continue + fi + + FILE_SETUP="$(cat "$PROFILES/$PROFILE/setup")" + if [ "$CURRENT_SETUP" = "$FILE_SETUP" ]; then + echo " (detected)" + load "$PROFILE" + # found the profile, exit with success + exit 0 + else + echo "" + fi +done + +# we did not find the profile, load default +if [ -n "$DEFAULT_PROFILE" ]; then + echo "No suitable profile detected, falling back to $DEFAULT_PROFILE" + load "$DEFAULT_PROFILE" +fi +exit 1 diff --git a/conf.awk b/conf.awk deleted file mode 100644 index f7df401..0000000 --- a/conf.awk +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/awk - -/^[^ ]+ disconnected / { - OUTPUT[$1] = "--off"; -} - -/^[^ ]+ connected / { - split($3, A, "+"); - OUTPUT[$1] = "--mode "A[1]" --pos "A[2]"x"A[3]; -} - -END { - printf "xrandr "; - for (O in OUTPUT) { - printf "--output " O " " OUTPUT[O] " "; - } - printf "\n"; -} diff --git a/fp.awk b/fp.awk deleted file mode 100644 index 5d0f497..0000000 --- a/fp.awk +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/awk -/^[^ ]+ (dis)?connected / { - DEV=$1; - ID[DEV] = ""; -} - -$1 ~ /^[a-f0-9]+$/ { - ID[DEV] = ID[DEV] $1 -} - -END { - for (X in ID) { - print X " " ID[X]; - } -}