joeylib2/scripts/verify-be-input.sh

118 lines
4.3 KiB
Bash
Executable file

#!/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-be-input.sh - Typed-character acceptance gate for a Be API port
# (haiku, haiku32, beos). Runs KEYS in the port's VM under QEMU
# (scripts/lib/beGate.sh) at one window pixel per stage pixel
# (JOEYLIB_SCALE=1, JOEYLIB_ASPECT=square), types the RetroNet
# definition-of-done string through QEMU's PS/2 keyboard (QMP send-key,
# shift and all: the keys go through the system's input server and keymap
# as a person's would), takes QEMU's screen and decodes the example's
# verification scanline (row 198) with tests/gate/keysRow.c, wherever the
# desktop put the window. Typing starts once the screen shows KEYS's empty
# row (the window is up); the screen is read until the row is whole or time
# runs out. Then the named keys a second key gives (scripts/lib/keysGate.sh):
# the keypad's arrows and Enter, and the right Ctrl and Alt, held through
# QMP and read off KEYS's cells (tests/gate/keysCells.c). Escape then ends
# KEYS, and the VM.
#
# Usage: scripts/verify-be-input.sh [haiku|haiku32|beos] (default haiku)
# Env: BE_INPUT_KEEP keep the last screen as build/PORT/be-input.png
# when the gate fails
# Requires: QEMU and the port's VM (./install.sh install emulator:PORT);
# build/PORT/bin/KEYS (make PORT).
set -uo pipefail
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
source "$repo/scripts/lib/joeyEnv.sh"
source "$repo/scripts/lib/beGate.sh"
source "$repo/scripts/lib/keysGate.sh"
port=${1:-haiku}
label="verify-be-input ($port)"
target="192.168.1.10:6510"
beNeed "$port"
program=$(joeyExampleProgram keys "$port")
[ -x "$program" ] || { echo "$label: build KEYS first (make $port)" >&2; exit 2; }
bootSeconds=120
runSeconds=120
rowSeconds=30
escapeHoldMs=400
work=$(mktemp -d -t joeylib-be-input.XXXXXX)
cleanup() {
beStop
rm -rf "$work"
}
trap cleanup EXIT
# rowShown TEXT -- the screen shows KEYS's row holding TEXT, read once a
# second for up to rowSeconds; the last read's verdict is printed.
rowShown() {
local tries
for ((tries = 0; tries < rowSeconds; tries++)); do
beQmp "$work" screendump "$work/keys.png"
if "$(joeyTool keysRow)" "$work/keys.png" "$1" --scale 1 > "$work/row.txt"; then
cat "$work/row.txt"
return 0
fi
sleep 1
done
cat "$work/row.txt"
return 1
}
mkdir -p "$work/job/KEYS"
cp "$program" "$work/job/KEYS/KEYS"
beJobScript KEYS KEYS "" "$runSeconds" JOEYLIB_SCALE=1 JOEYLIB_ASPECT=square > "$work/job/job.sh"
beJobDisk "$work/job.img" "$work/job"
beStart "$work" "$work/job.img"
if ! beWaitJob "$work" "$bootSeconds"; then
echo "$label: FAIL - the VM did not start the job within ${bootSeconds} s" >&2
exit 1
fi
if ! rowShown "" > /dev/null; then
echo "$label: FAIL - KEYS's window did not come up within ${rowSeconds} s" >&2
exit 1
fi
beQmp "$work" type "$target"
# The stage at one pixel a pixel, wherever the window is.
if rowShown "$target"; then
passed=1
else
passed=0
fi
if [ "$passed" = 1 ] && [[ "$(cat "$work/row.txt")" =~ row\ at\ \(([0-9]+),([0-9]+)\) ]]; then
stageAt="${BASH_REMATCH[1]},$((BASH_REMATCH[2] - 198))"
# QEMU's names for the keys (scripts/lib/keysGate.sh's).
declare -A qcode=([up]=up [kp8]=kp_8 [kp2]=kp_2 [kp4]=kp_4 [kp6]=kp_6 [kpenter]=kp_enter [rctrl]=ctrl_r [ralt]=alt_r)
KEYS_LABEL=$label
keysPress() {
beQmp "$work" down "${qcode[$1]}"
}
keysRelease() {
beQmp "$work" up "${qcode[$1]}"
}
keysRead() {
beQmp "$work" screendump "$work/cells.png"
"$(joeyTool keysCells)" "$work/cells.png" --at "$stageAt"
}
keysRunSteps kp8 kp2 kp4 kp6 kpenter rctrl ralt
[ -z "$KEYS_FAILS" ] || passed=0
fi
beQmp "$work" hold esc "$escapeHoldMs"
beWaitExit "$work" "$runSeconds" || true
if [ "$passed" = 1 ]; then
echo "$label: PASS (typed \"$target\", all ${#target} chars arrived via jlInputGetChar; $KEYS_STEPS named-key steps: the keypad's arrows and Enter, right Ctrl and Alt, Up held with its second key)"
else
echo "$label: FAIL${KEYS_FAILS:+ - $KEYS_FAILS}" >&2
if [ -n "${BE_INPUT_KEEP:-}" ]; then
cp "$work/keys.png" "$repo/build/$port/be-input.png"
fi
exit 1
fi