chromium,chromedriver: 129.0.6668.91 -> 129.0.6668.100
[NixPkgs.git] / pkgs / by-name / ed / edido / edido.sh
blob136205386ee1bb8d6d3a6b18e04b96b20c536f61
1 #!/usr/bin/env bash
2 set -eEuo pipefail
3 test -z "${DEBUG:-}" || set -x
4 set -eEuo pipefail
6 FIRMWARE_PATH="${EDID_PATH:-"/run/current-system/firmware"}"
7 mapfile -t edid_paths <<<"${FIRMWARE_PATH//":"/$'\n'}"
9 err() {
10 LOGGER="ERROR" log "$@"
11 return 1
14 log() {
15 # shellcheck disable=SC2059
16 printf "[${LOGGER:-"INFO"}] $1\n" "${@:2}" >&2
19 find_path() {
20 local filePath="$1"
21 mapfile -t candidates < <(
22 set -x
23 find -L "${@:2}" -path "*/${filePath}"
25 if test "${#candidates[@]}" -eq 0; then
26 log "'%s' path not found" "${filePath}"
27 return 1
29 log "'%s' path found at %s" "${filePath}" "${candidates[0]}"
30 echo -n "${candidates[0]}"
33 wait_for_file() {
34 local filePath="$1"
35 until find_path "${filePath}" "${@:2}"; do
36 backoff "${filePath}"
37 done
40 backoff() {
41 local what="$1" sleepFor
43 backoff_start="${backoff_start:-"5"}"
44 backoff_current="${backoff_current:-"${backoff_start}"}"
45 backoff_jitter_multiplier="${backoff_jitter_multiplier:-"0.3"}"
46 backoff_multiplier="${backoff_multiplier:-1.5}"
48 sleepFor="$(bc <<<"${backoff_current} + ${RANDOM} % (${backoff_current} * ${backoff_jitter_multiplier})")"
50 log "still waiting for '%s', retry in %s sec..." "${what}" "${sleepFor}"
51 sleep "${sleepFor}"
52 backoff_current="$(bc <<<"scale=2; ${backoff_current} * ${backoff_multiplier}")"
56 force_mode() {
57 local connPath="$1" newMode="$2" currentMode
58 currentMode="$(cat "$connPath/force")"
59 if test "${currentMode}" == "${newMode}"; then
60 log "video mode is already '%s'" "${currentMode}"
61 return
63 log "changing video mode from '%s' to '%s'" "${currentMode}" "${newMode}"
64 echo "${newMode}" >"$connPath/force"
65 CHANGED=1
68 force_edid() {
69 local connPath="$1" edidPath="$2"
72 apply_mode() {
73 local connPath="$1" mode="$2"
74 test -n "$mode" || return
75 log "setting up fb mode..."
77 # see https://github.com/torvalds/linux/blob/8cd26fd90c1ad7acdcfb9f69ca99d13aa7b24561/drivers/gpu/drm/drm_sysfs.c#L202-L207
78 # see https://docs.kernel.org/fb/modedb.html
79 case "${mode}" in
80 *d) force_mode "$connPath" off ;;
81 *e) force_mode "$connPath" on ;;
82 *D) force_mode "$connPath" on-digital ;;
83 esac
86 apply_edid() {
87 local connPath="$1" edidFilename="$2" edidPath
88 test -n "${edidFilename}" || return
89 log "loading EDID override..."
90 edidPath="$(find_path "${edidFilename}" "${edid_paths[@]/%/"/"}" -maxdepth 2)"
92 force_edid "${connPath}" "$edidPath"
93 cat "$edidPath" >"${connPath}/edid_override"
95 if cmp "${connPath}/edid_override" "${edidPath}" &>/dev/null; then
96 log "EDID is already up to date with '%s'" "${edidPath}"
97 else
98 log "applying EDID override from ${edidPath}"
99 cat "$edidPath" >"${connPath}/edid_override"
100 CHANGED=1
104 load() {
105 local conn="$1" edidFilename="$2" mode="$3"
106 export LOGGER="$conn:${edidFilename}:$mode"
107 CHANGED="${CHANGED:-0}"
109 log "starting configuration"
110 local connPath
111 connPath="$(wait_for_file "$conn" /sys/kernel/debug/dri/ -maxdepth 2 -type d)"
112 apply_edid "${connPath}" "${edidFilename}"
113 apply_mode "${connPath}" "$mode"
115 if test "${CHANGED}" != 0; then
116 log "changes detected, triggering hotplug"
117 echo 1 >"${connPath}/trigger_hotplug"
118 else
119 log "no changes detected, skipping hotplug trigger"
123 main() {
124 if [[ $EUID -ne 0 ]]; then
125 err "must be run as root"
128 if test "$#" == 0; then
129 log "loading kernel parameters from /proc/cmdline"
130 # replace script arguments with kernel parameters
131 mapfile -t args < <(xargs -n1 </proc/cmdline)
132 else
133 log "loading kernel parameters compatible arguments from commandline"
134 args=("$@")
137 local -A edids modes connectors
138 local -a entries
139 local key value
141 for arg in "${args[@]}"; do
142 key="${arg%%=*}"
143 value=""
144 test "${key}" == "${arg}" || value="${arg#*=}"
146 case "${key}" in
147 video)
148 # one argument per connector:
149 # video=DP-4:e video=DP-1:e
150 connector="${value%:*}"
151 mode="${value#*:}"
152 connectors["${connector}"]=""
153 modes["$connector"]="$mode"
155 drm.edid_firmware)
156 # single argument for all connectors:
157 # drm.edid_firmware=DP-4:edid/one.bin,DP-1:edid/two.bin
158 mapfile -t entries <<<"${value//","/$'\n'}"
159 for entry in "${entries[@]}"; do
160 connector="${entry%:*}"
161 edidFilename="${entry#*:}"
162 connectors["${connector}"]=""
163 edids["${connector}"]="${edidFilename}"
164 done
166 esac
167 done
169 for connector in "${!connectors[@]}"; do
170 # spawn in a subshell to easily adjust and runtime modify global variables
171 (load "${connector}" "${edids["${connector}"]:-""}" "${modes["${connector}"]:-""}") &
172 done
173 wait
176 main "$@"