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.
Main.c
/***************************************************************** |
Program: < ATP Demo > |
File: < Main.c > |
Written by Scott Kuechle |
of <Apple Macintosh Developer Technical Support> |
10/92 SRK created |
8/94 SRK Modified to use a queue of parameter |
blocks. |
Copyright © 1992, 1994 Apple Computer, Inc. |
All rights reserved. |
*****************************************************************/ |
/*****************************************************************/ |
/* I N C L U D E S |
/*****************************************************************/ |
#include "ATP Demo.h" |
#include "ATP Demo.protos" |
/******************************************************************** |
/* G L O B A L V A R I A B L E D E C L A R A T I O N S |
/********************************************************************/ |
DialogPtr myDialog; |
Boolean gHasWaitNextEvent,gInBackground,gGrowRect,gStopped,gStopRect,gGoRect,gHasSystem7; |
Boolean gATPEntityFilter; |
Boolean gReqClockTime,gSingleRequest,gStopRequests; |
MenuHandle ZoneMenu,ObjectMenu,TypeMenu; |
short LastZoneMenuChoice,LastTypeMenuChoice,LastObjectMenuChoice; |
SysEnvRec gMac; |
MenuHandle DataSizeMenu; |
Handle gTestDataHdl; |
long gTestDataSize; |
/*****************************************************************/ |
/* |
/* E X T E R N A L S |
/* |
/*****************************************************************/ |
extern Boolean SendReqToTarget(); |
extern void initializeATP(); |
extern void removeMyName(); |
extern void ATPLoop(); |
extern OSErr InitAppleTalk(); |
extern Boolean ATPZoneRequest (MenuHandle zoneMenu); |
extern void LookupNames (MenuHandle lookupMenu, |
Boolean doObjects); |
extern void GetZones(); |
extern void GetOurZone(); |
extern Str255 gZoneString,gTypeStr,gObjStr,gDataSizeStr; |
extern short gMenuItem; |
extern void removeATP(); |
extern void doGetRequest(ATPPBPtr atpPBPtr, |
char socket, |
short reqLength, |
Ptr reqPointer); |
extern void DisplayStatusString(short whichString,Ptr displayStr); |
extern QHdr gAvailQueue; |
extern char gOurATPSocket; |
#pragma segment Main |
// ***************************************************************** |
// * CopyPstr |
// * |
// * copies a pascal string |
// ***************************************************************** |
void CopyPstr(Ptr pSource, Ptr pDest) |
{ |
BlockMove(pSource, pDest, pSource[0]+1); |
} |
// ***************************************************************** |
// * PStrCat |
// * |
// * appends pascal string sourceStr, to pascal string destinationStr. |
// * Overflow is checked, and the copy halts if the destination |
// * string is filled. |
// ***************************************************************** |
void PStrCat(Ptr sourceStr, Ptr destinationStr) |
{ |
unsigned int srcIndex, dstIndex; |
unsigned int bytesToCopy; |
srcIndex = 1; |
dstIndex = destinationStr[0] + 1; |
bytesToCopy = sourceStr[0]; |
while(bytesToCopy > 0 && dstIndex < 255) |
{ |
destinationStr[dstIndex] = sourceStr[srcIndex]; |
dstIndex++; |
srcIndex++; |
bytesToCopy--; |
} |
destinationStr[0] = dstIndex - 1; |
} |
// ***************************************************************** |
// * 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. |
// ***************************************************************** |
void DoActivate (WindowPtr window, Boolean becomingActive) |
{ |
#pragma unused (window,becomingActive) |
} /*DoActivate*/ |
// ***************************************************************** |
// * ShowError |
// * |
// * Our routine for displaying an error message in a dialog box. |
// ***************************************************************** |
void ShowError(short index) |
{ |
short itemHit; |
switch (index) |
{ |
case atalkErr: |
ParamText("\perror loading AppleTalk drivers!","\p","\p","\p"); |
break; |
case memErr: |
ParamText("\pmemory error.","\p","\p","\p"); |
break; |
case menuErr: |
ParamText("\perror initializing menus.","\p","\p","\p"); |
break; |
case nbpErr: |
ParamText("\pCouldn't register our name on the network (duplicate already exists).","\p","\p","\p"); |
break; |
case noTargetErr: |
ParamText("\ptarget not found.","\p","\p","\p"); |
break; |
case badROMsErr: |
ParamText("\pYour machine does not have at least 128K ROMs.","\p","\p","\p"); |
break; |
case heapErr: |
ParamText("\pNot enough heap space.","\p","\p","\p"); |
break; |
case noMemErr: |
ParamText("\pNot enough memory.","\p","\p","\p"); |
break; |
case DrvrErr: |
ParamText("\pFatal Device Manager error.","\p","\p","\p"); |
break; |
case SktErr: |
ParamText("\pError opening a socket.","\p","\p","\p"); |
break; |
case RsrcErr: |
ParamText("\pError getting program resources.","\p","\p","\p"); |
break; |
case dataNotValidErr: |
ParamText("\pTest data received was not valid.","\p","\p","\p"); |
break; |
case dataIsValid: |
ParamText("\pTest data received is correct!","\p","\p","\p"); |
break; |
} |
itemHit = Alert(rErrorDialog, nil); |
} |
// ***************************************************************** |
// * FatalError |
// * |
// * This is called when we detect that we cannot operate in the |
// * current environment. |
// ***************************************************************** |
void FatalError(error) |
short error; |
{ |
ShowError(error); |
ExitToShell(); |
} |
// ***************************************************************** |
// * IsAppWindow |
// * |
// * Tells us whether or not a window is an application window |
// * |
// ***************************************************************** |
Boolean IsAppWindow(window) |
WindowPtr window; |
{ |
short windowKind; |
if ( window == nil ) |
return false; |
else { /* application windows have windowKinds >= userKind (8) or dialogKind (2) */ |
windowKind = ((WindowPeek) window)->windowKind; |
return (windowKind >= userKind) || (windowKind == dialogKind); |
} |
} /* IsAppWindow */ |
// ***************************************************************** |
// * IsDAWindow |
// * |
// * Check if a window belongs to a desk accessory. |
// ***************************************************************** |
Boolean IsDAWindow(WindowPtr window) |
{ |
if (window == nil) |
return false; |
else /* DA windows have negative windowKinds */ |
return((((WindowPeek)window)->windowKind < 0) ? true : false); |
} /*IsDAWindow*/ |
// ***************************************************************** |
// * DoCloseWindow |
// * |
// * Close a window. This handles only desk accessory windows because we do not |
// * allow our window to be closed. TESample provides an example of how to handle |
// * the closing of application windows. |
// ***************************************************************** |
void DoCloseWindow (WindowPtr window) |
{ |
if (IsDAWindow(window)) |
CloseDeskAcc(((WindowPeek)window)->windowKind); |
} /*DoCloseWindow*/ |
// ***************************************************************** |
// * outlinePopUpMenus |
// * |
// * this is a group routine for drawing the popup menu outlines |
// * compleat with drop shadow. the menu title is draw to the left |
// * of the popUp item itself by this routine. |
// ***************************************************************** |
void outlinePopUpMenus (WindowPtr whichWindow, Rect r, Str255 itemString) |
{ |
FrameRect(&r); |
MoveTo(r.left + 2, r.bottom); |
LineTo(r.right, r.bottom); |
MoveTo(r.right, r.bottom); |
LineTo(r.right, r.top + 2); |
InsetRect(&r, 1, 1); |
EraseRect(&r); |
InsetRect(&r, -1, -1); |
MoveTo(r.left + 5, r.top + 11); |
TextFont(geneva); |
TextSize(9); |
DrawString(itemString); |
drawPopUpTri(whichWindow, r); |
} |
// ***************************************************************** |
// * UpdateUserItems |
// * |
// * update procedure for the user items in our dialog. |
// ***************************************************************** |
pascal void UpdateUserItems (WindowPtr whichWindow, short theItem) |
{ |
GrafPtr savedPort; |
Rect r; |
short kind; |
Handle h; |
GetPort(&savedPort); |
SetPort(whichWindow); |
GetDItem(whichWindow, theItem, &kind, &h, &r); |
switch(theItem) |
{ |
case kzoneItemID: |
outlinePopUpMenus(whichWindow, r, gZoneString); |
break; |
case ktypeItemID: |
outlinePopUpMenus(whichWindow, r, gTypeStr); |
break; |
case kobjectItemID: |
outlinePopUpMenus(whichWindow, r, gObjStr); |
break; |
case kPopupBorderID: |
UpdateItemBorder(theItem, r); |
break; |
case kClockTimeBorder: |
UpdateItemBorder(theItem, r); |
break; |
case kStatusText: |
break; |
} |
SetPort(savedPort); |
} |
// ***************************************************************** |
// * DoModeless |
// * |
// * this handles mouse clicks inside our main dialog |
// ***************************************************************** |
void DoModeless (DialogPtr whichDialog, short whichItem) |
{ |
Rect r; |
short kind; |
Handle h; |
MenuHandle allPurposeMenu; |
long chosen; |
Point pt; |
Str255 title; |
Boolean reqSent; |
if (whichDialog == myDialog) |
{ |
GetDItem(whichDialog, whichItem, &kind, &h, &r); |
switch(whichItem) |
{ |
case kzoneItemID: |
pt.v = r.top; |
pt.h = r.left + 1; |
LocalToGlobal(&pt); |
SetCursor(*(GetCursor(watchCursor))); |
allPurposeMenu = NewMenu(ZoneMenuID, ""); |
InsertMenu(allPurposeMenu, -1); |
GetZones(allPurposeMenu); |
InitCursor(); |
chosen = PopUpMenuSelect(allPurposeMenu, pt.v, pt.h, 1); |
if (chosen != 0) |
{ |
GetItem(allPurposeMenu, LoWord(chosen), gZoneString); |
gMenuItem = LoWord(chosen); |
CopyPstr("\p", gObjStr); |
InvalRect(&r); |
} |
InitCursor(); |
DeleteMenu(ZoneMenuID); |
DisposeMenu(allPurposeMenu); |
break; |
case ktypeItemID: |
if (gATPEntityFilter == false) |
{ |
pt.v = r.top - 2; |
pt.h = r.left + 1; |
LocalToGlobal(&pt); |
allPurposeMenu = NewMenu(TypeMenuID, ""); |
InsertMenu(allPurposeMenu, -1); |
SetCursor(*(GetCursor(watchCursor))); |
LookupNames(allPurposeMenu, false); |
InitCursor(); |
chosen = PopUpMenuSelect(allPurposeMenu, pt.v, pt.h, 1); |
if (chosen != 0) |
{ |
GetItem(allPurposeMenu, LoWord(chosen), gTypeStr); |
gMenuItem = LoWord(chosen); |
InvalRect(&r); |
} |
DeleteMenu(TypeMenuID); |
DisposeMenu(allPurposeMenu); |
} |
else |
SysBeep(1); |
break; |
case kobjectItemID: |
pt.v = r.top - 2; |
pt.h = r.left + 1; |
LocalToGlobal(&pt); |
allPurposeMenu = NewMenu(ObjectMenuID, ""); |
InsertMenu(allPurposeMenu, -1); |
SetCursor(*(GetCursor(watchCursor))); |
LookupNames(allPurposeMenu, true); |
InitCursor(); |
chosen = PopUpMenuSelect(allPurposeMenu, pt.v, pt.h, 1); |
if (chosen != 0) |
{ |
GetItem(allPurposeMenu, LoWord(chosen), gObjStr); |
gMenuItem = LoWord(chosen); |
InvalRect(&r); |
} |
DeleteMenu(ObjectMenuID); |
DisposeMenu(allPurposeMenu); |
break; |
case kMoofFilterCheckBox: |
if (gATPEntityFilter == false) |
{ |
SetCtlValue((ControlHandle)h,1); |
gATPEntityFilter = true; |
CopyPstr(atpEntityFilter, gTypeStr); |
} |
else |
{ |
SetCtlValue((ControlHandle)h,0); |
gATPEntityFilter = false; |
CopyPstr("\p", gTypeStr); |
} |
gObjStr[0] = 0; |
/* update type popup menu */ |
GetDItem(whichDialog, ktypeItemID, &kind, &h, &r); |
InvalRect(&myDialog->portRect); |
break; /* iMoofFilter */ |
case kReqDataButton: |
/* clear status string first */ |
ShowStatusString(kBlankText); |
GetControlTitle((ControlHandle)h,&title); |
/* Is button titled "Send Requests" ? */ |
if (IUCompPString(title,&kSendReqBtnText,nil) == 0) |
{ |
/* go ahead and send a request to the target */ |
reqSent = SendReqToTarget(); |
if (reqSent == true) |
{ |
/* haven't stopped continuous requests */ |
gStopRequests = false; |
/* is the continuous requests option set? */ |
if (gSingleRequest == false) |
{ /* reset button title to "Stop Requests" */ |
SetCTitle((ControlHandle)h, &kStopReqBtnText); |
} |
} |
} |
else /* reset button title to "Send Requests" */ |
{ |
gStopRequests = true; |
SetCTitle((ControlHandle)h, &kSendReqBtnText); |
} |
break; |
} /* of case */ |
} |
} |
// ***************************************************************** |
// * setEachUserItem |
// * |
// * sets the update routine for our dialogs user items |
// ***************************************************************** |
void setEachUserItem (short item) |
{ |
Rect r; |
short kind; |
Handle h; |
GetDItem(myDialog, item, &kind, &h, &r); |
SetDItem(myDialog, item, userItem, (Handle)UpdateUserItems, &r); |
} |
// ***************************************************************** |
// * HiliteSendReqButton |
// * |
// * set the state of the send request button |
// ***************************************************************** |
void HiliteSendReqButton (short mode) |
{ |
Rect r; |
short kind; |
Handle h; |
GetDItem(myDialog, kReqDataButton, &kind, &h, &r); |
HiliteControl((ControlHandle)h, mode); |
} |
// ***************************************************************** |
// * 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. |
// ***************************************************************** |
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; |
MenuHandle menu; |
menuID = HiWord(menuResult); /* use built-ins (for efficiency)...*/ |
menuItem = LoWord(menuResult); /*to get menu item number and menu number*/ |
switch (menuID) |
{ |
case mApple: |
switch(menuItem) |
{ |
case iAbout: /*bring up alert for About*/ |
itemHit = Alert(rAboutDialog, nil); |
break; |
default: |
/*all non-About items in this menu are DAs*/ |
GetItem(GetMHandle(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*/ |
{ |
if (IsDAWindow(FrontWindow())) |
handledByDA = SystemEdit(menuItem - 1); |
} |
break; |
case mRequestOptions: |
{ |
menu = GetMenuHandle(mRequestOptions); |
switch(menuItem) |
{ |
case iReqClockTime: |
gReqClockTime = true; |
SetItemMark(menu, iReqClockTime, checkMark); |
SetItemMark(menu, iReqData, noMark); |
break; |
case iReqData: |
gReqClockTime = false; |
SetItemMark(menu, iReqClockTime, noMark); |
SetItemMark(menu, iReqData, checkMark); |
break; |
case iSingleRequest: |
gSingleRequest = true; |
SetItemMark(menu, iSingleRequest, checkMark); |
SetItemMark(menu, iMultipleRequests, noMark); |
break; |
case iMultipleRequests: |
gSingleRequest = false; |
SetItemMark(menu, iSingleRequest, noMark); |
SetItemMark(menu, iMultipleRequests, checkMark); |
break; |
} |
} |
break; |
} |
HiliteMenu(0); /*unhighlight what MenuSelect (or MenuKey) hilited*/ |
} /*DoMenuCommand*/ |
// ***************************************************************** |
// * 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. |
// ***************************************************************** |
void AdjustMenus() |
{ |
WindowPtr window; |
MenuHandle menu; |
window = FrontWindow(); |
menu = GetMHandle(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 window*/ |
menu = GetMHandle(mEdit); |
if (IsDAWindow(window)) |
{ /*a desk accessory might need the undo item */ |
EnableItem(menu, iUndo); |
EnableItem(menu, iCut); |
EnableItem(menu, iCopy); |
EnableItem(menu, iPaste); |
EnableItem(menu, iClear); |
} |
else |
{ /* but we do not support undo!!! */ |
DisableItem(menu, iUndo); |
DisableItem(menu, iCut); |
DisableItem(menu, iCopy); |
DisableItem(menu, iPaste); |
DisableItem(menu, iClear); |
} |
} /*AdjustMenus*/ |
// ***************************************************************** |
// * Terminate |
// * |
// * if we need to quit the program, we remove the connection |
// * end (if any), deallocate any memory we used, remove our |
// * nbp name from the network and exit. |
// ***************************************************************** |
void Terminate() |
{ |
removeATP(); |
ExitToShell(); |
} |
// ***************************************************************** |
// * Exit |
// * |
// * this routine is called for fatal control call errors. We exit |
// * the program in this situation. |
// ***************************************************************** |
void Exit(short message) |
{ |
ShowError(message); |
Terminate(); |
} |
// ***************************************************************** |
// * DoIdleProc |
// * |
// * this routine is called each time through our event loop. We |
// * process any atpp errors that were returned and check for connections |
// * coming and going. |
// ***************************************************************** |
void DoIdleProc() |
{ |
ATPLoop(); |
} |
// ***************************************************************** |
// * 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. |
// ***************************************************************** |
void AdjustCursor (Point mouse, RgnHandle region) |
{ |
WindowPtr window; |
RgnHandle arrowRgn; |
RgnHandle ourRgn; |
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(); |
ourRgn = NewRgn(); |
/*start with a big, big rectangular region*/ |
SetRectRgn(arrowRgn, extremeNeg, extremeNeg, extremePos, extremePos); |
/*calculate ourRgn*/ |
if (IsAppWindow(window)) |
{ |
SetPort(window); /*make a global version of the portRect*/ |
SetOrigin(-window->portBits.bounds.left, -window->portBits.bounds.top); |
globalPortRect = window->portRect; |
RectRgn(ourRgn, &globalPortRect); |
SectRgn(ourRgn, window->visRgn, ourRgn); |
SetOrigin(0, 0); |
} |
/*subtract other regions from arrowRgn*/ |
DiffRgn(arrowRgn, ourRgn, arrowRgn); |
/*change the cursor and the region parameter*/ |
if (PtInRgn(mouse, ourRgn)) |
{ |
SetCursor(&qd.arrow); |
CopyRgn(arrowRgn, region); |
} |
/*get rid of our local regions*/ |
DisposeRgn(arrowRgn); |
DisposeRgn(ourRgn); |
} |
} /*AdjustCursor*/ |
// ***************************************************************** |
// * UpdateItemBorder |
// * |
// * re-draws the borders around our items |
// ***************************************************************** |
void UpdateItemBorder (short item, Rect r) |
{ |
FontInfo fInfo; |
Rect tRect; |
Str255 theBorderString; |
switch(item) |
{ |
case kPopupBorderID: |
strcpy(&theBorderString,"Select A Target Machine"); |
break; |
case kClockTimeBorder: |
strcpy(&theBorderString,"Clock Time From Target Machine"); |
break; |
default: |
break; |
} |
c2pstr(theBorderString); |
GetFontInfo(&fInfo); |
FrameRect(&r); |
MoveTo(r.left + 5, r.top + fInfo.ascent / 2 - 1); |
tRect.left = r.left + 4; |
tRect.right = tRect.left + StringWidth(theBorderString) + 1; |
tRect.top = r.top; |
tRect.bottom = r.top + 1; |
EraseRect(&tRect); |
DrawString(&theBorderString); |
} |
// ***************************************************************** |
// * PlotSICN |
// * |
// * this is the PlotSICN code stolen from Tech Note # |
// ***************************************************************** |
void PlotSICN (Rect theRect,SICNHand theSICN, short theIndex) |
{ |
SignedByte state; /* we want a chance to restore original state */ |
BitMap srcBits; /* built up around 'SICN' data so we can _CopyBits */ |
/* check the index for a valid value */ |
if ((GetHandleSize((Handle)theSICN) / sizeof(SICN)) > theIndex) |
{ |
/* store the resource's current locked/unlocked condition */ |
state = HGetState((Handle)theSICN); |
/* lock the resource so it won't move during the _CopyBits call */ |
HLock((Handle)theSICN); |
/* set up the small icon's bitmap */ |
/*$PUSH*/ |
/*$R-*/ |
/* turn off range checking */ |
srcBits.baseAddr = (Ptr)(&(**theSICN[theIndex])); |
/*$POP*/ |
srcBits.rowBytes = 2; |
SetRect(&srcBits.bounds, 0, 0, 16, 16); |
/* draw the small icon in the current grafport */ |
CopyBits(&srcBits, &qd.thePort->portBits, &srcBits.bounds, &theRect, srcCopy, nil); |
/* restore the resource's locked/unlocked condition */ |
HSetState((Handle)theSICN, state); |
} |
} |
// ***************************************************************** |
// * drawPopUpTri |
// * |
// * this procedure draws the new "standard" SICN triangle now used |
// * in popup menus I guess the drop shadow was not enough of an |
// * indiciation to the users of the presence of the pop-up. |
// * standard in 7.0 and up systems |
// ***************************************************************** |
void drawPopUpTri (WindowPtr whichWindow, Rect r) |
{ |
#pragma unused (whichWindow) |
Handle popUpTri; |
Rect popUpTriRect; |
popUpTri = GetResource('SICN', kStandardTriSICN); |
if (popUpTri) |
{ |
popUpTriRect = r; |
popUpTriRect.right = popUpTriRect.right - 1; |
popUpTriRect.left = popUpTriRect.right - 16; |
popUpTriRect.top = popUpTriRect.top + 1; |
popUpTriRect.bottom = popUpTriRect.top + 16; |
PlotSICN(popUpTriRect, (SICNHand)popUpTri, 0); |
ReleaseResource(popUpTri); |
} |
} |
// ***************************************************************** |
// * DoEvent |
// * |
// * Do the right thing for an event. Determine what kind of event it is, and call |
// * the appropriate routines. |
// ***************************************************************** |
void DoEvent (EventRecord event) |
{ |
short part; |
char key; |
WindowPtr whichWindow; |
whichWindow = FrontWindow(); |
switch(event.what) |
{ |
case nullEvent: |
break; |
case mouseDown: |
part = FindWindow(event.where, &whichWindow); |
if (part != 0) |
{ |
switch(part) |
{ |
case inMenuBar: |
/*process the menu command*/ |
AdjustMenus(); |
DoMenuCommand(MenuSelect(event.where)); |
break; |
case inSysWindow: /*let the system handle the mouseDown*/ |
SystemClick(&event, whichWindow); |
break; |
case inContent: |
if (whichWindow != FrontWindow()) |
SelectWindow(whichWindow); |
break; |
case inDrag: /*pass screenBits.bounds to get all gDevices*/ |
DragWindow(whichWindow, event.where, &qd.screenBits.bounds); |
break; |
case inGrow: |
break; |
case inZoomIn: |
case inZoomOut: |
break; |
} |
} |
break; |
case keyDown: |
case autoKey: |
/*check for menukey equivalents*/ |
key = (char)(event.message & charCodeMask); |
if ((event.modifiers & cmdKey) != 0) /*Command key down*/ |
{ |
if ((event.what == keyDown) || (event.what == autoKey)) |
{ |
AdjustMenus(); /*enable/disable/check menu items properly*/ |
DoMenuCommand(MenuKey(key)); |
} |
} |
break; /*call DoActivate with the window and...*/ |
case activateEvt: /*true for activate, false for deactivate*/ |
DoActivate((WindowPtr)event.message, (event.modifiers & activeFlag) != 0); |
break; |
case updateEvt: |
break; |
case osEvent: |
switch(event.message >> 24) /*high byte of message*/ |
{ |
case suspendResumeMessage: |
gInBackground = (event.message & resumeMask) == 0; |
DoActivate(FrontWindow(), !gInBackground); |
break; |
} |
} |
} /*DoEvent*/ |
// ***************************************************************** |
// * 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. |
// ***************************************************************** |
void EventLoop() |
{ |
RgnHandle cursorRgn; |
Boolean gotEvent; |
EventRecord event; |
long sleepTime; |
WindowPtr whichDialog; |
short whichItem; |
cursorRgn = NewRgn(); /*weÕll pass WNE an empty region the 1st time thru*/ |
sleepTime = 15; |
do |
{ |
if (gHasWaitNextEvent) /*put us 'asleep' forever under MultiFinder*/ |
{ |
gotEvent = WaitNextEvent(everyEvent, &event, sleepTime, cursorRgn); |
} |
else |
{ |
SystemTask(); /*must be called if using GetNextEvent*/ |
gotEvent = GetNextEvent(everyEvent, &event); |
} |
DoIdleProc(); |
AdjustCursor(event.where, cursorRgn); /*make sure we have the right cursor*/ |
whichDialog = FrontWindow(); |
/* don't pass command keys or <enter> keys to our dialog */ |
if(!((event.what==keyDown)&&(event.modifiers & cmdKey)) && (IsDialogEvent(&event))) |
{ |
if (DialogSelect(&event, &whichDialog, &whichItem)) |
DoModeless(whichDialog, whichItem); |
} |
else |
DoEvent(event); |
} |
while (true); /*loop forever; we quit through an ExitToShell*/ |
} |
// ***************************************************************** |
// * Main |
// * |
// ***************************************************************** |
main() |
{ |
MaxApplZone(); /*expand the heap so code segments load at the top*/ |
CheckEnvirons(); /*check for some basic requirements; exits if not met*/ |
InitGraf(&qd.thePort); |
InitFonts(); |
InitWindows(); |
InitMenus(); |
TEInit(); |
InitDialogs(nil); |
InitCursor(); |
if (InitAppleTalk() != noErr) |
{ |
ShowError(atalkErr); |
ExitToShell(); |
} |
else |
{ |
Initialize(); /*initialize the program*/ |
UnloadSeg(&Initialize); /*note that Initialize must not be in Main!*/ |
EventLoop(); /*call the main event loop*/ |
} |
} |
#pragma segment Initialize |
// ***************************************************************** |
// * 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. |
// ***************************************************************** |
Boolean TrapAvailable(tNumber,tType) |
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) != GetTrapAddress(_Unimplemented); |
} /*TrapAvailable*/ |
// ***************************************************************** |
// * SetupUserItems |
// * |
// ***************************************************************** |
void SetupUserItems() |
{ |
setEachUserItem(kzoneItemID); |
setEachUserItem(ktypeItemID); |
setEachUserItem(kobjectItemID); |
setEachUserItem(kPopupBorderID); |
setEachUserItem(kClockTimeBorder); |
} |
// ***************************************************************** |
// * Initialize |
// * |
// * program initialization |
// ***************************************************************** |
void Initialize() |
{ |
Rect r; |
short kind; |
Handle h; |
Handle menuBar; |
DialogPeek dp; |
ATPPBPtr atpPBPtr; |
myATPParamBlockPtr myATPPBPtr; |
MenuHandle menu; |
gInBackground = false; |
gZoneString[0] = 0;gTypeStr[0] = 0;gObjStr[0] = 0; |
GetOurZone(); |
/* we will allocate our own window storage instead of letting the Window */ |
/* Manager do it because GetNewWindow may load in temp. resources before */ |
/* making the NewPtr call, and this can lead to heap fragmentation. */ |
myDialog = (DialogPtr)(NewPtr(sizeof(DialogRecord))); |
if (myDialog == nil) |
Exit(memErr); |
myDialog = GetNewDialog(rDialog, (Ptr)myDialog, (DialogPtr)-1); |
SetPort(myDialog); |
dp = (DialogPeek)myDialog; |
TextFont(geneva); |
TextSize(9); |
SetWTitle(myDialog, "\pATP"); |
ShowWindow(myDialog); |
LastZoneMenuChoice = 0; |
LastTypeMenuChoice = 0; |
LastObjectMenuChoice = 0; |
SetupUserItems(); |
/* turn on type entity filter (check box) initially */ |
GetDItem(myDialog, kMoofFilterCheckBox, &kind, &h, &r); |
SetCtlValue((ControlHandle)h,1); |
gATPEntityFilter = true; |
CopyPstr(atpEntityFilter, gTypeStr); |
gObjStr[0] = 0; |
menuBar = GetNewMBar(rMenuBar); /*read menus into menu bar*/ |
if (menuBar == nil) |
Exit(menuErr); |
SetMenuBar(menuBar); /*install menus*/ |
DisposHandle(menuBar); |
AddResMenu(GetMHandle(mApple), 'DRVR'); /*add DA names to Apple menu*/ |
DrawMenuBar(); |
/* initialize our "Request Options" menu */ |
menu = GetMenuHandle(mRequestOptions); |
gReqClockTime = true; |
SetItemMark(menu, iReqClockTime, checkMark); |
gSingleRequest = false; |
SetItemMark(menu, iMultipleRequests, checkMark); |
gStopRequests = false; |
initializeATP(); |
gTestDataHdl = GetResource(kTestDataType,kTestDataRsrcID); |
if (gTestDataHdl == NULL) |
Exit(RsrcErr); |
gTestDataSize = MaxSizeRsrc(gTestDataHdl); |
atpPBPtr = GetQElement(&gAvailQueue); |
if (atpPBPtr != NULL) |
{ |
myATPPBPtr = GetOurPBPtr(atpPBPtr); |
/* issue a get request so that we may receive requests from |
other machines */ |
doGetRequest(atpPBPtr, |
gOurATPSocket, |
sizeof(struct ourReqData), |
myATPPBPtr->reqData); |
} |
else |
/* ???????????????????????? */; |
} /*Initialize*/ |
// ***************************************************************** |
// * CheckEnvirons |
// * |
// * check the current operating environment |
// ***************************************************************** |
void CheckEnvirons() |
{ |
long total, contig, response; |
OSErr ignoreError; |
/* ignore the error returned from SysEnvirons; even if an error occurred,*/ |
/* the SysEnvirons glue will fill in the SysEnvRec*/ |
ignoreError = SysEnvirons(sysEnvironsVersion, &gMac); |
/* Make sure that the machine has at least 128K ROMs. If it doesn't, exit. */ |
if (gMac.machineType < 0) FatalError(9); |
if ((long) GetApplLimit() - (long) ApplicZone() < kMinHeap) FatalError(10); |
PurgeSpace(&total, &contig); |
if (total < kMinSpace) |
if (UnloadScrap() != noErr) |
FatalError(11); |
else |
{ |
PurgeSpace(&total, &contig); |
if (total < kMinSpace) |
FatalError(11); |
} |
/* verify if WaitNextEvent, Gestalt and PPCToolbox are available */ |
gHasWaitNextEvent = TrapAvailable(_WaitNextEvent, ToolTrap); |
if (TrapAvailable(_Gestalt, ToolTrap)) |
{ /* verify if system 7.0 */ |
Gestalt(gestaltSystemVersion,&response ); |
if (response >= 0x0700) |
gHasSystem7 = true; |
else gHasSystem7 = false; |
} |
else |
{ |
SysBeep(20); |
gHasSystem7 = false; |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14