X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=autorandr;h=9657536f9a2819f47c0cba0c4d58aa74107d272b;hb=236e99a0163e7db84bf25fbef446a81b08467db6;hp=f68392eb8eb8f50a9977f5c7e2c95e0d5210179e;hpb=f8ffa38ffaf1f630f4c957a4dbebc93d6868ffe8;p=deb_pkgs%2Fautorandr.git diff --git a/autorandr b/autorandr index f68392e..9657536 100755 --- a/autorandr +++ b/autorandr @@ -21,6 +21,9 @@ # # To manually load a profile, you can use the --load option. # +# autorandr tries to avoid reloading an identical configuration. To force the +# configuration, apply --force. +# # 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 @@ -37,26 +40,47 @@ XRANDR=/usr/bin/xrandr PROFILES=~/.autorandr/ +CONFIG=~/.autorandr.conf CHANGE_PROFILE=0 +FORCE_LOAD=0 DEFAULT_PROFILE="" SAVE_PROFILE="" -setup_fp_edid() { +FP_METHODS="setup_fp_xrandr_edid setup_fp_sysfs_edid" + +test -f $CONFIG && . $CONFIG + +setup_fp_xrandr_edid() { $XRANDR -q --verbose | awk ' - /^[^ ]+ (dis)?connected / { DEV=$1; ID[DEV] = ""; } + /^[^ ]+ (dis)?connected / { DEV=$1; } $1 ~ /^[a-f0-9]+$/ { ID[DEV] = ID[DEV] $1 } END { for (X in ID) { print X " " ID[X]; } }' } -setup_fp_dim() { - $XRANDR -q --verbose | awk ' - /^[^ ]+ connected / { CONNECTED=1 } - /^[^ ]+ disconnected / { CONNECTED=0 } - /^[^ ]+ (dis)?connected / \ - && match($0, "([0-9]+mm) x ([0-9]+mm)", A) { - print $1, (CONNECTED==1 ? A[1]"x"A[2] : "" ) - }' +setup_fp_sysfs_edid() { + # xrandr triggers the reloading of EDID data + $XRANDR -q > /dev/null + # hash the EDIDs of all _connected_ devices + for P in /sys/class/drm/card*-*/; do + if grep -q "^connected$" < "${P}status"; then + echo -n "$(basename "$P") " + md5sum ${P}edid | awk '{print $1}' + fi + done +} + +setup_fp() { + local FP=""; + for M in $FP_METHODS; do + FP="$($M)" + [ -n "$FP" ] && break; + done + if [ -z "$FP" ]; then + echo "Unable to fingerprint display configuration" >&2 + return + fi + echo "$FP" } @@ -75,83 +99,126 @@ current_cfg() { } blocked() { - local PROFILE="$1" - [ ! -x "$PROFILES/$PROFILE/block" ] && return 1 + local PROFILE="$1" + [ ! -x "$PROFILES/$PROFILE/block" ] && return 1 - "$PROFILES/$PROFILE/block" "$PROFILE" + "$PROFILES/$PROFILE/block" "$PROFILE" +} + +config_equal() { + local PROFILE="$1" + if [ "$(cat "$PROFILES/$PROFILE/config")" = "$(current_cfg)" ]; then + echo "Config already loaded" + return 0 + else + return 1 + fi } 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 + local PROFILE="$1" + if [ -e "$PROFILES/$PROFILE/config" ] ; 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 } +help() { + cat < save your current setup to profile +-l, --load load profile +--force force loading of a profile +--fingerprint fingerprints your actual config + + 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 + +EOH + exit +} # process parameters -OPTS=$(getopt -n autorandr -o s:l:d:cf --long change,default:,save:,load:,fingerprint -- "$@") +OPTS=$(getopt -n autorandr -o s:l:d:cfh --long change,default:,save:,load:,force,fingerprint,help -- "$@") 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 ;; - --fingerprint) setup_fp_edid; exit 0;; - --) shift; break ;; - *) echo "Error: $1"; exit 1;; - esac + 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 ;; + -h|--help) help ;; + --force) FORCE_LOAD=1; shift ;; + --fingerprint) setup_fp; exit 0;; + --) shift; break ;; + *) echo "Error: $1"; exit 1;; + esac done -CURRENT_SETUP="$(setup_fp_edid)" +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 + 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 $? + CHANGE_PROFILE=1 FORCE_LOAD=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 + 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)" + if [ "$CHANGE_PROFILE" -eq 1 ]; then + if [ "$FORCE_LOAD" -eq 1 ] || ! config_equal "$PROFILE"; then + load "$PROFILE" + fi + fi + # 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" + echo "No suitable profile detected, falling back to $DEFAULT_PROFILE" + load "$DEFAULT_PROFILE" fi exit 1