// 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 // 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