home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 500-599 / ff589.lza / Term / TermSrc.lha / termMain.c < prev    next >
C/C++ Source or Header  |  1991-12-08  |  50KB  |  2,503 lines

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