kdmoen@watcgl.UUCP (Doug Moen) (03/23/85)
: This is a shar archive. Extract with sh, not csh. : The rest of this file will extract: : main.c events.c menus.c windows.c edit.c file.c info.c documents.c docWindows.c makeDoc.c getDoc.c putDoc.c pGetItem.s echo Extracting main.c sed 's/^X//' > main.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * main.c X * Initialize the world, then operate the main loop. X * X * You may want to add calls to initialize X * application-dependent data structures. X */ X X#define INIT X#include "defs.h" X Xmain() X{ X struct QDVar QDVar; X X /* Set up memory layout */ X SetupRam(); X X /* Initialize the toolbox */ X QD = &QDVar; X InitGraf(&thePort); X InitFonts(); X InitWindows(); X InitMenus(); X TEInit(); X InitDialogs((ProcPtr)NIL); X FlushEvents(everyEvent, 0); X X /* X * Initialize the system event mask, in case the previous program X * left it in a bad state X */ X SetEventMask(everyEvent - keyUpMask); X X /* Application dependent setups */ X SetupUtil(); X SetupMenus(); X X /* X * Finally, we change the cursor from a watch to an arrow X * to let the user know that the program is ready to go. X */ X InitCursor(); X X /* X * Now sit in a loop, waiting for and processing events. X */ X for (;;) X DoEvent(); X} e-o-f echo Extracting events.c sed 's/^X//' > events.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * events.c: X * Process an incoming event from the Event Manager. X * X * You probably won't have to change anything here. X */ X X#include "defs.h" X XDoEvent() X{ X EventRecord myEvent; X WindowPtr whichWindow; X X SystemTask(); X CursorAdjust(); X VOID GetNextEvent(everyEvent, &myEvent); X switch (myEvent.what) { X case mouseDown: X switch (FindWindow(&myEvent.where, &whichWindow)) { X case inDesk: X break; X case inMenuBar: X SetCursor(&QD->arrow); X DoCommand(MenuSelect(&myEvent.where), TRUE); X break; X case inSysWindow: X SystemClick(&myEvent, whichWindow); X break; X case inContent: X DoContent(whichWindow, &myEvent); X break; X case inDrag: X DoDrag(whichWindow, &myEvent.where); X break; X case inGrow: X DoGrow(whichWindow, &myEvent); X break; X case inGoAway: X DoGoAway(whichWindow, &myEvent.where); X break; X } X break; X case keyDown: X case autoKey: X { X Int32 cmd; X X if (myEvent.modifiers & cmdKey && X myEvent.what != autoKey && X (cmd = MenuKey((char)myEvent.message)) != 0) X { X DoCommand(cmd, FALSE); X } else { X DoKey(&myEvent); X } X } X break; X case activateEvt: X break; X case updateEvt: X DoUpdate((WindowPtr)myEvent.message); X break; X } X} e-o-f echo Extracting menus.c sed 's/^X//' > menus.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * menus.c X * Code for handling the menu bar X * X * You only need to change this file if you are adding X * or deleting menus or menu items. X */ X X#include "defs.h" X X/* Menus */ X#define firstMenu 1 X#define appleMenu 1 X#define fileMenu 2 X#define editMenu 3 X#define lastMenu 3 X X/* Apple menu */ X#define C_AboutProgram 1 X X/* File menu */ X#define C_New 1 X#define C_Open 2 X#define C_Close 4 X#define C_Save 5 X#define C_SaveAs 6 X#define C_Revert 7 X#define C_PageSetup 9 X#define C_Print 10 X#define C_Quit 12 X X/* Edit menu */ X#define C_Undo 1 X#define C_Cut 3 X#define C_Copy 4 X#define C_Paste 5 X#define C_Clear 6 X#define C_ShowClipboard 8 X#define C_SelectAll 9 X Xstatic MenuHandle menus[firstMenu + lastMenu]; X XSetupMenus() X{ X int i; X X for (i = firstMenu; i <= lastMenu; ++i) X menus[i] = GetMenu(i); X (**menus[appleMenu]).menuData.s[1] = (char)appleMark; /* kludge */ X AddResMenu(menus[appleMenu], "DRVR"); /* add desk accessories */ X for (i = firstMenu; i <= lastMenu; ++i) X InsertMenu(menus[i], 0); X DrawMenuBar(); X} X XDoCommand(cmd, fromMenuBar) XInt32 cmd; XBoolean fromMenuBar; X{ X int theMenu, theItem; X X theMenu = HiWord(cmd); X theItem = LoWord(cmd); X /* X * If theMenu == 0, then do nothing X */ X switch (theMenu) { X case appleMenu: X AppleMenu(theItem); X break; X case fileMenu: X FileMenu(theItem); X break; X case editMenu: X EditMenu(theItem, fromMenuBar); X break; X } X HiliteMenu(0); X} X XAppleMenu(item) Xint item; X{ X char name[256]; X X if (item == C_AboutProgram) { X ShowInfo(); X } else { X PGetItem(menus[appleMenu], item, name); X VOID OpenDeskAcc(isapstr(name)); X } X} X XFileMenu(item) Xint item; X{ X switch (item) { X case C_New: X New(); X break; X case C_Open: X Open(); X break; X case C_Close: X Close(); X break; X case C_Save: X Save(); X break; X case C_SaveAs: X SaveAs(); X break; X case C_Revert: X Revert(); X break; X case C_PageSetup: X PageSetup(); X break; X case C_Print: X Print(); X break; X case C_Quit: X Quit(); X break; X#ifdef DEBUG X default: X MessageF("Can't find command %d in File menu", item); X#endif X } X} X XEditMenu(item, fromMenuBar) Xint item; XBoolean fromMenuBar; X{ X Boolean sysCmd; X X if (!fromMenuBar) { X sysCmd = FALSE; X } else { X switch (item) { X case C_Undo: X sysCmd = SystemEdit(undoCmd); X break; X case C_Cut: X sysCmd = SystemEdit(cutCmd); X break; X case C_Copy: X sysCmd = SystemEdit(copyCmd); X break; X case C_Paste: X sysCmd = SystemEdit(pasteCmd); X break; X case C_Clear: X sysCmd = SystemEdit(clearCmd); X break; X default: X sysCmd = FALSE; X break; X } X } X if (!sysCmd) { X switch (item) { X case C_Undo: X UndoCmd(); X break; X case C_Cut: X CutCmd(); X break; X case C_Copy: X CopyCmd(); X break; X case C_Paste: X PasteCmd(); X break; X case C_Clear: X ClearCmd(); X break; X case C_ShowClipboard: X ShowClipboard(); X break; X case C_SelectAll: X SelectAllCmd(); X break; X#ifdef DEBUG X default: X MessageF("Can't find command %d in Edit menu", item); X#endif X } X } X} e-o-f echo Extracting windows.c sed 's/^X//' > windows.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * windows.c: X * Top level code for dealing with window events. X * X * You need to modify this file if you add any more window types. X * Currently, there are 3 window types: X * - Desk Accessory windows (these are handled in events.c and menus.c) X * - The 'info' window (displayed by the 'About Example' command) X * - Document windows. X */ X X#include "defs.h" X XCursorAdjust() X{ X register WindowPtr w = FrontWindow(); X switch (WindowKind(w)) { X case documentKind: X DocumentCursor(w); X break; X } X} X X/* X * The mouse was clicked in the content region of window X */ XDoContent(window, event) XWindowPtr window; XEventRecord *event; X{ X if (window != FrontWindow()) X SelectWindow(window); X else X switch (WindowKind(window)) { X case documentKind: X DocumentClick(window, event); X break; X } X} X X/* X * A key was typed on the keyboard. X */ XDoKey(event) XEventRecord *event; X{ X register WindowPtr w = FrontWindow(); X X if (w != NIL) { X switch (WindowKind(w)) { X case documentKind: X DocumentKey(w, event); X break; X } X } X} X X/* X * The mouse was clicked in the drag region of window X */ XDoDrag(window, point) XWindowPtr window; XPoint *point; X{ X DragWindow(window, point, &deskBounds); X} X X/* X * The mouse was clicked in the grow region of the active window X */ XDoGrow(window, event) XWindowPtr window; XEventRecord *event; X{ X switch (WindowKind(window)) { X case documentKind: X /* X * If you don't want to support a grow box, X * then replace this with a call to DocumentClick() X */ X GrowDocument(window, &event->where); X break; X } X} X X/* X * The mouse was clicked in the go-away region of the active window X */ XDoGoAway(window, point) XWindowPtr window; XPoint *point; X{ X if (TrackGoAway(window, point)) { X switch (WindowKind(window)) { X case infoKind: X CloseInfo(); X break; X case documentKind: X CloseDocument(window); X break; X } X } X} X X/* X * An update event occurred for the window. Redraw its content region. X */ XDoUpdate(window) XWindowPtr window; X{ X BeginUpdate(window); X switch (WindowKind(window)) { X case infoKind: X UpdateInfo(); X break; X case documentKind: X UpdateDocument(window); X break; X } X EndUpdate(window); X} e-o-f echo Extracting edit.c sed 's/^X//' > edit.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * edit.c X * Top level routines for implementing the commands in the Edit menu. X * X * Code for handling cut, paste, etc in desk accessories is already X * in menus.c. These routines operate on application defined windows. X */ X X#include "defs.h" X XUndoCmd() {} X XCutCmd() {} X XCopyCmd() {} X XPasteCmd() {} X XClearCmd() {} X XShowClipboard() {} X XSelectAllCmd() {} e-o-f echo Extracting file.c sed 's/^X//' > file.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * file.c X * Top level routines for handling commands from the File menu. X */ X X#include "defs.h" X XClose() {} X XSave() X{ X register WindowPtr w; X X w = FrontWindow(); X if (WindowKind(w) == documentKind) { X SaveDocument((Document **) GetWRefCon(w)); X } X} X XSaveAs() X{ X register WindowPtr w; X X w = FrontWindow(); X if (WindowKind(w) == documentKind) { X SaveDocumentAs((Document **) GetWRefCon(w)); X } X} X XRevert() {} XPageSetup() {} XPrint() {} X XQuit() X{ X SetCursor(*WatchCursor); X /* X * Reset the event mask back to normal, in case we changed it. X * The Finder (1.1g) does NOT set it. X */ X SetEventMask(everyEvent - keyUpMask); X ExitToShell(); X} e-o-f echo Extracting info.c sed 's/^X//' > info.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * info.c X * The 'About Example' information window. X * X * The window size, location, and contents are defined as X * a DLOG resource in example.rc. X */ X X#include "defs.h" X Xstatic DialogPtr infoWindow = NIL; X XShowInfo() X{ X if (infoWindow == NIL) { X infoWindow = GetNewDialog(W_Info, (Ptr)NIL, (WindowPtr)-1); X SetWindowKind(infoWindow, infoKind); X } else { X SelectWindow(infoWindow); X } X} X XCloseInfo() X{ X DisposDialog(infoWindow); X infoWindow = NIL; X} X XUpdateInfo() X{ X DrawDialog(infoWindow); X} e-o-f echo Extracting documents.c sed 's/^X//' > documents.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * documents.c X * Operations on document records. X * X * You will want to add code to NewDocument and FreeDocument X * to initialize and dispose of application dependent data structures X * associated with each document window. X */ X X#include "defs.h" X X/* allocate a new document record */ XDocument **NewDocument(window) XWindowPtr window; X{ X Document **document, *d; X X document = (Document **) NewHandle(sizeof (struct Document)); X X d = *document; X d->next = NIL; X d->window = window; X d->dirty = FALSE; X d->untitled = TRUE; X X return document; X} X X/* Deallocate a document record. */ XFreeDocument(document) XDocument **document; X{ X DisposeWindow((**document).window); X DisposHandle((Handle) document); X} e-o-f echo Extracting docWindows.c sed 's/^X//' > docWindows.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * docWindows.c X * Top level operations on document windows. X * X * You need to add code to the following routines: X * UpdateDocument() - redraw a document window X * DocumentClick() - process a mouse click X * DocumentKey() - process a keystroke X * DocumentCursor() - change the cursor shape X */ X X#include "defs.h" X X/* numeric suffix for the titles of new documents, as in Untitled-1, ... */ Xstatic int nextNewDoc = 1; X X/* X * New command from File menu. X * Create a new, untitled document. X */ XNew() X{ X char sNum[256], title[256]; X Document **document; X X NumToString(nextNewDoc, sNum); X ++nextNewDoc; X CPstrcpy(title, *GetString(S_Untitled)); X VOID strcat(title, sNum); X document = MakeDocument(title); X ShowWindow((**document).window); X} X X/* X * Redraw part of a document window. X */ XUpdateDocument(window) XWindowPtr window; X{ X Document **document; X Rect growBoxRect; X X SetPort(window); X document = (Document **) GetWRefCon(window); X X /* X * Erase the update region before drawing into it, X * since it won't be blank after growing a window. X * (this may not be necessary for your application) X */ X EraseRect(&window->portRect); X X /* X * Redraw the grow box. X * It is necessary to put a clipping rectangle around the grow X * box region before calling DrawGrowIcon(), because that routine X * draws some extra lines that you frequently don't want. X */ X growBoxRect.botRight = window->portRect.botRight; X growBoxRect.top = growBoxRect.bottom - growBoxHeight; X growBoxRect.left = growBoxRect.right - growBoxWidth; X ClipRect(&growBoxRect); X DrawGrowIcon(window); X ClipRect(&window->portRect); X X /* X * Redraw the controls X * (there are none here to redraw, but you might add scroll bars) X */ X DrawControls(window); X X /* X * Redraw the contents of the window here. X */ X} X X/* X * Allow the user to change the size of a document window. X */ XGrowDocument(window, point) XWindowPtr window; XPoint *point; X{ X Document **document; X Rect growRect; X Int32 newSize; X int height, width; X X document = (Document **) GetWRefCon(window); X SetPort(window); X X growRect.top = growBoxHeight - 1; X growRect.left = growBoxWidth - 1; X growRect.botRight = QD->screenBits.bounds.botRight; X newSize = GrowWindow(window, point, &growRect); X X if (newSize != 0) { X height = HiWord(newSize); X width = LoWord(newSize); X SizeWindow(window, width, height, TRUE); X InvalRect(&window->portRect); /* redraw entire window */ X } X} X X/* X * What to do if she clicks in a document window. X */ XDocumentClick(window, event) XWindowPtr window; XEventRecord *event; X{ X Document **document; X Point point; X X SetPort(window); X document = (Document **) GetWRefCon(window); X point = event->where; X GlobalToLocal(&point); X X /* X * Okay, now do something to handle the mouse click X */ X} X X/* X * Process a keystroke typed into a document window X */ XDocumentKey(window, event) XWindowPtr window; XEventRecord *event; X{ X Document **document; X char c; X X SetPort(window); X document = (Document **) GetWRefCon(window); X c = (char)event->message; X X /* X * Okay, now process the keystroke. X */ X} X X/* X * Change the cursor shape to something appropriate X * when it passes over a document window X */ XDocumentCursor(window) XWindowPtr window; X{ X Document **document; X Point pt; X X SetPort(window); X document = (Document **)GetWRefCon(window); X GetMouse(&pt); X X /* X * You will probably either want the cursor to change X * shape depending on what object it is over within X * the document window, or delete this subroutine entirely. X */ X if (PtInRect(&pt, &window->portRect)) { X SetCursor(*CrossCursor); X } else { X SetCursor(&QD->arrow); X } X} X X/* X * Close a document window. X */ XCloseDocument(window) XWindowPtr window; X{ X Document **document, **s; X X document = (Document **) GetWRefCon(window); X X /* Remove document from document list. */ X if (document == docList) X docList = (**document).next; X else { X s = docList; X while ((**s).next != document) X s = (**s).next; X (**s).next = (**document).next; X } X X FreeDocument(document); X} e-o-f echo Extracting makeDoc.c sed 's/^X//' > makeDoc.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * makeDoc.c X * Contains MakeDocument() X * X * MakeDocument creates a new document window, using a somewhat X * involved algorithm for computing its screen location. X * It then creates the documents contents using NewDocument(), X * and adds it to the list of all documents (docList). X * X * You may want to change newDocHeight and newDocWidth. X */ X X#include "defs.h" X X/* X * height and width of a new document window X */ X#define newDocHeight 200 X#define newDocWidth 300 X X/* X * The top left corners of new document windows lie within the rectangle X * whose top left corner is (docVOrigin, docHOrigin) X * and whose height and width are (docVRange, docHRange) X */ X#define docVOrigin (menuBarHeight + thinMargin + wFrameTop) X#define docHOrigin (thinMargin + wFrameLeft) X#define docVRange (QD->screenBits.bounds.bottom \ X - docVOrigin \ X - (thinMargin + wFrameBottom) \ X - newDocHeight) X#define docHRange (QD->screenBits.bounds.right \ X - docHOrigin \ X - (thinMargin + wFrameRight) \ X - newDocWidth) X X/* X * screen offset between successively created document windows X */ X#define docVOffset (wFrameTop - 1) X#define docHOffset docVOffset X X/* X * (nextVPosition, nextHPosition) is the upper left corner of the X * next document window created, relative to (docVOrigin, docHOrigin) X */ Xint nextVPosition = 0, nextHPosition = 0; X X X/* X * create a new document + document window X */ XDocument **MakeDocument(title) Xchar *title; X{ X Rect bounds; X WindowPtr window; X Document **document; X X /* calculate the bounding rectangle for the new window */ X bounds.top = nextVPosition + docVOrigin; X bounds.left = nextHPosition + docHOrigin; X bounds.bottom = bounds.top + newDocHeight; X bounds.right = bounds.left + newDocWidth; X X /* calculate location of next document window */ X nextVPosition = (nextVPosition + docVOffset) % docVRange; X nextHPosition = (nextHPosition + docHOffset) % docHRange; X X window = NewWindow((WindowRecord *)NIL, &bounds, title, FALSE, X documentProc, (WindowPtr)-1, TRUE, 0); X SetWindowKind(window, documentKind); X X document = NewDocument(window); X X (**document).next = docList; X docList = document; X X SetWRefCon(window, (Int32)document); X X return document; X} e-o-f echo Extracting getDoc.c sed 's/^X//' > getDoc.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * getDoc.c X * Read a document from disk. X * X * You will want to supply code for ReadDocument(). X */ X X#include "defs.h" X X/* X * Open a new document from disk. X */ XOpen() X{ X SFReply reply; X X GetFile(&documentID, &reply); X if (reply.good) { X HandleFileError(GetDocument(reply.vRefNum, isapstr(reply.fName))); X } X} X X/* X * Get a document from disk and put it in a window X */ Xint GetDocument(vRefNum, fName) Xint vRefNum; Xchar *fName; X{ X int refNum; X Document **document; X X SetCursor(*WatchCursor); X X DCheck(FSOpen(fName, vRefNum, &refNum), "GetDocument: FSOpen"); X document = MakeDocument(fName); X Check(ReadDocument(document, refNum)); X DCheck(FSClose(refNum), "GetDocument: FSClose"); X X (**document).untitled = FALSE; X (**document).vRefNum = vRefNum; X (**document).dirty = FALSE; X ShowWindow((**document).window); X X SetCursor(&QD->arrow); X return noErr; X} X Xint ReadDocument(document, file) XDocument **document; Xint file; X{ X /* X * Read in a document from file descriptor 'file' X * into the document description record 'document'. X * If an i/o error occurs, return an error code, X * else return noErr. X */ X return noErr; X} e-o-f echo Extracting putDoc.c sed 's/^X//' > putDoc.c << 'e-o-f' X/* X * Example: a skeleton Macintosh program for new users of Sumacc X * Doug Moen, watcgl!kdmoen, 1985 X * X * putDocument.c X * Write a document to disk. X * X * You will want to supply code for WriteDocument(), X * which writes a document to disk. X */ X X#include "defs.h" X XSaveDocument(document) XDocument **document; X{ X char fName[65]; X X if ((**document).untitled) { X SaveDocumentAs(document); X } else { X GetWTitle((**document).window, fName); X HandleFileError(PutDocument(document, (**document).vRefNum, fName)); X } X} X XSaveDocumentAs(document) XDocument **document; X{ X char origName[65]; X SFReply reply; X X if ((**document).untitled) { X origName[0] = '\0'; X } else { X GetWTitle((**document).window, origName); X } X PutFile(isapstr(*GetString(S_SaveAs)), origName, &reply); X if (reply.good) { X HandleFileError(PutDocument(document, reply.vRefNum, isapstr(reply.fName))); X } X} X Xint PutDocument(document, vRefNum, fName) XDocument **document; Xint vRefNum; Xchar *fName; X{ X int refNum; X X SetCursor(*WatchCursor); X X Check(CreateAndOpen(fName, vRefNum, &programID, &documentID, &refNum)); X Check(WriteDocument(document, refNum)); X DCheck(FSClose(refNum), "PutDocument: FSClose"); X DCheck(FlushVol((char *)NIL, vRefNum), "PutDocument: FlushVol"); X X if ((**document).untitled) { X SetWTitle((**document).window, fName); X (**document).vRefNum = vRefNum; X (**document).untitled = FALSE; X } X (**document).dirty = FALSE; X X SetCursor(&QD->arrow); X return noErr; X} X Xint WriteDocument(document, file) XDocument **document; Xint file; X{ X /* X * Write the document described by 'document' X * onto the file descriptor 'file'. X * Return an error code if an i/o error occurs, otherwise 'noErr'. X */ X return noErr; X} e-o-f echo Extracting pGetItem.s sed 's/^X//' > pGetItem.s << 'e-o-f' X| This is an interface to the GetItem toolbox routine in ROM. X| PGetItem() is the same as GetItem(), except that the string X| returned is in Pascal format, not C format. X| X| PGetItem() is used by AppleMenu() in menus.c to fetch the X| name of desk accessories. GetItem() can't be used for this X| purpose, since most (but not all!) desk accessory names begin X| with '\0', which can't be stored in a C-style string. X X.globl PGetItem,_mactrap XPGetItem: X jbsr _mactrap X .long 1104 | the arg flags X .long -1455010191 | the trap address e-o-f exit 0