#!/usr/bin/env bash # Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License. # See LICENSE.md for license information. # SPDX-License-Identifier: MIT # # verify-win16-icon.sh - a Win16 program's icon as Windows 3.1 shows it. # # make binds every Win16 program's icon into its executable (make/win16.mk: # tools/iconBake ico16, 32x32 in the 16 VGA colors, resource # HOSTED_ICON_ID), and the backend gives its window class that icon. Here # Program Manager is Windows' shell and WIN.INI's load= starts DRAW # (examples/draw) minimized, so Windows draws the class's icon on the # desktop -- and DRAW runs on, minimized, presenting to a window with no # room. DOSBox's own screenshot of the 800x600 screen must hold the baked # icon: every pixel of it the icon's mask leaves opaque, in its color. # # Usage: scripts/verify-win16-icon.sh # Env: WIN16_ICON_KEEP keep the screenshot as build/win16/win16-icon.png # Exit: 0 PASS, 1 FAIL, 2 SKIP (Windows or DOSBox not installed, or DRAW # not built) # Requires: DOSBox Staging, Xvfb, xdotool, the win311 # component; DRAW.EXE and its icon (make win16). set -euo pipefail repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) source "$repo/scripts/lib/joeyEnv.sh" source "$repo/scripts/lib/win16Gate.sh" label=verify-win16-icon win16Need program=$(joeyExampleProgram draw win16) icon=$repo/build/win16/icon/DRAW/icon.ico [ -f "$program" ] && [ -f "$icon" ] || { echo "$label: build DRAW.EXE first (make win16)" >&2; exit 2; } # Seconds to wait for the icon (Windows' boot is most of it), and between # screenshots. startSeconds=120 shotSeconds=10 # iconShown PNG: true when PNG holds the icon; says where, or that it does # not. iconShown() { "$(joeyTool iconFind)" win16 "$1" "$icon" "$label" } work=$(mktemp -d -t joeylib-win16-icon.XXXXXX) cleanup() { win16Stop rm -rf "$work" } trap cleanup EXIT mkdir -p "$work/program" "$work/shots" cp "$program" "$work/program/DRAW.EXE" win16Stage "$work" "$work/program" DRAW.EXE "$(joeyTool winIni)" "$work/c/WINDOWS/SYSTEM.INI" set boot shell progman.exe "$(joeyTool winIni)" "$work/c/WINDOWS/WIN.INI" set windows load 'D:\DRAW.EXE' WIN16_DOSBOX_ARGS=(--set "capture_dir=$work/shots" --set "default_image_capture_formats=raw") win16Start "$work" win="" for ((waited = 0; waited < startSeconds; waited += shotSeconds)); do sleep "$shotSeconds" [ -n "$win" ] || win=$(win16Window) || win="" [ -n "$win" ] || continue # Ctrl+F5: DOSBox's screenshot hotkey (the Ctrl reaches Program Manager, # which ignores it). rm -f "$work/shots/"*.png DISPLAY="$WIN16_DISPLAY" xdotool key --window "$win" ctrl+F5 sleep 2 png=$(find "$work/shots" -name '*.png' -print -quit) [ -n "$png" ] || continue [ -n "${WIN16_ICON_KEEP:-}" ] && cp "$png" "$repo/build/win16/win16-icon.png" if iconShown "$png" > "$work/verdict"; then cat "$work/verdict" exit 0 fi done cat "$work/verdict" 2> /dev/null || echo "$label: FAIL - no screenshot of Windows within ${startSeconds}s" exit 1