home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------------------------------------------------
- # Modified for LightSpeed C by R. Mark Fleming Jan. 30, 1990
- #
- # Apple Macintosh Developer Technical Support
- #
- # AppleTalk GetZoneList Sample Application
- #
- # GetZoneList
- #
- # GetZoneList.c - C Source
- #
- # Copyright © 1989 Apple Computer, Inc.
- # All rights reserved.
- #
- # Versions: 1.0 11/88
- # 1.1 10/89
- #
- # Components: GetZoneList.p October 1, 1989
- # GetZoneList.c October 1, 1989
- # GetZoneList.r October 1, 1989
- # PGetZoneList.make October 1, 1989
- # CGetZoneList.make October 1, 1989
- #
- # Requirements:
- # UFailure.p November 1, 1988
- # UFailure.inc1.p November 1, 1988
- # UFailure.a November 1, 1988
- #
- # GetZoneList is a sample application that uses
- # AppleTalk ATP and ZIP to obtain a list of zones
- # on an AppleTalk internet.
- #
- # GetZoneList also demonstrates using a signal, or
- # failure-catching mechanism to recover from error
- # situations. Since C does not allow nested procedures
- # a la Pascal, a few modifications were made to incorporate
- # the failure handling and keep this sample fairly close in
- # design to the Pascal sample.
- # (Gee, thanks a lot M2 for using nested procs. - pvh)
- #
- # GetZoneList is based on MACDTS Sample.c. For more
- # description and explanation of the non-example
- # specific areas of this application, please refer to
- # either Sample.p or TESample.c.
- # PSendRequest() & GetBridgeAddress() - nAppleTalk library
- ------------------------------------------------------------------------------ */
- #include "MyExceptionHandler.h"
- #include "GetZoneInclude.h"
-
- /* Globs */
- SysEnvRec gMac; /* set up by Initialize */
- Boolean gHasWaitNextEvent; /* set up by Initialize */
- Boolean gInBackground; /* maintained by Initialize and DoEvent */
-
- ListHandle gList; /* the list to be filled with zone names */
-
- /* globals added for C sample use as the Pascal
- example used those horrid :-) nested procedures! */
- ATPPBPtr gATPPBPtr; /* the parameter block for GetZoneList call */
- Ptr gZones; /* the data buffer for GetZoneList call */
- DialogPtr gErrDlg; /* Dialog used for displaying zone list */
-
- Boolean TrapAvailable(short, int);
-
- void FailOSErrMsg(result, message)
- short result;
- short message;
- {
- if (result != noErr) Failure(result, message);
- } /* SignalOSErrMsg */
-
-
- void FailnilMsg(p, message)
- Ptr p;
- short message;
- {
- if (p == nil) Failure(memFullErr, message);
- } /* FailNILMsg */
-
-
- void AlertUser(error, message)
-
- /* Display an alert to inform the user of an error. Message acts as an
- index into a STR# resource of error messages. if no message is given,
- i.e. = 0, then use a standard message. if error is not noErr then
- display it as well. */
-
- short error;
- long message;
- {
- Str255 msg1, msg2;
- short itemHit;
-
- if (message == 0L) message = eStandardErr;
- GetIndString(msg1, sErrStrings, message);
- if (error == noErr) msg2[0] = '';
- else NumToString(error, msg2);
- ParamText(msg1, msg2, "\p", "\p");
- itemHit = Alert(rUserAlert, nil);
- } /* AlertUser */
-
-
- Boolean IsDAWindow(window)
- WindowPtr window;
- {
- if (window == nil) return (false);
- else /* DA windows have negative windowKinds */
- return ((WindowPeek) window)->windowKind < 0;
- } /* IsDAWindow */
-
-
- 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 */
-
-
- void ZoneListCleanUp()
- {
- if (gATPPBPtr != nil)
- DisposPtr((Ptr)gATPPBPtr); /* get rid of pb block */
- if (gZones != nil) DisposPtr(gZones); /* and buffer */
- } /* ZoneListCleanUp */
-
-
- pascal void HandleZoneListErr(error, message)
- short error;
- long message;
- {
- ZoneListCleanUp(); /* get rid of allocated junk */
- } /* HandleZoneListErr */
-
-
- void BuildZoneList()
-
- /* Create the list of zones on the network. Find a bridge to talk to , if one is
- present, then ask it for zone names. Add the names to the list in the dialog. */
-
- {
- BDSElement dBDS; /* the BDS for GetZoneList call */
- Ptr dCurr; /* the data buffer for GetZoneList call */
- short dIndex, dCount;
- short ignore;
- Cell cSize;
-
- FailInfo fi;
-
- gATPPBPtr = nil; /* init some important variables*/
- gZones = nil;
-
- CatchCFailures(&fi, HandleZoneListErr);
-
- gATPPBPtr = (ATPPBPtr)NewPtr(sizeof(ATPParamBlock));
- FailnilMsg(gATPPBPtr, eNoMemory);
-
- gZones = NewPtr(kZonesSize);
- FailnilMsg(gZones, eNoMemory);
-
- dBDS.buffSize = kZonesSize; /* set up BDS */
- dBDS.buffPtr = gZones;
-
- gATPPBPtr->ATPatpFlags = 0;
-
- FailOSErrMsg(GetNodeAddress(&ignore, &gATPPBPtr->ATPaddrBlock.aNet), eAppleTalk); /* get net of bridge */
-
- if (gATPPBPtr->ATPaddrBlock.aNet == 0) Failure(0, eNoZones); /* bail if no zones present */
-
- gATPPBPtr->ATPaddrBlock.aNode = GetBridgeAddress(); /* get node of bridge */
- gATPPBPtr->ATPaddrBlock.aSocket = kZIPSocket; /* the socket we want */
- gATPPBPtr->ATPreqLength = 0;
- gATPPBPtr->ATPreqPointer = nil;
- gATPPBPtr->ATPbdsPointer = (Ptr) &dBDS;
- gATPPBPtr->ATPnumOfBuffs = 1;
- gATPPBPtr->ATPtimeOutVal = kATPTimeOutVal;
- gATPPBPtr->ATPretryCount = kATPRetryCount;
-
- dIndex = 1;
- dCount = 0;
- SetPt(&cSize, 0, 0); /* we always stuff into first */
-
- do {
- gATPPBPtr->ATPuserData = kGZLCall + dIndex; /* indicate GetZoneList request */
- FailOSErrMsg(PSendRequest(gATPPBPtr, false), eAppleTalk); /* send sync request */
-
- dCount = dCount + dBDS.userBytes & kZoneCount; /* find out how many returned */
- dCurr = gZones; /* put current pointer at start */
- do { /* get each zone */
- ignore = LAddRow(1, 0, gList); /* create new cell at start */
- LSetCell((Ptr)dCurr + 1L, (short) *dCurr, cSize, gList); /* stuff in zone */
- dCurr = (Ptr)(dCurr + *dCurr + 1 ); /* bump up current pointer */
- dIndex = dIndex + 1; /* increment which zone */
- } while(! (dIndex > dCount));
-
- } while ((dBDS.userBytes & kMoreZones) == 0); /* keep going until none left */
-
- ZoneListCleanUp();
-
- Success(&fi);
- } /* BuildZoneList */
-
-
- pascal void ZoneListDraw(dlg, item)
- DialogPtr dlg;
- short item;
- {
-
- /* The user item void for the zone list user item and default
- box user item in the dialog. Draw the list and the frame that goes with it.
- Draw the default box around the OK button */
-
- GrafPtr port;
- short kind;
- Handle h;
- Rect r;
- PenState ps;
-
- GetPort(&port); /* save old port */
- SetPort(dlg); /* make dialog port */
-
- switch (item) {
- case dZoneList:
- LUpdate(dlg->visRgn, gList); /* re-draw list */
- GetDItem(dlg, dZoneList, &kind, &h, &r);
- InsetRect(&r, kListInset, kListInset);
- FrameRect(&r); /* re-draw frame */
- break;
-
- case dDefault:
- GetDItem(dlg, dDefault, &kind, &h, &r);
- GetPenState(&ps);
- PenSize(3, 3);
- InsetRect(&r, -4, -4);
- FrameRoundRect(&r, 16, 16); /* draw default box */
- SetPenState(&ps);
- break;
- }
- SetPort(port); /* restore old port */
- } /* ZoneListDraw */
-
-
- pascal Boolean ListFilter (dlg, event, item)
- DialogPtr dlg;
- EventRecord *event;
- short *item;
- {
-
- /* Passed as parameter to ModalDialog. Handle key presses and mouse clicks
- from the user. Do all the right default actions since we override them
- by virtue of our existence. */
-
- GrafPtr port;
- Point loc;
- short kind;
- Handle h;
- Rect r;
- Boolean ignore;
- char key;
- long finalTicks;
-
- Boolean returnValue;
-
- returnValue = false; /* always default false */
-
- switch (event->what) {
- case keyDown: /* check for <cr> or <enter> */
- case autoKey:
- key = (char) event->message;
- if (key == kCR || key == kENTER) { /* it was a <cr> or <enter> */
- GetDItem(dlg, ok, &kind, &h, &r);
- HiliteControl((ControlHandle)h, kHilite);
- Delay(kHiliteDelay, &finalTicks);
- HiliteControl((ControlHandle)h, kDeHilite);
- returnValue = true; /* so we handle it */
- *item = 1; /* and make the first item hit */
- }
- break;
- case mouseDown: /* we want mouseDowns */
- GetPort(&port);
- SetPort(dlg);
- loc = event->where;
- GlobalToLocal(&loc); /* find where clicked */
- GetDItem(dlg, dZoneList, &kind, &h, &r); /* get rect for list */
- if (PtInRect(loc, &r)) { /* if clicked inside… */
- returnValue = true; /* we take care of it */
- ignore = LClick(loc, event->modifiers, gList); /* by passing click to list */
- }
- SetPort(port);
- break;
- }
- return (returnValue);
- } /* ListFilter */
-
-
- void CleanUp_DoZoneList()
- {
- if (gList != nil) LDispose(gList); /* get rid of list */
- if (gErrDlg != nil) DisposDialog(gErrDlg); /* get rid of dialog */
- } /* CleanUp_DoZoneList */
-
-
- pascal void HandleErr_DoZoneList(error, message)
- short error; long message;
- {
- CleanUp_DoZoneList(); /* release junk */
- } /* HandleErr_DoZoneList */
-
-
- void DoZoneList()
-
- /* Put up a modal dialog that shows a list of the zones on the net. Create the dialog
- and list, call BuildZoneList to fill it, then wait for the user to click OK. */
-
- {
- DialogPtr dlg;
- short item, kind;
- Handle h;
- Rect r, rView, dataBounds;
- Cell cSize;
- FailInfo fi;
- short hor, ver;
-
- gList = nil; /* init some important variables */
- dlg = nil;
-
- CatchCFailures(&fi, HandleErr_DoZoneList);
-
-
- dlg = GetNewDialog(rZoneDialog, nil, (WindowPtr)-1); /* create dialog */
-
- gErrDlg = dlg;
-
- FailnilMsg(dlg, eNoMemory);
-
- /* We center the dialog horizontally and position it vertically one-third the
- distance from the menu bar to the bottom of the main device. We do not
- check for the dialog extending past the bottom of the device because we
- know the dialog is not that big. You may wish to make that check. */
-
- hor = dlg->portRect.right - dlg->portRect.left;
-
- hor = ((screenBits.bounds.right - screenBits.bounds.left) - hor) / 2;
- ver = ((screenBits.bounds.bottom - screenBits.bounds.top) - GetMBarHeight()) / 3;
-
- MoveWindow(dlg, hor, ver, false);
-
- GetDItem(dlg, dDefault, &kind, &h, &r);
- SetDItem(dlg, dDefault, kind, (Handle) ZoneListDraw, &r);
- GetDItem(dlg, dZoneList, &kind, &h, &r);
- SetDItem(dlg, dZoneList, kind, (Handle) ZoneListDraw, &r); /* connect drawing void */
- rView = r;
- rView.right -= kScrollBarWidth; /* adjust rectangle for scroll */
- SetRect(&dataBounds, 0, 0, 1, 0); /* init to one-wide list */
- SetPt(&cSize, 0, 0);
- gList = LNew(&rView, &dataBounds, cSize, 0, (WindowPtr)dlg,
- false, false, false, true); /* create with vertical scroll */
- FailnilMsg(gList, eNoMemory);
- BuildZoneList(); /* put the stuff into the list */
- SetPt(&cSize, 0, 0);
- LSetSelect(true, cSize, gList); /* select the first guy */
- LDoDraw(true, gList); /* turn on the list */
- ShowWindow(dlg); /* turn on the dialog */
-
- do {
- ModalDialog((ModalFilterProcPtr) ListFilter, &item); /* accept events */
- } while (item != ok); /* until he presses 'ok' */
-
- CleanUp_DoZoneList();
-
- Success(&fi);
- } /* DoZoneList */
-
-
- Boolean DoCloseWindow(window)
- WindowPtr window;
- {
- Boolean functionValue = true;
-
- if (IsDAWindow(window))
- CloseDeskAcc((short) ((WindowPeek)window)->windowKind);
- else
- if (IsAppWindow(window)) CloseWindow(window);
-
- return(functionValue);
- } /* DoCloseWindow */
-
- 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)); /* do all windows */
- if (closed) ExitToShell(); /* exit if no cancellation */
- } /* Terminate */
-
-
- 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 traffic light window */
-
- menu = GetMHandle(mEdit);
- if (IsDAWindow(window)) { /* a desk accessory might need the edit menu */
- EnableItem(menu, iUndo);
- EnableItem(menu, iCut);
- EnableItem(menu, iCopy);
- EnableItem(menu, iPaste);
- EnableItem(menu, iClear);
- } else { /* but we know we do not */
- DisableItem(menu, iUndo);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iClear);
- DisableItem(menu, iPaste);
- }
- } /* AdjustMenus */
-
-
- pascal void HandleMenu(error, message)
- short error; long message;
- {
- HiliteMenu(0); /* unhighlight what MenuSelect (or MenuKey) hilited */
- } /* HandleMenu */
-
-
- void DoMenuCommand(menuResult)
- 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 ;
- Boolean ignore;
- FailInfo fi;
-
- CatchCFailures(&fi, (HandlerFuncPtr) HandleMenu);
-
- 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(rAboutAlert, 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 iNew:
- DoZoneList();
- break;
- case iClose:
- ignore = 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;
- }
-
- HiliteMenu(0); /* cleanup */
-
- Success(&fi);
- } /* DoMenuCommand */
-
- void AdjustCursor(mouse, region)
- Point mouse; RgnHandle region;
- {
-
- } /* AdjustCursor */
-
-
- pascal void HandleErr_DoEvent(error, message)
- short error;
- long message;
- {
- if (error > 0) AlertUser(0, error);
- else AlertUser(error, message);
- ExitToShell();
- } /* HandleErr_DoEvent */
-
-
- void DoEvent(event)
- EventRecord event;
- {
- short part;
- WindowPtr window;
- char key;
- FailInfo fi;
- Point aPoint;
- OSErr err;
-
- CatchCFailures(&fi, (HandlerFuncPtr) HandleErr_DoEvent);
-
- switch (event.what) {
- case mouseDown:
- part = FindWindow(event.where, &window);
- switch (part) {
- case inMenuBar: /* process the menu command */
- AdjustMenus();
- DoMenuCommand(MenuSelect(event.where));
- break;
- case inSysWindow: /* let the system handle the mouseDown */
- SystemClick(&event, window);
- break;
- case inContent:
- break;
- case inDrag:
- break;
- case inGrow:
- break;
- case inZoomIn:
- case inZoomOut:
- break;
- }
- break;
- case keyDown: /* check for menukey equivalents */
- case autoKey:
- key = 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;
- /* call DoActivate with the window and... */
- case activateEvt:
- break;
- case updateEvt:
- 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 (HiWord(event.message) != noErr) {
- SetPt(&aPoint, kDILeft, kDITop);
- err = DIBadMount(aPoint, event.message);
- }
- case kOSEvent:
- switch ((event.message >> 24) & 0x0FF) { /* high byte of message */
- case kSuspendResumeMessage:
- gInBackground = event.message & kResumeMask;
- break;
- }
- break;
- }
- Success(&fi);
- } /* DoEvent */
-
-
- void EventLoop()
- {
- RgnHandle cursorRgn;
- Boolean gotEvent;
- EventRecord event;
-
- cursorRgn = NewRgn(); /* we’ll pass WNE an empty region the 1st time thru */
-
- do {
- if (gHasWaitNextEvent) /* put us 'asleep' forever under Multifinder */
- gotEvent = WaitNextEvent(everyEvent, &event, MAXLONG, cursorRgn);
- else {
- SystemTask(); /* must be called if using GetNextEvent */
- gotEvent = GetNextEvent(everyEvent, &event);
- }
-
- if (gotEvent) {
- AdjustCursor(event.where, cursorRgn); /* make sure we have the right cursor */
- DoEvent(event);
- }
- AdjustCursor(event.where, cursorRgn);
- } while (true); /* loop forever; we quit through an ExitToShell */
- } /* EventLoop */
-
-
- void main()
- {
- MaxApplZone(); /* expand the heap so code segments load at the top */
-
- InitUFailure();
-
- Initialize(); /* initialize the program */
- UnloadSeg(Initialize); /* note that Initialize must not be in Main! */
-
- EventLoop(); /* call the main event loop */
- } /* main */
-