diff --git a/scripts/install/server.sh b/scripts/install/server.sh index f85341e..d63917b 100755 --- a/scripts/install/server.sh +++ b/scripts/install/server.sh @@ -51,6 +51,121 @@ read_existing_hdmi_connector() { normalize_hdmi_connector "$value" } +boot_config_path() { + for path in /boot/config.txt /boot/firmware/config.txt; do + if [[ -e $path ]]; then + printf '%s\n' "$path" + return 0 + fi + done + return 0 +} + +boot_cmdline_path() { + for path in /boot/cmdline.txt /boot/firmware/cmdline.txt; do + if [[ -e $path ]]; then + printf '%s\n' "$path" + return 0 + fi + done + return 0 +} + +runtime_forced_hdmi_connectors() { + [[ -r /proc/cmdline ]] || return 0 + tr ' ' '\n' "$tmp" + sudo install -m 0644 "$tmp" "$cfg" + rm -f "$tmp" +} + +write_hdmi_cmdline_force() { + local connector="${1:-}" cmd token tmp line + cmd=$(boot_cmdline_path) + [[ -n $cmd ]] || return 0 + tmp=$(mktemp) + line=$(cat "$cmd") + for token in $line; do + case "$token" in + video=HDMI-A-*:1920x1080@60e) + continue + ;; + esac + printf '%s ' "$token" >>"$tmp" + done + if [[ -n $connector ]]; then + printf 'video=%s:1920x1080@60e ' "$connector" >>"$tmp" + fi + sed -i 's/[[:space:]]*$//' "$tmp" + printf '\n' >>"$tmp" + sudo install -m 0644 "$tmp" "$cmd" + rm -f "$tmp" +} + +clear_lesavka_hdmi_boot_force() { + remove_lesavka_hdmi_config_force + write_hdmi_cmdline_force "" +} + +write_hdmi_boot_force() { + local connector="$1" idx cfg + connector=$(normalize_hdmi_connector "$connector") + if [[ ! $connector =~ ^HDMI-A-([0-9]+)$ ]]; then + echo "⚠️ cannot write HDMI boot force for unexpected connector '$connector'." >&2 + return 0 + fi + + idx=$((BASH_REMATCH[1] - 1)) + cfg=$(boot_config_path) + remove_lesavka_hdmi_config_force + if [[ -n $cfg ]]; then + { + echo + echo "# lesavka: force HDMI mode for capture dongle ($connector)" + printf 'hdmi_force_hotplug:%s=1\n' "$idx" + printf 'hdmi_group:%s=2\n' "$idx" + printf 'hdmi_mode:%s=82\n' "$idx" + } | sudo tee -a "$cfg" >/dev/null + fi + write_hdmi_cmdline_force "$connector" +} + +prepare_hdmi_detection_boot_state() { + local -a forced=() + + if [[ -n ${LESAVKA_HDMI_CONNECTOR:-} ]]; then + return 0 + fi + + mapfile -t forced < <(runtime_forced_hdmi_connectors) + if (( ${#forced[@]} <= 1 )); then + return 0 + fi + + echo "⚠️ current boot forces multiple HDMI connectors: ${forced[*]}" >&2 + echo " Linux will report every forced connector as connected, so auto-detection cannot be trusted yet." >&2 + clear_lesavka_hdmi_boot_force + echo "✅ removed Lesavka-managed dual-HDMI force settings from boot config." >&2 + echo " Reboot Theia, then rerun this installer so it can see the real connected HDMI port." >&2 + echo " If both ports are physically connected after reboot, rerun once with LESAVKA_HDMI_CONNECTOR=HDMI-A-N." >&2 + exit 1 +} + describe_hdmi_connectors() { local dev name status id for dev in /sys/class/drm/card*-HDMI-A-*; do @@ -191,6 +306,7 @@ echo "==> 2a. Kernel-driver tweaks" cat <<'EOF' | sudo tee /etc/modprobe.d/gc311-stream.conf >/dev/null options uvcvideo quirks=0x200 timeout=10000 EOF +prepare_hdmi_detection_boot_state echo "==> 2b. Predictable /dev names for each capture card" # ensure relay (GPIO power) is on if present @@ -298,6 +414,7 @@ sudo install -d -m 0755 /etc/lesavka HDMI_CONNECTOR=$(resolve_hdmi_connector) if [[ -n $HDMI_CONNECTOR ]]; then echo " ↪ HDMI connector: $HDMI_CONNECTOR" + write_hdmi_boot_force "$HDMI_CONNECTOR" else echo "⚠️ no connected HDMI connector detected; leaving LESAVKA_HDMI_CONNECTOR unset." >&2 fi