home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / telecomm / terms / term-4.1-source.lha / Extras / Source / term-Source.lha / termMain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-31  |  91.1 KB  |  5,025 lines

  1. /*
  2. **    termMain.c
  3. **
  4. **    Program main routines and event loop
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Argument vectors offsets. */
  13.  
  14. enum    {    ARG_WINDOW,ARG_PUBSCREEN,ARG_STARTUP,ARG_PORTNAME,ARG_SETTINGS,ARG_UNIT,ARG_DEVICE,
  15.         ARG_NEW,ARG_SYNC,ARG_QUIET,ARG_BEHIND,ARG_DEBUG,
  16.  
  17.         ARG_COUNT
  18.     };
  19.  
  20.     /* Argument template. */
  21.  
  22. #define ARGTEMPLATE    "WINDOW/K,PUBSCREEN/K,STARTUP/K,PORTNAME/K,SETTINGS/K,UNIT/K/N,DEVICE/K,NEW/S,SYNC/S,QUIET/S,BEHIND/S,DEBUG/S"
  23.  
  24.     /* Local config path variable. */
  25.  
  26. STATIC STRPTR        ConfigPath;
  27. STATIC UBYTE __far    ThePath[MAX_FILENAME_LENGTH];
  28.  
  29.     /* Local dialing list. */
  30.  
  31. STATIC struct List    *LocalDialList;
  32. STATIC LONG         LocalCount = -1;
  33.  
  34.     /* Startup file name. */
  35.  
  36. STATIC UBYTE __far    StartupFile[MAX_FILENAME_LENGTH];
  37.  
  38.     /* Did we hang up the line? */
  39.  
  40. STATIC BOOLEAN        HungUp = FALSE;
  41.  
  42.     /* Segment split routine, has to be local. */
  43.  
  44. STATIC struct Process * __regargs    SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function);
  45. STATIC VOID                CloseLibs(VOID);
  46.  
  47.     /* main():
  48.      *
  49.      *    This is our main entry point, check for the right
  50.      *    Kickstart version and fire off the background task
  51.      *    if approritate.
  52.      */
  53.  
  54. LONG
  55. main()
  56. {
  57.     STRPTR Result;
  58.  
  59.         /* Are we running as a child of Workbench? */
  60.  
  61.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  62.  
  63.     if(!ThisProcess -> pr_CLI)
  64.     {
  65.         WaitPort(&ThisProcess -> pr_MsgPort);
  66.  
  67.         WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
  68.     }
  69.     else
  70.         WBenchMsg = NULL;
  71.  
  72.         /* Now try to open dos.library and utility.library and go on examining
  73.          * our calling parameters.
  74.          */
  75.  
  76.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
  77.     {
  78.         CloseLibs();
  79.  
  80.         return(RETURN_FAIL);
  81.     }
  82.  
  83.     if(!(UtilityBase = OpenLibrary("utility.library",0)))
  84.     {
  85.         CloseLibs();
  86.  
  87.         return(RETURN_FAIL);
  88.     }
  89.  
  90.         /* We were called from Shell. */
  91.  
  92.     if(ThisProcess -> pr_CLI)
  93.     {
  94.         STRPTR *ArgArray;
  95.  
  96.             /* Use the cute ReadArgs parser, allocate the
  97.              * argument vectors...
  98.              */
  99.  
  100.         if(ArgArray = (STRPTR *)AllocVec(sizeof(STRPTR) * (ARG_COUNT),MEMF_ANY|MEMF_CLEAR))
  101.         {
  102.             struct RDArgs *ArgsPtr;
  103.  
  104.             if(ArgsPtr = (struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE))
  105.             {
  106.                 ArgsPtr -> RDA_ExtHelp =    "\nUsage: term [WINDOW <Name>] [PUBSCREEN <Name>] [STARTUP <File name>]\n"
  107.                                 "            [SETTINGS <File or path name>] [UNIT <Number>] [DEVICE <Name>]\n"
  108.                                 "            [NEW] [SYNC] [QUIET] [BEHIND]\n\n"
  109.                                 "     Window = Output window specifier\n"
  110.                                 "  PubScreen = Name of public screen to open window upon\n"
  111.                                 "    Startup = ARexx script file to run on startup\n"
  112.                                 "   Settings = Main configuration file name or path name to search for it\n"
  113.                                 "       Unit = Serial device driver unit number\n"
  114.                                 "     Device = Serial device driver name\n"
  115.                                 "        New = Spawn a new `term' process\n"
  116.                                 "       Sync = Keep links to Shell environment\n"
  117.                                 "      Quiet = Start iconified\n"
  118.                                 "     Behind = Open screen behind all other screens, don't activate the window\n\n";
  119.  
  120.                     /* Parse the args (if any). */
  121.  
  122.                 if(ReadArgs(ARGTEMPLATE,(LONG *)ArgArray,ArgsPtr))
  123.                 {
  124.                         /* Pop a running `term' to the front? */
  125.  
  126.                     if((TermPort = (struct TermPort *)FindPort("term Port")) && !ArgArray[ARG_NEW])
  127.                     {
  128.                         if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  129.                         {
  130.                             if(TermPort -> TopWindow)
  131.                                 BumpWindow(TermPort -> TopWindow);
  132.                         }
  133.  
  134.                         TermPort = NULL;
  135.  
  136.                         FreeArgs(ArgsPtr);
  137.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  138.                         FreeVec(ArgArray);
  139.  
  140.                         CloseLibs();
  141.  
  142.                         return(RETURN_OK);
  143.                     }
  144.  
  145.                     if(ArgArray[ARG_DEBUG])
  146.                         DebugFlag = TRUE;
  147.  
  148.                         /* Are we to use a special settings path? */
  149.  
  150.                     if(ArgArray[ARG_SETTINGS])
  151.                     {
  152.                         ConfigPath = ThePath;
  153.  
  154.                         strcpy(ThePath,ArgArray[ARG_SETTINGS]);
  155.                     }
  156.  
  157.                         /* Are we to use a special ARexx host port name? */
  158.  
  159.                     if(ArgArray[ARG_PORTNAME])
  160.                         strcpy(RexxPortName,ArgArray[ARG_PORTNAME]);
  161.  
  162.                         /* Are we to use a special output window name? */
  163.  
  164.                     if(ArgArray[ARG_WINDOW])
  165.                         strcpy(WindowName,ArgArray[ARG_WINDOW]);
  166.  
  167.                         /* Are we to run an ARexx script on startup? */
  168.  
  169.                     if(ArgArray[ARG_STARTUP])
  170.                         strcpy(StartupFile,ArgArray[ARG_STARTUP]);
  171.  
  172.                         /* Are we to open a window on a public screen? */
  173.  
  174.                     if(ArgArray[ARG_PUBSCREEN])
  175.                         strcpy(SomePubScreenName,ArgArray[ARG_PUBSCREEN]);
  176.  
  177.                         /* Are we to use a special device? */
  178.  
  179.                     if(ArgArray[ARG_DEVICE])
  180.                     {
  181.                         strcpy(NewDevice,ArgArray[ARG_DEVICE]);
  182.  
  183.                         UseNewDevice = TRUE;
  184.                     }
  185.  
  186.                         /* Are we to use a special unit number? */
  187.  
  188.                     if(ArgArray[ARG_UNIT])
  189.                     {
  190.                         NewUnit = *(LONG *)ArgArray[ARG_UNIT];
  191.  
  192.                         UseNewUnit = TRUE;
  193.                     }
  194.  
  195.                         /* Are we to start up iconified? */
  196.  
  197.                     if(ArgArray[ARG_QUIET])
  198.                     {
  199.                         if(!StartupFile[0])
  200.                             DoIconify = TRUE;
  201.                     }
  202.  
  203.                         /* Hide the screen and don't activate the window? */
  204.  
  205.                     if(ArgArray[ARG_BEHIND])
  206.                         KeepQuiet = TRUE;
  207.  
  208.                         /* We are to keep our links to
  209.                          * the Shell.
  210.                          */
  211.  
  212.                     if(ArgArray[ARG_SYNC] || !ThisProcess -> pr_HomeDir)
  213.                     {
  214.                         BYTE OldPri = ThisProcess -> pr_Task . tc_Node . ln_Pri;
  215.  
  216.                             /* Do we have enough stack space available? */
  217.  
  218.                         if(((struct CommandLineInterface *)BADDR(ThisProcess -> pr_CLI)) -> cli_DefaultStack < 4096)
  219.                         {
  220.                             Printf("\33[1mterm:\33[0m %s.\a\n","Sorry, the Shell stack must be at least 16384 bytes large");
  221.  
  222.                             FreeArgs(ArgsPtr);
  223.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  224.                             FreeVec(ArgArray);
  225.  
  226.                             CloseLibs();
  227.  
  228.                             return(RETURN_FAIL);
  229.                         }
  230.  
  231.                             /* Open our resources and
  232.                              * squeak on failure.
  233.                              */
  234.  
  235.                         if(Result = OpenAll(ConfigPath))
  236.                         {
  237.                             if(Result[0])
  238.                                 Printf("\33[1mterm:\33[0m %s!\a\n",Result);
  239.  
  240.                             FreeArgs(ArgsPtr);
  241.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  242.                             FreeVec(ArgArray);
  243.  
  244.                             CloseAll(TRUE);
  245.  
  246.                             return(RETURN_FAIL);
  247.                         }
  248.  
  249.                             /* Go into main input
  250.                              * loop.
  251.                              */
  252.  
  253.                         HandleInput();
  254.  
  255.                             /* Free the argument
  256.                              * data.
  257.                              */
  258.  
  259.                         FreeArgs(ArgsPtr);
  260.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  261.                         FreeVec(ArgArray);
  262.  
  263.                             /* Restore old priority. */
  264.  
  265.                         SetTaskPri(ThisProcess,(LONG)OldPri);
  266.  
  267.                             /* Terminate execution. */
  268.  
  269.                         CloseAll(TRUE);
  270.  
  271.                         return(RETURN_OK);
  272.                     }
  273.  
  274.                     FreeArgs(ArgsPtr);
  275.                 }
  276.                 else
  277.                 {
  278.                     PrintFault(IoErr(),"term");
  279.  
  280.                     FreeDosObject(DOS_RDARGS,ArgsPtr);
  281.                     FreeVec(ArgArray);
  282.  
  283.                     CloseLibs();
  284.  
  285.                     return(RETURN_ERROR);
  286.                 }
  287.  
  288.                 FreeDosObject(DOS_RDARGS,ArgsPtr);
  289.             }
  290.  
  291.             FreeVec(ArgArray);
  292.  
  293.                 /* Create a new process from our code. */
  294.  
  295.             if(!SegmentSplit("term main process",0,16384,HandleInput))
  296.             {
  297.                 Printf("\33[1mterm:\33[0m Failed to create new process!\a\n");
  298.  
  299.                 CloseLibs();
  300.  
  301.                 return(RETURN_FAIL);
  302.             }
  303.         }
  304.         else
  305.         {
  306.             Printf("\33[1mterm:\33[0m Failed to allocate argument vectors!\a\n");
  307.  
  308.             CloseLibs();
  309.  
  310.             return(RETURN_FAIL);
  311.         }
  312.     }
  313.     else
  314.     {
  315.         LONG StackSize;
  316.  
  317.         StackSize = (LONG)SysBase -> ThisTask -> tc_SPUpper - (LONG)SysBase -> ThisTask -> tc_SPLower;
  318.  
  319.         if(StackSize < 16384)
  320.         {
  321.             if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
  322.                 MyEasyRequest(NULL,"`term' has a problem:\nThe current stack size of %ld bytes is too low,\nplease edit the tool icon to use at least\n16384 bytes and restart the program.","Continue",StackSize);
  323.  
  324.             CloseLibs();
  325.  
  326.             return(RETURN_FAIL);
  327.         }
  328.         else
  329.         {
  330.             WBenchLock = CurrentDir(WBenchMsg -> sm_ArgList -> wa_Lock);
  331.  
  332.                 /* Open icon.library, we want to take a
  333.                  * look at the icon.
  334.                  */
  335.  
  336.             if(IconBase = OpenLibrary("icon.library",0))
  337.             {
  338.                 struct DiskObject *Icon;
  339.  
  340.                     /* Try to read the icon file. */
  341.  
  342.                 if(Icon = GetProgramIcon())
  343.                 {
  344.                     STRPTR Type;
  345.  
  346.                     if(FindToolType(Icon -> do_ToolTypes,"DEBUG"))
  347.                         DebugFlag = TRUE;
  348.  
  349.                         /* Look for a `Settings' tooltype. */
  350.  
  351.                     if(ConfigPath = FindToolType(Icon -> do_ToolTypes,"SETTINGS"))
  352.                     {
  353.                             /* Remember the path and continue. */
  354.  
  355.                         strcpy(ThePath,ConfigPath);
  356.  
  357.                         ConfigPath = ThePath;
  358.                     }
  359.  
  360.                         /* Look for a `Portname' tooltype. */
  361.  
  362.                     if(Type = FindToolType(Icon -> do_ToolTypes,"PORTNAME"))
  363.                         strcpy(RexxPortName,Type);
  364.                     else
  365.                         RexxPortName[0] = 0;
  366.  
  367.                         /* Look for a `Window' tooltype. */
  368.  
  369.                     if(Type = FindToolType(Icon -> do_ToolTypes,"WINDOW"))
  370.                         strcpy(WindowName,Type);
  371.                     else
  372.                         WindowName[0] = 0;
  373.  
  374.                         /* Look for a `Pubscreen' tooltype. */
  375.  
  376.                     if(Type = FindToolType(Icon -> do_ToolTypes,"PUBSCREEN"))
  377.                         strcpy(SomePubScreenName,Type);
  378.                     else
  379.                         SomePubScreenName[0] = 0;
  380.  
  381.                         /* Look for a `Startup' tooltype. */
  382.  
  383.                     if(Type = FindToolType(Icon -> do_ToolTypes,"STARTUP"))
  384.                         strcpy(StartupFile,Type);
  385.                     else
  386.                         StartupFile[0] = 0;
  387.  
  388.                         /* Look for a `Device' tooltype. */
  389.  
  390.                     if(Type = FindToolType(Icon -> do_ToolTypes,"DEVICE"))
  391.                     {
  392.                         if(Type[0])
  393.                         {
  394.                             strcpy(NewDevice,Type);
  395.  
  396.                             UseNewDevice = TRUE;
  397.                         }
  398.                     }
  399.  
  400.                         /* Look for a `Unit' tooltype. */
  401.  
  402.                     if(Type = FindToolType(Icon -> do_ToolTypes,"UNIT"))
  403.                     {
  404.                         if(Type[0])
  405.                         {
  406.                             NewUnit = Atol(Type);
  407.  
  408.                             UseNewUnit = TRUE;
  409.                         }
  410.                     }
  411.  
  412.                         /* Look for a `Quiet' tooltype. */
  413.  
  414.                     if(FindToolType(Icon -> do_ToolTypes,"QUIET"))
  415.                     {
  416.                         if(!StartupFile[0])
  417.                             DoIconify = TRUE;
  418.                     }
  419.  
  420.                         /* Look for a `Behind' tooltype. */
  421.  
  422.                     if(FindToolType(Icon -> do_ToolTypes,"BEHIND"))
  423.                         KeepQuiet = TRUE;
  424.  
  425.                         /* Free the icon. */
  426.  
  427.                     FreeDiskObject(Icon);
  428.                 }
  429.  
  430.                 CloseLibrary(IconBase);
  431.  
  432.                 IconBase = NULL;
  433.             }
  434.  
  435.                 /* Initialize this, so OpenAll will work with
  436.                  * correct data.
  437.                  */
  438.  
  439.             TermPort = (struct TermPort *)FindPort("term Port");
  440.  
  441.                 /* We were called from Workbench. */
  442.  
  443.             if(Result = OpenAll(ConfigPath))
  444.             {
  445.                 if(IntuitionBase && Result[0])
  446.                     MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  447.  
  448.                 CloseAll(TRUE);
  449.             }
  450.             else
  451.                 HandleInput();
  452.         }
  453.     }
  454.  
  455.     return(RETURN_OK);
  456. }
  457.  
  458.     /* CloseLibs():
  459.      *
  460.      *    Plain and simple: close two libraries and clean up.
  461.      */
  462.  
  463. STATIC VOID
  464. CloseLibs(VOID)
  465. {
  466.     if(UtilityBase)
  467.     {
  468.         CloseLibrary(UtilityBase);
  469.  
  470.         UtilityBase = NULL;
  471.     }
  472.  
  473.     if(WBenchMsg)
  474.         CurrentDir(WBenchLock);
  475.  
  476.     if(DOSBase)
  477.     {
  478.         CloseLibrary(DOSBase);
  479.  
  480.         DOSBase = NULL;
  481.     }
  482.  
  483. #ifdef BETA
  484.     StopBetaTask();
  485. #endif    /* BETA */
  486.  
  487.     if(WBenchMsg)
  488.     {
  489.         Forbid();
  490.  
  491.         ReplyMsg((struct Message *)WBenchMsg);
  492.     }
  493. }
  494.  
  495.     /* ProcessCleanup(register __d1 BPTR SegList):
  496.      *
  497.      *    Frees all resource the main process has allocated when
  498.      *    it exits.
  499.      */
  500.  
  501. STATIC VOID __saveds __asm
  502. ProcessCleanup(register __d1 BPTR SegList)
  503. {
  504.     CloseAll(FALSE);
  505.  
  506.     Forbid();
  507.  
  508.     UnLoadSeg(SegList);
  509.  
  510.     CloseLibrary(DOSBase);
  511.  
  512.     DOSBase = NULL;
  513. }
  514.  
  515.     /* SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function):
  516.      *
  517.      *    Create a new process from the current one.
  518.      */
  519.  
  520. STATIC struct Process * __regargs
  521. SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function)
  522. {
  523.     struct Process            *Child;
  524.     struct CommandLineInterface    *CLI;
  525.  
  526.     CLI = (struct CommandLineInterface *)BADDR(((struct Process *)SysBase -> ThisTask) -> pr_CLI);
  527.  
  528.     Forbid();
  529.  
  530.     Child = CreateNewProcTags(
  531.         NP_CommandName,    "term",
  532.         NP_Name,    Name,
  533.         NP_Priority,    Pri,
  534.         NP_StackSize,    StackSize,
  535.         NP_Entry,    Function,
  536.         NP_Cli,        TRUE,
  537.         NP_ExitCode,    ProcessCleanup,
  538.         NP_ExitData,    CLI -> cli_Module,
  539.     TAG_DONE);
  540.  
  541.     if(Child)
  542.         CLI -> cli_Module = NULL;
  543.  
  544.     Permit();
  545.  
  546.     return(Child);
  547. }
  548.  
  549.     /* HandleInput():
  550.      *
  551.      *    This is our main input loop (check window & serial).
  552.      */
  553.  
  554. VOID __saveds
  555. HandleInput()
  556. {
  557.     STRPTR    Error;
  558.     BOOLEAN    AlmostFinished = FALSE;
  559.  
  560.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  561.  
  562.         /* Open the resources we need. */
  563.  
  564.     if(!IntuitionBase)
  565.     {
  566.         STRPTR Result;
  567.  
  568.         if(Result = OpenAll(ConfigPath))
  569.         {
  570.             if(IntuitionBase && Result[0])
  571.                 MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  572.  
  573.             if(WBenchMsg)
  574.                 CloseAll(TRUE);
  575.  
  576.             return;
  577.         }
  578.     }
  579.  
  580.         /* Start the online timer if a carrier is present? */
  581.  
  582.     if(Config -> SerialConfig -> CheckCarrier)
  583.     {
  584.             /* Is the carrier signal present? */
  585.  
  586.         if(!(GetSerialStatus() & CIAF_COMCD))
  587.         {
  588.                 /* Go into online state. */
  589.  
  590.             ObtainSemaphore(&OnlineSemaphore);
  591.  
  592.             WasOnline        = FALSE;
  593.             Online            = TRUE;
  594.  
  595.             ReleaseSemaphore(&OnlineSemaphore);
  596.  
  597.             BaudCount        = 0;
  598.             BaudBuffer[0]        = 0;
  599.             BaudPending        = FALSE;
  600.  
  601.             CurrentPay        = 0;
  602.  
  603.             ObtainSemaphore(&PatternSemaphore);
  604.  
  605.             ChosenEntry        = NULL;
  606.             ChosenPattern        = NULL;
  607.  
  608.             ReleaseSemaphore(&PatternSemaphore);
  609.  
  610.             Password[0]        = 0;
  611.             UserName[0]        = 0;
  612.  
  613.             SendStartup        = FALSE;
  614.  
  615.             LimitCount        = -1;
  616.  
  617.             CurrentBBSName[0]    = 0;
  618.             CurrentBBSComment[0]    = 0;
  619.             CurrentBBSNumber[0]    = 0;
  620.  
  621.             SetDialMenu(FALSE);
  622.         }
  623.     }
  624.  
  625.         /* Start up iconified? */
  626.  
  627.     if(DoIconify)
  628.     {
  629.         HandleIconify();
  630.  
  631.         DoIconify = FALSE;
  632.  
  633.         if(MainTerminated)
  634.             goto Stop;
  635.     }
  636.  
  637. #ifndef BETA
  638.     if(!KeepQuiet)
  639.         BumpWindow(Window);
  640. #endif    /* BETA */
  641.  
  642.         /* Set up the public screen data. */
  643.  
  644.     PubScreenStuff();
  645.  
  646.         /* Change program priority. */
  647.  
  648.     SetTaskPri(ThisProcess,(LONG)Config -> MiscConfig -> Priority);
  649.  
  650.     BlockWindows();
  651.  
  652.         /* Load the phone book. */
  653.  
  654.     LoadPhonebook(LastPhone);
  655.  
  656.         /* Build new menu strip. */
  657.  
  658.     if(Error = BuildMenu())
  659.     {
  660.         if(IntuitionBase)
  661.             MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  662.  
  663.         CloseAll(TRUE);
  664.  
  665.         return;
  666.     }
  667.  
  668. #ifdef BETA
  669.     StopBetaTask();
  670.  
  671.     if(!KeepQuiet)
  672.         BumpWindow(Window);
  673. #endif    /* BETA */
  674.  
  675.         /* Show our business card. */
  676.  
  677.     if(!StartupFile[0] && !Config -> CommandConfig -> StartupMacro[0] && !KeepQuiet)
  678.     {
  679.         if(ShowAbout(TRUE))
  680.             while(HandleRexx());
  681.     }
  682.  
  683.     ReleaseWindows();
  684.  
  685.         /* Don't do anything silly. */
  686.  
  687.     KeepQuiet = FALSE;
  688.  
  689.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_STARTED_TXT),TermName,TermDate);
  690.  
  691.         /* Initialize the modem. */
  692.  
  693.     SerialCommand(Config -> ModemConfig -> ModemInit);
  694.  
  695.         /* Execute the startup macro (if any). */
  696.  
  697.     if(Config -> CommandConfig -> StartupMacro[0])
  698.         SerialCommand(Config -> CommandConfig -> StartupMacro);
  699.  
  700.         /* Go into input loop... */
  701.  
  702. Loop:    while(!MainTerminated)
  703.     {
  704.         if(Recording)
  705.         {
  706.             if(RecordingLine)
  707.                 Status = STATUS_RECORDING_LINE;
  708.             else
  709.                 Status = STATUS_RECORDING;
  710.         }
  711.  
  712.             /* Handle the signal responses. */
  713.  
  714.         HandleResponse();
  715.  
  716.         if(RebuildMenu)
  717.         {
  718.             if(Error = BuildMenu())
  719.             {
  720.                 if(IntuitionBase)
  721.                     MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  722.  
  723.                 MainTerminated = TRUE;
  724.  
  725.                 break;
  726.             }
  727.  
  728.             RebuildMenu = FALSE;
  729.         }
  730.  
  731.             /* Are we to run an ARexx script file? */
  732.  
  733.         if(StartupFile[0])
  734.         {
  735.             BlockWindows();
  736.  
  737.             SendARexxCommand(StartupFile);
  738.  
  739.             ReleaseWindows();
  740.  
  741.             StartupFile[0] = 0;
  742.         }
  743.  
  744.             /* Are we to leave the main loop? */
  745.  
  746.         if(MainTerminated)
  747.             break;
  748.  
  749.             /* Make the user notice not too obvious events. */
  750.  
  751.         if(FlowInfo . Changed)
  752.             HandleFlowChange();
  753.  
  754.             /* Are we no longer online? */
  755.  
  756.         if(!Online)
  757.         {
  758.             if(WasOnline)
  759.             {
  760.                 HandleOnlineCleanup(HungUp);
  761.  
  762.                 WasOnline = FALSE;
  763.  
  764.                 HungUp = FALSE;
  765.             }
  766.         }
  767.  
  768.             /* Now for public screen mode changes. */
  769.  
  770.         if(FixPubScreenMode)
  771.             PubScreenStuff();
  772.  
  773.             /* Now for window size changes. */
  774.  
  775.         if(FixScreenSize)
  776.             ScreenSizeStuff();
  777.  
  778.             /* Somebody told us to re-open the display
  779.              * (changed the terminal emulation/colour
  780.              * mode, etc.).
  781.              */
  782.  
  783.         if(ResetDisplay)
  784.         {
  785.             if(!DisplayReset())
  786.                 break;
  787.         }
  788.  
  789.             /* Let's see if we still have to display the
  790.              * online cost.
  791.              */
  792.  
  793.         if(CurrentPay && !Online)
  794.         {
  795.                 /* Reset the text rendering styles, font, etc. in
  796.                  * order to keep the following text from getting
  797.                  * illegible.
  798.                  */
  799.  
  800.             SoftReset();
  801.  
  802.                 /* Display how much we expect
  803.                  * the user will have to pay for
  804.                  * this call.
  805.                  */
  806.  
  807.             ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  808.  
  809.             CurrentPay = 0;
  810.         }
  811.  
  812.             /* Iconify the program? */
  813.  
  814.         if(DoIconify)
  815.         {
  816.             HandleIconify();
  817.  
  818.             if(MainTerminated)
  819.                 break;
  820.         }
  821.  
  822.             /* Reset the serial driver? */
  823.  
  824.         if(ResetSerial)
  825.         {
  826.             HandleSerialReset();
  827.  
  828.             if(MainTerminated)
  829.                 break;
  830.         }
  831.  
  832.             /* We are to release the serial.device (or
  833.              * whatever we are using) for some reason.
  834.              */
  835.  
  836.         if(ReleaseSerial)
  837.         {
  838.             HandleSerialRelease();
  839.  
  840.             if(MainTerminated)
  841.                 break;
  842.         }
  843.  
  844.             /* Invoke the dialing function? */
  845.  
  846.         if(DoDial != DIAL_IGNORE)
  847.         {
  848.             if(Online)
  849.             {
  850.                 FreeDialList(FALSE);
  851.  
  852.                 DoDial = DIAL_IGNORE;
  853.  
  854.                 Forbid();
  855.  
  856.                 if(DialMsg)
  857.                 {
  858.                     DialMsg -> rm_Result1 = RC_WARN;
  859.                     DialMsg -> rm_Result2 = 0;
  860.  
  861.                     ReplyMsg(DialMsg);
  862.  
  863.                     DialMsg = NULL;
  864.                 }
  865.  
  866.                 Permit();
  867.             }
  868.             else
  869.             {
  870.                 if(DoDial == DIAL_LIST)
  871.                 {
  872.                     BYTE OldStatus = Status;
  873.  
  874.                     DoDial = DIAL_IGNORE;
  875.  
  876.                     BlockWindows();
  877.  
  878.                     DialPanel();
  879.  
  880.                     FreeDialList(FALSE);
  881.  
  882.                     Status = OldStatus;
  883.  
  884.                     SetRedialMenu();
  885.  
  886.                     ReleaseWindows();
  887.                 }
  888.                 else
  889.                 {
  890.                     DoDial = DIAL_IGNORE;
  891.  
  892.                     HandleMenuCode(MEN_REDIAL,NULL);
  893.                 }
  894.             }
  895.         }
  896.  
  897.             /* Can we quit now? */
  898.  
  899.         if(AlmostFinished && !CantQuit)
  900.             break;
  901.     }
  902.  
  903.         /* Don't exit until all background processes
  904.          * have terminated.
  905.          */
  906.  
  907.     if(MainTerminated && CantQuit)
  908.     {
  909.         MainTerminated = FALSE;
  910.         AlmostFinished = TRUE;
  911.  
  912.         goto Loop;
  913.     }
  914.  
  915.         /* User wants to quit term, so let's try to close
  916.          * our magnificient screen and exit.
  917.          */
  918.  
  919. Stop:    if(Screen)
  920.     {
  921.         struct List        *PubScreenList;
  922.         struct PubScreenNode    *ScreenNode;
  923.  
  924.             /* Lock the list of public screens. */
  925.  
  926.         PubScreenList = LockPubScreenList();
  927.  
  928.             /* Scan the list and try to find our
  929.              * private node.
  930.              */
  931.  
  932.         for(ScreenNode = (struct PubScreenNode *)PubScreenList -> lh_Head ; ScreenNode -> psn_Node . ln_Succ ; ScreenNode = (struct PubScreenNode *)ScreenNode -> psn_Node . ln_Succ)
  933.         {
  934.             if(ScreenNode -> psn_Screen == Screen)
  935.                 break;
  936.         }
  937.  
  938.         if(ScreenNode)
  939.         {
  940.                 /* Okay, we know who and where we are,
  941.                  * check the number of visitor windows
  942.                  * currently open on our screen.
  943.                  */
  944.  
  945.             if(ScreenNode -> psn_VisitorCount)
  946.             {
  947.                     /* No chance, don't close
  948.                      * the screen now.
  949.                      */
  950.  
  951.                 UnlockPubScreenList();
  952.  
  953.                 BlockWindows();
  954.  
  955.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  956.  
  957.                 ReleaseWindows();
  958.  
  959.                 AlmostFinished = MainTerminated = FALSE;
  960.  
  961.                 goto Loop;
  962.             }
  963.         }
  964.  
  965.         UnlockPubScreenList();
  966.     }
  967.  
  968.         /* Send the modem exit command, shut down the
  969.          * serial.device and close all resources.
  970.          */
  971.  
  972.     SerialCommand(Config -> ModemConfig -> ModemExit);
  973.  
  974.     ClearSerial();
  975.  
  976.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_TERMINATED_TXT));
  977.  
  978.     Say(LocaleString(MSG_TERMMAIN_BYE_BYE_TXT));
  979.  
  980.     if(Phonebook && PhoneSize)
  981.         DeletePhonebook(Phonebook,PhoneSize,TRUE);
  982.  
  983.     if(!ThisProcess -> pr_CLI)
  984.         CloseAll(TRUE);
  985. }
  986.  
  987.     /* SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell):
  988.      *
  989.      *    Transmit text the user typed or pasted via the
  990.      *    clipboard.
  991.      */
  992.  
  993. STATIC VOID __regargs
  994. SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell)
  995. {
  996.     UBYTE Mask,c;
  997.  
  998.     if(Config -> SerialConfig -> StripBit8)
  999.         Mask = 0x7F;
  1000.     else
  1001.         Mask = 0xFF;
  1002.  
  1003.     while(Len--)
  1004.     {
  1005.         switch(CharType[c = (*Buffer++) & Mask])
  1006.         {
  1007.             case CHAR_ENTER:
  1008.  
  1009.                 if(Status == STATUS_HOLDING)
  1010.                 {
  1011.                     if(Bell)
  1012.                         BellSignal();
  1013.                 }
  1014.                 else
  1015.                 {
  1016.                     switch(Config -> TerminalConfig -> SendLF)
  1017.                     {
  1018.                         case EOL_LF:
  1019.  
  1020.                             SerWrite("\n",1);
  1021.                             break;
  1022.  
  1023.                         case EOL_CR:
  1024.  
  1025.                             SerWrite("\r",1);
  1026.                             break;
  1027.  
  1028.                         case EOL_LFCR:
  1029.  
  1030.                             SerWrite("\n\r",2);
  1031.                             break;
  1032.  
  1033.                         case EOL_CRLF:
  1034.  
  1035.                             SerWrite("\r\n",2);
  1036.                             break;
  1037.                     }
  1038.                 }
  1039.  
  1040.                 break;
  1041.  
  1042.             case CHAR_RETURN:
  1043.  
  1044.                 if(Status == STATUS_HOLDING)
  1045.                 {
  1046.                     if(Bell)
  1047.                         BellSignal();
  1048.                 }
  1049.                 else
  1050.                 {
  1051.                     switch(Config -> TerminalConfig -> SendCR)
  1052.                     {
  1053.                         case EOL_LF:
  1054.  
  1055.                             SerWrite("\n",1);
  1056.                             break;
  1057.  
  1058.                         case EOL_CR:
  1059.  
  1060.                             SerWrite("\r",1);
  1061.                             break;
  1062.  
  1063.                         case EOL_LFCR:
  1064.  
  1065.                             SerWrite("\n\r",2);
  1066.                             break;
  1067.  
  1068.                         case EOL_CRLF:
  1069.  
  1070.                             SerWrite("\r\n",2);
  1071.                             break;
  1072.                     }
  1073.                 }
  1074.  
  1075.                 break;
  1076.  
  1077.                 /* Stop in/output. */
  1078.  
  1079.             case CHAR_XON:
  1080.  
  1081.                 if(Status == STATUS_HOLDING)
  1082.                 {
  1083.                     if(Bell)
  1084.                         BellSignal();
  1085.                 }
  1086.                 else
  1087.                 {
  1088.                     if(Config -> SerialConfig -> xONxOFF)
  1089.                         Status = STATUS_HOLDING;
  1090.  
  1091.                     if(Config -> SerialConfig -> PassThrough)
  1092.                         SerWrite(&c,1);
  1093.                 }
  1094.  
  1095.                 break;
  1096.  
  1097.                 /* Restart in/output. */
  1098.  
  1099.             case CHAR_XOFF:
  1100.  
  1101.                 if(Status == STATUS_HOLDING)
  1102.                     Status = STATUS_READY;
  1103.  
  1104.                 if(Config -> SerialConfig -> PassThrough)
  1105.                     SerWrite(&c,1);
  1106.  
  1107.                 break;
  1108.  
  1109.                 /* Any other character. */
  1110.  
  1111.             case CHAR_VANILLA:
  1112.  
  1113.                 if(Status == STATUS_HOLDING)
  1114.                 {
  1115.                     if(Bell)
  1116.                         BellSignal();
  1117.                 }
  1118.                 else
  1119.                 {
  1120.                     if(Config -> TerminalConfig -> FontMode == FONT_IBM)
  1121.                     {
  1122.                             /* Convert special
  1123.                              * Amiga characters into
  1124.                              * alien IBM dialect.
  1125.                              */
  1126.  
  1127.                         if(IBMConversion[c])
  1128.                             SerWrite(&IBMConversion[c],1);
  1129.                         else
  1130.                             SerWrite(&c,1);
  1131.                     }
  1132.                     else
  1133.                         SerWrite(&c,1);
  1134.                 }
  1135.  
  1136.                 break;
  1137.         }
  1138.     }
  1139. }
  1140.  
  1141.     /* HandleWindow():
  1142.      *
  1143.      *    This funny part checks the window(s) for incoming
  1144.      *    user input. Menus are handled elsewhere.
  1145.      */
  1146.  
  1147. BYTE
  1148. HandleWindow()
  1149. {
  1150.     STATIC ULONG         LastSeconds,LastMicros;
  1151.  
  1152.     struct IntuiMessage    *Message;
  1153.     ULONG             IClass,Code,Qualifier,Seconds,Micros;
  1154.     LONG             MouseX,MouseY,Len,GadgetID;
  1155.     struct Gadget        *Gadget;
  1156.     UBYTE             Char,InputBuffer[257];
  1157.     struct Window        *IDCMPWindow;
  1158.     BOOLEAN             Result = FALSE,ClickAndActivate = FALSE;
  1159.  
  1160.         /* Are we reading input from the clipboard? */
  1161.  
  1162.     if(ClipInput)
  1163.     {
  1164.         WORD Len = GetClip(InputBuffer,256,TRUE);
  1165.  
  1166.         if(Len < 0)
  1167.         {
  1168.             CloseClip();
  1169.  
  1170.             ClipInput = FALSE;
  1171.  
  1172.             if(ClipXerox)
  1173.             {
  1174.                 if(Config -> ClipConfig -> InsertSuffix[0])
  1175.                     SerialCommand(Config -> ClipConfig -> InsertSuffix);
  1176.  
  1177.                 ClipXerox = FALSE;
  1178.             }
  1179.  
  1180.             ClipPrefix = FALSE;
  1181.         }
  1182.         else
  1183.         {
  1184.             if(!ClipPrefix && ClipXerox)
  1185.             {
  1186.                 if(Config -> ClipConfig -> InsertPrefix[0])
  1187.                     SerialCommand(Config -> ClipConfig -> InsertPrefix);
  1188.  
  1189.                 ClipPrefix = TRUE;
  1190.             }
  1191.  
  1192.             if(Len > 0)
  1193.                 SendInputTextBuffer(InputBuffer,Len,FALSE);
  1194.  
  1195.             Result = TRUE;
  1196.         }
  1197.     }
  1198.  
  1199.         /* Any news in the mail? */
  1200.  
  1201.     if(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  1202.     {
  1203.             /* A click into the window should activate it, but
  1204.              * we don't want to have the character snapping activated
  1205.              * under these conditions. In this case we rely upon
  1206.              * Intuition sending the IDCMP_ACTIVEWINDOW and
  1207.              * IDCMP_MOUSEBUTTONS event marked with the same
  1208.              * creation time stamp. Even if the Intuition
  1209.              * implementation should change no harm should
  1210.              * be done.
  1211.              */
  1212.  
  1213.         Seconds    = Message -> Seconds;
  1214.         Micros    = Message -> Micros;
  1215.  
  1216.         if(Seconds == LastSeconds && Micros == LastMicros && Message -> IDCMPWindow == Window)
  1217.         {
  1218.             if(Message -> Class == IDCMP_ACTIVEWINDOW || Message -> Class == IDCMP_MOUSEBUTTONS)
  1219.                 ClickAndActivate = TRUE;
  1220.         }
  1221.  
  1222.         LastSeconds    = Seconds;
  1223.         LastMicros    = Micros;
  1224.  
  1225.             /* Pick up the pieces. */
  1226.  
  1227.         IClass        = Message -> Class;
  1228.         Code        = Message -> Code;
  1229.         Qualifier    = Message -> Qualifier;
  1230.         Gadget        = (struct Gadget *)Message -> IAddress;
  1231.  
  1232.         MouseX        = Message -> MouseX;
  1233.         MouseY        = Message -> MouseY;
  1234.  
  1235.         IDCMPWindow    = Message -> IDCMPWindow;
  1236.  
  1237.         if(IClass == IDCMP_IDCMPUPDATE)
  1238.             GadgetID = GetTagData(GA_ID,0,(struct TagItem *)Gadget);
  1239.  
  1240.         if(IClass == IDCMP_RAWKEY)
  1241.         {
  1242.                 /* Perform key conversion. */
  1243.  
  1244.             if(XEmulatorBase)
  1245.             {
  1246.                 if(Len = XEmulatorUserMon(XEM_IO,InputBuffer,256,Message))
  1247.                     Char = InputBuffer[0];
  1248.             }
  1249.             else
  1250.                 Char = KeyConvert(Message,InputBuffer,&Len);
  1251.         }
  1252.  
  1253.         ReplyMsg(Message);
  1254.     }
  1255.     else
  1256.         IClass = NULL;
  1257.  
  1258.         /* Did we get any information? */
  1259.  
  1260.     if(IClass)
  1261.     {
  1262.             /* The following messages probably
  1263.              * originated from the fast! macro
  1264.              * panel.
  1265.              */
  1266.  
  1267.         if(IDCMPWindow == FastWindow)
  1268.         {
  1269.             switch(IClass)
  1270.             {
  1271.                     /* Close the window. */
  1272.  
  1273.                 case IDCMP_CLOSEWINDOW:
  1274.  
  1275.                     CloseFastWindow();
  1276.  
  1277.                     return(TRUE);
  1278.  
  1279.                     /* Window size has changed for some reason. */
  1280.  
  1281.                 case IDCMP_NEWSIZE:
  1282.  
  1283.                     RefreshFastWindow(FALSE);
  1284.  
  1285.                     return(TRUE);
  1286.  
  1287.                     /* Some gadget was invoked. */
  1288.  
  1289.                 case IDCMP_GADGETUP:
  1290.                 case IDCMP_GADGETDOWN:
  1291.  
  1292.                     GadgetID = Gadget -> GadgetID;
  1293.  
  1294.                 case IDCMP_MOUSEMOVE:
  1295.                 case IDCMP_IDCMPUPDATE:
  1296.  
  1297.                     HandleFastWindowGadget(IClass,Code,GadgetID);
  1298.  
  1299.                     return(TRUE);
  1300.             }
  1301.         }
  1302.  
  1303.             /* Status window activated? */
  1304.  
  1305.         if(IDCMPWindow == StatusWindow)
  1306.         {
  1307.             if(IClass == IDCMP_ACTIVEWINDOW && !Config -> ScreenConfig -> SplitStatus)
  1308.                 NormalCursor();
  1309.  
  1310.             if(IClass == IDCMP_CLOSEWINDOW)
  1311.             {
  1312.                 Forbid();
  1313.  
  1314.                 ClrSignal(SIG_HANDSHAKE);
  1315.  
  1316.                 Signal(StatusProcess,SIG_CLOSEWINDOW);
  1317.  
  1318.                 Wait(SIG_HANDSHAKE);
  1319.  
  1320.                 Permit();
  1321.  
  1322.                 ClearMenuStrip(StatusWindow);
  1323.                 CloseWindowSafely(StatusWindow);
  1324.  
  1325.                 StatusWindow = NULL;
  1326.             }
  1327.         }
  1328.  
  1329.             /* Main window message? */
  1330.  
  1331.         if(IDCMPWindow == Window)
  1332.         {
  1333.             switch(IClass)
  1334.             {
  1335.                 case IDCMP_INACTIVEWINDOW:
  1336.  
  1337.                     HoldClick = FALSE;
  1338.  
  1339.                     GhostCursor();
  1340.  
  1341.                     break;
  1342.  
  1343.                 case IDCMP_ACTIVEWINDOW:
  1344.  
  1345.                     NormalCursor();
  1346.  
  1347.                     break;
  1348.  
  1349.                 case IDCMP_NEWSIZE:
  1350.  
  1351.                         /* Is a window clipping region installed? */
  1352.  
  1353.                     if(ClipRegion)
  1354.                     {
  1355.                         struct Rectangle RegionRectangle;
  1356.  
  1357.                             /* Install old region. */
  1358.  
  1359.                         InstallClipRegion(Window -> WLayer,OldRegion);
  1360.  
  1361.                             /* Fill in the clipping rectangle. */
  1362.  
  1363.                         RegionRectangle . MinX = Window -> BorderLeft;
  1364.                         RegionRectangle . MinY = Window -> BorderTop;
  1365.                         RegionRectangle . MaxX = Window -> Width - (Window -> BorderRight + 1);
  1366.                         RegionRectangle . MaxY = Window -> Height - (Window -> BorderBottom + 1);
  1367.  
  1368.                             /* Clear previous clipping region. */
  1369.  
  1370.                         ClearRegion(ClipRegion);
  1371.  
  1372.                             /* Set new clipping region. */
  1373.  
  1374.                         OrRectRegion(ClipRegion,&RegionRectangle);
  1375.  
  1376.                             /* Install new clipping region. */
  1377.  
  1378.                         OldRegion = InstallClipRegion(Window -> WLayer,ClipRegion);
  1379.                     }
  1380.  
  1381.                     HandleMenuCode(MEN_RESET_TERMINAL,Qualifier);
  1382.                     break;
  1383.  
  1384.                 case IDCMP_CLOSEWINDOW:
  1385.  
  1386.                     HandleMenuCode(MEN_QUIT,Qualifier);
  1387.                     break;
  1388.  
  1389.                 case IDCMP_MOUSEMOVE:
  1390.  
  1391.                     if(HoldClick)
  1392.                     {
  1393.                         if(!Marking)
  1394.                             SetMarker(ClickX,ClickY);
  1395.                         else
  1396.                         {
  1397.                             MouseX -= WindowLeft;
  1398.  
  1399.                             if(MouseX < 0)
  1400.                                 MouseX = 0;
  1401.  
  1402.                             if(MouseX > WindowWidth - 1)
  1403.                                 MouseX = WindowWidth - 1;
  1404.  
  1405.                             MouseY -= WindowTop;
  1406.  
  1407.                             if(MouseY < 0)
  1408.                                 MouseY = 0;
  1409.  
  1410.                             if(MouseY > WindowHeight - 1)
  1411.                                 MouseY = WindowHeight - 1;
  1412.  
  1413.                             MoveMarker(MouseX,MouseY);
  1414.                         }
  1415.                     }
  1416.  
  1417.                     break;
  1418.  
  1419.                 case IDCMP_MOUSEBUTTONS:
  1420.  
  1421.                     if((!ClickAndActivate || Code != SELECTDOWN) && (!XEmulatorBase || Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL))
  1422.                     {
  1423.                         if(Code == SELECTUP)
  1424.                             HoldClick = FALSE;
  1425.  
  1426.                         if(Code == SELECTDOWN)
  1427.                         {
  1428.                             MouseX -= WindowLeft;
  1429.  
  1430.                             if(MouseX < 0)
  1431.                                 MouseX = 0;
  1432.  
  1433.                             if(MouseX > WindowWidth - 1)
  1434.                                 MouseX = WindowWidth - 1;
  1435.  
  1436.                             MouseY -= WindowTop;
  1437.  
  1438.                             if(MouseY < 0)
  1439.                                 MouseY = 0;
  1440.  
  1441.                             if(MouseY > WindowHeight - 1)
  1442.                                 MouseY = WindowHeight - 1;
  1443.  
  1444.                             HoldClick = TRUE;
  1445.  
  1446.                             if(Qualifier & IEQUALIFIER_CONTROL)
  1447.                             {
  1448.                                 WORD FirstX,FirstY;
  1449.  
  1450.                                 FirstX = MouseX / TextFontWidth;
  1451.                                 FirstY = MouseY / TextFontHeight;
  1452.  
  1453.                                 if(FirstX <= LastColumn && FirstY <= LastLine)
  1454.                                 {
  1455.                                     UBYTE Char;
  1456.  
  1457.                                     ObtainSemaphore(RasterSemaphore);
  1458.  
  1459.                                     Char = Raster[FirstY * RasterWidth + FirstX];
  1460.  
  1461.                                     ReleaseSemaphore(RasterSemaphore);
  1462.  
  1463.                                     if(Char)
  1464.                                     {
  1465.                                         SerWrite(&Char,1);
  1466.  
  1467.                                         if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1468.                                         {
  1469.                                             switch(Config -> TerminalConfig -> SendCR)
  1470.                                             {
  1471.                                                 case EOL_LF:
  1472.  
  1473.                                                     SerWrite("\n",1);
  1474.                                                     break;
  1475.  
  1476.                                                 case EOL_CR:
  1477.  
  1478.                                                     SerWrite("\r",1);
  1479.                                                     break;
  1480.  
  1481.                                                 case EOL_LFCR:
  1482.  
  1483.                                                     SerWrite("\n\r",2);
  1484.                                                     break;
  1485.  
  1486.                                                 case EOL_CRLF:
  1487.  
  1488.                                                     SerWrite("\r\n",2);
  1489.                                                     break;
  1490.                                             }
  1491.                                         }
  1492.                                     }
  1493.                                 }
  1494.  
  1495.                                 return(TRUE);
  1496.                             }
  1497.  
  1498.                             if((Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) && (Qualifier & IEQUALIFIER_LEFTBUTTON))
  1499.                             {
  1500.                                 WORD DeltaX,DeltaY;
  1501.  
  1502.                                 ObtainSemaphore(&TerminalSemaphore);
  1503.  
  1504.                                 DeltaX = MouseX / TextFontWidth  - CursorX;
  1505.                                 DeltaY = MouseY / TextFontHeight - CursorY;
  1506.  
  1507.                                 ReleaseSemaphore(&TerminalSemaphore);
  1508.  
  1509.                                 if(DeltaX || DeltaY)
  1510.                                 {
  1511.                                     if(DeltaX > 0)
  1512.                                     {
  1513.                                         DeltaX++;
  1514.  
  1515.                                         while(DeltaX--)
  1516.                                             SerWrite("\33[C",3);
  1517.                                     }
  1518.  
  1519.                                     if(DeltaX < 0)
  1520.                                     {
  1521.                                         while(DeltaX++)
  1522.                                             SerWrite("\33[D",3);
  1523.                                     }
  1524.  
  1525.                                     if(DeltaY > 0)
  1526.                                     {
  1527.                                         DeltaY++;
  1528.  
  1529.                                         while(DeltaY--)
  1530.                                             SerWrite("\33[B",3);
  1531.                                     }
  1532.  
  1533.                                     if(DeltaY < 0)
  1534.                                     {
  1535.                                         while(DeltaY++)
  1536.                                             SerWrite("\33[A",3);
  1537.                                     }
  1538.                                 }
  1539.  
  1540.                                 return(TRUE);
  1541.                             }
  1542.  
  1543.                             ReportMouse(TRUE,Window);
  1544.  
  1545.                             if(!FirstClick)
  1546.                             {
  1547.                                 ULONG CurrentSecs,CurrentMicros;
  1548.  
  1549.                                 CurrentTime(&CurrentSecs,&CurrentMicros);
  1550.  
  1551.                                 FirstClick = TRUE;
  1552.  
  1553.                                 if(ABS(ClickX - MouseX) <= TextFontWidth && ABS(ClickY - MouseY) <= TextFontHeight && DoubleClick(ClickSecs,ClickMicros,CurrentSecs,CurrentMicros))
  1554.                                 {
  1555.                                     MarkWord(ClickX,ClickY);
  1556.  
  1557.                                     return(TRUE);
  1558.                                 }
  1559.                                 else
  1560.                                 {
  1561.                                     CurrentTime(&ClickSecs,&ClickMicros);
  1562.  
  1563.                                     FirstClick    = FALSE;
  1564.  
  1565.                                     ClickX        = MouseX;
  1566.                                     ClickY        = MouseY;
  1567.                                 }
  1568.                             }
  1569.                             else
  1570.                             {
  1571.                                 CurrentTime(&ClickSecs,&ClickMicros);
  1572.  
  1573.                                 FirstClick    = FALSE;
  1574.  
  1575.                                 ClickX        = MouseX;
  1576.                                 ClickY        = MouseY;
  1577.                             }
  1578.  
  1579.                             if(Marking)
  1580.                             {
  1581.                                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1582.                                     MoveMarker(MouseX,MouseY);
  1583.                                 else
  1584.                                 {
  1585.                                     DropMarker();
  1586.  
  1587.                                     CurrentTime(&ClickSecs,&ClickMicros);
  1588.  
  1589.                                     FirstClick    = FALSE;
  1590.  
  1591.                                     ClickX        = MouseX;
  1592.                                     ClickY        = MouseY;
  1593.  
  1594.                                     ReportMouse(TRUE,Window);
  1595.                                 }
  1596.                             }
  1597.                         }
  1598.                     }
  1599.  
  1600.                     break;
  1601.             }
  1602.         }
  1603.  
  1604.             /* Now for general information. */
  1605.  
  1606.         switch(IClass)
  1607.         {
  1608.             case IDCMP_RAWKEY:
  1609.  
  1610.                     /* Take care of the numeric keypad. */
  1611.  
  1612.                 if((Qualifier & IEQUALIFIER_NUMERICPAD) && (Config -> EmulationConfig -> NumericMode == KEYMODE_APPLICATION))
  1613.                 {
  1614.                     STATIC STRPTR StringTable[22][2] =
  1615.                     {
  1616.                         "0",    "\033Op",
  1617.                         "1",    "\033Oq",
  1618.                         "2",    "\033Or",
  1619.                         "3",    "\033Os",
  1620.                         "4",    "\033Ot",
  1621.                         "5",    "\033Ou",
  1622.                         "6",    "\033Ov",
  1623.                         "7",    "\033Ow",
  1624.                         "8",    "\033Ox",
  1625.                         "9",    "\033Oy",
  1626.                         "-",    "\033Om",
  1627.                         "+",    "\033Ol",    // This should really be a comma
  1628.                         ".",    "\033On",
  1629.  
  1630.                         "(",    "\033OP",
  1631.                         "[",    "\033OP",
  1632.                         "{",    "\033OP",
  1633.                         "]",    "\033OQ",
  1634.                         ")",    "\033OQ",
  1635.                         "}",    "\033OQ",
  1636.                         "/",    "\033OR",
  1637.                         "*",    "\033OS",
  1638.  
  1639.                         "\r",    "\033OM"
  1640.                     };
  1641.  
  1642.                     STATIC struct { UBYTE Code; STRPTR String; } CodeTable[18] =
  1643.                     {
  1644.                         0x0F,    "\033Op",    // "0"
  1645.                         0x1D,    "\033Oq",    // "1"
  1646.                         0x1E,    "\033Or",    // "2"
  1647.                         0x1F,    "\033Os",    // "3"
  1648.                         0x2D,    "\033Ot",    // "4"
  1649.                         0x2E,    "\033Ou",    // "5"
  1650.                         0x2F,    "\033Ov",    // "6"
  1651.                         0x3D,    "\033Ow",    // "7"
  1652.                         0x3E,    "\033Ox",    // "8"
  1653.                         0x3F,    "\033Oy",    // "9"
  1654.                         0x4A,    "\033Om",    // "-"
  1655.                         0x5E,    "\033Ol",    // "+", but this should really be a comma
  1656.                         0x3C,    "\033On",    // "."
  1657.  
  1658.                         0x5A,    "\033OP",    // "["
  1659.                         0x5B,    "\033OQ",    // "]"
  1660.                         0x5C,    "\033OR",    // "/"
  1661.                         0x5D,    "\033OS",    // "*"
  1662.  
  1663.                         0x43,    "\033OM"    // <cr>
  1664.                     };
  1665.  
  1666.                     STRPTR    String = NULL;
  1667.                     WORD    i;
  1668.  
  1669.                     for(i = 0 ; i < 22 ; i++)
  1670.                     {
  1671.                         if(Char == StringTable[i][0][0])
  1672.                         {
  1673.                             String = StringTable[i][1];
  1674.  
  1675.                             break;
  1676.                         }
  1677.                     }
  1678.  
  1679.                     if(!String)
  1680.                     {
  1681.                         for(i = 0 ; i < 18 ; i++)
  1682.                         {
  1683.                             if(Code == CodeTable[i] . Code)
  1684.                             {
  1685.                                 String = CodeTable[i] . String;
  1686.  
  1687.                                 break;
  1688.                             }
  1689.                         }
  1690.                     }
  1691.  
  1692.                     if(String)
  1693.                     {
  1694.                         if(ClipInput)
  1695.                         {
  1696.                             CloseClip();
  1697.  
  1698.                             ClipInput = ClipXerox = ClipPrefix = FALSE;
  1699.                         }
  1700.  
  1701.                         SerWrite(String,strlen(String));
  1702.  
  1703.                         Len = 0;
  1704.                     }
  1705.                 }
  1706.  
  1707.                     /* This looks like a raw, or better, now cooked key. */
  1708.  
  1709.                 if(Len)
  1710.                 {
  1711.                     switch(CharType[Char])
  1712.                     {
  1713.                         case CHAR_HELP:
  1714.  
  1715.                             GuideDisplay(CONTEXT_MAIN);
  1716.  
  1717.                             Len = 0;
  1718.  
  1719.                             break;
  1720.  
  1721.                         case CHAR_CURSOR:
  1722.  
  1723.                             if(ClipInput)
  1724.                             {
  1725.                                 CloseClip();
  1726.  
  1727.                                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  1728.                             }
  1729.  
  1730.                                 /* If in cursor key applications mode,
  1731.                                  * send the corresponding string.
  1732.                                  */
  1733.  
  1734.                             if(Config -> EmulationConfig -> CursorMode == KEYMODE_APPLICATION)
  1735.                             {
  1736.                                 STATIC STRPTR CursorTable[4] =
  1737.                                 {
  1738.                                     "\033OA",
  1739.                                     "\033OB",
  1740.                                     "\033OC",
  1741.                                     "\033OD"
  1742.                                 };
  1743.  
  1744.                                 SerWrite(CursorTable[Char - CUP],3);
  1745.                             }
  1746.                             else
  1747.                             {
  1748.                                 WORD QualType;
  1749.  
  1750.                                     /* Find the approriate qualifier. */
  1751.  
  1752.                                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1753.                                     QualType = 1;
  1754.                                 else
  1755.                                 {
  1756.                                     if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1757.                                         QualType = 2;
  1758.                                     else
  1759.                                     {
  1760.                                         if(Qualifier & IEQUALIFIER_CONTROL)
  1761.                                             QualType = 3;
  1762.                                         else
  1763.                                             QualType = 0;
  1764.                                     }
  1765.                                 }
  1766.  
  1767.                                     /* Send the corresponding string. */
  1768.  
  1769.                                 SerialCommand(CursorKeys -> Keys[QualType][Char - CUP]);
  1770.                             }
  1771.  
  1772.                             Len = 0;
  1773.  
  1774.                             break;
  1775.  
  1776.                             /* Any function key pressed? */
  1777.  
  1778.                         case CHAR_FUNCTION:
  1779.  
  1780.                             if(ClipInput)
  1781.                             {
  1782.                                 CloseClip();
  1783.  
  1784.                                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  1785.                             }
  1786.  
  1787.                             if(Qualifier & IEQUALIFIER_CONTROL)
  1788.                                 SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
  1789.                             else
  1790.                             {
  1791.                                 if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1792.                                     SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
  1793.                                 else
  1794.                                 {
  1795.                                     if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1796.                                         SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
  1797.                                     else
  1798.                                         SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
  1799.                                 }
  1800.                             }
  1801.  
  1802.                             Len = 0;
  1803.  
  1804.                             break;
  1805.  
  1806.                             /* Anything else? */
  1807.  
  1808.                         default:
  1809.  
  1810.                             if(Len == 1 && Char == '\r' && Recording && !RecordingLine && (Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  1811.                             {
  1812.                                 RememberInputText("\r",1);
  1813.  
  1814.                                 Len = 0;
  1815.  
  1816.                                 RecordingLine = TRUE;
  1817.  
  1818.                                 RememberResetInput();
  1819.  
  1820.                                 RememberOutput = FALSE;
  1821.                                 RememberInput = TRUE;
  1822.  
  1823.                                 CheckItem(MEN_RECORD_LINE,TRUE);
  1824.                             }
  1825.  
  1826.                             break;
  1827.                     }
  1828.  
  1829.                         /* Any characters to send? */
  1830.  
  1831.                     if(Len)
  1832.                         SendInputTextBuffer(InputBuffer,Len,TRUE);
  1833.                 }
  1834.  
  1835.                 break;
  1836.  
  1837.                 /* A menu item was selected. */
  1838.  
  1839.             case IDCMP_MENUPICK:
  1840.  
  1841.                 HandleMenu(Code,Qualifier);
  1842.                 break;
  1843.  
  1844.                 /* Menu help is required. */
  1845.  
  1846.             case IDCMP_MENUHELP:
  1847.  
  1848.                 if(MENUNUM(Code) == NOMENU || MENUNUM(Code) > 9 || ITEMNUM(Code) == NOITEM)
  1849.                     GuideDisplay(CONTEXT_MAIN_MENU);
  1850.                 else
  1851.                     GuideDisplay(CONTEXT_PROJECT_MEN + MENUNUM(Code));
  1852.  
  1853.                 break;
  1854.         }
  1855.  
  1856.         return(TRUE);
  1857.     }
  1858.  
  1859.     return(Result);
  1860. }
  1861.  
  1862.     /* HandleLocalDialList(BYTE ClearIt):
  1863.      *
  1864.      *    Invoke the local dialing list or clear it.
  1865.      */
  1866.  
  1867. STATIC VOID __regargs
  1868. HandleLocalDialList(BYTE ClearIt)
  1869. {
  1870.     if(Menu)
  1871.     {
  1872.         struct MenuItem *DialItem;
  1873.  
  1874.         if(DialItem = FindThisItem(Menu,FirstDialMenu))
  1875.         {
  1876.             if(Window)
  1877.                 ClearMenuStrip(Window);
  1878.  
  1879.             if(StatusWindow)
  1880.                 ClearMenuStrip(StatusWindow);
  1881.  
  1882.             if(FastWindow)
  1883.                 ClearMenuStrip(FastWindow);
  1884.  
  1885.             do
  1886.                 DialItem -> Flags &= ~CHECKED;
  1887.             while(DialItem = DialItem -> NextItem);
  1888.  
  1889.             if(Window)
  1890.                 ResetMenuStrip(Window,Menu);
  1891.  
  1892.             if(StatusWindow)
  1893.                 ResetMenuStrip(StatusWindow,Menu);
  1894.  
  1895.             if(FastWindow)
  1896.                 ResetMenuStrip(FastWindow,Menu);
  1897.         }
  1898.     }
  1899.  
  1900.     if(LocalDialList)
  1901.     {
  1902.         if(LocalDialList -> lh_Head -> ln_Succ && !Online && !ClearIt)
  1903.         {
  1904.             FreeDialList(TRUE);
  1905.  
  1906.             DialList = LocalDialList;
  1907.  
  1908.             LocalDialList = NULL;
  1909.  
  1910.             LocalCount = -1;
  1911.  
  1912.             SetRedialMenu();
  1913.  
  1914.             HandleMenuCode(MEN_REDIAL,NULL);
  1915.         }
  1916.         else
  1917.         {
  1918.             FreeList(LocalDialList);
  1919.  
  1920.             FreeVecPooled(LocalDialList);
  1921.  
  1922.             LocalDialList = NULL;
  1923.  
  1924.             LocalCount = -1;
  1925.         }
  1926.     }
  1927. }
  1928.  
  1929.     /* HandleMenuCode(ULONG Code,ULONG Qualifier):
  1930.      *
  1931.      *    Handle each function associated with a menu code.
  1932.      */
  1933.  
  1934. VOID __regargs
  1935. HandleMenuCode(ULONG Code,ULONG Qualifier)
  1936. {
  1937.     struct FileRequester    *FileRequest;
  1938.     UBYTE             DummyBuffer[MAX_FILENAME_LENGTH],
  1939.                 *DummyChar;
  1940.     BYTE             OldStatus = Status;
  1941.  
  1942.     BPTR             SomeFile;
  1943.     APTR             OldPtr;
  1944.  
  1945.     struct MenuItem        *Item;
  1946.  
  1947.     switch(Code)
  1948.     {
  1949.             /* Save screen as IFF-ILBM file. */
  1950.  
  1951.         case MEN_SAVE_AS_PICTURE:
  1952.  
  1953.             BlockWindows();
  1954.  
  1955.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),TRUE))
  1956.             {
  1957.                 if(!SaveWindow(DummyBuffer,Window))
  1958.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  1959.  
  1960.                 FreeAslRequest(FileRequest);
  1961.             }
  1962.  
  1963.             ReleaseWindows();
  1964.  
  1965.             break;
  1966.  
  1967.             /* Save screen as ASCII file. */
  1968.  
  1969.         case MEN_SAVE_AS_TEXT:
  1970.  
  1971.             BlockWindows();
  1972.  
  1973.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  1974.             {
  1975.                 LONG Error = 0;
  1976.  
  1977.                 if(GetFileSize(DummyBuffer))
  1978.                 {
  1979.                     switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  1980.                     {
  1981.                         case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  1982.                             break;
  1983.  
  1984.                         case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  1985.                             {
  1986.                                 if(Seek(SomeFile,0,OFFSET_END) == -1)
  1987.                                 {
  1988.                                     Close(SomeFile);
  1989.  
  1990.                                     SomeFile = NULL;
  1991.                                 }
  1992.                             }
  1993.  
  1994.                             break;
  1995.  
  1996.                         case 0:    SomeFile = ~0;
  1997.                             break;
  1998.                     }
  1999.                 }
  2000.                 else
  2001.                     SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2002.  
  2003.                 if(SomeFile)
  2004.                 {
  2005.                     if(SomeFile != ~0)
  2006.                     {
  2007.                         LONG     i,j;
  2008.                         UBYTE    *Buffer;
  2009.  
  2010.                         for(i = 0 ; i < RasterHeight ; i++)
  2011.                         {
  2012.                             Buffer = &Raster[i * RasterWidth];
  2013.  
  2014.                             j = LastColumn;
  2015.  
  2016.                             while(j >= 0 && Buffer[j] == ' ')
  2017.                                 j--;
  2018.  
  2019.                             if(j >= 0)
  2020.                             {
  2021.                                 SetIoErr(0);
  2022.  
  2023.                                 if(FWrite(SomeFile,Buffer,j + 1,1) < 1)
  2024.                                 {
  2025.                                     Error = IoErr();
  2026.  
  2027.                                     break;
  2028.                                 }
  2029.                             }
  2030.  
  2031.                             SetIoErr(0);
  2032.  
  2033.                             if(FWrite(SomeFile,"\n",1,1) < 1)
  2034.                             {
  2035.                                 Error = IoErr();
  2036.  
  2037.                                 break;
  2038.                             }
  2039.                         }
  2040.  
  2041.                         Close(SomeFile);
  2042.  
  2043.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  2044.  
  2045.                         if(Config -> MiscConfig -> CreateIcons)
  2046.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  2047.                     }
  2048.                 }
  2049.                 else
  2050.                     Error = IoErr();
  2051.  
  2052.                 if(Error)
  2053.                     ShowError(Window,ERR_SAVE_ERROR,Error,DummyBuffer);
  2054.  
  2055.                 FreeAslRequest(FileRequest);
  2056.             }
  2057.  
  2058.             ReleaseWindows();
  2059.  
  2060.             break;
  2061.  
  2062.             /* Print the screen (pure ASCII). */
  2063.  
  2064.         case MEN_PRINT_SCREEN:
  2065.  
  2066.             BlockWindows();
  2067.  
  2068.             if(RasterEnabled)
  2069.                 PrintSomething(PRINT_SCREEN);
  2070.             else
  2071.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NO_DATA_TO_PRINT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2072.  
  2073.             ReleaseWindows();
  2074.  
  2075.             break;
  2076.  
  2077.             /* Print the screen (graphics). */
  2078.  
  2079.         case MEN_PRINT_SCREEN_AS_GFX:
  2080.  
  2081.             BlockWindows();
  2082.  
  2083.             PrintScreenGfx();
  2084.  
  2085.             ReleaseWindows();
  2086.  
  2087.             break;
  2088.  
  2089.             /* Print the clipboard contents. */
  2090.  
  2091.         case MEN_PRINT_CLIP:
  2092.  
  2093.             BlockWindows();
  2094.  
  2095.             PrintSomething(PRINT_CLIP);
  2096.  
  2097.             ReleaseWindows();
  2098.  
  2099.             break;
  2100.  
  2101.             /* Open/close the terminal capture file. */
  2102.  
  2103.         case MEN_CAPTURE_TO_FILE:
  2104.  
  2105.             if(FileCapture)
  2106.                 CloseFileCapture();
  2107.             else
  2108.                 OpenFileCapture();
  2109.  
  2110.             CheckItem(MEN_CAPTURE_TO_FILE,FileCapture != NULL);
  2111.  
  2112.             break;
  2113.  
  2114.             /* Start/terminate the printer
  2115.              * capture.
  2116.              */
  2117.  
  2118.         case MEN_CAPTURE_TO_PRINTER:
  2119.  
  2120.             if(PrinterCapture)
  2121.                 ClosePrinterCapture(TRUE);
  2122.             else
  2123.                 OpenPrinterCapture(FALSE);
  2124.  
  2125.             CheckItem(MEN_CAPTURE_TO_PRINTER,PrinterCapture != NULL);
  2126.  
  2127.             break;
  2128.  
  2129.             /* Iconify the program. */
  2130.  
  2131.         case MEN_ICONIFY:
  2132.  
  2133.             if(Online && Config -> MiscConfig -> ReleaseDevice && !(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  2134.             {
  2135.                 if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2136.                     break;
  2137.             }
  2138.  
  2139.             DoIconify = TRUE;
  2140.  
  2141.             break;
  2142.  
  2143.             /* Say who we are. */
  2144.  
  2145.         case MEN_ABOUT:
  2146.  
  2147.             BlockWindows();
  2148. #ifdef DATAFEED
  2149.             if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2150.             {
  2151.                 STATIC UBYTE LastFile[40],LastPath[256];
  2152.  
  2153.                 extern BPTR DataFeed;
  2154.  
  2155.                 if(DataFeed)
  2156.                 {
  2157.                     Close(DataFeed);
  2158.  
  2159.                     DataFeed = NULL;
  2160.                 }
  2161.  
  2162.                 if(FileRequest = GetFile(Window,"Select terminal test file",LastPath,LastFile,DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SELECT_TXT),FALSE))
  2163.                 {
  2164.                     if(GetFileSize(DummyBuffer))
  2165.                     {
  2166.                         if(DataFeed = Open(DummyBuffer,MODE_OLDFILE))
  2167.                         {
  2168.                             strcpy(LastFile,FileRequest -> fr_File);
  2169.                             strcpy(LastPath,FileRequest -> fr_Drawer);
  2170.  
  2171.                             if(Kick30)
  2172.                                 SetVBuf(DataFeed,NULL,2,8192);
  2173.                         }
  2174.                     }
  2175.  
  2176.                     FreeAslRequest(FileRequest);
  2177.                 }
  2178.             }
  2179.             else
  2180. #endif    /* DATAFEED */
  2181.  
  2182.             ShowAbout(FALSE);
  2183.  
  2184.             ReleaseWindows();
  2185.  
  2186.             break;
  2187.  
  2188.             /* Terminate the program. */
  2189.  
  2190.         case MEN_QUIT:
  2191.  
  2192.             if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  2193.                 MainTerminated = TRUE;
  2194.             else
  2195.             {
  2196.                 STRPTR    Buffer;
  2197.                 LONG    OldLen,Len = strlen(LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT)) + 3;
  2198.  
  2199.                 OldLen = Len;
  2200.  
  2201.                 if(Online)
  2202.                     Len += strlen(LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT)) + 4;
  2203.  
  2204.                 if(BufferChanged)
  2205.                     Len += strlen(LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT)) + 4;
  2206.  
  2207.                 if(ConfigChanged)
  2208.                     Len += strlen(LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT)) + 4;
  2209.  
  2210.                 if(PhonebookChanged)
  2211.                     Len += strlen(LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT)) + 4;
  2212.  
  2213.                 if(TranslationChanged)
  2214.                     Len += strlen(LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT)) + 4;
  2215.  
  2216.                 if(MacroChanged)
  2217.                     Len += strlen(LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT)) + 4;
  2218.  
  2219.                 if(CursorKeysChanged)
  2220.                     Len += strlen(LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT)) + 4;
  2221.  
  2222.                 if(FastMacrosChanged)
  2223.                     Len += strlen(LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT)) + 4;
  2224.  
  2225.                 if(HotkeysChanged)
  2226.                     Len += strlen(LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT)) + 4;
  2227.  
  2228.                 if(SpeechChanged)
  2229.                     Len += strlen(LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT)) + 4;
  2230.  
  2231.                 if(SoundChanged)
  2232.                     Len += strlen(LocaleString(MSG_WAIT_SOUND_SETTINGS_CHANGED_TXT)) + 4;
  2233.  
  2234.                 BlockWindows();
  2235.  
  2236.                 OldPtr = ThisProcess -> pr_WindowPtr;
  2237.  
  2238.                 ThisProcess -> pr_WindowPtr = (APTR)Window;
  2239.  
  2240.                 if(OldLen != Len)
  2241.                 {
  2242.                     if(Buffer = (STRPTR)AllocVecPooled(Len,MEMF_ANY))
  2243.                     {
  2244.                         SPrintf(Buffer,"%s\n\n",LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT));
  2245.  
  2246.                         if(Online)
  2247.                         {
  2248.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT));
  2249.  
  2250.                             strcat(Buffer,SharedBuffer);
  2251.                         }
  2252.  
  2253.                         if(BufferChanged)
  2254.                         {
  2255.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT));
  2256.  
  2257.                             strcat(Buffer,SharedBuffer);
  2258.                         }
  2259.  
  2260.                         if(ConfigChanged)
  2261.                         {
  2262.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT));
  2263.  
  2264.                             strcat(Buffer,SharedBuffer);
  2265.                         }
  2266.  
  2267.                         if(PhonebookChanged)
  2268.                         {
  2269.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT));
  2270.  
  2271.                             strcat(Buffer,SharedBuffer);
  2272.                         }
  2273.  
  2274.                         if(TranslationChanged)
  2275.                         {
  2276.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT));
  2277.  
  2278.                             strcat(Buffer,SharedBuffer);
  2279.                         }
  2280.  
  2281.                         if(MacroChanged)
  2282.                         {
  2283.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT));
  2284.  
  2285.                             strcat(Buffer,SharedBuffer);
  2286.                         }
  2287.  
  2288.                         if(CursorKeysChanged)
  2289.                         {
  2290.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT));
  2291.  
  2292.                             strcat(Buffer,SharedBuffer);
  2293.                         }
  2294.  
  2295.                         if(FastMacrosChanged)
  2296.                         {
  2297.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT));
  2298.  
  2299.                             strcat(Buffer,SharedBuffer);
  2300.                         }
  2301.  
  2302.                         if(HotkeysChanged)
  2303.                         {
  2304.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT));
  2305.  
  2306.                             strcat(Buffer,SharedBuffer);
  2307.                         }
  2308.  
  2309.                         if(SpeechChanged)
  2310.                         {
  2311.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT));
  2312.  
  2313.                             strcat(Buffer,SharedBuffer);
  2314.                         }
  2315.  
  2316.                         if(MyEasyRequest(Window,Buffer,LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2317.                             MainTerminated = TRUE;
  2318.  
  2319.                         FreeVecPooled(Buffer);
  2320.                     }
  2321.                     else
  2322.                         MainTerminated = TRUE;
  2323.                 }
  2324.                 else
  2325.                     MainTerminated = TRUE;
  2326.  
  2327.                 ThisProcess -> pr_WindowPtr = OldPtr;
  2328.  
  2329.                 ReleaseWindows();
  2330.             }
  2331.  
  2332.             break;
  2333.  
  2334.             /* Feed the contents of the clipboard
  2335.              * into the input stream.
  2336.              */
  2337.  
  2338.         case MEN_PASTE:
  2339.  
  2340.             if(!OpenClip(Config -> ClipConfig -> ClipboardUnit))
  2341.             {
  2342.                 ClipInput = TRUE;
  2343.  
  2344.                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2345.                     ClipXerox = TRUE;
  2346.             }
  2347.             else
  2348.                 ClipInput = FALSE;
  2349.  
  2350.             break;
  2351.  
  2352.         case MEN_COPY:
  2353.  
  2354.             if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2355.                 ClipMarker(TRUE);
  2356.             else
  2357.                 ClipMarker(FALSE);
  2358.  
  2359.             break;
  2360.  
  2361.         case MEN_CLEAR:
  2362.  
  2363.             DropMarker();
  2364.             break;
  2365.  
  2366.             /* Execute an AmigaDOS command. */
  2367.  
  2368.         case MEN_EXECUTE_DOS_COMMAND:
  2369.  
  2370.             BlockWindows();
  2371.  
  2372.                 /* Enter the name of the command. */
  2373.  
  2374.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AMIGADOS_COMMAND_TXT),AmigaDOSCommandBuffer))
  2375.                 SendAmigaDOSCommand(AmigaDOSCommandBuffer);
  2376.  
  2377.             ReleaseWindows();
  2378.  
  2379.             break;
  2380.  
  2381.             /* Execute an ARexx script command. */
  2382.  
  2383.         case MEN_EXECUTE_REXX_COMMAND:
  2384.  
  2385.             BlockWindows();
  2386.  
  2387.                 /* Get the rexx file name/program. */
  2388.  
  2389.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AREXX_COMMAND_TXT),ARexxCommandBuffer))
  2390.                 SendARexxCommand(ARexxCommandBuffer);
  2391.  
  2392.             ReleaseWindows();
  2393.  
  2394.             break;
  2395.  
  2396.             /* Turn recording on/off. */
  2397.  
  2398.         case MEN_RECORD:
  2399.  
  2400.             if(GetItem(MEN_RECORD))
  2401.             {
  2402.                 if(!Recording)
  2403.                 {
  2404.                     if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : LocaleString(MSG_SCREENPANEL_UNKNOWN_TXT)))
  2405.                     {
  2406.                         RememberResetOutput();
  2407.                         RememberResetInput();
  2408.  
  2409.                         RememberOutput = TRUE;
  2410.  
  2411.                         Recording = TRUE;
  2412.                         RecordingLine = FALSE;
  2413.  
  2414.                         OnItem(MEN_RECORD_LINE);
  2415.                     }
  2416.                 }
  2417.             }
  2418.             else
  2419.             {
  2420.                 if(Recording)
  2421.                 {
  2422.                     FinishRecord();
  2423.  
  2424.                     RememberOutput = FALSE;
  2425.                     RememberInput = FALSE;
  2426.  
  2427.                     Recording = FALSE;
  2428.                     RecordingLine = FALSE;
  2429.  
  2430.                     OffItem(MEN_RECORD_LINE);
  2431.  
  2432.                     Status = STATUS_READY;
  2433.                 }
  2434.             }
  2435.  
  2436.             break;
  2437.  
  2438.         case MEN_RECORD_LINE:
  2439.  
  2440.             if(Recording)
  2441.             {
  2442.                 if(GetItem(MEN_RECORD))
  2443.                 {
  2444.                     if(!RecordingLine)
  2445.                     {
  2446.                         RecordingLine = TRUE;
  2447.  
  2448.                         RememberResetInput();
  2449.  
  2450.                         RememberOutput = FALSE;
  2451.                         RememberInput = TRUE;
  2452.                     }
  2453.                 }
  2454.                 else
  2455.                 {
  2456.                     if(RecordingLine)
  2457.                     {
  2458.                         RememberSpill();
  2459.  
  2460.                         RecordingLine = FALSE;
  2461.  
  2462.                         RememberOutput = TRUE;
  2463.                         RememberInput = FALSE;
  2464.                     }
  2465.                 }
  2466.             }
  2467.  
  2468.             break;
  2469.  
  2470.         case MEN_DISABLE_TRAPS:
  2471.  
  2472.             if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
  2473.             {
  2474.                 ObtainSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
  2475.  
  2476.                 if(!(Item -> Flags & CHECKED) && GenericListTable[GLIST_TRAP] -> ListHeader . mlh_Head -> mln_Succ)
  2477.                     WatchTraps = TRUE;
  2478.                 else
  2479.                     WatchTraps = FALSE;
  2480.  
  2481.                 ReleaseSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
  2482.             }
  2483.  
  2484.             break;
  2485.  
  2486.             /* Edit the trap settings? */
  2487.  
  2488.         case MEN_EDIT_TRAPS:
  2489.  
  2490.             BlockWindows();
  2491.  
  2492.             TrapPanel();
  2493.  
  2494.             if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
  2495.             {
  2496.                 if(WatchTraps)
  2497.                     Item -> Flags &= ~CHECKED;
  2498.                 else
  2499.                     Item -> Flags |= CHECKED;
  2500.             }
  2501.  
  2502.             ReleaseWindows();
  2503.  
  2504.             break;
  2505.  
  2506.             /* Set the name we will use to open the
  2507.              * default console output window for
  2508.              * AmigaDOS commands and ARexx scripts.
  2509.              */
  2510.  
  2511.         case MEN_SET_CONSOLE:
  2512.  
  2513.             BlockWindows();
  2514.  
  2515.             if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_SET_CONSOLE_WINDOW_TXT),WindowName))
  2516.                 SetEnvDOS("TERMWINDOW",WindowName);
  2517.  
  2518.             ReleaseWindows();
  2519.  
  2520.             break;
  2521.  
  2522.             /* Open the phonebook and dial the
  2523.              * list of entries the user will select.
  2524.              */
  2525.  
  2526.         case MEN_PHONEBOOK:
  2527.  
  2528.             BlockWindows();
  2529.  
  2530.             HandleLocalDialList(TRUE);
  2531.  
  2532.             while(PhonePanel())
  2533.             {
  2534.                 if(!DialPanel())
  2535.                 {
  2536.                     Status = OldStatus;
  2537.  
  2538.                     break;
  2539.                 }
  2540.  
  2541.                 Status = OldStatus;
  2542.             }
  2543.  
  2544.             SetRedialMenu();
  2545.  
  2546.             ReleaseWindows();
  2547.  
  2548.             break;
  2549.  
  2550.             /* Redial those dial list entries which
  2551.              * we were unable to connect.
  2552.              */
  2553.  
  2554.         case MEN_REDIAL:
  2555.  
  2556.             BlockWindows();
  2557.  
  2558.             HandleLocalDialList(TRUE);
  2559.  
  2560.             do
  2561.             {
  2562.                 if(!DialPanel())
  2563.                 {
  2564.                     Status = OldStatus;
  2565.  
  2566.                     break;
  2567.                 }
  2568.  
  2569.                 Status = OldStatus;
  2570.             }
  2571.             while(PhonePanel());
  2572.  
  2573.             SetRedialMenu();
  2574.  
  2575.             ReleaseWindows();
  2576.  
  2577.             break;
  2578.  
  2579.             /* Dial a single number. */
  2580.  
  2581.         case MEN_DIAL_NUMBER:
  2582.  
  2583.             BlockWindows();
  2584.  
  2585.             HandleLocalDialList(TRUE);
  2586.  
  2587.             DummyBuffer[0] = 0;
  2588.  
  2589.             if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TXT),DummyBuffer))
  2590.             {
  2591.                 if(DummyBuffer[0])
  2592.                 {
  2593.                     struct List *LocalList;
  2594.  
  2595.                     if(LocalList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
  2596.                     {
  2597.                         struct PhoneNode    *DialNode;
  2598.                         LONG             Len = strlen(DummyBuffer);
  2599.  
  2600.                         NewList(LocalList);
  2601.  
  2602.                         if(DialNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode) + Len + 1,MEMF_ANY|MEMF_CLEAR))
  2603.                         {
  2604.                             DialNode -> VanillaNode . ln_Name = (char *)(DialNode + 1);
  2605.  
  2606.                             strcpy(DialNode -> VanillaNode . ln_Name,DummyBuffer);
  2607.  
  2608.                             AddTail(LocalList,&DialNode -> VanillaNode);
  2609.  
  2610.                             FreeDialList(TRUE);
  2611.  
  2612.                             DialList = LocalList;
  2613.  
  2614.                             DialPanel();
  2615.  
  2616.                             Status = OldStatus;
  2617.                         }
  2618.                         else
  2619.                             FreeVecPooled(LocalList);
  2620.                     }
  2621.                 }
  2622.             }
  2623.  
  2624.             SetRedialMenu();
  2625.  
  2626.             ReleaseWindows();
  2627.  
  2628.             break;
  2629.  
  2630.             /* Send a break across the serial line. */
  2631.  
  2632.         case MEN_SEND_BREAK:
  2633.  
  2634.             SendBreak();
  2635.             break;
  2636.  
  2637.             /* Hang up the phone line. */
  2638.  
  2639.         case MEN_HANG_UP:
  2640.  
  2641.             BlockWindows();
  2642.  
  2643.             if(DialMsg)
  2644.             {
  2645.                 DialMsg -> rm_Result1 = RC_WARN;
  2646.                 DialMsg -> rm_Result2 = 0;
  2647.  
  2648.                 ReplyMsg(DialMsg);
  2649.  
  2650.                 DialMsg = NULL;
  2651.             }
  2652.  
  2653.             HangUp();
  2654.  
  2655.             ReleaseWindows();
  2656.  
  2657.             if(Config -> SerialConfig -> CheckCarrier)
  2658.                 HungUp = TRUE;
  2659.             else
  2660.             {
  2661.                 ObtainSemaphore(&OnlineSemaphore);
  2662.  
  2663.                     /* Remember online state. */
  2664.  
  2665.                 WasOnline = Online;
  2666.  
  2667.                     /* We are no longer online. */
  2668.  
  2669.                 Online = FALSE;
  2670.  
  2671.                 ReleaseSemaphore(&OnlineSemaphore);
  2672.  
  2673.                 HandleOnlineCleanup(TRUE);
  2674.             }
  2675.  
  2676.             break;
  2677.  
  2678.             /* Wait a bit... */
  2679.  
  2680.         case MEN_WAIT:
  2681.         {
  2682.             struct Window        *ReqWindow;
  2683.             struct EasyStruct     Easy;
  2684.  
  2685.             Easy . es_StructSize    = sizeof(struct EasyStruct);
  2686.             Easy . es_Flags        = NULL;
  2687.             Easy . es_Title        = (UBYTE *)LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  2688.             Easy . es_GadgetFormat    = (UBYTE *)LocaleString(MSG_GLOBAL_CONTINUE_TXT);
  2689.             Easy . es_TextFormat    = (UBYTE *)LocaleString(MSG_TERMMAIN_WAITING_TXT);
  2690.  
  2691.             BlockWindows();
  2692.  
  2693.             if(ReqWindow = BuildEasyRequest(Window,&Easy,NULL))
  2694.             {
  2695.                 ULONG    Signals;
  2696.                 BYTE    Done = FALSE;
  2697.  
  2698.                     /* Don't echo serial output. */
  2699.  
  2700.                 Quiet = TRUE;
  2701.  
  2702.                 do
  2703.                 {
  2704.                     SerWrite(" \b",2);
  2705.  
  2706.                     HandleSerial();
  2707.  
  2708.                     StartTime(1,0);
  2709.  
  2710.                     Signals = Wait(SIG_TIMER | PORTMASK(ReqWindow -> UserPort));
  2711.  
  2712.                     if(Signals & SIG_TIMER)
  2713.                         WaitIO(TimeRequest);
  2714.  
  2715.                     if(Signals & PORTMASK(ReqWindow -> UserPort))
  2716.                     {
  2717.                         if(!SysReqHandler(ReqWindow,NULL,FALSE))
  2718.                         {
  2719.                             if(!CheckIO(TimeRequest))
  2720.                                 AbortIO(TimeRequest);
  2721.  
  2722.                             WaitIO(TimeRequest);
  2723.  
  2724.                             Done = TRUE;
  2725.                         }
  2726.                     }
  2727.                 }
  2728.                 while(!Done);
  2729.  
  2730.                 Quiet = FALSE;
  2731.  
  2732.                 FreeSysRequest(ReqWindow);
  2733.             }
  2734.  
  2735.             ReleaseWindows();
  2736.         }
  2737.  
  2738.         break;
  2739.  
  2740.             /* Flush the serial buffers. */
  2741.  
  2742.         case MEN_FLUSH_BUFFER:
  2743.  
  2744.             ClearSerial();
  2745.  
  2746.             RestartSerial(FALSE);
  2747.  
  2748.             break;
  2749.  
  2750.             /* Release the serial device for other
  2751.              * applications.
  2752.              */
  2753.  
  2754.         case MEN_RELEASE_DEVICE:
  2755.  
  2756.             ReleaseSerial = TRUE;
  2757.             break;
  2758.  
  2759.         case MEN_UPLOAD_ASCII:
  2760.  
  2761.             BlockWindows();
  2762.  
  2763.             if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary))
  2764.             {
  2765.                 BinaryTransfer = FALSE;
  2766.  
  2767.                 StartXprSend(TRANSFER_ASCII,TRUE);
  2768.  
  2769.                 BinaryTransfer = TRUE;
  2770.             }
  2771.  
  2772.             ResetProtocol();
  2773.  
  2774.             ReleaseWindows();
  2775.  
  2776.             break;
  2777.  
  2778.         case MEN_DOWNLOAD_ASCII:
  2779.  
  2780.             BlockWindows();
  2781.  
  2782.             if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary))
  2783.             {
  2784.                 BinaryTransfer = FALSE;
  2785.  
  2786.                 StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
  2787.  
  2788.                 BinaryTransfer = TRUE;
  2789.             }
  2790.  
  2791.             ResetProtocol();
  2792.  
  2793.             ReleaseWindows();
  2794.  
  2795.             break;
  2796.  
  2797.         case MEN_UPLOAD_TEXT:
  2798.  
  2799.             BlockWindows();
  2800.  
  2801.             if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary))
  2802.             {
  2803.                 BinaryTransfer = FALSE;
  2804.  
  2805.                 StartXprSend(TRANSFER_TEXT,TRUE);
  2806.  
  2807.                 BinaryTransfer = TRUE;
  2808.             }
  2809.  
  2810.             ResetProtocol();
  2811.  
  2812.             ReleaseWindows();
  2813.  
  2814.             break;
  2815.  
  2816.         case MEN_DOWNLOAD_TEXT:
  2817.  
  2818.             BlockWindows();
  2819.  
  2820.             if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary))
  2821.             {
  2822.                 BinaryTransfer = FALSE;
  2823.  
  2824.                 StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  2825.  
  2826.                 BinaryTransfer = TRUE;
  2827.             }
  2828.  
  2829.             ResetProtocol();
  2830.  
  2831.             ReleaseWindows();
  2832.  
  2833.             break;
  2834.  
  2835.             /* Edit and transfer a file. */
  2836.  
  2837.         case MEN_EDIT_AND_UPLOAD_TEXT:
  2838.  
  2839.             BlockWindows();
  2840.  
  2841.             if(!Config -> PathConfig -> Editor[0])
  2842.                 GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_NAME_OF_EDITOR_TO_USE_TXT),Config -> PathConfig -> Editor);
  2843.  
  2844.             if(Config -> PathConfig -> Editor[0])
  2845.             {
  2846.                 if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_EDIT_AND_TRANSFER_FILE_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMMAIN_EDIT_TXT),TRUE))
  2847.                 {
  2848.                     UBYTE CompoundName[512];
  2849.  
  2850.                     strcpy(CompoundName,Config -> PathConfig -> Editor);
  2851.                     strcat(CompoundName," \"");
  2852.                     strcat(CompoundName,DummyBuffer);
  2853.                     strcat(CompoundName,"\"");
  2854.  
  2855.                     SystemTags(CompoundName,
  2856.                         SYS_UserShell,    TRUE,
  2857.                     TAG_DONE);
  2858.  
  2859.                     BumpWindow(Window);
  2860.  
  2861.                     FreeAslRequest(FileRequest);
  2862.  
  2863.                     if(GetFileSize(DummyBuffer))
  2864.                     {
  2865.                         BinaryTransfer = FALSE;
  2866.  
  2867.                         switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILE_AS_TXT),LocaleString(MSG_TERMMAIN_ASCII_UPLOAD_CANCEL_TXT),FilePart(DummyBuffer)))
  2868.                         {
  2869.                             case 1:    if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary))
  2870.                                     SendTextFile(TRANSFER_ASCII,DummyBuffer);
  2871.  
  2872.                                 ResetProtocol();
  2873.  
  2874.                                 break;
  2875.  
  2876.                             case 2:    if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary))
  2877.                                     SendTextFile(TRANSFER_TEXT,DummyBuffer);
  2878.  
  2879.                                 ResetProtocol();
  2880.  
  2881.                                 break;
  2882.                         }
  2883.  
  2884.                         BinaryTransfer = TRUE;
  2885.                     }
  2886.                 }
  2887.             }
  2888.  
  2889.             ReleaseWindows();
  2890.             break;
  2891.  
  2892.         case MEN_UPLOAD_BINARY:
  2893.  
  2894.             BlockWindows();
  2895.  
  2896.             if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary))
  2897.             {
  2898.                 BinaryTransfer = TRUE;
  2899.  
  2900.                 StartXprSend(TRANSFER_BINARY,TRUE);
  2901.             }
  2902.  
  2903.             ResetProtocol();
  2904.  
  2905.             ReleaseWindows();
  2906.  
  2907.             break;
  2908.  
  2909.             /* Download some files. */
  2910.  
  2911.         case MEN_DOWNLOAD_BINARY:
  2912.  
  2913.             BlockWindows();
  2914.  
  2915.             if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary))
  2916.             {
  2917.                 BinaryTransfer = TRUE;
  2918.  
  2919.                 StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  2920.             }
  2921.  
  2922.             ResetProtocol();
  2923.  
  2924.             ReleaseWindows();
  2925.  
  2926.             break;
  2927.  
  2928.             /* Clear the contents of the scrollback
  2929.              * buffer.
  2930.              */
  2931.  
  2932.         case MEN_CLEAR_BUFFER:
  2933.  
  2934.             if(Lines)
  2935.             {
  2936.                 BlockWindows();
  2937.  
  2938.                 if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  2939.                 {
  2940.                     FreeBuffer();
  2941.  
  2942.                     TerminateBuffer();
  2943.                 }
  2944.                 else
  2945.                 {
  2946.                     if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  2947.                     {
  2948.                         FreeBuffer();
  2949.  
  2950.                         TerminateBuffer();
  2951.                     }
  2952.                 }
  2953.  
  2954.                 ReleaseWindows();
  2955.             }
  2956.  
  2957.             break;
  2958.  
  2959.             /* Display the scrollback buffer.
  2960.              * Notify the scrollback task or
  2961.              * fire it off if approriate.
  2962.              */
  2963.  
  2964.         case MEN_DISPLAY_BUFFER:
  2965.  
  2966.             if(!LaunchBuffer())
  2967.             {
  2968.                 BlockWindows();
  2969.  
  2970.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNABLE_TO_CREATE_BUFFER_TASK_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2971.  
  2972.                 ReleaseWindows();
  2973.             }
  2974.  
  2975.             break;
  2976.  
  2977.             /* Close the buffer display. */
  2978.  
  2979.         case MEN_CLOSE_BUFFER:
  2980.  
  2981.             if(BufferTask)
  2982.             {
  2983.                 Forbid();
  2984.  
  2985.                 Signal(BufferTask,SIG_KILL);
  2986.  
  2987.                 ClrSignal(SIG_HANDSHAKE);
  2988.  
  2989.                 Wait(SIG_HANDSHAKE);
  2990.  
  2991.                 Permit();
  2992.             }
  2993.  
  2994.             break;
  2995.  
  2996.             /* Is the buffer to be frozen? */
  2997.  
  2998.         case MEN_FREEZE_BUFFER:
  2999.  
  3000.             if(Item = FindThisItem(Menu,MEN_FREEZE_BUFFER))
  3001.             {
  3002.                 if(Item -> Flags & CHECKED)
  3003.                     BufferFrozen = TRUE;
  3004.                 else
  3005.                     BufferFrozen = FALSE;
  3006.  
  3007.                 Forbid();
  3008.  
  3009.                 ConOutputUpdate();
  3010.  
  3011.                 Permit();
  3012.             }
  3013.  
  3014.             break;
  3015.  
  3016.             /* Load the buffer contents from a file. */
  3017.  
  3018.         case MEN_OPEN_BUFFER:
  3019.  
  3020.             BlockWindows();
  3021.  
  3022.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),FALSE))
  3023.             {
  3024.                 if(GetFileSize(DummyBuffer))
  3025.                 {
  3026.                     if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  3027.                     {
  3028.                         if(Lines)
  3029.                         {
  3030.                             switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_TERMMAIN_DISCARD_APPPEND_CANCEL_TXT),Lines))
  3031.                             {
  3032.                                 case 1:    FreeBuffer();
  3033.                                     break;
  3034.  
  3035.                                 case 2:    break;
  3036.  
  3037.                                 case 0:    Close(SomeFile);
  3038.                                     SomeFile = NULL;
  3039.                                     break;
  3040.                             }
  3041.                         }
  3042.  
  3043.                         if(SomeFile)
  3044.                         {
  3045.                             LONG Len;
  3046.  
  3047.                             LineRead(NULL,NULL,NULL);
  3048.  
  3049.                             while((Len = LineRead(SomeFile,DummyBuffer,80)) > 0)
  3050.                                 StoreBuffer(DummyBuffer,Len,AddLine);
  3051.  
  3052.                             Close(SomeFile);
  3053.  
  3054.                             BufferChanged = TRUE;
  3055.                         }
  3056.                     }
  3057.                     else
  3058.                         ShowError(Window,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
  3059.                 }
  3060.  
  3061.                 FreeAslRequest(FileRequest);
  3062.             }
  3063.  
  3064.             ReleaseWindows();
  3065.             break;
  3066.  
  3067.             /* Save the contents of the scrollback
  3068.              * buffer to a file (line by line).
  3069.              */
  3070.  
  3071.         case MEN_SAVE_BUFFER_AS:
  3072.  
  3073.             BlockWindows();
  3074.  
  3075.             if(!Lines || !BufferLines)
  3076.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3077.             else
  3078.             {
  3079.                 if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT),Config -> CaptureConfig -> BufferPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  3080.                 {
  3081.                     LONG Error = 0;
  3082.  
  3083.                     SomeFile = NULL;
  3084.  
  3085.                         /* If the file we are about
  3086.                          * to create already exists,
  3087.                          * ask the user whether we are
  3088.                          * to create, append or skip
  3089.                          * the file.
  3090.                          */
  3091.  
  3092.                     if(GetFileSize(DummyBuffer))
  3093.                     {
  3094.                         switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  3095.                         {
  3096.                             case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3097.                                 break;
  3098.  
  3099.                             case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  3100.                                 {
  3101.                                     if(Seek(SomeFile,0,OFFSET_END) == -1)
  3102.                                     {
  3103.                                         Close(SomeFile);
  3104.  
  3105.                                         SomeFile = NULL;
  3106.                                     }
  3107.                                 }
  3108.  
  3109.                                 break;
  3110.                         }
  3111.                     }
  3112.                     else
  3113.                         SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3114.  
  3115.                     if(SomeFile)
  3116.                     {
  3117.                         LONG i,Len;
  3118.  
  3119.                             /* Obtain the semaphore required
  3120.                              * to gain access to the line buffer
  3121.                              */
  3122.  
  3123.                         ObtainSemaphore(BufferSemaphore);
  3124.  
  3125.                         for(i = 0 ; i < Lines ; i++)
  3126.                         {
  3127.                             Len = BufferLines[i][-1];
  3128.  
  3129.                             if(Len)
  3130.                             {
  3131.                                 SetIoErr(0);
  3132.  
  3133.                                 if(FWrite(SomeFile,BufferLines[i],Len,1) < 1)
  3134.                                 {
  3135.                                     Error = IoErr();
  3136.  
  3137.                                     break;
  3138.                                 }
  3139.                             }
  3140.  
  3141.                             SetIoErr(0);
  3142.  
  3143.                             if(FPrintf(SomeFile,"\n") < 1)
  3144.                             {
  3145.                                 Error = IoErr();
  3146.  
  3147.                                 break;
  3148.                             }
  3149.                         }
  3150.  
  3151.                         ReleaseSemaphore(BufferSemaphore);
  3152.  
  3153.                         Close(SomeFile);
  3154.  
  3155.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  3156.  
  3157.                         if(Config -> MiscConfig -> CreateIcons)
  3158.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  3159.  
  3160.                         BufferChanged = FALSE;
  3161.                     }
  3162.                     else
  3163.                         Error = IoErr();
  3164.  
  3165.                     if(Error)
  3166.                         ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  3167.  
  3168.                     FreeAslRequest(FileRequest);
  3169.                 }
  3170.             }
  3171.  
  3172.             ReleaseWindows();
  3173.  
  3174.             break;
  3175.  
  3176.             /* Simply clear the screen and move the
  3177.              * cursor to its home position.
  3178.              */
  3179.  
  3180.         case MEN_CLEAR_SCREEN:
  3181.  
  3182.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3183.                 XEmulatorClearConsole(XEM_IO);
  3184.             else
  3185.             {
  3186.                 DropMarker();
  3187.  
  3188.                 ConBypass("\033[2J\033[H",-1);
  3189.             }
  3190.  
  3191.             break;
  3192.  
  3193.             /* Reset the current text rendering font. */
  3194.  
  3195.         case MEN_RESET_FONT:
  3196.  
  3197.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3198.                 XEmulatorResetCharset(XEM_IO);
  3199.             else
  3200.             {
  3201.                 DropMarker();
  3202.  
  3203.                 CurrentFont = TextFont;
  3204.  
  3205.                 SetFont(RPort,CurrentFont);
  3206.  
  3207.                 ConOutputUpdate();
  3208.             }
  3209.  
  3210.             break;
  3211.  
  3212.             /* Reset the display styles and restore
  3213.              * the colours.
  3214.              */
  3215.  
  3216.         case MEN_RESET_STYLES:
  3217.  
  3218.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3219.                 XEmulatorResetTextStyles(XEM_IO);
  3220.             else
  3221.             {
  3222.                 DropMarker();
  3223.  
  3224.                 ConBypass("\033[0m",-1);
  3225.  
  3226.                 ObtainSemaphore(&TerminalSemaphore);
  3227.  
  3228.                 ClearCursor();
  3229.  
  3230.                 Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
  3231.  
  3232.                 FgPen = GetPenIndex(SafeTextPen);
  3233.                 BgPen = 0;
  3234.  
  3235.                 if(ReadAPen(RPort) != MappedPens[0][FgPen])
  3236.                     SetAPen(RPort,MappedPens[0][FgPen]);
  3237.  
  3238.                 if(ReadBPen(RPort) != MappedPens[0][BgPen])
  3239.                     SetBPen(RPort,MappedPens[0][BgPen]);
  3240.  
  3241.                 SetWrMsk(RPort,DepthMask);
  3242.  
  3243.                 ConFontScaleUpdate();
  3244.  
  3245.                 DrawCursor();
  3246.  
  3247.                 ReleaseSemaphore(&TerminalSemaphore);
  3248.             }
  3249.  
  3250.             break;
  3251.  
  3252.             /* Reset the whole terminal. */
  3253.  
  3254.         case MEN_RESET_TERMINAL:
  3255.  
  3256.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3257.                 XEmulatorResetConsole(XEM_IO);
  3258.             else
  3259.             {
  3260.                 FreeMarker();
  3261.  
  3262.                 ConBypass("\033c",-1);
  3263.             }
  3264.  
  3265.             break;
  3266.  
  3267.         case MEN_SET_EMULATION:
  3268.  
  3269.             BlockWindows();
  3270.  
  3271.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3272.             {
  3273.                 OptionTitle = LocaleString(MSG_TERMMAIN_EMULATION_PREFERENCES_TXT);
  3274.  
  3275.                 NewOptions = FALSE;
  3276.  
  3277.                 XEmulatorOptions(XEM_IO);
  3278.  
  3279.                 if(NewOptions)
  3280.                 {
  3281.                     SetEmulatorOptions(XEM_PREFS_SAVE);
  3282.  
  3283.                     NewOptions = FALSE;
  3284.                 }
  3285.  
  3286.                 OptionTitle = NULL;
  3287.             }
  3288.             else
  3289.                 EmulationPanel(Config,NULL);
  3290.  
  3291.             ReleaseWindows();
  3292.  
  3293.             break;
  3294.  
  3295.             /* Set the serial preferences. */
  3296.  
  3297.         case MEN_SERIAL:
  3298.  
  3299.             BlockWindows();
  3300.  
  3301.             if(SerialPanel(Config,NULL))
  3302.             {
  3303.                 ConfigSetup();
  3304.  
  3305.                 ConfigChanged = TRUE;
  3306.             }
  3307.  
  3308.             ReleaseWindows();
  3309.  
  3310.             break;
  3311.  
  3312.             /* Set the modem preferences. */
  3313.  
  3314.         case MEN_MODEM:
  3315.  
  3316.             BlockWindows();
  3317.  
  3318.             if(ModemPanel(Config,NULL))
  3319.             {
  3320.                 FlowInit(TRUE);
  3321.  
  3322.                 ConfigChanged = TRUE;
  3323.             }
  3324.  
  3325.             ReleaseWindows();
  3326.  
  3327.             break;
  3328.  
  3329.             /* Set the screen preferences. */
  3330.  
  3331.         case MEN_SCREEN:
  3332.  
  3333.             BlockWindows();
  3334.  
  3335.             if(ScreenPanel(Config,NULL))
  3336.             {
  3337.                 if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
  3338.                 {
  3339.                     switch(Config -> ScreenConfig -> ColourMode)
  3340.                     {
  3341.                         case COLOUR_EIGHT:
  3342.  
  3343.                             CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
  3344.                             break;
  3345.  
  3346.                         case COLOUR_SIXTEEN:
  3347.  
  3348.                             CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
  3349.                             break;
  3350.  
  3351.                         case COLOUR_AMIGA:
  3352.  
  3353.                             CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
  3354.                             break;
  3355.  
  3356.                         case COLOUR_MONO:
  3357.  
  3358.                             CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
  3359.                             break;
  3360.                     }
  3361.                 }
  3362.  
  3363.                 ConfigSetup();
  3364.  
  3365.                 ConfigChanged = TRUE;
  3366.             }
  3367.             else
  3368.             {
  3369.                 if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
  3370.                 {
  3371.                     switch(Config -> ScreenConfig -> ColourMode)
  3372.                     {
  3373.                         case COLOUR_EIGHT:
  3374.  
  3375.                             CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
  3376.                             break;
  3377.  
  3378.                         case COLOUR_SIXTEEN:
  3379.  
  3380.                             CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
  3381.                             break;
  3382.  
  3383.                         case COLOUR_AMIGA:
  3384.  
  3385.                             CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
  3386.                             break;
  3387.  
  3388.                         case COLOUR_MONO:
  3389.  
  3390.                             CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
  3391.                             break;
  3392.                     }
  3393.  
  3394.                     ConfigChanged = TRUE;
  3395.                 }
  3396.             }
  3397.  
  3398.             ReleaseWindows();
  3399.  
  3400.             break;
  3401.  
  3402.             /* Set the terminal preferences. */
  3403.  
  3404.         case MEN_TERMINAL:
  3405.  
  3406.             BlockWindows();
  3407.  
  3408.             if(TerminalPanel(Config,NULL))
  3409.             {
  3410.                 Update_CR_LF_Translation();
  3411.  
  3412.                 ConfigSetup();
  3413.  
  3414.                 ConfigChanged = TRUE;
  3415.             }
  3416.  
  3417.             ReleaseWindows();
  3418.  
  3419.             break;
  3420.  
  3421.             /* Set the clipboard preferences. */
  3422.  
  3423.         case MEN_CLIPBOARD:
  3424.  
  3425.             BlockWindows();
  3426.  
  3427.             if(ClipPanel(Config,NULL))
  3428.             {
  3429.                 ConfigSetup();
  3430.  
  3431.                 ConfigChanged = TRUE;
  3432.             }
  3433.  
  3434.             ReleaseWindows();
  3435.  
  3436.             break;
  3437.  
  3438.             /* Set the capture preferences. */
  3439.  
  3440.         case MEN_CAPTURE:
  3441.  
  3442.             BlockWindows();
  3443.  
  3444.             if(CapturePanel(Config,NULL))
  3445.             {
  3446.                 ConOutputUpdate();
  3447.  
  3448.                 ConfigSetup();
  3449.  
  3450.                 ConfigChanged = TRUE;
  3451.             }
  3452.  
  3453.             ReleaseWindows();
  3454.  
  3455.             break;
  3456.  
  3457.             /* Set the command preferences. */
  3458.  
  3459.         case MEN_COMMANDS:
  3460.  
  3461.             BlockWindows();
  3462.  
  3463.             if(CommandPanel(Config,NULL))
  3464.                 ConfigChanged = TRUE;
  3465.  
  3466.             ReleaseWindows();
  3467.  
  3468.             break;
  3469.  
  3470.             /* Set the miscellaneous preferences. */
  3471.  
  3472.         case MEN_MISC:
  3473.  
  3474.             BlockWindows();
  3475.  
  3476.             if(MiscPanel(Config,NULL))
  3477.             {
  3478.                 ConfigSetup();
  3479.  
  3480.                 ConfigChanged = TRUE;
  3481.             }
  3482.  
  3483.             ReleaseWindows();
  3484.  
  3485.             break;
  3486.  
  3487.             /* Set the path settings. */
  3488.  
  3489.         case MEN_PATH:
  3490.  
  3491.             BlockWindows();
  3492.  
  3493.             if(PathPanel(Config,NULL))
  3494.                 ConfigChanged = TRUE;
  3495.  
  3496.             ReleaseWindows();
  3497.  
  3498.             break;
  3499.  
  3500.             /* Set the file transfer options. */
  3501.  
  3502.         case MEN_TRANSFER:
  3503.  
  3504.             BlockWindows();
  3505.  
  3506.             XprIO -> xpr_filename = NULL;
  3507.  
  3508.                 /* Set up the library options. */
  3509.  
  3510.             if(XProtocolBase)
  3511.             {
  3512.                 XPRCommandSelected = FALSE;
  3513.  
  3514.                 ClearSerial();
  3515.  
  3516.                 NewOptions = FALSE;
  3517.  
  3518.                 TransferBits = XProtocolSetup(XprIO);
  3519.  
  3520.                 RestartSerial(FALSE);
  3521.  
  3522.                 DeleteTransferPanel(TRUE);
  3523.  
  3524.                     /* Successful? */
  3525.  
  3526. /*                if(!XPRCommandSelected)*/
  3527.                 {
  3528.                     if(!(TransferBits & XPRS_SUCCESS))
  3529.                     {
  3530.                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  3531.  
  3532.                         CloseLibrary(XProtocolBase);
  3533.  
  3534.                         XProtocolBase = NULL;
  3535.  
  3536.                         LastXprLibrary[0] = 0;
  3537.  
  3538.                         TransferBits = 0;
  3539.  
  3540.                         SetTransferMenu(FALSE);
  3541.                     }
  3542.                     else
  3543.                         SaveProtocolOpts();
  3544.                 }
  3545.             }
  3546.  
  3547.             ReleaseWindows();
  3548.  
  3549.             break;
  3550.  
  3551.             /* Set the file transfer procol settings. */
  3552.  
  3553.         case MEN_TRANSFER_PROTOCOL:
  3554.  
  3555.             BlockWindows();
  3556.  
  3557.             if(LibPanel(Config,NULL))
  3558.             {
  3559.                 ConfigSetup();
  3560.  
  3561.                 ConfigChanged = TRUE;
  3562.             }
  3563.  
  3564.             ReleaseWindows();
  3565.  
  3566.             break;
  3567.  
  3568.             /* Set the translation tables. */
  3569.  
  3570.         case MEN_TRANSLATION:
  3571.  
  3572.             BlockWindows();
  3573.  
  3574.             TranslationChanged |= TranslationPanel(&SendTable,&ReceiveTable,LastTranslation,Window);
  3575.  
  3576.                 /* Choose the right console write routine. */
  3577.  
  3578.             ConOutputUpdate();
  3579.  
  3580.             ReleaseWindows();
  3581.  
  3582.             break;
  3583.  
  3584.             /* Set the keyboard macros. */
  3585.  
  3586.         case MEN_MACROS:
  3587.  
  3588.             BlockWindows();
  3589.  
  3590.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3591.             {
  3592.                 XEmulatorMacroKeyFilter(XEM_IO,NULL);
  3593.  
  3594.                 MacroChanged |= MacroPanel(MacroKeys,LastMacros,TRUE,Window);
  3595.  
  3596.                 SetupXEM_MacroKeys(MacroKeys);
  3597.             }
  3598.             else
  3599.                 MacroChanged |= MacroPanel(MacroKeys,LastMacros,TRUE,Window);
  3600.  
  3601.             ReleaseWindows();
  3602.  
  3603.             break;
  3604.  
  3605.             /* Set the cursor keys. */
  3606.  
  3607.         case MEN_CURSORKEYS:
  3608.  
  3609.             BlockWindows();
  3610.  
  3611.             CursorKeysChanged |= CursorPanel(CursorKeys,LastCursorKeys,Window);
  3612.  
  3613.             ReleaseWindows();
  3614.  
  3615.             break;
  3616.  
  3617.             /* Set the fast macros. */
  3618.  
  3619.         case MEN_FAST_MACROS:
  3620.  
  3621.             BlockWindows();
  3622.  
  3623.             FastMacrosChanged |= FastMacroPanel(&FastMacroList,LastFastMacros,Window);
  3624.  
  3625.             ReleaseWindows();
  3626.  
  3627.             break;
  3628.  
  3629.             /* Set the hotkey preferences. */
  3630.  
  3631.         case MEN_HOTKEYS:
  3632.  
  3633.             BlockWindows();
  3634.  
  3635.             if(HotkeyPanel(&Hotkeys))
  3636.             {
  3637.                 if(!SetupCx())
  3638.                     MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_SET_UP_HOTKEYS_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3639.             }
  3640.  
  3641.             ReleaseWindows();
  3642.  
  3643.             break;
  3644.  
  3645.             /* Set the speech preferences. */
  3646.  
  3647.         case MEN_SPEECH:
  3648.  
  3649.             BlockWindows();
  3650.  
  3651.             SpeechPanel();
  3652.  
  3653.             ReleaseWindows();
  3654.  
  3655.             break;
  3656.  
  3657.             /* Set the sound preferences. */
  3658.  
  3659.         case MEN_SOUND:
  3660.  
  3661.             BlockWindows();
  3662.  
  3663.             if(SoundPanel(&SoundConfig))
  3664.                 SoundInit();
  3665.  
  3666.             ReleaseWindows();
  3667.  
  3668.             break;
  3669.  
  3670.             /* Edit the phone number patterns and rates. */
  3671.  
  3672.             /* Edit the trap settings? */
  3673.  
  3674.         case MEN_RATES:
  3675.  
  3676.             BlockWindows();
  3677.  
  3678.             PatternPanel();
  3679.  
  3680.             ReleaseWindows();
  3681.  
  3682.             break;
  3683.  
  3684.             /* Open the preferences settings. */
  3685.  
  3686.         case MEN_OPEN_SETTINGS:
  3687.  
  3688.             BlockWindows();
  3689.  
  3690.             strcpy(DummyBuffer,LastConfig);
  3691.  
  3692.             DummyChar = PathPart(DummyBuffer);
  3693.  
  3694.             *DummyChar = 0;
  3695.  
  3696.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",FALSE,FALSE,FALSE,NULL,TRUE))
  3697.             {
  3698.                 if(ReadConfig(DummyBuffer,PrivateConfig))
  3699.                 {
  3700.                     SwapConfig(PrivateConfig,Config);
  3701.  
  3702.                     strcpy(DummyBuffer,LastConfig);
  3703.  
  3704.                     ConfigSetup();
  3705.  
  3706.                     ConfigChanged = FALSE;
  3707.                 }
  3708.                 else
  3709.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  3710.  
  3711.                 FreeAslRequest(FileRequest);
  3712.             }
  3713.  
  3714.             ReleaseWindows();
  3715.  
  3716.             break;
  3717.  
  3718.             /* Save the terminal preferences. */
  3719.  
  3720.         case MEN_SAVE_SETTINGS:
  3721.  
  3722.             if(LastConfig[0])
  3723.             {
  3724.                 BlockWindows();
  3725.  
  3726.                 if(!WriteConfig(LastConfig,Config))
  3727.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),LastConfig);
  3728.                 else
  3729.                     ConfigChanged = FALSE;
  3730.  
  3731.                 ReleaseWindows();
  3732.  
  3733.                 break;
  3734.             }
  3735.  
  3736.             /* Save the terminal preferences to a
  3737.              * given file name.
  3738.              */
  3739.  
  3740.         case MEN_SAVE_SETTINGS_AS:
  3741.  
  3742.             BlockWindows();
  3743.  
  3744.             strcpy(DummyBuffer,LastConfig);
  3745.  
  3746.             DummyChar = PathPart(DummyBuffer);
  3747.  
  3748.             *DummyChar = 0;
  3749.  
  3750.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",TRUE,FALSE,FALSE,NULL,TRUE))
  3751.             {
  3752.                 if(WriteConfig(DummyBuffer,Config))
  3753.                 {
  3754.                     strcpy(LastConfig,DummyBuffer);
  3755.  
  3756.                     ConfigChanged = FALSE;
  3757.                 }
  3758.                 else
  3759.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  3760.  
  3761.                 FreeAslRequest(FileRequest);
  3762.             }
  3763.  
  3764.             ReleaseWindows();
  3765.  
  3766.             break;
  3767.  
  3768.             /* Show terminal information window. */
  3769.  
  3770.         case MEN_STATUS_WINDOW:
  3771.  
  3772.             if(InfoWindow)
  3773.                 CloseInfoWindow();
  3774.             else
  3775.                 OpenInfoWindow();
  3776.  
  3777.             break;
  3778.  
  3779.         case MEN_REVIEW_WINDOW:
  3780.  
  3781.             if(ReviewWindow)
  3782.                 DeleteReview();
  3783.             else
  3784.                 CreateReview();
  3785.  
  3786.             break;
  3787.  
  3788.             /* Open the packet window if necessary, else
  3789.              * just activate it.
  3790.              */
  3791.  
  3792.         case MEN_PACKET_WINDOW:
  3793.  
  3794.             CreatePacketWindow();
  3795.             break;
  3796.  
  3797.             /* Toggle the presence of the fast! macro panel. */
  3798.  
  3799.         case MEN_FAST_MACROS_WINDOW:
  3800.  
  3801.             if(FastWindow)
  3802.                 CloseFastWindow();
  3803.             else
  3804.                 OpenFastWindow();
  3805.  
  3806.             break;
  3807.  
  3808.             /* Open the upload queue window. */
  3809.  
  3810.         case MEN_UPLOAD_QUEUE_WINDOW:
  3811.  
  3812.             CreateQueueProcess();
  3813.             break;
  3814.  
  3815.         default:if(Code >= DIAL_MENU_LIMIT)
  3816.             {
  3817.                 LONG Index = Code - DIAL_MENU_LIMIT;
  3818.  
  3819.                 if(!LocalDialList && !Online)
  3820.                 {
  3821.                     if(LocalDialList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
  3822.                     {
  3823.                         LONG i;
  3824.  
  3825.                             /* Clear previous list contents, we
  3826.                              * don't want to redial yet.
  3827.                              */
  3828.  
  3829.                         for(i = 0 ; i < NumPhoneEntries ; i++)
  3830.                             Phonebook[i] -> Count = -1;
  3831.  
  3832.                         NewList(LocalDialList);
  3833.                     }
  3834.                 }
  3835.  
  3836.                 if(Phonebook[Index] -> Count == -1)
  3837.                 {
  3838.                     if(LocalDialList)
  3839.                     {
  3840.                         struct PhoneNode *NewNode;
  3841.  
  3842.                             /* Create a new node to be added to the dial list. */
  3843.  
  3844.                         if(NewNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
  3845.                         {
  3846.                                 /* Take care of the name and the corresponding phone book entry. */
  3847.  
  3848.                             NewNode -> VanillaNode . ln_Name    = NewNode -> LocalName;
  3849.                             NewNode -> Entry            = Phonebook[Index];
  3850.  
  3851.                             Phonebook[Index] -> Count = ++LocalCount;
  3852.  
  3853.                             SPrintf(NewNode -> LocalName,"%3ld - %s",LocalCount + 1,Phonebook[Index] -> Header -> Name);
  3854.  
  3855.                                 /* Install back-link. */
  3856.  
  3857.                             NewNode -> Entry -> Node = NewNode;
  3858.  
  3859.                             AddTail(LocalDialList,&NewNode -> VanillaNode);
  3860.                         }
  3861.                     }
  3862.                 }
  3863.             }
  3864.  
  3865.             break;
  3866.     }
  3867. }
  3868.  
  3869.     /* HandleMenu(ULONG Code,ULONG Qualifier):
  3870.      *
  3871.      *    Skip along the number of selected menu items and
  3872.      *    handle the associated functions.
  3873.      */
  3874.  
  3875. VOID __regargs
  3876. HandleMenu(ULONG Code,ULONG Qualifier)
  3877. {
  3878.     struct MenuItem *MenuItem;
  3879.  
  3880.     DisplayReopened = FALSE;
  3881.  
  3882.         /* Check until the last menuitem has been
  3883.          * processed.
  3884.          */
  3885.  
  3886.     while(Code != MENUNULL)
  3887.     {
  3888.             /* Pick up the associated menu item. */
  3889.  
  3890.         if(MenuItem = ItemAddress(Menu,Code))
  3891.         {
  3892.             HandleMenuCode((ULONG)GTMENUITEM_USERDATA(MenuItem),Qualifier);
  3893.  
  3894.             if(Apocalypse)
  3895.                 return;
  3896.  
  3897.             if(DisplayReopened)
  3898.             {
  3899.                 DisplayReopened = FALSE;
  3900.  
  3901.                 return;
  3902.             }
  3903.  
  3904.             Code = MenuItem -> NextSelect;
  3905.         }
  3906.         else
  3907.             break;
  3908.     }
  3909.  
  3910.     HandleLocalDialList(FALSE);
  3911. }
  3912.  
  3913.     /* HandleWorkbenchWindow():
  3914.      *
  3915.      *    Handle input coming from the Workbench window.
  3916.      */
  3917.  
  3918. BYTE
  3919. HandleWorkbenchWindow()
  3920. {
  3921.     struct FileInfoBlock    *FileInfo;
  3922.     struct AppMessage    *AppMessage;
  3923.  
  3924.     if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  3925.     {
  3926.         struct FileTransferInfo *Info;
  3927.  
  3928.         if(Info = AllocFileTransferInfo())
  3929.         {
  3930.             LONG FilesFound = 0,i;
  3931.             BYTE Success = TRUE;
  3932.  
  3933.             while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
  3934.             {
  3935.                 if(Success && AppMessage -> am_Type == MTYPE_APPWINDOW)
  3936.                 {
  3937.                     for(i = 0 ; Success && i < AppMessage -> am_NumArgs ; i++)
  3938.                     {
  3939.                         if(AppMessage -> am_ArgList[i] . wa_Lock && AppMessage -> am_ArgList[i] . wa_Name)
  3940.                         {
  3941.                             BPTR OldLock;
  3942.  
  3943.                             if(OldLock = CurrentDir(AppMessage -> am_ArgList[i] . wa_Lock))
  3944.                             {
  3945.                                 BPTR FileLock;
  3946.  
  3947.                                 if(FileLock = Lock(AppMessage -> am_ArgList[i] . wa_Name,ACCESS_READ))
  3948.                                 {
  3949.                                     if(Examine(FileLock,FileInfo))
  3950.                                     {
  3951.                                         if(FileInfo -> fib_DirEntryType < 0)
  3952.                                         {
  3953.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  3954.                                             {
  3955.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  3956.                                                     Success = FALSE;
  3957.                                                 else
  3958.                                                 {
  3959.                                                     FilesFound++;
  3960.  
  3961.                                                     if(Config -> MiscConfig -> TransferIcons)
  3962.                                                     {
  3963.                                                         BPTR InfoLock;
  3964.  
  3965.                                                         strcat(SharedBuffer,".info");
  3966.  
  3967.                                                         if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
  3968.                                                         {
  3969.                                                             if(Examine(InfoLock,FileInfo))
  3970.                                                             {
  3971.                                                                 if(FileInfo -> fib_DirEntryType < 0)
  3972.                                                                 {
  3973.                                                                     if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  3974.                                                                         Success = FALSE;
  3975.                                                                     else
  3976.                                                                         FilesFound++;
  3977.                                                                 }
  3978.                                                             }
  3979.  
  3980.                                                             UnLock(InfoLock);
  3981.                                                         }
  3982.                                                     }
  3983.                                                 }
  3984.                                             }
  3985.                                         }
  3986.                                     }
  3987.  
  3988.                                     UnLock(FileLock);
  3989.                                 }
  3990.  
  3991.                                 CurrentDir(OldLock);
  3992.                             }
  3993.                         }
  3994.                     }
  3995.                 }
  3996.  
  3997.                 ReplyMsg((struct Message *)AppMessage);
  3998.             }
  3999.  
  4000.             if(FilesFound)
  4001.             {
  4002.                 SortFileTransferInfo(Info);
  4003.  
  4004.                 BlockWindows();
  4005.  
  4006.                 switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILES_AS_TXT),LocaleString(MSG_TERMMAIN_BINARY_UPLOAD_CANCEL_TXT)))
  4007.                 {
  4008.                     case 1:    BinaryTransfer        = TRUE;
  4009.                         FileTransferInfo    = Info;
  4010.  
  4011.                         StartXprSendFromList(TRANSFER_BINARY,TRUE);
  4012.  
  4013.                         break;
  4014.  
  4015.                     case 2:    BinaryTransfer        = FALSE;
  4016.                         FileTransferInfo    = Info;
  4017.  
  4018.                         StartXprSendFromList(TRANSFER_TEXT,TRUE);
  4019.  
  4020.                         break;
  4021.  
  4022.                     case 0:    FreeFileTransferInfo(Info);
  4023.                         break;
  4024.                 }
  4025.  
  4026.                 ReleaseWindows();
  4027.             }
  4028.         }
  4029.  
  4030.         FreeDosObject(DOS_FIB,FileInfo);
  4031.     }
  4032.  
  4033.     while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
  4034.         ReplyMsg((struct Message *)AppMessage);
  4035.  
  4036.     return(FALSE);
  4037. }
  4038.  
  4039.     /* HandleIconify():
  4040.      *
  4041.      *    Handle program iconification.
  4042.      */
  4043.  
  4044. VOID
  4045. HandleIconify()
  4046. {
  4047.     BYTE Released = FALSE;
  4048.  
  4049.         /* Set the wait mouse pointer... */
  4050.  
  4051.     BlockWindows();
  4052.  
  4053.         /* Open workbench.library. */
  4054.  
  4055.     if(WorkbenchBase)
  4056.     {
  4057.             /* Open icon.library. */
  4058.  
  4059.         if(IconBase)
  4060.         {
  4061.             struct DiskObject *Icon;
  4062.  
  4063.             if(!(Icon = GetProgramIcon()))
  4064.                 Icon = GetDefDiskObject(WBTOOL);
  4065.  
  4066.                 /* Did we get an icon? */
  4067.  
  4068.             if(Icon)
  4069.             {
  4070.                 struct MsgPort *IconPort;
  4071.  
  4072.                     /* Reset the icon type. */
  4073.  
  4074.                 Icon -> do_Type        = NULL;
  4075.  
  4076.                     /* Default icon position. */
  4077.  
  4078.                 Icon -> do_CurrentX    = NO_ICON_POSITION;
  4079.                 Icon -> do_CurrentY    = NO_ICON_POSITION;
  4080.  
  4081.                     /* Create the Workbench reply port. */
  4082.  
  4083.                 if(IconPort = CreateMsgPort())
  4084.                 {
  4085.                     struct AppIcon *AppIcon;
  4086.  
  4087.                         /* Add the application icon. */
  4088.  
  4089.                     if(AppIcon = AddAppIcon(0,0,TermIDString,IconPort,NULL,Icon,TAG_DONE))
  4090.                     {
  4091.                         struct AppMessage    *AppMessage;
  4092.                         UBYTE            *String,*Error;
  4093.                         ULONG             SignalSet;
  4094.  
  4095.                             /* Reset the guardian. */
  4096.  
  4097.                         IconTerminated = FALSE;
  4098.  
  4099.                             /* Release the window. */
  4100.  
  4101.                         Released = TRUE;
  4102.  
  4103.                         ReleaseWindows();
  4104.  
  4105.                         WindowBox . Left    = Window -> LeftEdge;
  4106.                         WindowBox . Top        = Window -> TopEdge;
  4107.                         WindowBox . Width    = Window -> Width;
  4108.                         WindowBox . Height    = Window -> Height;
  4109.  
  4110.                             /* Close the display. full stop. */
  4111.  
  4112.                         if(DeleteDisplay())
  4113.                         {
  4114.                                 /* Reset and release the serial driver. */
  4115.  
  4116.                             if(Config -> MiscConfig -> ReleaseDevice)
  4117.                             {
  4118.                                 ClearSerial();
  4119.  
  4120.                                 DeleteSerial();
  4121.                             }
  4122.  
  4123.                                 /* Wait for double-click. */
  4124.  
  4125. IconLoop:                        while(!IconTerminated)
  4126.                             {
  4127.                                 SignalSet = Wait(PORTMASK(IconPort) | SIG_REXX | SIGBREAKF_CTRL_F);
  4128.  
  4129.                                 if(SignalSet & PORTMASK(IconPort))
  4130.                                 {
  4131.                                         /* Pick up application messages. */
  4132.  
  4133.                                     while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  4134.                                     {
  4135.                                             /* Received a double-click? */
  4136.  
  4137.                                         IconTerminated = TRUE;
  4138.  
  4139.                                         ReplyMsg(AppMessage);
  4140.                                     }
  4141.                                 }
  4142.  
  4143.                                     /* Wake up if ARexx command received. */
  4144.  
  4145.                                 if(SignalSet & SIG_REXX)
  4146.                                     while(HandleRexx());
  4147.  
  4148.                                 if(SignalSet & SIGBREAKF_CTRL_F)
  4149.                                     IconTerminated = TRUE;
  4150.                             }
  4151.  
  4152.                                 /* Open the serial driver. */
  4153.  
  4154.                             if(Config -> MiscConfig -> ReleaseDevice)
  4155.                             {
  4156.                                 if(Error = CreateSerial())
  4157.                                 {
  4158.                                     DeleteSerial();
  4159.  
  4160.                                     switch(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_IGNORE_QUIT_TXT),Error))
  4161.                                     {
  4162.                                         case 1:    IconTerminated = FALSE;
  4163.                                             goto IconLoop;
  4164.  
  4165.                                         case 0:    MainTerminated = TRUE;
  4166.                                     }
  4167.                                 }
  4168.                                 else
  4169.                                 {
  4170.                                     if(SerialMessage)
  4171.                                     {
  4172.                                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  4173.  
  4174.                                         SerialMessage = NULL;
  4175.                                     }
  4176.                                 }
  4177.                             }
  4178.  
  4179.                             if(CantQuit && MainTerminated)
  4180.                                 MainTerminated = FALSE;
  4181.  
  4182.                                 /* Create the display. */
  4183.  
  4184.                             if(!MainTerminated)
  4185.                             {
  4186.                                 if(String = CreateDisplay(FALSE))
  4187.                                 {
  4188.                                     if(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_QUIT_TXT),String))
  4189.                                     {
  4190.                                         ClearSerial();
  4191.  
  4192.                                         DeleteSerial();
  4193.  
  4194.                                         IconTerminated = FALSE;
  4195.  
  4196.                                         goto IconLoop;
  4197.                                     }
  4198.                                     else
  4199.                                         MainTerminated = FALSE;
  4200.                                 }
  4201.                                 else
  4202.                                 {
  4203.                                     BumpWindow(Window);
  4204.  
  4205.                                     PubScreenStuff();
  4206.                                 }
  4207.                             }
  4208.                         }
  4209.                         else
  4210.                         {
  4211.                             BlockWindows();
  4212.  
  4213.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  4214.  
  4215.                             ReleaseWindows();
  4216.                         }
  4217.  
  4218.                             /* Remove the application icon. */
  4219.  
  4220.                         RemoveAppIcon(AppIcon);
  4221.  
  4222.                             /* Reply pending messages. */
  4223.  
  4224.                         while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  4225.                             ReplyMsg(AppMessage);
  4226.                     }
  4227.                     else
  4228.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_ADD_APPLICATION_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4229.  
  4230.                     DeleteMsgPort(IconPort);
  4231.                 }
  4232.                 else
  4233.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_CREATE_MSGPORT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4234.  
  4235.                 FreeDiskObject(Icon);
  4236.             }
  4237.             else
  4238.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_TOOL_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4239.         }
  4240.         else
  4241.             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_ICON_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4242.     }
  4243.     else
  4244.         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_WORKBENCH_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4245.  
  4246.     if(!Released)
  4247.         ReleaseWindows();
  4248.  
  4249.         /* Finished! */
  4250.  
  4251.     DoIconify = FALSE;
  4252. }
  4253.  
  4254.     /* HandleOnlineCleanup():
  4255.      *
  4256.      *    Perform offline cleanup tasks.
  4257.      */
  4258.  
  4259. VOID __regargs
  4260. HandleOnlineCleanup(BOOL Hangup)
  4261. {
  4262.     SoundPlay(SOUND_DISCONNECT);
  4263.  
  4264.         /* Execute logoff macro. */
  4265.  
  4266.     if(Config -> CommandConfig -> LogoffMacro[0] && WasOnline)
  4267.         SerialCommand(Config -> CommandConfig -> LogoffMacro);
  4268.  
  4269.     StopCall(FALSE);
  4270.  
  4271.     if(CurrentPay)
  4272.     {
  4273.         if(Hangup)
  4274.             LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_COST_TXT),CreateSum(CurrentPay,TRUE));
  4275.         else
  4276.             LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_COST_TXT),CreateSum(CurrentPay,TRUE));
  4277.     }
  4278.     else
  4279.     {
  4280.         if(Hangup)
  4281.             LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
  4282.         else
  4283.             LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
  4284.     }
  4285.  
  4286.     SetDialMenu(TRUE);
  4287.  
  4288.     if(!Hangup)
  4289.         Say(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
  4290.  
  4291.         /* Clear the password. */
  4292.  
  4293.     Password[0]        = 0;
  4294.     UserName[0]        = 0;
  4295.  
  4296.     CurrentBBSName[0]    = 0;
  4297.     CurrentBBSComment[0]    = 0;
  4298.     CurrentBBSNumber[0]    = 0;
  4299.  
  4300.     ObtainSemaphore(&OnlineSemaphore);
  4301.  
  4302.     if(!Config -> SerialConfig -> CheckCarrier)
  4303.         Online = WasOnline = FALSE;
  4304.  
  4305.     ReleaseSemaphore(&OnlineSemaphore);
  4306.  
  4307.     ObtainSemaphore(&PatternSemaphore);
  4308.  
  4309.     ChosenEntry    = NULL;
  4310.     ChosenPattern    = NULL;
  4311.  
  4312.     ReleaseSemaphore(&PatternSemaphore);
  4313.  
  4314.     LimitCount = -1;
  4315.  
  4316.         /* Previous configuration available? */
  4317.  
  4318.     if(BackupConfig)
  4319.     {
  4320.             /* Remember old configuration. */
  4321.  
  4322.         SaveConfig(Config,PrivateConfig);
  4323.  
  4324.             /* Copy configuration. */
  4325.  
  4326.         SaveConfig(BackupConfig,Config);
  4327.  
  4328.             /* Set up new configuration. */
  4329.  
  4330.         ConfigSetup();
  4331.  
  4332.             /* Free old configuration. */
  4333.  
  4334.         DeleteConfiguration(BackupConfig);
  4335.  
  4336.         BackupConfig = NULL;
  4337.     }
  4338.  
  4339.     if(!ResetDisplay)
  4340.     {
  4341.             /* Reset the text rendering styles, font, etc. in
  4342.              * order to keep the following text from getting
  4343.              * illegible.
  4344.              */
  4345.  
  4346.         SoftReset();
  4347.  
  4348.             /* Display how much we expect
  4349.              * the user will have to pay for
  4350.              * this call.
  4351.              */
  4352.  
  4353.         ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  4354.  
  4355.         CurrentPay = 0;
  4356.     }
  4357.  
  4358.     if(Config -> ModemConfig -> RedialAfterHangup)
  4359.     {
  4360.         if(DialList)
  4361.         {
  4362.             if(DialList -> lh_Head -> ln_Succ)
  4363.             {
  4364.                 Online = WasOnline = FALSE;
  4365.  
  4366.                 DoDial = DIAL_REDIAL;
  4367.             }
  4368.         }
  4369.     }
  4370. }
  4371.  
  4372.     /* HandleFlowChange():
  4373.      *
  4374.      *    Handle data flow scanner information.
  4375.      */
  4376.  
  4377. VOID
  4378. HandleFlowChange()
  4379. {
  4380.     if(Online)
  4381.     {
  4382.         if(FlowInfo . NoCarrier)
  4383.         {
  4384.             if(Config -> SerialConfig -> CheckCarrier)
  4385.             {
  4386.                     /* Is the carrier still present? */
  4387.  
  4388.                 if(!(GetSerialStatus() & CIAF_COMCD))    // = Carrier detected
  4389.                     FlowInfo . NoCarrier = FALSE;
  4390.             }
  4391.  
  4392.             if(FlowInfo . NoCarrier)
  4393.             {
  4394.                 ObtainSemaphore(&OnlineSemaphore);
  4395.  
  4396.                 WasOnline    = Online;
  4397.                 Online        = FALSE;
  4398.  
  4399.                 ReleaseSemaphore(&OnlineSemaphore);
  4400.             }
  4401.         }
  4402.     }
  4403.     else
  4404.     {
  4405.         if(FlowInfo . Voice)
  4406.         {
  4407.             UBYTE DateTimeBuffer[256];
  4408.  
  4409.             FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
  4410.  
  4411.             WakeUp(Window,SOUND_VOICE);
  4412.  
  4413.             ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_VOIC_CALL_TXT),DateTimeBuffer);
  4414.  
  4415.             Say(LocaleString(MSG_TERMMAIN_SAY_INCOMING_VOICE_CALL_TXT));
  4416.         }
  4417.  
  4418.         if(FlowInfo . Ring)
  4419.         {
  4420.             UBYTE DateTimeBuffer[256];
  4421.  
  4422.             FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
  4423.  
  4424.             WakeUp(Window,SOUND_RING);
  4425.  
  4426.             ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_CALL_TXT),DateTimeBuffer);
  4427.  
  4428.             Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  4429.         }
  4430.  
  4431.         if(FlowInfo . Connect)
  4432.         {
  4433.                 /* Are we to check the carrier signal? */
  4434.  
  4435.             if(Config -> SerialConfig -> CheckCarrier)
  4436.             {
  4437.                     /* No carrier signal present? */
  4438.  
  4439.                 if(GetSerialStatus() & CIAF_COMCD)    // = Carrier lost
  4440.                     FlowInfo . Connect = FALSE;
  4441.             }
  4442.  
  4443.             if(FlowInfo . Connect)
  4444.             {
  4445.                 WakeUp(Window,SOUND_CONNECT);
  4446.  
  4447.                 ObtainSemaphore(&OnlineSemaphore);
  4448.  
  4449.                 WasOnline    = Online;
  4450.                 Online        = TRUE;
  4451.                 BaudPending    = FALSE;
  4452.  
  4453.                 ReleaseSemaphore(&OnlineSemaphore);
  4454.  
  4455.                 SetDialMenu(FALSE);
  4456.             }
  4457.         }
  4458.     }
  4459.  
  4460.         /* Check if we are to prompt the user for
  4461.          * ZModem upload type.
  4462.          */
  4463.  
  4464.     if(UsesZModem && FlowInfo . ZModemUpload && XProtocolBase)
  4465.     {
  4466.         if(Config -> MiscConfig -> AutoUpload)
  4467.         {
  4468.             BlockWindows();
  4469.  
  4470.             switch(UploadPanel())
  4471.             {
  4472.                 case UPLOAD_TEXT:
  4473.  
  4474.                     BinaryTransfer = FALSE;
  4475.  
  4476.                     if(!StartXprSend(TRANSFER_TEXT,TRUE))
  4477.                         SerWrite(ZModemCancel,20);
  4478.  
  4479.                     break;
  4480.  
  4481.                 case UPLOAD_BINARY:
  4482.  
  4483.                     BinaryTransfer = TRUE;
  4484.  
  4485.                     if(!StartXprSend(TRANSFER_BINARY,TRUE))
  4486.                         SerWrite(ZModemCancel,20);
  4487.  
  4488.                     break;
  4489.  
  4490.                 case UPLOAD_ABORT:
  4491.  
  4492.                     SerWrite(ZModemCancel,20);
  4493.                     break;
  4494.  
  4495.                 case UPLOAD_BINARY_FROM_LIST:
  4496.  
  4497.                     StartUpload(UPLOAD_BINARY);
  4498.                     break;
  4499.  
  4500.                 case UPLOAD_TEXT_FROM_LIST:
  4501.  
  4502.                     StartUpload(UPLOAD_TEXT);
  4503.                     break;
  4504.             }
  4505.  
  4506.             ReleaseWindows();
  4507.         }
  4508.     }
  4509.  
  4510.     FlowInit(TRUE);
  4511. }
  4512.  
  4513.     /* HandleSerialReset():
  4514.      *
  4515.      *    Handle serial device reset.
  4516.      */
  4517.  
  4518. VOID
  4519. HandleSerialReset()
  4520. {
  4521.     ClearSerial();
  4522.  
  4523.     DeleteSerial();
  4524.  
  4525.     BlockWindows();
  4526.  
  4527.     ReopenSerial();
  4528.  
  4529.     ReleaseWindows();
  4530. }
  4531.  
  4532.     /* HandleSerialRelease():
  4533.      *
  4534.      *    Release the serial device driver, then reopen it again.
  4535.      */
  4536.  
  4537. VOID
  4538. HandleSerialRelease()
  4539. {
  4540.     APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  4541.     BYTE    Continue,SerialClosed;
  4542.  
  4543.     ThisProcess -> pr_WindowPtr = (APTR)Window;
  4544.  
  4545.         /* This might happen if an ARexx user
  4546.          * released the serial device and
  4547.          * failed to reopen it.
  4548.          */
  4549.  
  4550.     if(ReadPort)
  4551.         SerialClosed = FALSE;
  4552.     else
  4553.         SerialClosed = TRUE;
  4554.  
  4555.     BlockWindows();
  4556.  
  4557.         /* Prevent catastrophes! */
  4558.  
  4559.     if(Online && !SerialClosed)
  4560.     {
  4561.         if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  4562.             Continue = FALSE;
  4563.         else
  4564.             Continue = TRUE;
  4565.     }
  4566.     else
  4567.         Continue = TRUE;
  4568.  
  4569.     if(Continue)
  4570.     {
  4571.         if(SerialClosed)
  4572.             ReopenSerial();
  4573.         else
  4574.         {
  4575.             ClearSerial();
  4576.  
  4577.             DeleteSerial();
  4578.  
  4579.             if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNIT_RESET_AND_RELEASED_TXT),LocaleString(MSG_TERMMAIN_RETURN_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
  4580.                 ReopenSerial();
  4581.             else
  4582.                 MainTerminated = TRUE;
  4583.         }
  4584.     }
  4585.  
  4586.     ReleaseSerial = FALSE;
  4587.  
  4588.     ThisProcess -> pr_WindowPtr = OldPtr;
  4589.  
  4590.     ReleaseWindows();
  4591. }
  4592.  
  4593.     /* HandleExternalEmulation():
  4594.      *
  4595.      *    Handle external emulation event.
  4596.      */
  4597.  
  4598. VOID
  4599. HandleExternalEmulation()
  4600. {
  4601.     if(!XEmulatorSignal(XEM_IO,XEM_Signal))
  4602.     {
  4603.         CloseEmulator();
  4604.  
  4605.         ResetDisplay = TRUE;
  4606.     }
  4607. }
  4608.  
  4609.     /* HandleSerialCheck():
  4610.      *
  4611.      *    Handle routine checkup actions.
  4612.      */
  4613.  
  4614. BYTE
  4615. HandleSerialCheck()
  4616. {
  4617.         /* Take a look at the carrier signal. */
  4618.  
  4619.     if(Config -> SerialConfig -> CheckCarrier && WriteRequest)
  4620.     {
  4621.         register UWORD Status = GetSerialStatus();
  4622.  
  4623.             /* Still online? */
  4624.  
  4625.         if(Online)
  4626.         {
  4627.                 /* Carrier detect signal lost? */
  4628.  
  4629.             if(Status & CIAF_COMCD)    // = Carrier lost
  4630.             {
  4631.                 ObtainSemaphore(&OnlineSemaphore);
  4632.  
  4633.                 WasOnline    = Online;
  4634.                 Online        = FALSE;
  4635.  
  4636.                 ReleaseSemaphore(&OnlineSemaphore);
  4637.             }
  4638.         }
  4639.         else
  4640.         {
  4641.                 /* Is the carrier detect signal
  4642.                  * present?
  4643.                  */
  4644.  
  4645.             if(!(Status & CIAF_COMCD))    // = Carrier detected
  4646.             {
  4647.                 ObtainSemaphore(&OnlineSemaphore);
  4648.  
  4649.                 WasOnline        = Online;
  4650.                 Online            = TRUE;
  4651.  
  4652.                 ReleaseSemaphore(&OnlineSemaphore);
  4653.  
  4654.                 BaudCount        = 0;
  4655.                 BaudBuffer[0]        = 0;
  4656.                 BaudPending        = FALSE;
  4657.  
  4658.                 CurrentPay        = 0;
  4659.  
  4660.                 ObtainSemaphore(&PatternSemaphore);
  4661.  
  4662.                 ChosenEntry        = NULL;
  4663.                 ChosenPattern        = NULL;
  4664.  
  4665.                 ReleaseSemaphore(&PatternSemaphore);
  4666.  
  4667.                 Password[0]        = 0;
  4668.                 UserName[0]        = 0;
  4669.  
  4670.                 SendStartup        = FALSE;
  4671.  
  4672.                 LimitCount        = -1;
  4673.  
  4674.                 CurrentBBSName[0]    = 0;
  4675.                 CurrentBBSComment[0]    = 0;
  4676.                 CurrentBBSNumber[0]    = 0;
  4677.  
  4678.                 SetDialMenu(FALSE);
  4679.             }
  4680.         }
  4681.     }
  4682.  
  4683.         /* Check online time limit. */
  4684.  
  4685.     if(!LimitCount)
  4686.     {
  4687.         LimitCount = -1;
  4688.  
  4689.         BlockWindows();
  4690.  
  4691.         SendARexxCommand(LimitMacro);
  4692.  
  4693.         ReleaseWindows();
  4694.     }
  4695.  
  4696.         /* Flush capture file contents to disk,
  4697.          * this routine is executed each minute
  4698.          * in order to store the captured data.
  4699.          */
  4700.  
  4701.     if(BufferFlushCount-- <= 0)
  4702.     {
  4703.         BufferFlushCount = 60;
  4704.  
  4705.             /* Flush the capture file. */
  4706.  
  4707.         if(FileCapture)
  4708.             BufferFlush(FileCapture);
  4709.     }
  4710.  
  4711.     return(FALSE);
  4712. }
  4713.  
  4714.     /* HandleQueueMsg():
  4715.      *
  4716.      *    Process the special message queue.
  4717.      */
  4718.  
  4719. BYTE
  4720. HandleQueueMsg()
  4721. {
  4722.     struct DataMsg *Item;
  4723.  
  4724.     if(Item = GetMsgItem(SpecialQueue))
  4725.     {
  4726.         struct FileTransferInfo *Info;
  4727.         BYTE             OldEcho;
  4728.  
  4729.         switch(Item -> Type)
  4730.         {
  4731.                 // Output data.
  4732.  
  4733.             case DATAMSGTYPE_WRITE:
  4734.  
  4735.                 SerWrite(Item -> Data,Item -> Size);
  4736.                 break;
  4737.  
  4738.                 // Execute a command.
  4739.  
  4740.             case DATAMSGTYPE_SERIALCOMMAND:
  4741.  
  4742.                 SerialCommand(Item -> Data);
  4743.                 break;
  4744.  
  4745.                 // Execute a command, but don't echo it.
  4746.  
  4747.             case DATAMSGTYPE_SERIALCOMMANDNOECHO:
  4748.  
  4749.                 OldEcho = Config -> SerialConfig -> Duplex;
  4750.  
  4751.                 Config -> SerialConfig -> Duplex = DUPLEX_FULL;
  4752.  
  4753.                 SerialCommand(Item -> Data);
  4754.  
  4755.                 Config -> SerialConfig -> Duplex = OldEcho;
  4756.                 break;
  4757.  
  4758.                 // Output contents of clipboard
  4759.  
  4760.             case DATAMSGTYPE_WRITECLIP:
  4761.  
  4762.                 if(!ClipInput)
  4763.                 {
  4764.                     if(!OpenClip(Item -> Size))
  4765.                         ClipInput = ClipXerox = TRUE;
  4766.                     else
  4767.                         ClipInput = ClipXerox = FALSE;
  4768.                 }
  4769.  
  4770.                     /* Are we reading input from the clipboard? */
  4771.  
  4772.                 if(ClipInput)
  4773.                 {
  4774.                     UBYTE    InputBuffer[257];
  4775.                     WORD    Len;
  4776.  
  4777.                     if((Len = GetClip(InputBuffer,256,TRUE)) < 0)
  4778.                     {
  4779.                         CloseClip();
  4780.  
  4781.                         ClipInput = FALSE;
  4782.  
  4783.                         if(ClipXerox)
  4784.                         {
  4785.                             if(Config -> ClipConfig -> InsertSuffix[0])
  4786.                                 SerialCommand(Config -> ClipConfig -> InsertSuffix);
  4787.  
  4788.                             ClipXerox = FALSE;
  4789.                         }
  4790.  
  4791.                         ClipPrefix = FALSE;
  4792.                     }
  4793.                     else
  4794.                     {
  4795.                         if(!ClipPrefix && ClipXerox)
  4796.                         {
  4797.                             if(Config -> ClipConfig -> InsertPrefix[0])
  4798.                                 SerialCommand(Config -> ClipConfig -> InsertPrefix);
  4799.  
  4800.                             ClipPrefix = TRUE;
  4801.                         }
  4802.  
  4803.                         if(Len > 0)
  4804.                             SendInputTextBuffer(InputBuffer,Len,FALSE);
  4805.                     }
  4806.                 }
  4807.  
  4808.                 break;
  4809.  
  4810.                 // Start an upload
  4811.  
  4812.             case DATAMSGTYPE_UPLOAD:
  4813.  
  4814.                 if(((struct List *)Item -> Data) -> lh_Head -> ln_Succ)
  4815.                 {
  4816.                     if(Info = AllocFileTransferInfo())
  4817.                     {
  4818.                         struct FileInfoBlock *FileInfo;
  4819.                         LONG FilesFound = 0,Type = Item -> Size;
  4820.  
  4821.                         if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  4822.                         {
  4823.                             BPTR FileLock;
  4824.                             struct List *List;
  4825.                             struct Node *Node,*Next;
  4826.                             APTR OldPtr = ThisProcess -> pr_WindowPtr;
  4827.  
  4828.                             ThisProcess -> pr_WindowPtr = (APTR)-1;
  4829.  
  4830.                             List = (struct List *)Item -> Data;
  4831.  
  4832.                             for(Node = List -> lh_Head ; Next = Node -> ln_Succ ; Node = Next)
  4833.                             {
  4834.                                 if(FileLock = Lock(Node -> ln_Name,ACCESS_READ))
  4835.                                 {
  4836.                                     if(Examine(FileLock,FileInfo))
  4837.                                     {
  4838.                                         if(FileInfo -> fib_DirEntryType < 0)
  4839.                                         {
  4840.                                             if(AddFileTransferNode(Info,Node -> ln_Name,FileInfo -> fib_Size))
  4841.                                                 FilesFound++;
  4842.  
  4843.                                             if(Config -> MiscConfig -> TransferIcons)
  4844.                                             {
  4845.                                                 BPTR InfoLock;
  4846.  
  4847.                                                 strcpy(SharedBuffer,Node -> ln_Name);
  4848.  
  4849.                                                 strcat(SharedBuffer,".info");
  4850.  
  4851.                                                 if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
  4852.                                                 {
  4853.                                                     if(Examine(InfoLock,FileInfo))
  4854.                                                     {
  4855.                                                         if(FileInfo -> fib_DirEntryType < 0)
  4856.                                                         {
  4857.                                                             if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4858.                                                                 FilesFound++;
  4859.                                                         }
  4860.                                                     }
  4861.  
  4862.                                                     UnLock(InfoLock);
  4863.                                                 }
  4864.                                             }
  4865.  
  4866.                                             Remove(Node);
  4867.  
  4868.                                             FreeVecPooled(Node);
  4869.                                         }
  4870.                                     }
  4871.  
  4872.                                     UnLock(FileLock);
  4873.                                 }
  4874.                             }
  4875.  
  4876.                             ThisProcess -> pr_WindowPtr = OldPtr;
  4877.  
  4878.                             FreeDosObject(DOS_FIB,FileInfo);
  4879.                         }
  4880.  
  4881.                         DeleteMsgItem(Item);
  4882.  
  4883.                         Item = NULL;
  4884.  
  4885.                         if(FilesFound)
  4886.                         {
  4887.                             BlockWindows();
  4888.  
  4889.                             SortFileTransferInfo(Info);
  4890.  
  4891.                             switch(Type)
  4892.                             {
  4893.                                 case UPLOAD_BINARY:
  4894.  
  4895.                                     BinaryTransfer        = TRUE;
  4896.                                     FileTransferInfo    = Info;
  4897.  
  4898.                                     StartXprSendFromList(TRANSFER_BINARY,TRUE);
  4899.  
  4900.                                     break;
  4901.  
  4902.                                 case UPLOAD_TEXT:
  4903.  
  4904.                                     BinaryTransfer        = FALSE;
  4905.                                     FileTransferInfo    = Info;
  4906.  
  4907.                                     StartXprSendFromList(TRANSFER_TEXT,TRUE);
  4908.  
  4909.                                     break;
  4910.                             }
  4911.  
  4912.                             ReleaseWindows();
  4913.                         }
  4914.                         else
  4915.                             FreeFileTransferInfo(Info);
  4916.                     }
  4917.                 }
  4918.                 else
  4919.                 {
  4920.                     UBYTE Type = Item -> Size;
  4921.  
  4922.                     DeleteMsgItem(Item);
  4923.  
  4924.                     Item = NULL;
  4925.  
  4926.                     if(Type == UPLOAD_BINARY)
  4927.                     {
  4928.                         BinaryTransfer = TRUE;
  4929.  
  4930.                         if(!StartXprSend(TRANSFER_BINARY,TRUE))
  4931.                             SerWrite(ZModemCancel,20);
  4932.                     }
  4933.                     else
  4934.                     {
  4935.                         BinaryTransfer = FALSE;
  4936.  
  4937.                         if(!StartXprSend(TRANSFER_TEXT,TRUE))
  4938.                             SerWrite(ZModemCancel,20);
  4939.                     }
  4940.                 }
  4941.  
  4942.                 break;
  4943.  
  4944.                 // ARexx script execution finished.
  4945.  
  4946.             case DATAMSGTYPE_COMMANDDONE:
  4947.  
  4948.                 if(CantQuit > 0)
  4949.                     CantQuit--;
  4950.  
  4951.                 BumpWindow(Window);
  4952.  
  4953.                 ReleaseWindows();
  4954.  
  4955.                 break;
  4956.  
  4957.                 // Call a menu item
  4958.  
  4959.             case DATAMSGTYPE_MENU:
  4960.  
  4961.                 HandleMenuCode((ULONG)Item -> Size,(ULONG)Item -> Data);
  4962.  
  4963.                 break;
  4964.  
  4965.                 // Rendezvous with external process
  4966.  
  4967.             case DATAMSGTYPE_RENDEZVOUS:
  4968.  
  4969.                 if(ReadRequest && WriteRequest)
  4970.                 {
  4971.                         // Abort serial I/O processing
  4972.  
  4973.                     ClearSerial();
  4974.  
  4975.                     BlockWindows();
  4976.  
  4977.                         // Return the message, caution, we're not ready yet
  4978.  
  4979.                     Forbid();
  4980.  
  4981.                     DeleteMsgItem(Item);
  4982.  
  4983.                     Item = NULL;
  4984.  
  4985.                         // Prepare to wait...
  4986.  
  4987.                     ClrSignal(SIG_HANDSHAKE);
  4988.  
  4989.                     Wait(SIG_HANDSHAKE);
  4990.  
  4991.                         // Pick up the queue
  4992.  
  4993.                     RestartSerial(FALSE);
  4994.  
  4995.                     Permit();
  4996.  
  4997.                     ReleaseWindows();
  4998.                 }
  4999.  
  5000.                 break;
  5001.         }
  5002.  
  5003.         if(Item)
  5004.             DeleteMsgItem(Item);
  5005.  
  5006.         return(TRUE);
  5007.     }
  5008.     else
  5009.         return(FALSE);
  5010. }
  5011.  
  5012.     /* HandleOwnDevUnit():
  5013.      *
  5014.      *    Deal with the OwnDevUnit signal notification.
  5015.      */
  5016.  
  5017. BYTE
  5018. HandleOwnDevUnit()
  5019. {
  5020.     if(!Online || !ReadPort)
  5021.         HandleSerialRelease();
  5022.  
  5023.     return(FALSE);
  5024. }
  5025.