mmswitch

minimal multimedia switch
git clone git://git.2f30.org/mmswitch
Log | Files | Refs

mmswitch-monitor (4282B)


      1 #!/bin/sh
      2 
      3 DMENU_ARGS='-nb #151515 -nf #787878 -sb #151515 -sf #a78edb -fn -*-*-medium-r-normal-*-*-*-*-*-*-80-*-*'
      4 
      5 usage() {
      6     echo "Usage $(basename $0) [options] [MONITOR ..]"
      7     echo
      8     echo "Options:"
      9     echo "  -h, --help             Show this help menu"
     10     echo "  -l, --list-monitors    List connected monitors"
     11     echo "  -e                     Extent all monitors (ignores [MONITOR ..] list)"
     12     echo "  -d                     Duplicate all monitors (ignores [MONITOR ..] list)"
     13     echo "  --dmenu                Use dmenu"
     14     echo
     15     echo "If a connected monitor is not listed in the arguments, then it will switched off."
     16     echo
     17     echo "Monitor syntax by example:"
     18     echo "  MONITOR1                     - Use MONITOR1 only"
     19     echo "  MONITOR1 MONITOR2            - MONITOR1 is at the left of MONITOR2"
     20     echo "  MONITOR2 MONITOR1            - MONITOR2 is at the left of MONITOR1"
     21     echo "  MONITOR2=MONITOR1            - MONITOR2 is a duplicate of MONITOR1"
     22     echo "  MONITOR2=MONITOR3=MONITOR1   - MONITOR2 and MONITOR3 are duplicates of MONITOR1"
     23     echo "  MONITOR2 MONITOR3=MONITOR1   - MONITOR2 is at the left of MONITOR1"
     24     echo "                                 and MONITOR3 is a duplicate of MONITOR1"
     25     echo "  MONITOR1 MONITOR2 MONITOR3   - MONITOR1 is at the left of MONITOR2"
     26     echo "                                 and MONITOR3 is at the right of MONITOR2"
     27     echo
     28     echo "Example:"
     29     echo "  $(basename $0) LVDS-0 DP-0"
     30     echo "  $(basename $0) -e"
     31     echo "  $(basename $0) -d"
     32 }
     33 
     34 die() {
     35     echo "$(basename $0): Error: $1" >&2
     36     exit 1
     37 }
     38 
     39 list_monitors() {
     40     xrandr -q | grep ' connected' | awk '{print $1}'
     41 }
     42 
     43 list_forced_unplugged() {
     44     xrandr -q | grep ' 0mm x 0mm' | awk '{print $1}'
     45 }
     46 
     47 is_connected() {
     48     list_monitors | grep -E "^$1\$" > /dev/null 2>&1
     49 }
     50 
     51 is_monitor_in() {
     52     local mon="$1"
     53     local x
     54     local y
     55     shift
     56 
     57     for x in "$@"; do
     58 	for y in $(echo $x | tr '=' ' '); do
     59 	    [ "$mon" = "$y" ] && return 0
     60 	done
     61     done
     62 
     63     return 1
     64 }
     65 
     66 last_arg() {
     67     local last
     68     local x
     69 
     70     for x in "$@"; do
     71 	last="$x"
     72     done
     73 
     74     echo $last
     75 }
     76 
     77 ARGS=$(getopt -o lhed -l "list-monitors,help,dmenu" -n $(basename $0) -- "$@")
     78 [ $? -ne 0 ] && exit 1
     79 eval set -- "$ARGS"
     80 
     81 while :; do
     82     case "$1" in
     83 	-h|--help)
     84 	    usage
     85 	    exit 1
     86 	    ;;
     87 	-l|--list-monitors)
     88 	    list_monitors
     89 	    exit 0
     90 	    ;;
     91 	-e)
     92 	    ARGS=
     93 	    for x in $(list_monitors); do
     94 		ARGS="${ARGS} ${x}"
     95 	    done
     96 	    break
     97 	    ;;
     98 	-d)
     99 	    ARGS=
    100 	    for x in $(list_monitors); do
    101 		[ -n "$ARGS" ] && ARGS="${ARGS}="
    102 		ARGS="${ARGS}${x}"
    103 	    done
    104 	    break
    105 	    ;;
    106 	--dmenu)
    107 	    SELECT=$({
    108 		    echo Extend monitors
    109 		    echo Duplicate monitors
    110 		    list_monitors
    111 		} | dmenu -i -p 'Choose monitor:' $DMENU_ARGS)
    112 
    113 	    [ -z "$SELECT" ] && exit 0
    114 
    115 	    ARGS=
    116 	    case "$SELECT" in
    117 		"Extend monitors")
    118 		    for x in $(list_monitors); do
    119 			ARGS="${ARGS} ${x}"
    120 		    done
    121 		    ;;
    122 		"Duplicate monitors")
    123 		    for x in $(list_monitors); do
    124 			[ -n "$ARGS" ] && ARGS="${ARGS}="
    125 			ARGS="${ARGS}${x}"
    126 		    done
    127 		    ;;
    128 		*)
    129 		    ARGS="$SELECT"
    130 		    ;;
    131 	    esac
    132 	    break
    133 	    ;;
    134 	--)
    135 	    shift
    136 	    ARGS="$@"
    137 	    break
    138 	    ;;
    139     esac
    140 done
    141 
    142 if [ -z "$ARGS" ]; then
    143     usage
    144     exit 1
    145 fi
    146 
    147 ARGS=$(echo $ARGS | tr '[a-z]' '[A-Z]')
    148 
    149 for x in $ARGS; do
    150     for y in $(echo $x | tr '=' ' '); do
    151 	is_connected $y || die "Monitor \`$y' is not in the connected list. Use -l argument to see the list."
    152     done
    153 done
    154 
    155 ALL_OFF=1
    156 
    157 for x in $(list_monitors); do
    158     is_monitor_in "$x" $ARGS && {
    159 	ALL_OFF=0
    160 	continue
    161     }
    162     OPT="${OPT} --output $x --off"
    163 done
    164 
    165 [ $ALL_OFF -eq 1 ] && die "You can not switch off all the monitors"
    166 
    167 for x in $(list_forced_unplugged); do
    168     OPT="${OPT} --output $x --off"
    169 done
    170 
    171 for x in $ARGS; do
    172     k=$(echo $x | tr '=' ' ')
    173     if [ "$k" != "$x" ]; then
    174 	SAME_AS=$(last_arg $k)
    175 	OPT="${OPT} --output $SAME_AS --auto"
    176 	if [ -n "$PREV" ]; then
    177 	    OPT="${OPT} --right-of ${PREV}"
    178 	fi
    179 	for y in $k; do
    180 	    [ "$SAME_AS" = "$y" ] && continue
    181 	    OPT="${OPT} --output $y --auto --same-as $SAME_AS"
    182 	done
    183 	PREV=$SAME_AS
    184 	continue
    185     fi
    186 
    187     OPT="${OPT} --output ${x} --auto"
    188     if [ -n "$PREV" ]; then
    189 	OPT="${OPT} --right-of ${PREV}"
    190     fi
    191     PREV="$x"
    192 done
    193 
    194 xrandr $OPT