#!/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"