// 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. // // Differences from the original: // - The watchdog at the bottom of the loop forces a clean exit so // the headless test (`demos/test.sh frame`) can verify $70 = $99. // In interactive use the watchdog is benign. #include "iigs/toolbox.h" #include "iigs/desktop.h" #define apple_About 257 #define file_Quit 256 #define wInSpecial 25 #define wInMenuBar 3 #define norml 0 #define stop 1 #define note 2 #define caution 3 #define buttonItem 10 #define statText 136 #define itemDisable 0x8000 typedef struct { unsigned short wmWhat; unsigned long wmMessage; unsigned long wmWhen; short wmWhereV, wmWhereH; unsigned short wmModifiers; unsigned long wmTaskData; unsigned long wmTaskMask; unsigned long wmLastClickTick; unsigned long wmClickCount; unsigned long wmTaskData2; unsigned long wmTaskData3; unsigned long wmTaskData4; } WmTaskRec; typedef struct { short itemID; short itemRectV1, itemRectH1, itemRectV2, itemRectH2; unsigned short itemType; void *itemDescr; short itemValue; short itemFlag; void *itemColor; } ItemTemplate; typedef struct { short atRectV1, atRectH1, atRectV2, atRectH2; short atBtnHorz; short atBeep0, atBeep1, atBeep2, atBeep3; void *atSound; void *atResv1; void *atResv2; void *atItemList[8]; } AlertTemplate; static unsigned char editMenuStr[] = ">> Edit \\N3\r" "--Undo\\N250V*Zz\r" "--Cut\\N251*Xx\r" "--Copy\\N252*Cc\r" "--Paste\\N253*Vv\r" "--Clear\\N254\r" ".\r"; static unsigned char fileMenuStr[] = ">> File \\N2\r" "--Close\\N255V\r" "--Quit\\N256*Qq\r" ".\r"; static unsigned char appleMenuStr[] = ">>@\\XN1\r" "--About Frame\\N257V\r" ".\r"; static unsigned char gAboutMsg[] = "\x3a" "Frame 1.0\r" "Copyright 1989\r" "Byte Works, Inc.\r\r" "By Mike Westerfield"; static WmTaskRec gEvent; static volatile unsigned short gDone; static void doAlert(unsigned short kind, void *msg) { static unsigned char okStr[] = "\x02OK"; static ItemTemplate button = { 1, 36, 15, 0, 0, buttonItem, okStr, 0, 0, (void *)0 }; static ItemTemplate message = { 100, 5, 100, 90, 280, itemDisable | statText, (void *)0, 0, 0, (void *)0 }; static AlertTemplate alertRec = { 50, 180, 107, 460, 2, 0x80, 0x80, 0x80, 0x80, (void *)0, (void *)0, (void *)0, { (void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0 } }; SetForeColor(0); SetBackColor(15); message.itemDescr = msg; alertRec.atItemList[0] = (void *)&button; alertRec.atItemList[1] = (void *)&message; alertRec.atItemList[2] = (void *)0; switch (kind) { case norml: (void)Alert(&alertRec, (void *)0); break; case stop: (void)StopAlert(&alertRec, (void *)0); break; case note: (void)NoteAlert(&alertRec, (void *)0); break; case caution: (void)CautionAlert(&alertRec, (void *)0); break; default: break; } } static void menuAbout(void) { doAlert(note, gAboutMsg); } static void handleMenu(unsigned short menuNum) { switch (menuNum) { case apple_About: menuAbout(); break; case file_Quit: gDone = 1; break; default: break; } HiliteMenu(0, (unsigned short)(gEvent.wmTaskData >> 16)); } static void initMenus(void) { InsertMenu(NewMenu(editMenuStr), 0); InsertMenu(NewMenu(fileMenuStr), 0); InsertMenu(NewMenu(appleMenuStr), 0); FixAppleMenu(1); FixMenuBar(); DrawMenuBar(); } int main(void) { unsigned short userId = startdesk(640); (void)userId; paintDesktopBackdrop(); // white desktop (WM dither -> noise in // our 640 B/W palette; paint directly) initMenus(); gEvent.wmTaskMask = 0x1FFFL; ShowCursor(); gDone = 0; unsigned short watchdog = 0; do { unsigned short event = TaskMaster(0x076E, &gEvent); switch (event) { case wInSpecial: case wInMenuBar: handleMenu((unsigned short)gEvent.wmTaskData); break; default: break; } watchdog++; } while (!gDone && watchdog < 4000); *(volatile unsigned char *)0x70 = 0x99; return 0; }