diff --git a/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/TemplateInfo.plist b/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/TemplateInfo.plist
index 3bfb740..420a8d1 100644
--- a/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/TemplateInfo.plist
+++ b/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/TemplateInfo.plist
@@ -135,7 +135,25 @@
Description
This template creates an Apple IIgs C code project to build desktop application. The project starts with a single C file which you can modify. You can also add more assembly or C files as you may like.
Options
-
+
+
+ Identifier
+ RESOLUTIONMODE
+ Name
+ Desktop Resolution
+ Description
+ Specify 640 or 320 pixel desktop enviroment.
+ Type
+ popup
+ Default
+ 640
+ Values
+
+ 640
+ 320
+
+
+
Targets
diff --git a/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.c b/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.c
index d34c346..88f0c0b 100644
--- a/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.c
+++ b/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.c
@@ -14,45 +14,665 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
+#include
+#include
+#include
+
+#include
+#include
+#include
#include "___FILEBASENAME___.h"
-// Defines and macros
+/* Defines and macros */
#define TOOLFAIL(string) \
if (toolerror()) SysFailMgr(toolerror(), "\p" string "\n\r Error Code -> $");
+#define MAX_DOCUMENT_NAME 80
-// Globals
+#define PRINT_RECORD_SIZE 140
-BOOLEAN done;
+
+/* Types */
+
+typedef struct tDocument
+{
+ struct tDocument * nextDocument;
+ struct tDocument * prevDocument;
+ GrafPortPtr wPtr;
+ char documentName[MAX_DOCUMENT_NAME + 1];
+ BOOLEAN isOnDisk;
+ ResultBuf255Hndl fileName;
+ ResultBuf255Hndl pathName;
+ PrRecHndl printRecordHandle;
+} tDocument;
+
+
+/* Globals */
+
+BOOLEAN shouldQuit;
EventRecord myEvent;
unsigned int userid;
+tDocument * documentList;
-// Implementation
+/* Forward declarations */
-void doAbout(void)
+void doFileSave(void);
+
+
+/* Implementation */
+
+const char * resourceString(int resourceId, const char * defaultValue)
{
- AlertWindow(awCString + awResource, NULL, ABOUT_ALERT_STRING);
+ Handle handle;
+ const char *result = defaultValue;
+
+ handle = LoadResource(rCString, resourceId);
+ if (toolerror() == 0) {
+ HLock(handle);
+ result = (const char *) (*handle);
+ }
+ return(result);
}
-GrafPortPtr newDocument(void)
+void freeResourceString(int resourceId)
{
- return(NewWindow2("\p MyWindow ", 0, NULL, NULL, 0x02, WINDOW_RESID, rWindParam1));
+ ReleaseResource(-3, rCString, resourceId);
+}
+
+
+void showErrorAlert(int resourceId, int toolErrorCode)
+{
+ char buffer[40] = "";
+ const char *substArray[2];
+ const char *toolErrorFormat;
+
+ if (toolErrorCode != 0) {
+ toolErrorFormat = resourceString(TOOL_ERROR_STRING, "\n\nTool error code = $%04x");
+ sprintf(buffer, toolErrorFormat, toolErrorCode);
+ freeResourceString(TOOL_ERROR_STRING);
+ }
+
+ substArray[0] = resourceString(resourceId, "Unknown error has occurred");
+ substArray[1] = buffer;
+
+ AlertWindow(awCString + awResource, (Pointer) substArray, ERROR_ALERT_STRING);
+ freeResourceString(resourceId);
+}
+
+
+tDocument * findDocumentFromWindow(GrafPortPtr wPtr)
+{
+ tDocument * result = documentList;
+
+ while (result != NULL) {
+ if (result->wPtr == wPtr)
+ break;
+
+ result = result->nextDocument;
+ }
+
+ return result;
+}
+
+
+#pragma databank 1
+void drawContents(void)
+{
+ DrawControls(GetPort());
+}
+#pragma databank 0
+
+
+const char * getUntitledName(void)
+{
+ static int untitledNum = 1;
+ static char buffer[MAX_DOCUMENT_NAME];
+ const char *untitledFormat = resourceString(UNTITLED_STRING, " Untitled %d ");
+
+ sprintf(buffer, untitledFormat, untitledNum);
+ freeResourceString(UNTITLED_STRING);
+ untitledNum++;
+
+ return(buffer);
+}
+
+
+tDocument * newDocument(const char * windowName)
+{
+ tDocument * documentPtr;
+ int titleLength;
+
+ documentPtr = malloc(sizeof(tDocument));
+ if (documentPtr == NULL) {
+ showErrorAlert(MALLOC_ERROR_STRING, 0);
+ return(NULL);
+ }
+ documentPtr->printRecordHandle = (PrRecHndl) NewHandle(PRINT_RECORD_SIZE, userid, 0, NULL);
+ if (toolerror() != 0) {
+ showErrorAlert(MALLOC_ERROR_STRING, toolerror());
+ free(documentPtr);
+ return(NULL);
+ }
+ PrDefault(documentPtr->printRecordHandle);
+
+ documentPtr->isOnDisk = FALSE;
+ documentPtr->fileName = NULL;
+ documentPtr->pathName = NULL;
+
+ titleLength = strlen(windowName);
+ if (titleLength > MAX_DOCUMENT_NAME) {
+ titleLength = MAX_DOCUMENT_NAME;
+ }
+ documentPtr->documentName[0] = titleLength;
+ strncpy(&(documentPtr->documentName[1]), windowName, titleLength);
+
+ documentPtr->wPtr = NewWindow2(documentPtr->documentName, 0, drawContents, NULL, refIsResource,
+ WINDOW_RESID, rWindParam1);
+ if (documentPtr->wPtr == NULL) {
+ showErrorAlert(NEW_WINDOW_ERROR_STRING, toolerror());
+ DisposeHandle((Handle)documentPtr->printRecordHandle);
+ free(documentPtr);
+ return(NULL);
+ }
+
+ documentPtr->nextDocument = documentList;
+ documentPtr->prevDocument = NULL;
+ if (documentList != NULL)
+ documentList->prevDocument = documentPtr;
+
+ documentList = documentPtr;
+
+ return(documentPtr);
+}
+
+
+BOOLEAN isDocumentDirty(tDocument * documentPtr)
+{
+ BOOLEAN isDirty = FALSE;
+ CtlRecHndl controlHdl;
+ CtlRec * controlPtr;
+
+ controlHdl = GetCtlHandleFromID(documentPtr->wPtr, CONTROL_TEXT_EDIT);
+ if (toolerror() == 0) {
+ HLock((Handle) controlHdl);
+ controlPtr = *controlHdl;
+ isDirty = ((controlPtr->ctlFlag & fRecordDirty) != 0);
+ HUnlock((Handle) controlHdl);
+ }
+ return isDirty;
+}
+
+
+void clearDocumentDirty(tDocument * documentPtr)
+{
+ CtlRecHndl controlHdl;
+ CtlRec * controlPtr;
+
+ controlHdl = GetCtlHandleFromID(documentPtr->wPtr, CONTROL_TEXT_EDIT);
+ if (toolerror() == 0) {
+ HLock((Handle) controlHdl);
+ controlPtr = *controlHdl;
+ controlPtr->ctlFlag &= (~fRecordDirty);
+ HUnlock((Handle) controlHdl);
+ }
+}
+
+
+void saveDocument(tDocument * documentPtr)
+{
+ RefNumRecGS closeRecord;
+ CreateRecGS createRecord;
+ NameRecGS destroyRecord;
+ OpenRecGS openRecord;
+ IORecGS writeRecord;
+
+ GrafPortPtr tmpPort;
+ LongWord dataLength;
+ Handle dataHandle;
+
+ tmpPort = GetPort();
+ SetPort(documentPtr->wPtr);
+ dataLength = TEGetText(teTextIsNewHandle | teDataIsCString, (Ref) &dataHandle, 0,
+ 0, (Ref) NULL, NULL);
+ if (toolerror() != 0) {
+ showErrorAlert(SAVE_FILE_ERROR_STRING, toolerror());
+ SetPort(tmpPort);
+ return;
+ }
+
+ HLock((Handle) documentPtr->pathName);
+
+ destroyRecord.pCount = 1;
+ destroyRecord.pathname = &((*(documentPtr->pathName))->bufString);
+ DestroyGS(&destroyRecord);
+
+ createRecord.pCount = 5;
+ createRecord.pathname = &((*(documentPtr->pathName))->bufString);
+ createRecord.access = destroyEnable | renameEnable | readWriteEnable;
+ createRecord.fileType = 0x04;
+ createRecord.auxType = 0x0000;
+ createRecord.storageType = 1;
+ CreateGS(&createRecord);
+
+ if (toolerror() != 0) {
+ showErrorAlert(SAVE_FILE_ERROR_STRING, toolerror());
+ } else {
+ openRecord.pCount = 3;
+ openRecord.pathname = &((*(documentPtr->pathName))->bufString);
+ openRecord.requestAccess = writeEnable;
+ OpenGS(&openRecord);
+
+ if (toolerror() != 0) {
+ showErrorAlert(SAVE_FILE_ERROR_STRING, toolerror());
+ } else {
+ HLock(dataHandle);
+
+ writeRecord.pCount = 4;
+ writeRecord.refNum = openRecord.refNum;
+ writeRecord.dataBuffer = *dataHandle;
+ writeRecord.requestCount = dataLength;
+ WriteGS(&writeRecord);
+
+ if (toolerror() != 0) {
+ showErrorAlert(SAVE_FILE_ERROR_STRING, toolerror());
+ } else {
+ documentPtr->isOnDisk = TRUE;
+ clearDocumentDirty(documentPtr);
+ }
+
+ HUnlock(dataHandle);
+
+ closeRecord.pCount = 1; /* close the file */
+ closeRecord.refNum = openRecord.refNum;
+ CloseGS(&closeRecord);
+ }
+ }
+
+ DisposeHandle(dataHandle);
+ HUnlock((Handle) documentPtr->pathName);
+ SetPort(tmpPort);
+}
+
+
+BOOLEAN loadDocument(tDocument * documentPtr)
+{
+ BOOLEAN result = TRUE;
+
+ RefNumRecGS closeRecord;
+ OpenRecGS openRecord;
+ IORecGS readRecord;
+ GrafPortPtr tmpPort;
+ Handle dataHandle;
+
+ openRecord.pCount = 12;
+ HLock((Handle) documentPtr->pathName);
+ openRecord.pathname = &((*(documentPtr->pathName))->bufString);
+ openRecord.requestAccess = readEnable;
+ openRecord.resourceNumber = 0;
+ openRecord.optionList = NULL;
+ OpenGS(&openRecord);
+
+ if (toolerror() != 0) {
+ showErrorAlert(OPEN_FILE_ERROR_STRING, toolerror());
+ result = FALSE;
+ } else {
+ dataHandle = NewHandle(openRecord.eof, userid, attrLocked, NULL);
+
+ if (toolerror() != 0) {
+ showErrorAlert(MALLOC_ERROR_STRING, toolerror());
+ result = FALSE;
+ } else {
+ readRecord.pCount = 4;
+ readRecord.refNum = openRecord.refNum;
+ readRecord.dataBuffer = *dataHandle;
+ readRecord.requestCount = openRecord.eof;
+ ReadGS(&readRecord);
+
+ if (toolerror() != 0) {
+ showErrorAlert(OPEN_FILE_ERROR_STRING, toolerror());
+ result = FALSE;
+ } else {
+ tmpPort = GetPort();
+ SetPort(documentPtr->wPtr);
+ TESetText(teTextIsPtr | teDataIsTextBlock, (Ref)*dataHandle, openRecord.eof,
+ teCtlStyleIsPtr, NULL, NULL);
+ SetPort(tmpPort);
+ }
+ DisposeHandle(dataHandle);
+ }
+
+ closeRecord.pCount = 1;
+ closeRecord.refNum = openRecord.refNum;
+ CloseGS(&closeRecord);
+ }
+
+ HUnlock((Handle) documentPtr->pathName);
+ clearDocumentDirty(documentPtr);
+
+ return result;
}
void closeDocument(GrafPortPtr wPtr)
{
- if (wPtr != NULL) {
- CloseWindow(wPtr);
+ tDocument * documentPtr;
+ char documentName[MAX_DOCUMENT_NAME];
+ char * alertStrings[] = { documentName };
+ int documentNameLen;
+ char * tmpPtr;
+ int buttonClicked;
+
+ if (wPtr == NULL)
+ return;
+
+ documentPtr = findDocumentFromWindow(wPtr);
+ if (documentPtr != NULL) {
+ while (isDocumentDirty(documentPtr)) {
+ /* The documentName in the documentPtr is actually a PString so the
+ first byte is the length of the string. */
+ tmpPtr = documentPtr->documentName;
+ documentNameLen = *tmpPtr;
+ tmpPtr++;
+
+ /* The documentName has spaces before and after the real name to format
+ the string for the window title bar. Strip those spaces out and store
+ the name into the documentName local array. */
+ while ((documentNameLen > 0) &&
+ (tmpPtr[documentNameLen - 1] == ' ')) {
+ documentNameLen--;
+ }
+ while (*tmpPtr == ' ') {
+ tmpPtr++;
+ documentNameLen--;
+ }
+ strncpy(documentName, tmpPtr, documentNameLen);
+ documentName[documentNameLen] = '\0';
+
+ buttonClicked = AlertWindow(awCString+awResource, (Pointer) alertStrings, SAVE_BEFORE_CLOSING);
+ switch (buttonClicked) {
+ case 0:
+ doFileSave();
+ break;
+
+ case 1:
+ clearDocumentDirty(documentPtr);
+ break;
+
+ case 2:
+ return;
+ }
+ }
}
+
+ CloseWindow(wPtr);
+
+ if (documentPtr == NULL)
+ return;
+
+ if (documentPtr->fileName != NULL) {
+ DisposeHandle((Handle) documentPtr->fileName);
+ documentPtr->fileName = NULL;
+ }
+ if (documentPtr->pathName != NULL) {
+ DisposeHandle((Handle) documentPtr->pathName);
+ documentPtr->pathName = NULL;
+ }
+ if (documentPtr->printRecordHandle != NULL) {
+ DisposeHandle((Handle)documentPtr->printRecordHandle);
+ documentPtr->printRecordHandle = NULL;
+ }
+ if (documentList == documentPtr) {
+ documentList = documentPtr->nextDocument;
+ } else if (documentPtr->prevDocument != NULL) {
+ documentPtr->prevDocument->nextDocument = documentPtr->nextDocument;
+ }
+
+ if (documentPtr->nextDocument != NULL)
+ documentPtr->nextDocument->prevDocument = documentPtr->prevDocument;
+
+ free(documentPtr);
+}
+
+
+void printDocument(tDocument * documentPtr)
+{
+ GrafPortPtr printerPort;
+ LongWord lineNumber;
+ PrStatusRec printerStatus;
+ Rect pageRect;
+
+ printerPort = PrOpenDoc(documentPtr->printRecordHandle, NULL);
+ if (toolerror() != 0) {
+ showErrorAlert(PRINT_ERROR_STRING, toolerror());
+ return;
+ }
+
+ HLock((Handle) documentPtr->printRecordHandle);
+ pageRect = (*(documentPtr->printRecordHandle))->prInfo.rPage;
+ HUnlock((Handle) documentPtr->printRecordHandle);
+
+ if (toolerror() != 0) {
+ showErrorAlert(PRINT_ERROR_STRING, toolerror());
+ } else {
+ lineNumber = 0;
+ while (lineNumber != -1) {
+ PrOpenPage(printerPort, NULL);
+ if (toolerror() != 0) {
+ showErrorAlert(PRINT_ERROR_STRING, toolerror());
+ break;
+ }
+ else {
+ lineNumber = TEPaintText(printerPort, lineNumber, &pageRect, 0,
+ (Handle) GetCtlHandleFromID(documentPtr->wPtr, CONTROL_TEXT_EDIT));
+ PrClosePage(printerPort);
+ }
+ }
+ }
+ PrCloseDoc(printerPort);
+
+ if (PrError() == 0)
+ PrPicFile(documentPtr->printRecordHandle, NULL, &printerStatus);
+}
+
+
+void doAppleAbout(void)
+{
+ AlertWindow(awCString + awResource, NULL, ABOUT_ALERT_STRING);
+}
+
+
+void doFileNew(void)
+{
+ newDocument(getUntitledName());
+}
+
+
+void doFileOpen(void)
+{
+ tDocument * documentPtr;
+ SFTypeList2 fileTypes;
+ Handle nameHandle;
+ ResultBuf255Ptr namePtr;
+ int nameLen;
+ char documentName[MAX_DOCUMENT_NAME];
+ SFReplyRec2 reply;
+
+ /* By default, we want to open text files only which is what
+ the following fileTypes request. Customize as necessary. */
+ fileTypes.numEntries = 1;
+ fileTypes.fileTypeEntries[0].flags = 0x0000;
+ fileTypes.fileTypeEntries[0].fileType = 0x04;
+ fileTypes.fileTypeEntries[0].auxType = 0x0000;
+
+ reply.nameRefDesc = refIsNewHandle;
+ reply.pathRefDesc = refIsNewHandle;
+ SFGetFile2(30, 30, refIsResource, OPEN_FILE_STRING, NULL, &fileTypes, &reply);
+ if (toolerror() != 0) {
+ showErrorAlert(OPEN_FILE_ERROR_STRING, toolerror());
+ return;
+ }
+
+ if (reply.good) {
+ nameHandle = (Handle) reply.nameRef;
+ HLock(nameHandle);
+ namePtr = (ResultBuf255Ptr) (*nameHandle);
+ strcpy(documentName, " ");
+ nameLen = namePtr->bufString.length;
+ if (nameLen > MAX_DOCUMENT_NAME - 5)
+ nameLen = MAX_DOCUMENT_NAME - 5;
+ strncat(documentName, namePtr->bufString.text, nameLen);
+ strcat(documentName, " ");
+ HUnlock(nameHandle);
+ documentPtr = newDocument(documentName);
+ if (documentPtr == NULL) {
+ DisposeHandle((Handle) reply.nameRef);
+ DisposeHandle((Handle) reply.pathRef);
+ } else {
+ documentPtr->fileName = (ResultBuf255Hndl) reply.nameRef;
+ documentPtr->pathName = (ResultBuf255Hndl) reply.pathRef;
+ documentPtr->isOnDisk = loadDocument(documentPtr);
+
+ if (!documentPtr->isOnDisk)
+ closeDocument(documentPtr->wPtr);
+ }
+ }
+}
+
+
+void doFileSaveAs(void)
+{
+ Handle nameHandle;
+ ResultBuf255Ptr namePtr;
+ int nameLen;
+ SFReplyRec2 reply;
+ tDocument * documentPtr = findDocumentFromWindow(FrontWindow());
+
+ if (documentPtr == NULL)
+ return;
+
+ reply.nameRefDesc = refIsNewHandle;
+ reply.pathRefDesc = refIsNewHandle;
+
+ if (documentPtr->fileName == NULL)
+ SFPutFile2(30, 30, refIsResource, SAVE_FILE_STRING, refIsPointer,
+ (Ref) &(documentPtr->fileName), &reply);
+ else
+ SFPutFile2(30, 30, refIsResource, SAVE_FILE_STRING, refIsPointer,
+ (Ref) &((*(documentPtr->pathName))->bufString), &reply);
+
+ if (toolerror() != 0) {
+ showErrorAlert(SAVE_FILE_ERROR_STRING, toolerror());
+ return;
+ }
+
+ if (reply.good) {
+ nameHandle = (Handle) reply.nameRef;
+ HLock(nameHandle);
+ namePtr = (ResultBuf255Ptr) (*nameHandle);
+ strcpy(documentPtr->documentName, " ");
+ nameLen = namePtr->bufString.length;
+ if (nameLen > MAX_DOCUMENT_NAME - 6)
+ nameLen = MAX_DOCUMENT_NAME - 6;
+ strncat(documentPtr->documentName, namePtr->bufString.text, nameLen);
+ strcat(documentPtr->documentName, " ");
+ documentPtr->documentName[0] = strlen(documentPtr->documentName) - 1;
+ HUnlock(nameHandle);
+ SetWTitle(documentPtr->documentName, documentPtr->wPtr);
+
+ documentPtr->fileName = (ResultBuf255Hndl) reply.nameRef;
+ documentPtr->pathName = (ResultBuf255Hndl) reply.pathRef;
+ documentPtr->isOnDisk = TRUE;
+ saveDocument(documentPtr);
+ }
+}
+
+
+void doFileSave(void)
+{
+ tDocument * documentPtr = findDocumentFromWindow(FrontWindow());
+
+ if (documentPtr == NULL)
+ return;
+
+ if (documentPtr->isOnDisk)
+ saveDocument(documentPtr);
+ else
+ doFileSaveAs();
+}
+
+
+void doFileClose(void)
+{
+ closeDocument(FrontWindow());
+}
+
+
+void doFilePageSetup(void)
+{
+ tDocument * documentPtr = findDocumentFromWindow(FrontWindow());
+
+ if (documentPtr == NULL)
+ return;
+
+ PrStlDialog(documentPtr->printRecordHandle);
+}
+
+
+void doFilePrint(void)
+{
+ tDocument * documentPtr = findDocumentFromWindow(FrontWindow());
+
+ if (documentPtr == NULL)
+ return;
+
+ if (PrJobDialog(documentPtr->printRecordHandle))
+ printDocument(documentPtr);
+}
+
+
+void doFileQuit(void)
+{
+ shouldQuit = TRUE;
+}
+
+
+void doEditUndo(void)
+{
+ /* Nothing extra to do here. The text edit control handles this for us. */
+}
+
+
+void doEditCut(void)
+{
+ /* Nothing extra to do here. The text edit control handles this for us. */
+}
+
+
+void doEditCopy(void)
+{
+ /* Nothing extra to do here. The text edit control handles this for us. */
+}
+
+
+void doEditPaste(void)
+{
+ /* Nothing extra to do here. The text edit control handles this for us. */
+}
+
+
+void doEditClear(void)
+{
+ /* Nothing extra to do here. The text edit control handles this for us. */
}
@@ -66,35 +686,108 @@ void handleMenu(void)
switch (menuItemNum) {
case APPLE_ABOUT:
- doAbout();
+ doAppleAbout();
break;
+
case FILE_NEW:
- newDocument();
+ doFileNew();
break;
+
case FILE_OPEN:
- newDocument();
+ doFileOpen();
break;
+
+ case FILE_SAVE:
+ doFileSave();
+ break;
+
+ case FILE_SAVE_AS:
+ doFileSaveAs();
+ break;
+
case FILE_CLOSE:
- closeDocument(FrontWindow());
+ doFileClose();
break;
+
+ case FILE_PAGE_SETUP:
+ doFilePageSetup();
+ break;
+
+ case FILE_PRINT:
+ doFilePrint();
+ break;
+
case FILE_QUIT:
- done = TRUE;
+ doFileQuit();
break;
+
case EDIT_UNDO:
+ doEditUndo();
break;
+
case EDIT_CUT:
+ doEditCut();
break;
+
case EDIT_COPY:
+ doEditCopy();
break;
+
case EDIT_PASTE:
+ doEditPaste();
break;
+
case EDIT_CLEAR:
+ doEditClear();
break;
}
HiliteMenu(FALSE, menuNum);
}
+void dimMenus(void)
+{
+ static BOOLEAN windowWasOpen = TRUE;
+ static BOOLEAN applicationWindowWasInFront = TRUE;
+ BOOLEAN windowIsOpen;
+ BOOLEAN applicationWindowIsInFront;
+
+ GrafPortPtr wPtr = FrontWindow();
+ windowIsOpen = (wPtr != NULL);
+ applicationWindowIsInFront = (findDocumentFromWindow(wPtr) != NULL);
+
+ if ((windowIsOpen == windowWasOpen) &&
+ (applicationWindowIsInFront == applicationWindowWasInFront)) {
+ return;
+ }
+
+ windowWasOpen = windowIsOpen;
+ applicationWindowWasInFront = applicationWindowIsInFront;
+
+ if (windowIsOpen) {
+ EnableMItem(FILE_CLOSE);
+ SetMenuFlag(enableMenu, EDIT_MENU);
+ } else {
+ DisableMItem(FILE_CLOSE);
+ SetMenuFlag(disableMenu, EDIT_MENU);
+ }
+
+ if (applicationWindowIsInFront) {
+ EnableMItem(FILE_SAVE);
+ EnableMItem(FILE_SAVE_AS);
+ EnableMItem(FILE_PAGE_SETUP);
+ EnableMItem(FILE_PRINT);
+ } else {
+ DisableMItem(FILE_SAVE);
+ DisableMItem(FILE_SAVE_AS);
+ DisableMItem(FILE_PAGE_SETUP);
+ DisableMItem(FILE_PRINT);
+ }
+
+ DrawMenuBar();
+}
+
+
void initMenus(void)
{
int height;
@@ -120,6 +813,14 @@ void initMenus(void)
}
+void initGlobals(void)
+{
+ documentList = NULL;
+ shouldQuit = FALSE;
+ myEvent.wmTaskMask = 0x001F7FFF;
+}
+
+
int main(void)
{
int event;
@@ -134,12 +835,12 @@ int main(void)
toolStartupRef = StartUpTools(userid, refIsResource, TOOL_STARTUP);
TOOLFAIL("Unable to start tools");
+ initGlobals();
initMenus();
InitCursor();
- done = FALSE;
- myEvent.wmTaskMask = 0x001F7FFF;
- while (!done) {
+ while (!shouldQuit) {
+ dimMenus();
event = TaskMaster(everyEvent, &myEvent);
TOOLFAIL("Unable to handle next event");
diff --git a/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.h b/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.h
index fc87d96..ad388e1 100644
--- a/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.h
+++ b/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.h
@@ -11,30 +11,72 @@
#define _GUARD_PROJECT___PROJECTNAMEASIDENTIFIER____FILE___FILEBASENAMEASIDENTIFIER____
-#define MENU_BAR 1
+/* Menu bars */
+#define MENU_BAR 1
-#define APPLE_MENU 3
-#define FILE_MENU 4
-#define EDIT_MENU 5
-#define EDIT_UNDO 250
-#define EDIT_CUT 251
-#define EDIT_COPY 252
-#define EDIT_PASTE 253
-#define EDIT_CLEAR 254
+/* Menus */
+#define APPLE_MENU 3
+#define FILE_MENU 4
+#define EDIT_MENU 5
-#define FILE_NEW 401
-#define FILE_OPEN 402
-#define FILE_CLOSE 255
-#define FILE_QUIT 256
+
+/* Menu items */
+#define EDIT_UNDO 250
+#define EDIT_CUT 251
+#define EDIT_COPY 252
+#define EDIT_PASTE 253
+#define EDIT_CLEAR 254
+
+#define FILE_NEW 401
+#define FILE_OPEN 402
+#define FILE_SAVE 403
+#define FILE_SAVE_AS 404
+#define FILE_CLOSE 255
+#define FILE_PAGE_SETUP 405
+#define FILE_PRINT 406
+#define FILE_QUIT 256
#define APPLE_ABOUT 301
-#define ABOUT_ALERT_STRING 1
+/* Alert strings */
+#define ABOUT_ALERT_STRING 1
+#define ERROR_ALERT_STRING 2
+#define SAVE_BEFORE_CLOSING 3
+
+
+/* Error strings */
+#define TOOL_ERROR_STRING 2001
+#define NEW_WINDOW_ERROR_STRING 2002
+#define MALLOC_ERROR_STRING 2003
+#define OPEN_FILE_ERROR_STRING 2004
+#define SAVE_FILE_ERROR_STRING 2005
+#define PRINT_ERROR_STRING 2006
+
+
+/* Other strings */
+#define UNTITLED_STRING 3001
+#define OPEN_FILE_STRING 3002
+#define SAVE_FILE_STRING 3003
+#define HELLO_WORLD_STRING 3004
+
+
+/* Windows */
#define WINDOW_RESID 1001
+
+/* Controls */
+#define CONTROL_TEXT_EDIT 1001
+
+
+/* Tools */
#define TOOL_STARTUP 1
+/* By default, thie template builds for 640x200 mode. To build for
+ * 320x200 change the following value to 320 */
+#define RES_MODE ___VARIABLE_RESOLUTIONMODE___
+
+
#endif /* defined(_GUARD_PROJECT___PROJECTNAMEASIDENTIFIER____FILE___FILEBASENAMEASIDENTIFIER____) */
diff --git a/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.rez b/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.rez
index 0f847ca..6603118 100644
--- a/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.rez
+++ b/pkg/Templates/Apple IIgs/ORCAC Desktop Application.xctemplate/main.rez
@@ -11,6 +11,7 @@
#include "___FILEBASENAME___.h"
+/* Version resource */
resource rVersion (1) {
{
0, /* Major version number in BCD */
@@ -25,6 +26,7 @@ resource rVersion (1) {
};
+/* Menu bars */
resource rMenuBar (MENU_BAR) {
{
APPLE_MENU,
@@ -34,6 +36,7 @@ resource rMenuBar (MENU_BAR) {
};
+/* Menus */
resource rMenu (APPLE_MENU) {
APPLE_MENU,
refIsResource * menuTitleRefShift
@@ -44,7 +47,7 @@ resource rMenu (APPLE_MENU) {
APPLE_ABOUT
};
};
-
+resource rPString (APPLE_MENU, noCrossBank) {"@"};
resource rMenu (FILE_MENU) {
FILE_MENU,
@@ -55,11 +58,15 @@ resource rMenu (FILE_MENU) {
{
FILE_NEW,
FILE_OPEN,
+ FILE_SAVE,
+ FILE_SAVE_AS,
FILE_CLOSE,
+ FILE_PAGE_SETUP,
+ FILE_PRINT,
FILE_QUIT
};
};
-
+resource rPString (FILE_MENU, noCrossBank) {" File "};
resource rMenu (EDIT_MENU) {
EDIT_MENU,
@@ -75,8 +82,10 @@ resource rMenu (EDIT_MENU) {
EDIT_CLEAR
};
};
+resource rPString (EDIT_MENU, noCrossBank) {" Edit "};
+/* Menu items */
resource rMenuItem (EDIT_UNDO) {
EDIT_UNDO,
"Z", "z",
@@ -85,7 +94,7 @@ resource rMenuItem (EDIT_UNDO) {
+ fDivider,
EDIT_UNDO
};
-
+resource rPString (EDIT_UNDO, noCrossBank) {"Undo"};
resource rMenuItem (EDIT_CUT) {
EDIT_CUT,
@@ -94,7 +103,7 @@ resource rMenuItem (EDIT_CUT) {
refIsResource * itemTitleRefShift,
EDIT_CUT
};
-
+resource rPString (EDIT_CUT, noCrossBank) {"Cut"};
resource rMenuItem (EDIT_COPY) {
EDIT_COPY,
@@ -103,7 +112,7 @@ resource rMenuItem (EDIT_COPY) {
refIsResource * itemTitleRefShift,
EDIT_COPY
};
-
+resource rPString (EDIT_COPY, noCrossBank) {"Copy"};
resource rMenuItem (EDIT_PASTE) {
EDIT_PASTE,
@@ -112,7 +121,7 @@ resource rMenuItem (EDIT_PASTE) {
refIsResource * itemTitleRefShift,
EDIT_PASTE
};
-
+resource rPString (EDIT_PASTE, noCrossBank) {"Paste"};
resource rMenuItem (EDIT_CLEAR) {
EDIT_CLEAR,
@@ -121,7 +130,7 @@ resource rMenuItem (EDIT_CLEAR) {
refIsResource * itemTitleRefShift,
EDIT_CLEAR
};
-
+resource rPString (EDIT_CLEAR, noCrossBank) {"Clear"};
resource rMenuItem (FILE_NEW) {
FILE_NEW,
@@ -130,7 +139,7 @@ resource rMenuItem (FILE_NEW) {
refIsResource * itemTitleRefShift,
FILE_NEW
};
-
+resource rPString (FILE_NEW, noCrossBank) {"New"};
resource rMenuItem (FILE_OPEN) {
FILE_OPEN,
@@ -140,7 +149,25 @@ resource rMenuItem (FILE_OPEN) {
+ fDivider,
FILE_OPEN
};
+resource rPString (FILE_OPEN, noCrossBank) {"Open"};
+resource rMenuItem (FILE_SAVE) {
+ FILE_SAVE,
+ "S", "s",
+ 0,
+ refIsResource * itemTitleRefShift,
+ FILE_SAVE
+};
+resource rPString (FILE_SAVE, noCrossBank) {"Save"};
+
+resource rMenuItem (FILE_SAVE_AS) {
+ FILE_SAVE_AS,
+ "", "",
+ 0,
+ refIsResource * itemTitleRefShift,
+ FILE_SAVE_AS
+};
+resource rPString (FILE_SAVE_AS, noCrossBank) {"Save As..."};
resource rMenuItem (FILE_CLOSE) {
FILE_CLOSE,
@@ -150,7 +177,26 @@ resource rMenuItem (FILE_CLOSE) {
+ fDivider,
FILE_CLOSE
};
+resource rPString (FILE_CLOSE, noCrossBank) {"Close"};
+resource rMenuItem (FILE_PAGE_SETUP) {
+ FILE_PAGE_SETUP,
+ "", "",
+ 0,
+ refIsResource * itemTitleRefShift,
+ FILE_PAGE_SETUP
+};
+resource rPString (FILE_PAGE_SETUP, noCrossBank) {"Page Setup..."};
+
+resource rMenuItem (FILE_PRINT) {
+ FILE_PRINT,
+ "P", "p",
+ 0,
+ refIsResource * itemTitleRefShift
+ + fDivider,
+ FILE_PRINT
+};
+resource rPString (FILE_PRINT, noCrossBank) {"Print..."};
resource rMenuItem (FILE_QUIT) {
FILE_QUIT,
@@ -159,7 +205,7 @@ resource rMenuItem (FILE_QUIT) {
refIsResource * itemTitleRefShift,
FILE_QUIT
};
-
+resource rPString (FILE_QUIT, noCrossBank) {"Quit"};
resource rMenuItem (APPLE_ABOUT) {
APPLE_ABOUT,
@@ -169,84 +215,153 @@ resource rMenuItem (APPLE_ABOUT) {
+ fDivider,
APPLE_ABOUT
};
-
-
-resource rPString (APPLE_MENU, noCrossBank) {"@"};
-resource rPString (FILE_MENU, noCrossBank) {" File "};
-resource rPString (EDIT_MENU, noCrossBank) {" Edit "};
-
-resource rPString (EDIT_UNDO, noCrossBank) {"Undo"};
-resource rPString (EDIT_CUT, noCrossBank) {"Cut"};
-resource rPString (EDIT_COPY, noCrossBank) {"Copy"};
-resource rPString (EDIT_PASTE, noCrossBank) {"Paste"};
-resource rPString (EDIT_CLEAR, noCrossBank) {"Clear"};
-
-resource rPString (FILE_NEW, noCrossBank) {"New"};
-resource rPString (FILE_OPEN, noCrossBank) {"Open"};
-resource rPString (FILE_CLOSE, noCrossBank) {"Close"};
-resource rPString (FILE_QUIT, noCrossBank) {"Quit"};
-
resource rPString (APPLE_ABOUT, noCrossBank) {"About ___PROJECTNAME___..."};
+/* Error strings */
+resource rCString (TOOL_ERROR_STRING) {"\n\nTool error code = $%04x"};
+resource rCString (NEW_WINDOW_ERROR_STRING) {"Error occurred when creating a new window"};
+resource rCString (MALLOC_ERROR_STRING) {"Out of memory"};
+resource rCString (OPEN_FILE_ERROR_STRING) {"Error opening file"};
+resource rCString (SAVE_FILE_ERROR_STRING) {"Error saving file"};
+resource rCString (PRINT_ERROR_STRING) {"Error printing document"};
+
+
+/* Other strings */
+resource rCString (UNTITLED_STRING) {" Untitled %d "};
+resource rPString (OPEN_FILE_STRING, noCrossBank) {"Choose a file to open..."};
+resource rPString (SAVE_FILE_STRING, noCrossBank) {"Save file as..."};
+resource rPString (HELLO_WORLD_STRING, noCrossBank) {"Hello, world!"};
+
+
+/* Alert strings */
resource rAlertString (ABOUT_ALERT_STRING) {
"0" /* Custom size */
+#if RES_MODE == 320
+ "\$38\$00" /* Upper Y coordinate at 56 */
+ "\$10\$00" /* Left X coordinate at 16 */
+ "\$90\$00" /* Lower Y coorinate at 144 */
+ "\$30\$01" /* Right X coordinate at 304 */
+#else
"\$38\$00" /* Upper Y coordinate at 56 */
"\$90\$00" /* Left X coordinate at 144 */
"\$90\$00" /* Lower Y coorinate at 144 */
"\$F0\$01" /* Right X coordinate at 496 */
+#endif
"3/"
"___PROJECTNAME___\n"
" by ___FULLUSERNAME___\n"
"\n"
- "Copyright \$A9 ___YEAR___ ___FULLUSERNAME___ Rand\n"
+ "Copyright \$A9 ___YEAR___ ___FULLUSERNAME___\n"
"\n"
"Contains libraries from ORCAC,\n"
"Copyright \$A9 1991, Byte Works Inc."
"/^#0\$00";
};
+resource rAlertString (ERROR_ALERT_STRING) {
+ "42/"
+ "*0\n"
+ "*1"
+ "/^#0\$00";
+};
+resource rAlertString (SAVE_BEFORE_CLOSING) {
+ "34/"
+ "Save changes to *0 before closing?"
+ "/^#2/#3/#1\$00";
+};
+
+
+/* Windows */
resource rWindParam1 (WINDOW_RESID) {
- $DDA5, /* wFrameBits */
+ /* wFrameBits */
+ fTitle + fClose + fZoom + fMove + fVis + fAllocated + fHilited,
nil, /* wTitle */
0, /* wRefCon */
{0, 0, 0, 0}, /* ZoomRect */
$07FF0001, /* wColor ID */
{0, 0}, /* Origin */
- {1, 1}, /* data size */
+ {0, 0}, /* data size */
{0, 0}, /* max height-width */
{8, 8}, /* scroll ver hors */
{0, 0}, /* page ver horiz */
0, /* winfoRefCon */
10, /* wInfoHeight */
+#if RES_MODE == 320
+ {30, 10, 183, 300}, /* wposition */
+#else
{30, 10, 183, 602}, /* wposition */
+#endif
infront, /* wPlane */
- nil, /* wStorage */
- $0800 /* wInVerb */
+ CONTROL_TEXT_EDIT, /* wStorage */
+ $0802 /* wInVerb */
};
-resource rToolStartup (TOOL_STARTUP) {
- mode640,
- {
- 3,$0100, /* Misc Tool */
- 4,$0100, /* Quickdraw */
- 5,$0100, /* Desk Manager */
- 6,$0100, /* Event Manager */
- 11,$0100, /* Int Math */
- 14,$0300, /* Window Manager */
- 15,$0300, /* Menu Manager */
- 16,$0300, /* Control Manager */
- 18,$0200, /* QD Aux */
- 19,$0100, /* Print Manager */
- 20,$0100, /* LineEdit Tool */
- 21,$0100, /* Dialog Manager */
- 22,$0100, /* Scrap Manager */
- 23,$0100, /* Standard File */
- 27,$0100, /* Font Manager */
- 28,$0100, /* List Manager */
- 30,$0100, /* Resource Manager */
- 34,$0100 /* TextEdit */
+/* Controls */
+resource rControlTemplate (CONTROL_TEXT_EDIT) {
+ CONTROL_TEXT_EDIT, /* Application defined ID */
+#if RES_MODE == 320
+ {0,0,165,300}, /* Bounding rectangle */
+#else
+ {0,0,165,620}, /* Bounding rectangle */
+#endif
+ editTextControl {
+ {
+ $0000, /* Flags */
+ /* More flags */
+ FctlCanBeTarget + FctlWantsEvents + FctlProcNotPtr + FctlTellAboutSize + FctlIsMultiPart,
+ 0, /* Refcon */
+ /* Text flags */
+ fSingleFormat + fSmartCutPaste + fGrowRuler + fDrawInactiveSelection,
+ {-1,-1,-1,-1}, /* Indent rectangle */
+ $FFFFFFFF, /* Vertical bar */
+ 0, /* Vertical amount */
+ nil, /* Horizontal bar */
+ 0, /* Horizontal amount */
+ nil, /* Style ref */
+ /* Text descriptor */
+ refIsResource * 8 + dataIsPString,
+ HELLO_WORLD_STRING, /* Text ref */
+ 0, /* Text length */
+ nil, /* Maximum chars */
+ nil, /* Maximum lines */
+ nil, /* Maximum chars per line */
+ nil, /* Max height */
+ nil, /* Color ref */
+ 4, /* Drawing mode */
+ nil, /* Filter procedure */
+ }
+ }
+};
+
+
+/* Tools */
+resource rToolStartup (TOOL_STARTUP) {
+#if RES_MODE == 320
+ mode320,
+#else
+ mode640,
+#endif
+ {
+ 3, $0100, /* Misc Tool */
+ 4, $0100, /* Quickdraw */
+ 5, $0100, /* Desk Manager */
+ 6, $0100, /* Event Manager */
+ 11, $0100, /* Int Math */
+ 14, $0300, /* Window Manager */
+ 15, $0300, /* Menu Manager */
+ 16, $0300, /* Control Manager */
+ 18, $0200, /* QD Aux */
+ 19, $0100, /* Print Manager */
+ 20, $0100, /* LineEdit Tool */
+ 21, $0100, /* Dialog Manager */
+ 22, $0100, /* Scrap Manager */
+ 23, $0100, /* Standard File */
+ 27, $0100, /* Font Manager */
+ 28, $0100, /* List Manager */
+ 30, $0100, /* Resource Manager */
+ 34, $0100 /* TextEdit */
}
};
diff --git a/pkg/Templates/Apple IIgs/ORCAM Desktop Application.xctemplate/TemplateInfo.plist b/pkg/Templates/Apple IIgs/ORCAM Desktop Application.xctemplate/TemplateInfo.plist
index 4aa7b7e..3211fc9 100644
--- a/pkg/Templates/Apple IIgs/ORCAM Desktop Application.xctemplate/TemplateInfo.plist
+++ b/pkg/Templates/Apple IIgs/ORCAM Desktop Application.xctemplate/TemplateInfo.plist
@@ -128,8 +128,26 @@
Description
This template creates an Apple IIgs ORCA/M code project to build desktop application. The project starts with a single assembly file which you can modify. You can also add more assembly or C files as you may like.
- Options
-
+ Options
+
+
+ Identifier
+ RESOLUTIONMODE
+ Name
+ Desktop Resolution
+ Description
+ Specify 640 or 320 pixel desktop enviroment.
+ Type
+ popup
+ Default
+ 640
+ Values
+
+ 640
+ 320
+
+
+
Targets
diff --git a/pkg/Templates/Apple IIgs/ORCAM Desktop Application.xctemplate/main.rez b/pkg/Templates/Apple IIgs/ORCAM Desktop Application.xctemplate/main.rez
index f107723..4303d39 100644
--- a/pkg/Templates/Apple IIgs/ORCAM Desktop Application.xctemplate/main.rez
+++ b/pkg/Templates/Apple IIgs/ORCAM Desktop Application.xctemplate/main.rez
@@ -35,6 +35,10 @@
#define toolStartup 1
+/* By default, thie template builds for 640x200 mode. To build for
+ * 320x200 change the following value to 320 */
+#define RES_MODE ___VARIABLE_RESOLUTIONMODE___
+
resource rVersion (1) {
{
@@ -216,15 +220,22 @@ resource rPString (appleAbout, noCrossBank) {"About ___PROJECTNAME___..."};
resource rAlertString (aboutAlertString) {
"0" /* Custom size */
+#if RES_MODE == 320
+ "\$38\$00" /* Upper Y coordinate at 56 */
+ "\$10\$00" /* Left X coordinate at 16 */
+ "\$90\$00" /* Lower Y coorinate at 144 */
+ "\$30\$01" /* Right X coordinate at 304 */
+#else
"\$38\$00" /* Upper Y coordinate at 56 */
"\$90\$00" /* Left X coordinate at 144 */
"\$90\$00" /* Lower Y coorinate at 144 */
"\$F0\$01" /* Right X coordinate at 496 */
+#endif
"3/"
"___PROJECTNAME___\n"
" by ___FULLUSERNAME___\n"
"\n"
- "Copyright \$A9 ___YEAR___ ___FULLUSERNAME___ Rand\n"
+ "Copyright \$A9 ___YEAR___ ___FULLUSERNAME___\n"
"\n"
"Contains libraries from ORCAC,\n"
"Copyright \$A9 1991, Byte Works Inc."
@@ -245,7 +256,11 @@ resource rWindParam1 (windowRes) {
{0, 0}, /* page ver horiz */
0, /* winfoRefCon */
10, /* wInfoHeight */
+#if RES_MODE == 320
+ {30, 10, 183, 300}, /* wposition */
+#else
{30, 10, 183, 602}, /* wposition */
+#endif
infront, /* wPlane */
nil, /* wStorage */
$0800 /* wInVerb */
@@ -253,7 +268,11 @@ resource rWindParam1 (windowRes) {
resource rToolStartup (toolStartup) {
+#if RES_MODE == 320
+ mode320,
+#else
mode640,
+#endif
{
3,$0100, /* Misc Tool */
4,$0100, /* Quickdraw */