188 lines
5.2 KiB
C
188 lines
5.2 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.
|
|
//
|
|
// 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;
|
|
}
|