home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / Newton Platform Info / Newton 2.0 Sample Code / Desktop Connectivity / SoupDrink-2 / SoupDrink-Mac-2 / SoupDrink.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-09  |  20.5 KB  |  701 lines  |  [TEXT/R*ch]

  1. /*
  2.  *    File:        SoupDrink.c
  3.  * 
  4.  *    Contains:    Demonstration application for the CDIL and FDIL
  5.  *              This is the Macintosh version of SoupDrink - see SOUPDRNK.C for Windows.
  6.  *
  7.  *    Written by:    Rob Langhorne, J. Christopher Bell and David Fedor
  8.  * 
  9.  *    Copyright:    © 1995-1996 by Apple Computer, Inc.  All rights reserved.
  10.  *
  11.  *  Notes:
  12.  *     This is nearly all of the Macintosh-specific code.  It is not intended to be
  13.  *   good Mac sample code :-)  but it works to demonstrate & test how the DILs work.
  14.  *
  15.  *     Nearly all of the DIL code can be found in engine.c.  The only interesting
  16.  *   DIL code in here can be found near the top - in SetupPortMenu and InitializePipe.
  17.  *
  18.  *   You may incorporate this sample code into your applications without
  19.  *   restriction.  This sample code has been provided "AS IS" and the
  20.  *   responsibility for its operation is 100% yours.  You are not
  21.  *   permitted to modify and redistribute the source as "DTS Sample Code."
  22.  *   If you are going to re-distribute the source, we require that you
  23.  *   make it clear in the source that the code was descended from
  24.  *   Apple-provided sample code, but that you've made changes.
  25.  */ 
  26.  
  27. #include <Types.h>
  28. #include <memory.h>
  29. #include <Packages.h>
  30. #include <Errors.h>
  31. #include <quickdraw.h>
  32. #include <fonts.h>
  33. #include <dialogs.h>
  34. #include <windows.h>
  35. #include <menus.h>
  36. #include <events.h>
  37. #include <OSEvents.h>
  38. #include <Desk.h>
  39. #include <diskinit.h>
  40. #include <OSUtils.h>
  41. #include <resources.h>
  42. #include <toolutils.h>
  43. #include <AppleEvents.h>
  44. #include <string.h>
  45. #include <Strings.h>
  46. #include <stdio.h>
  47.  
  48. #define forMac  // this is a Macintosh-only source file...
  49. #include "DILCPipe.h"
  50. #include "HLFDIL.h"
  51. #include "AppDialogs.h"
  52. #include "SoupDrink.h"
  53. #include "Engine.h"
  54.  
  55.  
  56.  
  57. /******    Function prototypes  *******/
  58. void             EventLoop(void) ;
  59. Boolean            DoMenuItem(long val) ;
  60. void             DoDiskEvents(long dinfo) ;
  61. void             DoDeskAccCall(MenuHandle themenu, long theit) ;
  62. void             DisableExpertFuncs(void);
  63. void             EnableExpertFuncs(void);
  64.  
  65.  
  66. /********    Global variables **********/
  67.  
  68. // UI stuff
  69. MenuHandle        gAppleMenuHandle, gFileMenuHandle, gEditMenuHandle, gTestHandle, gPortHandle, gFuncMenuHandle;
  70. Boolean         gQuit;                    // Flags for application state
  71. int                gNumPorts;                // how many ports are in our port menu
  72.  
  73. // Configuration options set through menus
  74. long            gWhichPort,                // the number in the menu of which port to use
  75.                 gWhichTool;                // Selector for which communications tool to use
  76. Boolean         gEncrypt = false,        // Toggles for advanced reading and writing
  77.                 gByteSwap = false,
  78.                 gUseUnicode = false,
  79.                 gExpertMode = false;
  80.  
  81. // the following are globals set in here, used in Engine.c
  82. void            *ourPipe;
  83. void            *gThisObject;                /* This is the only DIL frame active at one time in this app */
  84. int                gInputMode;                    /* drink mode (receive frames) or spit mode (receive strings) */
  85. char            gReceivedString[kMAXSTR];     /* received string; used in 'spit mode' */
  86. long            gReceivedStringLen;            /* received string length (see above) */
  87. char             gTempBuffer [256];            /* a global string buffer for input dialogs, etc */
  88.  
  89.  
  90. // SetupPortMenu() demonstrates finding the available ports available on your machine.
  91. // Different model MacOS computers have different ports, and the port names can be 
  92. // localized into other languages.
  93. //
  94. // The port names are gotten from the Communications Toolbox and placed directly into
  95. // menu items.  Note that InitCRM() is not called - that is called by the DILs as part
  96. // of CDInitCDIL().  (Future versions of the DILs might not call it, though - watch
  97. // for more information on this.)
  98. //
  99. // SoupDrink has a "config" menu to which this function adds port names.  When it comes
  100. // time to call CDPipeInit, the port name is taken directly out of the menu.
  101. //
  102. // The basis for this routine was stolen from:
  103. // http://dev.info.apple.com/source/code/Snippets/Communications_Toolbox/FindSerialPorts/ReadMe.html
  104.  
  105. #include <CommResources.h>
  106. #include <CRMSerialDevices.h>
  107.  
  108. void SetupPortMenu()
  109. {
  110.     CRMRec            c;
  111.     CRMRecPtr        cPtr = &c;
  112.     CRMSerialPtr    serialPtr;
  113.         
  114.     gNumPorts = 0;
  115.     c.crmDeviceType = crmSerialDevice;
  116.     c.crmDeviceID   = 0;
  117.     while (cPtr != nil) {
  118.         cPtr = (CRMRecPtr)CRMSearch(&c);
  119.         if (cPtr) {
  120.             serialPtr = (CRMSerialPtr)cPtr->crmAttributes;
  121.             AppendMenu(gPortHandle, *(serialPtr->name));    // this is a Pascal-style string, which is what AppendMenu wants.
  122.             gNumPorts++;
  123.             c.crmDeviceID = cPtr->crmDeviceID;
  124.         }
  125.     }
  126.        gWhichPort = kFirstPortItem;                // default to the first port in the list
  127.        if (gNumPorts)
  128.            CheckItem(gPortHandle, gWhichPort, true);    // put a checkmark next to it.
  129. }
  130.  
  131.  
  132. /*
  133.  * InitializePipe
  134.  *
  135.  * Purpose: This function sets up port options for the CDIL function called CDPipeInit.
  136.  *
  137.  * Note that if you do not "dispose" of the connection, the port can be locked and you will
  138.  * get the "port busy" error which will make life difficult for both you and users. It would
  139.  * be best if the function which Initializes the pipe takes responsibility for disposing of
  140.  * of the pipe.
  141.  */
  142. OSErr InitializePipe () 
  143. {
  144.     OSErr    fErr;
  145.     char    Port[100];
  146.  
  147.     // Copy the text for the port right out of the menu item.
  148.     // It'll look like "Modem Port" but could be localized into another language!
  149.     getitem(gPortHandle, gWhichPort, Port);
  150.     
  151.     switch (gWhichTool) {
  152.         case kSerialTool:
  153.             fErr = CDPipeInit(ourPipe, "Serial","","Baud 38400 dataBits 8 Parity None Port ", Port, kDefaultBufferSize, kDefaultBufferSize);    
  154.             break;
  155.         case kModemTool:
  156.             fErr = CDPipeInit(ourPipe, "Modem","","ModemType \"Newton Serial Connection\" dataBits 8 Parity None Baud 38400 Port ", Port, kDefaultBufferSize, kDefaultBufferSize);    
  157.             break;
  158.         case kADSPTool:
  159.             fErr = CDPipeInit(ourPipe, "ADSP","My Desktop Mac","LocalADSPType \"SoupDrink\" RegisterName 1 LocalADSPName ", Port, kDefaultBufferSize, kDefaultBufferSize);    
  160.             break;
  161.         case kIRTool:
  162.             fErr = CDPipeInit(ourPipe, "IR","","", Port, kDefaultBufferSize, kDefaultBufferSize);    
  163.             break;
  164.         }
  165.     
  166.     return fErr;
  167. }
  168.  
  169. void ListenCallback( CommErr errorValue, long refCon )
  170. // This is only used by the "expert" mode, to test asynchronous listening...
  171. {
  172.     long length=5;
  173.     
  174.     if (errorValue)
  175.         PostAlertMessage("CDPipeAccept asynch returned:", ErrorStrings((int) errorValue, gTempBuffer), "", "");
  176.     else {
  177.         errorValue = CDPipeAccept(ourPipe) ;
  178.         if (errorValue)
  179.             PostAlertMessage("CDPipeAccept asynch returned:", ErrorStrings((int) errorValue, gTempBuffer), "", "");
  180.         else {
  181.             errorValue = CDPipeWrite(ourPipe, (void *)"asdf\4", &length, true,0,0,600,0,0);        // will generate an error on the Newton side
  182.             if (errorValue)
  183.                 PostAlertMessage("CDPipeWrite asynch returned:", ErrorStrings((int) errorValue, gTempBuffer), "", "");
  184.         }
  185.     }
  186. }
  187.  
  188.  
  189. /*
  190.  * encryptProc
  191.  *
  192.  * encryptProc is the encryption callback function
  193.  */
  194. static void encryptProc ( void *pData, Size Count, long refCon ) 
  195. {
  196.     Str255 refConStr;
  197.     char * localStr;
  198.     
  199.     
  200.     localStr = (char *) NewPtrClear(Count + 1);
  201.     if (!localStr)
  202.         return;
  203.         
  204.     strcpy(localStr, (char *)pData);
  205.     sprintf((char*) refConStr, "%d", refCon);
  206.     PostAlertMessage("We have encrypted:", (char*) localStr, " Reference constant: ", (char*) refConStr);
  207. }
  208.  
  209.  
  210. /*
  211.  * decryptProc
  212.  *
  213.  * decryptProc is the decryption callback function
  214.  */
  215. static void decryptProc ( void *pData, Size Count, long refCon ) 
  216. {
  217.     Str255 refConStr;
  218.     char * localStr;
  219.     
  220.     localStr = (char *)NewPtrClear(Count + 1);
  221.     if (!localStr)
  222.         return;
  223.  
  224.     strcpy(localStr,(char *) pData);
  225.     NumToString(Count, (unsigned char*) gTempBuffer);
  226.     sprintf((char*) refConStr, "%d", refCon);
  227.     PostAlertMessage("We have encrypted:", localStr, "Reference constant: ",(char*) refConStr);
  228. }
  229.  
  230.  
  231. /* StateStrings
  232.  * 
  233.  * Purpose: return state string based on state number from the CDILs
  234.  * (as a pascal string)
  235.  * note, if theErr is greater than 50, it is a user CDIL error
  236.  */
  237. char* StateStrings(int theState, Str255 theString)
  238. {
  239.     char* s;
  240.     char theNum[128];
  241.     
  242.     switch (theState) {
  243.         case kCDIL_Uninitialized:         s = "CDIL is uninitialized."; break;
  244.         case kCDIL_InvalidConnection:    s = "CDIL tried to bring up connection, but it failed."; break;
  245.         case kCDIL_Disconnected:          s = "CDIL is disconnected."; break;
  246.         case kCDIL_Listening:            s = "CDIL is listening for a connection."; break;
  247.         case kCDIL_ConnectPending:        s = "A CDIL connection is pending."; break;
  248.         case kCDIL_Connected:            s = "CDIL is connected."; break;
  249.         case kCDIL_Busy:                s = "CDIL is busy (either reading or writing)."; break;
  250.         case kCDIL_Aborting:            s = "CDIL is aborting."; break;
  251.         case kCDIL_Startup:                s = "CDIL is starting up."; break;
  252.         default:  s = (theState < 50) ? "Unknown CDIL state." : "(User-defined CDIL state)";
  253.         };
  254.         
  255.     strcpy((char*) theString, s);
  256.     strcat((char*) theString, ": State #");
  257.     NumToString(theState, (unsigned char*) theNum);
  258.     strcat((char*) theString,  (char*) p2cstr((unsigned char*)theNum));
  259.  
  260.     return (( char*) theString);
  261. }
  262.  
  263.  
  264. /*
  265.  *    Main
  266.  * 
  267.  *    This is the entry point for this application.
  268.  */
  269. void main(void)
  270. {
  271.     CommErr            fErr;
  272.      CursHandle         W;            /*    Cursor handle to get cursors    */
  273.     DialogPtr        splash;        /*    For use in splash screen */
  274.     Handle             MyMenu;                   /* my menu bar handle */
  275.     Cursor            myWatchCursor ;            /* The watch "busy" cursor */
  276.  
  277. #ifdef DEFINE_QD
  278. // This is needed for some compilers...
  279.     QDGlobals        qd;
  280. #endif
  281.  
  282.     /*     Start out with the standard Macintosh initializations */
  283.     MaxApplZone();
  284.     InitGraf((Ptr)&qd.thePort);
  285.     InitFonts();
  286.     InitWindows();
  287.     InitMenus();
  288.     TEInit();
  289.     InitDialogs(nil);
  290.     InitCursor();
  291.     MoreMasters();
  292.     MoreMasters();
  293.     MoreMasters();
  294.         
  295.      fErr = CDInitCDIL() ; 
  296.     if (fErr)  {
  297.         PostAlertMessage("Error initializing CDIL", ErrorStrings((int) fErr, gTempBuffer), "", "");
  298.         return;
  299.     }
  300.     
  301.     // Initialize the libraries themselves (does not make a connection)
  302.     fErr = FDInitFDIL();
  303.     if (fErr)  {
  304.         PostAlertMessage("Error initializing FDIL", ErrorStrings((int) fErr, gTempBuffer), "", "");
  305.         return;
  306.     }
  307.  
  308.     // Set up the menus
  309.     MyMenu = GetNewMBar(kMBarID);
  310.     SetMenuBar(MyMenu);
  311.     
  312.     gAppleMenuHandle = GetMenuHandle(kAppleMenu);
  313.     gFileMenuHandle = GetMenuHandle(kFileMenu);
  314.     gEditMenuHandle = GetMenuHandle(kEditMenu);
  315.     gTestHandle = GetMenuHandle(kTestMenu);
  316.     gPortHandle = GetMenuHandle(kPortMenu);
  317.     gFuncMenuHandle = GetMenuHandle(kFnMenu);
  318.     
  319.     // add desk accessories to the apple menu
  320.     AppendResMenu(gAppleMenuHandle, 'DRVR');
  321.         
  322.     SetupPortMenu();
  323.     if (gNumPorts==0){
  324.         PostAlertMessage("Error getting serial port names", "", "", "");
  325.         return;
  326.     }
  327.     
  328.     CheckItem(gPortHandle, kSerialTool, false);
  329.     CheckItem(gPortHandle, kModemTool, true);        // default to the modem tool
  330.     CheckItem(gPortHandle, kADSPTool, false);
  331.     CheckItem(gPortHandle, kIRTool, false);
  332.     gWhichTool = kModemTool;
  333.     
  334.     DisableExpertFuncs();
  335.  
  336.     DrawMenuBar();
  337.  
  338.     // Turn on the watch cursor while the splash screen is showing
  339.     W = GetCursor (watchCursor);
  340.     if (W)
  341.         myWatchCursor = **W;
  342.  
  343.       SetCursor((CursPtr)&myWatchCursor);
  344.       ShowCursor();
  345.     
  346.     ShowSplash(&splash);
  347.  
  348.     ourPipe = CDCreateCDILObject();
  349.     if (!ourPipe) {
  350.         PostAlertMessage("Error instantiating CDIL", "", "", "");
  351.         return;
  352.     }
  353.  
  354.     HideSplash(splash);
  355.     HideCursor();
  356.     SetCursor((const Cursor *)&qd.arrow);
  357.     ShowCursor();
  358.  
  359.     EventLoop ();
  360.  
  361.     fErr = CDPipeDisconnect (ourPipe);
  362.     
  363.     CDDisposeCDILObject( ourPipe ) ;
  364.     CDDisposeCDIL() ;
  365. #ifdef useASLM
  366.     CleanupLibraryManager();
  367. #endif
  368. }
  369.  
  370. /*
  371.  * EventLoop
  372.  *
  373.  * Purpose: This is the main Macintosh event loop processor.
  374.  *          This function must handle any type of Macintosh event
  375.  *          like mouse clicks and keyboard events.
  376.  */
  377. void EventLoop ( void )
  378. {
  379.     EventRecord     gERecord;                /* Current Macintosh Toolbox event record */
  380.     WindowPtr    twindow;
  381.     short        part;
  382.     
  383.      do {
  384.         CDIdle(ourPipe);
  385.         WaitNextEvent(everyEvent, &gERecord, 30, nil);
  386.         
  387.         switch (gERecord.what) {
  388.             case mouseDown:
  389.                 /* first see where the hit was */
  390.                 part = FindWindow(gERecord.where, &twindow);
  391.                 switch (part) {
  392.                     
  393.                     case inDesk:                            /* if they hit in desk, then the process manager */
  394.                         break;                              /* will switch us out, we don't need to do anything */
  395.  
  396.                     case inMenuBar:
  397.                         DoMenuItem(MenuSelect(gERecord.where));
  398.                         break;
  399.                         
  400.                     case inSysWindow:    /* pass to the system */
  401.                         SystemClick(&gERecord, twindow);
  402.                         break;
  403.                         
  404.                     case inContent:    /*    This app doesn't do windows    */
  405.                     case inDrag:
  406.                     case inGrow:
  407.                     case inGoAway:
  408.                     case inZoomIn:                            
  409.                     case inZoomOut:
  410.                         break;
  411.         
  412.                 }
  413.                 break;
  414.  
  415.             case keyUp:                /* don't care */
  416.             case mouseUp:            /* don't care */
  417.             case networkEvt:        /* don't care */
  418.             case driverEvt:            /* don't care */
  419.             case kHighLevelEvent:    /*    AppleEvents    */
  420.                 break;
  421.  
  422.             case keyDown:
  423.             case autoKey:
  424.                 if (gERecord.modifiers & cmdKey)
  425.                     DoMenuItem(MenuKey((short)gERecord.message & charCodeMask));
  426.                 else
  427.                     SysBeep(2);
  428.                 break;
  429.  
  430.             case diskEvt:
  431.                 /* We don't do anything special for disk events, this just passes them
  432.                  * to a function that checks for an error on the mount
  433.                  */
  434.                 DoDiskEvents((long)gERecord.message);
  435.                 break;
  436.  
  437.             default:
  438.                 break;
  439.                 
  440.         }
  441.     } while (gQuit != true);
  442. }
  443.  
  444. /*
  445.  * DoDeskAccCall
  446.  *
  447.  * DoDeskAccCall opens the requested DA
  448.  */
  449.  
  450. void DoDeskAccCall(MenuHandle themenu, long theit)
  451. {
  452.     Str255 DAname;
  453.     
  454.     GetMenuItemText(themenu, (short)theit, DAname);
  455.     OpenDeskAcc(DAname);
  456. }    /*    end DoDeskAccCall    */
  457.  
  458. /*
  459.  * DoDiskEvents
  460.  *
  461.  * DoDiskEvents performs disk mount operations
  462.  */
  463. void DoDiskEvents(long dinfo)    /* hi word is error code, lo word is drive number */
  464. {
  465.     short theHighWord, theLowWord, hdl;
  466.     Point mountpoint =  {
  467.         40, 40
  468.     };
  469.     
  470.     theHighWord = HiWord(dinfo);
  471.     theLowWord = LoWord(dinfo);
  472.     if (theHighWord != noErr)/* something happened */ {
  473.         hdl = DIBadMount(mountpoint, dinfo);
  474.     }
  475. }    
  476.  
  477. /*
  478.  * DoMenuItem
  479.  *
  480.  * DoMenuItem processes a menu event
  481.  */
  482.  
  483. Boolean DoMenuItem(long val)
  484. {
  485.     short                 theLowWord, theHighWord;
  486.     CommErr                fErr = 0;
  487.     Str255                stateString;
  488.     CDIL_State            state;
  489.  
  490.     theLowWord = LoWord(val);
  491.     theHighWord = HiWord(val);
  492.     
  493.     switch (theHighWord) {                                  /* switch off the menu number selected */
  494.         case kAppleMenu:                                    /* Apple menu */
  495.             if (theLowWord != 1)                             /* if this was not About, it's a DA */
  496.                 DoDeskAccCall(gAppleMenuHandle, theLowWord);
  497.             else 
  498.                 Alert(kAboutDialog, nil);                 /* do about box */
  499.             break;
  500.             
  501.         case kFileMenu:                                        /* File menu */
  502.             gQuit = true;                                    /* only edit item */
  503.             break;
  504.  
  505.         case kEditMenu:                                        /* don't care */
  506.             SysBeep(1);
  507.             break;
  508.  
  509.         case kTestMenu:                                        /*    Test suites    */
  510.             switch(theLowWord) {
  511.                 case kSoupDrinkItem:
  512.                     fErr = SoupDrink();
  513.                     if (fErr)
  514.                         PostAlertMessage("Error from Soup Drink", ErrorStrings((int) fErr, gTempBuffer), "", "");
  515.                     break;
  516.                 
  517.                 case kNewNameItem:                            /* Create a new Names Soup entry on the Newton */
  518.                     fErr = UploadNewName();
  519.                     if (fErr)
  520.                         PostAlertMessage("Error from UploadNewName", ErrorStrings((int) fErr, gTempBuffer), "", "");
  521.                     break;
  522.                         
  523.                 default:                                    /* Sanity check. Shouldn't get here */
  524.                     SysBeep(1);
  525.                     break;
  526.             }
  527.             break;
  528.             
  529.         case kPortMenu:    //    Choose a port…
  530.              switch(theLowWord) {
  531.                 case kSerialTool:
  532.                 case kModemTool:
  533.                 case kADSPTool:
  534.                 case kIRTool:
  535.                     CheckItem(gPortHandle, kSerialTool, (theLowWord==kSerialTool));
  536.                     CheckItem(gPortHandle, kModemTool, (theLowWord==kModemTool));
  537.                     CheckItem(gPortHandle, kADSPTool, (theLowWord==kADSPTool));
  538.                     CheckItem(gPortHandle, kIRTool, (theLowWord==kIRTool));
  539.                     gWhichTool = theLowWord;
  540.                     break;
  541.  
  542.                 default: {
  543.                     int i;
  544.                     
  545.                     for (i=0; i<gNumPorts; i++)
  546.                         CheckItem(gPortHandle, kFirstPortItem + i, (theLowWord== kFirstPortItem + i));
  547.                     gWhichPort = theLowWord;
  548.                     break;
  549.                 }
  550.             } 
  551.             break;
  552.             
  553.         case kFnMenu: // Choose a function …
  554.              switch(theLowWord) {
  555.                 case kFInitItem:
  556.                     fErr = InitializePipe();
  557.                     if (fErr)
  558.                         PostAlertMessage("InitializePipe returned:", ErrorStrings((int) fErr, gTempBuffer), "", "");
  559.                     break;
  560.                     
  561.                 case kFListenItem:
  562.                     fErr = CDPipeListen(ourPipe, kDefaultTimeout, (CDILCompletionProcPtr)ListenCallback, 0) ;
  563.                     if (fErr)
  564.                         PostAlertMessage("CDPipeListen returned:", ErrorStrings((int) fErr, gTempBuffer), "", "");
  565.                     break;
  566.                     
  567.                 case kFAcceptItem:
  568.                     fErr = CDPipeAccept(ourPipe) ;
  569.                     if (fErr)
  570.                         PostAlertMessage("CDPipeAccept returned:", ErrorStrings((int) fErr, gTempBuffer), "", "");
  571.                     break;
  572.                     
  573.                 case kFAbortItem:
  574.                     fErr = CDPipeAbort(ourPipe, kAllPipes) ;
  575.                     if (fErr)
  576.                         PostAlertMessage("CDPipeAbort returned:", ErrorStrings((int) fErr, gTempBuffer), "", "");
  577.                     break;
  578.                     
  579.                 case kFDiscItem:
  580.                     fErr = CDPipeDisconnect(ourPipe) ;
  581.                     if (fErr)
  582.                         PostAlertMessage("CDPipeDisconnect returned:", ErrorStrings((int) fErr, gTempBuffer), "", "");
  583.                     break;
  584.                     
  585.                 case kFReadItem:
  586.                     SysBeep(1);
  587.                     break;
  588.                     
  589.                 case kFCountItem:
  590.                     SysBeep(1);
  591.                     break;
  592.                     
  593.                 case kFWriteItem:
  594.                     SysBeep(1);
  595.                     break;
  596.                     
  597.                 case kFGetStateItem:
  598.                     state = CDGetPipeState(ourPipe);
  599.  
  600.                     PostAlertMessage("Current state:", StateStrings(state, stateString), "", "");
  601.                     break;
  602.                     
  603.                 case kFSetStateItem:                         /* Set State number (e.g. kCDIL_Busy) */
  604.                     SysBeep(1);
  605.                     break;
  606.  
  607.                 case kToggleEncryption:
  608.                     if (gEncrypt) {
  609.                         CDEncryptFunction(ourPipe, (CDILEncryptionProcPtr) nil, 0 ) ;
  610.                         CDDecryptFunction(ourPipe, (CDILDecryptionProcPtr) nil, 0 ) ;
  611.                         gEncrypt = false ;
  612.                     }
  613.                     else {
  614.                         CDEncryptFunction(ourPipe, (CDILEncryptionProcPtr) encryptProc, 100 ) ;
  615.                         CDDecryptFunction(ourPipe,  (CDILDecryptionProcPtr) decryptProc, 100 ) ;
  616.                         gEncrypt = true ;
  617.                     }    
  618.                     CheckItem(gFuncMenuHandle, kToggleEncryption, gEncrypt);
  619.                     
  620.                     break;
  621.                     
  622.                 case kToggleByteSwap:
  623.                     if (gByteSwap)
  624.                         gByteSwap = false ;
  625.                     else
  626.                         gByteSwap = true ;
  627.                         
  628.                     CheckItem(gFuncMenuHandle, kToggleByteSwap, gByteSwap);
  629.                     break;
  630.                     
  631.                 case kToggleUnicode:
  632.                     if (gUseUnicode)
  633.                         gUseUnicode = false ;
  634.                     else
  635.                         gUseUnicode = true ;
  636.                         
  637.                     CheckItem(gFuncMenuHandle, kToggleUnicode, gUseUnicode);
  638.                     break;
  639.                 case kExpertModeToggle:
  640.                     if (gExpertMode) {
  641.                         gExpertMode = false ;
  642.                         DisableExpertFuncs();
  643.                         }
  644.                     else {
  645.                         gExpertMode = true ;
  646.                         EnableExpertFuncs();
  647.                         }
  648.                         
  649.                     CheckItem(gFuncMenuHandle, kExpertModeToggle, gExpertMode);
  650.                     break;
  651.  
  652.                 default:    
  653.                     SysBeep(1);  //    Sanity check; shouldn't get here
  654.                     break;
  655.             }
  656.             
  657.     }
  658.     HiliteMenu(0);                        // Unhilite the menu label itself
  659.     return noErr;
  660. }    /*    end DoMenuItem    */
  661.  
  662.  
  663. void EnableExpertFuncs(void) {
  664.     EnableItem(gFuncMenuHandle,kFInitItem);
  665.     EnableItem(gFuncMenuHandle,kFListenItem);
  666.     EnableItem(gFuncMenuHandle,kFAcceptItem);
  667.     EnableItem(gFuncMenuHandle,kFAbortItem);
  668.     EnableItem(gFuncMenuHandle,kFDiscItem);
  669.     //EnableItem(gFuncMenuHandle,kFReadItem);
  670.     //EnableItem(gFuncMenuHandle,kFCountItem);
  671.     //EnableItem(gFuncMenuHandle,kFWriteItem);
  672.     //EnableItem(gFuncMenuHandle,kFSetStateItem);
  673.     EnableItem(gFuncMenuHandle,kToggleEncryption);
  674.     EnableItem(gFuncMenuHandle,kToggleByteSwap);
  675.     EnableItem(gFuncMenuHandle,kToggleUnicode);
  676. }
  677.  
  678. void DisableExpertFuncs(void) {
  679.     DisableItem(gFuncMenuHandle,kFInitItem);
  680.     DisableItem(gFuncMenuHandle,kFListenItem);
  681.     DisableItem(gFuncMenuHandle,kFAcceptItem);
  682.     DisableItem(gFuncMenuHandle,kFAbortItem);
  683.     DisableItem(gFuncMenuHandle,kFDiscItem);
  684.     DisableItem(gFuncMenuHandle,kFReadItem);
  685.     DisableItem(gFuncMenuHandle,kFCountItem);
  686.     DisableItem(gFuncMenuHandle,kFWriteItem);
  687.     DisableItem(gFuncMenuHandle,kFSetStateItem);
  688.     DisableItem(gFuncMenuHandle,kToggleEncryption);
  689.     DisableItem(gFuncMenuHandle,kToggleByteSwap);
  690.     DisableItem(gFuncMenuHandle,kToggleUnicode);
  691. }
  692.  
  693.  
  694. long CurrentTimeInSeconds()
  695. // return something indicating what time it is, in seconds units
  696. // This is only used to compare one time against another; it does
  697. // not need to have any relationship to the time of day.
  698. {
  699.     return (TickCount() / 60);
  700. }
  701.