home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1990 / 12 / cheapcom.c < prev    next >
Text File  |  1990-07-09  |  40KB  |  1,498 lines

  1. /* 
  2.  
  3.     By Don Gaspar
  4.     
  5.     MOOSE, Inc. (Macintosh Object-Oriented Software Engineering)
  6.     10866 Northridge Square
  7.     Cupertino, CA 95014
  8.     (408)252-7576
  9.     
  10.     Tuesday, April 10, 1990                Added MultiFinder support.
  11.                                                             by Don T. Gaspar
  12.     
  13.     Wednesday, April 11, 1990        Added scrollbars and DoGrowWindow
  14.                                                             by Don T. Gaspar
  15.     
  16.     Wednesday, April 25, 1990        Started adding the buffer, and invoking the basics
  17.                                                             to add saving selections/sessions. This is not
  18.                                                             completed yet.
  19.                                                             by Don T. Gaspar
  20.                                                 
  21. */
  22.  
  23.  
  24.     /* These are the standard Mac includes for all managers */
  25.  
  26. #include <values.h>
  27. #include <types.h>
  28. #include <Resources.h>
  29. #include <QuickDraw.h>
  30. #include <fonts.h>
  31. #include <events.h>
  32. #include <windows.h>
  33. #include <menus.h>
  34. #include <textedit.h>
  35. #include <dialogs.h>
  36. #include <Controls.h>
  37. #include <desk.h>
  38. #include <toolutils.h>
  39. #include <memory.h>
  40. #include <Lists.h>
  41. #include <SegLoad.h>
  42. #include <Files.h>
  43. #include <Packages.h>
  44. #include <OSEvents.h>
  45. #include <OSUtils.h>
  46. #include <DiskInit.h>
  47. #include <Traps.h>
  48. #include <String.h>
  49. #include <Strings.h>
  50.  
  51. #include <CRMIntf.h>                                                        // Communications Resource Manager stuff
  52. #include <CMIntf.h>                                                        // Connection Manager stuff
  53. #include <FTIntf.h>                                                            // File Transfer Manager stuff
  54. #include <TMIntf.h>                                                        // Terminal Manager stuff
  55. #include <CTBUtils.h>                                                    // Communications Toolbox Utility stuff
  56.  
  57. #include <Errors.h>
  58. #include <Limits.h>
  59. #include <Traps.h>
  60.  
  61. #include "CommTypes.h"                                                // our communications types, etc.
  62. #include "CheapComm.h"                                                    // our constants, forward declarations, etc.
  63.  
  64. /*     Here's our global variables, dude!    */
  65. Boolean                gHasWaitNextEvent;                            // does user machine have WaitNextEvent????
  66. Boolean                gInBackground;                                    // are we in the background????
  67. Boolean                gStopped;                                                // are we stopped????
  68.     
  69. TermHandle        gTerm;                                                    // handle to terminal record
  70. ConnHandle        gConn;                                                    // handle to connection record
  71. FTHandle            gFT;                                                        // handle to file transfer record
  72.  
  73. Ptr                        gBuffer;                                                    // global connection buffer
  74.  
  75. long                    gFTSearchRefNum;
  76. Boolean                gStartFT;                                                // are we doing a file transfer????
  77. Boolean                gWasFT;                                                // was a file transfer in progress????
  78.  
  79. short                    gDummy;
  80.  
  81. Handle                gCache;                                                    // buffer for the last terminal line recdeived/sent
  82. TEHandle                gTE;                                                        // buffer for terminal emulator
  83.  
  84. ControlHandle    gScrollHHandle, gScrollVHandle;    // our scroll bars in the terminal window
  85.  
  86. #pragma segment Initialize
  87. /* Checks to see if a given trap is implemented */
  88. Boolean    TrapAvailable(tNumber,tType)
  89.     short            tNumber;
  90.     TrapType    tType;
  91. {
  92.     short    unImplemented;
  93.     
  94.     if (tType == OSTrap)
  95.         unImplemented = _UnimplementedOSTrap;
  96.     else
  97.         unImplemented = _UnimplementedToolTrap;
  98.         
  99.     return(NGetTrapAddress(tNumber,tType) != GetTrapAddress(unImplemented));
  100. }
  101.  
  102. #pragma segment Main
  103. /*    Sends the data out via the choosen connection */
  104. pascal long    TermSendProc(thePtr, theSize, refCon, flags)
  105.     Ptr            thePtr;
  106.     long        theSize;
  107.     long        refCon;
  108.     short        flags;
  109. {
  110.     CMErr    theErr;
  111.     long        termSendProc = 0L;
  112.     
  113.     if (gConn != nil) {
  114.         theErr = CMWrite(gConn,thePtr,&theSize,cmData,false,nil,0,flags);
  115.         if (theErr == noErr)
  116.             termSendProc = theSize;
  117.     }
  118.     return(termSendProc);
  119. }
  120.  
  121. #pragma segment Main
  122. /*  Gets the data from the connection tool and sends it to the terminal tool */
  123. pascal void TermRecvProc()
  124. {
  125.     CMErr                theErr;
  126.     CMStatFlags    status;
  127.     CMBufferSizes    sizes;
  128.     short                    flags;
  129.     
  130.     if (gConn != nil && gTerm != nil) {
  131.         theErr = CMStatus(gConn, sizes, &status);
  132.         
  133.         if (theErr == noErr) {
  134.             if ((status & (cmStatusOpen+cmStatusDataAvail)) != 0 && sizes[cmDataIn] != 0) {
  135.                 if (sizes[cmDataIn] > kBufferSize)
  136.                     sizes[cmDataIn] = kBufferSize;
  137.                 
  138.                 theErr = CMRead(gConn, gBuffer, &sizes[cmDataIn], cmData, false, nil, 0, &flags);
  139.                 
  140.                 if (theErr  == noErr)    // give it to the terinal emulation buffer
  141.                     sizes[cmDataIn] = TMStream(gTerm, gBuffer, sizes[cmDataIn], flags);
  142.             }
  143.         }
  144.         else
  145.             ;                    // Connection Manager will handle this for us
  146.     }
  147. }
  148.  
  149. #pragma segment Main
  150. /* Gets the connection environments for the FT or Term tool */
  151. pascal OSErr    ToolGetConnEnvirons(refCon, theEnvirons)
  152.     long                        refCon;
  153.     ConnEnvironRec    *theEnvirons;
  154. {
  155.     OSErr        toolGetConnEnvirons = envNotPresent;
  156.     
  157.     if(gConn != nil)
  158.         toolGetConnEnvirons = CMGetConnEnvirons(gConn,theEnvirons);
  159.         
  160.     return(toolGetConnEnvirons);
  161. }
  162.  
  163. #pragma segment Main
  164. /* Sends the data during a file transfer */
  165. pascal long    FTSendProc(thePtr, theSize, refCon, channel, flags)
  166.     Ptr                    thePtr;
  167.     long                theSize;
  168.     long                refCon;
  169.     CMChannel    channel;
  170.     short                flags;
  171. {
  172.     CMErr    theErr;
  173.     long        ftSendProc = 0L;
  174.     
  175.     if (gConn != nil) {
  176.         theErr = CMWrite(gConn, thePtr,& theSize, channel, false, nil, 0, flags);
  177.         
  178.         if(theErr == noErr)
  179.             ftSendProc = theSize;
  180.     }
  181.     return(ftSendProc);
  182. }
  183.  
  184. #pragma segment Main
  185. /* Gets the data during a data transfer */
  186. pascal long    FTReceiveProc(thePtr, theSize, refCon, channel, flags)
  187.     Ptr                    thePtr;
  188.     long                theSize;
  189.     long                refCon;
  190.     CMChannel    channel;
  191.     short                *flags;
  192. {
  193.     CMErr        theErr;
  194.     long            ftReceiveProc = 0L;
  195.     
  196.     if (gConn != nil) {
  197.         theErr = CMRead(gConn, thePtr, &theSize, channel, false, nil, 0, flags);
  198.         if (theErr == noErr)
  199.             ftReceiveProc = theSize;
  200.     }
  201.     return(ftReceiveProc);
  202. }
  203.  
  204. #pragma segment Main
  205. /* Sets the file transfer flag if an autoreceive string was found */
  206. pascal void AutoRecCallBack(theConn, data, refNum)
  207.     ConnHandle        theConn;
  208.     Ptr                        data;
  209.     long                    refNum;
  210. {
  211.     if (gFTSearchRefNum == refNum)
  212.         gStartFT = true;
  213. }
  214.  
  215. #pragma segment Main
  216. /* Checks to see if the file transfer has an autoreceive string, and then adds a
  217.     search to find it                                                                                                                */
  218. void AddFTSearch()
  219. {
  220.     Str255    tempStr;
  221.     
  222.     if (gFT != nil && gConn != nil) {
  223.         //tempStr = (*gFT)->autoRec;
  224.         
  225.         if ((*gFT)->autoRec[0] != 0) {
  226.             gFTSearchRefNum = CMAddSearch(gConn,(*gFT)->autoRec, cmSearchSevenBit,
  227.                 (ProcPtr)AutoRecCallBack);
  228.             if (gFTSearchRefNum == -1) {
  229.                 AlertUser("Couldn't add stream search\0", false);
  230.                 gFTSearchRefNum = 0;
  231.             }
  232.         }
  233.     }
  234. }
  235.  
  236. #pragma segment Main
  237. /* Initiates a file transfer send from the menu command */
  238. void DoSend()
  239. {
  240.     SFReply        theReply;
  241.     Point                where;
  242.     short                numTypes;
  243.     SFTypeList    typeList;
  244.     FTErr                anyErr;
  245.     
  246.     if(gFT != nil) {
  247.         SetPt(&where,100,100);
  248.         
  249.         if(((**gFT).attributes & ftTextOnly) != 0) {
  250.             typeList[0] = 'TEXT';
  251.             numTypes = 1;
  252.         }
  253.         else
  254.             numTypes = -1;
  255.         
  256.         sfgetfile(&where, "File to send", nil, numTypes, typeList, nil, &theReply);
  257.         
  258.         if(theReply.good) {
  259.             anyErr = FTStart(gFT, ftTransmitting, &theReply);
  260.             if(anyErr != noErr)
  261.                 ;                                    // file transfer tool will alert user
  262.         }
  263.     }
  264. }
  265.  
  266. #pragma segment Main
  267. /* Initiates a file transfer receive from the menu */
  268. void DoReceive()
  269. {
  270.     SFReply        theReply;
  271.     OSErr                anyErr;
  272.     
  273.     if (gFT != nil) {
  274.         theReply.vRefNum = 0;
  275.         //theReply.fName = '';
  276.         gStartFT = false;
  277.         
  278.         if (gConn != nil ) {
  279.             if ((**gFT).autoRec != "\0" && gFTSearchRefNum != 0) {
  280.                 CMRemoveSearch(gConn, gFTSearchRefNum);
  281.                 gFTSearchRefNum = 0;
  282.             }
  283.         }
  284.         
  285.         anyErr = FTStart(gFT, ftReceiving, &theReply);
  286.         
  287.         if(anyErr != noErr)
  288.             ;                                    // file transfer tool will alert the user
  289.     }
  290. }
  291.  
  292. #pragma segment Main
  293. /* checks to see if a window belongs to a DA */
  294. Boolean    IsDAWindow(window)
  295.     WindowPtr    window;
  296. {
  297.     if (window == nil)
  298.         return(false);
  299.     else 
  300.         return (((WindowPeek) window)->windowKind < 0);
  301. }
  302.  
  303. #pragma segment Main
  304. /* Adjust the scroll bars if the window need it */
  305. void AdjustScrollBars(OldRect,whichWindow)/* Resized this window */
  306.     Rect    *OldRect;                   /* Rect area */ 
  307.     WindowPtr    whichWindow;           /* Window that was resized */ 
  308. {
  309.     WindowPtr    SavePort;              /* Place to save the last port */
  310.     Rect    temp2Rect,tempRect;                  /* temp rectangle */
  311.     short    Index;                     /* temp integer */
  312.  
  313.     GetPort(&SavePort);             /* Save the current port */
  314.     SetPort(whichWindow);              /* Set the port to my window */
  315.     
  316.     if (gScrollHHandle != nil)       /* Only do if the control is valid */
  317.     {
  318.         HLock((Handle)gScrollHHandle);/* Lock the handle while we use it */
  319.         tempRect.left = (*gScrollHHandle)->contrlRect.left;/* the area to update */
  320.         tempRect.top = (*gScrollHHandle)->contrlRect.top - 4;/* Widen the area to update */
  321.         tempRect.right = (*gScrollHHandle)->contrlRect.right + 16;/* Widen the area to update */
  322.         tempRect.bottom = (*gScrollHHandle)->contrlRect.bottom;/* the area to update */
  323.         InvalRect(&tempRect);       /* Flag old position for update routine */
  324.         tempRect.top = (*gScrollHHandle)->contrlRect.top ;/*  */
  325.         tempRect.right = (*gScrollHHandle)->contrlRect.right ;/*  */
  326.         temp2Rect.left = whichWindow->portRect.left;/* Get window rectangle */
  327.         temp2Rect.top =  whichWindow->portRect.top ;/*  */
  328.         temp2Rect.right =  whichWindow->portRect.right ;/*  */
  329.         temp2Rect.bottom =  whichWindow->portRect.bottom;/*  */
  330.         Index = temp2Rect.right - temp2Rect.left - 13;/* Get the scroll area width */
  331.         tempRect.left = -1;         /* Pin at left edge */
  332.         HideControl(gScrollHHandle);/* Hide it during size and move */
  333.         SizeControl(gScrollHHandle, Index,16);/* Make it 16 pixels high, std width */
  334.         MoveControl(gScrollHHandle, tempRect.left,temp2Rect.bottom - temp2Rect.top-15);/* Size it correctly */
  335.         ShowControl(gScrollHHandle);/* Safe to show it now */
  336.         HUnlock((Handle)gScrollHHandle);/* Let it float again */
  337.     }                               /* End for scroll handle not nil)*/
  338.     
  339.     if (gScrollVHandle != nil)       /* Only do if the control is valid */
  340.     {
  341.         HLock((Handle)gScrollVHandle);/* Lock the handle while we use it */
  342.         tempRect.left = (*gScrollVHandle)->contrlRect.left-4;/* the area to update */
  343.         tempRect.top = (*gScrollVHandle)->contrlRect.top;/* Widen the area to update */
  344.         tempRect.right = (*gScrollVHandle)->contrlRect.right;/* Widen the area to update */
  345.         tempRect.bottom = (*gScrollVHandle)->contrlRect.bottom+16;/* the area to update */
  346.         InvalRect(&tempRect);       /* Flag old position for update routine */
  347.         tempRect.left = (*gScrollVHandle)->contrlRect.left;/* Get control rectangle */
  348.         tempRect.bottom = (*gScrollVHandle)->contrlRect.bottom;/*  */
  349.         temp2Rect.left = whichWindow->portRect.left;/* Get window rectangle */
  350.         temp2Rect.top =  whichWindow->portRect.top ;/*  */
  351.         temp2Rect.right =  whichWindow->portRect.right ;/*  */
  352.         temp2Rect.bottom =  whichWindow->portRect.bottom;/*  */
  353.         Index = temp2Rect.bottom - temp2Rect.top - 13;/* Get the scroll area height */
  354.         tempRect.top = -1;          /* Pin at top edge */
  355.         HideControl(gScrollVHandle);/* Hide it during size and move */
  356.         SizeControl(gScrollVHandle, 16,Index);/* Make it 16 pixels wide, std height */
  357.         MoveControl(gScrollVHandle, temp2Rect.right - temp2Rect.left-15,tempRect.top);/* Size it correctly */
  358.         ShowControl(gScrollVHandle);/* Safe to show it now */
  359.         HUnlock((Handle)gScrollVHandle);/* Let it float again */
  360.     }                               /* End for scroll handle not nil) */
  361.     
  362.     SetPort(SavePort);              /* Restore the old port */
  363. }                                                   /* End of function */
  364.  
  365.  
  366. #pragma segment Main
  367. /* Checks to see if the window belongs to our application */
  368. Boolean IsAppWindow(window)
  369.     WindowPtr    window;
  370. {
  371.     short        windowKind;
  372.     long        theRefCon;
  373.  
  374.     if ( window == nil )
  375.         return false;
  376.     else {    /* application windows have windowKinds >= userKind (8) or dialogKind (2) */
  377.     theRefCon = GetWRefCon(window);
  378.         windowKind = ((WindowPeek) window)->windowKind;
  379.         return ((windowKind >= userKind) || (windowKind == dialogKind)
  380.          & (gTerm != (TermHandle)theRefCon) & (gConn != (ConnHandle)theRefCon)
  381.          & (gFT != (FTHandle)theRefCon));
  382.     }
  383. } /*IsAppWindow*/
  384.  
  385. #pragma segment Main
  386. /* alerts the user of any errors that have occurred */
  387. void AlertUser(msg, fatal)
  388. char            *msg;
  389. Boolean        fatal;
  390. {
  391.     short    itemHit;
  392.     
  393.     SetCursor(&qd.arrow);
  394.     ParamText(c2pstr(msg),"","","");
  395.     itemHit = Alert(rUserAlert, nil);
  396.     
  397.     if (fatal)
  398.         Terminate();
  399. }
  400.  
  401. #pragma segment Main
  402. /* Initiates a connection */
  403. void OpenConnection()
  404. {
  405.     CMErr                theErr;
  406.     CMBufferSizes    sizes;
  407.     CMStatFlags    status;
  408.     
  409.     if(gConn != nil) {
  410.         theErr = CMStatus(gConn, sizes, &status);
  411.         
  412.         if(theErr == noErr) 
  413.             if((status & (cmStatusOpen + cmStatusOpening)) == 0)
  414.                 theErr =CMOpen(gConn, false, nil, -1);
  415.             
  416.             if (theErr != noErr)
  417.                 ;                                // connection tool will tell the uer if there's an errror
  418.     }
  419. }
  420.  
  421. #pragma segment Main
  422. /* Nukes the connection */
  423. void CloseConnection()
  424. {
  425.     CMErr                theErr;
  426.     CMBufferSizes    sizes;
  427.     CMStatFlags    status;
  428.     
  429.     if (gConn != nil) {
  430.         theErr = CMStatus(gConn, sizes, &status);
  431.         if(theErr == noErr)
  432.             if ((status & (cmStatusOpen+cmStatusOpening)) != 0)
  433.                 theErr = CMClose(gConn, false, nil ,0, true);
  434.         
  435.         if (theErr != noErr)
  436.             ;                                // connection tool will handle the error
  437.     }
  438. }
  439.  
  440. #pragma segment Main
  441. /* Closes our window */
  442. Boolean DoCloseWindow(window)
  443.     WindowPtr    window;
  444. {
  445.     Boolean        doCloseWindow = true;
  446.     
  447.     if(IsDAWindow(window))
  448.         CloseDeskAcc(((WindowPeek) window)->windowKind);
  449.     else if (IsAppWindow(window)) {
  450.         CloseConnection();
  451.         
  452.         if(gTerm != nil) {
  453.             HUnlock((Handle)gTerm);
  454.             TMDispose(gTerm);
  455.         }
  456.         
  457.         if(gFT != nil) {
  458.             HUnlock((Handle)gFT);
  459.             FTDispose(gFT);
  460.         }    
  461.         
  462.         if(gConn != nil) {
  463.             HUnlock((Handle)gConn);
  464.             CMDispose(gConn);
  465.         }
  466.         
  467.         if (gBuffer != nil)
  468.             DisposPtr(gBuffer);
  469.             
  470.         if(gCache != nil)
  471.             DisposHandle(gCache);
  472.         
  473.         if(gTE != nil)
  474.             TEDispose(gTE);
  475.             
  476.         DisposeWindow(window);
  477.             
  478.     }
  479.     return(doCloseWindow);
  480. }
  481.  
  482. #pragma segment Main
  483. /* tries to get the default tool proc ID, otherwise gets the first one it can find */
  484. short    FindToolID(toolClass)
  485.     OSType    toolClass;
  486. {
  487.     Str255    toolName;
  488.     OSErr        anyErr;
  489.     short        procID = -1;
  490.     
  491.     if (toolClass == classTM) {
  492.         StuffHex(&toolName,kDefaultTermTool);
  493.         procID = TMGetProcID(toolName);
  494.         
  495.         if(procID == -1) {
  496.             anyErr = CRMGetIndToolName(toolClass,1, toolName);
  497.             if (anyErr == noErr)
  498.                 procID = TMGetProcID(toolName);
  499.         }
  500.     }
  501.     else if (toolClass == classCM) {
  502.         StuffHex(&toolName,kDefaultConnTool);
  503.         procID = CMGetProcID(toolName);
  504.         
  505.         if(procID == -1) {
  506.             anyErr = CRMGetIndToolName(toolClass,1, toolName);
  507.             if (anyErr == noErr)
  508.                 procID = CMGetProcID(toolName);
  509.         }
  510.     }
  511.     
  512.     else if (toolClass == classFT) {
  513.         StuffHex(&toolName,kDefaultFTTool);
  514.         procID = FTGetProcID(toolName);
  515.         
  516.         if(procID == -1) {
  517.             anyErr = CRMGetIndToolName(toolClass,1, toolName);
  518.             if (anyErr == noErr)
  519.                 procID = FTGetProcID(toolName);
  520.         }
  521.     }
  522.     return(procID);
  523. }
  524.  
  525. #pragma segment Main
  526. /* this is the click loop for the terminal emulation to track */
  527. pascal Boolean clikLoop(refcon)
  528.     long    refcon;
  529. {
  530.     return(true);
  531. }
  532.  
  533. #pragma segment Initialize
  534. /* this function just sets up the CommToolbox for what we need;
  535.     it should resemble most of the other Macinotosh toolbox calls    */
  536. void InitCommTB()
  537. {
  538.     (void)InitCTBUtilities();        //    Comm Toolbox Utilities
  539.     (void)InitCRM();                        //    Communications Resource Manager
  540.     
  541.     //    initialize the Terminal Manager
  542.     if (InitTM() == tmNoTools)            //    Did we fail
  543.         AlertUser("No terminal tools found, dude!\0", true);
  544.     
  545.     //    Initialize the Connection Manager
  546.     if(InitCM()== cmNoTools)            //    failure????
  547.         AlertUser("No connection tools found, dude!\0", true);
  548.     
  549.     //    Initialize the File Transfer Manager
  550.     if(InitFT() == ftNoTools)                // failure????
  551.         AlertUser("No file transfer tools found, dude!\0",false);
  552.         
  553.     gTerm = nil;                            //    gotta initialize our globals
  554.     gConn = nil;
  555.     gFT = nil;
  556.     gCache = nil;
  557.     gFTSearchRefNum = 0;
  558. }
  559.  
  560. #pragma segment Main
  561. /*    this will cache all the data coming in through the serial port */
  562. pascal long cacheProc(refCon, theTermData)
  563.     long                        refCon;
  564.     TermDataBlock    *theTermData;
  565. {
  566.     long                        sizeCached;
  567.     TermEnvironRec    theEnvirons;
  568.     
  569.     theEnvirons.version = curTermEnvRecVers;
  570.     theEnvirons.termType = tmTextTerminal;
  571.     (void)TMGetTermEnvirons(gTerm, &theEnvirons);
  572.  
  573.     if (theTermData->theData == nil) 
  574.         return(-1);
  575.         
  576.     if(gCache != nil)                             //    is it valid????
  577.             DisposHandle(gCache);    //    nuke it, dude
  578.     
  579.     HLock((Handle)theTermData->theData);
  580.     
  581.     gCache = theTermData->theData;
  582.     
  583.     if(HandToHand(&gCache)) {
  584.             DisposHandle(gCache);
  585.             sizeCached = -1;
  586.         }
  587.         else {
  588.             sizeCached = GetHandleSize(gCache);
  589.         }
  590.     
  591.     HUnlock((Handle)theTermData->theData);
  592.     
  593.     if(theTermData->flags == tmTextTerminal && sizeCached >0L) {
  594.         /*HandAndHand(gCache, (**gTE).hText);
  595.         (**gTE).teLength += 80;
  596.         (**gTE).nLines += 1;*/
  597.         ((Ptr)*gCache,80L,gTE);
  598.         //(**gTE).viewRect.top -= (**gTE).lineHeight;
  599.         //(**gTE).destRect.top -= (**gTE).lineHeight;
  600.         //TECalText(gTE);
  601.         //TEScroll(0,-(**gTE).lineHeight,gTE);
  602.     }    
  603.     return(tmNoErr);
  604. }
  605.  
  606. #pragma segment Main
  607. /* gets the window and create the session */
  608. Boolean    DoNewWindow()
  609. {
  610.     WindowPtr        window;
  611.     Rect                    theRect;
  612.     short                    procID;
  613.     CMBufferSizes    sizes;
  614.     Rect                    tempRect;
  615.     short                    index;
  616.     Rect                    r;
  617.     
  618.     window = GetNewWindow(rWindow, nil, (WindowPtr)-1);
  619.     SetPort(window);
  620.     
  621. /*  Make a scroll bar, Scroll bar   */
  622.     SetRect(&tempRect,-1,241,392,257);
  623.     tempRect.left = window->portRect.left;
  624.     tempRect.right = window->portRect.right;
  625.     tempRect.top = window->portRect.top;
  626.     tempRect.bottom = window->portRect.bottom;
  627.     gScrollHHandle = GetNewControl(cHScrollBar,window);
  628.     index = tempRect.right - tempRect.left - 13;
  629.     tempRect.left = 0; 
  630.     SizeControl(gScrollHHandle, index,16);
  631.     MoveControl(gScrollHHandle, tempRect.left-1,tempRect.bottom - tempRect.top-15);
  632.     
  633.     /*  Make a scroll bar, Scroll bar   */
  634.     SetRect(&tempRect,391,-1,407,242);
  635.     tempRect.left = window->portRect.left;
  636.     tempRect.right = window->portRect.right;
  637.     tempRect.top = window->portRect.top;
  638.     tempRect.bottom = window->portRect.bottom;
  639.     gScrollVHandle = GetNewControl(cVScrollBar,window);
  640.     index = tempRect.bottom - tempRect.top - 13;
  641.     tempRect.top = 0;           
  642.     SizeControl(gScrollVHandle, 16,index);
  643.     MoveControl(gScrollVHandle, tempRect.right - tempRect.left-15,tempRect.top-1);
  644.     //SetCtlMax(gScrollVHandle,10000);
  645.     /* terminal tool */
  646.     procID = FindToolID(classTM);
  647.     if(procID == -1)
  648.         AlertUser("No terminal tools found, dude!\0", true);
  649.     
  650.     theRect = window->portRect;
  651.     theRect.bottom -= 16;
  652.     theRect.right -= 16;
  653.     
  654.     /* no cache, breakproc, or clikloop */
  655.     gTerm = TMNew(&theRect,&theRect, tmSaveBeforeClear + tmAutoScroll,
  656.          procID, window, (ProcPtr)TermSendProc,(ProcPtr)cacheProc,nil,
  657.         /*(ProcPtr)clikLoop*/nil, (ProcPtr)ToolGetConnEnvirons,0,0);
  658.     
  659.     SetRect(&r,theRect.left,-theRect.bottom,theRect.right,theRect.top);
  660.     gTE = TENew(&r,&r);
  661.     (**gTE).txSize = 9;
  662.     (**gTE).txFont = monaco;
  663.     (**gTE).viewRect.bottom = (((**gTE).viewRect.bottom - (**gTE).viewRect.top)/
  664.         (**gTE).lineHeight)*(**gTE).lineHeight + (**gTE).viewRect.top;
  665.     TEAutoView(true,gTE);
  666.         
  667.     /* custom configure with our personal settings -- store this as a file later */
  668.     (void)TMSetConfig(gTerm, "Scroll Smooth\0");
  669.     
  670.     if(gTerm == nil)
  671.         AlertUser("Can't create a terminal tool, dude!\0", true);
  672.     
  673.     HLock((Handle)gTerm);
  674.     
  675.     /* connection tool */
  676.     procID = FindToolID(classCM);
  677.     if(procID == -1)
  678.         AlertUser("No connection tools found, dude!/0", true);
  679.         
  680.     sizes[cmDataIn] = kBufferSize*10;        // just the data channel; large incoming buffer
  681.     sizes[cmDataOut] = kBufferSize;
  682.     sizes[cmCntlIn] = 0;
  683.     sizes[cmCntlOut] = 0;
  684.     sizes[cmAttnIn] = 0;
  685.     sizes[cmAttnOut] = 0;
  686.     
  687.     gConn = CMNew(procID, cmData, sizes, 0,0);
  688.     (void)CMSetConfig(gConn,"Baud 9600 DataBits 7 StopBits 1 Parity Even ModemType Other PhoneNumber \0429,1800-346-0145\042\0");
  689.     if(gConn == nil)
  690.         AlertUser("Can't create a connection tool, dude!/0", true);
  691.     
  692.     HLock((Handle)gConn);
  693.     
  694.     /* allocate space for reads/writes using the number returned by the connection tool */
  695.     gBuffer = NewPtrClear(sizes[cmDataIn]);
  696.     if(MemError() != noErr)
  697.         AlertUser("Out of memory, dude!\0", true);
  698.     
  699.     /* file transfer tool */
  700.     procID = FindToolID(classFT);
  701.     if(procID == -1)
  702.         AlertUser("No file transfer tools found, dude!\0", false);
  703.         
  704.     /* no read/write proc -- tool has its own */
  705.     gFT = FTNew(procID, 0 ,(ProcPtr)FTSendProc, (ProcPtr)FTReceiveProc, 
  706.         nil, nil, (ProcPtr)ToolGetConnEnvirons, window, 0L,0L);
  707.     
  708.     if(gFT == nil)
  709.         AlertUser("Can't create a file transfer tool, dude!\0", true);
  710.     
  711.     HLock((Handle)gFT);
  712.     
  713.     gWasFT = false;
  714.     gStartFT = false;
  715.     gFTSearchRefNum = 0;
  716.     
  717.     AddFTSearch();
  718.     
  719.     return(true);
  720. }
  721.  
  722. #pragma segment Initialize
  723. /* initialize our goodies and the toolbox */
  724. void Initialize()
  725. {
  726.     Handle            menuBar;
  727.     WindowPtr    window;
  728.     OSErr                ignoreError;
  729.     long                total,contig;
  730.     Boolean            ignoreResult;
  731.     EventRecord    event;
  732.     short                count;
  733.     SysEnvRec    TerraMac;
  734.     short                err;
  735.     
  736.     gHasWaitNextEvent = TrapAvailable(_WaitNextEvent, ToolTrap);
  737.     gInBackground = false;
  738.     
  739.     InitGraf((Ptr) &qd.thePort);
  740.     InitFonts();
  741.     InitWindows();
  742.     InitMenus();
  743.     TEInit();
  744.     InitDialogs(nil);
  745.     InitCursor();
  746.     
  747.     for(count=0;count<3;count++)
  748.         ignoreResult = GetNextEvent(everyEvent, &event);
  749.         
  750.     if (!TrapAvailable(_CommToolboxTrap, OSTrap))
  751.         AlertUser("No commtoolbox, dude!\0", true);
  752.     
  753.     ignoreError = SysEnvirons(kSysEnvironsVersion, &TerraMac);
  754.     
  755.     if (TerraMac.systemVersion < 0x600 || TerraMac.machineType < 0)
  756.         AlertUser("You need System 6.0 or later, dude!\0", true);
  757.  
  758.     PurgeSpace(&total, &contig);
  759.     if (total < kMinSpace) 
  760.         AlertUser(true);
  761.         
  762.     if ((long) GetApplLimit() - (long) ApplicZone() < kMinHeap) 
  763.         AlertUser("Out of memory, dude!\0", true);
  764.         
  765.     InitCommTB();                                                            // initialize our comm toolbox things
  766.         
  767.     menuBar = GetNewMBar(rMenuBar);
  768.     if(menuBar == nil)
  769.         AlertUser("Can't get the menubar, dude!\0", true);
  770.     SetMenuBar(menuBar);
  771.     DisposHandle(menuBar);
  772.     
  773.     AddResMenu(GetMHandle(mApple), 'DRVR');    //    desk accessories
  774.     DrawMenuBar();                                                        //    show the menus
  775.     
  776.     if (!DoNewWindow())                                                // can we create our comm window????
  777.         AlertUser("Can't create a session, dude!\0", true);
  778.     
  779.     gStopped = true;
  780. }
  781.  
  782. #pragma segment Main
  783. /* cleans up and gets the hell out of here */
  784. void Terminate()
  785. {
  786.     WindowPtr    aWindow;
  787.     Boolean            closed = true;
  788.     
  789.     aWindow = FrontWindow();
  790.     
  791.     do {
  792.         if (aWindow != nil)
  793.             if (IsAppWindow(aWindow))
  794.                 closed = DoCloseWindow(aWindow);
  795.         
  796.         if(aWindow != nil)
  797.             aWindow = (WindowPtr)(((WindowPeek)aWindow)->nextWindow);
  798.     } while(!(closed | aWindow ==nil));
  799.     
  800.     if(closed)
  801.         ExitToShell();
  802. }
  803.  
  804. #pragma segment Main
  805. /* enables and disables items based on the applications current state */
  806. void AdjustMenus()
  807. {
  808.     WindowPtr        window;
  809.     MenuHandle    menu;
  810.     CMErr                theErr;
  811.     CMBufferSizes    sizes;
  812.     CMStatFlags    status;
  813.     
  814.     window = FrontWindow();
  815.     
  816.     menu = GetMHandle(mFile);
  817.     if(menu == nil)
  818.         AlertUser("Can't get menu resource, dude!\0", true);
  819.     
  820.     if (gConn != nil) {
  821.         theErr = CMStatus(gConn, sizes, &status);
  822.         if (theErr == noErr) {
  823.             if (!IsDAWindow(window)) {
  824.                 setitem(menu, iOpen, "Open");
  825.                 setitem(menu,iClose,"Close");
  826.                 if((status & (cmStatusOpen+cmStatusOpening)) == 0) {
  827.                         EnableItem(menu, iOpen);
  828.                         DisableItem(menu, iClose);
  829.                 }
  830.                 else {
  831.                     DisableItem(menu,iOpen);
  832.                     EnableItem(menu,iClose);
  833.                 }
  834.                 DisableItem(menu, iSendFile);
  835.                 DisableItem(menu,iReceiveFile);
  836.                 
  837.                 if (gFT != nil ) {
  838.                     if (((**gFT).attributes & ftSendDisable) == 0)
  839.                         EnableItem(menu, iSendFile);
  840.                     if (((**gFT).attributes & ftReceiveDisable) == 0)
  841.                         EnableItem(menu, iReceiveFile);
  842.                 }
  843.             }
  844.             else {
  845.                 setitem(menu,iOpen, "Open");
  846.                 setitem(menu, iClose, "Close");
  847.                 DisableItem(menu, iOpen);
  848.                 EnableItem(menu,iClose);
  849.                 DisableItem(menu, iSendFile);
  850.                 DisableItem(menu, iReceiveFile);
  851.             }
  852.         }
  853.     }
  854.     
  855.     menu = GetMHandle(mEdit);
  856.     if (menu == nil) 
  857.         AlertUser("Can't get the menu resource, dude!\0", true);
  858.         
  859.     if (!IsDAWindow(window)) {
  860.         EnableItem(menu, iUndo);
  861.         EnableItem(menu, iCut);
  862.         EnableItem(menu,iCopy);
  863.         EnableItem(menu,iPaste);
  864.         EnableItem(menu,iClear);
  865.         EnableItem(menu,iSelectAll);
  866.         EnableItem(menu,iFind);
  867.         EnableItem(menu,iFindAgain);
  868.         EnableItem(menu,iRecallLast);
  869.         EnableItem(menu,iShowClip);
  870.     }
  871.     else {
  872.         DisableItem(menu,iUndo);
  873.         DisableItem(menu, iCut);
  874.         DisableItem(menu, iCopy);
  875.         DisableItem(menu, iPaste);
  876.         DisableItem(menu, iClear);
  877.         DisableItem(menu,iSelectAll);
  878.         DisableItem(menu,iFind);
  879.         DisableItem(menu,iFindAgain);
  880.         DisableItem(menu,iRecallLast);
  881.         DisableItem(menu,iShowClip);
  882.     }
  883.     
  884.     menu = GetMHandle(mSettings);
  885.     if (menu == nil) 
  886.         AlertUser("Can't get the menu resource, dude!\0", true);
  887.         
  888.     if (!IsDAWindow(window)) {
  889.         EnableItem(menu, iConnection);
  890.         EnableItem(menu, iFileTransfer);
  891.         EnableItem(menu, iTerminal);
  892.     }
  893.     else {
  894.         DisableItem(menu, iConnection);
  895.         DisableItem(menu, iFileTransfer);
  896.         DisableItem(menu, iTerminal);
  897.     }
  898.             
  899.     if (gConn != nil) {
  900.         theErr = CMStatus(gConn, sizes, &status);
  901.         
  902.     }
  903.     
  904.     menu = GetMHandle(mPhone);
  905.     if (menu == nil) 
  906.         AlertUser("Can't get the menu resource, dude!\0", true);
  907.         
  908.     if (gConn != nil) {
  909.         theErr = CMStatus(gConn, sizes, &status);
  910.         if (theErr == noErr) {
  911.                 
  912.             if (!IsDAWindow(window)) {
  913.                 if(status & (cmStatusOpen+cmStatusOpening)) {
  914.                     DisableItem(menu, iOpenConn);
  915.                     EnableItem(menu, iHangUp);
  916.                     EnableItem(menu, iBreak);
  917.                     EnableItem(menu, iSendXON);
  918.                     EnableItem(menu, iSendXOFF);
  919.                 }
  920.                 else {
  921.                     EnableItem(menu, iOpenConn);
  922.                     DisableItem(menu, iHangUp);
  923.                     DisableItem(menu, iBreak);
  924.                     DisableItem(menu, iSendXON);
  925.                     DisableItem(menu, iSendXOFF);
  926.                 }
  927.             }
  928.             else {
  929.                 DisableItem(menu, iOpenConn);
  930.                 DisableItem(menu, iHangUp);
  931.                 DisableItem(menu, iBreak);
  932.                 DisableItem(menu, iSendXON);
  933.                 DisableItem(menu, iSendXOFF);
  934.             }
  935.         }
  936.     }
  937. }
  938.  
  939. /* tries to give the menu to the tool */ 
  940. #pragma segment Main
  941. Boolean DoToolMenu(menuID, menuItem)
  942.     short    menuID;
  943.     short    menuItem;
  944. {
  945.     
  946.     if (gTerm != nil)
  947.         return(TMMenu(gTerm, menuID, menuItem) );
  948.     
  949.     if (gConn != nil)
  950.         return(CMMenu(gConn, menuID, menuItem));
  951.     
  952.     if(gFT != nil)
  953.         return(FTMenu(gFT, menuID, menuItem));
  954.         
  955.     return(false);
  956. }
  957.  
  958. #pragma segment Main
  959. /* execute our application commands */
  960. void DoMenuCommand(menuResult)
  961.     long    menuResult;
  962. {
  963.     short            menuID;
  964.     short            menuItem;
  965.     short            itemHit;
  966.     Str255        DAName;
  967.     short            DARefNum;
  968.     Boolean        handledByDA;
  969.     Boolean        ignore;
  970.     Point            where;
  971.     short            result;
  972.     Handle        tempHand;
  973.     
  974.     menuID = HiWrd(menuResult);
  975.     menuItem = LoWrd(menuResult);
  976.     
  977.     if(!DoToolMenu(menuID,menuItem))
  978.         switch (menuID) {
  979.             case    mApple:
  980.                 switch(menuItem) {
  981.                     case iAbout:
  982.                         itemHit = Alert(rAboutAlert,nil);
  983.                         break;
  984.                     default:
  985.                         GetItem(GetMHandle(mApple), menuItem, DAName);
  986.                         DARefNum = OpenDeskAcc(DAName);
  987.                 }
  988.                 break;
  989.             case mFile:
  990.                 switch(menuItem) {
  991.                     case iOpen:
  992.                         if (!IsDAWindow(FrontWindow()))
  993.                             OpenConnection();
  994.                         break;
  995.                     case iClose:
  996.                         if(IsDAWindow(FrontWindow()))
  997.                             ignore = DoCloseWindow(FrontWindow());
  998.                         else
  999.                             CloseConnection();
  1000.                         break;
  1001.                     case iSendFile:
  1002.                         if(!IsDAWindow(FrontWindow()))
  1003.                             DoSend();
  1004.                         break;
  1005.                     case iReceiveFile:
  1006.                         if(!IsDAWindow(FrontWindow()))
  1007.                             DoReceive();
  1008.                         break;
  1009.                     case iRevert:
  1010.                         break;
  1011.                     case iOpenCapture:
  1012.                         break;
  1013.                     case iAppendCapture:
  1014.                         break;
  1015.                     case iPageSetup:
  1016.                         break;
  1017.                     case iPrint:
  1018.                         break;
  1019.                     case iQuit:
  1020.                         Terminate();
  1021.                 }
  1022.                 break;
  1023.             case mEdit:
  1024.                 case iUndo:
  1025.                 case iCut:
  1026.                 case iCopy:
  1027.                 case iPaste:
  1028.                 case iClear:
  1029.                 case iSelectAll:
  1030.                     handledByDA = SystemEdit(menuItem-1);
  1031.                 break;
  1032.                 case iFind:
  1033.                     break;
  1034.                 case iFindAgain:
  1035.                     break;
  1036.                 case iRecallLast:
  1037.                     break;
  1038.                 case iShowClip:
  1039.                     break;
  1040.             case mSettings:
  1041.                 switch (menuItem) {
  1042.                     case iConnection:
  1043.                         if (gConn != nil ) {
  1044.                             HUnlock((Handle)gConn);
  1045.                             SetPt(&where,10,40);
  1046.                             result = CMChoose(&gConn,where, nil);
  1047.                             switch (result) {    
  1048.                                 case chooseDisaster:
  1049.                                 case chooseFailed:
  1050.                                     AlertUser("Connection choose failed, dude!\0",(result = chooseDisaster));
  1051.                                     break;
  1052.                                 case chooseOKMajor:
  1053.                                     AddFTSearch();
  1054.                             }
  1055.                             HLock((Handle)gConn);
  1056.                         }
  1057.                         break;
  1058.                     case iFileTransfer:
  1059.                         if(gFT != nil ) {
  1060.                             HUnlock((Handle)gFT);
  1061.                             SetPt(&where,10,40);
  1062.                             result = FTChoose(&gFT,where, nil);
  1063.                             
  1064.                             switch (result) {
  1065.                                 case chooseDisaster:
  1066.                                 case chooseFailed:
  1067.                                     AlertUser("File transfer choose failed, dude!\0", (result = chooseDisaster));
  1068.                                     break;
  1069.                                 case chooseOKMinor:
  1070.                                 case chooseOKMajor:
  1071.                                     if(gFTSearchRefNum != 0 && gConn != nil)
  1072.                                         CMRemoveSearch(gConn,gFTSearchRefNum);
  1073.                                     gFTSearchRefNum = 0;
  1074.                                     
  1075.                                     AddFTSearch();
  1076.                             }
  1077.                             HLock((Handle)gFT);
  1078.                         }
  1079.                         break;
  1080.                     case iTerminal:
  1081.                         if(gTerm != nil) {
  1082.                             HUnlock((Handle)gTerm);
  1083.                             
  1084.                             SetPt(&where,10,40);
  1085.                             result = TMChoose(&gTerm,where, nil);
  1086.                             
  1087.                             if(result < 0)
  1088.                                 AlertUser("Terminal choose failed, dude!\0", (result = chooseDisaster));
  1089.                             
  1090.                             HLock((Handle)gTerm);
  1091.                         }
  1092.                         break;
  1093.                 }
  1094.                 case mPhone:
  1095.                     switch(menuItem) {
  1096.                         case iOpenConn:
  1097.                             if (!IsDAWindow(FrontWindow()))
  1098.                                 OpenConnection();
  1099.                             break;
  1100.                         case iHangUp:
  1101.                             if(IsDAWindow(FrontWindow()))
  1102.                                 ignore = DoCloseWindow(FrontWindow());
  1103.                             else
  1104.                                 CloseConnection();
  1105.                             break;
  1106.                         case iBreak:
  1107.                             CMBreak(gConn,20L,true,nil);                // break signal
  1108.                             AlertUser("Break completed, dude!\0", false);
  1109.                             break;
  1110.                         case iSendXON:
  1111.                             break;
  1112.                         case iSendXOFF:
  1113.                             break;
  1114.                     }
  1115.                     break;
  1116.                     
  1117.         }
  1118.         HiliteMenu(0);
  1119. }
  1120.  
  1121. #pragma segment Main
  1122. /* Grows the window in response to the user resizing it */
  1123. void DoGrowWindow(theEvent, whichWindow)
  1124.     EventRecord        *theEvent;
  1125.     WindowPtr        whichWindow;
  1126. {
  1127.     Point        myPt;
  1128.     Rect        oldRect, tempRect;
  1129.     long        mResult;
  1130.     
  1131.     SetPort(whichWindow);/* Point all activity to this window */
  1132.  
  1133.     myPt = theEvent->where;/* Get mouse position */
  1134.     GlobalToLocal(&myPt);/* Make it relative */
  1135.  
  1136.     oldRect.left = whichWindow->portRect.left;/* Save the rect before resizing */
  1137.     oldRect.right = whichWindow->portRect.right;/*   */
  1138.     oldRect.top = whichWindow->portRect.top;/*   */
  1139.     oldRect.bottom = whichWindow->portRect.bottom;/*   */
  1140.  
  1141.     SetRect(&tempRect,475,100,(qd.screenBits.bounds.right - qd.screenBits.bounds.left), (qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - 20);/* l,t,r,b */
  1142.     mResult = GrowWindow(whichWindow, theEvent->where, &tempRect);/* Grow it , globally relative*/
  1143.     SizeWindow(whichWindow, LoWrd(mResult), HiWrd(mResult), true);/* Resize to result */
  1144.  
  1145.     AdjustScrollBars(&oldRect, whichWindow);
  1146.     SetPort(whichWindow);/* Point all activity to this window */
  1147.  
  1148.     SetRect(&tempRect, 0, myPt.v - 15, myPt.h + 15, myPt.v + 15); /* Position for horz scrollbar area */
  1149.     EraseRect(&tempRect);/* Erase old area */
  1150.     InvalRect(&tempRect);/* Flag us to update it */
  1151.     SetRect(&tempRect, myPt.h - 15, 0, myPt.h + 15, myPt.v + 15);  /* Position for vert scrollbar area */
  1152.     EraseRect(&tempRect);/* Erase old area */
  1153.     InvalRect(&tempRect);/* Flag us to update it */
  1154.     DrawGrowIcon(whichWindow);/* Draw the grow Icon again */
  1155.     
  1156.     if (gTerm != nil) {                                                                                    //adjust the terminal emulation area
  1157.         tempRect = whichWindow->portRect;
  1158.         tempRect.bottom -= 16;
  1159.         tempRect.right -= 16;
  1160.         //TMResize(gTerm,&tempRect);
  1161.     }
  1162. }
  1163.  
  1164. #pragma segment Main
  1165. /* Updates the window, dude! */
  1166. void DoUpdate(window)
  1167.     WindowPtr    window;
  1168. {
  1169.     RgnHandle    savedClip;
  1170.     GrafPtr            savedPort;
  1171.     
  1172.     if (IsAppWindow(window)) {
  1173.         GetPort(&savedPort);
  1174.         SetPort(window);
  1175.         
  1176.         /* clip to the window content */
  1177.         savedClip = NewRgn();
  1178.         GetClip(savedClip);
  1179.         ClipRect(&window->portRect);
  1180.         DrawControls(window);
  1181.         DrawGrowIcon(window);
  1182.         
  1183.         BeginUpdate(window);
  1184.             if(gTerm != nil )
  1185.                 TMUpdate(gTerm, window->visRgn);
  1186.             if(gTE != nil)
  1187.                 TEUpdate(&window->portRect,gTE);
  1188.         EndUpdate(window);
  1189.         
  1190.         SetClip(savedClip);
  1191.         DisposeRgn(savedClip);
  1192.         
  1193.         SetPort(savedPort);
  1194.     }
  1195. }
  1196.  
  1197. #pragma segment Main
  1198. /* Suspends/Resumes the terminal window */
  1199. void DoResume(becomingActive)
  1200.     Boolean    becomingActive;
  1201. {
  1202.     WindowPtr    theWindow;
  1203.     GrafPtr            savedPort;
  1204.     
  1205.     GetPort(&savedPort);
  1206.     
  1207.     theWindow = FrontWindow();
  1208.     
  1209.     while (theWindow!= nil) {
  1210.         if (IsAppWindow(theWindow)) {
  1211.             SetPort(theWindow);
  1212.             
  1213.             if(gTerm != nil)
  1214.                 TMResume(gTerm, becomingActive);
  1215.             if(gConn != nil)
  1216.                 CMResume(gConn, becomingActive);
  1217.             if(gFT != nil)
  1218.                 FTResume(gFT, becomingActive);
  1219.         }
  1220.         theWindow = (WindowPtr)(((WindowPeek) theWindow)->nextWindow);
  1221.     }
  1222.     SetPort(savedPort);
  1223. }
  1224.  
  1225. #pragma segment Main
  1226. /* (De)Activates the window */
  1227. void DoActivate(window, becomingActive)
  1228.     WindowPtr    window;
  1229.     Boolean            becomingActive;
  1230.  
  1231. {    
  1232.     if (IsAppWindow(window)) {                // does the window belong to us????
  1233.         SetPort(window);                                //    set current port
  1234.         
  1235.         if(gConn != nil)                                    //    do we have a valid connection????
  1236.             CMActivate(gConn, becomingActive);//    activate it
  1237.         
  1238.         if(gTerm != nil)                                    //    do we have a terminal????
  1239.             TMActivate(gTerm, becomingActive);    //    activate it
  1240.     
  1241.         if(gFT != nil)                                        //    do we have a vlaid file transfer????
  1242.             FTActivate(gFT, becomingActive);//    activate it
  1243.     }
  1244. }
  1245.  
  1246. #pragma segment Main
  1247. /* updates mouse cursor depending on its cotton-pickin' location */
  1248. void AdjustCursor(mouse)
  1249.     Point        *mouse;
  1250. {
  1251.     WindowPtr    window;
  1252.     Point                bozoPt;
  1253.  
  1254.     bozoPt = *mouse;
  1255.     
  1256.     window = FrontWindow();    /* we only adjust the cursor when we are in front */
  1257.     
  1258.     if ( ! gInBackground &&  IsAppWindow(window) ) {
  1259.         GlobalToLocal(&bozoPt);    //    localize the coordinates
  1260.         if (gTerm != nil)     //    if the terminal is valid
  1261.             if(!PtInRect(bozoPt,&(**gTerm).viewRect)) 
  1262.                 InitCursor();
  1263.     }
  1264. } /*AdjustCursor*/
  1265.  
  1266. #pragma segment Main
  1267. /* tries to pass the event to a tool if the window is a tool window;
  1268.     handles event if appropriate    */
  1269. Boolean    DoToolEvent(event, window)
  1270.     EventRecord        *event;
  1271.     WindowPtr        window;
  1272. {
  1273.     Boolean        doToolEvent;
  1274.     
  1275.     if (window != nil    &&    !IsAppWindow(window)) {    //    is the window valid and not ours????
  1276.         doToolEvent = true;
  1277.         
  1278.         /* Evidently, copies of the commtb record are in the refCon field of
  1279.             the window for changing the settings    */
  1280.         if(gFT != nil && gFT == (FTHandle)GetWRefCon(window))
  1281.             FTEvent(gFT,event);    // handle  file transfer manager event 
  1282.         else if(gConn != nil && gConn == (ConnHandle)GetWRefCon(window))
  1283.             CMEvent(gConn,event);    //    handle the connection manager event
  1284.         else if(gTerm != nil && gTerm == (TermHandle)GetWRefCon(window))
  1285.             TMEvent(gTerm,event);    // handle the terminal manager event
  1286.         else
  1287.             doToolEvent = false;
  1288.     }
  1289.     else
  1290.         doToolEvent = false;
  1291.         
  1292.     return(doToolEvent);
  1293. }
  1294.  
  1295. #pragma segment Main
  1296. /* Controls handling all the events in the event queue in our application;
  1297.     We could define scripting events if we wanted and intercept them here
  1298.     as well. This should be straight forward and pretty much self-explanatory.*/
  1299. void DoEvent(event)
  1300.     EventRecord        *event;
  1301. {
  1302.     short                part;
  1303.     short                err;
  1304.     WindowPtr    window;
  1305.     char                key;
  1306.     long                result;
  1307.     Boolean            processed;
  1308.     Point                aPoint;
  1309.     
  1310.     switch (event->what) {                            //    what type of event did we have????
  1311.         case mouseDown:
  1312.             part = FindWindow(event->where,&window);    //    find where the mouse was clicked
  1313.             switch(part) {
  1314.                 case inMenuBar:
  1315.                     AdjustMenus();
  1316.                     DoMenuCommand(MenuSelect(event->where));
  1317.                     break;
  1318.                 case inSysWindow:
  1319.                     SystemClick(event, window);
  1320.                     break;
  1321.                 case inContent:                    //    within the window itself
  1322.                     if (!DoToolEvent(event, window)) {    //    tool event???? try to handle anyway
  1323.                         if (window != FrontWindow())    //     not in front????
  1324.                             SelectWindow(window);    //    bring it to front
  1325.                         else if (gTerm != nil)    //    otherwise, it may be a terminal event
  1326.                             TMClick(gTerm, event);
  1327.                     }
  1328.                     break;
  1329.                 case inDrag:    //    user wants to move the window????
  1330.                     if (!DoToolEvent(event, window))
  1331.                         DragWindow(window,event->where,&qd.screenBits.bounds);
  1332.                     break;
  1333.                 case inGrow:
  1334.                     if(!DoToolEvent(event,window))    //    user wants to change the window's size????
  1335.                         if(IsAppWindow(window))
  1336.                             DoGrowWindow(event, window);
  1337.                     break;
  1338.                 case inZoomIn:
  1339.                 case inZoomOut:
  1340.                 case inGoAway:    //    user wants to nuke the window????
  1341.                     if (DoToolEvent(event, window))
  1342.                         ;
  1343.                     break;
  1344.             }
  1345.             break;
  1346.         case keyDown:    //    user typed on the keyboard
  1347.         case autoKey:
  1348.             window = FrontWindow();        //    need to get the front window
  1349.             if (IsAppWindow(window)) {    //    is it our window????
  1350.                 key = event->message & charCodeMask;
  1351.                 processed = false;
  1352.                 
  1353.                 if ( event->modifiers & cmdKey ) {    
  1354.                     AdjustMenus();                        /* enable/disable/check menu items properly */
  1355.                     result = MenuKey(key);
  1356.                     if(result != 0L) {        //    user selected a cmd-key combination
  1357.                         processed = true;
  1358.                         DoMenuCommand(result);    // handle it like a menu
  1359.                     }
  1360.                 }
  1361.                 
  1362.                 if(gTerm != nil && !processed)    //    key pressed was for the terminal
  1363.                     if(!DoToolEvent(event, window)) 
  1364.                         TMKey(gTerm, event);            //    let the terminal manager handle it
  1365.                 }
  1366.         break;
  1367.         case activateEvt:
  1368.             window = (WindowPtr)event->message;
  1369.             
  1370.             if(!DoToolEvent(event, window))
  1371.                 DoActivate(window, (event->modifiers & activeFlag) != 0);
  1372.             break;
  1373.         case updateEvt:
  1374.             window = (WindowPtr)event->message;
  1375.             
  1376.             if(!DoToolEvent(event, window))
  1377.                 DoUpdate(window);
  1378.                 break;
  1379.         case diskEvt:    //    disk inserted events!
  1380.             if (HiWrd(event->message) != noErr) {
  1381.                 SetPt(&aPoint, kDILeft, kDITop);
  1382.                 err = DIBadMount(aPoint, event->message);
  1383.             }
  1384.             break;
  1385.         case kOSEvent:
  1386.             switch (event->message >> 24) {        /* high byte of message */
  1387.                 case kSuspendResumeMessage:        /* suspend/resume is also an activate/deactivate */
  1388.                     if(!DoToolEvent(event, FrontWindow()))
  1389.                         ;    //    do nothing
  1390.                     gInBackground = (event->message & kResumeMask) == 0;
  1391.                     DoResume(!gInBackground);
  1392.                     break;
  1393.             }
  1394.             break;
  1395.     }
  1396. }
  1397.  
  1398. #pragma segment Main
  1399. /* idles all the communications tools; this was taken from the Surfer pascal
  1400.     example provided from Apple -- you can get it from APDA.*/
  1401. void DoIdle()
  1402. {
  1403.     WindowPtr        theWindow;
  1404.     Boolean                doFT, doTM;
  1405.     GrafPtr                savedPort;
  1406.     
  1407.     GetPort(&savedPort);
  1408.     theWindow = FrontWindow();
  1409.     
  1410.     while (theWindow != nil) {
  1411.         if (IsAppWindow(theWindow)) {
  1412.             SetPort(theWindow);
  1413.             //TEIdle(gTE);
  1414.             
  1415.             if(gConn != nil)
  1416.                 CMIdle(gConn);
  1417.                 
  1418.             doFT = false;
  1419.             doTM = true;
  1420.             
  1421.             if (gFT != nil ) {
  1422.                 if (((**gFT).flags  & ftIsFTMode) != 0) {
  1423.                     doFT = true;
  1424.                     gWasFT = true;
  1425.                     
  1426.                     if(((**gFT).attributes & ftSameCircuit) != 0)
  1427.                         doTM = false;
  1428.                 }
  1429.                 else {
  1430.                     if (gWasFT) {
  1431.                         gWasFT = false;
  1432.                         
  1433.                         if(((**gFT).flags & ftSucc) == 0)
  1434.                             ;
  1435.                         AddFTSearch();
  1436.                     }
  1437.                     if(gStartFT)
  1438.                         DoReceive();
  1439.                 }
  1440.                 if (doFT)
  1441.                     FTExec(gFT);
  1442.             } /* if gFT != nil  */
  1443.             
  1444.             if(gTerm != nil) {
  1445.                 if (doTM) {
  1446.                     TMIdle(gTerm);
  1447.                     TermRecvProc();
  1448.                 }    
  1449.             }/* gTerm != nil */
  1450.         }
  1451.         
  1452.         theWindow = (WindowPtr)(((WindowPeek)theWindow)->nextWindow);
  1453.     }
  1454.     SetPort(savedPort);
  1455. }
  1456.  
  1457. #pragma segment Main
  1458. /* Main event loop, dude */
  1459. void EventLoop()
  1460. {
  1461.     Boolean                gotEvent;
  1462.     EventRecord        event;
  1463.  
  1464.     do {
  1465.         /* use WNE if it is available */
  1466.         DoIdle();                                //keep the term looking cool, dude!
  1467.         if ( gHasWaitNextEvent )
  1468.             gotEvent = WaitNextEvent(everyEvent, &event, 0, nil);
  1469.         else {
  1470.             SystemTask();
  1471.             gotEvent = GetNextEvent(everyEvent, &event);
  1472.         }
  1473.         if ( gotEvent ) {
  1474.             /* make sure we have the right cursor before handling the event */
  1475.             AdjustCursor(&event.where);
  1476.             DoEvent(&event);
  1477.         }
  1478.         /* change the cursor (and region) if necessary */
  1479.         AdjustCursor(&event.where);
  1480.     } while ( true );    /* loop forever; we quit via ExitToShell */
  1481. } /*EventLoop*/
  1482.  
  1483. #pragma segment Main
  1484. /* main */
  1485. main()
  1486. {
  1487.     UnloadSeg((Ptr)_DataInit);                        // Give a hoot, don't pollute!
  1488.     
  1489.     MaxApplZone();                                            //    expand the heap
  1490.     MoreMasters();                                                //    allocate some blocks of master pointers
  1491.     MoreMasters();
  1492.     MoreMasters();
  1493.     
  1494.     Initialize();                                                        //    set up everything -- let's get going!
  1495.     UnloadSeg((Ptr)Initialize);                            // Give a hoot, don't pollute!
  1496.  
  1497.     EventLoop();
  1498. }