#!/bin/sh
# The machine-level wineserver: the Windows side of this machine, running
# before anyone logs in and outliving every logout.
#
# This is what a session-scoped wineserver cannot be. Windows services run as
# SYSTEM from boot, survive logout, and are visible to every logged-in user
# through one SCM. A server started by a login session and dying with it cannot
# express any of that -- debt item D5, and the hardest clause of the S2 gate.
#
# Runs as root, which wine-sg maps to the SYSTEM SID. See the security note in
# systemd/sg-wineserver.service before changing that.
set -eu

SG_LIB="${SG_LIB:-/usr/lib/stained-glass}"
# shellcheck source=lib/sg-common.sh
. "$SG_LIB/sg-common.sh"
# The machine's Windows system never uses a display. Whatever screen this was
# started from -- a build host's, a developer's desktop -- would otherwise be
# recorded in the shared prefix as the machine's monitor, and every user's
# desktop would be laid out for it.
unset DISPLAY WAYLAND_DISPLAY XAUTHORITY
sg_wine_env

# The prefix must exist before there is anything to serve.
if [ ! -e "$SG_PREFIX/.sg-initialized" ]; then
    sg_die "no initialized prefix at $SG_PREFIX; sg-prefix-init must run first"
fi

# HOME matters: Wine reads it for per-user paths, and root's must not be a
# session user's.
HOME="${HOME:-$SG_ROOT}"
export HOME

# A runtime dir for the server itself. There is no logind session here.
XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/stained-glass}"
export XDG_RUNTIME_DIR
mkdir -p "$XDG_RUNTIME_DIR"
chmod 700 "$XDG_RUNTIME_DIR"

# Session 0. The Windows system runs on the non-interactive window station, as
# it does on Windows, so Wine creates the desktop window for these processes
# itself instead of starting an explorer for them. Without this the machine
# gets a second shell that no one asked for, sharing a prefix and a wineserver
# with the logged-in user's real one, and the taskbar ends up laid out for
# whichever screen size won the race. See wine-sg patch 0007.
SG_WINSTATION='__wineservice_winstation\Default'
export SG_WINSTATION

# The machine's server must be the prefix's server. A Wine command run before
# this one (sg-prefix-init's, say) started a transient server of its own, and
# once the prefix has auto-start services -- Microsoft Edge installs three --
# they keep that server alive: this one then found the prefix taken, exited,
# and the machine came up on the wrong server. Stop any server first.
timeout 30 wineserver -k 2>/dev/null || true
# ...and wait until it is gone: -k only asks. Started at once, this server
# found the old one still there and exited (status 2); the login screen then
# came up against no machine server and nobody could sign in (release 612's
# boot gate). -w returns when the prefix has no server.
timeout 30 wineserver -w 2>/dev/null || true

sg_log "starting the machine-level wineserver (prefix: $SG_PREFIX)"

# -p with no argument means persistent forever: the server must not exit when
# the last client goes away, or logging out would take the machine's services
# with it -- which is the whole problem this exists to fix.
# -f keeps it in the foreground so systemd can supervise it.
exec wineserver -p -f
