forked from wertarbyte/autorandr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathautorandr
executable file
·171 lines (151 loc) · 4.19 KB
/
autorandr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/bin/sh
#
# Automatically select a display configuration based on connected devives
#
# Stefan Tomanek <stefan.tomanek@wertarbyte.de>
#
# 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 <profile> 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 <profile>
#
# 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_edid() {
$XRANDR -q --verbose | awk '
/^[^ ]+ (dis)?connected / { DEV=$1; }
$1 ~ /^[a-f0-9]+$/ { ID[DEV] = ID[DEV] $1 }
END { for (X in ID) { print X " " ID[X]; } }'
}
setup_fp_sysfs_edid() {
# 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 METHODS="setup_fp_xrandr_edid setup_fp_sysfs_edid"
local FP="";
for M in $METHODS; do
FP="$($M)"
[ -n "$FP" ] && break;
done
if [ -z "$FP" ]; then
echo "Unable to fingerprint display configuration" >&2
return
fi
echo "$FP"
}
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:cf --long change,default:,save:,load:,fingerprint -- "$@")
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; exit 0;;
--) 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