home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Sample.c
-
- Contains: This is a simple application, based on the DTS traffic light example,
- that demonstrates how to use the Shared Library Manager. It puts the
- functionality of the traffic light window into a shared library and
- then uses that library from the client application.
-
- Copyright: © 1993-1994 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #include <LibraryManager.h>
- #include <LibraryManagerUtilities.h>
-
- #include <limits.h>
- #include <Types.h>
- #include <Resources.h>
- #include <QuickDraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <Desk.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <SegLoad.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <OSEvents.h>
- #include <DiskInit.h>
- #include <Packages.h>
- #include <Traps.h>
-
- #include "Sample.h"
- #include "SampleLibrary.h"
-
- /* The "g" prefix is used to emphasize that a variable is global. */
-
- /* gMac is used to hold the result of a SysEnvirons call. This makes
- it convenient for any routine to check the environment. */
-
- SysEnvRec gMac; /* set up by Initialize */
-
- /* gHasWaitNextEvent is set at startup, and tells whether the WaitNextEvent
- trap is available. If it is false, we know that we must call GetNextEvent. */
-
- Boolean gHasWaitNextEvent; /* set up by Initialize */
-
- /* gInBackground is maintained by our osEvent handling routines. Any part of
- the program can check it to find out if it is currently in the background. */
-
- Boolean gInBackground; /* maintained by Initialize and DoEvent */
-
- /* Here are declarations for all of the C routines. In MPW 3.0 and later we can use
- actual prototypes for parameter type checking. */
-
- void EventLoop( void );
- void DoEvent( EventRecord *event );
- void AdjustCursor( Point mouse, RgnHandle region );
- void GetGlobalMouse( Point *mouse );
- void DoUpdate( WindowPtr window );
- void DoActivate( WindowPtr window, Boolean becomingActive );
- void DoContentClick( WindowPtr window );
- void DrawWindow( WindowPtr window );
- void AdjustMenus( void );
- void DoMenuCommand( long menuResult );
- Boolean DoCloseWindow( WindowPtr window );
- void Terminate( void );
- void UnLoadTrafficLightLibrary();
- void LoadTrafficLightLibrary();
- void Initialize( void );
- void ForceEnvirons( void );
- Boolean IsAppWindow( WindowPtr window );
- Boolean IsDAWindow( WindowPtr window );
- Boolean TrapAvailable( short tNumber, TrapType tType );
- void AlertUser( void );
-
- /* Define TopLeft and BotRight macros for convenience. Notice the implicit
- dependency on the ordering of fields within a Rect */
-
- #define TopLeft(aRect) (* (Point *) &(aRect).top)
- #define BotRight(aRect) (* (Point *) &(aRect).bottom)
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- _DataInit
-
- This routine is part of the MPW runtime library. This external reference to
- it is done so that we can unload its segment, %A5Init.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- extern void _DataInit();
-
- /*————————————————————————————————————————————————————————————————————————————————————
- main
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- main()
- {
- UnloadSeg((Ptr) _DataInit); /* note that _DataInit must not be in Main! */
-
- /* If you have stack requirements that differ from the default,
- then you could use SetApplLimit to increase StackSpace at
- this point, before calling MaxApplZone. */
- MaxApplZone(); /* expand the heap so code segments load at the top */
-
- Initialize(); /* initialize the program */
- UnloadSeg((Ptr) Initialize); /* note that Initialize must not be in Main! */
-
- EventLoop(); /* call the main event loop */
- }
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- EventLoop
-
- Get events forever, and handle them by calling DoEvent.
- Get the events by calling WaitNextEvent, if it's available, otherwise
- by calling GetNextEvent. Also call AdjustCursor each time through the loop.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- void EventLoop()
- {
- RgnHandle cursorRgn;
- Boolean gotEvent;
- EventRecord event;
- Point mouse;
-
- cursorRgn = NewRgn(); /* we’ll pass WNE an empty region the 1st time thru */
- do {
- /* use WNE if it is available */
- if ( gHasWaitNextEvent ) {
- GetGlobalMouse(&mouse);
- AdjustCursor(mouse, cursorRgn);
- gotEvent = WaitNextEvent(everyEvent, &event, LONG_MAX, cursorRgn);
- }
- else {
- SystemTask();
- gotEvent = GetNextEvent(everyEvent, &event);
- }
- if ( gotEvent ) {
- /* make sure we have the right cursor before handling the event */
- AdjustCursor(event.where, cursorRgn);
- DoEvent(&event);
- }
- /* If you are using modeless dialogs that have editText items,
- you will want to call IsDialogEvent to give the caret a chance
- to blink, even if WNE/GNE returned FALSE. However, check FrontWindow
- for a non-NIL value before calling IsDialogEvent. */
- } while ( true ); /* loop forever; we quit via ExitToShell */
- } /*EventLoop*/
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- DoEvent
-
- Do the right thing for an event. Determine what kind of event it is, and call
- the appropriate routines.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
-
- void DoEvent( EventRecord *event)
- {
- short part, err;
- WindowPtr window;
- Boolean hit;
- char key;
- Point aPoint;
-
- switch ( event->what ) {
- case mouseDown:
- part = FindWindow(event->where, &window);
- switch ( part ) {
- case inMenuBar: /* process a mouse menu command (if any) */
- AdjustMenus();
- DoMenuCommand(MenuSelect(event->where));
- break;
- case inSysWindow: /* let the system handle the mouseDown */
- SystemClick(event, window);
- break;
- case inContent:
- if ( window != FrontWindow() ) {
- SelectWindow(window);
- /*DoEvent(event);*/ /* use this line for "do first click" */
- } else
- DoContentClick(window);
- break;
- case inDrag: /* pass screenBits.bounds to get all gDevices */
- DragWindow(window, event->where, &qd.screenBits.bounds);
- break;
- case inGrow:
- break;
- case inZoomIn:
- case inZoomOut:
- hit = TrackBox(window, event->where, part);
- if ( hit ) {
- SetPort(window); /* the window must be the current port... */
- EraseRect(&window->portRect); /* because of a bug in ZoomWindow */
- ZoomWindow(window, part, true); /* note that we invalidate and erase... */
- InvalRect(&window->portRect); /* to make things look better on-screen */
- }
- break;
- }
- break;
- case keyDown:
- case autoKey: /* check for menukey equivalents */
- key = (char)(event->message & charCodeMask);
- if ( event->modifiers & cmdKey ) /* Command key down */
- if ( event->what == keyDown ) {
- AdjustMenus(); /* enable/disable/check menu items properly */
- DoMenuCommand(MenuKey(key));
- }
- break;
- case activateEvt:
- DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
- break;
- case updateEvt:
- DoUpdate((WindowPtr) event->message);
- break;
- /* It is not a bad idea to at least call DIBadMount in response
- to a diskEvt, so that the user can format a floppy. */
- case diskEvt:
- if ( HighWord(event->message) != noErr ) {
- SetPt(&aPoint, kDILeft, kDITop);
- err = DIBadMount(aPoint, event->message);
- }
- break;
- case kOSEvent:
- /* must BitAND with 0x0FF to get only low byte */
- switch ((event->message >> 24) & 0x0FF) { /* high byte of message */
- case kSuspendResumeMessage: /* suspend/resume is also an activate/deactivate */
- gInBackground = (event->message & kResumeMask) == 0;
- DoActivate(FrontWindow(), !gInBackground);
- break;
- }
- break;
- }
- } /*DoEvent*/
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- AdjustCursor
-
- Change the cursor's shape, depending on its position. This also calculates the region
- where the current cursor resides (for WaitNextEvent). If the mouse is ever outside of
- that region, an event would be generated, causing this routine to be called,
- allowing us to change the region to the region the mouse is currently in. If
- there is more to the event than just “the mouse moved”, we get called before the
- event is processed to make sure the cursor is the right one. In any (ahem) event,
- this is called again before we fall back into WNE.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- void AdjustCursor( Point mouse, RgnHandle region )
- {
- WindowPtr window;
- RgnHandle arrowRgn;
- RgnHandle plusRgn;
- Rect globalPortRect;
-
- window = FrontWindow(); /* we only adjust the cursor when we are in front */
- if ( (! gInBackground) && (! IsDAWindow(window)) ) {
- /* calculate regions for different cursor shapes */
- arrowRgn = NewRgn();
- plusRgn = NewRgn();
-
- /* start with a big, big rectangular region */
- SetRectRgn(arrowRgn, kExtremeNeg, kExtremeNeg, kExtremePos, kExtremePos);
-
- /* calculate plusRgn */
- if ( IsAppWindow(window) ) {
- SetPort(window); /* make a global version of the viewRect */
- SetOrigin(-window->portBits.bounds.left, -window->portBits.bounds.top);
- globalPortRect = window->portRect;
- RectRgn(plusRgn, &globalPortRect);
- SectRgn(plusRgn, window->visRgn, plusRgn);
- SetOrigin(0, 0);
- }
-
- /* subtract other regions from arrowRgn */
- DiffRgn(arrowRgn, plusRgn, arrowRgn);
-
- /* change the cursor and the region parameter */
- if ( PtInRgn(mouse, plusRgn) ) {
- SetCursor(*GetCursor(plusCursor));
- CopyRgn(plusRgn, region);
- } else {
- SetCursor(&qd.arrow);
- CopyRgn(arrowRgn, region);
- }
-
- /* get rid of our local regions */
- DisposeRgn(arrowRgn);
- DisposeRgn(plusRgn);
- }
- } /*AdjustCursor*/
-
- /*————————————————————————————————————————————————————————————————————————————————————
- GetGlobalMouse
-
- Get the global coordinates of the mouse. When you call OSEventAvail
- it will return either a pending event or a null event. In either case,
- the where field of the event record will contain the current position
- of the mouse in global coordinates and the modifiers field will reflect
- the current state of the modifiers. Another way to get the global
- coordinates is to call GetMouse and LocalToGlobal, but that requires
- being sure that thePort is set to a valid port.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- void GetGlobalMouse(Point *mouse)
- {
- EventRecord event;
-
- OSEventAvail(kNoEvents, &event); /* we aren't interested in any events */
- *mouse = event.where; /* just the mouse position */
- } /*GetGlobalMouse*/
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- DoUpdate
-
- This is called when an update event is received for a window.
- It calls DrawWindow to draw the contents of an application window.
- As an effeciency measure that does not have to be followed, it
- calls the drawing routine only if the visRgn is non-empty. This
- will handle situations where calculations for drawing or drawing
- itself is very time-consuming.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- void DoUpdate( WindowPtr window)
- {
- if ( IsAppWindow(window) ) {
- BeginUpdate(window); /* this sets up the visRgn */
- if ( ! EmptyRgn(window->visRgn) ) /* draw if updating needs to be done */
- DrawWindow(window);
- EndUpdate(window);
- }
- } /*DoUpdate*/
-
- /*————————————————————————————————————————————————————————————————————————————————————
- DoActivate
-
- This is called when a window is activated or deactivated.
- In Sample, the Window Manager's handling of activate and
- deactivate events is sufficient. Other applications may have
- TextEdit records, controls, lists, etc., to activate/deactivate.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- void DoActivate(WindowPtr window, Boolean becomingActive)
- {
- if ( IsAppWindow(window) ) {
- if ( becomingActive )
- /* do whatever you need to at activation */ ;
- else
- /* do whatever you need to at deactivation */ ;
- }
- } /*DoActivate*/
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- DoContentClick
-
- This is called when a mouse-down event occurs in the content of a window.
- Other applications might want to call FindControl, TEClick, etc., to
- further process the click.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
-
- void DoContentClick ( WindowPtr window )
- {
- #pragma unused( window )
-
- /* Here we are going to toggle the traffic light by getting the previous state
- and inverting it to new state. All the calls are going through v-table */
-
- SetLightState( !GetLightState() );
-
- } /*DoContentClick*/
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- DrawWindow
-
- Draw the contents of the application window. We do some drawing in color, using
- Classic QuickDraw's color capabilities. This will be black and white on old
- machines, but color on color machines. At this point, the window’s visRgn
- is set to allow drawing only where it needs to be done.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
-
- void DrawWindow(WindowPtr window)
- {
- #pragma unused( window )
-
- /* DrawLight draws the traffic light through FunctionSets */
-
- DrawLight();
-
- } /*DrawWindow*/
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- AdjustMenus
-
- Enable and disable menus based on the current state.
- The user can only select enabled menu items. We set up all the menu items
- before calling MenuSelect or MenuKey, since these are the only times that
- a menu item can be selected. Note that MenuSelect is also the only time
- the user will see menu items. This approach to deciding what enable/
- disable state a menu item has the advantage of concentrating all
- the decision-making in one routine, as opposed to being spread throughout
- the application. Other application designs may take a different approach
- that is just as valid.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- void AdjustMenus()
- {
- MenuHandle menu;
-
- WindowPtr window = FrontWindow();
-
- menu = GetMenuHandle(mFile);
- if ( IsDAWindow(window) ) /* we can allow desk accessories to be closed from the menu */
- EnableItem(menu, iClose);
- else
- DisableItem(menu, iClose); /* but not our traffic light window */
-
- menu = GetMenuHandle(mEdit);
- if ( IsDAWindow(window) ) { /* a desk accessory might need the edit menu… */
- EnableItem(menu, iUndo);
- EnableItem(menu, iCut);
- EnableItem(menu, iCopy);
- EnableItem(menu, iClear);
- EnableItem(menu, iPaste);
- } else { /* …but we don’t use it */
- DisableItem(menu, iUndo);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iClear);
- DisableItem(menu, iPaste);
- }
-
- /* after adjusting the application's menus adjust the traffic light menus by
- going through the v-table */
-
- AdjustTrafficLightMenus( IsAppWindow(window) );
-
- } /* AdjustMenus */
-
- /*————————————————————————————————————————————————————————————————————————————————————
- DoMenuCommand
-
- This is called when an item is chosen from the menu bar (after calling
- MenuSelect or MenuKey). It performs the right operation for each command.
- It is good to have both the result of MenuSelect and MenuKey go to
- one routine like this to keep everything organized. It checks to see if the
- menu hit where the Apple, File, or Edit if so it calls the local DoMenuCommand
- else it must be our traffic light's menu, therefore traffic light menu command
- is being called.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- void DoMenuCommand(long menuResult)
- {
- short menuID; /* the resource ID of the selected menu */
- short menuItem; /* the item number of the selected menu */
- short itemHit;
- Str255 daName;
- short daRefNum;
- Boolean handledByDA;
-
- /* Here we are going to get a pointer to our object TLibraryFile this is
- necessary for allocating our traffic light's resources */
-
- menuID = HighWord(menuResult); /* use macros for efficiency to... */
- menuItem = LowWord(menuResult); /* get menu item number and menu number */
-
- switch ( menuID ) {
- case mApple:
- switch ( menuItem ) {
- case iAbout: /* bring up alert for About */
- itemHit = Alert(rAboutAlert, nil);
- break;
- default: /* all non-About items in this menu are DAs */
- /* type Str255 is an array in MPW 3 */
- GetMenuItemText(GetMenuHandle(mApple), menuItem, daName);
- daRefNum = OpenDeskAcc(daName);
- break;
- }
- break;
- case mFile:
- switch ( menuItem ) {
- case iClose:
- DoCloseWindow(FrontWindow());
- break;
- case iQuit:
- Terminate();
- break;
- }
- break;
- case mEdit: /* call SystemEdit for DA editing & MultiFinder */
- handledByDA = SystemEdit(menuItem-1); /* since we don’t do any Editing */
- break;
- case mLight: /* this must be our shared library resource */
- /* since DoMenuCommand uses the traffic light's resources. */
- DoTrafficLightMenuCommand( menuItem ); /* Do traffic light's menu command */
- break;
- }
- HiliteMenu(0); /* unhighlight what MenuSelect (or MenuKey) hilited */
- } /*DoMenuCommand*/
-
- /*————————————————————————————————————————————————————————————————————————————————————
- DoCloseWindow
-
- Close a window. This handles desk accessory and application windows. Note the
- traffic library manager allocated the windowrecord for window, so disposing of
- the WindowRecord should be left upon the traffic light library.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
-
- #pragma segment Main
- Boolean DoCloseWindow(WindowPtr window)
- {
- if ( IsDAWindow(window) )
- CloseDeskAcc(((WindowPeek) window)->windowKind);
- else if ( IsAppWindow(window) )
- FreeTrafficLight(); /* done with trafficlight, deallocate */
- return true;
- } /*DoCloseWindow*/
-
- /*————————————————————————————————————————————————————————————————————————————————————
- Terminate
-
- Cleanup the application and exits. Close all of the windows, and cleanup our
- library. We replace the ExitToShell by UnLoadTrafficLightLibrary so we get a
- chance to unload the library and cleanup the library manager.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- void Terminate()
- {
- WindowPtr aWindow;
- Boolean closed;
-
- closed = true;
-
- do {
- aWindow = FrontWindow(); /* get the current front window */
- if ( aWindow != nil )
- closed = DoCloseWindow(aWindow);/* close this window */
- } while (closed && (aWindow != nil));
-
- if (closed)
- UnLoadTrafficLightLibrary(); /* exit if no cancellation */
-
- } /*Terminate*/
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- UnLoadTrafficLightLibrary
-
- unload the traffic light object and free the memory allocated by our library
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- void UnLoadTrafficLightLibrary()
- {
- /* A library loaded with LoadFunctionSet() is not
- unloaded until all objects from the library
- are deleted and an UnloadFunctionSet() call is
- made to balance each LoadFunctionSet() call */
- UnloadFunctionSet(kTrafficLightFunctionSet);
-
- CleanupLibraryManager(); /* clean up the library manager we are done. */
- ExitToShell(); /* Hasta la Vista baby! */
- } /* UnLoadTrafficLightLibrary */
-
- /*————————————————————————————————————————————————————————————————————————————————————
- LoadTrafficLightLibrary
-
- load the traffic light library. This library automatically creates a window and
- attach a traffic menu to our current menu.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- void LoadTrafficLightLibrary()
- {
- /* always initilize the library manager before any Shared Library calls. This
- creates a local instance of TLibraryManager for accessing our libraries. */
-
- if( InitLibraryManager( 0, /* we don't need memory in our local pool */
- kCurrentZone, /* use application zone = current zone */
- kNormalMemory /* default memory type, no VM stuff */
- ) == kNoError ) {
-
- /* make sure the library is available before initializing trafficlight(via LoadFunctionSet) */
- if( LoadFunctionSet(kTrafficLightFunctionSet, true ) == kNoError) {
- if( NewTrafficLight() ) /* initialize our trafficlight shared library */
- AlertUser();
- }
- else
- AlertUser();
- }
- else
- AlertUser(); /* not good. SLM IS NOT INSLALLED */
-
- } /* LoadTrafficLightLibrary */
-
- /*————————————————————————————————————————————————————————————————————————————————————
- Initialize
-
- Set up the whole world, including global variables, Toolbox managers,
- and menus. Sample is going to create its window, and traffic menu through its
- traffic library, using the shared library manager(Nahhhh...). The Library auto-
- matically create a window, attach a menu and draws the traffic light.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Initialize
- void Initialize()
- {
- Handle menuBar;
- long total, contig;
- EventRecord event;
- short count;
-
- gInBackground = false;
-
- InitGraf((Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- /* This next bit of code is necessary to allow the default button of our
- alert be outlined */
-
- for (count = 1; count <= 3; count++)
- EventAvail(everyEvent, &event);
-
- /* Ignore the error returned from SysEnvirons; even if an error occurred,
- the SysEnvirons glue will fill in the SysEnvRec. You can save a redundant
- call to SysEnvirons by calling it after initializing AppleTalk.*/
-
- SysEnvirons(kSysEnvironsVersion, &gMac);
-
- /* Make sure that the machine has at least 128K ROMs. If it doesn't, exit. */
-
- if (gMac.machineType < 0) AlertUser();
-
- /* Move TrapAvailable call to after SysEnvirons so that we can tell
- in TrapAvailable if a tool trap value is out of range. */
-
- gHasWaitNextEvent = TrapAvailable(_WaitNextEvent, ToolTrap);
-
- /* We used to make a check for memory at this point by examining ApplLimit,
- ApplicationZone, and StackSpace and comparing that to the minimum size we told
- MultiFinder we needed. This did not work well because it assumed too much about
- the relationship between what we asked MultiFinder for and what we would actually
- get back, as well as how to measure it. Instead, we will use an alternate
- method comprised of two steps. */
-
- /* It is better to first check the size of the application heap against a value
- that you have determined is the smallest heap the application can reasonably
- work in. This number should be derived by examining the size of the heap that
- is actually provided by MultiFinder when the minimum size requested is used.
- The derivation of the minimum size requested from MultiFinder is described
- in Sample.h. The check should be made because the preferred size can end up
- being set smaller than the minimum size by the user. This extra check acts to
- insure that your application is starting from a solid memory foundation. */
-
- if ((long) GetApplLimit() - (long) ApplicationZone() < kMinHeap) AlertUser();
-
- /* Next, make sure that enough memory is free for your application to run. It
- is possible for a situation to arise where the heap may have been of required
- size, but a large scrap was loaded which left too little memory. To check for
- this, call PurgeSpace and compare the result with a value that you have determined
- is the minimum amount of free memory your application needs at initialization.
- This number can be derived several different ways. One way that is fairly
- straightforward is to run the application in the minimum size configuration
- as described previously. Call PurgeSpace at initialization and examine the value
- returned. However, you should make sure that this result is not being modified
- by the scrap's presence. You can do that by calling ZeroScrap before calling
- PurgeSpace. Make sure to remove that call before shipping, though.*/
-
- PurgeSpace(&total, &contig);
- if (total < kMinSpace) AlertUser();
-
- menuBar = GetNewMBar(rMenuBar); /* read menus into menu bar */
- if ( menuBar == nil ) AlertUser();
- SetMenuBar(menuBar); /* install menus */
- DisposeHandle(menuBar);
- AppendResMenu(GetMenuHandle(mApple), 'DRVR'); /* add DA names to Apple menu */
-
- DrawMenuBar(); /* go ahead and update the menu bar */
-
- LoadTrafficLightLibrary(); /* Load trafficlight shared library */
-
- } /*Initialize*/
-
- /*————————————————————————————————————————————————————————————————————————————————————
- IsAppWindow
-
- Check to see if a window belongs to the application. If the window pointer
- passed was NIL, then it could not be an application window. WindowKinds
- that are negative belong to the system and windowKinds less than userKind
- are reserved by Apple except for windowKinds equal to dialogKind, which
- mean it is a dialog.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- Boolean IsAppWindow( WindowPtr window)
- {
- short windowKind;
-
- if ( window == nil )
- return false;
- else { /* application windows have windowKinds = userKind (8) */
- windowKind = ((WindowPeek) window)->windowKind;
- return ( windowKind == userKind );
- }
- } /*IsAppWindow*/
-
- /*————————————————————————————————————————————————————————————————————————————————————
- IsDAWindow
-
- Check to see if a window belongs to a desk accessory
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- Boolean IsDAWindow(WindowPtr window)
- {
- if ( window == nil )
- return false;
- else /* DA windows have negative windowKinds */
- return ( ((WindowPeek) window)->windowKind < 0 );
- } /*IsDAWindow*/
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- TrapAvailable
-
- Check to see if a given trap is implemented. This is only used by the
- Initialize routine in this program, so we put it in the Initialize segment.
- The recommended approach to see if a trap is implemented is to see if
- the address of the trap routine is the same as the address of the
- Unimplemented trap.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Initialize
- Boolean TrapAvailable( short tNumber, TrapType tType)
- {
- if ( ( tType == ToolTrap ) &&
- ( gMac.machineType > envMachUnknown ) &&
- ( gMac.machineType < envMacII ) ) { /* it's a 512KE, Plus, or SE */
- tNumber = tNumber & 0x03FF;
- if ( tNumber > 0x01FF ) /* which means the tool traps */
- tNumber = _Unimplemented; /* only go to 0x01FF */
- }
- return NGetTrapAddress(tNumber, tType) != NGetTrapAddress(_Unimplemented, tType);
- } /*TrapAvailable*/
-
- /*————————————————————————————————————————————————————————————————————————————————————
- AlertUser
-
- Display an alert that tells the user an error occurred, then exit the program.
- This routine is used as an ultimate bail-out for serious errors that prohibit
- the continuation of the application. Errors that do not require the termination
- of the application should be handled in a different manner. Error checking and
- reporting has a place even in the simplest application. The error number is used
- to index an 'STR#' resource so that a relevant message can be displayed.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- #pragma segment Main
- void AlertUser()
- {
- short itemHit;
-
- SetCursor(&qd.arrow);
- itemHit = Alert(rUserAlert, nil);
- UnLoadTrafficLightLibrary();
- } /* AlertUser */