From e0dfa631a21d7d30424a4ba9dde26faeedfcd224 Mon Sep 17 00:00:00 2001 From: Phillip Berndt Date: Tue, 27 Jan 2015 08:25:04 +0100 Subject: [PATCH] Removed legacy autorandr (see the legacy branch) --- Makefile | 3 +- README.md | 59 ++--- auto-disper | 1 - autorandr | 542 -------------------------------------- autorandr.py | 2 +- bash_completion/autorandr | 4 +- pm-utils/40auto-disper | 1 - pm-utils/40autorandr | 11 +- 8 files changed, 25 insertions(+), 598 deletions(-) delete mode 120000 auto-disper delete mode 100755 autorandr delete mode 120000 pm-utils/40auto-disper diff --git a/Makefile b/Makefile index f1d2725..4141b1c 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,7 @@ all: INSTALL_PATH=/usr/local/bin install: - install -D auto-disper ${DESTDIR}${INSTALL_PATH}/auto-disper - install -D -m 755 autorandr ${DESTDIR}${INSTALL_PATH}/autorandr + install -D -m 755 autorandr.py ${DESTDIR}${INSTALL_PATH}/autorandr install -D -m 644 bash_completion/autorandr ${DESTDIR}/etc/bash_completion.d/autorandr hotplug: diff --git a/README.md b/README.md index f3f8d32..5fb8ac1 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,29 @@ -# autorandr - +# autorandr Automatically select a display configuration based on connected devices ## Branch information +This is a compatible Python rewrite of +[wertarbyte/autorandr](https://github.com/wertarbyte/autorandr). + The original [wertarbyte/autorandr](https://github.com/wertarbyte/autorandr) -tree is unmaintained, with lots of open pull requests and issues. I forked -it and merged what I thought were the most important changes. I will maintain -this branch until @wertarbyte finds the time to maintain his branch again. +tree is unmaintained, with lots of open pull requests and issues. I forked it +and merged what I thought were the most important changes. If you are searching +for that version, see the [`legacy` branch](https://github.com/phillipberndt/autorandr/tree/legacy). +Note that the Python version is better suited for non-standard configurations, +like if you use `--transform` or `--reflect`. If you use `auto-disper`, you +have to use the bash version, as there is no disper support in the Python +version (yet). Both versions use a compatible configuration file format, so +you can, to some extent, switch between them. I will maintain the `legacy` +branch until @wertarbyte finds the time to maintain his branch again. + +If you are interested in why there are two versions around, see +[#7](https://github.com/phillipberndt/autorandr/issues/7), +[#8](https://github.com/phillipberndt/autorandr/issues/8) and +especially +[#12](https://github.com/phillipberndt/autorandr/issues/12) +if you are unhappy with this version and would like to contibute to the bash +version. ## License information and authors @@ -28,22 +44,6 @@ Contributors to this version of autorandr are: * stormc * tachylatus -## autorandr vs. autorandr.py - -The two files `autorandr` and `autorandr.py` are two independent versions of -autorandr. For now, both are here, but I might move one of both versions into -its own branch or repository someday. See [bug #7](https://github.com/phillipberndt/autorandr/issues/7) -for details on why there are two versions around. - -The two versions are compatible with respect to the profile format and command -line parameters, but - -* the *Python version* does not support auto-disper -* the *bash version* does not support changes in available adapters and slightly esoteric configurations (like transformations and reflections) - -Active development in this repository is likely to occur preferably in the -Python version. - ## How to use Save your current display configuration and setup with: @@ -84,22 +84,5 @@ Another script called `postswitch` can be placed in the directory after a mode switch has taken place and can notify window managers or other applications about it. -While the script uses xrandr by default, calling it by the name `autodisper` -or `auto-disper` forces it to use the [disper](http://willem.engen.nl/projects/disper/) -utility, which is useful for controlling nvidia chipsets. The formats for -fingerprinting the current setup and saving/loading the current configuration -are adjusted accordingly. - To install autorandr call `make install`, define your setup and then call `make hotplug` to install hotplug scripts. - -For Debian using auto-disper: -To make the screen auto-configure when your computer wakes up, -* Copy auto-disper into /usr/local/bin/ -* Copy pm-utils/40auto-disper into /etc/pm/sleep.d/ -* (Assuming gnome) Run gnome-keybinding-properties and ADD a shortcut, - I called it "Run auto-disper", I set it to CTRL-F7, and the command is: - `auto-disper -c --default default` -* Create a default disper setting... eg for laptop: unplug all monitors, - set up the screen nicely on the laptop display. - Then run `auto-disper --save laptop` diff --git a/auto-disper b/auto-disper deleted file mode 120000 index 94cdea8..0000000 --- a/auto-disper +++ /dev/null @@ -1 +0,0 @@ -autorandr \ No newline at end of file diff --git a/autorandr b/autorandr deleted file mode 100755 index eace950..0000000 --- a/autorandr +++ /dev/null @@ -1,542 +0,0 @@ -#!/bin/sh -# -# Automatically select a display configuration based on connected devices -# -# Copyright (c) 2013 Stefan Tomanek -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# -# -# How to use: -# -# Save your current display configuration and setup with: -# $ autorandr --save mobile -# -# Connect an additional display, configure your setup and save it: -# $ autorandr --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. -# -# autorandr tries to avoid reloading an identical configuration. To force the -# (re)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 -# 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 -# ~/.autorandr 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. -# -# -# While the script uses xrandr by default, calling it by the name "autodisper" -# or "auto-disper" forces it to use the "disper" utility, which is useful for -# controlling nvidia chipsets. The formats for fingerprinting the current setup -# and saving/loading the current configuration are adjusted accordingly. - -XRANDR=/usr/bin/xrandr -DISPER=/usr/bin/disper -XDPYINFO=/usr/bin/xdpyinfo -PROFILES=~/.autorandr -CONFIG=~/.autorandr.conf -RESERVED_PROFILE_NAMES=`cat <&2 - FP_METHODS="setup_fp_disper" - CURRENT_CFG_METHOD="current_cfg_disper" - LOAD_METHOD="load_cfg_disper" -fi - -if [ -f $CONFIG ]; then - echo "Loading configuration from '$CONFIG'" >&2 - . $CONFIG -fi - -if ! which xxd 2>&1 >/dev/null; then - xxd() { - # xxd replacement for systems without vim. Ugly, but the only simple - # version that both Python 2 and 3 understand that I could come up with. - # awk can only do one direction, it has no ord() function. - if [ "$1" = "-r" ]; then - python -c "import binascii, sys; getattr(sys.stdout, 'buffer', sys.stdout).write(binascii.unhexlify(getattr(sys.stdin, 'buffer', sys.stdin).read()))" - else - python -c "import binascii, sys; getattr(sys.stdout, 'buffer', sys.stdout).write(binascii.hexlify(getattr(sys.stdin, 'buffer', sys.stdin).read()))" - echo - fi - } -fi - -setup_fp_xrandr_edid() { - $XRANDR -q --verbose | awk ' - ORS=""; - / (dis)?connected/ { DEVICE=gensub("-([A-Z]-)?", "", "g", $1) " "; } - /^[[:blank:]]+EDID:/ { - print DEVICE - DEVICE="" - for(getline; /^[[:blank:]]+[0-9a-f]+$/; getline) { - print $1; - } - print "\n"; - } - END { - print "\n"; - } - ' -} - -setup_fp_sysfs_edid() { - $XRANDR -q > /dev/null - for DEVICE in /sys/class/drm/card*-*; do - [ -e "${DEVICE}/status" ] && grep -q "^connected$" "${DEVICE}/status" || continue - echo -n "$(echo "${DEVICE}/edid" | sed -re 's#^.+card[0-9]+-([^/]+).+#\1#; s#-([A-Z]-)?##') " - cat "${DEVICE}/edid" | xxd -c 256 -ps | awk 'ORS=""; /.+/ { print; }' - echo - done -} - -setup_fp_disper() { - $DISPER -l | grep '^display ' -} - -setup_fp() { - local FP=""; - for M in $FP_METHODS; do - FP="$($M)" - if [ -n "$FP" ]; then - break - fi - done - if [ -z "$FP" ]; then - echo "Unable to fingerprint display configuration" >&2 - return - fi - echo "$FP" | sort -} - -current_cfg_xrandr() { - local PRIMARY_SETUP=""; - if [ -x "$XDPYINFO" ]; then - PRIMARY_SETUP="$($XDPYINFO -ext XINERAMA | awk '/^ head #0:/ {printf $3 $5}')" - fi - $XRANDR -q | awk -v primary_setup="${PRIMARY_SETUP}" ' - # display is connected and has a mode - /^[^ ]+ connected [^(]/ { - output=$1 - print "output "$1; - if ($3 == "primary") { - print $3 - split($4, A, "+") - $4=$5 - } - else { - split($3, A, "+"); - if (A[1] A[2] "," A[3] == primary_setup) - print "primary"; - } - if (($4 == "left") || ($4 == "right")) { - split(A[1], B, "x"); - A[1] = B[2]"x"B[1]; - } - print "mode "A[1]; - print "pos "A[2]"x"A[3]; - if ($4 !~ /^\(/) { - print "rotate "$4; - } - else { - print "rotate normal"; - } - next; - } - / [0-9]+x[0-9]+ .+/ { - if (output) { - for (n=1; n<10; n++) { - if($n ~ /[0-9]+\.[0-9]+\*/) { - print "rate " gensub(/(+|\*)/, "", "g", $n); - } - } - } - } - # disconnected or disabled displays - /^[^ ]+ (dis)?connected / || - /^[^ ]+ unknown connection / { - output="" - print "output "$1; - print "off"; - next; - }' -} - -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; -} - -blocked() { - local PROFILE="$1" - [ ! -x "$PROFILES/$PROFILE/block" ] && return 1 - - "$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_cfg_xrandr() { - # sed 1: Prefix arguments with "--" - # sed 2: Merge arguments into one line per output - # sed 3: * Merge all --off outputs into the first line - # * Place the output with --pos 0x0 on the second line - # * Remaining outputs are appended as they appear - # * Keep everything in hold buffer until the last line - # sed 4: Remove empty lines caused by G and H on empty hold buffer - # sed 5: Join lines enabling screens in pairs of two (See https://github.com/phillipberndt/autorandr/pull/6) - sed 's/^/--/' "$1" | sed -e ' - :START - /\n--output/{P;D} - s/\n/ / - N;bSTART' | sed -e ' - / --off/{ - G - # Merge with next line if it contains --off - s/\n\([^\n]* --off\)/ \1/ - h - $!d;b - } - / --pos 0x0/{ - G - # Swap lines 1 and 2 if --off is found - / --off/ s/^\([^\n]*\)\n\([^\n]*\)/\2\n\1/ - h - $!d;b - } - H - $!d - x' | sed -e ' - /./ !d' | sed -e ' - /--mode/{ N; s/\n/ /; } - ' | xargs -L 1 $XRANDR -} - -load_cfg_disper() { - $DISPER -i < "$1" -} - -load() { - local PROFILE="$1" - local CONF="$PROFILES/$PROFILE/config" - 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 - if [ -x "$PROFILES/$PROFILE/preswitch" ]; then - "$PROFILES/$PROFILE/preswitch" "$PROFILE" - fi - - 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" - fi - if [ -x "$PROFILES/postswitch" ]; then - "$PROFILES/postswitch" "$PROFILE" - fi -} - -help() { - cat < save your current setup to profile --l, --load load profile --d, --default make profile the default profile ---force force (re)loading of a profile ---fingerprint fingerprint your current hardware setup ---config dump your current xrandr setup - - 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 - ~/.autorandr as well as in any profile directories: The scripts are executed - after a mode switch has taken place and can notify window managers. - - 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 -} -# process parameters -OPTS=$(getopt -n autorandr -o s:l:d:cfh --long change,default:,save:,load:,force,fingerprint,config,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 ;; - -h|--help) help ;; - --force) FORCE_LOAD=1; shift ;; - --fingerprint) setup_fp; exit 0;; - --config) current_cfg; exit 0;; - --) shift; break ;; - *) echo "Error: $1"; exit 1;; - esac -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" - $CURRENT_CFG_METHOD > "$PROFILES/$SAVE_PROFILE/config" - exit 0 -fi - -if [ -n "$LOAD_PROFILE" ]; then - 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 - - # This sed command is for compatibility with old versions that did not try - # to normalize device names - FILE_SETUP="$(sed -re 's#-([A-Z]-)?##g; s#card[0-9]##;' "$PROFILES/$PROFILE/setup")" - # Detect the md5sum in fingerprint files created using the old sysfs fingerprinting - # If it is detected, output a warning and calculate the legacy variant of the current - # setup. - if echo "$FILE_SETUP" | grep -Eq "^[^ ]+ [0-9a-f]{32}$"; then - echo -n " (Obsolete fingerprint format. Please update using --save.) " - - if [ -z "$LEGACY_CURRENT_SETUP" ]; then - LEGACY_CURRENT_SETUP="$(echo "$CURRENT_SETUP" | while read DEVICE EDID; do - echo -n "${DEVICE} " - echo -n "${EDID}" | xxd -r -ps | md5sum - | awk '{print $1}' - done)" - fi - FILE_SETUP="$(echo "$FILE_SETUP" | sort)" - if [ "$LEGACY_CURRENT_SETUP" = "$FILE_SETUP" ]; then - CURRENT_SETUP="$LEGACY_CURRENT_SETUP" - fi - fi - - 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" -fi -exit 1 - -# Local Variables: -# tab-width: 8 -# sh-basic-offset: 8 -# sh-indentation: 8 -# indent-tabs-mode: t -# End: diff --git a/autorandr.py b/autorandr.py index 1339014..85c06d3 100755 --- a/autorandr.py +++ b/autorandr.py @@ -4,7 +4,7 @@ # autorandr.py # Copyright (c) 2015, Phillip Berndt # -# Experimental autorandr rewrite in Python +# Autorandr rewrite in Python # # This script aims to be fully compatible with the original autorandr. # diff --git a/bash_completion/autorandr b/bash_completion/autorandr index 14b4ddb..61de0bb 100644 --- a/bash_completion/autorandr +++ b/bash_completion/autorandr @@ -9,7 +9,7 @@ _autorandr () prev="${COMP_WORDS[COMP_CWORD-1]}" opts="-h -c -s -l -d" - lopts="--help --change --save --load --default --force --fingerprint --config" + lopts="--help --change --save --load --default --force --fingerprint --config --dry-run" if [ -d ~/.autorandr ]; then prfls="`find ~/.autorandr/* -maxdepth 1 -type d -printf '%f\n'`" else @@ -44,5 +44,3 @@ _autorandr () return 0 } complete -F _autorandr autorandr -complete -F _autorandr auto-disper - diff --git a/pm-utils/40auto-disper b/pm-utils/40auto-disper deleted file mode 120000 index 9d7b227..0000000 --- a/pm-utils/40auto-disper +++ /dev/null @@ -1 +0,0 @@ -40autorandr \ No newline at end of file diff --git a/pm-utils/40autorandr b/pm-utils/40autorandr index b8b2bee..1129177 100755 --- a/pm-utils/40autorandr +++ b/pm-utils/40autorandr @@ -3,16 +3,7 @@ # 40autorandr: Change autorandr profile on thaw/resume exec > /var/log/autorandr.log 2>&1 -# detect if we are being called as 40auto-disper or 40autorandr -FORM=${0##*40} -case $FORM in - auto-disper) - AUTORANDR="auto-disper -c --default default" - ;; - *) - AUTORANDR="autorandr -c --default default" - ;; -esac +AUTORANDR="autorandr -c --default default" detect_display() { -- 2.39.2