home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 550b.lha / Term_v1.8a / Source.LZH / termMain.c < prev    next >
C/C++ Source or Header  |  1991-07-26  |  43KB  |  2,156 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by Olaf 'Olsen' Barthel & MXM
  4.  *
  5.  *    Name .....: TermMain.c
  6.  *    Created ..: Monday 21-Jan-91 20:12
  7.  *    Revision .: 0
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    21-Jan-91       Olsen           Created this file!
  12.  *
  13.  * $Revision Header ********************************************************/
  14.  
  15. #include "TermGlobal.h"
  16.  
  17.     /* Argument vectors offsets. */
  18.  
  19. enum    {    ARG_KEEPIO,ARG_DONTPOP,ARG_DEBUGWINDOW,ARG_DEBUGFILE };
  20.  
  21.     /* Some global variables for starters. */
  22.  
  23. STATIC BYTE Terminated = FALSE;
  24.  
  25. #ifndef DONT_DEBUG
  26.  
  27.     /* My debug info - don't remove it! */
  28.  
  29. extern BPTR    DebugConsole,DebugFile;
  30.  
  31. BPTR        TermHelp;
  32.  
  33. #define ARGTEMPLATE    "K=KEEPIO/S,D=DONTPOP/S,W=DEBUGWINDOW/S,F=DEBUGFILE/K"
  34. #define NUMARGS        4
  35.  
  36. #else
  37.  
  38. #define ARGTEMPLATE    "K=KEEPIO/S,D=DONTPOP/S"
  39. #define NUMARGS        2
  40.  
  41. #endif /* DONT_DEBUG */
  42.  
  43.     /* main():
  44.      *
  45.      *    This is our main entry point, check for the right
  46.      *    Kickstart version and fire off the background task
  47.      *    if approritate.
  48.      */
  49.  
  50. LONG __saveds
  51. main()
  52. {
  53.     UBYTE *Result;
  54.  
  55.         /* Set up SysBase. */
  56.  
  57.     SysBase = *(struct ExecBase **)4;
  58.  
  59.         /* Are we running as a child of Workbench? */
  60.  
  61.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  62.  
  63.     if(!ThisProcess -> pr_CLI)
  64.     {
  65.         WaitPort(&ThisProcess -> pr_MsgPort);
  66.  
  67.         WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
  68.     }
  69.     else
  70.         WBenchMsg = NULL;
  71.  
  72.         /* Kickstart 2.0 or higher required, do you hear me? */
  73.  
  74.     if(SysBase -> LibNode . lib_Version < 36)
  75.     {
  76.         if(ThisProcess -> pr_CLI)
  77.         {
  78.             if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0))
  79.             {
  80.                 Write(ThisProcess -> pr_COS,"Kickstart 2.0 or higher required.\a\n",35);
  81.  
  82.                 ThisProcess -> pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
  83.  
  84.                 CloseLibrary(DOSBase);
  85.             }
  86.         }
  87.         else
  88.         {
  89.             if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  90.             {
  91.                 STATIC struct IntuiText BodyText =  {0,1,JAM1,5,3,&DefaultFont,(UBYTE *)"Kickstart 2.0 or higher required.", NULL};
  92.                 STATIC struct IntuiText SorryText = {0,1,JAM1,6,3,&DefaultFont,(UBYTE *)"Sorry",NULL};
  93.  
  94.                 struct Window *Window;
  95.  
  96.                 if(Window = (struct Window *)BuildSysRequest(NULL,&BodyText,NULL,&SorryText,GADGETUP,301,46))
  97.                 {
  98.                     struct IntuiMessage *Message;
  99.  
  100.                     ScreenToFront(Window -> WScreen);
  101.  
  102.                     DisplayBeep(Window -> WScreen);
  103.  
  104.                     WaitPort(Window -> UserPort);
  105.  
  106.                     if(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  107.                         ReplyMsg(Message);
  108.  
  109.                     FreeSysRequest(Window);
  110.                 }
  111.  
  112.                 CloseLibrary(IntuitionBase);
  113.             }
  114.         }
  115.  
  116.         if(WBenchMsg)
  117.         {
  118.             Forbid();
  119.  
  120.             ReplyMsg((struct Message *)WBenchMsg);
  121.         }
  122.  
  123.         return(RETURN_FAIL);
  124.     }
  125.  
  126.         /* Now try to open dos.library and go on examining
  127.          * our calling parameters.
  128.          */
  129.  
  130.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36)))
  131.     {
  132.         CloseAll();
  133.  
  134.         return(RETURN_FAIL);
  135.     }
  136.  
  137.         /* We were called from Shell. */
  138.  
  139.     if(ThisProcess -> pr_CLI)
  140.     {
  141.         UBYTE **ArgArray;
  142.  
  143.             /* Use the cute ReadArgs parser, allocate the
  144.              * argument vectors...
  145.              */
  146.  
  147.         if(ArgArray = (UBYTE **)AllocVec(sizeof(UBYTE *) * NUMARGS,MEMF_PUBLIC | MEMF_CLEAR))
  148.         {
  149.             struct RDArgs *ArgsPtr;
  150.  
  151.             if(ArgsPtr = (struct RDArgs *)AllocVec(sizeof(struct RDArgs),MEMF_PUBLIC|MEMF_CLEAR))
  152.             {
  153.                 ArgsPtr -> RDA_ExtHelp = "\nUsage: \33[1mterm\33[0m [KeepIO] [DontPop]\n\n       KeepIO ....: Keep links to the current Shell window.\n       DontPop ...: Don't pop an already running term to the front.\n\n";
  154.  
  155.                     /* Parse the args (if any). */
  156.  
  157.                 if(ReadArgs(ARGTEMPLATE,(LONG *)ArgArray,ArgsPtr))
  158.                 {
  159. #ifndef DONT_DEBUG
  160.                     {
  161.                         extern UBYTE    DebugFileName[256];
  162.                         extern BYTE    DebugWindow;
  163.  
  164.                         if(ArgArray[ARG_DEBUGWINDOW])
  165.                             DebugWindow = TRUE;
  166.  
  167.                         if(ArgArray[ARG_DEBUGFILE])
  168.                             strcpy(DebugFileName,ArgArray[ARG_DEBUGFILE]);
  169.                     }
  170. #endif /* DONT_DEBUG */
  171.                         /* Pop a running `term' to the front? */
  172.  
  173.                     if((TermPort = (struct TermPort *)FindPort("term Port")) && !ArgArray[ARG_DONTPOP])
  174.                     {
  175.                         if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  176.                         {
  177.                             if(TermPort -> TopWindow)
  178.                                 BumpWindow(TermPort -> TopWindow);
  179.  
  180.                             CloseLibrary(IntuitionBase);
  181.                         }
  182.  
  183.                         FreeArgs(ArgsPtr);
  184.                         FreeVec(ArgsPtr);
  185.                         FreeVec(ArgArray);
  186.  
  187.                         return(RETURN_OK);
  188.                     }
  189.  
  190.                         /* We are to keep our links to
  191.                          * the Shell.
  192.                          */
  193.  
  194.                     if(ArgArray[ARG_KEEPIO])
  195.                     {
  196.                             /* Open our resources and
  197.                              * squeak after failure.
  198.                              */
  199.  
  200.                         if(Result = OpenAll())
  201.                         {
  202.                             if(Result[0])
  203.                                 Printf("\33[1mterm:\33[0m %s!\a\n",Result);
  204.  
  205.                             CloseAll();
  206.  
  207.                             FreeArgs(ArgsPtr);
  208.                             FreeVec(ArgsPtr);
  209.                             FreeVec(ArgArray);
  210.  
  211.                             return(RETURN_FAIL);
  212.                         }
  213.  
  214.                             /* Go into main input
  215.                              * loop.
  216.                              */
  217.  
  218.                         HandleInput();
  219.  
  220.                             /* Does anybody understand
  221.                              * this joke?
  222.                              */
  223.  
  224.                         Printf("You quit with 0 gold pieces\nTo play again, just type \"term\"\n");
  225.  
  226.                             /* Free the argument
  227.                              * data.
  228.                              */
  229.  
  230.                         FreeArgs(ArgsPtr);
  231.                         FreeVec(ArgsPtr);
  232.                         FreeVec(ArgArray);
  233.  
  234.                             /* Mega-glitch: term used to
  235.                              * bolt and lock the door
  236.                              * before the last dos.library
  237.                              * functions were called!
  238.                              */
  239.  
  240.                         CloseAll();
  241.  
  242.                         return(RETURN_OK);
  243.                     }
  244.  
  245.                     FreeArgs(ArgsPtr);
  246.                 }
  247.                 else
  248.                 {
  249.                     PrintFault(IoErr(),"term");
  250.  
  251.                     FreeVec(ArgsPtr);
  252.                     FreeVec(ArgArray);
  253.  
  254.                     return(RETURN_ERROR);
  255.                 }
  256.  
  257.                 FreeVec(ArgsPtr);
  258.             }
  259.  
  260.             FreeVec(ArgArray);
  261.  
  262.                 /* Clone the current directory of our
  263.                  * process before we detach ourselves
  264.                  * from the starting Shell.
  265.                  */
  266.  
  267.             CurrentDir(RemoteCurrentDir = CurrentDir(NULL));
  268.             RemoteCurrentDir = DupLock(RemoteCurrentDir);
  269.  
  270.                 /* Create a new process from our code. */
  271.  
  272.             if(!Res("term Main Process",0,HandleInput,16384,FALSE))
  273.             {
  274.                 UnLock(RemoteCurrentDir);
  275.  
  276.                 Printf("\33[1mterm:\33[0m Failed to create new process!\a\n");
  277.  
  278.                 CloseAll();
  279.  
  280.                 return(RETURN_FAIL);
  281.             }
  282.         }
  283.         else
  284.         {
  285.             Printf("\33[1mterm:\33[0m Failed to allocate argument vectors!\a\n");
  286.  
  287.             CloseLibrary(DOSBase);
  288.  
  289.             return(RETURN_FAIL);
  290.         }
  291.     }
  292.     else
  293.     {
  294.             /* Initialize this, so OpenAll will work with
  295.              * correct data.
  296.              */
  297.  
  298.         TermPort = (struct TermPort *)FindPort("term Port");
  299.  
  300.             /* We were called from Workbench. */
  301.  
  302.         if(Result = OpenAll())
  303.         {
  304.             if(IntuitionBase && Result[0])
  305.                 MyEasyRequest(NULL,"term has a problem:\n%s!","Continue",Result);
  306.  
  307.             CloseAll();
  308.         }
  309.         else
  310.             HandleInput();
  311.     }
  312.  
  313.     return(RETURN_OK);
  314. }
  315.  
  316.     /* HandleInput():
  317.      *
  318.      *    This is our main input loop (check window & serial).
  319.      */
  320.  
  321. VOID
  322. HandleInput()
  323. {
  324.     ULONG SignalSet,SavageSignals;
  325.  
  326.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  327.  
  328.         /* Return to the previous current directory
  329.          * (so that file requesters and the like
  330.          * will know where to start).
  331.          */
  332.  
  333.     if(RemoteCurrentDir)
  334.     {
  335.         CurrentDir(RemoteCurrentDir);
  336.  
  337.         /* Oops, some data still remains and needs to
  338.          * be cleared.
  339.          */
  340.  
  341.         ThisProcess -> pr_CIS        = NULL;
  342.         ThisProcess -> pr_COS        = NULL;
  343.  
  344.         ThisProcess -> pr_ConsoleTask    = NULL;
  345.         ThisProcess -> pr_CLI        = NULL;
  346.     }
  347.  
  348.         /* Open the resources we need. */
  349.  
  350.     if(!ThisProcess -> pr_CLI && !WBenchMsg)
  351.     {
  352.         UBYTE *Result;
  353.  
  354.         if(Result = OpenAll())
  355.         {
  356.             if(IntuitionBase && Result[0])
  357.                 MyEasyRequest(NULL,"term has a problem:\n%s!","Continue",Result);
  358.  
  359.             CloseAll();
  360.  
  361.             return;
  362.         }
  363.     }
  364.  
  365.     BumpWindow(Window);
  366.  
  367.         /* Set up the public screen data. */
  368.  
  369.     PubScreenStuff();
  370.  
  371.         /* Show our business card. */
  372.  
  373.     BlockWindows();
  374.  
  375.     ShowInfo(TRUE);
  376.  
  377.     ReleaseWindows();
  378.  
  379.         /* Initialize the modem. */
  380.  
  381.     SerialCommand(Config . ModemInit);
  382.  
  383.         /* Execute the startup macro (if any). */
  384.  
  385.     if(Config . StartupMacro[0])
  386.         SerialCommand(Config . StartupMacro);
  387.  
  388.     LogAction("Program started (%s %s).",TermName,TermDate);
  389.  
  390.         /* Go into input loop... */
  391.  
  392. Loop:    while(!Terminated)
  393.     {
  394.             /* We did a file transfer (auto-download?) and
  395.              * will need to close the transfer window.
  396.              */
  397.  
  398.         if(TransferWindow)
  399.         {
  400.             WakeUp(TransferWindow);
  401.  
  402.             DeleteTransferPanel();
  403.  
  404.             ReleaseWindows();
  405.  
  406.             Say("Transfer completed.");
  407.         }
  408.  
  409.             /* For debugging purposes only: feed a file
  410.              * to the `term' display.
  411.              */
  412.  
  413. #ifndef DONT_DEBUG
  414.         if(TermHelp && (DebugConsole || DebugFile))
  415.         {
  416.             LONG HelpChar;
  417.  
  418.             while((HelpChar = FGetC(TermHelp)) != -1)
  419.             {
  420.                 UBYTE Dummy = HelpChar;
  421.  
  422.                 ConProcess(&Dummy,1);
  423.  
  424.                 HandleWindow();
  425.  
  426.                 if(!TermHelp)
  427.                     break;
  428.             }
  429.  
  430.             if(TermHelp)
  431.             {
  432.                 Close(TermHelp);
  433.                 TermHelp = NULL;
  434.             }
  435.         }
  436. #endif /* DONT_DEBUG */
  437.  
  438.         SavageSignals = NULL;
  439.  
  440.             /* The serial line is active. */
  441.  
  442.         if(Status != STATUS_HOLDING && ReadPort)
  443.             SavageSignals |= SIG_SERIAL;
  444.  
  445.             /* The packet window is still open. */
  446.  
  447.         if(PacketWindow)
  448.             SavageSignals |= SIG_PACKET;
  449.  
  450.             /* Wait for input events to occur. */
  451.  
  452.         SignalSet = Wait(SIG_WINDOW | SIG_REXX | SIG_AUDIO | SavageSignals);
  453.  
  454.             /* Loop & check until the dust has settled. */
  455.  
  456.         if(SignalSet & (SIG_WINDOW | SavageSignals))
  457.             while(HandleWindow() || HandleSerial() || HandlePacket());
  458.  
  459.             /* Remove audio request. */
  460.  
  461.         if(SignalSet & SIG_AUDIO)
  462.             WaitIO(AudioBlock);
  463.  
  464.             /* Check if we are to prompt the user for
  465.              * ZModem upload type.
  466.              */
  467.  
  468.         if(UsesZModem)
  469.         {
  470.             if(FlowInfo . ZModemUpload)
  471.             {
  472.                 FlowInit();
  473.  
  474.                 BlockWindows();
  475.  
  476.                 if(UploadPanel() == 1)
  477.                     BinaryTransfer = FALSE;
  478.  
  479.                 StartXprSend(BinaryTransfer ? TRANSFER_BINARY : TRANSFER_TEXT);
  480.  
  481.                 ReleaseWindows();
  482.             }
  483.         }
  484.  
  485.             /* Make the user notice not too obvious events. */
  486.  
  487.         if((FlowInfo . Voice || FlowInfo . Ring) && Online)
  488.         {
  489.             BumpWindow(Window);
  490.  
  491.             if(FlowInfo . Voice)
  492.                 ConWrites("\r\nIncoming call!\r\n\r\n");
  493.             else
  494.                 ConWrites("\r\nIncoming voice call!\r\n\r\n");
  495.  
  496.             Say("Incoming call.");
  497.  
  498.             FlowInit();
  499.         }
  500.  
  501.             /* Check for rexx messages to be processed. */
  502.  
  503.         if(SignalSet & SIG_REXX)
  504.             HandleRexx();
  505.  
  506.         if(!Online && CurrentPay)
  507.         {
  508.                 /* Display how much we expect
  509.                  * the user will have to pay for
  510.                  * this call.
  511.                  */
  512.  
  513.             ConWrites("\r\nThis call will cost you %ld.%02ld.\r\n\r\n",CurrentPay / 100,CurrentPay % 100);
  514.  
  515.             CurrentPay = 0;
  516.         }
  517.  
  518.             /* We did a file transfer (auto-download?) and
  519.              * will need to close the transfer window.
  520.              */
  521.  
  522.         if(TransferWindow)
  523.         {
  524.             WakeUp(TransferWindow);
  525.  
  526.             DeleteTransferPanel();
  527.  
  528.             ReleaseWindows();
  529.  
  530.             Say("Transfer completed.");
  531.         }
  532.  
  533.         if(ResetSerial)
  534.         {
  535.             FlushSerial();
  536.  
  537.             DeleteSerial();
  538.  
  539.             BlockWindows();
  540.  
  541. OpenLoop:        if(!CreateSerial())
  542.             {
  543.                 APTR OldPtr = ThisProcess -> pr_WindowPtr;
  544.  
  545.                 DeleteSerial();
  546.  
  547.                 ThisProcess -> pr_WindowPtr = (APTR)Window;
  548.  
  549.                 switch(MyEasyRequest(Window,"term has a problem:\nFailed to open %s!","Retry|Ignore|Quit term",Config . SerialDevice))
  550.                 {
  551.                     case 1:        goto OpenLoop;
  552.                     case 2:        break;
  553.                     case 0:        Terminated = TRUE;
  554.                 }
  555.  
  556.                 ThisProcess -> pr_WindowPtr = OldPtr;
  557.             }
  558.             else
  559.                 ResetSerial = TRUE;
  560.  
  561.             ReleaseWindows();
  562.         }
  563.  
  564.             /* We are to release the serial.device (or
  565.              * whatever we are using) for some reason.
  566.              */
  567.  
  568.         if(ReleaseSerial)
  569.         {
  570.             APTR OldPtr = ThisProcess -> pr_WindowPtr;
  571.  
  572.             ThisProcess -> pr_WindowPtr = (APTR)Window;
  573.  
  574.                 /* This might happen if an ARexx user
  575.                  * released the serial device and
  576.                  * failed to reopen it.
  577.                  */
  578.  
  579.             if(!ReadPort)
  580.                 goto OpenIt;
  581.  
  582.             FlushSerial();
  583.  
  584.             DeleteSerial();
  585.  
  586.             BlockWindows();
  587.  
  588.             if(MyEasyRequest(Window,"%s unit %ld has been reset and released.\nClick below to continue.","Continue|Quit term",Config . SerialDevice,Config . UnitNumber))
  589.             {
  590. OpenIt:                if(!CreateSerial())
  591.                 {
  592.                     DeleteSerial();
  593.  
  594.                     switch(MyEasyRequest(Window,"term has a problem:\nFailed to open %s!","Retry|Ignore|Quit term",Config . SerialDevice))
  595.                     {
  596.                         case 1:        goto OpenIt;
  597.                         case 2:        break;
  598.                         case 0:        Terminated = TRUE;
  599.                     }
  600.                 }
  601.             }
  602.             else
  603.                 Terminated = TRUE;
  604.  
  605.             ReleaseSerial = FALSE;
  606.  
  607.             ThisProcess -> pr_WindowPtr = OldPtr;
  608.  
  609.             ReleaseWindows();
  610.         }
  611.  
  612.             /* Somebody told us to re-open the display
  613.              * (changed the terminal emulation/colour
  614.              * mode).
  615.              */
  616.  
  617.         if(ResetDisplay)
  618.         {
  619.             UBYTE *Result;
  620.  
  621.                 /* Delete the display (if possible).
  622.                  * This will go wrong if there
  623.                  * are any visitor windows on our
  624.                  * screen.
  625.                  */
  626.  
  627.             if(DeleteDisplay())
  628.             {
  629.                 if(Result = CreateDisplay(FALSE))
  630.                 {
  631.                     ThisProcess -> pr_WindowPtr = (APTR)Window;
  632.  
  633.                     MyEasyRequest(NULL,"term has a problem:\n%s!","Continue",Result);
  634.  
  635.                     Terminated = TRUE;
  636.                 }
  637.  
  638.                 BumpWindow(Window);
  639.  
  640.                 PubScreenStuff();
  641.             }
  642.             else
  643.             {
  644.                 CopyMem(&PrivateConfig,&Config,sizeof(struct Configuration));
  645.  
  646.                 BlockWindows();
  647.  
  648.                 MyEasyRequest(Window,"term has a problem:\nCannot close screen yet!","Continue");
  649.  
  650.                 ReleaseWindows();
  651.             }
  652.  
  653.             ResetDisplay = FALSE;
  654.         }
  655.  
  656.         if(SendStartup && Online)
  657.         {
  658.             if(Config . StartupMacro[0])
  659.                 SerialCommand(Config . StartupMacro);
  660.  
  661.             SendStartup = FALSE;
  662.         }
  663.     }
  664.  
  665.         /* User wants to quit term, so let's try to close
  666.          * our magnificient screen and exit.
  667.          */
  668.  
  669.     if(Screen)
  670.     {
  671.         struct List        *PubScreenList;
  672.         struct PubScreenNode    *ScreenNode;
  673.  
  674.             /* Lock the list of public screens. */
  675.  
  676.         PubScreenList = LockPubScreenList();
  677.  
  678.             /* Scan the list and try to find our
  679.              * private node.
  680.              */
  681.  
  682.         for(ScreenNode = (struct PubScreenNode *)PubScreenList -> lh_Head ; ScreenNode -> psn_Node . ln_Succ ; ScreenNode = (struct PubScreenNode *)ScreenNode -> psn_Node . ln_Succ)
  683.         {
  684.             if(ScreenNode -> psn_Screen == Screen)
  685.                 break;
  686.         }
  687.  
  688.         if(ScreenNode)
  689.         {
  690.                 /* Okay, we know who and where we are,
  691.                  * check the number of visitor windows
  692.                  * currently open on our screen.
  693.                  */
  694.  
  695.             if(ScreenNode -> psn_VisitorCount)
  696.             {
  697.                     /* No chance, don't close
  698.                      * the screen now.
  699.                      */
  700.  
  701.                 UnlockPubScreenList();
  702.  
  703.                 BlockWindows();
  704.  
  705.                 MyEasyRequest(Window,"term has a problem:\nCannot close screen yet!","Continue");
  706.  
  707.                 ReleaseWindows();
  708.  
  709.                 Terminated = FALSE;
  710.  
  711.                 goto Loop;
  712.             }
  713.         }
  714.  
  715.         UnlockPubScreenList();
  716.     }
  717.  
  718.         /* Send the modem exit command, shut down the
  719.          * serial.device and close all resources.
  720.          */
  721.  
  722.     SerialCommand(Config . ModemExit);
  723.  
  724.     FlushSerial();
  725.  
  726.     LogAction("Program terminated.");
  727.  
  728. #ifndef DONT_DEBUG
  729.     if(TermHelp)
  730.         Close(TermHelp);
  731. #endif /* DONT_DEBUG */
  732.  
  733.     Say("Bye bye.");
  734.  
  735.     if(!ThisProcess -> pr_CLI)
  736.         CloseAll();
  737. }
  738.  
  739.     /* HandleWindow():
  740.      *
  741.      *    This funny part checks the window(s) for incoming
  742.      *    user input. Menus are handled elsewhere.
  743.      */
  744.  
  745. BYTE
  746. HandleWindow()
  747. {
  748.     struct IntuiMessage    *Massage;
  749.     ULONG             Class,Code,Qualifier;
  750.     struct Gadget        *Gadget;
  751.     UBYTE             Char,InputBuffer[257];
  752.  
  753.         /* Any news in the mail? */
  754.  
  755.     if(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  756.     {
  757.             /* Perform key conversion. */
  758.  
  759.         Char = KeyConvert(Massage,InputBuffer);
  760.  
  761.             /* Pick up the pieces. */
  762.  
  763.         Class        = Massage -> Class;
  764.         Code        = Massage -> Code;
  765.         Qualifier    = Massage -> Qualifier;
  766.  
  767.         Gadget        = (struct Gadget *)Massage -> IAddress;
  768.  
  769.         ReplyMsg(Massage);
  770.  
  771.             /* This looks like a raw key. */
  772.  
  773.         if(Class == IDCMP_RAWKEY)
  774.         {
  775.                 /* Make it a vanilla key if
  776.                  * possible. I didn't set
  777.                  * both VANILLAKEY & RAWKEY
  778.                  * since I prefer to convert
  779.                  * a few keys on my own and
  780.                  * I am not really sure whether
  781.                  * cooked key input includes
  782.                  * double-dead keys.
  783.                  */
  784.  
  785.             if(Char)
  786.             {
  787.                     /* VT100 prefers to handle
  788.                      * the numeric keypad differently
  789.                      * in applications mode.
  790.                      */
  791.  
  792.                 if(Qualifier & IEQUALIFIER_NUMERICPAD)
  793.                 {
  794.                     if(HandleCursor(Char))
  795.                         goto SkipIt;
  796.                 }
  797.  
  798.                     /* If input is not a control
  799.                      * character, such as F-keys,
  800.                      * cursor keys, etc. process
  801.                      * it as usual.
  802.                      */
  803.  
  804.                 if(!IsControl(Char))
  805.                 {
  806.                     SHORT i;
  807.  
  808.                         /* Run down the contents of
  809.                          * the key result string.
  810.                          */
  811.  
  812.                     for(i = 0 ; i < strlen(InputBuffer) ; i++)
  813.                     {
  814.                             /* Restart serial line
  815.                              * after XON.
  816.                              */
  817.  
  818.                         if(Status == STATUS_HOLDING)
  819.                         {
  820.                             if(InputBuffer[i] == XOF)
  821.                             {
  822.                                 SerWrite(&InputBuffer[i],1);
  823.  
  824.                                 Status = STATUS_READY;
  825.                             }
  826.                             else
  827.                                 DoSomeBeep();
  828.                         }
  829.                         else
  830.                         {
  831.                                 /* Convert chars
  832.                                  * as approriate.
  833.                                  */
  834.  
  835.                             if(InputBuffer[i] == '\n')
  836.                             {
  837.                                 switch(Config . SendLF)
  838.                                 {
  839.                                     case LF_IGNORE:    break;
  840.  
  841.                                     case LF_ASLF:    goto SendIt;
  842.  
  843.                                     case LF_ASLFCR:    SerWrite("\n\r",2);
  844.                                             break;
  845.                                 }
  846.  
  847.                                 continue;
  848.                             }
  849.  
  850.                             if(InputBuffer[i] == '\r')
  851.                             {
  852.                                 switch(Config . SendCR)
  853.                                 {
  854.                                     case CR_IGNORE:    break;
  855.  
  856.                                     case CR_ASCR:    goto SendIt;
  857.  
  858.                                     case CR_ASCRLF:    SerWrite("\r\n",2);
  859.                                             break;
  860.                                 }
  861.  
  862.                                 continue;
  863.                             }
  864.  
  865.                                 /* Stop in/output. */
  866.  
  867.                             if(InputBuffer[i] == XON)
  868.                             {
  869.                                 if(Config . Handshaking == HANDSHAKING_XONXOFF)
  870.                                     Status = STATUS_HOLDING;
  871.                             }
  872.  
  873.                                 /* Convert special
  874.                                  * Amiga characters into
  875.                                  * alien IBM dialect.
  876.                                  */
  877.  
  878. SendIt:                            if(Config . Font == FONT_IBM)
  879.                             {
  880.                                 if(IBMConversion[InputBuffer[i]])
  881.                                     SerWrite(&IBMConversion[InputBuffer[i]],1);
  882.                                 else
  883.                                     SerWrite(&InputBuffer[i],1);
  884.                             }
  885.                             else
  886.                                 SerWrite(&InputBuffer[i],1);
  887.                         }
  888.                     }
  889.                 }
  890.                 else
  891.                 {
  892.                         /* Send keyboard macro commands
  893.                          * or perform cursor functions.
  894.                          */
  895.  
  896.                     if(Char >= FN1 && Char <= F10)
  897.                     {
  898.                         if(Qualifier & IEQUALIFIER_CONTROL)
  899.                             SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
  900.                         else
  901.                         {
  902.                             if(Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT))
  903.                                 SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
  904.                             else
  905.                             {
  906.                                 if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  907.                                     SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
  908.                                 else
  909.                                     SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
  910.                             }
  911.                         }
  912.                     }
  913.                     else
  914.                     {
  915. #ifndef DONT_DEBUG
  916.                         if(Char == HLP && (DebugConsole || DebugFile))
  917.                         {
  918.                             if(TermHelp)
  919.                             {
  920.                                 Close(TermHelp);
  921.                                 TermHelp = NULL;
  922.                             }
  923.                             else
  924.                             {
  925.                                 struct FileRequester    *FileRequest;
  926.                                 UBYTE             DummyBuffer[256];
  927.  
  928.                                 BlockWindows();
  929.  
  930.                                 if(FileRequest = GetFile("Load Test File...","","",DummyBuffer,"#?.ansi",FALSE,FALSE))
  931.                                     TermHelp = Open(DummyBuffer,MODE_OLDFILE);
  932.  
  933.                                 ReleaseWindows();
  934.                             }
  935.                         }
  936.                         else
  937. #endif /* DONT_DEBUG */
  938.                             HandleCursor(Char);
  939.                     }
  940.                 }
  941.             }
  942.         }
  943.  
  944.             /* Capture characters from the main
  945.              * screen.
  946.              */
  947.  
  948.         if(Class == IDCMP_MOUSEBUTTONS && Code == SELECTDOWN)
  949.         {
  950.             BYTE SingleChar,Xerox;
  951.  
  952.                 /* We want to know where the mouse
  953.                  * moves...
  954.                  */
  955.  
  956.             ReportMouse(TRUE,Window);
  957.  
  958.                 /* Pick a single character. */
  959.  
  960.             if(Qualifier & IEQUALIFIER_CONTROL)
  961.                 SingleChar = TRUE;
  962.             else
  963.                 SingleChar = FALSE;
  964.  
  965.                 /* Xerox style snapping (feed into
  966.                  * input stream after selection).
  967.                  */
  968.  
  969.             if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  970.                 Xerox = TRUE;
  971.             else
  972.                 Xerox = FALSE;
  973.  
  974.             RasterClip(SingleChar,Xerox);
  975.  
  976.             ReportMouse(FALSE,Window);
  977.         }
  978.  
  979.             /* A menu item was selected. */
  980.  
  981. SkipIt:        if(Class == IDCMP_MENUPICK)
  982.             HandleMenu(Code);
  983.  
  984.         return(TRUE);
  985.     }
  986.  
  987.     return(FALSE);
  988. }
  989.  
  990.     /* HandleSerial():
  991.      *
  992.      *    Handle the data coming in from the serial line.
  993.      */
  994.  
  995. BYTE
  996. HandleSerial()
  997. {
  998.         /* We are XON'ed or the serial line was shut down. */
  999.  
  1000.     if(Status != STATUS_HOLDING && ReadPort && !ReleaseSerial && !Terminated)
  1001.     {
  1002.             /* Any news? */
  1003.  
  1004.         if(CheckIO(ReadRequest))
  1005.         {
  1006.             LONG Length;
  1007.  
  1008.             if(WaitIO(ReadRequest))
  1009.                 return(FALSE);
  1010.  
  1011.                 /* Process the data if necessary (XPR-function). */
  1012.  
  1013.             if(TransferBits & XPRS_HOSTMON)
  1014.                 if(!XProtocolHostMon(XprIO,ReadBuffer,1,1))
  1015.                     goto Loop;
  1016.  
  1017.                 /* Send the byte to the console. */
  1018.  
  1019.             ConProcess(ReadBuffer,1);
  1020.  
  1021.                 /* Loop until all data has been processed. */
  1022.  
  1023. Loop:            do
  1024.             {
  1025.                     /* Check how many bytes are still in
  1026.                      * the serial buffer.
  1027.                      */
  1028.  
  1029.                 WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1030.                 DoIO(WriteRequest);
  1031.  
  1032.                 if(Length = WriteRequest -> IOSer . io_Actual)
  1033.                 {
  1034.                     if(Length > 1024)
  1035.                         Length = 1024;
  1036.  
  1037.                     ReadRequest -> IOSer . io_Command    = CMD_READ;
  1038.                     ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1039.                     ReadRequest -> IOSer . io_Length    = Length;
  1040.  
  1041.                     DoIO(ReadRequest);
  1042.  
  1043.                         /* Process the serial data if
  1044.                          * necessary (XPR-stuff).
  1045.                          */
  1046.  
  1047.                     if(TransferBits & XPRS_HOSTMON)
  1048.                     {
  1049.                         if(!(Length = XProtocolHostMon(XprIO,ReadBuffer,Length,1024)))
  1050.                         {
  1051.                             Length = 1;
  1052.                             continue;
  1053.                         }
  1054.                     }
  1055.  
  1056.                         /* Send the data to the console. */
  1057.  
  1058.                     ConProcess(ReadBuffer,Length);
  1059.                 }
  1060.             }
  1061.             while(Length);
  1062.  
  1063.                 /* Ask for another byte. */
  1064.  
  1065.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  1066.             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1067.             ReadRequest -> IOSer . io_Length     = 1;
  1068.  
  1069.             SendIO(ReadRequest);
  1070.  
  1071.             return(TRUE);
  1072.         }
  1073.     }
  1074.  
  1075.     return(FALSE);
  1076. }
  1077.  
  1078.     /* HandleMenu(ULONG Code):
  1079.      *
  1080.      *    Skip along the number of selected menu items and
  1081.      *    handle the associated functions.
  1082.      */
  1083.  
  1084. VOID
  1085. HandleMenu(ULONG Code)
  1086. {
  1087.     STATIC UBYTE         NumberBuffer[256];
  1088.  
  1089.     struct MenuItem        *MenuItem;
  1090.     struct FileRequester    *FileRequest;
  1091.     UBYTE             DummyBuffer[256],*DummyChar;
  1092.     BYTE             OldStatus;
  1093.  
  1094.     struct List        *DialList;
  1095.     LONG             DialListNum;
  1096.  
  1097.     LONG             Size;
  1098.     BPTR             SomeFile;
  1099.     APTR             OldPtr;
  1100.  
  1101.         /* Check until the last menuitem has been
  1102.          * processed.
  1103.          */
  1104.  
  1105.     while(Code != MENUNULL)
  1106.     {
  1107.             /* Pick up the associated menu item. */
  1108.  
  1109.         if(!(MenuItem = ItemAddress(Menu,Code)))
  1110.             break;
  1111.  
  1112.         OldStatus = Status;
  1113.  
  1114.             /* Now call the approriate routine. */
  1115.  
  1116.         switch((ULONG)MENU_USERDATA(MenuItem))
  1117.         {
  1118.                 /* Say who we are. */
  1119.  
  1120.             case MEN_ABOUT:        BlockWindows();
  1121.  
  1122.                         ShowInfo(FALSE);
  1123.  
  1124.                         ReleaseWindows();
  1125.  
  1126.                         break;
  1127.  
  1128.                 /* Open the preferences settings. */
  1129.  
  1130.             case MEN_OPEN:        BlockWindows();
  1131.  
  1132.                         strcpy(DummyBuffer,LastConfig);
  1133.  
  1134.                         DummyChar = PathPart(DummyBuffer);
  1135.  
  1136.                         *DummyChar = 0;
  1137.  
  1138.                         if(FileRequest = GetFile("Open Preferences...",DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.term",FALSE,FALSE))
  1139.                         {
  1140.                             if(ReadIFFData(DummyBuffer,&PrivateConfig,sizeof(struct Configuration),'PREF'))
  1141.                             {
  1142.                                 swmem(&PrivateConfig,&Config,sizeof(struct Configuration));
  1143.  
  1144.                                 strcpy(DummyBuffer,LastConfig);
  1145.  
  1146.                                 ConfigSetup();
  1147.                             }
  1148.                             else
  1149.                                 MyEasyRequest(Window,"Error opening file\n%s!","Continue",DummyBuffer);
  1150.  
  1151.                             FreeAslRequest(FileRequest);
  1152.                         }
  1153.  
  1154.                         ReleaseWindows();
  1155.  
  1156.                         break;
  1157.  
  1158.                 /* Save the terminal preferences. */
  1159.  
  1160.             case MEN_SAVE:        if(LastConfig[0])
  1161.                         {
  1162.                             BlockWindows();
  1163.  
  1164.                             if(!WriteIFFData(LastConfig,&Config,sizeof(struct Configuration),'PREF'))
  1165.                                 MyEasyRequest(Window,"Error writing preferences to\nfile %s!","Continue",LastConfig);
  1166.  
  1167.                             ReleaseWindows();
  1168.                         }
  1169.  
  1170.                         break;
  1171.  
  1172.                 /* Save the terminal preferences to a
  1173.                  * given file name.
  1174.                  */
  1175.  
  1176.             case MEN_SAVEAS:    BlockWindows();
  1177.  
  1178.                         strcpy(DummyBuffer,LastConfig);
  1179.  
  1180.                         DummyChar = PathPart(DummyBuffer);
  1181.  
  1182.                         *DummyChar = 0;
  1183.  
  1184.                         if(FileRequest = GetFile("Save Preferences As...",DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.term",TRUE,FALSE))
  1185.                         {
  1186.                             if(WriteIFFData(DummyBuffer,&Config,sizeof(struct Configuration),'PREF'))
  1187.                                 strcpy(LastConfig,DummyBuffer);
  1188.                             else
  1189.                                 MyEasyRequest(Window,"Error writing preferences to\nfile %s!","Continue",DummyBuffer);
  1190.  
  1191.                             FreeAslRequest(FileRequest);
  1192.                         }
  1193.  
  1194.                         ReleaseWindows();
  1195.  
  1196.                         break;
  1197.  
  1198.                 /* Print the screen (pure ASCII). */
  1199.  
  1200.             case MEN_PRINTSCREEN:    BlockWindows();
  1201.  
  1202.                         if(SomeFile = Open("PRT:",MODE_NEWFILE))
  1203.                         {
  1204.                             SHORT i;
  1205.  
  1206.                             for(i = 0 ; i < RasterHeight ; i++)
  1207.                             {
  1208.                                 if(!FWrite(SomeFile,&Raster[i * RasterWidth],RasterWidth,1))
  1209.                                     break;
  1210.  
  1211.                                 if(!FWrite(SomeFile,"\n",1,1))
  1212.                                     break;
  1213.                             }
  1214.  
  1215.                             Close(SomeFile);
  1216.                         }
  1217.                         else
  1218.                             MyEasyRequest(Window,"Failed to open device PRT:!","Continue");
  1219.  
  1220.                         ReleaseWindows();
  1221.  
  1222.                         break;
  1223.  
  1224.                 /* Terminate the program. */
  1225.  
  1226.             case MEN_QUIT:        BlockWindows();
  1227.  
  1228.                         OldPtr = ThisProcess -> pr_WindowPtr;
  1229.  
  1230.                         ThisProcess -> pr_WindowPtr = (APTR)Window;
  1231.  
  1232.                         if(MyEasyRequest(Window,"Do you really want to quit term?","Yes|No"))
  1233.                             Terminated = TRUE;
  1234.  
  1235.                         ThisProcess -> pr_WindowPtr = OldPtr;
  1236.  
  1237.                         ReleaseWindows();
  1238.  
  1239.                         break;
  1240.  
  1241.                 /* Set the name we will use to open the
  1242.                  * default console output window for
  1243.                  * AmigaDOS commands and ARexx scripts.
  1244.                  */
  1245.  
  1246.             case MEN_SETCONSOLE:    BlockWindows();
  1247.  
  1248.                         if(xpr_gets("Set Console Window",WindowName))
  1249.                             SetEnvDOS("TERMWINDOW",WindowName);
  1250.  
  1251.                         ReleaseWindows();
  1252.  
  1253.                         break;
  1254.  
  1255.                 /* Execute an AmigaDOS command. */
  1256.  
  1257.             case MEN_DOSCOMMAND:    BlockWindows();
  1258.  
  1259.                         DummyBuffer[0] = 0;
  1260.  
  1261.                             /* Enter the name of the command. */
  1262.  
  1263.                         if(GetString("Enter AmigaDOS Command",DummyBuffer))
  1264.                             SendAmigaDOSCommand(DummyBuffer);
  1265.  
  1266.                         ReleaseWindows();
  1267.  
  1268.                         break;
  1269.  
  1270.                 /* Execute an ARexx script command. */
  1271.  
  1272.             case MEN_REXXCOMMAND:    BlockWindows();
  1273.  
  1274.                         DummyBuffer[0] = 0;
  1275.  
  1276.                             /* Get the rexx file name/program. */
  1277.  
  1278.                         if(GetString("Enter ARexx Command",DummyBuffer))
  1279.                             SendARexxCommand(DummyBuffer);
  1280.  
  1281.                         ReleaseWindows();
  1282.  
  1283.                         break;
  1284.  
  1285.                 /* Edit a file. */
  1286.  
  1287.             case MEN_EDIT:        BlockWindows();
  1288.  
  1289.                         if(!Config . Editor[0])
  1290.                             GetString("Enter Name Of Editor To Use",&Config . Editor[0]);
  1291.  
  1292.                         if(Config . Editor[0])
  1293.                         {
  1294.                             if(FileRequest = GetFile("Edit File...","","",DummyBuffer,NULL,FALSE,FALSE))
  1295.                             {
  1296.                                 UBYTE CompoundName[512];
  1297.                                 ULONG TagEnd = TAG_END;
  1298.  
  1299.                                 strcpy(CompoundName,Config . Editor);
  1300.                                 strcat(CompoundName," ");
  1301.                                 strcat(CompoundName,DummyBuffer);
  1302.  
  1303.                                 System(CompoundName,&TagEnd);
  1304.  
  1305.                                 BumpWindow(Window);
  1306.  
  1307.                                 FreeAslRequest(FileRequest);
  1308.                             }
  1309.                         }
  1310.  
  1311.                         ReleaseWindows();
  1312.                         break;
  1313.  
  1314.                 /* Feed the contents of the clipboard
  1315.                  * into the input stream.
  1316.                  */
  1317.  
  1318.             case MEN_PASTE:        if(Size = LoadClip(SharedBuffer,256))
  1319.                             SerWrite(SharedBuffer,Size);
  1320.  
  1321.                         break;
  1322.  
  1323.                 /* Open the packet window if necessary, else
  1324.                  * just activate it.
  1325.                  */
  1326.  
  1327.             case MEN_PACKET:    if(!PacketWindow)
  1328.                             CreatePacketWindow();
  1329.                         else
  1330.                             ActivateWindow(PacketWindow);
  1331.  
  1332.                         break;
  1333.  
  1334.                 /* Clear the contents of the scrollback
  1335.                  * buffer.
  1336.                  */
  1337.  
  1338.             case MEN_CLEARBUFFER:    if(Lines)
  1339.                         {
  1340.                             BlockWindows();
  1341.  
  1342.                             if(MyEasyRequest(Window,"The buffer still holds %ld lines,\ndo you wish to discard them?","Yes|No",Lines))
  1343.                                 ClearBuffer();
  1344.  
  1345.                             ReleaseWindows();
  1346.                         }
  1347.  
  1348.                         break;
  1349.  
  1350.                 /* Display the scrollback buffer.
  1351.                  * Notify the scrollback task or
  1352.                  * fire it off if approriate.
  1353.                  */
  1354.  
  1355.             case MEN_DISPLAYBUFFER:    if(BufferProcess)
  1356.                             Signal(BufferProcess,SIGBREAKF_CTRL_D);
  1357.                         else
  1358.                         {
  1359.                             if(BufferProcess = (struct Process *)CreateNewProcTags(
  1360.                                 NP_Entry,    BufferServer,
  1361.                                 NP_Name,    "term Buffer Process",
  1362.                                 NP_Priority,    0,
  1363.                                 NP_StackSize,    8192,
  1364.                                 NP_WindowPtr,    -1,
  1365.                             TAG_END))
  1366.                                 Wait(SIGBREAKF_CTRL_C);
  1367.  
  1368.                             if(!BufferProcess)
  1369.                             {
  1370.                                 BlockWindows();
  1371.  
  1372.                                 MyEasyRequest(Window,"Unable to create buffer task!","Continue");
  1373.  
  1374.                                 ReleaseWindows();
  1375.                             }
  1376.                         }
  1377.  
  1378.                         break;
  1379.  
  1380.  
  1381.             case MEN_CLOSEBUFFER:    if(BufferProcess)
  1382.                             Signal(BufferProcess,SIGBREAKF_CTRL_C);
  1383.  
  1384.                         break;
  1385.  
  1386.             case MEN_LOADBUFFER:    BlockWindows();
  1387.  
  1388.                         if(FileRequest = GetFile("Load Buffer...","","",DummyBuffer,NULL,FALSE,FALSE))
  1389.                         {
  1390.                             if(GetFileSize(DummyBuffer))
  1391.                             {
  1392.                                 if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  1393.                                 {
  1394.                                     if(Lines)
  1395.                                     {
  1396.                                         switch(MyEasyRequest(Window,"The display buffer still holds %ld\nlines, do you wish to continue?","Discard Buffer|Append Buffer|Cancel",Lines))
  1397.                                         {
  1398.                                             case 1:    ClearBuffer();
  1399.                                                 break;
  1400.  
  1401.                                             case 2:    break;
  1402.  
  1403.                                             case 0:    Close(SomeFile);
  1404.                                                 SomeFile = NULL;
  1405.                                                 break;
  1406.                                         }
  1407.                                     }
  1408.  
  1409.                                     if(SomeFile)
  1410.                                     {
  1411.                                         LineRead(NULL,NULL,NULL);
  1412.  
  1413.                                         while(LineRead(SomeFile,DummyBuffer,80))
  1414.                                             StoreBuffer(DummyBuffer,strlen(DummyBuffer));
  1415.  
  1416.                                         Close(SomeFile);
  1417.                                     }
  1418.                                 }
  1419.                             }
  1420.  
  1421.                             FreeAslRequest(FileRequest);
  1422.                         }
  1423.  
  1424.                         ReleaseWindows();
  1425.                         break;
  1426.  
  1427.                 /* Save the contents of the scrollback
  1428.                  * buffer to a file (line by line).
  1429.                  */
  1430.  
  1431.             case MEN_SAVEBUFFER:    BlockWindows();
  1432.  
  1433.                         if(!Lines)
  1434.                             MyEasyRequest(Window,"There isn't anything in the\nbuffer right now.","Continue");
  1435.                         else
  1436.                         {
  1437.                             if(FileRequest = GetFile("Save Buffer...","","",DummyBuffer,NULL,TRUE,FALSE))
  1438.                             {
  1439.                                 SomeFile = NULL;
  1440.  
  1441.                                     /* If the file we are about
  1442.                                      * to create already exists,
  1443.                                      * ask the user whether we are
  1444.                                      * to create, append or skip
  1445.                                      * the file.
  1446.                                      */
  1447.  
  1448.                                 if(GetFileSize(DummyBuffer))
  1449.                                 {
  1450.                                     switch(MyEasyRequest(Window,"File %s already exists!","Create New File|Append Data|Cancel",DummyBuffer))
  1451.                                     {
  1452.                                         case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  1453.                                             break;
  1454.  
  1455.                                         case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  1456.                                             {
  1457.                                                 if(Seek(SomeFile,0,OFFSET_END) == -1)
  1458.                                                 {
  1459.                                                     Close(SomeFile);
  1460.  
  1461.                                                     SomeFile = NULL;
  1462.                                                 }
  1463.                                             }
  1464.  
  1465.                                             break;
  1466.                                     }
  1467.                                 }
  1468.                                 else
  1469.                                     SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  1470.  
  1471.                                 if(!SomeFile)
  1472.                                     MyEasyRequest(Window,"Error opening file %s!","Continue",DummyBuffer);
  1473.                                 else
  1474.                                 {
  1475.                                     LONG i;
  1476.  
  1477.                                         /* Obtain the semaphore required
  1478.                                          * to gain access to the line buffer
  1479.                                          */
  1480.  
  1481.                                     ObtainSemaphore(BufferSemaphore);
  1482.  
  1483.                                     for(i = 0 ; i < Lines ; i++)
  1484.                                     {
  1485.                                         if(FPrintf(SomeFile,"%s\n",BufferLines[i]) == -1)
  1486.                                             break;
  1487.                                     }
  1488.  
  1489.                                     ReleaseSemaphore(BufferSemaphore);
  1490.  
  1491.                                     Close(SomeFile);
  1492.  
  1493.                                     SetProtection(DummyBuffer,FIBF_EXECUTE);
  1494.                                 }
  1495.  
  1496.                                 FreeAslRequest(FileRequest);
  1497.                             }
  1498.                         }
  1499.  
  1500.                         ReleaseWindows();
  1501.  
  1502.                         break;
  1503.  
  1504.                 /* Open/close the terminal capture file. */
  1505.  
  1506.             case MEN_CAPTUREDISK:    if(FileCapture)
  1507.                         {
  1508.                             Close(FileCapture);
  1509.  
  1510.                             MenuItem -> Flags &= ~CHECKED;
  1511.  
  1512.                             FileCapture = NULL;
  1513.  
  1514.                             if(!GetFileSize(CaptureName))
  1515.                                 DeleteFile(CaptureName);
  1516.                             else
  1517.                                 SetProtection(CaptureName,FIBF_EXECUTE);
  1518.                         }
  1519.                         else
  1520.                         {
  1521.                             BlockWindows();
  1522.  
  1523.                             strcpy(DummyBuffer,CaptureName);
  1524.  
  1525.                             DummyChar = PathPart(DummyBuffer);
  1526.  
  1527.                             *DummyChar = 0;
  1528.  
  1529.                             if(FileRequest = GetFile("Capture To Disk...",DummyBuffer,FilePart(CaptureName),DummyBuffer,NULL,TRUE,FALSE))
  1530.                             {
  1531.                                 if(GetFileSize(DummyBuffer))
  1532.                                 {
  1533.                                     switch(MyEasyRequest(Window,"File %s already exists!","Create New File|Append Data|Cancel",DummyBuffer))
  1534.                                     {
  1535.                                         case 1:    FileCapture = Open(DummyBuffer,MODE_NEWFILE);
  1536.                                             break;
  1537.  
  1538.                                         case 2:    if(FileCapture = Open(DummyBuffer,MODE_READWRITE))
  1539.                                             {
  1540.                                                 if(Seek(FileCapture,0,OFFSET_END) == -1)
  1541.                                                 {
  1542.                                                     Close(FileCapture);
  1543.  
  1544.                                                     FileCapture = NULL;
  1545.                                                 }
  1546.                                             }
  1547.                                             break;
  1548.  
  1549.                                         case 0:    MenuItem -> Flags &= ~CHECKED;
  1550.                                             goto CapSkip;
  1551.                                     }
  1552.                                 }
  1553.                                 else
  1554.                                     FileCapture = Open(DummyBuffer,MODE_NEWFILE);
  1555.  
  1556.                                 if(!FileCapture)
  1557.                                 {
  1558.                                     MyEasyRequest(Window,"Error opening file %s!","Continue",DummyBuffer);
  1559.  
  1560.                                     MenuItem -> Flags &= ~CHECKED;
  1561.                                 }
  1562.                                 else
  1563.                                 {
  1564.                                     strcpy(CaptureName,DummyBuffer);
  1565.  
  1566.                                     MenuItem -> Flags |= CHECKED;
  1567.                                 }
  1568.  
  1569.                                 FreeAslRequest(FileRequest);
  1570.                             }
  1571.                             else
  1572.                                 MenuItem -> Flags &= ~CHECKED;
  1573.  
  1574. CapSkip:                        ReleaseWindows();
  1575.                         }
  1576.  
  1577.                         break;
  1578.  
  1579.                 /* Start/terminate the printer
  1580.                  * capture.
  1581.                  */
  1582.  
  1583.             case MEN_CAPTUREPRINTER:if(PrinterCapture)
  1584.                         {
  1585.                             Close(PrinterCapture);
  1586.  
  1587.                             MenuItem -> Flags &= ~CHECKED;
  1588.  
  1589.                             PrinterCapture = NULL;
  1590.                         }
  1591.                         else
  1592.                         {
  1593.                             if(PrinterCapture = Open("PRT:",MODE_NEWFILE))
  1594.                                 MenuItem -> Flags |= CHECKED;
  1595.                             else
  1596.                             {
  1597.                                 MenuItem -> Flags &= ~CHECKED;
  1598.  
  1599.                                 BlockWindows();
  1600.  
  1601.                                 MyEasyRequest(Window,"Error opening PRT: device!","Continue");
  1602.  
  1603.                                 ReleaseWindows();
  1604.                             }
  1605.                         }
  1606.  
  1607.                         break;
  1608.  
  1609.                 /* This follows the upload routines.
  1610.                  * Text upload makes the xpr_finfo function
  1611.                  * identify any file as being a text
  1612.                  * file (no voodoo magic yet).
  1613.                  */
  1614.  
  1615.             case MEN_UPLOADTEXT:    BinaryTransfer = FALSE;
  1616.  
  1617.                 /* The rest of the upload routines. */
  1618.  
  1619.             case MEN_UPLOAD:    BlockWindows();
  1620.  
  1621.                         StartXprSend(BinaryTransfer ? TRANSFER_BINARY : TRANSFER_TEXT);
  1622.  
  1623.                         BinaryTransfer = TRUE;
  1624.  
  1625.                         ReleaseWindows();
  1626.  
  1627.                         break;
  1628.  
  1629.             case MEN_DOWNLOADTEXT:    BinaryTransfer = FALSE;
  1630.  
  1631.                 /* Download some files. */
  1632.  
  1633.             case MEN_DOWNLOAD:    BlockWindows();
  1634.  
  1635.                         StartXprReceive(BinaryTransfer ? TRANSFER_BINARY : TRANSFER_TEXT);
  1636.  
  1637.                         BinaryTransfer = TRUE;
  1638.  
  1639.                         ReleaseWindows();
  1640.  
  1641.                         break;
  1642.  
  1643.                 /* Set the file transfer options. */
  1644.  
  1645.             case MEN_XFERPROTOCOL:    BlockWindows();
  1646.  
  1647.                         for(;;)
  1648.                         {
  1649.                             XprIO -> xpr_filename = NULL;
  1650.  
  1651.                             NewLibrary = FALSE;
  1652.  
  1653.                                 /* Set up the library options. */
  1654.  
  1655.                             if(XProtocolBase)
  1656.                             {
  1657.                                 TransferBits = XProtocolSetup(XprIO);
  1658.  
  1659.                                     /* Successful? */
  1660.  
  1661.                                 if(!(TransferBits & XPRS_SUCCESS))
  1662.                                 {
  1663.                                     MyEasyRequest(Window,"Failed to set up protocol\n\"%s\"!","Continue",LastXprLibrary);
  1664.  
  1665.                                     CloseLibrary(XProtocolBase);
  1666.  
  1667.                                     XProtocolBase = NULL;
  1668.  
  1669.                                     LastXprLibrary[0] = 0;
  1670.  
  1671.                                     TransferBits = 0;
  1672.  
  1673.                                     break;
  1674.                                 }
  1675.                             }
  1676.                             else
  1677.                                 xpr_options(0,NULL);
  1678.  
  1679.                                 /* Save the options if necessary. */
  1680.  
  1681.                             SaveProtocolOpts();
  1682.  
  1683.                             if(NewLibrary)
  1684.                             {
  1685.                                 if(!ProtocolSetup())
  1686.                                     break;
  1687.  
  1688.                                 strcpy(Config . Protocol,LastXprLibrary);
  1689.                             }
  1690.                             else
  1691.                                 break;
  1692.                         }
  1693.  
  1694.                         ReleaseWindows();
  1695.  
  1696.                         break;
  1697.  
  1698.                 /* Select the transfer protocol; I had hoped
  1699.                  * to get rid of this option but xprascii and
  1700.                  * the older pre-2.0 standard xpr-libraries
  1701.                  * forced it back in.
  1702.                  */
  1703.  
  1704.             case MEN_SELECTXFER:    BlockWindows();
  1705.  
  1706.                         NewLibrary = FALSE;
  1707.  
  1708.                         xpr_options(0,NULL);
  1709.  
  1710.                         if(NewLibrary)
  1711.                         {
  1712.                             if(ProtocolSetup())
  1713.                                 strcpy(Config . Protocol,LastXprLibrary);
  1714.                         }
  1715.  
  1716.                         ReleaseWindows();
  1717.  
  1718.                         break;
  1719.  
  1720.                 /* These routines simply switch the
  1721.                  * transfer library (to xprascii.library)
  1722.                  * and perform up/download. To lessen the
  1723.                  * confusion both routines have been
  1724.                  * implemented as single routines.
  1725.                  * After the transfer the control is
  1726.                  * returned to the previously selected
  1727.                  * transfer library.
  1728.                  */
  1729.  
  1730.             case MEN_SEND:        BlockWindows();
  1731.  
  1732.                         if(ASCIISetup())
  1733.                         {
  1734.                             StartXprSend(TRANSFER_ASCII);
  1735.  
  1736.                             ASCIIShutdown();
  1737.                         }
  1738.  
  1739.                         ReleaseWindows();
  1740.  
  1741.                         break;
  1742.  
  1743.             case MEN_RECEIVE:    BlockWindows();
  1744.  
  1745.                         if(ASCIISetup())
  1746.                         {
  1747.                             StartXprReceive(TRANSFER_ASCII);
  1748.  
  1749.                             ASCIIShutdown();
  1750.                         }
  1751.  
  1752.                         ReleaseWindows();
  1753.  
  1754.                         break;
  1755.  
  1756.                 /* Open the phonebook and dial the
  1757.                  * list of entries the user will select.
  1758.                  */
  1759.  
  1760.             case MEN_PHONEBOOK:    BlockWindows();
  1761.  
  1762.                         if(PhonePanel(&DialListNum))
  1763.                         {
  1764.                             DialPanel();
  1765.  
  1766.                             Status = OldStatus;
  1767.                         }
  1768.  
  1769.                         ReleaseWindows();
  1770.  
  1771.                         break;
  1772.  
  1773.                 /* Dial a single number. */
  1774.  
  1775.             case MEN_DIAL:        BlockWindows();
  1776.  
  1777.                         if(xpr_gets("Enter Phone Number",NumberBuffer))
  1778.                         {
  1779.                             if(DialList = (struct List *)AllocMem(sizeof(struct List),MEMF_PUBLIC | MEMF_CLEAR))
  1780.                             {
  1781.                                 struct PhoneNode *DialNode;
  1782.  
  1783.                                 NewList(DialList);
  1784.  
  1785.                                 if(DialNode = (struct PhoneNode *)AllocMem(sizeof(struct PhoneNode),MEMF_PUBLIC|MEMF_CLEAR))
  1786.                                 {
  1787.                                     DialNode -> VanillaNode . ln_Name = (UBYTE *)NumberBuffer;
  1788.  
  1789.                                     AddTail(DialList,&DialNode -> VanillaNode);
  1790.  
  1791.                                     FreeSubList();
  1792.  
  1793.                                     SubList        = DialList;
  1794.                                     SubListNum    = 1;
  1795.  
  1796.                                     DialPanel();
  1797.  
  1798.                                     Status = OldStatus;
  1799.                                 }
  1800.                                 else
  1801.                                     FreeMem(DialList,sizeof(struct List));
  1802.                             }
  1803.                         }
  1804.  
  1805.                         ReleaseWindows();
  1806.  
  1807.                         break;
  1808.  
  1809.                 /* Redial those dial list entries which
  1810.                  * we were unable to connect.
  1811.                  */
  1812.  
  1813.             case MEN_REDIAL:    BlockWindows();
  1814.  
  1815.                         if(SubList)
  1816.                         {
  1817.                             DialPanel();
  1818.  
  1819.                             Status = OldStatus;
  1820.                         }
  1821.                         else
  1822.                             MyEasyRequest(Window,"Current dialing list is empty.","Continue");
  1823.  
  1824.                         ReleaseWindows();
  1825.  
  1826.                         break;
  1827.  
  1828.                 /* Play a touch-tone phone number. */
  1829.  
  1830.             case MEN_PLAY:        BlockWindows();
  1831.  
  1832.                         if(xpr_gets("Enter Phone Number To Play",NumberBuffer))
  1833.                         {
  1834.                             if(!ToneDial(NumberBuffer))
  1835.                                 MyEasyRequest(NULL,"term has a problem:\n%s!","Continue","Failed to allocate resources for playing.");
  1836.                             else
  1837.                                 DeleteTone();
  1838.                         }
  1839.  
  1840.                         ReleaseWindows();
  1841.                         break;
  1842.  
  1843.                 /* Send a break across the serial line. */
  1844.  
  1845.             case MEN_SENDBREAK:    if(WriteRequest)
  1846.                         {
  1847.                             Status = STATUS_BREAKING;
  1848.  
  1849.                             WriteRequest -> IOSer . io_Command = SDCMD_BREAK;
  1850.                             DoIO(WriteRequest);
  1851.  
  1852.                             Status = OldStatus;
  1853.                         }
  1854.  
  1855.                         break;
  1856.  
  1857.                 /* Hang up the phone line. */
  1858.  
  1859.             case MEN_HANGUP:    Status = STATUS_HANGUP;
  1860.  
  1861.                         SerialCommand(Config . ModemHangup);
  1862.  
  1863.                         Status = OldStatus;
  1864.  
  1865.                         Online = FALSE;
  1866.  
  1867.                         Password[0] = 0;
  1868.  
  1869.                         LogAction("Hang up line.");
  1870.  
  1871.                         break;
  1872.  
  1873.                 /* Release the serial device for other
  1874.                  * applications.
  1875.                  */
  1876.  
  1877.             case MEN_RELEASE:    ReleaseSerial = TRUE;
  1878.                         break;
  1879.  
  1880.                 /* Reset the display styles and restore
  1881.                  * the colours.
  1882.                  */
  1883.  
  1884.             case MEN_RESETSTYLES:    Escape = TRUE;
  1885.  
  1886.                         ConProcess("\033[m",3);
  1887.  
  1888.                         Config . FontScale = SCALE_NORMAL;
  1889.  
  1890.                         switch(Config . ColourMode)
  1891.                         {
  1892.                             case COLOUR_EIGHT:    FgPen = 7;
  1893.                                         break;
  1894.  
  1895.                             case COLOUR_SIXTEEN:    FgPen = 15;
  1896.                                         break;
  1897.  
  1898.                             case COLOUR_AMIGA:
  1899.                             default:        FgPen = 1;
  1900.                                         break;
  1901.                         }
  1902.  
  1903.                         BgPen = 0;
  1904.  
  1905.                         if(RPort -> FgPen != FgPen)
  1906.                             SetAPen(RPort,FgPen);
  1907.  
  1908.                         if(RPort -> BgPen != BgPen)
  1909.                             SetBPen(RPort,BgPen);
  1910.  
  1911.                         Escape = FALSE;
  1912.  
  1913.                         break;
  1914.  
  1915.                 /* Simply clear the screen and move the
  1916.                  * cursor to its home position.
  1917.                  */
  1918.  
  1919.             case MEN_CLEARSCREEN:    Escape = TRUE;
  1920.  
  1921.                         ConProcess("\033[2J\033[H",7);
  1922.  
  1923.                         Escape = FALSE;
  1924.  
  1925.                         break;
  1926.  
  1927.                 /* Save screen as IFF-ILBM file. */
  1928.  
  1929.             case MEN_SAVEILBM:    BlockWindows();
  1930.  
  1931.                         if(FileRequest = GetFile("Save Screen (IFF-ILBM)...","","",DummyBuffer,NULL,TRUE,FALSE))
  1932.                         {
  1933.                             if(!SaveRPort(&Screen -> RastPort,VPort,0,Window -> TopEdge,Window -> Width,Window -> Height,Screen -> Width,Screen -> Height,FALSE,DummyBuffer))
  1934.                                 MyEasyRequest(Window,"Failed to save screen to\nfile %s!","Continue",DummyBuffer);
  1935.  
  1936.                             FreeAslRequest(FileRequest);
  1937.                         }
  1938.  
  1939.                         ReleaseWindows();
  1940.  
  1941.                         break;
  1942.  
  1943.                 /* Save screen as ASCII file. */
  1944.  
  1945.             case MEN_SAVEASCII:    BlockWindows();
  1946.  
  1947.                         if(FileRequest = GetFile("Save Screen (ASCII)...","","",DummyBuffer,NULL,TRUE,FALSE))
  1948.                         {
  1949.                             if(GetFileSize(DummyBuffer))
  1950.                             {
  1951.                                 switch(MyEasyRequest(Window,"File %s already exists!","Create New File|Append Data|Cancel",DummyBuffer))
  1952.                                 {
  1953.                                     case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  1954.                                         break;
  1955.  
  1956.                                     case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  1957.                                         {
  1958.                                             if(Seek(SomeFile,0,OFFSET_END) == -1)
  1959.                                             {
  1960.                                                 Close(SomeFile);
  1961.  
  1962.                                                 SomeFile = NULL;
  1963.                                             }
  1964.                                         }
  1965.  
  1966.                                         break;
  1967.  
  1968.                                     case 0:    SomeFile = ~0;
  1969.                                         break;
  1970.                                 }
  1971.                             }
  1972.                             else
  1973.                                 SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  1974.  
  1975.                             if(!SomeFile)
  1976.                                 MyEasyRequest(Window,"Failed to save screen to\nfile %s!","Continue",DummyBuffer);
  1977.                             else
  1978.                             {
  1979.                                 if(SomeFile != ~0)
  1980.                                 {
  1981.                                     SHORT i;
  1982.  
  1983.                                     for(i = 0 ; i < RasterHeight ; i++)
  1984.                                     {
  1985.                                         if(!FWrite(SomeFile,&Raster[i * RasterWidth],RasterWidth,1))
  1986.                                             break;
  1987.  
  1988.                                         if(!FWrite(SomeFile,"\n",1,1))
  1989.                                             break;
  1990.                                     }
  1991.  
  1992.                                     Close(SomeFile);
  1993.  
  1994.                                     SetProtection(DummyBuffer,FIBF_EXECUTE);
  1995.                                 }
  1996.                             }
  1997.  
  1998.                             FreeAslRequest(FileRequest);
  1999.                         }
  2000.  
  2001.                         ReleaseWindows();
  2002.  
  2003.                         break;
  2004.  
  2005.                 /* Set the serial preferences. */
  2006.  
  2007.             case MEN_SERIAL:    BlockWindows();
  2008.  
  2009.                         if(SerialPanel(&Config))
  2010.                         {
  2011.                             FlushSerial();
  2012.  
  2013.                             DeleteSerial();
  2014.  
  2015.                             if(!CreateSerial())
  2016.                             {
  2017.                                 OldPtr = ThisProcess -> pr_WindowPtr;
  2018.  
  2019.                                 DeleteSerial();
  2020.  
  2021.                                 ThisProcess -> pr_WindowPtr = (APTR)Window;
  2022.  
  2023.                                 if(!MyEasyRequest(Window,"term has a problem:\nFailed to open %s!","Continue|Quit term",Config . SerialDevice))
  2024.                                 {
  2025.                                     ThisProcess -> pr_WindowPtr = OldPtr;
  2026.  
  2027.                                     Terminated = TRUE;
  2028.  
  2029.                                     break;
  2030.                                 }
  2031.  
  2032.                                 ThisProcess -> pr_WindowPtr = OldPtr;
  2033.                             }
  2034.                         }
  2035.  
  2036.                         ReleaseWindows();
  2037.  
  2038.                         break;
  2039.  
  2040.                 /* Set the modem preferences. */
  2041.  
  2042.             case MEN_MODEM:        BlockWindows();
  2043.  
  2044.                         if(ModemPanel(&Config))
  2045.                             FlowInit();
  2046.  
  2047.                         ReleaseWindows();
  2048.  
  2049.                         break;
  2050.  
  2051.                 /* Set the keyboard macros. */
  2052.  
  2053.             case MEN_MACROS:    BlockWindows();
  2054.  
  2055.                         MacroPanel(MacroKeys);
  2056.  
  2057.                         ReleaseWindows();
  2058.  
  2059.                         break;
  2060.  
  2061.                 /* Set the screen preferences. */
  2062.  
  2063.             case MEN_SCREEN:    BlockWindows();
  2064.  
  2065.                         if(ScreenPanel(&Config))
  2066.                             ResetDisplay = TRUE;
  2067.                         else
  2068.                             PubScreenStuff();
  2069.  
  2070.                         ReleaseWindows();
  2071.  
  2072.                         break;
  2073.  
  2074.                 /* Set the terminal preferences. */
  2075.  
  2076.             case MEN_TERMINAL:    BlockWindows();
  2077.  
  2078.                         if(TerminalPanel(&Config))
  2079.                         {
  2080.                             if(Config . Font != PrivateConfig . Font)
  2081.                             {
  2082.                                 if(Config . Font == FONT_TOPAZ)
  2083.                                     SetFont(RPort,Topaz);
  2084.                                 else
  2085.                                     SetFont(RPort,IBM);
  2086.                             }
  2087.  
  2088.                             if(Config . Emulation != PrivateConfig . Emulation || Config . ColourMode != PrivateConfig . ColourMode)
  2089.                                 ResetDisplay = TRUE;
  2090.                         }
  2091.  
  2092.                         ReleaseWindows();
  2093.  
  2094.                         break;
  2095.  
  2096.             case MEN_STARTUP:    BlockWindows();
  2097.  
  2098.                         GetString("Enter Startup Macro",&Config . StartupMacro[0]);
  2099.  
  2100.                         ReleaseWindows();
  2101.  
  2102.                         break;
  2103.  
  2104.             case MEN_EMULATION:    BlockWindows();
  2105.  
  2106.                         EmulationPanel(&Config);
  2107.  
  2108.                         ReleaseWindows();
  2109.  
  2110.                         break;
  2111.  
  2112.             case MEN_PATH:        BlockWindows();
  2113.  
  2114.                         if(PathPanel(&Config))
  2115.                         {
  2116.                             DeleteBeep();
  2117.  
  2118.                             if(!OpenSound(Config . BeepSound))
  2119.                                 MyEasyRequest(Window,"Failed to open sound \"%s\"!","Continue",Config . BeepSound);
  2120.  
  2121.                             CreateBeep();
  2122.                         }
  2123.  
  2124.                         ReleaseWindows();
  2125.  
  2126.                         break;
  2127.  
  2128.             case MEN_HOTKEYS:    BlockWindows();
  2129.  
  2130.                         if(HotkeyPanel(&Hotkeys))
  2131.                         {
  2132.                             if(!SetupCx())
  2133.                                 MyEasyRequest(Window,"Failed to set up hotkeys (spelling mistake?).","Continue");
  2134.                         }
  2135.  
  2136.                         ReleaseWindows();
  2137.  
  2138.                         break;
  2139.  
  2140.             case MEN_SPEECH:    BlockWindows();
  2141.  
  2142.                         SpeechPanel();
  2143.  
  2144.                         ReleaseWindows();
  2145.  
  2146.                         break;
  2147.  
  2148.                 /* Ignore the rest. */
  2149.  
  2150.             default:        break;
  2151.         }
  2152.  
  2153.         Code = MenuItem -> NextSelect;
  2154.     }
  2155. }
  2156.