home *** CD-ROM | disk | FTP | other *** search
- /* file CSApp.c Copyright (C) 1996,1997 by John R. Montbriand. All Rights Reserved.
- callback skeleton application, implementation.
- Copyright (c) 1996, 1997 by John Montbriand. All Rights Reserved.
- Permission hereby granted for public use.
- Distribute freely in areas where the laws of copyright apply.
- USE AT YOUR OWN RISK.
- DO NOT DISTRIBUTE MODIFIED COPIES.
- Comments/questions/postcards* to the author at the address:
- John Montbriand
- P.O. Box. 1133
- Saskatoon Saskatchewan Canada
- S7K 3N2
- or by email at:
- tinyjohn@sk.sympatico.ca
- *if you mail a postcard, then I will provide you with technical support
- regarding questions you may have about this file.
- */
-
- #include "CSApp.h"
- #include <Traps.h>
- #include <OSUtils.h>
- #include <ToolUtils.h>
- #include <Events.h>
- #include <Fonts.h>
- #include <Gestalt.h>
- #include <SegLoad.h>
- #include <Resources.h>
-
- QDGlobals qd;
- static Boolean gWNE = false;
- static Boolean gAPPLEVENTS = false;
-
- OSErr GotReqParam(const AppleEvent *apple_event) {
- DescType retType;
- Size actSize;
- OSErr err;
- err = AEGetAttributePtr(apple_event, keyMissedKeywordAttr, typeWildCard, &retType, NULL, 0, &actSize);
- if (err == errAEDescNotFound)
- return noErr;
- else if (err == noErr)
- return errAEEventNotHandled;
- else return err;
- }
-
- static unsigned short NumToolboxTraps(void) {
- if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
- return 0x0200;
- else return 0x0400;
- }
-
- static TrapType FindTrapType(unsigned short theTrap) {
- if (theTrap & 0x0800)
- return ToolTrap;
- else return OSTrap;
- }
-
- Boolean TrapAvail(unsigned short theTrap) {
- unsigned short localTrap = theTrap;
- TrapType tType = FindTrapType(localTrap);
- if ( tType == ToolTrap ) {
- localTrap &= 0x07FF;
- if ( localTrap >= NumToolboxTraps() )
- localTrap = _Unimplemented;
- }
- return NGetTrapAddress(localTrap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap);
- }
-
-
-
- /* MENU ROUTINES */
- static MenuResetFunc gMenuReset = NULL;
- static MenuHandlerFunc gMenuHandler = NULL;
-
- OSErr SetMenuFunctions(short menubarID, MenuResetFunc reset, MenuHandlerFunc handler) {
- Handle menu_bar;
- gMenuReset = reset;
- gMenuHandler = handler;
- if (menubarID == 0) return noErr;
- if ((menu_bar = GetNewMBar(menubarID)) == NULL) return resNotFound;
- ClearMenuBar();
- SetMenuBar(menu_bar);
- DrawMenuBar();
- return noErr;
- }
-
-
-
- /* DIALOG ROUTINES */
- static DialogEventFunc gDialogEvent = NULL;
- static DialogHitFunc gDialogHit = NULL;
- static EditDialogFunc gEditDialog = NULL;
-
- void SetDialogFunctions(DialogEventFunc evtproc, DialogHitFunc hitproc, EditDialogFunc edit) {
- gDialogEvent = evtproc;
- gDialogHit = hitproc;
- gEditDialog = edit;
- }
-
- void DialogEdit(short itemno) {
- WindowPtr target;
- if ((target = FrontWindow()) == NULL) return;
- if (GetWindowKind(target) != dialogKind) return;
- switch (itemno) {
- case iCut: DialogCut(target); break;
- case iCopy: DialogCopy(target); break;
- case iPaste: DialogPaste(target); break;
- case iClear: DialogDelete(target); break;
- }
- }
-
-
-
- #pragma options align=mac68k
-
- typedef struct {
- Handle handle; /* handle or procedure pointer for this item */
- Rect bounds; /* display rectangle for this item */
- unsigned char type; /* item type - 1 */
- unsigned char data[1]; /* length byte of data */
- } DialogItem, *DialogItemPtr, **DialogItemHandle;
-
- typedef struct {
- short max_index; /* number of items - 1 */
- DialogItem items[1]; /* first item in the array */
- } ItemList, *ItemListPtr, **ItemListHandle;
-
- #pragma options align=reset
-
- /* DialogAppendItems appends the DITL with the given id to the end of
- the items in dialog resizing the window as necessary to accomodate
- the new items. if first_item != NULL, it is set to the index
- of the first appended item. */
- OSErr DialogAppendItems(DialogPtr dialog, short id, short *first_item) {
- long response;
-
- /* parameter checking */
- if (dialog == NULL) return paramErr;
-
- /* use new calls, if they're in place */
- if (Gestalt(gestaltDITLExtAttr, &response) != noErr) response = 0;
- if ((response & (1<<gestaltDITLExtPresent)) != 0) {
- Handle the_ditl;
- if ((the_ditl = GetResource('DITL', id)) == NULL) return resNotFound;
- if (first_item != NULL) *first_item = CountDITL(dialog) + 1;
- AppendDITL(dialog, the_ditl, appendDITLBottom);
- ReleaseResource(the_ditl);
- return noErr;
- } else {
- Point offset;
- Rect max_rect;
- ItemListHandle itms, actitms; /* handle to DITL being appended */
- DialogItemPtr item; /* pointer to item being appended */
- short new_items, data_size, i;
- OSErr err;
- itms = (ItemListHandle) GetResource('DITL', id);
- if (itms == NULL) { err = resNotFound; goto bail; }
- /* collect the information we'll be using */
- max_rect = dialog->portRect;
- SetPt(&offset, 0, max_rect.bottom);
- max_rect.bottom -= 5; max_rect.right -= 5;
- actitms = (ItemListHandle) ((DialogPeek)dialog)->items;
- if (first_item != NULL) *first_item = (*actitms)->max_index + 2;
- HLock((Handle)itms);
- new_items = (*itms)->max_index + 1;
- /* build the new items */
- for (item = (*itms)->items, i = 0; i < new_items; i++ ) {
- OffsetRect(&item->bounds, offset.h, offset.v);
- UnionRect(&item->bounds, &max_rect, &max_rect);
- switch ( item->type & 0x7F ) {
- case ctrlItem + btnCtrl: case ctrlItem + chkCtrl: case ctrlItem + radCtrl:
- item->handle = (Handle) NewControl((DialogPtr) dialog, &item->bounds,
- (StringPtr)item->data, true, 0, 0, 1, item->type & 0x03, 0);
- break;
- case ctrlItem + resCtrl:
- item->handle = (Handle) GetNewControl(*(short*)(item->data + 1), (DialogPtr) dialog);
- (*(ControlHandle)item->handle)->contrlRect = item->bounds;
- break;
- case statText: case editText:
- if ((err = PtrToHand(item->data + 1, &item->handle, item->data[0])) != noErr) goto bail;
- break;
- case iconItem:
- item->handle = GetIcon(*(short*)(item->data + 1));
- break;
- case picItem:
- item->handle = (Handle) GetPicture(*(short*)(item->data + 1));
- break;
- default: item->handle = NULL; break;
- }
- data_size = (item->data[0] + 1) & 0xFFFE;
- item = (DialogItemPtr)((char*)item + data_size + sizeof(DialogItem));
- }
- if ((err = PtrAndHand((*itms)->items, (Handle)actitms, GetHandleSize((Handle) itms) - 2)) != noErr) goto bail;
- (*actitms)->max_index += new_items;
- HUnlock((Handle) itms);
- ReleaseResource((Handle) itms);
- max_rect.bottom += 5; max_rect.right += 5;
- SizeWindow((WindowPtr) dialog, max_rect.right, max_rect.bottom, true);
- return noErr;
- bail:
- if (itms != NULL) {
- HUnlock((Handle) itms);
- ReleaseResource((Handle) itms);
- }
- return err;
- }
- }
-
-
-
-
-
-
-
- /* WINDOW ROUTINES */
- static CloseWindowFunc gCloseWindow = NULL;
- static GrowWindowFunc gGrowWindow = NULL;
- static ZoomWindowFunc gZoomWindow = NULL;
- static ClickWindowFunc gClickWindow = NULL;
- static unsigned long gLastClickTime = 0;
- static short gClickCounter = 0;
- static ActivateWindowFunc gActivateWindow = NULL;
- static UpdateWindowFunc gUpdateWindow = NULL;
- static EditWindowFunc gEditWindow = NULL;
- static WindowPtr gTheActiveWindow = NULL;
-
- void SafeCloseWindow(WindowPtr window) {
- if (window == gTheActiveWindow && gActivateWindow) {
- gActivateWindow(window, false);
- gTheActiveWindow = NULL;
- }
- CloseWindow(window);
- }
-
- void SafeDisposeWindow(WindowPtr window) {
- if (window == gTheActiveWindow && gActivateWindow) {
- gActivateWindow(window, false);
- gTheActiveWindow = NULL;
- }
- DisposeWindow(window);
- }
-
- void SetWindowManipulators(CloseWindowFunc close, GrowWindowFunc grow, ZoomWindowFunc zoom) {
- gCloseWindow = close;
- gGrowWindow = grow;
- gZoomWindow = zoom;
- }
-
- void SetWindowInteraction(ClickWindowFunc click, EditWindowFunc edit) {
- gClickWindow = click;
- gEditWindow = edit;
- }
-
- void SetWindowRedraw(ActivateWindowFunc activate, UpdateWindowFunc update) {
- gActivateWindow = activate;
- gUpdateWindow = update;
- }
-
-
- static Rect* GetMaxDeviceRect(Rect *globalRect, Rect* maxDevRect) {
- GrafPtr mainPort;
- long response, maxArea, area;
- GDHandle device, mainDevice;
- Rect sect;
- if (Gestalt(gestaltQuickdrawVersion, &response) != noErr) response = 0;
- if (response >= gestalt8BitQD) {
- mainDevice = GetMainDevice();
- maxArea = 0;
- for (device = GetDeviceList(); device != NULL; device = GetNextDevice(device)) {
- if (TestDeviceAttribute(device, screenDevice)
- && TestDeviceAttribute(device, screenActive)
- && SectRect(globalRect, &((*device)->gdRect), §)) {
- area = ((long) (sect.right - sect.left)) * ((long) (sect.bottom - sect.top));
- if (area > maxArea) {
- *maxDevRect = (*device)->gdRect;
- if (device == mainDevice)
- maxDevRect->top += GetMBarHeight();
- maxArea = area;
- }
- }
- }
- } else {
- GetWMgrPort(&mainPort);
- *maxDevRect = mainPort->portRect;
- maxDevRect->top += GetMBarHeight();
- }
- return maxDevRect;
- }
-
-
- void ZoomWindowToSize(WindowPtr window, short width, short height, short zoomDir) {
- Rect standard, global, device;
- /* erase the window */
- SetPort(window);
- EraseRect(&window->portRect);
- /* find the window's monitor coordinates */
- global = window->portRect;
- LocalToGlobal((Point*) &global.top);
- LocalToGlobal((Point*) &global.bottom);
- GetMaxDeviceRect(&global, &device);
-
- /* calculate the new coordinates */
- standard.top = device.top + 30;
- standard.left = device.left + 20;
- if ((standard.bottom = device.top + 30 + height) > device.bottom - 10) standard.bottom = device.bottom - 10;
- if ((standard.right = device.left + 20 + width) > device.right - 10) standard.right = device.right - 10;
-
- /* install the new coordinates */
- if (zoomDir == inZoomOut)
- SetWindowStandardState(window, &standard);
- else SetWindowUserState(window, &standard);
- ZoomWindow(window, zoomDir, true);
- }
-
-
- void CallEditCommand(short editcmd) {
- if (!SystemEdit(editcmd-1)) {
- WindowPtr target;
- if ((target = FrontWindow()) != NULL) {
- if (GetWindowKind(target) == dialogKind) {
- if (gEditDialog)
- gEditDialog(target, editcmd);
- else DialogEdit(editcmd);
- } else if (gEditWindow)
- gEditWindow(target, editcmd);
- }
- }
- }
-
- /* keydown callback */
- static KeyboardFunc gKeyboard = NULL;
- void SetKeyboardHook(KeyboardFunc keys) {
- gKeyboard = keys;
- }
-
- /* MISC ROUTINES */
- static DiskInsertFunc gDiskInsert = NULL;
- static EventHookFunc gEventHook = NULL;
- static SwitcherFunc gSwitcher = NULL;
-
- void SetMiscFunctions(DiskInsertFunc disk, EventHookFunc hook, SwitcherFunc switcher) {
- gDiskInsert = disk;
- gEventHook = hook;
- gSwitcher = switcher;
- }
-
-
- /* MOVEABLE MODAL ROUTINES */
- static WindowPtr gMMWindow = NULL;
- static MMHookFunc gMMHook = NULL;
-
- void SetMMHookProc(MMHookFunc mmhook) {
- gMMHook = mmhook;
- }
-
- WindowPtr GetMMWindow(void) {
- return gMMWindow;
- }
-
- WindowPtr SetMMWindow(WindowPtr target) {
- WindowPtr old_mmwind;
- old_mmwind = gMMWindow;
- gMMWindow = target;
- if (gMMHook) {
- int hasold, hasnew;
- hasold = ((old_mmwind != NULL) ? 1 : 0);
- hasnew = ((target != NULL) ? 1 : 0);
- if ((hasold ^ hasnew) != 0)
- gMMHook(hasnew);
- }
- return old_mmwind;
- }
-
-
- /* MAIN DRIVER */
- void CSAppEvent(EventRecord *ev) {
- WindowPtr target;
- DialogPtr the_dialog;
- short item_hit, part_code;
- Boolean activate;
- long menuresult;
-
- /* call our hook function */
- if (gEventHook) if (gEventHook(ev)) return;
-
- /* is it a menu command? */
- if ((ev->what == keyDown || ev->what == autoKey) && (ev->modifiers & cmdKey) != 0) {
- if (gMenuReset) gMenuReset();
- menuresult = MenuKey((short) (ev->message & charCodeMask));
- if (gMenuHandler && HiWord(menuresult) != 0)
- gMenuHandler(HiWord(menuresult), LoWord(menuresult), ev->modifiers, GetMHandle(HiWord(menuresult)));
- ev->what = nullEvent;
- }
-
- /* are we switching? */
- if (ev->what == osEvt && ((ev->message >> 24) & 0x0FF) == suspendResumeMessage) {
- activate = (ev->message & resumeFlag) != 0;
- target = FrontWindow();
- if (gActivateWindow && target) {
- gActivateWindow(target, activate);
- if (activate) gTheActiveWindow = target;
- }
- if (gSwitcher) gSwitcher(activate);
- }
-
- /* preprocess for dialogs if it applies */
- if (ev->what == activateEvt || ev->what == updateEvt)
- target = (WindowPtr) ev->message;
- else target = FrontWindow();
- if (target && gDialogEvent)
- if (GetWindowKind(target) == dialogKind)
- gDialogEvent(target, ev);
-
- /* dispatch the event to the appropriate handler. */
- if (IsDialogEvent(ev)) {
- if (DialogSelect(ev, &the_dialog, &item_hit))
- if (gDialogHit) gDialogHit(the_dialog, item_hit, ev->modifiers);
- } else switch (ev->what) {
- case keyDown:
- case autoKey:
- if (gKeyboard) gKeyboard((char) (ev->message & charCodeMask), ev);
- case diskEvt:
- if (gDiskInsert) gDiskInsert(ev);
- break;
- case mouseDown:
- part_code = FindWindow(ev->where, &target);
- switch (part_code) {
- case inMenuBar:
- if (gMenuReset) gMenuReset();
- menuresult = MenuSelect(ev->where);
- if (gMenuHandler && HiWord(menuresult) != 0)
- gMenuHandler(HiWord(menuresult), LoWord(menuresult), ev->modifiers, GetMHandle(HiWord(menuresult)));
- break;
- case inSysWindow:
- SystemClick(ev, target);
- break;
- case inGoAway:
- if (TrackGoAway(target, ev->where) && gCloseWindow)
- gCloseWindow(target);
- break;
- case inDrag:
- if ((GetMMWindow() != NULL) && (target != FrontWindow())) {
- SysBeep(1);
- } else {
- Rect boundsRect;
- boundsRect = qd.screenBits.bounds;
- InsetRect(&boundsRect, 4, 4);
- boundsRect.top += GetMBarHeight();
- DragWindow(target, ev->where, &boundsRect);
- }
- break;
- case inGrow:
- if ((GetMMWindow() != NULL) && (target != FrontWindow())) {
- SysBeep(1);
- } else if (gGrowWindow)
- gGrowWindow(target, ev->where, ev->modifiers);
- break;
- case inContent:
- if ((GetMMWindow() != NULL) && (target != FrontWindow())) {
- SysBeep(1);
- } else {
- Point pt;
- if (target != FrontWindow())
- SelectWindow(target);
- else {
- SetPort(target);
- if (ev->when - gLastClickTime <= GetDblTime()) gClickCounter++; else gClickCounter = 1;
- pt = ev->where;
- GlobalToLocal(&pt);
- if (gClickWindow) gClickWindow(target, pt, gClickCounter, ev->modifiers);
- }
- }
- break;
- case inZoomIn:
- case inZoomOut:
- if (gZoomWindow)
- gZoomWindow(target, part_code, ev->modifiers);
- break;
-
- }
- break;
- case activateEvt:
- target = (WindowPtr) (ev->message);
- activate = ((ev->modifiers&1) != 0);
- if (gActivateWindow) {
- gActivateWindow(target, activate);
- if (activate) gTheActiveWindow = target;
- }
- break;
- case updateEvt:
- target = (WindowPtr) (ev->message);
- SetPort(target);
- if (gUpdateWindow)
- gUpdateWindow(target);
- else {
- BeginUpdate(target);
- EndUpdate(target);
- }
- break;
- case kHighLevelEvent:
- if (gAPPLEVENTS) AEProcessAppleEvent(ev);
- break;
- }
- }
-
- Boolean CSAppGetEvent(EventRecord *ev, long sleep) {
- Boolean got_event;
- got_event = false;
- if (gWNE) {
- if (!WaitNextEvent(everyEvent, ev, (sleep > GetCaretTime() ? GetCaretTime() : sleep), NULL))
- ev->what = nullEvent;
- else got_event = true;
- } else {
- SystemTask();
- if (!GetNextEvent(everyEvent, ev)) ev->what = nullEvent; else got_event = true;
- }
- return got_event;
- }
-
- Boolean RunCSApp(long sleep) {
- EventRecord ev;
- Boolean got_event;
- got_event = CSAppGetEvent(&ev, sleep);
- CSAppEvent(&ev);
- return got_event;
- }
-
-
- OSErr OpenCSApp(long stack_kilobytes, long masterblocks) {
- long response;
- long i;
- OSErr err;
- if (stack_kilobytes >= 0) {
- SetApplLimit(GetApplLimit() - (stack_kilobytes*1024));
- if ((err = MemError()) != noErr) return err;
- MaxApplZone();
- }
- for (i=0; i<masterblocks; i++) {
- MoreMasters();
- if ((err = MemError()) != noErr) return err;
- }
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- TEInit();
- InitMenus();
- InitDialogs(0);
- FlushEvents(everyEvent, 0);
- InitCursor();
- gWNE = TrapAvail(_WaitNextEvent);
- if (Gestalt(gestaltAppleEventsAttr, &response) != noErr) response = 0;
- gAPPLEVENTS = ((response & (1<<gestaltAppleEventsPresent)) != 0);
- return noErr;
- }
-
- void CloseCSApp(void) {
- ExitToShell();
- }
-