home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  104.4 KB  |  5,666 lines

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