65816-llvm-mos/runtime/include/iigs/eventLoop.h
2026-05-30 19:40:29 -05:00

86 lines
3 KiB
C

// iigs/eventLoop.h - curated event loop for desktop apps.
//
// Wraps TaskMaster in a "register callbacks, call run, get out when
// you signal quit" pattern. Saves writing the same 30-line dispatch
// switch in every demo. Built on the existing toolbox bindings —
// you can still drive TaskMaster directly for anything this header
// doesn't expose.
//
// Lifecycle:
// 1. startdesk(640) (from iigs/desktop.h)
// 2. Build menus + windows.
// 3. Fill an IigsEventCallbacksT.
// 4. iigsEventLoop(&cb) — runs until iigsEventLoopQuit() is called
// from inside a callback.
// 5. enddesk(userId).
#ifndef IIGS_EVENT_LOOP_H
#define IIGS_EVENT_LOOP_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
// EventRecord layout (per Apple GS/OS toolbox reference). Exposed
// here so callbacks can inspect the raw event when they need more
// than the dispatched arguments give them.
typedef struct {
uint16_t what; // event code
uint32_t message; // event-specific payload
uint32_t when; // tick count
int16_t whereX; // mouse X at event time
int16_t whereY; // mouse Y at event time
uint16_t modifiers; // key + button modifier state
uint16_t taskData; // TaskMaster scratch
uint16_t taskMask;
uint32_t window; // affected window (close box, content click, etc.)
uint32_t reserved[4];
} IigsEventT;
// Callback table. Any field may be NULL — the dispatch skips it and
// returns the event to TaskMaster's default handler.
typedef struct {
// Fired when the user clicks a window's close box. Argument is
// the window pointer; the callback should call CloseWindow on it
// and (if it was the last window) iigsEventLoopQuit().
void (*onClose)(uint32_t windowPtr);
// Fired when a menu item is picked (return value of MenuKey or
// MenuSelect). Arg layout: high 16 = menu ID, low 16 = item ID.
// The callback should HiliteMenu(0) when done with menu state.
void (*onMenu)(uint16_t menuId, uint16_t itemId);
// Fired for keystrokes that weren't a menu shortcut. Low 8 of
// arg is the character; modifiers are in the event record passed
// in `ev`.
void (*onKey)(uint8_t ch, const IigsEventT *ev);
// Fired for mouse clicks not consumed by TaskMaster (content
// clicks inside your window, drag-region clicks, etc.).
void (*onMouse)(const IigsEventT *ev);
// Called once per loop iteration when no event was pending.
// Use sparingly — this fires ~60 Hz and competes with WM redraw.
void (*onIdle)(void);
} IigsEventCallbacksT;
// Run the event loop until iigsEventLoopQuit() is called. TaskMaster
// is invoked with the standard `everyEvent` mask + all task masks
// enabled (drag bar, close box, zoom box, etc.).
void iigsEventLoop(const IigsEventCallbacksT *cb);
// Signal the running event loop to exit. Safe to call from any
// callback; takes effect after the current event is fully dispatched.
void iigsEventLoopQuit(void);
#ifdef __cplusplus
}
#endif
#endif // IIGS_EVENT_LOOP_H