Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Source/MainStuff.c
/*-------------------------------------------------------------------------------------- |
// |
// File: MainStuff.c |
// |
// Contents: Main event loop. Only those portions needed for support of the tools |
// features have been included. |
// |
// |
// By Georgiann ("George") Delaney |
// ©Ê1989 - 1990, Apple Computer, Inc. |
// |
//--------------------------------------------------------------------------------------*/ |
#include "MacHeaders.h" |
#include "BitBlitz.h" |
#include "MainStuff.h" |
#pragma segment main |
/*======================================================================================*/ |
/* Shell Global Variables */ |
Boolean gFinished = false; /* Does the user want to quit the application? */ |
Boolean gWNEAvailable; /* Specifies if WaitNextEvent is available */ |
Boolean gInBackground = false; /* Is the application in the background under MF */ |
Handle gtheMenuBar; /* Handle to the tool menus */ |
MenuHandle gtheMenus[kMenuCount+kHeirCount]; /* Structure holding the application menus */ |
short gCmdOn = false; /* Is the command key being pressed? */ |
Boolean gDoubleClick = false; /* Determines if the user double-clicked */ |
long gLastTime; |
Point gLastPoint; |
/*======================================================================================*/ |
/* Setup Routines */ |
/*--------------------------------------------------------------------------------------*/ |
void SetUpMenu() |
/* |
// This procedure reads in all of the menu resources and builds the application |
// menu. |
*/ |
{ |
short n; |
InitMenus(); |
gtheMenus[kAppleMenu] = GetMenu( kAppleMenuID ); |
AddResMenu(gtheMenus[kAppleMenu],'DRVR'); |
gtheMenus[kFileMenu] = GetMenu(kFileMenuID); |
gtheMenus[kEditMenu] = GetMenu(kEditMenuID); |
gtheMenus[kOptionsMenu] = GetMenu(kOptionsMenuID); |
gtheMenus[khCopyModeMenu] = GetMenu(khCopyModeMenuID); |
gtheMenus[khClipRgnMenu] = GetMenu(khClipRgnMenuID); |
gtheMenus[khVisRgnMenu] = GetMenu(khVisRgnMenuID); |
gtheMenus[khMaskRgnMenu] = GetMenu(khMaskRgnMenuID); |
gtheMenus[khFGColorMenu] = GetMenu(khFGColorMenuID); |
gtheMenus[khBKColorMenu] = GetMenu(khBKColorMenuID); |
gtheMenus[khOPColorMenu] = GetMenu(khOPColorMenuID); |
gtheMenus[khHiliteMenu] = GetMenu(khHiliteMenuID); |
for ( n = 0; n < kMenuCount; n++ ) |
InsertMenu(gtheMenus[n],0); |
for ( n = n; n < (kMenuCount+kHeirCount); n++ ) |
InsertMenu(gtheMenus[n], hierMenu); |
gtheMenuBar = GetMenuBar(); |
DrawMenuBar(); |
} |
/*--------------------------------------------------------------------------------------*/ |
void InitAppMenus() |
{ |
if (!gColorAvail) { |
DisableItem(gtheMenus[kOptionsMenu], kSrcOr ); |
DisableItem(gtheMenus[kOptionsMenu], kSrcXor ); |
DisableItem(gtheMenus[kOptionsMenu], kSrcBic ); |
DisableItem(gtheMenus[kOptionsMenu], kNotSrcCopy ); |
DisableItem(gtheMenus[kOptionsMenu], kNotSrcOr ); |
DisableItem(gtheMenus[kOptionsMenu], kNotSrcXor ); |
DisableItem(gtheMenus[kOptionsMenu], kNotSrcBic ); |
DisableItem(gtheMenus[kOptionsMenu], kBlend ); |
DisableItem(gtheMenus[kOptionsMenu], kAddPin ); |
DisableItem(gtheMenus[kOptionsMenu], kAddOver ); |
DisableItem(gtheMenus[kOptionsMenu], kAddMin ); |
DisableItem(gtheMenus[kOptionsMenu], kAddMax ); |
DisableItem(gtheMenus[kOptionsMenu], kSubPin ); |
DisableItem(gtheMenus[kOptionsMenu], kSubOver ); |
DisableItem(gtheMenus[kOptionsMenu], kTransparent ); |
DisableItem(gtheMenus[kOptionsMenu], kHilite ); |
} |
else |
CheckItem (gtheMenus[khCopyModeMenu],CopyMode2ModeMenuItem(gCopyMode),true); |
} |
/*--------------------------------------------------------------------------------------*/ |
void InitMac() |
/* |
// This procedure executes all Macintosh initialization functions. |
*/ |
{ |
EventRecord theEvent; |
MaxApplZone(); |
MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters(); |
InitGraf(&qd.thePort); |
InitFonts(); |
InitWindows(); |
SetUpMenu(); |
TEInit(); |
InitDialogs(nil); |
InitCursor(); |
InitAllPacks(); |
gWNEAvailable = myTrapAvailable(_WaitNextEvent, ToolTrap); |
EventAvail(everyEvent,&theEvent); /* Force windows to frontÉ (for MF) */ |
} |
/*======================================================================================*/ |
/* Main Loop and Event Management Routines */ |
/*--------------------------------------------------------------------------------------*/ |
Boolean IsDAWindow( window ) |
WindowPtr window; |
{ |
if ( window == nil ) |
return false; |
else |
return ( (WindowPeek) window)->windowKind < 0; |
} |
/*--------------------------------------------------------------------------------------*/ |
void AdjustMenusForDA() |
{ |
EnableItem (gtheMenus[kFileMenu], kNew); |
EnableItem (gtheMenus[kFileMenu], kOpen); |
EnableItem (gtheMenus[kFileMenu], kClose); |
EnableItem (gtheMenus[kFileMenu], kSave); |
EnableItem (gtheMenus[kFileMenu], kSaveAs); |
EnableItem (gtheMenus[kFileMenu], kPageSetUp); |
EnableItem (gtheMenus[kFileMenu], kPrint); |
EnableItem (gtheMenus[kFileMenu], kQuit); |
EnableItem (gtheMenus[kEditMenu], kUndo); |
EnableItem (gtheMenus[kEditMenu], kCut); |
EnableItem (gtheMenus[kEditMenu], kCopy); |
EnableItem (gtheMenus[kEditMenu], kPaste); |
EnableItem (gtheMenus[kEditMenu], kClear); |
DisableItem(gtheMenus[kOptionsMenu], kSrcAttributes ); |
DisableItem(gtheMenus[kOptionsMenu], kMskAttributes ); |
DisableItem(gtheMenus[kOptionsMenu], kDstAttributes ); |
DisableItem(gtheMenus[kOptionsMenu], kTrapSelect); |
DisableItem(gtheMenus[kOptionsMenu], kCopyModeSelect); |
DisableItem(gtheMenus[kOptionsMenu], kMaskRgnSelect); |
} |
/*--------------------------------------------------------------------------------------*/ |
void AdjustMenusForApp() |
{ |
DisableItem(gtheMenus[kFileMenu], kNew); |
DisableItem(gtheMenus[kFileMenu], kOpen); |
DisableItem(gtheMenus[kFileMenu], kClose); |
DisableItem(gtheMenus[kFileMenu], kSave); |
DisableItem(gtheMenus[kFileMenu], kSaveAs); |
DisableItem(gtheMenus[kFileMenu], kPageSetUp); |
DisableItem(gtheMenus[kFileMenu], kPrint); |
EnableItem (gtheMenus[kFileMenu], kQuit); |
DisableItem(gtheMenus[kEditMenu], kUndo); |
DisableItem(gtheMenus[kEditMenu], kCut); |
DisableItem(gtheMenus[kEditMenu], kCopy); |
DisableItem(gtheMenus[kEditMenu], kPaste); |
DisableItem(gtheMenus[kEditMenu], kClear); |
EnableItem (gtheMenus[kOptionsMenu], kSrcAttributes ); |
EnableItem (gtheMenus[kOptionsMenu], kMskAttributes ); |
EnableItem (gtheMenus[kOptionsMenu], kDstAttributes ); |
EnableItem (gtheMenus[kOptionsMenu], kTrapSelect); |
EnableItem (gtheMenus[kOptionsMenu], kFGColor); |
CheckItem (gtheMenus[khFGColorMenu], gFGColor.menuIndex, true); |
EnableItem (gtheMenus[kOptionsMenu], kBKColor); |
CheckItem (gtheMenus[khBKColorMenu], gBKColor.menuIndex, true); |
EnableItem (gtheMenus[kOptionsMenu], kClipRgnSelect); |
CheckItem (gtheMenus[khClipRgnMenu], gRList[kClpRgn].type, true); |
EnableItem (gtheMenus[kOptionsMenu], kVisRgnSelect); |
CheckItem (gtheMenus[khVisRgnMenu], gRList[kVisRgn].type, true); |
EnableItem (gtheMenus[kOptionsMenu], kUseScreenBits); |
CheckItem (gtheMenus[kOptionsMenu], kUseScreenBits, gUseScreenBits); |
EnableItem (gtheMenus[kOptionsMenu], kDither); |
CheckItem (gtheMenus[kOptionsMenu], kDither, gDither); |
if (gColorAvail) { |
EnableItem (gtheMenus[kOptionsMenu], kOpColor); |
CheckItem (gtheMenus[khOPColorMenu],gOPColor.menuIndex,true); |
EnableItem (gtheMenus[kOptionsMenu], kHiliteColor); |
CheckItem (gtheMenus[khHiliteMenu], gHiliteColor.menuIndex,true); |
} |
else { |
DisableItem(gtheMenus[khFGColorMenu], kCustomColor); |
DisableItem(gtheMenus[khFGColorMenu], kCustomColor); |
DisableItem(gtheMenus[kOptionsMenu], kOpColor); |
DisableItem(gtheMenus[kOptionsMenu], kHiliteColor); |
} |
if ((gTrapSelect == kCopyDeepMask) || (gTrapSelect == kCopyBits)) { |
EnableItem (gtheMenus[kOptionsMenu], kCopyModeSelect); |
EnableItem (gtheMenus[kOptionsMenu], kMaskRgnSelect); |
CheckItem (gtheMenus[khMaskRgnMenu], gRList[kMskRgn].type,true); |
if (gTrapSelect == kCopyBits) |
DisableItem(gtheMenus[kOptionsMenu], kMskAttributes ); |
} |
else { |
DisableItem(gtheMenus[kOptionsMenu], kCopyModeSelect); |
DisableItem(gtheMenus[kOptionsMenu], kMaskRgnSelect); |
} |
} |
/*--------------------------------------------------------------------------------------*/ |
void AdjustMenus() |
/* |
AdjustMenus will properly activate/deactivate/update each menu item in each |
of the menus to properly reflect the available selections with respect to the |
currently active window. |
*/ |
{ |
WindowPtr theActiveWindow; |
theActiveWindow = FrontWindow(); |
if (IsDAWindow(theActiveWindow)) |
AdjustMenusForDA(); |
else AdjustMenusForApp(); |
} |
/*--------------------------------------------------------------------------------------*/ |
void DoMenuCommand(long menuData) |
{ |
short theMenu; |
short theItem; |
Str255 theName; |
short theRefNum; |
Boolean imageChanged = true; |
OSErr result = noErr; |
theMenu = HiWord(menuData); |
theItem = LoWord(menuData); |
switch (theMenu) { |
case kAppleMenuID: |
switch ( theItem ) { |
case kAboutBox: AboutBitBlitz(); break; |
default: |
GetItem(GetMHandle(kAppleMenuID), theItem, theName); |
theRefNum = OpenDeskAcc(theName); |
break; |
} |
break; |
case kFileMenuID: |
switch ( theItem ) { |
case kNew: break; |
case kOpen: break; |
case kClose: break; |
case kSave: break; |
case kSaveAs: break; |
case kPageSetUp: break; |
case kPrint: break; |
case kQuit: gFinished = true; break; |
} |
break; |
case kEditMenuID: |
switch ( theItem ) { |
case kUndo: break; |
case kCut: break; |
case kCopy: break; |
case kPaste: break; |
case kClear: break; |
} |
break; |
case kOptionsMenuID: |
switch ( theItem ) { |
case kSrcAttributes: ChangeWindowAttributes(kSrcWindow); break; |
case kMskAttributes: ChangeWindowAttributes(kMskWindow); break; |
case kDstAttributes: ChangeWindowAttributes(kDstWindow); break; |
case kTrapSelect: SelectTrap(); break; |
case kUseScreenBits: gUseScreenBits = !gUseScreenBits; |
CheckItem (gtheMenus[kOptionsMenu],kUseScreenBits,gUseScreenBits); |
DrawBuffer(kBitWindow); |
DrawWindow(kBitWindow); |
break; |
case kDither: gDither = !gDither; |
CheckItem (gtheMenus[kOptionsMenu],kDither,gDither); |
if ((gCopyMode == srcCopy) || (gCopyMode == ditherCopy)) { |
if (gDither) |
gCopyMode = ditherCopy; |
else |
gCopyMode = srcCopy; |
} |
DrawBuffer(kBitWindow); |
DrawWindow(kBitWindow); |
break; |
} |
break; |
case khCopyModeMenuID: |
CheckItem(gtheMenus[khCopyModeMenu],CopyMode2ModeMenuItem(gCopyMode),false); |
CheckItem(gtheMenus[khCopyModeMenu],theItem,true); |
gCopyMode = ModeMenuItem2CopyMode(theItem); |
DrawBuffer(kBitWindow); |
DrawWindow(kBitWindow); |
break; |
case khClipRgnMenuID: |
CheckItem (gtheMenus[khClipRgnMenu],gRList[kClpRgn].type,false); |
SelectRgn (kClpRgn,theItem); |
CheckItem (gtheMenus[khClipRgnMenu],gRList[kClpRgn].type,true); |
break; |
case khVisRgnMenuID: |
CheckItem (gtheMenus[khVisRgnMenu],gRList[kVisRgn].type,false); |
SelectRgn (kVisRgn,theItem); |
CheckItem (gtheMenus[khVisRgnMenu],gRList[kVisRgn].type,true); |
break; |
case khMaskRgnMenuID: |
CheckItem (gtheMenus[khMaskRgnMenu],gRList[kMskRgn].type,false); |
SelectRgn (kMskRgn,theItem); |
CheckItem (gtheMenus[khMaskRgnMenu],gRList[kMskRgn].type,true); |
break; |
case khFGColorMenuID: |
CheckItem (gtheMenus[khFGColorMenu],gFGColor.menuIndex,false); |
SelectFGColor(theItem); |
CheckItem (gtheMenus[khFGColorMenu],gFGColor.menuIndex,true); |
break; |
case khBKColorMenuID: |
CheckItem (gtheMenus[khBKColorMenu],gBKColor.menuIndex,false); |
SelectBKColor(theItem); |
CheckItem (gtheMenus[khBKColorMenu],gBKColor.menuIndex,true); |
break; |
case khOPColorMenuID: |
CheckItem (gtheMenus[khOPColorMenu],gOPColor.menuIndex,false); |
SelectOPColor(theItem); |
CheckItem (gtheMenus[khOPColorMenu],gOPColor.menuIndex,true); |
break; |
case khHiliteMenuID : |
CheckItem (gtheMenus[khHiliteMenu],gHiliteColor.menuIndex,false); |
SelectHiliteColor(theItem); |
CheckItem (gtheMenus[khHiliteMenu],gHiliteColor.menuIndex,true); |
break; |
} |
HiliteMenu(0); |
} |
/*--------------------------------------------------------------------------------------*/ |
void DoGrowWindow(WindowPtr theWindow, EventRecord *theEvent) |
{ |
long newSize; |
Point newDimen, oldDimen; |
if (theWindow != FrontWindow()) |
SelectWindow(theWindow); |
else |
SetPort(theWindow); |
newSize = GrowWindow(theWindow,theEvent->where,&qd.screenBits.bounds); |
if (newSize != 0) { |
SetCursor(*GetCursor(watchCursor)); |
newDimen.h = LoWord(newSize); |
newDimen.v = HiWord(newSize); |
if ((theWindow == gWList[kSrcWindow].window) || (theWindow == gWList[kMskWindow].window)) { |
SetPort(gWList[kSrcWindow].window); |
if (ResizeTestWindow(&newDimen,kSrcWindow)) { |
oldDimen.h = gWList[kSrcWindow].window->portRect.right - gWList[kSrcWindow].window->portRect.left; |
oldDimen.v = gWList[kSrcWindow].window->portRect.bottom - gWList[kSrcWindow].window->portRect.top; |
SetPort(gWList[kMskWindow].window); |
if (ResizeTestWindow(&newDimen,kMskWindow)) { |
SizeWindow(gWList[kMskWindow].window,newDimen.h,newDimen.v,false); |
SizeWindow(gWList[kSrcWindow].window,newDimen.h,newDimen.v,false); |
} |
else { |
SetPort(gWList[kSrcWindow].window); |
ResizeTestWindow(&oldDimen,kSrcWindow); |
} |
} |
} |
if ((theWindow == gWList[kDstWindow].window) || (theWindow == gWList[kBitWindow].window)) { |
SetPort(gWList[kDstWindow].window); |
if (ResizeTestWindow(&newDimen,kDstWindow)) { |
oldDimen.h = gWList[kDstWindow].window->portRect.right - gWList[kDstWindow].window->portRect.left; |
oldDimen.v = gWList[kDstWindow].window->portRect.bottom - gWList[kDstWindow].window->portRect.top; |
SetPort(gWList[kBitWindow].window); |
if (ResizeTestWindow(&newDimen,kBitWindow)) { |
SizeWindow(gWList[kBitWindow].window,newDimen.h,newDimen.v,false); |
SizeWindow(gWList[kDstWindow].window,newDimen.h,newDimen.v,false); |
UpdateRgnSettings(); |
} |
else { |
SetPort(gWList[kDstWindow].window); |
ResizeTestWindow(&oldDimen,kDstWindow); |
} |
} |
} |
SetPort(theWindow); |
DrawBuffer(kBitWindow); |
DrawWindow(kSrcWindow); |
DrawWindow(kMskWindow); |
DrawWindow(kDstWindow); |
DrawWindow(kBitWindow); |
InitCursor(); |
} |
} |
/*--------------------------------------------------------------------------------------*/ |
short abs(short a) |
{ |
return((a<0)?-a:a); |
} |
/*--------------------------------------------------------------------------------------*/ |
Boolean AlmostEqualPt(Point *pt1, Point *pt2, short tolerance) |
/* |
// AlmostEqualPt() determines if two points are equal within the specified tolerance. |
*/ |
{ |
return ((abs(pt2->h - pt1->h) < tolerance) && (abs(pt2->v - pt1->v) < tolerance)); |
} |
/*--------------------------------------------------------------------------------------*/ |
void DoMouseDown(EventRecord *theEvent) |
{ |
short thePart; |
WindowPtr theWindow; |
register i; |
gDoubleClick = ((theEvent->when - gLastTime) <= GetDblTime()); |
gDoubleClick = ( (gDoubleClick) && AlmostEqualPt(&gLastPoint,&theEvent->where,3)); |
thePart = FindWindow(theEvent->where, &theWindow); |
switch ( thePart ) { |
case inMenuBar: |
AdjustMenus(); |
DoMenuCommand(MenuSelect(theEvent->where)); |
break; |
case inSysWindow: |
SystemClick( theEvent, theWindow ); |
break; |
case inContent: |
if (theWindow != FrontWindow()) |
SelectWindow(theWindow); |
else { |
SetPort(theWindow); |
if (gDoubleClick) |
for (i=kSrcWindow; i<=kBitWindow; i++) |
if (theWindow == gWList[i].window) |
if (i<kBitWindow) |
ChangeWindowAttributes(i); |
else |
SysBeep(10); |
} |
break; |
case inDrag: |
DragWindow(theWindow,theEvent->where,&qd.screenBits.bounds); |
if (gUseScreenBits) { |
for (i=kSrcWindow; i<=kDstWindow; i++) |
DrawWindow(i); |
DrawBuffer(kBitWindow); |
DrawWindow(kBitWindow); |
} |
break; |
case inGrow: |
DoGrowWindow(theWindow, theEvent); |
break; |
case inZoomIn: |
case inZoomOut: |
if ( TrackBox(theWindow, theEvent->where, thePart) ) |
{ |
SetPort(theWindow); |
ZoomWindow(theWindow, thePart, true); |
InvalRect(&theWindow->portRect); |
} |
break; |
} |
gLastTime = theEvent->when; |
gLastPoint = theEvent->where; |
} |
/*--------------------------------------------------------------------------------------*/ |
void DoKeyDown( theEvent ) |
EventRecord *theEvent; |
{ |
char theKey; |
gCmdOn = ( theEvent->modifiers & cmdKey ); |
theKey = theEvent->message & charCodeMask; |
if ((gCmdOn) && (theEvent->what == keyDown)) { |
AdjustMenus(); |
DoMenuCommand( MenuKey(theKey) ); |
} |
} |
/*--------------------------------------------------------------------------------------*/ |
void DoUpdate(EventRecord *theEvent) |
{ |
WindowPtr theWindow; |
theWindow = (WindowPtr)theEvent->message; |
if (theWindow != nil) { |
BeginUpdate(theWindow); |
if (theWindow == gWList[kSrcWindow].window) |
DrawWindow(kSrcWindow); |
else if (theWindow == gWList[kMskWindow].window) |
DrawWindow(kMskWindow); |
else if (theWindow == gWList[kDstWindow].window) |
DrawWindow(kDstWindow); |
else if (theWindow == gWList[kBitWindow].window) |
DrawWindow(kBitWindow); |
EndUpdate(theWindow); |
} |
} |
/*--------------------------------------------------------------------------------------*/ |
void DoEvent(EventRecord *theEvent) |
{ |
switch (theEvent->what) { |
case nullEvent: |
break; |
case mouseDown: |
DoMouseDown(theEvent); |
break; |
case keyDown: |
case autoKey: |
DoKeyDown(theEvent); |
break; |
case activateEvt: |
InitCursor(); |
break; |
case updateEvt: |
DoUpdate(theEvent); |
break; |
case diskEvt: |
break; |
} |
} |
/*--------------------------------------------------------------------------------------*/ |
void MainLoop() |
{ |
EventRecord theEvent; |
do { |
if (gWNEAvailable) |
WaitNextEvent(everyEvent, &theEvent, LONG_MAX, nil); |
else { |
SystemTask(); |
GetNextEvent(everyEvent, &theEvent); |
} |
DoEvent(&theEvent); |
} while (! gFinished); |
} |
/*--------------------------------------------------------------------------------------*/ |
main() |
{ |
SysEnvRec theWorld; |
/* Perform standard mac initialization. */ |
InitMac(); |
SysEnvirons(1, &theWorld); |
if (theWorld.systemVersion < 0x0700) { |
NeedSystem7Dlog(); |
ExitToShell(); |
} |
InitTestGlobals(); |
InitAppMenus(); |
/* Initialize all of the app's windows' structures. */ |
InitTestWindowAttributes(); |
InitColorSettings(); |
InitRgnSettings(); |
/* If there is not enough memory to bring up windows exit. */ |
if (CreateTestWindows()) |
MainLoop(); |
DisposeRgnSettings(); |
DisposeTestWindows(); |
ExitToShell(); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-10-10