65816-llvm-mos/demos/menuBuilderProbe.c
Scott Duensing da095402ec Updated
2026-06-02 23:17:57 -05:00

103 lines
2.6 KiB
C

// menuBuilderProbe.c - Phase 4.1 smoke test.
//
// Builds a minimal Apple+File menu bar via the uiBuilder surface,
// installs it, runs the event loop, then sets $70=0x99 when the
// File>Quit (or cmd-Q) handler fires. Verifies:
// - uiBuilderMenuBytes emits a byte stream NewMenu accepts.
// - uiBuilderInstallMenuBar drives DrawMenuBar without hanging.
// - uiBuilderDispatch routes the menu pick to the right handler.
// - Cmd-Q keystroke wakes the loop within the test.sh timeout.
#include "iigs/toolbox.h"
#include "iigs/desktop.h"
#include "iigs/eventLoop.h"
#include "iigs/uiBuilder.h"
#include <stdint.h>
#define CMD_ABOUT 257
#define CMD_QUIT 256
static volatile uint16_t gIdleTicks;
static void onIdle(void) {
if (++gIdleTicks > 2000) {
iigsEventLoopQuit();
}
}
static void onAbout(uint16_t cmdId) {
(void)cmdId;
// Mark "About picked" at $71. Test reads this if it wants to
// confirm the dispatcher fired for a non-Quit item.
*(volatile unsigned char *)0x71 = 0xAB;
}
static void onQuit(uint16_t cmdId) {
(void)cmdId;
// Mark "Quit picked" at $72, then ask the loop to exit.
*(volatile unsigned char *)0x72 = 0xCD;
iigsEventLoopQuit();
}
static const UiCmdHandlerT gCmdTable[] = {
{ CMD_ABOUT, onAbout },
{ CMD_QUIT, onQuit },
};
static const UiMenuItemT gAppleItems[] = {
{ CMD_ABOUT, "About Menu Probe", 0, 0 },
};
static const UiMenuItemT gFileItems[] = {
{ CMD_QUIT, "Quit", 'Q', 0 },
};
static const UiMenuT gMenus[] = {
{ 1, "Apple", MN_APPLE, 1, gAppleItems },
{ 2, "File", 0, 1, gFileItems },
};
static void myOnMenu(uint16_t menuId, uint16_t itemId) {
(void)menuId;
uiBuilderDispatch(itemId, gCmdTable, (uint16_t)(sizeof gCmdTable / sizeof gCmdTable[0]));
}
int main(void) {
unsigned short userId = startdesk(640);
(void)userId;
paintDesktopBackdrop();
uiBuilderInstallMenuBar(gMenus, (uint16_t)(sizeof gMenus / sizeof gMenus[0]));
ShowCursor();
// Marker: init complete. Even if no menu pick comes in, this
// proves the builder + DrawMenuBar got through.
*(volatile unsigned char *)0x70 = 0x55;
IigsEventCallbacksT cb;
{
unsigned char *p = (unsigned char *)&cb;
for (uint16_t i = 0; i < sizeof cb; i++) {
p[i] = 0;
}
}
cb.onMenu = myOnMenu;
// Watchdog so the headless test exits even if no key injection
// reaches the menu pick: count idle ticks and quit after ~2000.
cb.onIdle = onIdle;
iigsEventLoop(&cb);
// Final marker: loop exited cleanly.
*(volatile unsigned char *)0x70 = 0x99;
return 0;
}