111 lines
3.6 KiB
Bash
111 lines
3.6 KiB
Bash
# shellcheck shell=bash
|
|
# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
|
|
# See LICENSE.md for license information.
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
# Shared by the Win32 gates (scripts/bench-win32.sh, scripts/verify-win32-*.sh)
|
|
# and joey-run: run a Win32 program (make win32) under Wine on a private Xvfb
|
|
# display with a private Wine prefix, so nothing reaches ~/.wine. Source after
|
|
# joeyEnv.sh. (Win16 programs run on Windows 3.11 in DOSBox instead:
|
|
# scripts/lib/win16Gate.sh.)
|
|
#
|
|
# wineNeed exit 2 unless Wine is installed
|
|
# wineEnv PREFIX Wine's environment for the prefix PREFIX, quiet;
|
|
# Wine makes the prefix when it first runs
|
|
# winePrefix WORK a prefix under WORK, made and settled before
|
|
# anything runs in it (a program started alongside
|
|
# Wine's first-run setup got no sound for its first
|
|
# seconds); sets WINEPREFIX
|
|
# wineStart WORK a display, then winePrefix WORK; sets DISPLAY,
|
|
# WINEPREFIX and WINE_XVFB_PID
|
|
# wineComPort N PATH the prefix's COMn opens the Unix device PATH (a pty
|
|
# a gate's peer or joey-run's socat made), and its
|
|
# wineserver is started; before wineRun
|
|
# wineRun EXE [ARGS...] start EXE in the background; sets WINE_PID
|
|
# wineWindow TITLE print the X window titled TITLE (waits for it)
|
|
# wineStop stop the program, the prefix's wineserver and the
|
|
# display
|
|
|
|
WINE_PID=""
|
|
WINE_XVFB_PID=""
|
|
WINE_WINDOW_TRIES=60
|
|
|
|
|
|
wineNeed() {
|
|
joeyNeed WINE wine
|
|
}
|
|
|
|
|
|
wineEnv() {
|
|
mkdir -p "$1"
|
|
export WINEPREFIX="$1"
|
|
export WINEDEBUG=-all
|
|
# No Mono or Gecko install prompts in a fresh prefix.
|
|
export WINEDLLOVERRIDES="mscoree,mshtml="
|
|
}
|
|
|
|
|
|
winePrefix() {
|
|
wineEnv "$1/prefix"
|
|
"$WINE" wineboot --init > "$1/wineboot.log" 2>&1
|
|
"$(dirname "$WINE")/wineserver" -w
|
|
}
|
|
|
|
|
|
wineStart() {
|
|
export DISPLAY=":$((RANDOM % 400 + 1800))"
|
|
Xvfb "$DISPLAY" -screen 0 1280x1024x24 -nolisten tcp > /dev/null 2>&1 &
|
|
WINE_XVFB_PID=$!
|
|
sleep 1
|
|
winePrefix "$1"
|
|
}
|
|
|
|
|
|
# Wine's mount manager makes dosdevices/comN from HKLM\Software\Wine\Ports
|
|
# when Wine starts (a link made by hand is refused, access denied), so the
|
|
# key is set and Wine restarted. The new wineserver is started here, its
|
|
# output in a log: it opens the pty itself and, a daemon with no terminal,
|
|
# makes it its own, so when the far end closes the pty it gets SIGHUP and
|
|
# prints every object it holds (megabytes), which must not land where the
|
|
# program's output goes.
|
|
wineComPort() {
|
|
printf 'REGEDIT4\r\n\r\n[HKEY_LOCAL_MACHINE\\Software\\Wine\\Ports]\r\n"COM%s"="%s"\r\n' "$1" "$2" > "$WINEPREFIX/../ports.reg"
|
|
"$WINE" regedit /S "$WINEPREFIX/../ports.reg"
|
|
"$(dirname "$WINE")/wineserver" -k
|
|
"$(dirname "$WINE")/wineserver" -w
|
|
"$(dirname "$WINE")/wineserver" > "$WINEPREFIX/../wineserver.log" 2>&1
|
|
}
|
|
|
|
|
|
wineRun() {
|
|
"$WINE" "$@" > "$WINEPREFIX/../wine.log" 2>&1 &
|
|
WINE_PID=$!
|
|
}
|
|
|
|
|
|
wineWindow() {
|
|
local tries
|
|
local win
|
|
for ((tries = 0; tries < WINE_WINDOW_TRIES; tries++)); do
|
|
win="$(xdotool search --name "^$1\$" 2>/dev/null | head -1)"
|
|
if [ -n "$win" ]; then
|
|
printf '%s\n' "$win"
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
return 1
|
|
}
|
|
|
|
|
|
wineStop() {
|
|
joeyStop "$WINE_PID"
|
|
WINE_PID=""
|
|
if [ -n "${WINEPREFIX:-}" ]; then
|
|
"$(dirname "$WINE")/wineserver" -k 2> /dev/null || true
|
|
fi
|
|
if [ -n "$WINE_XVFB_PID" ]; then
|
|
kill "$WINE_XVFB_PID" 2> /dev/null || true
|
|
WINE_XVFB_PID=""
|
|
fi
|
|
}
|