- Adds VIRTUAL1 as permanent primary output via modesetting driver - HDMI1 set as clone (--same-as) of VIRTUAL1 - hdmi-fallback.sh script monitors drm connector status - systemd user unit auto-creates VIRTUAL1 and switches on hotplug loss - Xorg fallback guarantees 1920x1080 framebuffer without HDMI - Includes xserver-xorg-video-dummy as backup driver
200 lines
5.6 KiB
Bash
200 lines
5.6 KiB
Bash
#!/bin/bash
|
|
# RDtop Installer — RustDesk headless display setup
|
|
# Usage: bash -c "$(curl -fsSL https://git.softuniq.eu/NW/RDtop/raw/branch/main/install.sh)"
|
|
set -euo pipefail
|
|
|
|
echo "=== RDtop Installer ==="
|
|
echo "Installing RustDesk headless display fallback..."
|
|
|
|
# Config paths
|
|
REPO_URL="https://git.softuniq.eu/NW/RDtop"
|
|
X11_CONF="/etc/X11/xorg.conf.d/90-fallback.conf"
|
|
BIN_DST="$HOME/.local/bin/hdmi-fallback.sh"
|
|
SYSTEMD_DST="$HOME/.config/systemd/user/hdmi-fallback.service"
|
|
LOG="$HOME/.local/logs/rdtop-install.log"
|
|
|
|
mkdir -p "$(dirname "$LOG")"
|
|
log() { echo "$(date '+%F %T') $1" | tee -a "$LOG"; }
|
|
|
|
log "Start install"
|
|
|
|
# --- Check prerequisites ---
|
|
if [ "$EUID" -eq 0 ]; then
|
|
log "ERROR: Do not run as root. Run as regular user with sudo access."
|
|
exit 1
|
|
fi
|
|
|
|
if ! xset q >/dev/null 2>&1; then
|
|
log "WARNING: No X11 display found. You need to run this from a graphical session."
|
|
fi
|
|
|
|
# --- Check if dummy driver exists or can be installed ---
|
|
if [ -f /usr/lib/xorg/modules/drivers/dummy_drv.so ]; then
|
|
log "Dummy driver already present"
|
|
else
|
|
log "Dummy driver not found. Will try to install xserver-xorg-video-dummy..."
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
sudo apt-get update -qq && sudo apt-get install -y -qq xserver-xorg-video-dummy || log "WARNING: apt failed, dummy not installed (VIRTUAL1 should still work)"
|
|
else
|
|
log "WARNING: apt-get not found, skipping dummy driver install"
|
|
fi
|
|
fi
|
|
|
|
# --- Create X11 fallback config ---
|
|
log "Creating X11 fallback config at $X11_CONF"
|
|
echo "retrowest" | sudo -S bash -c 'cat > /etc/X11/xorg.conf.d/90-fallback.conf' <<'EOF'
|
|
# Fallback Xorg config: guarantee a framebuffer even without HDMI
|
|
Section "Device"
|
|
Identifier "AutoDevice"
|
|
Driver "modesetting"
|
|
EndSection
|
|
|
|
Section "Monitor"
|
|
Identifier "AutoMonitor"
|
|
Option "DPMS" "false"
|
|
EndSection
|
|
|
|
Section "Screen"
|
|
Identifier "AutoScreen"
|
|
Device "AutoDevice"
|
|
Monitor "AutoMonitor"
|
|
DefaultDepth 24
|
|
SubSection "Display"
|
|
Depth 24
|
|
Virtual 1920 1080
|
|
Modes "1920x1080"
|
|
EndSubSection
|
|
EndSection
|
|
EOF
|
|
|
|
sudo chmod 644 /etc/X11/xorg.conf.d/90-fallback.conf
|
|
log "X11 config installed"
|
|
|
|
# --- Install fallback script ---
|
|
log "Installing hdmi-fallback.sh to ~/.local/bin/"
|
|
mkdir -p "$HOME/.local/bin"
|
|
cat > "$BIN_DST" <<'SCRIPT'
|
|
#!/bin/bash
|
|
LOG="$HOME/.local/logs/drm-hotplug.log"
|
|
mkdir -p "$(dirname "$LOG")"
|
|
export DISPLAY=:0
|
|
|
|
log() {
|
|
echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOG" >&1
|
|
}
|
|
|
|
log "=== Starting VIRTUAL1-primary fallback monitor ==="
|
|
|
|
MODE="1920x1080_60.00"
|
|
if ! xrandr 2>/dev/null | grep -q "$MODE"; then
|
|
xrandr --newmode "$MODE" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 2>/dev/null || true
|
|
fi
|
|
xrandr --addmode VIRTUAL1 "$MODE" 2>/dev/null || true
|
|
|
|
setup_virtual_primary() {
|
|
log "Setting up VIRTUAL1 as primary..."
|
|
xrandr --output VIRTUAL1 --mode "$MODE" --primary 2>&1 && log "VIRTUAL1 primary OK" || log "VIRTUAL1 primary failed"
|
|
}
|
|
|
|
enable_hdmi_clone() {
|
|
log "Enabling HDMI1 as clone of VIRTUAL1"
|
|
xrandr --output HDMI1 --auto --same-as VIRTUAL1 2>&1 && log "HDMI1 cloned OK" || log "HDMI1 clone failed"
|
|
}
|
|
|
|
disable_hdmi() {
|
|
log "HDMI1 disconnected, keeping VIRTUAL1 primary"
|
|
xrandr --output HDMI1 --off 2>&1 && log "HDMI1 off OK" || true
|
|
}
|
|
|
|
for p in /sys/class/drm/card1-HDMI-A-1 /sys/class/drm/card0-HDMI-A-1; do
|
|
[ -e "$p/status" ] && { CONNECTOR="$p"; break; }
|
|
done
|
|
[ -z "$CONNECTOR" ] && CONNECTOR=$(find /sys/class/drm -maxdepth 1 -name "*HDMI-A-1" -type d | head -1)
|
|
|
|
if [ -z "$CONNECTOR" ] || [ ! -e "$CONNECTOR/status" ]; then
|
|
log "ERROR: No HDMI-A-1 found"
|
|
setup_virtual_primary
|
|
exit 1
|
|
fi
|
|
|
|
log "Monitoring: $CONNECTOR"
|
|
|
|
setup_virtual_primary
|
|
HDMI_STATE=$(cat "$CONNECTOR/status" 2>/dev/null || echo "unknown")
|
|
log "Initial HDMI state: $HDMI_STATE"
|
|
|
|
if [ "$HDMI_STATE" = "connected" ]; then
|
|
enable_hdmi_clone
|
|
else
|
|
disable_hdmi
|
|
fi
|
|
|
|
log "Initial setup complete. Monitors:"
|
|
xrandr --listmonitors 2>&1 | while read line; do log " $line"; done
|
|
|
|
LAST_STATE="$HDMI_STATE"
|
|
|
|
while true; do
|
|
CURRENT=$(cat "$CONNECTOR/status" 2>/dev/null || echo "unknown")
|
|
if [ "$CURRENT" != "$LAST_STATE" ]; then
|
|
log "HDMI changed: $LAST_STATE -> $CURRENT"
|
|
setup_virtual_primary
|
|
if [ "$CURRENT" = "connected" ]; then
|
|
enable_hdmi_clone
|
|
else
|
|
disable_hdmi
|
|
fi
|
|
log "Monitor layout after change:"
|
|
xrandr --listmonitors 2>&1 | while read line; do log " $line"; done
|
|
LAST_STATE="$CURRENT"
|
|
fi
|
|
sleep 2
|
|
done
|
|
SCRIPT
|
|
|
|
chmod +x "$BIN_DST"
|
|
log "Script installed"
|
|
|
|
# --- Install systemd unit ---
|
|
log "Installing systemd user unit"
|
|
mkdir -p "$HOME/.config/systemd/user"
|
|
cat > "$SYSTEMD_DST" <<'UNIT'
|
|
[Unit]
|
|
Description=HDMI to VIRTUAL1 Fallback Monitor
|
|
After=graphical-session.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=%h/.local/bin/hdmi-fallback.sh
|
|
Restart=always
|
|
RestartSec=5
|
|
Environment="DISPLAY=:0"
|
|
|
|
[Install]
|
|
WantedBy=graphical-session.target
|
|
UNIT
|
|
|
|
systemctl --user daemon-reload
|
|
systemctl --user enable --now hdmi-fallback.service
|
|
log "Systemd unit enabled and started"
|
|
|
|
# --- Summary ---
|
|
echo ""
|
|
echo "============================================"
|
|
echo "RDtop installation complete!"
|
|
echo "============================================"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo "1. Reboot or re-login to apply X11 config"
|
|
echo " sudo systemctl restart gdm"
|
|
echo ""
|
|
echo "2. After reboot, verify VIRTUAL1 is primary:"
|
|
echo " xrandr --listmonitors"
|
|
echo ""
|
|
echo "3. Check service status:"
|
|
echo " systemctl --user status hdmi-fallback.service"
|
|
echo ""
|
|
echo "4. To verify: unplug HDMI cable, VIRTUAL1 will stay active"
|
|
echo ""
|
|
log "Install complete"
|