123 lines
3 KiB
C
123 lines
3 KiB
C
// frame.c - faithful port of ORCA-C's Frame.cc sample.
|
|
//
|
|
// Mike Westerfield, Byte Works 1989. Original at
|
|
// tools/orca-c/C.Samples/Desktop.Samples/Frame.cc.
|
|
//
|
|
// The simplest possible Apple IIgs desktop app: Apple/File/Edit menu
|
|
// bar + TaskMaster event loop + About dialog. File>Quit (or cmd-Q)
|
|
// exits. The "About Frame" item in the Apple menu shows the original
|
|
// 4-line copyright dialog.
|
|
//
|
|
// Phase 4.1 migration: previously hand-rolled menu mini-format strings
|
|
// + AlertTemplate boilerplate. Now uses iigs/uiBuilder.h for both,
|
|
// shrinking the file by ~80 lines.
|
|
|
|
#include "iigs/toolbox.h"
|
|
#include "iigs/desktop.h"
|
|
#include "iigs/eventLoop.h"
|
|
#include "iigs/uiBuilder.h"
|
|
|
|
|
|
#define apple_About 257
|
|
#define file_Quit 256
|
|
|
|
|
|
static void onAbout(uint16_t cmdId);
|
|
static void onClose(uint32_t windowPtr);
|
|
static void onMenuDispatch(uint16_t menuId, uint16_t itemId);
|
|
static void onQuit(uint16_t cmdId);
|
|
|
|
|
|
static const UiCmdHandlerT gCmdTable[] = {
|
|
{ apple_About, onAbout },
|
|
{ file_Quit, onQuit },
|
|
};
|
|
|
|
|
|
static const UiMenuItemT gEditItems[] = {
|
|
{ 250, "Undo", 'Z', MI_CHECKED },
|
|
{ 251, "Cut", 'X', 0 },
|
|
{ 252, "Copy", 'C', 0 },
|
|
{ 253, "Paste", 'V', 0 },
|
|
{ 254, "Clear", 0, 0 },
|
|
};
|
|
|
|
static const UiMenuItemT gFileItems[] = {
|
|
{ 255, "Close", 0, MI_CHECKED },
|
|
{ 256, "Quit", 'Q', 0 },
|
|
};
|
|
|
|
static const UiMenuItemT gAppleItems[] = {
|
|
{ 257, "About Frame", 0, MI_CHECKED },
|
|
};
|
|
|
|
static const UiMenuT gMenus[] = {
|
|
{ 1, "Apple", MN_APPLE, 1, gAppleItems },
|
|
{ 2, " File ", 0, 2, gFileItems },
|
|
{ 3, " Edit ", 0, 5, gEditItems },
|
|
};
|
|
|
|
|
|
static void onAbout(uint16_t cmdId) {
|
|
(void)cmdId;
|
|
uiBuilderAlert(UA_NOTE,
|
|
"Frame 1.0\r"
|
|
"Copyright 1989\r"
|
|
"Byte Works, Inc.\r\r"
|
|
"By Mike Westerfield");
|
|
}
|
|
|
|
|
|
static void onClose(uint32_t windowPtr) {
|
|
(void)windowPtr;
|
|
// No app windows; close click is a no-op.
|
|
}
|
|
|
|
|
|
static void onMenuDispatch(uint16_t menuId, uint16_t itemId) {
|
|
(void)menuId;
|
|
uiBuilderDispatch(itemId, gCmdTable, (uint16_t)(sizeof gCmdTable / sizeof gCmdTable[0]));
|
|
}
|
|
|
|
|
|
static void onQuit(uint16_t cmdId) {
|
|
(void)cmdId;
|
|
iigsEventLoopQuit();
|
|
}
|
|
|
|
|
|
static volatile uint16_t gIdleTicks;
|
|
|
|
|
|
static void onIdle(void) {
|
|
// Headless watchdog: exit cleanly if no menu pick fires within
|
|
// ~4000 idle ticks. Interactive runs effectively never trip this.
|
|
if (++gIdleTicks > 4000) {
|
|
iigsEventLoopQuit();
|
|
}
|
|
}
|
|
|
|
|
|
int main(void) {
|
|
unsigned short userId = startdesk(640);
|
|
(void)userId;
|
|
|
|
paintDesktopBackdrop();
|
|
uiBuilderInstallMenuBar(gMenus, (uint16_t)(sizeof gMenus / sizeof gMenus[0]));
|
|
ShowCursor();
|
|
|
|
IigsEventCallbacksT cb;
|
|
{
|
|
unsigned char *p = (unsigned char *)&cb;
|
|
for (uint16_t i = 0; i < sizeof cb; i++) {
|
|
p[i] = 0;
|
|
}
|
|
}
|
|
cb.onMenu = onMenuDispatch;
|
|
cb.onClose = onClose;
|
|
cb.onIdle = onIdle;
|
|
iigsEventLoop(&cb);
|
|
|
|
*(volatile unsigned char *)0x70 = 0x99;
|
|
return 0;
|
|
}
|