home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / comm / term23_2.lha / Source_Code / termSource / termMain.c < prev    next >
C/C++ Source or Header  |  1992-08-21  |  63KB  |  3,244 lines

  1. /*
  2. **    $Id: termMain.c,v 1.16 92/08/18 16:12:39 olsen Sta Locker: olsen $
  3. **    $Revision: 1.16 $
  4. **    $Date: 92/08/18 16:12:39 $
  5. **
  6. **    Program main routines and event loop
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* Argument vectors offsets. */
  15.  
  16. enum    {    ARG_KEEPIO,ARG_DONTPOP,ARG_SETTINGS,ARG_COUNT };
  17.  
  18.     /* Argument template. */
  19.  
  20. #define ARGTEMPLATE "K=KEEPIO/S,D=DONTPOP/S,S=SETTINGS/K"
  21.  
  22.     /* Some global variables for starters. */
  23.  
  24. STATIC BYTE    DoIconify = FALSE;
  25.  
  26.     /* Local config path variable. */
  27.  
  28. STATIC STRPTR    ConfigPath;
  29. STATIC UBYTE    ThePath[256];
  30.  
  31.     /* main():
  32.      *
  33.      *    This is our main entry point, check for the right
  34.      *    Kickstart version and fire off the background task
  35.      *    if approritate.
  36.      */
  37.  
  38. LONG __saveds
  39. main()
  40. {
  41.     UBYTE *Result;
  42.  
  43.         /* Set up SysBase. */
  44.  
  45.     SysBase = *(struct ExecBase **)4;
  46.  
  47.         /* Are we running as a child of Workbench? */
  48.  
  49.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  50.  
  51.     if(!ThisProcess -> pr_CLI)
  52.     {
  53.         WaitPort(&ThisProcess -> pr_MsgPort);
  54.  
  55.         WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
  56.     }
  57.     else
  58.         WBenchMsg = NULL;
  59.  
  60.         /* Kickstart 2.0 or higher required, do you hear me? */
  61.  
  62.     if(SysBase -> LibNode . lib_Version < 36)
  63.     {
  64.         if(ThisProcess -> pr_CLI)
  65.         {
  66.             if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0))
  67.             {
  68.                 Write(ThisProcess -> pr_COS,"Kickstart 2.0 or higher required.\a\n",35);
  69.  
  70.                 ThisProcess -> pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
  71.  
  72.                 CloseLibrary(DOSBase);
  73.             }
  74.         }
  75.         else
  76.         {
  77.             if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  78.             {
  79.                 STATIC struct IntuiText BodyText =  {0,1,JAM1,5,3,&DefaultFont,(UBYTE *)"Kickstart 2.0 or higher required.", NULL};
  80.                 STATIC struct IntuiText SorryText = {0,1,JAM1,6,3,&DefaultFont,(UBYTE *)"Sorry",NULL};
  81.  
  82.                 struct Window *Window;
  83.  
  84.                 if(Window = (struct Window *)BuildSysRequest(NULL,&BodyText,NULL,&SorryText,GADGETUP,301,46))
  85.                 {
  86.                     struct IntuiMessage *Message;
  87.  
  88.                     ScreenToFront(Window -> WScreen);
  89.  
  90.                     DisplayBeep(Window -> WScreen);
  91.  
  92.                     WaitPort(Window -> UserPort);
  93.  
  94.                     if(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  95.                         ReplyMsg(Message);
  96.  
  97.                     FreeSysRequest(Window);
  98.                 }
  99.  
  100.                 CloseLibrary(IntuitionBase);
  101.             }
  102.         }
  103.  
  104.         if(WBenchMsg)
  105.         {
  106.             Forbid();
  107.  
  108.             ReplyMsg((struct Message *)WBenchMsg);
  109.         }
  110.  
  111.         return(RETURN_FAIL);
  112.     }
  113.  
  114.         /* Now try to open dos.library and go on examining
  115.          * our calling parameters.
  116.          */
  117.  
  118.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36)))
  119.     {
  120.         CloseAll();
  121.  
  122.         return(RETURN_FAIL);
  123.     }
  124.  
  125.         /* We were called from Shell. */
  126.  
  127.     if(ThisProcess -> pr_CLI)
  128.     {
  129.         UBYTE **ArgArray;
  130.  
  131.             /* Use the cute ReadArgs parser, allocate the
  132.              * argument vectors...
  133.              */
  134.  
  135.         if(ArgArray = (UBYTE **)AllocVec(sizeof(UBYTE *) * (ARG_COUNT),MEMF_ANY|MEMF_CLEAR))
  136.         {
  137.             struct RDArgs *ArgsPtr;
  138.  
  139.             if(ArgsPtr = (struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE))
  140.             {
  141.                 ArgsPtr -> RDA_ExtHelp = "\nUsage: \33[1mterm\33[0m [KeepIO] [DontPop] [Settings <Path name>]\n\n         KeepIO = Keep links to the current Shell window.\n        DontPop = Do not pop an already running `term' to the front.\n       Settings = Path to search for settings files.\n\n";
  142.  
  143.                     /* Parse the args (if any). */
  144.  
  145.                 if(ReadArgs(ARGTEMPLATE,(LONG *)ArgArray,ArgsPtr))
  146.                 {
  147.                         /* Pop a running `term' to the front? */
  148.  
  149.                     if((TermPort = (struct TermPort *)FindPort("term Port")) && !ArgArray[ARG_DONTPOP])
  150.                     {
  151.                         if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  152.                         {
  153.                             if(TermPort -> TopWindow)
  154.                                 BumpWindow(TermPort -> TopWindow);
  155.  
  156.                             CloseLibrary(IntuitionBase);
  157.                         }
  158.  
  159.                         FreeArgs(ArgsPtr);
  160.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  161.                         FreeVec(ArgArray);
  162.  
  163.                         CloseLibrary(DOSBase);
  164.  
  165.                         return(RETURN_OK);
  166.                     }
  167.  
  168.                         /* Are we to use a special settings path? */
  169.  
  170.                     if(ArgArray[ARG_SETTINGS])
  171.                     {
  172.                         ConfigPath = ThePath;
  173.  
  174.                         strcpy(ThePath,ArgArray[ARG_SETTINGS]);
  175.                     }
  176.  
  177.                         /* We are to keep our links to
  178.                          * the Shell.
  179.                          */
  180.  
  181.                     if(ArgArray[ARG_KEEPIO])
  182.                     {
  183.                         BYTE OldPri = ThisProcess -> pr_Task . tc_Node . ln_Pri;
  184.  
  185.                             /* Do we have enough stack space available? */
  186.  
  187.                         if(((struct CommandLineInterface *)BADDR(ThisProcess -> pr_CLI)) -> cli_DefaultStack < 4096)
  188.                         {
  189.                             Printf("\33[1mterm:\33[0m %s.\a\n","Sorry, the Shell stack must be at least 16384 bytes large");
  190.  
  191.                             FreeArgs(ArgsPtr);
  192.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  193.                             FreeVec(ArgArray);
  194.  
  195.                             CloseLibrary(DOSBase);
  196.  
  197.                             return(RETURN_FAIL);
  198.                         }
  199.  
  200.                             /* Open our resources and
  201.                              * squeak on failure.
  202.                              */
  203.  
  204.                         if(Result = OpenAll(ConfigPath))
  205.                         {
  206.                             if(Result[0])
  207.                                 Printf("\33[1mterm:\33[0m %s!\a\n",Result);
  208.  
  209.                             CloseAll();
  210.  
  211.                             FreeArgs(ArgsPtr);
  212.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  213.                             FreeVec(ArgArray);
  214.  
  215.                             CloseLibrary(DOSBase);
  216.  
  217.                             return(RETURN_FAIL);
  218.                         }
  219.  
  220.                             /* Go into main input
  221.                              * loop.
  222.                              */
  223.  
  224.                         HandleInput();
  225.  
  226.                             /* Does anybody understand
  227.                              * this joke?
  228.                              */
  229.  
  230.                         Printf("You quit with 0 gold pieces\nTo play again, just type \"term\"\n");
  231.  
  232.                             /* Free the argument
  233.                              * data.
  234.                              */
  235.  
  236.                         FreeArgs(ArgsPtr);
  237.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  238.                         FreeVec(ArgArray);
  239.  
  240.                             /* Restore old priority. */
  241.  
  242.                         SetTaskPri(ThisProcess,(LONG)OldPri);
  243.  
  244.                             /* Terminate execution. */
  245.  
  246.                         CloseAll();
  247.  
  248.                         CloseLibrary(DOSBase);
  249.  
  250.                         return(RETURN_OK);
  251.                     }
  252.  
  253.                     FreeArgs(ArgsPtr);
  254.                 }
  255.                 else
  256.                 {
  257.                     PrintFault(IoErr(),"term");
  258.  
  259.                     FreeDosObject(DOS_RDARGS,ArgsPtr);
  260.                     FreeVec(ArgArray);
  261.  
  262.                     CloseLibrary(DOSBase);
  263.  
  264.                     return(RETURN_ERROR);
  265.                 }
  266.  
  267.                 FreeDosObject(DOS_RDARGS,ArgsPtr);
  268.             }
  269.  
  270.             FreeVec(ArgArray);
  271.  
  272.                 /* Create a new process from our code. */
  273.  
  274.             if(!SegmentSplit("term main process",0,16384,HandleInput))
  275.             {
  276.                 Printf("\33[1mterm:\33[0m Failed to create new process!\a\n");
  277.  
  278.                 CloseAll();
  279.  
  280.                 CloseLibrary(DOSBase);
  281.  
  282.                 return(RETURN_FAIL);
  283.             }
  284.         }
  285.         else
  286.         {
  287.             Printf("\33[1mterm:\33[0m Failed to allocate argument vectors!\a\n");
  288.  
  289.             CloseLibrary(DOSBase);
  290.  
  291.             return(RETURN_FAIL);
  292.         }
  293.     }
  294.     else
  295.     {
  296.         LONG StackSize;
  297.  
  298.         StackSize = (LONG)SysBase -> ThisTask -> tc_SPUpper - (LONG)SysBase -> ThisTask -> tc_SPLower;
  299.  
  300.         if(StackSize < 16384)
  301.         {
  302.             if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
  303.             {
  304.                 MyEasyRequest(NULL,"`term' has a problem:\nThe current stack size of %ld bytes is too low,\nplease edit the icon file to use at least\n16384 bytes and restart the proram.","Continue",StackSize);
  305.  
  306.                 CloseLibrary(IntuitionBase);
  307.             }
  308.  
  309.             if(DOSBase)
  310.                 CloseLibrary(DOSBase);
  311.  
  312.             Forbid();
  313.  
  314.             ReplyMsg((struct Message *)WBenchMsg);
  315.  
  316.             return(RETURN_FAIL);
  317.         }
  318.         else
  319.         {
  320.             CurrentDir(WBenchMsg -> sm_ArgList -> wa_Lock);
  321.  
  322.                 /* Open icon.library, we want to take a
  323.                  * look at the icon.
  324.                  */
  325.  
  326.             if(IconBase = OpenLibrary("icon.library",0))
  327.             {
  328.                 struct DiskObject *Icon;
  329.  
  330.                     /* Try to read the icon file. */
  331.  
  332.                 if(Icon = GetDiskObject(WBenchMsg -> sm_ArgList -> wa_Name))
  333.                 {
  334.                         /* Look for a `Settings' tooltype. */
  335.  
  336.                     if(ConfigPath = FindToolType(Icon -> do_ToolTypes,"SETTINGS"))
  337.                     {
  338.                             /* Remember the path and continue. */
  339.  
  340.                         strcpy(ThePath,ConfigPath);
  341.  
  342.                         ConfigPath = ThePath;
  343.                     }
  344.  
  345.                         /* Free the icon. */
  346.  
  347.                     FreeDiskObject(Icon);
  348.                 }
  349.  
  350.                     /* Close the library. */
  351.  
  352.                 CloseLibrary(IconBase);
  353.  
  354.                 IconBase = NULL;
  355.             }
  356.  
  357.                 /* Initialize this, so OpenAll will work with
  358.                  * correct data.
  359.                  */
  360.  
  361.             TermPort = (struct TermPort *)FindPort("term Port");
  362.  
  363.                 /* We were called from Workbench. */
  364.  
  365.             if(Result = OpenAll(ConfigPath))
  366.             {
  367.                 if(IntuitionBase && Result[0])
  368.                     MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  369.  
  370.                 CloseAll();
  371.             }
  372.             else
  373.                 HandleInput();
  374.         }
  375.     }
  376.  
  377.     return(RETURN_OK);
  378. }
  379.  
  380.     /* HandleInput():
  381.      *
  382.      *    This is our main input loop (check window & serial).
  383.      */
  384.  
  385. VOID __saveds
  386. HandleInput()
  387. {
  388.     ULONG SignalSet = NULL,SavageSignals = NULL;
  389.  
  390.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  391.  
  392.         /* Open the resources we need. */
  393.  
  394.     if(!IntuitionBase)
  395.     {
  396.         UBYTE *Result;
  397.  
  398.         if(Result = OpenAll(ConfigPath))
  399.         {
  400.             if(IntuitionBase && Result[0])
  401.                 MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  402.  
  403.             CloseAll();
  404.  
  405.             return;
  406.         }
  407.     }
  408.  
  409.     BumpWindow(Window);
  410.  
  411.         /* Set up the public screen data. */
  412.  
  413.     PubScreenStuff();
  414.  
  415.         /* Change program priority. */
  416.  
  417.     SetTaskPri(ThisProcess,(LONG)Config . Priority);
  418.  
  419.     BlockWindows();
  420.  
  421.         /* Load the phone book. */
  422.  
  423.     LoadPhonebook(LastPhone);
  424.  
  425.         /* Show our business card. */
  426.  
  427.     if(ShowInfo(TRUE))
  428.         SignalSet |= SIG_REXX;
  429.  
  430.     ReleaseWindows();
  431.  
  432.         /* Initialize the modem. */
  433.  
  434.     SerialCommand(Config . ModemInit);
  435.  
  436.         /* Execute the startup macro (if any). */
  437.  
  438.     if(Config . StartupMacro[0])
  439.         SerialCommand(Config . StartupMacro);
  440.  
  441.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_STARTED_TXT),TermName,TermDate);
  442.  
  443.         /* Go into input loop... */
  444.  
  445. Loop:    while(!MainTerminated)
  446.     {
  447.             /* Is the serial write request available? */
  448.  
  449.         if((SignalSet & SIG_CHECK) && WriteRequest)
  450.         {
  451.                 /* Query serial status. */
  452.  
  453.             WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  454.  
  455.             DoIO(WriteRequest);
  456.  
  457.                 /* Is the carrier detect signal
  458.                  * still present?
  459.                  */
  460.  
  461.             if(WriteRequest -> io_Status & (1 << 5))
  462.             {
  463.                 WasOnline    = TRUE;
  464.                 Online        = FALSE;
  465.             }
  466.         }
  467.  
  468.             /* If no longer online, get back to the
  469.              * previous configuration.
  470.              */
  471.  
  472.         if(!Online)
  473.         {
  474.             BYTE ShowRate = TRUE;
  475.  
  476.             if(WasOnline)
  477.             {
  478.                 StopCall(FALSE);
  479.  
  480.                 SetDialMenu(TRUE);
  481.  
  482.                     /* Execute logoff macro. */
  483.  
  484.                 if(Config . LogoffMacro[0])
  485.                     SerialCommand(Config . LogoffMacro);
  486.  
  487.                     /* Clear the password. */
  488.  
  489.                 Password[0] = 0;
  490.                 UserName[0] = 0;
  491.  
  492.                 WasOnline = FALSE;
  493.  
  494.             }
  495.  
  496.             ChosenEntry = NULL;
  497.  
  498.                 /* Previous configuration available? */
  499.  
  500.             if(BackupConfig)
  501.             {
  502.                     /* Remember old configuration. */
  503.  
  504.                 PrivateConfig = Config;
  505.  
  506.                     /* Copy configuration. */
  507.  
  508.                 memcpy(&Config,BackupConfig,sizeof(struct Configuration));
  509.  
  510.                     /* Set up new configuration. */
  511.  
  512.                 ConfigSetup();
  513.  
  514.                     /* Free old configuration. */
  515.  
  516.                 FreeVec(BackupConfig);
  517.  
  518.                 BackupConfig = NULL;
  519.  
  520.                     /* Don't show the rate yet. */
  521.  
  522.                 ShowRate = FALSE;
  523.             }
  524.  
  525.             if(CurrentPay && ShowRate)
  526.             {
  527.                 /* Display how much we expect
  528.                  * the user will have to pay for
  529.                  * this call.
  530.                  */
  531.  
  532.                 ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  533.  
  534.                 CurrentPay = 0;
  535.             }
  536.         }
  537.  
  538.             /* Take care of external terminal emulation library. */
  539.  
  540.         if(SignalSet & XEM_Signal)
  541.         {
  542.             if(!XEmulatorSignal(XEM_IO,SignalSet))
  543.             {
  544.                 CloseEmulator();
  545.  
  546.                 ResetDisplay = TRUE;
  547.             }
  548.         }
  549.  
  550.             /* A SIG_CLIP will cause us to transmit the current contents of
  551.              * the clipboard...
  552.              */
  553.  
  554.         if(SignalSet & SIG_CLIP)
  555.         {
  556.             if(!ClipInput)
  557.             {
  558.                 if(!OpenClip())
  559.                     ClipInput = ClipXerox = TRUE;
  560.                 else
  561.                     ClipInput = ClipXerox = FALSE;
  562.             }
  563.         }
  564.  
  565.             /* Loop & check until the dust has settled. */
  566.  
  567.         if(SignalSet & (SIG_WINDOW | SavageSignals | SIG_CLIP))
  568.             while(HandleWindow() || HandleSerial() || HandlePacket() || HandleReview());
  569.  
  570.             /* Remove audio request. */
  571.  
  572.         if(SignalSet & SIG_AUDIO)
  573.             ClearAudio();
  574.  
  575.             /* Check if we are to prompt the user for
  576.              * ZModem upload type.
  577.              */
  578.  
  579.         if(UsesZModem)
  580.         {
  581.             if(FlowInfo . ZModemUpload && XProtocolBase)
  582.             {
  583.                 FlowInit();
  584.  
  585.                 if(Config . AutoUpload)
  586.                 {
  587.                     BlockWindows();
  588.  
  589.                     switch(UploadPanel())
  590.                     {
  591.                         case UPLOAD_TEXT:    BinaryTransfer = FALSE;
  592.  
  593.                                     if(!StartXprSend(TRANSFER_TEXT))
  594.                                         SerWrite(ZModemCancel,20);
  595.  
  596.                                     break;
  597.  
  598.                         case UPLOAD_BINARY:    BinaryTransfer = TRUE;
  599.  
  600.                                     if(!StartXprSend(TRANSFER_BINARY))
  601.                                         SerWrite(ZModemCancel,20);
  602.  
  603.                                     break;
  604.  
  605.                         case UPLOAD_IGNORE:    break;
  606.  
  607.                         case UPLOAD_ABORT:    SerWrite(ZModemCancel,20);
  608.                                     break;
  609.                     }
  610.  
  611.                     ReleaseWindows();
  612.                 }
  613.             }
  614.         }
  615.  
  616.             /* Make the user notice not too obvious events. */
  617.  
  618.         if(FlowInfo . Changed && (FlowInfo . Voice || FlowInfo . Ring || FlowInfo . Connect))
  619.         {
  620.             if(!Online)
  621.             {
  622.                 WakeUp(Window);
  623.  
  624.                 if(FlowInfo . Voice)
  625.                 {
  626.                     ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_VOIC_CALL_TXT));
  627.  
  628.                     Say(LocaleString(MSG_TERMMAIN_SAY_INCOMING_VOICE_CALL_TXT));
  629.                 }
  630.  
  631.                 if(FlowInfo . Ring)
  632.                 {
  633.                     ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_CALL_TXT));
  634.  
  635.                     Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  636.                 }
  637.  
  638.                 if(FlowInfo . Connect)
  639.                 {
  640.                     Online        = TRUE;
  641.                     BaudPending    = FALSE;
  642.  
  643.                     SetDialMenu(FALSE);
  644.                 }
  645.             }
  646.  
  647.             FlowInit();
  648.         }
  649.  
  650.             /* Check for rexx messages to be processed. */
  651.  
  652.         if(SignalSet & SIG_REXX)
  653.         {
  654.             HandleRexx();
  655.  
  656.             if(MainTerminated)
  657.                 break;
  658.         }
  659.  
  660.             /* Iconify the program? */
  661.  
  662.         if(DoIconify)
  663.         {
  664.             BYTE Released = FALSE;
  665.  
  666.                 /* Set the wait mouse pointer... */
  667.  
  668.             BlockWindows();
  669.  
  670.                 /* Open workbench.library. */
  671.  
  672.             if(WorkbenchBase = OpenLibrary("workbench.library",0))
  673.             {
  674.                     /* Open icon.library. */
  675.  
  676.                 if(IconBase = OpenLibrary("icon.library",0))
  677.                 {
  678.                     struct DiskObject *Icon = NULL;
  679.  
  680.                         /* Get the program icon. */
  681.  
  682.                     if(WBenchMsg)
  683.                     {
  684.                         if(WBenchMsg -> sm_ArgList)
  685.                         {
  686.                             if(WBenchMsg -> sm_ArgList -> wa_Name)
  687.                                 Icon = GetDiskObjectNew(WBenchMsg -> sm_ArgList -> wa_Name);
  688.                         }
  689.                     }
  690.  
  691.                         /* No icon? Use the default name. */
  692.  
  693.                     if(!Icon)
  694.                         Icon = GetDiskObjectNew("term");
  695.  
  696.                         /* Did we get any icon? */
  697.  
  698.                     if(Icon)
  699.                     {
  700.                             /* Not a tool icon? */
  701.  
  702.                         if(Icon -> do_Type != WBTOOL)
  703.                         {
  704.                                 /* Get rid of it... */
  705.  
  706.                             FreeDiskObject(Icon);
  707.  
  708.                                 /* Get the default tool icon. */
  709.  
  710.                             Icon = GetDefDiskObject(WBTOOL);
  711.                         }
  712.                     }
  713.                     else
  714.                     {
  715.                             /* Get the default tool icon. */
  716.  
  717.                         Icon = GetDefDiskObject(WBTOOL);
  718.                     }
  719.  
  720.                         /* Did we get an icon? */
  721.  
  722.                     if(Icon)
  723.                     {
  724.                         struct MsgPort *IconPort;
  725.  
  726.                             /* Default icon position. */
  727.  
  728.                         Icon -> do_CurrentX = NO_ICON_POSITION;
  729.                         Icon -> do_CurrentY = NO_ICON_POSITION;
  730.  
  731.                             /* Create the Workbench reply port. */
  732.  
  733.                         if(IconPort = CreateMsgPort())
  734.                         {
  735.                             struct AppIcon *AppIcon;
  736.  
  737.                                 /* Add the application icon. */
  738.  
  739.                             if(AppIcon = AddAppIcon(0,0,TermIDString,IconPort,NULL,Icon,NULL))
  740.                             {
  741.                                 BYTE             IconTerminated = FALSE;
  742.                                 struct AppMessage    *AppMessage;
  743.                                 BYTE             HadBuffer = BufferProcess ? TRUE : FALSE;
  744.                                 UBYTE            *String,*Error;
  745.  
  746.                                     /* Release the window. */
  747.  
  748.                                 Released = TRUE;
  749.  
  750.                                 ReleaseWindows();
  751.  
  752.                                     /* Remove the display buffer. */
  753.  
  754.                                 if(BufferProcess)
  755.                                 {
  756.                                     Signal(BufferProcess,SIGBREAKF_CTRL_C);
  757.  
  758.                                     Wait(SIGBREAKF_CTRL_C);
  759.                                 }
  760.  
  761.                                     /* Reset and release the serial driver. */
  762.  
  763.                                 ClearSerial();
  764.  
  765.                                 DeleteSerial();
  766.  
  767.                                     /* Close the display. full stop. */
  768.  
  769.                                 DeleteDisplay();
  770.  
  771.                                     /* Wait for double-click. */
  772.  
  773. IconLoop:                            while(!IconTerminated)
  774.                                 {
  775.                                     ULONG SignalSet = Wait((1 << IconPort -> mp_SigBit) | SIG_REXX);
  776.  
  777.                                     if(SignalSet & (1 << IconPort -> mp_SigBit))
  778.                                     {
  779.                                             /* Pick up application messages. */
  780.  
  781.                                         while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  782.                                         {
  783.                                                 /* Received a double-click? */
  784.  
  785.                                             IconTerminated = TRUE;
  786.  
  787.                                             ReplyMsg(AppMessage);
  788.                                         }
  789.                                     }
  790.  
  791.                                         /* Wake up if ARexx command received. */
  792.  
  793.                                     if(SignalSet & SIG_REXX)
  794.                                         IconTerminated = TRUE;
  795.                                 }
  796.  
  797.                                     /* The buffer process was running before we
  798.                                      * went into iconified state, so let's try to
  799.                                      * conjure it up again.
  800.                                      */
  801.  
  802.                                 if(HadBuffer)
  803.                                     LaunchBuffer();
  804.  
  805.                                     /* Open the serial driver. */
  806.  
  807.                                 if(Error = CreateSerial())
  808.                                 {
  809.                                     DeleteSerial();
  810.  
  811.                                     switch(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_IGNORE_QUIT_TXT),Error))
  812.                                     {
  813.                                         case 1:        goto IconLoop;
  814.                                         case 2:        break;
  815.                                         case 0:        MainTerminated = TRUE;
  816.                                     }
  817.                                 }
  818.                                 else
  819.                                 {
  820.                                     if(SerialMessage)
  821.                                     {
  822.                                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  823.  
  824.                                         SerialMessage = NULL;
  825.                                     }
  826.                                 }
  827.  
  828.                                     /* Create the display. */
  829.  
  830.                                 if(String = CreateDisplay(FALSE))
  831.                                 {
  832.                                     if(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_QUIT_TXT),String))
  833.                                     {
  834.                                         ClearSerial();
  835.  
  836.                                         DeleteSerial();
  837.  
  838.                                         IconTerminated = FALSE;
  839.  
  840.                                         goto IconLoop;
  841.                                     }
  842.                                     else
  843.                                         MainTerminated = FALSE;
  844.                                 }
  845.                                 else
  846.                                 {
  847.                                     BumpWindow(Window);
  848.  
  849.                                     PubScreenStuff();
  850.                                 }
  851.  
  852.                                     /* Remove the application icon. */
  853.  
  854.                                 RemoveAppIcon(AppIcon);
  855.  
  856.                                     /* Reply pending messages. */
  857.  
  858.                                 while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  859.                                     ReplyMsg(AppMessage);
  860.                             }
  861.                             else
  862.                                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_ADD_APPLICATION_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  863.  
  864.                             DeleteMsgPort(IconPort);
  865.                         }
  866.                         else
  867.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_CREATE_MSGPORT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  868.  
  869.                         FreeDiskObject(Icon);
  870.                     }
  871.                     else
  872.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_TOOL_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  873.  
  874.                     CloseLibrary(IconBase);
  875.                 }
  876.                 else
  877.                     MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_ICON_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  878.  
  879.                 CloseLibrary(WorkbenchBase);
  880.             }
  881.             else
  882.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_WORKBENCH_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  883.  
  884.             if(!Released)
  885.                 ReleaseWindows();
  886.  
  887.                 /* Finished! */
  888.  
  889.             DoIconify = FALSE;
  890.  
  891.                 /* Just a check for safety. */
  892.  
  893.             HandleRexx();
  894.         }
  895.  
  896.             /* Reset the serial driver? */
  897.  
  898.         if(ResetSerial)
  899.         {
  900.             UBYTE *Error;
  901.  
  902.             ClearSerial();
  903.  
  904.             DeleteSerial();
  905.  
  906.             BlockWindows();
  907.  
  908. OpenLoop:        if(Error = CreateSerial())
  909.             {
  910.                 APTR OldPtr = ThisProcess -> pr_WindowPtr;
  911.  
  912.                 DeleteSerial();
  913.  
  914.                 ThisProcess -> pr_WindowPtr = (APTR)Window;
  915.  
  916.                 switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_RETRY_IGNORE_QUIT_TXT),Error))
  917.                 {
  918.                     case 1:        goto OpenLoop;
  919.                     case 2:        break;
  920.                     case 0:        MainTerminated = TRUE;
  921.                 }
  922.  
  923.                 ThisProcess -> pr_WindowPtr = OldPtr;
  924.             }
  925.             else
  926.             {
  927.                 if(SerialMessage)
  928.                 {
  929.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  930.  
  931.                     SerialMessage = NULL;
  932.                 }
  933.  
  934.                 ResetSerial = FALSE;
  935.             }
  936.  
  937.             ReleaseWindows();
  938.         }
  939.  
  940.             /* We are to release the serial.device (or
  941.              * whatever we are using) for some reason.
  942.              */
  943.  
  944.         if(ReleaseSerial)
  945.         {
  946.             APTR OldPtr = ThisProcess -> pr_WindowPtr;
  947.  
  948.             ThisProcess -> pr_WindowPtr = (APTR)Window;
  949.  
  950.                 /* This might happen if an ARexx user
  951.                  * released the serial device and
  952.                  * failed to reopen it.
  953.                  */
  954.  
  955.             if(!ReadPort)
  956.                 goto OpenIt;
  957.  
  958.             ClearSerial();
  959.  
  960.             DeleteSerial();
  961.  
  962.             BlockWindows();
  963.  
  964.             if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNIT_RESET_AND_RELEASED_TXT),LocaleString(MSG_TERMMAIN_RETURN_QUIT_TXT),Config . SerialDevice,Config . UnitNumber))
  965.             {
  966.                 UBYTE *Error;
  967.  
  968. OpenIt:                if(Error = CreateSerial())
  969.                 {
  970.                     DeleteSerial();
  971.  
  972.                     switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_RETRY_IGNORE_QUIT_TXT),Error))
  973.                     {
  974.                         case 1:        goto OpenIt;
  975.                         case 2:        break;
  976.                         case 0:        MainTerminated = TRUE;
  977.                     }
  978.                 }
  979.                 else
  980.                 {
  981.                     if(SerialMessage)
  982.                     {
  983.                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  984.  
  985.                         SerialMessage = NULL;
  986.                     }
  987.                 }
  988.             }
  989.             else
  990.                 MainTerminated = TRUE;
  991.  
  992.             ReleaseSerial = FALSE;
  993.  
  994.             ThisProcess -> pr_WindowPtr = OldPtr;
  995.  
  996.             ReleaseWindows();
  997.         }
  998.  
  999.             /* Somebody told us to re-open the display
  1000.              * (changed the terminal emulation/colour
  1001.              * mode).
  1002.              */
  1003.  
  1004.         if(ResetDisplay)
  1005.         {
  1006.             if(!DisplayReset())
  1007.                 MainTerminated = TRUE;
  1008.         }
  1009.  
  1010.         if(Blocking && !MainTerminated)
  1011.         {
  1012.             Blocking = FALSE;
  1013.  
  1014.             continue;
  1015.         }
  1016.  
  1017.             /* Set up the signal bits to wait for. */
  1018.  
  1019.         SavageSignals = XEM_Signal;
  1020.  
  1021.             /* The serial line is active. */
  1022.  
  1023.         if(Status != STATUS_HOLDING && ReadPort)
  1024.             SavageSignals |= SIG_SERIAL;
  1025.  
  1026.             /* The packet window is still open. */
  1027.  
  1028.         if(PacketWindow)
  1029.             SavageSignals |= SIG_PACKET;
  1030.  
  1031.             /* The review buffer window is open. */
  1032.  
  1033.         if(ReviewPort)
  1034.             SavageSignals |= SIG_REVIEW;
  1035.  
  1036.             /* Wait for input events to occur. */
  1037.  
  1038.         SignalSet = Wait(SIG_WINDOW | SIG_REXX | SIG_AUDIO | SIG_CLIP | SIG_CHECK | SavageSignals);
  1039.     }
  1040.  
  1041.         /* Shut down the transfer panel if any. */
  1042.  
  1043.     if(TransferWindow)
  1044.     {
  1045.         if(DidTransfer)
  1046.         {
  1047.             if(SendAbort && UsesZModem)
  1048.                 SerWrite(ZModemCancel,20);
  1049.         }
  1050.  
  1051.         DeleteTransferPanel();
  1052.     }
  1053.  
  1054.         /* User wants to quit term, so let's try to close
  1055.          * our magnificient screen and exit.
  1056.          */
  1057.  
  1058.     if(Screen)
  1059.     {
  1060.         struct List        *PubScreenList;
  1061.         struct PubScreenNode    *ScreenNode;
  1062.  
  1063.             /* Lock the list of public screens. */
  1064.  
  1065.         PubScreenList = LockPubScreenList();
  1066.  
  1067.             /* Scan the list and try to find our
  1068.              * private node.
  1069.              */
  1070.  
  1071.         for(ScreenNode = (struct PubScreenNode *)PubScreenList -> lh_Head ; ScreenNode -> psn_Node . ln_Succ ; ScreenNode = (struct PubScreenNode *)ScreenNode -> psn_Node . ln_Succ)
  1072.         {
  1073.             if(ScreenNode -> psn_Screen == Screen)
  1074.                 break;
  1075.         }
  1076.  
  1077.         if(ScreenNode)
  1078.         {
  1079.                 /* Okay, we know who and where we are,
  1080.                  * check the number of visitor windows
  1081.                  * currently open on our screen.
  1082.                  */
  1083.  
  1084.             if(ScreenNode -> psn_VisitorCount)
  1085.             {
  1086.                     /* No chance, don't close
  1087.                      * the screen now.
  1088.                      */
  1089.  
  1090.                 UnlockPubScreenList();
  1091.  
  1092.                 BlockWindows();
  1093.  
  1094.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  1095.  
  1096.                 ReleaseWindows();
  1097.  
  1098.                 MainTerminated = FALSE;
  1099.  
  1100.                 goto Loop;
  1101.             }
  1102.         }
  1103.  
  1104.         UnlockPubScreenList();
  1105.     }
  1106.  
  1107.         /* Send the modem exit command, shut down the
  1108.          * serial.device and close all resources.
  1109.          */
  1110.  
  1111.     SerialCommand(Config . ModemExit);
  1112.  
  1113.     ClearSerial();
  1114.  
  1115.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_TERMINATED_TXT));
  1116.  
  1117.     Say(LocaleString(MSG_TERMMAIN_BYE_BYE_TXT));
  1118.  
  1119.     if(!ThisProcess -> pr_CLI)
  1120.         CloseAll();
  1121. }
  1122.  
  1123.     /* HandleWindow():
  1124.      *
  1125.      *    This funny part checks the window(s) for incoming
  1126.      *    user input. Menus are handled elsewhere.
  1127.      */
  1128.  
  1129. BYTE
  1130. HandleWindow()
  1131. {
  1132.     struct IntuiMessage    *Massage;
  1133.     ULONG             Class,Code,Qualifier;
  1134.     LONG             MouseX,MouseY,Len;
  1135.     struct Gadget        *Gadget;
  1136.     UBYTE             Char,InputBuffer[257];
  1137.     struct Window        *IDCMPWindow;
  1138.     BYTE             Result = FALSE;
  1139.  
  1140.     if(ClipInput)
  1141.     {
  1142.         WORD Len = GetClip(InputBuffer,256,FALSE);
  1143.  
  1144.         if(Len < 0)
  1145.         {
  1146.             CloseClip();
  1147.  
  1148.             ClipInput = FALSE;
  1149.  
  1150.             if(ClipXerox)
  1151.             {
  1152.                 switch(Config . SendCR)
  1153.                 {
  1154.                     case CR_IGNORE:    break;
  1155.  
  1156.                     case CR_ASCR:    SerWrite("\r",1);
  1157.                             break;
  1158.  
  1159.                     case CR_ASCRLF:    SerWrite("\r\n",2);
  1160.                             break;
  1161.                 }
  1162.             }
  1163.  
  1164.             ClipXerox = FALSE;
  1165.         }
  1166.         else
  1167.         {
  1168.             if(Len > 0)
  1169.             {
  1170.                     /* Is a send-delay enabled? */
  1171.  
  1172.                 if(Config . CharDelay || Config . LineDelay)
  1173.                 {
  1174.                     WORD i;
  1175.  
  1176.                         /* Run down the buffer... */
  1177.  
  1178.                     for(i = 0 ; i < Len ; i++)
  1179.                     {
  1180.                             /* What kind of delay
  1181.                              * are we to provide?
  1182.                              */
  1183.  
  1184.                         switch(InputBuffer[i])
  1185.                         {
  1186.                             case '\r':    if(Config . LineDelay)
  1187.                                         WaitTime(Config . LineDelay / 100,(Config . LineDelay % 100) * 10000);
  1188.  
  1189.                                     break;
  1190.  
  1191.                             default:    if(Config . CharDelay)
  1192.                                         WaitTime(Config . CharDelay / 100,(Config . CharDelay % 100) * 10000);
  1193.  
  1194.                                     break;
  1195.                         }
  1196.  
  1197.                         SerWrite(&InputBuffer[i],1);
  1198.                     }
  1199.                 }
  1200.                 else
  1201.                     SerWrite(InputBuffer,Len);
  1202.             }
  1203.  
  1204.             Result = TRUE;
  1205.         }
  1206.     }
  1207.  
  1208.         /* Any news in the mail? */
  1209.  
  1210.     if(Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort))
  1211.     {
  1212.             /* Pick up the pieces. */
  1213.  
  1214.         Class        = Massage -> Class;
  1215.         Code        = Massage -> Code;
  1216.         Qualifier    = Massage -> Qualifier;
  1217.  
  1218.         MouseX        = Massage -> MouseX;
  1219.         MouseY        = Massage -> MouseY;
  1220.  
  1221.         Gadget        = (struct Gadget *)Massage -> IAddress;
  1222.  
  1223.         IDCMPWindow    = Massage -> IDCMPWindow;
  1224.  
  1225.         if(Class == IDCMP_RAWKEY)
  1226.         {
  1227.                 /* Perform key conversion. */
  1228.  
  1229.             if(XEmulatorBase)
  1230.             {
  1231.                 if(Len = XEmulatorUserMon(XEM_IO,InputBuffer,256,Massage))
  1232.                     Char = InputBuffer[0];
  1233.             }
  1234.             else
  1235.                 Char = KeyConvert(Massage,InputBuffer,&Len);
  1236.         }
  1237.  
  1238.         GT_ReplyIMsg(Massage);
  1239.  
  1240.         if(IDCMPWindow == InfoWindow)
  1241.         {
  1242.             switch(Class)
  1243.             {
  1244.                 case IDCMP_CLOSEWINDOW:    CloseInfoWindow();
  1245.  
  1246.                             return(Result);
  1247.  
  1248.                 case IDCMP_MOUSEBUTTONS:if(!(Code & IECODE_UP_PREFIX))
  1249.                                 RefreshInfoWindow();
  1250.  
  1251.                             return(Result);
  1252.  
  1253.                 default:        break;
  1254.             }
  1255.         }
  1256.  
  1257.             /* The following messages probably
  1258.              * originate from the fast! macro
  1259.              * panel.
  1260.              */
  1261.  
  1262.         if(IDCMPWindow == FastWindow)
  1263.         {
  1264.             struct MacroNode *Node;
  1265.  
  1266.             switch(Class)
  1267.             {
  1268.                             /* Close the window. */
  1269.  
  1270.                 case IDCMP_CLOSEWINDOW:    CloseFastWindow();
  1271.  
  1272.                             return(Result);
  1273.  
  1274.                             /* Window size has changed for some reason. */
  1275.  
  1276.                 case IDCMP_NEWSIZE:    if(FastWindow -> Height != Screen -> WBorTop + Screen -> Font -> ta_YSize + 1)
  1277.                             {
  1278.                                 RefreshFastWindow(FastWindow -> Height);
  1279.  
  1280.                                 RefreshWindowFrame(FastWindow);
  1281.                             }
  1282.  
  1283.                             return(Result);
  1284.  
  1285.                 case IDCMP_GADGETUP:    if(Node = GetFastMacro(Code))
  1286.                             {
  1287.                                 if(Node -> mn_Code[0])
  1288.                                     SerialCommand(Node -> mn_Code);
  1289.                             }
  1290.  
  1291.                             return(Result);
  1292.  
  1293.                 case IDCMP_MOUSEBUTTONS:return(Result);
  1294.  
  1295.                 default:        break;
  1296.             }
  1297.         }
  1298.  
  1299.             /* This looks like a raw, or better, now cooked key. */
  1300.  
  1301.         if(Class == IDCMP_RAWKEY && Len)
  1302.         {
  1303.             if(ClipInput)
  1304.             {
  1305.                 CloseClip();
  1306.  
  1307.                 ClipInput = ClipXerox = FALSE;
  1308.             }
  1309.  
  1310.                 /* VT100 prefers to handle
  1311.                  * the numeric keypad differently
  1312.                  * in applications mode.
  1313.                  */
  1314.  
  1315.             if(Qualifier & IEQUALIFIER_NUMERICPAD)
  1316.             {
  1317.                 if(HandleCursor(Char))
  1318.                     goto SkipIt;
  1319.             }
  1320.  
  1321.                 /* If input is not a control
  1322.                  * character, such as F-keys,
  1323.                  * cursor keys, etc. process
  1324.                  * it as usual.
  1325.                  */
  1326.  
  1327.             if(!IsBlank(Char))
  1328.             {
  1329.                 WORD    i;
  1330.                 UBYTE    c;
  1331.  
  1332.                     /* Run down the contents of
  1333.                      * the key result string.
  1334.                      */
  1335.  
  1336.                 for(i = 0 ; i < Len ; i++)
  1337.                 {
  1338.                     if(Config . StripBit8)
  1339.                         c = InputBuffer[i] & 0x7F;
  1340.                     else
  1341.                         c = InputBuffer[i];
  1342.  
  1343.                         /* Restart serial line
  1344.                          * after XON.
  1345.                          */
  1346.  
  1347.                     if(Status == STATUS_HOLDING)
  1348.                     {
  1349.                         if(c == XOF)
  1350.                         {
  1351.                             SerWrite(&c,1);
  1352.  
  1353.                             Status = STATUS_READY;
  1354.                         }
  1355.                         else
  1356.                             DoBeep();
  1357.                     }
  1358.                     else
  1359.                     {
  1360.                             /* Convert chars
  1361.                              * as approriate.
  1362.                              */
  1363.  
  1364.                         if(c == '\n')
  1365.                         {
  1366.                             switch(Config . SendLF)
  1367.                             {
  1368.                                 case LF_IGNORE:    break;
  1369.  
  1370.                                 case LF_ASLF:    goto SendIt;
  1371.  
  1372.                                 case LF_ASLFCR:    SerWrite("\n\r",2);
  1373.                                         break;
  1374.                             }
  1375.  
  1376.                             continue;
  1377.                         }
  1378.  
  1379.                         if(c == '\r')
  1380.                         {
  1381.                             switch(Config . SendCR)
  1382.                             {
  1383.                                 case CR_IGNORE:    break;
  1384.  
  1385.                                 case CR_ASCR:    goto SendIt;
  1386.  
  1387.                                 case CR_ASCRLF:    SerWrite("\r\n",2);
  1388.                                         break;
  1389.                             }
  1390.  
  1391.                             continue;
  1392.                         }
  1393.  
  1394.                             /* Stop in/output. */
  1395.  
  1396.                         if(c == XON)
  1397.                         {
  1398.                             if(Config . PassThrough)
  1399.                             {
  1400.                                 SerWrite(&c,1);
  1401.  
  1402.                                 continue;
  1403.                             }
  1404.                             else
  1405.                             {
  1406.                                 if(Config . xONxOFF)
  1407.                                     Status = STATUS_HOLDING;
  1408.                             }
  1409.                         }
  1410.  
  1411.                             /* Restart in/output. */
  1412.  
  1413.                         if(c == XOF)
  1414.                         {
  1415.                             if(Config . PassThrough)
  1416.                             {
  1417.                                 SerWrite(&c,1);
  1418.  
  1419.                                 continue;
  1420.                             }
  1421.                         }
  1422.  
  1423.                             /* Convert special
  1424.                              * Amiga characters into
  1425.                              * alien IBM dialect.
  1426.                              */
  1427.  
  1428. SendIt:                        if(Config . Font == FONT_IBM)
  1429.                         {
  1430.                             if(IBMConversion[c])
  1431.                                 SerWrite(&IBMConversion[c],1);
  1432.                             else
  1433.                                 SerWrite(&c,1);
  1434.                         }
  1435.                         else
  1436.                             SerWrite(&c,1);
  1437.                     }
  1438.                 }
  1439.             }
  1440.             else
  1441.             {
  1442.                     /* Send keyboard macro commands
  1443.                      * or perform cursor functions.
  1444.                      */
  1445.  
  1446.                 if(Char >= FN1 && Char <= F10)
  1447.                 {
  1448.                     if(Qualifier & IEQUALIFIER_CONTROL)
  1449.                         SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
  1450.                     else
  1451.                     {
  1452.                         if(Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT))
  1453.                             SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
  1454.                         else
  1455.                         {
  1456.                             if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  1457.                                 SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
  1458.                             else
  1459.                                 SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
  1460.                         }
  1461.                     }
  1462.                 }
  1463.                 else
  1464.                     HandleCursor(Char);
  1465.             }
  1466.         }
  1467.  
  1468.             /* Capture characters from the main
  1469.              * screen.
  1470.              */
  1471.  
  1472.         if(Class == IDCMP_MOUSEBUTTONS && !(Code & IECODE_UP_PREFIX))
  1473.         {
  1474.             if(Code == SELECTDOWN && (Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT)) && (Qualifier & IEQUALIFIER_LEFTBUTTON))
  1475.             {
  1476.                 WORD    DeltaX = MouseX / TextFontWidth  - CursorX,
  1477.                     DeltaY = MouseY / TextFontHeight - CursorY;
  1478.  
  1479.                 if(DeltaX || DeltaY)
  1480.                 {
  1481.                     if(DeltaX > 0)
  1482.                     {
  1483.                         DeltaX++;
  1484.  
  1485.                         while(DeltaX--)
  1486.                             SerWrite("\33[C",3);
  1487.                     }
  1488.  
  1489.                     if(DeltaX < 0)
  1490.                     {
  1491.                         while(DeltaX++)
  1492.                             SerWrite("\33[D",3);
  1493.                     }
  1494.  
  1495.                     if(DeltaY > 0)
  1496.                     {
  1497.                         DeltaY++;
  1498.  
  1499.                         while(DeltaY--)
  1500.                             SerWrite("\33[B",3);
  1501.                     }
  1502.  
  1503.                     if(DeltaY < 0)
  1504.                     {
  1505.                         while(DeltaY++)
  1506.                             SerWrite("\33[A",3);
  1507.                     }
  1508.                 }
  1509.             }
  1510.             else
  1511.             {
  1512.                 if(!XEmulatorBase || Config . Emulation != EMULATION_EXTERNAL)
  1513.                 {
  1514.                     BYTE SingleChar,Xerox;
  1515.  
  1516.                     Marking = TRUE;
  1517.  
  1518.                         /* We want to know where the mouse
  1519.                          * moves...
  1520.                          */
  1521.  
  1522.                     ReportMouse(TRUE,Window);
  1523.  
  1524.                         /* Pick a single character. */
  1525.  
  1526.                     if(Qualifier & IEQUALIFIER_CONTROL)
  1527.                         SingleChar = TRUE;
  1528.                     else
  1529.                         SingleChar = FALSE;
  1530.  
  1531.                         /* Xerox style snapping (feed into
  1532.                          * input stream after selection).
  1533.                          */
  1534.  
  1535.                     if(Code == MIDDLEDOWN || (Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)))
  1536.                         Xerox = TRUE;
  1537.                     else
  1538.                         Xerox = FALSE;
  1539.  
  1540.                     MarkClip(SingleChar,Xerox);
  1541.  
  1542.                     ReportMouse(FALSE,Window);
  1543.  
  1544.                     while(Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort))
  1545.                         GT_ReplyIMsg(Massage);
  1546.  
  1547.                     Marking = FALSE;
  1548.  
  1549.                     return(Result);
  1550.                 }
  1551.             }
  1552.         }
  1553.  
  1554.             /* A menu item was selected. */
  1555.  
  1556. SkipIt:        if(Class == IDCMP_MENUPICK)
  1557.             HandleMenu(Code,Qualifier);
  1558.  
  1559.         return(TRUE);
  1560.     }
  1561.  
  1562.     return(Result);
  1563. }
  1564.  
  1565.     /* TransferCleanup():
  1566.      *
  1567.      * We did a file transfer (auto-download?) and
  1568.      * will need to close the transfer window.
  1569.      */
  1570.  
  1571. VOID
  1572. TransferCleanup()
  1573. {
  1574.     if(DidTransfer)
  1575.     {
  1576.         WakeUp(TransferWindow);
  1577.  
  1578.         WaitTime(2,0);
  1579.  
  1580.         DeleteTransferPanel();
  1581.  
  1582.         if(SendAbort && UsesZModem)
  1583.             SerWrite(ZModemCancel,20);
  1584.  
  1585.         SendAbort = FALSE;
  1586.  
  1587.         if(Config . DownloadMacro[0])
  1588.             SerialCommand(Config . DownloadMacro);
  1589.  
  1590.         Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
  1591.  
  1592.         DidTransfer = FALSE;
  1593.     }
  1594.     else
  1595.     {
  1596.         WaitTime(3,0);
  1597.  
  1598.         DeleteTransferPanel();
  1599.     }
  1600.  
  1601.     ReleaseWindows();
  1602. }
  1603.  
  1604.     /* HandleSerial():
  1605.      *
  1606.      *    Handle the data coming in from the serial line.
  1607.      */
  1608.  
  1609. BYTE
  1610. HandleSerial()
  1611. {
  1612.     if(ReadPort && !ReleaseSerial && !MainTerminated)
  1613.     {
  1614.         BYTE Return = FALSE;
  1615.  
  1616.         if(HostReadBuffer)
  1617.         {
  1618.             LONG Length;
  1619.  
  1620.             if(Length = XProtocolHostMon(XprIO,HostReadBuffer,0,Config . SerBuffSize))
  1621.             {
  1622.                 ConProcess(ReadBuffer,Length);
  1623.  
  1624.                 Return = TRUE;
  1625.             }
  1626.         }
  1627.  
  1628.             /* We are XON'ed or the serial line was shut down. */
  1629.  
  1630.         if(Status != STATUS_HOLDING && !Blocking)
  1631.         {
  1632.             register ULONG MaxReadSize = Config . SerBuffSize;
  1633.  
  1634.             if(MaxReadSize > ReadRequest -> io_Baud / 4)
  1635.                 MaxReadSize = ReadRequest -> io_Baud / 4;
  1636.  
  1637.                 /* Any news? */
  1638.  
  1639.             if(CheckIO(ReadRequest))
  1640.             {
  1641.                 LONG Length;
  1642.  
  1643.                 if(WaitIO(ReadRequest))
  1644.                 {
  1645.                     ReadRequest -> IOSer . io_Command    = CMD_READ;
  1646.                     ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1647.                     ReadRequest -> IOSer . io_Length     = 1;
  1648.  
  1649.                     SetSignal(0,SIG_SERIAL);
  1650.  
  1651.                     SendIO(ReadRequest);
  1652.  
  1653.                     return(Return);
  1654.                 }
  1655.  
  1656.                 BytesIn++;
  1657.  
  1658.                 if(XProtocolBase)
  1659.                 {
  1660.                         /* Process the data if necessary (XPR-function). */
  1661.  
  1662.                     if(TransferBits & XPRS_HOSTMON)
  1663.                     {
  1664.                         LONG Result = XProtocolHostMon(XprIO,ReadBuffer,1,1);
  1665.  
  1666.                         if(TransferWindow)
  1667.                             TransferCleanup();
  1668.  
  1669.                         if(!Result)
  1670.                             goto Loop;
  1671.                     }
  1672.                 }
  1673.  
  1674.                     /* Send the byte to the console. */
  1675.  
  1676.                 ConProcess(ReadBuffer,1);
  1677.  
  1678.                     /* Loop until all data has been processed. */
  1679.  
  1680. Loop:                do
  1681.                 {
  1682.                         /* Check how many bytes are still in
  1683.                          * the serial buffer.
  1684.                          */
  1685.  
  1686.                     WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1687.  
  1688.                     DoIO(WriteRequest);
  1689.  
  1690.                     if(Length = WriteRequest -> IOSer . io_Actual)
  1691.                     {
  1692.                         if(Length > MaxReadSize)
  1693.                             Length = MaxReadSize;
  1694.  
  1695.                         ReadRequest -> IOSer . io_Command    = CMD_READ;
  1696.                         ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1697.                         ReadRequest -> IOSer . io_Length    = Length;
  1698.  
  1699.                         if(!DoIO(ReadRequest))
  1700.                         {
  1701.                             BytesIn += ReadRequest -> IOSer . io_Actual;
  1702.  
  1703.                             if(XProtocolBase)
  1704.                             {
  1705.                                     /* Process the serial data if
  1706.                                      * necessary (XPR-stuff).
  1707.                                      */
  1708.  
  1709.                                 if(TransferBits & XPRS_HOSTMON)
  1710.                                 {
  1711.                                     Length = XProtocolHostMon(XprIO,ReadBuffer,Length,Config . SerBuffSize);
  1712.  
  1713.                                     if(TransferWindow)
  1714.                                         TransferCleanup();
  1715.  
  1716.                                     if(!Length)
  1717.                                     {
  1718.                                         Length = 1;
  1719.  
  1720.                                         continue;
  1721.                                     }
  1722.                                 }
  1723.                             }
  1724.  
  1725.                                 /* Send the data to the console. */
  1726.  
  1727.                             ConProcess(ReadBuffer,Length);
  1728.                         }
  1729.                     }
  1730.                 }
  1731.                 while(Length);
  1732.  
  1733.                     /* Ask for another byte. */
  1734.  
  1735.                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  1736.                 ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1737.                 ReadRequest -> IOSer . io_Length     = 1;
  1738.  
  1739.                 SetSignal(0,SIG_SERIAL);
  1740.  
  1741.                 SendIO(ReadRequest);
  1742.  
  1743.                 return(TRUE);
  1744.             }
  1745.         }
  1746.  
  1747.         return(Return);
  1748.     }
  1749.  
  1750.     return(FALSE);
  1751. }
  1752.  
  1753.     /* HandleCode(ULONG Code,ULONG Qualifier,struct MenuItem *MenuItem):
  1754.      *
  1755.      *    Handle each function associated with a menu code.
  1756.      */
  1757.  
  1758. VOID
  1759. HandleCode(ULONG Code,ULONG Qualifier,struct MenuItem *MenuItem)
  1760. {
  1761.     STATIC UBYTE         NumberBuffer[256];
  1762.  
  1763.     struct FileRequester    *FileRequest;
  1764.     UBYTE             DummyBuffer[256],
  1765.                 *DummyChar;
  1766.     BYTE             OldStatus = Status;
  1767.  
  1768.     BPTR             SomeFile;
  1769.     APTR             OldPtr;
  1770.  
  1771.     switch(Code)
  1772.     {
  1773.             /* Save screen as IFF-ILBM file. */
  1774.  
  1775.         case MEN_SAVE_AS_PICTURE:
  1776.  
  1777.                     BlockWindows();
  1778.  
  1779.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT)))
  1780.                     {
  1781.                         if(!SaveRPort(&Screen -> RastPort,VPort,0,Window -> TopEdge,Window -> Width,Window -> Height,Screen -> Width,Screen -> Height,FALSE,DummyBuffer))
  1782.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SAVE_SCREEN_TO_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  1783.  
  1784.                         FreeAslRequest(FileRequest);
  1785.                     }
  1786.  
  1787.                     ReleaseWindows();
  1788.  
  1789.                     break;
  1790.  
  1791.             /* Save screen as ASCII file. */
  1792.  
  1793.         case MEN_SAVE_AS_TEXT:
  1794.  
  1795.                     BlockWindows();
  1796.  
  1797.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT)))
  1798.                     {
  1799.                         if(GetFileSize(DummyBuffer))
  1800.                         {
  1801.                             switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  1802.                             {
  1803.                                 case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  1804.                                     break;
  1805.  
  1806.                                 case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  1807.                                     {
  1808.                                         if(Seek(SomeFile,0,OFFSET_END) == -1)
  1809.                                         {
  1810.                                             Close(SomeFile);
  1811.  
  1812.                                             SomeFile = NULL;
  1813.                                         }
  1814.                                     }
  1815.  
  1816.                                     break;
  1817.  
  1818.                                 case 0:    SomeFile = ~0;
  1819.                                     break;
  1820.                             }
  1821.                         }
  1822.                         else
  1823.                             SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  1824.  
  1825.                         if(!SomeFile)
  1826.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SAVE_SCREEN_TO_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  1827.                         else
  1828.                         {
  1829.                             if(SomeFile != ~0)
  1830.                             {
  1831.                                 WORD     i,j;
  1832.                                 UBYTE    *Buffer;
  1833.  
  1834.                                 for(i = 0 ; i < RasterHeight ; i++)
  1835.                                 {
  1836.                                     Buffer = &Raster[i * RasterWidth];
  1837.  
  1838.                                     j = LastColumn;
  1839.  
  1840.                                     while(j >= 0 && Buffer[j] == ' ')
  1841.                                         j--;
  1842.  
  1843.                                     if(j >= 0)
  1844.                                     {
  1845.                                         if(!FWrite(SomeFile,Buffer,j + 1,1))
  1846.                                             break;
  1847.                                     }
  1848.  
  1849.                                     if(!FWrite(SomeFile,"\n",1,1))
  1850.                                         break;
  1851.                                 }
  1852.  
  1853.                                 Close(SomeFile);
  1854.  
  1855.                                 SetProtection(DummyBuffer,FIBF_EXECUTE);
  1856.                             }
  1857.                         }
  1858.  
  1859.                         FreeAslRequest(FileRequest);
  1860.                     }
  1861.  
  1862.                     ReleaseWindows();
  1863.  
  1864.                     break;
  1865.  
  1866.             /* Print the screen (pure ASCII). */
  1867.  
  1868.         case MEN_PRINT_SCREEN:
  1869.  
  1870.                     BlockWindows();
  1871.  
  1872.                     if(!XEmulatorBase || Config . Emulation != EMULATION_EXTERNAL)
  1873.                         PrintSomething(PRINT_SCREEN);
  1874.                     else
  1875.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NO_DATA_TO_PRINT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  1876.  
  1877.                     ReleaseWindows();
  1878.  
  1879.                     break;
  1880.  
  1881.             /* Print the clipboard contents. */
  1882.  
  1883.         case MEN_PRINT_CLIP:
  1884.  
  1885.                     BlockWindows();
  1886.  
  1887.                     PrintSomething(PRINT_CLIP);
  1888.  
  1889.                     ReleaseWindows();
  1890.  
  1891.                     break;
  1892.  
  1893.             /* Open/close the terminal capture file. */
  1894.  
  1895.         case MEN_CAPTURE_TO_FILE:
  1896.  
  1897.                     if(FileCapture)
  1898.                     {
  1899.                         BufferClose(FileCapture);
  1900.  
  1901.                         MenuItem -> Flags &= ~CHECKED;
  1902.  
  1903.                         FileCapture = NULL;
  1904.  
  1905.                         if(!GetFileSize(CaptureName))
  1906.                             DeleteFile(CaptureName);
  1907.                         else
  1908.                             SetProtection(CaptureName,FIBF_EXECUTE);
  1909.                     }
  1910.                     else
  1911.                     {
  1912.                         BlockWindows();
  1913.  
  1914.                         if(!CaptureName[0])
  1915.                         {
  1916.                             strcpy(CaptureName,Config . CapturePath);
  1917.  
  1918.                             if(!AddPart(CaptureName,LocaleString(MSG_DIALPANEL_CAPTURE_NAME_TXT),256))
  1919.                                 CaptureName[0] = 0;
  1920.                         }
  1921.  
  1922.                         strcpy(DummyBuffer,CaptureName);
  1923.  
  1924.                         DummyChar = PathPart(DummyBuffer);
  1925.  
  1926.                         *DummyChar = 0;
  1927.  
  1928.                         if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_CAPTURE_TO_DISK_TXT),DummyBuffer,FilePart(CaptureName),DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_OPEN_TXT)))
  1929.                         {
  1930.                             if(GetFileSize(DummyBuffer))
  1931.                             {
  1932.                                 switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  1933.                                 {
  1934.                                     case 1:    FileCapture = BufferOpen(DummyBuffer,"w");
  1935.                                         break;
  1936.  
  1937.                                     case 2:    FileCapture = BufferOpen(DummyBuffer,"a");
  1938.                                         break;
  1939.  
  1940.                                     case 0:    MenuItem -> Flags &= ~CHECKED;
  1941.                                         goto CapSkip;
  1942.                                 }
  1943.                             }
  1944.                             else
  1945.                                 FileCapture = BufferOpen(DummyBuffer,"w");
  1946.  
  1947.                             if(!FileCapture)
  1948.                             {
  1949.                                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  1950.  
  1951.                                 MenuItem -> Flags &= ~CHECKED;
  1952.                             }
  1953.                             else
  1954.                             {
  1955.                                 strcpy(CaptureName,DummyBuffer);
  1956.  
  1957.                                 MenuItem -> Flags |= CHECKED;
  1958.                             }
  1959.  
  1960.                             FreeAslRequest(FileRequest);
  1961.                         }
  1962.                         else
  1963.                             MenuItem -> Flags &= ~CHECKED;
  1964.  
  1965. CapSkip:                    ReleaseWindows();
  1966.                     }
  1967.  
  1968.                     break;
  1969.  
  1970.             /* Start/terminate the printer
  1971.              * capture.
  1972.              */
  1973.  
  1974.         case MEN_CAPTURE_TO_PRINTER:
  1975.  
  1976.                     if(PrinterCapture)
  1977.                         ClosePrinterCapture(TRUE);
  1978.                     else
  1979.                         OpenPrinterCapture(FALSE);
  1980.  
  1981.                     break;
  1982.  
  1983.             /* Iconify the program. */
  1984.  
  1985.         case MEN_ICONIFY:
  1986.  
  1987.                     DoIconify = TRUE;
  1988.  
  1989.                     break;
  1990.  
  1991.             /* Say who we are. */
  1992.  
  1993.         case MEN_ABOUT:
  1994.  
  1995.                     BlockWindows();
  1996.  
  1997.                     ShowInfo(FALSE);
  1998.  
  1999.                     ReleaseWindows();
  2000.  
  2001.                     break;
  2002.  
  2003.             /* Terminate the program. */
  2004.  
  2005.         case MEN_QUIT:        if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  2006.                         MainTerminated = TRUE;
  2007.                     else
  2008.                     {
  2009.                         BlockWindows();
  2010.  
  2011.                         OldPtr = ThisProcess -> pr_WindowPtr;
  2012.  
  2013.                         ThisProcess -> pr_WindowPtr = (APTR)Window;
  2014.  
  2015.                         if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2016.                             MainTerminated = TRUE;
  2017.  
  2018.                         ThisProcess -> pr_WindowPtr = OldPtr;
  2019.  
  2020.                         ReleaseWindows();
  2021.                     }
  2022.  
  2023.                     break;
  2024.  
  2025.             /* Feed the contents of the clipboard
  2026.              * into the input stream.
  2027.              */
  2028.  
  2029.         case MEN_PASTE:
  2030.  
  2031.                     if(!OpenClip())
  2032.                         ClipInput = TRUE;
  2033.                     else
  2034.                         ClipInput = FALSE;
  2035.  
  2036.                     break;
  2037.  
  2038.             /* Execute an AmigaDOS command. */
  2039.  
  2040.         case MEN_EXECUTE_DOS_COMMAND:
  2041.  
  2042.                     BlockWindows();
  2043.  
  2044.                     DummyBuffer[0] = 0;
  2045.  
  2046.                         /* Enter the name of the command. */
  2047.  
  2048.                     if(GetString(LocaleString(MSG_TERMMAIN_ENTER_AMIGADOS_COMMAND_TXT),DummyBuffer))
  2049.                         SendAmigaDOSCommand(DummyBuffer);
  2050.  
  2051.                     ReleaseWindows();
  2052.  
  2053.                     break;
  2054.  
  2055.             /* Execute an ARexx script command. */
  2056.  
  2057.         case MEN_EXECUTE_REXX_COMMAND:
  2058.  
  2059.                     BlockWindows();
  2060.  
  2061.                     DummyBuffer[0] = 0;
  2062.  
  2063.                         /* Get the rexx file name/program. */
  2064.  
  2065.                     if(GetString(LocaleString(MSG_TERMMAIN_ENTER_AREXX_COMMAND_TXT),DummyBuffer))
  2066.                         SendARexxCommand(DummyBuffer);
  2067.  
  2068.                     ReleaseWindows();
  2069.  
  2070.                     break;
  2071.  
  2072.             /* Set the name we will use to open the
  2073.              * default console output window for
  2074.              * AmigaDOS commands and ARexx scripts.
  2075.              */
  2076.  
  2077.         case MEN_SET_CONSOLE:
  2078.  
  2079.                     BlockWindows();
  2080.  
  2081.                     if(xpr_gets(LocaleString(MSG_TERMMAIN_SET_CONSOLE_WINDOW_TXT),WindowName))
  2082.                         SetEnvDOS("TERMWINDOW",WindowName);
  2083.  
  2084.                     ReleaseWindows();
  2085.  
  2086.                     break;
  2087.  
  2088.             /* Open the phonebook and dial the
  2089.              * list of entries the user will select.
  2090.              */
  2091.  
  2092.         case MEN_PHONEBOOK:
  2093.  
  2094.                     BlockWindows();
  2095.  
  2096.                     while(PhonePanel())
  2097.                     {
  2098.                         if(!DialPanel())
  2099.                         {
  2100.                             Status = OldStatus;
  2101.  
  2102.                             break;
  2103.                         }
  2104.  
  2105.                         Status = OldStatus;
  2106.                     }
  2107.  
  2108.                     ReleaseWindows();
  2109.  
  2110.                     break;
  2111.  
  2112.             /* Redial those dial list entries which
  2113.              * we were unable to connect.
  2114.              */
  2115.  
  2116.         case MEN_REDIAL:
  2117.  
  2118.                     BlockWindows();
  2119.  
  2120.                     if(DialList)
  2121.                     {
  2122.                         if(DialList -> lh_Head -> ln_Succ)
  2123.                         {
  2124.                             DialPanel();
  2125.  
  2126.                             Status = OldStatus;
  2127.                         }
  2128.                         else
  2129.                             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_CURRENT_DIALING_LIST_IS_EMPTY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2130.                     }
  2131.                     else
  2132.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_CURRENT_DIALING_LIST_IS_EMPTY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2133.  
  2134.                     ReleaseWindows();
  2135.  
  2136.                     break;
  2137.  
  2138.             /* Dial a single number. */
  2139.  
  2140.         case MEN_DIAL_NUMBER:
  2141.  
  2142.                     BlockWindows();
  2143.  
  2144.                     if(xpr_gets(LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TXT),NumberBuffer))
  2145.                     {
  2146.                         if(NumberBuffer[0])
  2147.                         {
  2148.                             struct List *LocalList;
  2149.  
  2150.                             if(LocalList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
  2151.                             {
  2152.                                 struct PhoneNode *DialNode;
  2153.  
  2154.                                 NewList(LocalList);
  2155.  
  2156.                                 if(DialNode = (struct PhoneNode *)AllocVec(sizeof(struct PhoneNode),MEMF_ANY|MEMF_CLEAR))
  2157.                                 {
  2158.                                     DialNode -> VanillaNode . ln_Name = (UBYTE *)NumberBuffer;
  2159.  
  2160.                                     AddTail(LocalList,&DialNode -> VanillaNode);
  2161.  
  2162.                                     FreeDialList();
  2163.  
  2164.                                     DialList = LocalList;
  2165.  
  2166.                                     DialPanel();
  2167.  
  2168.                                     Status = OldStatus;
  2169.                                 }
  2170.                                 else
  2171.                                     FreeVec(LocalList);
  2172.                             }
  2173.                         }
  2174.                     }
  2175.  
  2176.                     ReleaseWindows();
  2177.  
  2178.                     break;
  2179.  
  2180.             /* Play a touch-tone phone number. */
  2181.  
  2182.         case MEN_PLAY_NUMBER:
  2183.  
  2184.                     BlockWindows();
  2185.  
  2186.                     if(xpr_gets(LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TO_PLAY_TXT),NumberBuffer))
  2187.                     {
  2188.                         if(!ToneDial(NumberBuffer))
  2189.                             MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_GLOBAL_FAILED_TO_ALLOCATE_RESOURCES_FOR_PLAYING_TXT));
  2190.                         else
  2191.                             DeleteTone();
  2192.                     }
  2193.  
  2194.                     ReleaseWindows();
  2195.                     break;
  2196.  
  2197.  
  2198.             /* Send a break across the serial line. */
  2199.  
  2200.         case MEN_SEND_BREAK:
  2201.  
  2202.                     if(WriteRequest)
  2203.                     {
  2204.                         Status = STATUS_BREAKING;
  2205.  
  2206.                         WriteRequest -> IOSer . io_Command = SDCMD_BREAK;
  2207.  
  2208.                         DoIO(WriteRequest);
  2209.  
  2210.                         Status = OldStatus;
  2211.                     }
  2212.  
  2213.                     break;
  2214.  
  2215.             /* Hang up the phone line. */
  2216.  
  2217.         case MEN_HANG_UP:
  2218.  
  2219.                     BlockWindows();
  2220.  
  2221.                     Status = STATUS_HANGUP;
  2222.  
  2223.                         /* Are we to drop the DTR line
  2224.                          * before sending the hangup
  2225.                          * string?
  2226.                          */
  2227.  
  2228.                     if(Config . DropDTR)
  2229.                     {
  2230.                         /* Let's be nice and try to transmit the
  2231.                          * `drop the line' command before
  2232.                          * trying to close and reopen the driver.
  2233.                          */
  2234.  
  2235.                         WriteRequest -> IOSer . io_Command    = SIOCMD_SETCTRLLINES;
  2236.                         WriteRequest -> IOSer . io_Offset    = SIOB_DTRF;
  2237.                         WriteRequest -> IOSer . io_Length    = 0;
  2238.  
  2239.                         /* Transmit the command. */
  2240.  
  2241.                         if(!DoIO(WriteRequest))
  2242.                         {
  2243.                             /* Wait a bit... */
  2244.  
  2245.                             WaitTime(1,0);
  2246.  
  2247.                             /* Raise the line again. */
  2248.  
  2249.                             WriteRequest -> IOSer . io_Command    = SIOCMD_SETCTRLLINES;
  2250.                             WriteRequest -> IOSer . io_Offset    = SIOB_DTRF;
  2251.                             WriteRequest -> IOSer . io_Length    = SIOB_DTRF;
  2252.  
  2253.                             DoIO(WriteRequest);
  2254.                         }
  2255.                         else
  2256.                         {
  2257.                             /* Do it the standard way: close and reopen
  2258.                              * the serial driver (the serial.device is
  2259.                              * supposed to drop the DTR line when closed).
  2260.                              */
  2261.  
  2262.                             if(!DropDTR())
  2263.                             {
  2264.                                 if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_REOPEN_UNIT_TXT),LocaleString(MSG_TERMMAIN_IGNORE_QUIT_TXT),Config . SerialDevice,Config . UnitNumber))
  2265.                                     MainTerminated = TRUE;
  2266.                             }
  2267.                         }
  2268.                     }
  2269.  
  2270.                         /* Transmit the hangup command. */
  2271.  
  2272.                     SerialCommand(Config . ModemHangup);
  2273.  
  2274.                         /* Reset to old status. */
  2275.  
  2276.                     Status = OldStatus;
  2277.  
  2278.                         /* We are no longer online. */
  2279.  
  2280.                     Online = FALSE;
  2281.  
  2282.                         /* Clear the password. */
  2283.  
  2284.                     Password[0] = 0;
  2285.  
  2286.                         /* Clear the user name as well. */
  2287.  
  2288.                     UserName[0] = 0;
  2289.  
  2290.                         /* Note the  last action. */
  2291.  
  2292.                     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
  2293.  
  2294.                     ReleaseWindows();
  2295.  
  2296.                         /* Execute logoff macro. */
  2297.  
  2298.                     if(Config . LogoffMacro[0] && WasOnline)
  2299.                         SerialCommand(Config . LogoffMacro);
  2300.  
  2301.                         /* Update the logfile. */
  2302.  
  2303.                     StopCall(FALSE);
  2304.  
  2305.                         /* Don't execute the logoff macro twice. */
  2306.  
  2307.                     WasOnline = FALSE;
  2308.  
  2309.                         /* Enable the dialing functions. */
  2310.  
  2311.                     SetDialMenu(TRUE);
  2312.  
  2313.                     break;
  2314.  
  2315.             /* Flush the serial buffers. */
  2316.  
  2317.         case MEN_FLUSH_BUFFER:
  2318.  
  2319.                     ClearSerial();
  2320.  
  2321.                     if(ReadRequest)
  2322.                     {
  2323.                         ReadRequest -> IOSer . io_Command    = CMD_READ;
  2324.                         ReadRequest -> IOSer . io_Data        = ReadBuffer;
  2325.                         ReadRequest -> IOSer . io_Length     = 1;
  2326.  
  2327.                         SetSignal(0,SIG_SERIAL);
  2328.  
  2329.                         SendIO(ReadRequest);
  2330.                     }
  2331.  
  2332.                     break;
  2333.  
  2334.             /* Release the serial device for other
  2335.              * applications.
  2336.              */
  2337.  
  2338.         case MEN_RELEASE_DEVICE:
  2339.  
  2340.                     ReleaseSerial = TRUE;
  2341.                     break;
  2342.  
  2343.         case MEN_UPLOAD_ASCII:
  2344.  
  2345.                     BlockWindows();
  2346.  
  2347.                     if(ASCIISetup())
  2348.                     {
  2349.                         StartXprSend(TRANSFER_ASCII);
  2350.  
  2351.                         ASCIIShutdown();
  2352.                     }
  2353.  
  2354.                     ReleaseWindows();
  2355.  
  2356.                     break;
  2357.  
  2358.         case MEN_DOWNLOAD_ASCII:
  2359.  
  2360.                     BlockWindows();
  2361.  
  2362.                     if(ASCIISetup())
  2363.                     {
  2364.                         StartXprReceive(TRANSFER_ASCII);
  2365.  
  2366.                         ASCIIShutdown();
  2367.                     }
  2368.  
  2369.                     ReleaseWindows();
  2370.  
  2371.                     break;
  2372.  
  2373.         case MEN_UPLOAD_TEXT:
  2374.  
  2375.                     BlockWindows();
  2376.  
  2377.                     BinaryTransfer = FALSE;
  2378.  
  2379.                     StartXprSend(TRANSFER_TEXT);
  2380.  
  2381.                     BinaryTransfer = TRUE;
  2382.  
  2383.                     ReleaseWindows();
  2384.  
  2385.                     break;
  2386.  
  2387.         case MEN_DOWNLOAD_TEXT:
  2388.                     BlockWindows();
  2389.  
  2390.                     BinaryTransfer = FALSE;
  2391.  
  2392.                     StartXprReceive(TRANSFER_TEXT);
  2393.  
  2394.                     BinaryTransfer = TRUE;
  2395.  
  2396.                     ReleaseWindows();
  2397.  
  2398.                     break;
  2399.  
  2400.             /* Edit and transfer a file. */
  2401.  
  2402.         case MEN_EDIT_AND_UPLOAD_TEXT:
  2403.  
  2404.                     BlockWindows();
  2405.  
  2406.                     if(!Config . Editor[0])
  2407.                         GetString(LocaleString(MSG_TERMMAIN_ENTER_NAME_OF_EDITOR_TO_USE_TXT),&Config . Editor[0]);
  2408.  
  2409.                     if(Config . Editor[0])
  2410.                     {
  2411.                         if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_EDIT_AND_TRANSFER_FILE_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMMAIN_EDIT_TXT)))
  2412.                         {
  2413.                             UBYTE CompoundName[512];
  2414.  
  2415.                             strcpy(CompoundName,Config . Editor);
  2416.                             strcat(CompoundName," ");
  2417.                             strcat(CompoundName,DummyBuffer);
  2418.  
  2419.                             SystemTags(CompoundName,TAG_DONE);
  2420.  
  2421.                             BumpWindow(Window);
  2422.  
  2423.                             FreeAslRequest(FileRequest);
  2424.  
  2425.                             if(GetFileSize(DummyBuffer))
  2426.                             {
  2427.                                 BinaryTransfer = FALSE;
  2428.  
  2429.                                 switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILE_AS_TXT),LocaleString(MSG_TERMMAIN_ASCII_UPLOAD_CANCEL_TXT),FilePart(DummyBuffer)))
  2430.                                 {
  2431.                                     case 1:    if(ASCIISetup())
  2432.                                         {
  2433.                                             SendTextFile(DummyBuffer);
  2434.  
  2435.                                             ASCIIShutdown();
  2436.                                         }
  2437.  
  2438.                                         break;
  2439.  
  2440.                                     case 2:    SendTextFile(DummyBuffer);
  2441.  
  2442.                                         break;
  2443.  
  2444.                                     case 0:    break;
  2445.                                 }
  2446.  
  2447.                                 BinaryTransfer = TRUE;
  2448.                             }
  2449.                         }
  2450.                     }
  2451.  
  2452.                     ReleaseWindows();
  2453.                     break;
  2454.  
  2455.         case MEN_UPLOAD_BINARY:
  2456.  
  2457.                     BlockWindows();
  2458.  
  2459.                     BinaryTransfer = TRUE;
  2460.  
  2461.                     StartXprSend(TRANSFER_BINARY);
  2462.  
  2463.                     ReleaseWindows();
  2464.  
  2465.                     break;
  2466.  
  2467.             /* Download some files. */
  2468.  
  2469.         case MEN_DOWNLOAD_BINARY:
  2470.  
  2471.                     BlockWindows();
  2472.  
  2473.                     BinaryTransfer = TRUE;
  2474.  
  2475.                     StartXprReceive(TRANSFER_BINARY);
  2476.  
  2477.                     ReleaseWindows();
  2478.  
  2479.                     break;
  2480.  
  2481.             /* Clear the contents of the scrollback
  2482.              * buffer.
  2483.              */
  2484.  
  2485.         case MEN_CLEAR_BUFFER:
  2486.  
  2487.                     if(Lines)
  2488.                     {
  2489.                         BlockWindows();
  2490.  
  2491.                         if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  2492.                             ClearBuffer();
  2493.                         else
  2494.                         {
  2495.                             if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  2496.                                 ClearBuffer();
  2497.                         }
  2498.  
  2499.                         UpdateReview(TRUE);
  2500.  
  2501.                         ReleaseWindows();
  2502.                     }
  2503.  
  2504.                     break;
  2505.  
  2506.             /* Display the scrollback buffer.
  2507.              * Notify the scrollback task or
  2508.              * fire it off if approriate.
  2509.              */
  2510.  
  2511.         case MEN_DISPLAY_BUFFER:
  2512.  
  2513.                     if(!LaunchBuffer())
  2514.                     {
  2515.                         BlockWindows();
  2516.  
  2517.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNABLE_TO_CREATE_BUFFER_TASK_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2518.  
  2519.                         ReleaseWindows();
  2520.                     }
  2521.  
  2522.                     break;
  2523.  
  2524.  
  2525.             /* Close the buffer display. */
  2526.  
  2527.         case MEN_CLOSE_BUFFER:
  2528.  
  2529.                     if(BufferProcess)
  2530.                     {
  2531.                         Signal(BufferProcess,SIGBREAKF_CTRL_C);
  2532.  
  2533.                         Wait(SIGBREAKF_CTRL_C);
  2534.                     }
  2535.  
  2536.                     break;
  2537.  
  2538.             /* Is the buffer to be frozen? */
  2539.  
  2540.         case MEN_FREEZE_BUFFER:
  2541.  
  2542.                     if(MenuItem -> Flags & CHECKED)
  2543.                         BufferFrozen = TRUE;
  2544.                     else
  2545.                         BufferFrozen = FALSE;
  2546.  
  2547.                     break;
  2548.  
  2549.             /* Load the buffer contents from a file. */
  2550.  
  2551.         case MEN_OPEN_BUFFER:
  2552.  
  2553.                     BlockWindows();
  2554.  
  2555.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT)))
  2556.                     {
  2557.                         if(GetFileSize(DummyBuffer))
  2558.                         {
  2559.                             if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  2560.                             {
  2561.                                 if(Lines)
  2562.                                 {
  2563.                                     switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_TERMMAIN_DISCARD_APPPEND_CANCEL_TXT),Lines))
  2564.                                     {
  2565.                                         case 1:    ClearBuffer();
  2566.                                             break;
  2567.  
  2568.                                         case 2:    break;
  2569.  
  2570.                                         case 0:    Close(SomeFile);
  2571.                                             SomeFile = NULL;
  2572.                                             break;
  2573.                                     }
  2574.                                 }
  2575.  
  2576.                                 if(SomeFile)
  2577.                                 {
  2578.                                     LONG Len;
  2579.  
  2580.                                     LineRead(NULL,NULL,NULL);
  2581.  
  2582.                                     while(Len = LineRead(SomeFile,DummyBuffer,80))
  2583.                                         StoreBuffer(DummyBuffer,Len);
  2584.  
  2585.                                     Close(SomeFile);
  2586.                                 }
  2587.                             }
  2588.                         }
  2589.  
  2590.                         FreeAslRequest(FileRequest);
  2591.                     }
  2592.  
  2593.                     ReleaseWindows();
  2594.                     break;
  2595.  
  2596.             /* Save the contents of the scrollback
  2597.              * buffer to a file (line by line).
  2598.              */
  2599.  
  2600.         case MEN_SAVE_BUFFER_AS:
  2601.  
  2602.                     BlockWindows();
  2603.  
  2604.                     if(!Lines)
  2605.                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2606.                     else
  2607.                     {
  2608.                         if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT)))
  2609.                         {
  2610.                             SomeFile = NULL;
  2611.  
  2612.                                 /* If the file we are about
  2613.                                  * to create already exists,
  2614.                                  * ask the user whether we are
  2615.                                  * to create, append or skip
  2616.                                  * the file.
  2617.                                  */
  2618.  
  2619.                             if(GetFileSize(DummyBuffer))
  2620.                             {
  2621.                                 switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  2622.                                 {
  2623.                                     case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2624.                                         break;
  2625.  
  2626.                                     case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  2627.                                         {
  2628.                                             if(Seek(SomeFile,0,OFFSET_END) == -1)
  2629.                                             {
  2630.                                                 Close(SomeFile);
  2631.  
  2632.                                                 SomeFile = NULL;
  2633.                                             }
  2634.                                         }
  2635.  
  2636.                                         break;
  2637.                                 }
  2638.                             }
  2639.                             else
  2640.                                 SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2641.  
  2642.                             if(!SomeFile)
  2643.                                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  2644.                             else
  2645.                             {
  2646.                                 LONG i,Len;
  2647.  
  2648.                                     /* Obtain the semaphore required
  2649.                                      * to gain access to the line buffer
  2650.                                      */
  2651.  
  2652.                                 ObtainSemaphore(BufferSemaphore);
  2653.  
  2654.                                 for(i = 0 ; i < Lines ; i++)
  2655.                                 {
  2656.                                     Len = ((ULONG *)BufferLines[i])[-1];
  2657.  
  2658.                                     if(Len)
  2659.                                     {
  2660.                                         if(FWrite(SomeFile,BufferLines[i],Len,1) != 1)
  2661.                                             break;
  2662.                                     }
  2663.  
  2664.                                     if(FPrintf(SomeFile,"\n") < 1)
  2665.                                         break;
  2666.                                 }
  2667.  
  2668.                                 ReleaseSemaphore(BufferSemaphore);
  2669.  
  2670.                                 Close(SomeFile);
  2671.  
  2672.                                 SetProtection(DummyBuffer,FIBF_EXECUTE);
  2673.                             }
  2674.  
  2675.                             FreeAslRequest(FileRequest);
  2676.                         }
  2677.                     }
  2678.  
  2679.                     ReleaseWindows();
  2680.  
  2681.                     break;
  2682.  
  2683.             /* Simply clear the screen and move the
  2684.              * cursor to its home position.
  2685.              */
  2686.  
  2687.         case MEN_CLEAR_SCREEN:
  2688.  
  2689.                     if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2690.                         XEmulatorClearConsole(XEM_IO);
  2691.                     else
  2692.                     {
  2693.                         EraseScreen("2J");
  2694.                         SetAbsolutePosition("H");
  2695.                     }
  2696.  
  2697.                     break;
  2698.  
  2699.             /* Reset the current text rendering font. */
  2700.  
  2701.         case MEN_RESET_FONT:
  2702.  
  2703.                     if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2704.                         XEmulatorResetCharset(XEM_IO);
  2705.                     else
  2706.                     {
  2707.                         CurrentFont = TextFont;
  2708.  
  2709.                         SetFont(RPort,CurrentFont);
  2710.                     }
  2711.  
  2712.                     break;
  2713.  
  2714.             /* Reset the display styles and restore
  2715.              * the colours.
  2716.              */
  2717.  
  2718.         case MEN_RESET_STYLES:
  2719.  
  2720.                     if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2721.                         XEmulatorResetTextStyles(XEM_IO);
  2722.                     else
  2723.                     {
  2724.                         SetAttributes("0m");
  2725.  
  2726.                         Config . FontScale = SCALE_NORMAL;
  2727.  
  2728.                         switch(Config . ColourMode)
  2729.                         {
  2730.                             case COLOUR_EIGHT:    FgPen = 7;
  2731.                                         break;
  2732.  
  2733.                             case COLOUR_SIXTEEN:    FgPen = 15;
  2734.                                         break;
  2735.  
  2736.                             case COLOUR_AMIGA:
  2737.                             default:        FgPen = 1;
  2738.                                         break;
  2739.                         }
  2740.  
  2741.                         BgPen = 0;
  2742.  
  2743.                         if(RPort -> FgPen != FgPen)
  2744.                             SetAPen(RPort,FgPen);
  2745.  
  2746.                         if(RPort -> BgPen != BgPen)
  2747.                             SetBPen(RPort,BgPen);
  2748.  
  2749.                         SetWrMsk(RPort,0xFF);
  2750.                     }
  2751.  
  2752.                     break;
  2753.  
  2754.             /* Reset the whole terminal. */
  2755.  
  2756.         case MEN_RESET_TERMINAL:
  2757.  
  2758.                     if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2759.                         XEmulatorResetConsole(XEM_IO);
  2760.                     else
  2761.                     {
  2762.                         DoCancel();
  2763.  
  2764.                         Reset();
  2765.                     }
  2766.  
  2767.                     break;
  2768.  
  2769.         case MEN_SET_EMULATION:
  2770.  
  2771.                     BlockWindows();
  2772.  
  2773.                     if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  2774.                     {
  2775.                         OptionTitle = LocaleString(MSG_TERMMAIN_EMULATION_PREFERENCES_TXT);
  2776.  
  2777.                         XEmulatorOptions(XEM_IO);
  2778.  
  2779.                         if(NewOptions)
  2780.                         {
  2781.                             SetEmulatorOptions(XEM_PREFS_SAVE);
  2782.  
  2783.                             NewOptions = FALSE;
  2784.                         }
  2785.  
  2786.                         OptionTitle = NULL;
  2787.                     }
  2788.                     else
  2789.                         EmulationPanel(&Config);
  2790.  
  2791.                     ReleaseWindows();
  2792.  
  2793.                     break;
  2794.  
  2795.             /* Set the serial preferences. */
  2796.  
  2797.         case MEN_SERIAL:
  2798.  
  2799.                     BlockWindows();
  2800.  
  2801.                     if(SerialPanel(&Config))
  2802.                         ConfigSetup();
  2803.  
  2804.                     ReleaseWindows();
  2805.  
  2806.                     break;
  2807.  
  2808.             /* Set the modem preferences. */
  2809.  
  2810.         case MEN_MODEM:
  2811.  
  2812.                     BlockWindows();
  2813.  
  2814.                     if(ModemPanel(&Config))
  2815.                         FlowInit();
  2816.  
  2817.                     ReleaseWindows();
  2818.  
  2819.                     break;
  2820.  
  2821.             /* Set the screen preferences. */
  2822.  
  2823.         case MEN_SCREEN:
  2824.  
  2825.                     BlockWindows();
  2826.  
  2827.                     if(ScreenPanel(&Config))
  2828.                         ResetDisplay = TRUE;
  2829.                     else
  2830.                         PubScreenStuff();
  2831.  
  2832.                     if(memcmp(&PrivateConfig . Colours[0],&Config . Colours[0],sizeof(UWORD) * 16))
  2833.                     {
  2834.                         switch(Config . ColourMode)
  2835.                         {
  2836.                             case COLOUR_EIGHT:    CopyMem(&Config . Colours[0],&ANSIColours[0],16 * sizeof(UWORD));
  2837.                                         break;
  2838.  
  2839.                             case COLOUR_SIXTEEN:    CopyMem(&Config . Colours[0],&EGAColours[0],16 * sizeof(UWORD));
  2840.                                         break;
  2841.  
  2842.                             case COLOUR_AMIGA:    CopyMem(&Config . Colours[0],&DefaultColours[0],16 * sizeof(UWORD));
  2843.                                         break;
  2844.  
  2845.                             case COLOUR_MONO:    CopyMem(&Config . Colours[0],&AtomicColours[0],16 * sizeof(UWORD));
  2846.                                         break;
  2847.                         }
  2848.                     }
  2849.  
  2850.                     ReleaseWindows();
  2851.  
  2852.                     break;
  2853.  
  2854.             /* Set the terminal preferences. */
  2855.  
  2856.         case MEN_TERMINAL:
  2857.  
  2858.                     BlockWindows();
  2859.  
  2860.                     TerminalPanel(&Config);
  2861.  
  2862.                     ConfigSetup();
  2863.  
  2864.                     ReleaseWindows();
  2865.  
  2866.                     break;
  2867.  
  2868.         case MEN_COMMANDS:
  2869.  
  2870.                     BlockWindows();
  2871.  
  2872.                     CommandPanel(&Config);
  2873.  
  2874.                     ReleaseWindows();
  2875.  
  2876.                     break;
  2877.  
  2878.         case MEN_MISC:
  2879.  
  2880.                     BlockWindows();
  2881.  
  2882.                     MiscPanel(&Config);
  2883.  
  2884.                     ConfigSetup();
  2885.  
  2886.                     ReleaseWindows();
  2887.  
  2888.                     break;
  2889.  
  2890.         case MEN_PATH:
  2891.  
  2892.                     BlockWindows();
  2893.  
  2894.                     if(PathPanel(&Config))
  2895.                     {
  2896.                         DeleteBeep();
  2897.  
  2898.                         if(Config . BeepSound[0])
  2899.                         {
  2900.                             if(!OpenSound(Config . BeepSound))
  2901.                                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_SOUND_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Config . BeepSound);
  2902.                         }
  2903.  
  2904.                         CreateBeep();
  2905.                     }
  2906.  
  2907.                     ReleaseWindows();
  2908.  
  2909.                     break;
  2910.  
  2911.             /* Set the file transfer options. */
  2912.  
  2913.         case MEN_TRANSFER:
  2914.  
  2915.                     BlockWindows();
  2916.  
  2917.                     for(;;)
  2918.                     {
  2919.                         XprIO -> xpr_filename = NULL;
  2920.  
  2921.                         NewLibrary = FALSE;
  2922.  
  2923.                             /* Set up the library options. */
  2924.  
  2925.                         if(XProtocolBase)
  2926.                         {
  2927.                             TransferBits = XProtocolSetup(XprIO);
  2928.  
  2929.                                 /* Successful? */
  2930.  
  2931.                             if(!(TransferBits & XPRS_SUCCESS))
  2932.                             {
  2933.                                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  2934.  
  2935.                                 CloseLibrary(XProtocolBase);
  2936.  
  2937.                                 XProtocolBase = NULL;
  2938.  
  2939.                                 LastXprLibrary[0] = 0;
  2940.  
  2941.                                 TransferBits = 0;
  2942.  
  2943.                                 break;
  2944.                             }
  2945.                         }
  2946.                         else
  2947.                             xpr_options(0,NULL);
  2948.  
  2949.                             /* Save the options if necessary. */
  2950.  
  2951.                         SaveProtocolOpts();
  2952.  
  2953.                         if(NewLibrary)
  2954.                         {
  2955.                             if(!ProtocolSetup())
  2956.                                 SetTransferMenu(FALSE);
  2957.                             else
  2958.                                 SetTransferMenu(TRUE);
  2959.  
  2960.                             if(strlen(LastXprLibrary) > 39)
  2961.                             {
  2962.                                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NAME_TOO_LONG_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2963.  
  2964.                                 strcpy(Config . Protocol,FilePart(LastXprLibrary));
  2965.                             }
  2966.                             else
  2967.                                 strcpy(Config . Protocol,LastXprLibrary);
  2968.                         }
  2969.                         else
  2970.                             break;
  2971.                     }
  2972.  
  2973.                     ReleaseWindows();
  2974.  
  2975.                     break;
  2976.  
  2977.             /* Select the transfer protocol; I had hoped
  2978.              * to get rid of this option but xprascii and
  2979.              * the older pre-2.0 standard xpr-libraries
  2980.              * forced it back in.
  2981.              */
  2982.  
  2983.         case MEN_TRANSFER_PROTOCOL:
  2984.  
  2985.                     BlockWindows();
  2986.  
  2987.                     if(SelectProtocol(LastXprLibrary,Window))
  2988.                     {
  2989.                         if(ProtocolSetup())
  2990.                         {
  2991.                             if(strlen(LastXprLibrary) > 39)
  2992.                             {
  2993.                                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NAME_TOO_LONG_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2994.  
  2995.                                 strcpy(Config . Protocol,FilePart(LastXprLibrary));
  2996.                             }
  2997.                             else
  2998.                                 strcpy(Config . Protocol,LastXprLibrary);
  2999.                         }
  3000.                         else
  3001.                         {
  3002.                             strcpy(LastXprLibrary,Config . Protocol);
  3003.  
  3004.                             ProtocolSetup();
  3005.                         }
  3006.  
  3007.                         if(!XProtocolBase)
  3008.                             SetTransferMenu(FALSE);
  3009.                         else
  3010.                             SetTransferMenu(TRUE);
  3011.                     }
  3012.  
  3013.                     ReleaseWindows();
  3014.  
  3015.                     break;
  3016.  
  3017.             /* Set the keyboard macros. */
  3018.  
  3019.         case MEN_MACROS:
  3020.  
  3021.                     BlockWindows();
  3022.  
  3023.                     if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  3024.                     {
  3025.                         XEmulatorMacroKeyFilter(XEM_IO,NULL);
  3026.  
  3027.                         MacroPanel(MacroKeys);
  3028.  
  3029.                         SetupXEM_MacroKeys(MacroKeys);
  3030.                     }
  3031.                     else
  3032.                         MacroPanel(MacroKeys);
  3033.  
  3034.                     ReleaseWindows();
  3035.  
  3036.                     break;
  3037.  
  3038.             /* Set the fast macros. */
  3039.  
  3040.         case MEN_FAST_MACROS:
  3041.  
  3042.                     BlockWindows();
  3043.  
  3044.                     FastMacroPanel();
  3045.  
  3046.                     ReleaseWindows();
  3047.  
  3048.                     break;
  3049.  
  3050.         case MEN_HOTKEYS:
  3051.  
  3052.                     BlockWindows();
  3053.  
  3054.                     if(HotkeyPanel(&Hotkeys))
  3055.                     {
  3056.                         if(!SetupCx())
  3057.                             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_SET_UP_HOTKEYS_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3058.                     }
  3059.  
  3060.                     ReleaseWindows();
  3061.  
  3062.                     break;
  3063.  
  3064.         case MEN_SPEECH:
  3065.  
  3066.                     BlockWindows();
  3067.  
  3068.                     SpeechPanel();
  3069.  
  3070.                     ReleaseWindows();
  3071.  
  3072.                     break;
  3073.  
  3074.             /* Open the preferences settings. */
  3075.  
  3076.         case MEN_OPEN_SETTINGS:
  3077.  
  3078.                     BlockWindows();
  3079.  
  3080.                     strcpy(DummyBuffer,LastConfig);
  3081.  
  3082.                     DummyChar = PathPart(DummyBuffer);
  3083.  
  3084.                     *DummyChar = 0;
  3085.  
  3086.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",FALSE,FALSE,FALSE,NULL))
  3087.                     {
  3088.                         if(ReadIFFData(DummyBuffer,&PrivateConfig,sizeof(struct Configuration),'PREF'))
  3089.                         {
  3090.                             swmem(&PrivateConfig,&Config,sizeof(struct Configuration));
  3091.  
  3092.                             strcpy(DummyBuffer,LastConfig);
  3093.  
  3094.                             UpdatePrefs(&Config);
  3095.  
  3096.                             ConfigSetup();
  3097.                         }
  3098.                         else
  3099.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  3100.  
  3101.                         FreeAslRequest(FileRequest);
  3102.                     }
  3103.  
  3104.                     ReleaseWindows();
  3105.  
  3106.                     break;
  3107.  
  3108.             /* Save the terminal preferences. */
  3109.  
  3110.         case MEN_SAVE_SETTINGS:
  3111.  
  3112.                     if(LastConfig[0])
  3113.                     {
  3114.                         BlockWindows();
  3115.  
  3116.                         if(!WriteIFFData(LastConfig,&Config,sizeof(struct Configuration),'PREF'))
  3117.                             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_ERROR_WRITING_PREFERENCES_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastConfig);
  3118.  
  3119.                         ReleaseWindows();
  3120.  
  3121.                         break;
  3122.                     }
  3123.  
  3124.             /* Save the terminal preferences to a
  3125.              * given file name.
  3126.              */
  3127.  
  3128.         case MEN_SAVE_SETTINGS_AS:
  3129.  
  3130.                     BlockWindows();
  3131.  
  3132.                     strcpy(DummyBuffer,LastConfig);
  3133.  
  3134.                     DummyChar = PathPart(DummyBuffer);
  3135.  
  3136.                     *DummyChar = 0;
  3137.  
  3138.                     if(FileRequest = GetFile(LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",TRUE,FALSE,FALSE,NULL))
  3139.                     {
  3140.                         if(WriteIFFData(DummyBuffer,&Config,sizeof(struct Configuration),'PREF'))
  3141.                             strcpy(LastConfig,DummyBuffer);
  3142.                         else
  3143.                             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_ERROR_WRITING_PREFERENCES_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  3144.  
  3145.                         FreeAslRequest(FileRequest);
  3146.                     }
  3147.  
  3148.                     ReleaseWindows();
  3149.  
  3150.                     break;
  3151.  
  3152.             /* Show terminal information window. */
  3153.  
  3154.         case MEN_STATUS_WINDOW:
  3155.  
  3156.                     if(InfoWindow)
  3157.                         CloseInfoWindow();
  3158.                     else
  3159.                         OpenInfoWindow();
  3160.  
  3161.                     break;
  3162.  
  3163.         case MEN_REVIEW_WINDOW:
  3164.  
  3165.                     if(ReviewWindow)
  3166.                         DeleteReview();
  3167.                     else
  3168.                         CreateReview();
  3169.  
  3170.                     break;
  3171.  
  3172.             /* Open the packet window if necessary, else
  3173.              * just activate it.
  3174.              */
  3175.  
  3176.         case MEN_PACKET_WINDOW:
  3177.  
  3178.                     if(!PacketWindow)
  3179.                         CreatePacketWindow();
  3180.                     else
  3181.                     {
  3182.                         ActivateWindow(PacketWindow);
  3183.  
  3184.                         MenuItem -> Flags |= CHECKED;
  3185.                     }
  3186.  
  3187.                     break;
  3188.  
  3189.             /* Toggle the presence of the fast! macro panel. */
  3190.  
  3191.         case MEN_FAST_MACROS_WINDOW:
  3192.  
  3193.                     if(FastWindow)
  3194.                         CloseFastWindow();
  3195.                     else
  3196.                         OpenFastWindow();
  3197.  
  3198.                     break;
  3199.  
  3200.             /* Ignore the rest. */
  3201.  
  3202.         default:        break;
  3203.     }
  3204. }
  3205.  
  3206.     /* HandleMenu(ULONG Code,ULONG Qualifier):
  3207.      *
  3208.      *    Skip along the number of selected menu items and
  3209.      *    handle the associated functions.
  3210.      */
  3211.  
  3212. VOID
  3213. HandleMenu(ULONG Code,ULONG Qualifier)
  3214. {
  3215.     struct MenuItem *MenuItem;
  3216.  
  3217.     DisplayReopened = FALSE;
  3218.  
  3219.         /* Check until the last menuitem has been
  3220.          * processed.
  3221.          */
  3222.  
  3223.     while(Code != MENUNULL)
  3224.     {
  3225.             /* Pick up the associated menu item. */
  3226.  
  3227.         if(MenuItem = ItemAddress(Menu,Code))
  3228.         {
  3229.             HandleCode((ULONG)GTMENUITEM_USERDATA(MenuItem),Qualifier,MenuItem);
  3230.  
  3231.             if(DisplayReopened)
  3232.             {
  3233.                 DisplayReopened = FALSE;
  3234.  
  3235.                 break;
  3236.             }
  3237.  
  3238.             Code = MenuItem -> NextSelect;
  3239.         }
  3240.         else
  3241.             break;
  3242.     }
  3243. }
  3244.