86 lines
2.2 KiB
Bash
Executable File
86 lines
2.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
log() {
|
|
printf '[display-audio] %s\n' "$*"
|
|
}
|
|
|
|
warn() {
|
|
printf '[display-audio] WARN: %s\n' "$*" >&2
|
|
logger -t couch-display-audio -- "$*" 2>/dev/null || true
|
|
}
|
|
|
|
pick_hdmi_refresh() {
|
|
awk '
|
|
$1 == "HDMI-1" && $2 == "connected" { in_hdmi=1; next }
|
|
in_hdmi && $0 !~ /^[[:space:]]/ { exit }
|
|
in_hdmi && $1 == "1920x1080" {
|
|
for (i = 2; i <= NF; i++) {
|
|
gsub(/[+*]/, "", $i)
|
|
if ($i ~ /^[0-9]+(\.[0-9]+)?$/) {
|
|
value = $i + 0
|
|
if (value > best) {
|
|
best = value
|
|
best_text = $i
|
|
}
|
|
}
|
|
}
|
|
}
|
|
END {
|
|
if (best_text != "") {
|
|
print best_text
|
|
}
|
|
}
|
|
'
|
|
}
|
|
|
|
choose_hdmi_profile() {
|
|
pactl list cards | awk '
|
|
/^Card #[0-9]+/ { card="" }
|
|
/^\tName: / { sub(/^\tName: /, "", $0); card=$0 }
|
|
/^\t\toutput:hdmi/ && /available: yes/ {
|
|
profile=$1
|
|
sub(/:$/, "", profile)
|
|
print card "\t" profile
|
|
exit
|
|
}
|
|
'
|
|
}
|
|
|
|
choose_hdmi_sink() {
|
|
pactl list short sinks | awk '$2 ~ /\.hdmi/ { print $2; exit }'
|
|
}
|
|
|
|
xrandr_output="$(xrandr --query)"
|
|
if ! grep -q '^HDMI-1 connected' <<<"${xrandr_output}"; then
|
|
warn "HDMI-1 is not connected; deferring display/audio switch"
|
|
exit 0
|
|
fi
|
|
|
|
refresh="$(printf '%s\n' "${xrandr_output}" | pick_hdmi_refresh)"
|
|
if [[ -z "${refresh}" ]]; then
|
|
warn "HDMI-1 is connected but no 1920x1080 refresh was discovered"
|
|
exit 0
|
|
fi
|
|
|
|
log "setting HDMI-1 primary at 1920x1080@${refresh} and disabling eDP-1"
|
|
xrandr --output HDMI-1 --primary --mode 1920x1080 --rate "${refresh}" --output eDP-1 --off
|
|
|
|
profile_line="$(choose_hdmi_profile || true)"
|
|
if [[ -z "${profile_line}" ]]; then
|
|
warn "HDMI audio sink/profile not available yet; display configured and audio switch deferred"
|
|
exit 0
|
|
fi
|
|
|
|
card_name="${profile_line%%$'\t'*}"
|
|
profile_name="${profile_line#*$'\t'}"
|
|
log "selecting HDMI audio profile ${profile_name} on ${card_name}"
|
|
pactl set-card-profile "${card_name}" "${profile_name}"
|
|
pactl list short sinks >/dev/null 2>&1 || true
|
|
sink_name="$(choose_hdmi_sink || true)"
|
|
if [[ -z "${sink_name}" ]]; then
|
|
warn "HDMI sink still unavailable after profile switch; audio switch deferred"
|
|
exit 0
|
|
fi
|
|
pactl set-default-sink "${sink_name}"
|