home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / comm / term23_2.lha / Source_Code / termSource / termConsole.c < prev    next >
C/C++ Source or Header  |  1992-08-18  |  30KB  |  1,818 lines

  1. /*
  2. **    $Id: termConsole.c,v 1.4 92/08/15 20:13:46 olsen Sta Locker: olsen $
  3. **    $Revision: 1.4 $
  4. **    $Date: 92/08/15 20:13:46 $
  5. **
  6. **    High-level console control routines
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* StripSequence():
  15.      *
  16.      *    Strips a string from ESC and CSI introduced control
  17.      *    sequences.
  18.      */
  19.  
  20. STATIC LONG __regargs
  21. StripSequence(UBYTE *Src,UBYTE *Dst,LONG Length)
  22. {
  23.     STATIC BYTE    HasESC = FALSE,HasCSI = FALSE;
  24.     LONG        Size = 0;
  25.  
  26.     while(Length--)
  27.     {
  28.         if(HasESC)
  29.         {
  30.             if(*Src == '[')
  31.             {
  32.                 HasESC = FALSE;
  33.                 HasCSI = TRUE;
  34.             }
  35.             else
  36.             {
  37.                 if(*Src >= '0')
  38.                     HasESC = FALSE;
  39.             }
  40.  
  41.             Src++;
  42.  
  43.             continue;
  44.         }
  45.  
  46.         if(HasCSI)
  47.         {
  48.             if(*Src >= '@')
  49.                 HasCSI = FALSE;
  50.  
  51.             Src++;
  52.  
  53.             continue;
  54.         }
  55.  
  56.         switch(*Src)
  57.         {
  58.             case CAN:
  59.             case SUB:    HasESC = HasCSI = FALSE;
  60.  
  61.                     Src++;
  62.  
  63.                     break;
  64.  
  65.             case '\r':    Src++;
  66.  
  67.                     break;
  68.  
  69.             case ESC:    HasESC = TRUE;
  70.  
  71.                     Src++;
  72.  
  73.                     break;
  74.  
  75.             case CSI:    HasCSI = TRUE;
  76.  
  77.                     Src++;
  78.  
  79.                     break;
  80.  
  81.             default:    if(!ValidTab[*Src])
  82.                         Src++;
  83.                     else
  84.                     {
  85.                         *Dst++ = *Src++;
  86.  
  87.                         Size++;
  88.                     }
  89.  
  90.                     break;
  91.         }
  92.     }
  93.  
  94.     return(Size);
  95. }
  96.  
  97.     /* CaptureToFile(APTR Buffer,LONG Size):
  98.      *
  99.      *    Send data to the capture file.
  100.      */
  101.  
  102. VOID __regargs
  103. CaptureToFile(APTR Buffer,LONG Size)
  104. {
  105.     if(FileCapture && Size)
  106.     {
  107.         struct MenuItem    *SomeItem;
  108.  
  109.         if(BufferWrite(FileCapture,Buffer,Size) != Size)
  110.         {
  111.             BlockWindows();
  112.  
  113.                 /* We had an error writing to the file. */
  114.  
  115.             switch(MyEasyRequest(NULL,LocaleString(MSG_CONSOLE_ERROR_WRITING_TO_CAPTURE_FILE_TXT),LocaleString(MSG_CONSOLE_IGNORE_DISCARD_CLOSE_TXT),CaptureName))
  116.             {
  117.                 case 0:    break;
  118.  
  119.                 case 1:    BufferClose(FileCapture);
  120.  
  121.                     DeleteFile(CaptureName);
  122.  
  123.                     if(SomeItem = FindThisItem(MEN_CAPTURE_TO_FILE))
  124.                         SomeItem -> Flags &= ~CHECKED;
  125.  
  126.                     FileCapture = NULL;
  127.  
  128.                     break;
  129.  
  130.                 case 2:    BufferClose(FileCapture);
  131.  
  132.                     if(SomeItem = FindThisItem(MEN_CAPTURE_TO_FILE))
  133.                         SomeItem -> Flags &= ~CHECKED;
  134.  
  135.                     FileCapture = NULL;
  136.  
  137.                     if(!GetFileSize(CaptureName))
  138.                         DeleteFile(CaptureName);
  139.                     else
  140.                         SetProtection(CaptureName,FIBF_EXECUTE);
  141.  
  142.                     break;
  143.             }
  144.  
  145.             ReleaseWindows();
  146.         }
  147.     }
  148. }
  149.  
  150.     /* Capture(APTR Buffer,LONG Size):
  151.      *
  152.      *    Send the buffer contents to the display/disk capture.
  153.      */
  154.  
  155. VOID __regargs
  156. Capture(APTR Buffer,LONG Size)
  157. {
  158.     struct MenuItem *SomeItem;
  159.  
  160.         /* Send the filtered data to the capture file. */
  161.  
  162.     if(Config . CaptureFilter)
  163.         CaptureToFile(Buffer,Size);
  164.  
  165.         /* Store data in the log book. */
  166.  
  167.     if(!BufferFrozen)
  168.         StoreBuffer(Buffer,Size);
  169.  
  170.         /* Send the buffer to the printer. */
  171.  
  172.     if(PrinterCapture && Size)
  173.     {
  174.         if(!FWrite(PrinterCapture,Buffer,Size,1))
  175.         {
  176.             BlockWindows();
  177.  
  178.             if(!MyEasyRequest(Window,LocaleString(MSG_CONSOLE_ERROR_WRITING_TO_PRINTER_TXT),LocaleString(MSG_CONSOLE_IGNORE_CLOSE_PRINTER_TXT)))
  179.             {
  180.                 Close(PrinterCapture);
  181.  
  182.                 if(SomeItem = FindThisItem(MEN_CAPTURE_TO_PRINTER))
  183.                     SomeItem -> Flags &= ~CHECKED;
  184.  
  185.                 PrinterCapture = NULL;
  186.             }
  187.  
  188.             ReleaseWindows();
  189.         }
  190.     }
  191. }
  192.  
  193.     /* ClosePrinterCapture(BYTE Force):
  194.      *
  195.      *    Closes printer capture file.
  196.      */
  197.  
  198. VOID
  199. ClosePrinterCapture(BYTE Force)
  200. {
  201.     struct MenuItem *Item = FindThisItem(MEN_CAPTURE_TO_PRINTER);
  202.  
  203.     if(PrinterCapture)
  204.     {
  205.         if(ControllerActive && StandardPrinterCapture && !Force)
  206.             FPrintf(PrinterCapture,LocaleString(MSG_CONSOLE_TERMINAL_TRANSCRIPT_ENDING_TXT));
  207.  
  208.         if(Force)
  209.         {
  210.             Close(PrinterCapture);
  211.  
  212.             Item -> Flags &= ~CHECKED;
  213.  
  214.             PrinterCapture = NULL;
  215.  
  216.             StandardPrinterCapture = FALSE;
  217.         }
  218.     }
  219.  
  220.     ControllerActive = FALSE;
  221. }
  222.  
  223.     /* OpenPrinterCapture(BYTE Controller):
  224.      *
  225.      *    Opens printer capture file.
  226.      */
  227.  
  228. BYTE
  229. OpenPrinterCapture(BYTE Controller)
  230. {
  231.     if(PrinterCapture)
  232.     {
  233.         if(Controller && !ControllerActive)
  234.         {
  235.             ControllerActive = TRUE;
  236.  
  237.             FPrintf(PrinterCapture,LocaleString(MSG_CONSOLE_TERMINAL_TRANSCRIPT_FOLLOWS_TXT));
  238.         }
  239.  
  240.         return(TRUE);
  241.     }
  242.     else
  243.     {
  244.         struct MenuItem *Item = FindThisItem(MEN_CAPTURE_TO_PRINTER);
  245.  
  246.         if(PrinterCapture = Open("PRT:",MODE_NEWFILE))
  247.             Item -> Flags |= CHECKED;
  248.         else
  249.         {
  250.             Item -> Flags &= ~CHECKED;
  251.  
  252.             BlockWindows();
  253.  
  254.             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_ERROR_OPENING_PRINTER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  255.  
  256.             ReleaseWindows();
  257.         }
  258.  
  259.         if(Controller)
  260.         {
  261.             ControllerActive    = TRUE;
  262.             StandardPrinterCapture    = FALSE;
  263.         }
  264.         else
  265.         {
  266.             StandardPrinterCapture = FALSE;
  267.  
  268.             if(ControllerActive)
  269.                 FPrintf(PrinterCapture,LocaleString(MSG_CONSOLE_USER_TERMINAL_TRANSCRIPT_FOLLOWS_TXT));
  270.         }
  271.  
  272.         if(PrinterCapture)
  273.             return(TRUE);
  274.         else
  275.             return(FALSE);
  276.     }
  277. }
  278.  
  279.     /* PrintRegion(WORD Top,WORD Bottom):
  280.      *
  281.      *    Print the contents of a screen region.
  282.      */
  283.  
  284. VOID
  285. PrintRegion(WORD Top,WORD Bottom)
  286. {
  287.     BPTR     SomeFile;
  288.     WORD     i,j;
  289.     UBYTE    *Buffer;
  290.  
  291.     if(PrinterCapture)
  292.     {
  293.         if(!FPrintf(PrinterCapture,LocaleString(MSG_CONSOLE_SCREEN_PRINTOUT_FOLLOWS_TXT)))
  294.         {
  295.             MyEasyRequest(Window,LocaleString(MSG_CONSOLE_ERROR_WRITING_TO_PRINTER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  296.  
  297.             return;
  298.         }
  299.  
  300.         SomeFile = PrinterCapture;
  301.     }
  302.     else
  303.     {
  304.         if(!(SomeFile = Open("PRT:",MODE_NEWFILE)))
  305.         {
  306.             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_PRINTER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  307.  
  308.             return;
  309.         }
  310.     }
  311.  
  312.     for(i = Top ; i < Bottom ; i++)
  313.     {
  314.         Buffer = &Raster[i * RasterWidth];
  315.  
  316.         j = LastColumn;
  317.  
  318.         while(j >= 0 && Buffer[j] == ' ')
  319.             j--;
  320.  
  321.         if(j >= 0)
  322.         {
  323.             if(!FWrite(SomeFile,Buffer,j + 1,1))
  324.                 break;
  325.         }
  326.  
  327.         if(!FWrite(SomeFile,"\n",1,1))
  328.             break;
  329.     }
  330.  
  331.     if(PrinterCapture)
  332.         FPrintf(PrinterCapture,LocaleString(MSG_CONSOLE_SCREEN_PRINTOUT_ENDING_TXT));
  333.     else
  334.         Close(SomeFile);
  335. }
  336.  
  337.     /* HandleCursor(UBYTE Char):
  338.      *
  339.      *    This routine handles the somewhat strange behaviour of
  340.      *    an assorted set of keys in VT100 applications mode.
  341.      */
  342.  
  343. BYTE __regargs
  344. HandleCursor(UBYTE Char)
  345. {
  346.     STATIC struct
  347.     {
  348.         UBYTE     Char;
  349.         UBYTE    *VanillaString;
  350.         UBYTE    *ApplicationString;
  351.     } Table[18] =
  352.     {
  353.         CUP,    "\033[A",    "\033OA",
  354.         CDN,    "\033[B",    "\033OB",
  355.         CFW,    "\033[C",    "\033OC",
  356.         CBK,    "\033[D",    "\033OD",
  357.  
  358.         '0',    "0",        "\033Op",
  359.         '1',    "1",        "\033Oq",
  360.         '2',    "2",        "\033Or",
  361.         '3',    "3",        "\033Os",
  362.         '4',    "4",        "\033Ot",
  363.         '5',    "5",        "\033Ou",
  364.         '6',    "6",        "\033Ov",
  365.         '7',    "7",        "\033Ow",
  366.         '8',    "8",        "\033Ox",
  367.         '9',    "9",        "\033Oy",
  368.         '-',    "-",        "\033Om",
  369.         '*',    "*",        "\033Ol",
  370.         '.',    ".",        "\033On",
  371.         '\r',    "\r",        "\033OM"
  372.     };
  373.  
  374.     BYTE i;
  375.  
  376.         /* Look for the cursor keys first. */
  377.  
  378.     for(i = 0 ; i < 4 ; i++)
  379.     {
  380.         if(Table[i] . Char == Char)
  381.         {
  382.             if(Config . CursorApp)
  383.                 SerWrite(Table[i] . ApplicationString,strlen(Table[i] . ApplicationString));
  384.             else
  385.                 SerWrite(Table[i] . VanillaString,strlen(Table[i] . VanillaString));
  386.  
  387.             return(TRUE);
  388.         }
  389.     }
  390.  
  391.         /* Then take a look at the numeric pad. */
  392.  
  393.     for(i = 4 ; i < 18 ; i++)
  394.     {
  395.         if(Table[i] . Char == Char)
  396.         {
  397.             if(Config . NumApp)
  398.                 SerWrite(Table[i] . ApplicationString,strlen(Table[i] . ApplicationString));
  399.             else
  400.             {
  401.                 if(i == 17)
  402.                 {
  403.                     switch(Config . SendCR)
  404.                     {
  405.                         case CR_IGNORE:    break;
  406.  
  407.                         case CR_ASCR:    SerWrite("\r",1);
  408.                                 break;
  409.  
  410.                         case CR_ASCRLF:    SerWrite("\r\n",2);
  411.                                 break;
  412.                     }
  413.                 }
  414.                 else
  415.                     SerWrite(Table[i] . VanillaString,strlen(Table[i] . VanillaString));
  416.             }
  417.  
  418.             return(TRUE);
  419.         }
  420.     }
  421.  
  422.     return(FALSE);
  423. }
  424.  
  425.     /* KeyConvert(struct IntuiMessage *Massage,UBYTE *Buffer):
  426.      *
  427.      *    Convert a raw key information according to the
  428.      *    current keymap settings.
  429.      */
  430.  
  431. UBYTE __regargs
  432. KeyConvert(struct IntuiMessage *Massage,UBYTE *Buffer,LONG *Len)
  433. {
  434.     if(Buffer)
  435.         Buffer[0] = 0;
  436.  
  437.     if(Len)
  438.         *Len = 0;
  439.  
  440.     if(Massage -> Class == IDCMP_RAWKEY)
  441.     {
  442.             /* These are the sequences mapped to special
  443.              * control keys (cursor keys, function keys,
  444.              * the help key).
  445.              */
  446.  
  447.         STATIC struct
  448.         {
  449.             UBYTE *RawCode;
  450.             UBYTE Result;
  451.         } ConversionTable[16] =
  452.         {
  453.             (UBYTE *)"A",    CUP,
  454.             (UBYTE *)"B",    CDN,
  455.             (UBYTE *)"C",    CFW,
  456.             (UBYTE *)"D",    CBK,
  457.  
  458.             (UBYTE *)"?~",    HLP,
  459.  
  460.             (UBYTE *)"0~",    FN1,
  461.             (UBYTE *)"1~",    FN2,
  462.             (UBYTE *)"2~",    FN3,
  463.             (UBYTE *)"3~",    FN4,
  464.             (UBYTE *)"4~",    FN5,
  465.             (UBYTE *)"5~",    FN6,
  466.             (UBYTE *)"6~",    FN7,
  467.             (UBYTE *)"7~",    FN8,
  468.             (UBYTE *)"8~",    FN9,
  469.             (UBYTE *)"9~",    F10
  470.         };
  471.  
  472.         STATIC UBYTE SeqLens[16] = {1,1,1,1,2,2,2,2,2,2,2,2,2,2,2 };
  473.  
  474.             /* Key was pressed, not released. */
  475.  
  476.         if(!(Massage -> Code & IECODE_UP_PREFIX))
  477.         {
  478.             UBYTE    ConvertBuffer[257],i;
  479.             ULONG    Qualifier = Massage -> Qualifier;
  480.             LONG    Actual;
  481.  
  482.                 /* If it's a function key, clear the qualifier. */
  483.  
  484.             if(Massage -> Code >= 80 && Massage -> Code <= 89)
  485.                 Qualifier = NULL;
  486.  
  487.                 /* Convert the key. */
  488.  
  489.             FakeInputEvent -> ie_Code        = Massage -> Code;
  490.             FakeInputEvent -> ie_Qualifier        = Qualifier;
  491.             FakeInputEvent -> ie_position . ie_addr    = *((APTR *)Massage -> IAddress);
  492.  
  493.             if((Actual = RawKeyConvert(FakeInputEvent,(UBYTE *)ConvertBuffer,256,KeyMap)) > 0)
  494.             {
  495.                 if(ConvertBuffer[0])
  496.                 {
  497.                     if(Config . SwapBSDelete)
  498.                     {
  499.                         for(i = 0 ; i < Actual ; i++)
  500.                         {
  501.                             if(ConvertBuffer[i] == BKS)
  502.                                 ConvertBuffer[i] = DEL;
  503.                             else
  504.                             {
  505.                                 if(ConvertBuffer[i] == DEL)
  506.                                     ConvertBuffer[i] = BKS;
  507.                             }
  508.                         }
  509.                     }
  510.  
  511.                     if(Len)
  512.                     {
  513.                         if(Actual == 1 && (Qualifier & IEQUALIFIER_CONTROL))
  514.                         {
  515.                             if(ConvertBuffer[0] == '@' || ConvertBuffer[0] == ' ')
  516.                             {
  517.                                 ConvertBuffer[0] = Buffer[0] = 0;
  518.  
  519.                                 *Len = 1;
  520.                             }
  521.                             else
  522.                             {
  523.                                 *Len = Actual;
  524.  
  525.                                 if(Buffer)
  526.                                     memcpy(Buffer,ConvertBuffer,Actual);
  527.                             }
  528.                         }
  529.                         else
  530.                         {
  531.                             *Len = Actual;
  532.  
  533.                             memcpy(Buffer,ConvertBuffer,Actual);
  534.                         }
  535.                     }
  536.                     else
  537.                     {
  538.                         if(Buffer)
  539.                             memcpy(Buffer,ConvertBuffer,Actual);
  540.                     }
  541.  
  542.                         /* Translated sequence starts
  543.                          * with a CSI, let's have a look
  544.                          * at the associated control
  545.                          * key.
  546.                          */
  547.  
  548.                     if(ConvertBuffer[0] == CSI)
  549.                     {
  550.                         for(i = 0 ; i < sizeof(SeqLens) ; i++)
  551.                         {
  552.                             if(!Strnicmp(&ConvertBuffer[1],ConversionTable[i] . RawCode,SeqLens[i]))
  553.                             {
  554.                                 ConvertBuffer[0] = ConversionTable[i] . Result;
  555.  
  556.                                 if(Buffer)
  557.                                 {
  558.                                     Buffer[0] = ConversionTable[i] . Result;
  559.                                     Buffer[1] = 0;
  560.  
  561.                                     if(Len)
  562.                                         *Len = 1;
  563.                                 }
  564.  
  565.                                 break;
  566.                             }
  567.                         }
  568.                     }
  569.  
  570.                     return(ConvertBuffer[0]);
  571.                 }
  572.             }
  573.  
  574.                 /* If nothing came from the key conversion,
  575.                  * check for shift-tab.
  576.                  */
  577.  
  578.             if(Massage -> Code == 66 && (Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)))
  579.             {
  580.                 *Len = 2;
  581.  
  582.                 strcpy(ConvertBuffer,"\33\t");
  583.  
  584.                 if(Buffer)
  585.                     memcpy(Buffer,ConvertBuffer,2);
  586.  
  587.                 return(ConvertBuffer[0]);
  588.             }
  589.         }
  590.     }
  591.  
  592.     return(0);
  593. }
  594.  
  595.     /* GfxText(struct RastPort *RPort,STRPTR Buffer,LONG Length):
  596.      *
  597.      *    Text output, if necessary switching from gfx font
  598.      *    to current default font.
  599.      */
  600.  
  601. VOID __regargs
  602. GfxText(struct RastPort *RPort,STRPTR Buffer,LONG Length)
  603. {
  604.     if(GFX -> tf_XSize == TextFont -> tf_XSize && GFX -> tf_YSize == TextFont -> tf_YSize)
  605.     {
  606.         BYTE Mode = 1;
  607.  
  608.         while(Length--)
  609.         {
  610.             if(GfxTable[*Buffer] == Mode)
  611.                 Text(RPort,Buffer++,1);
  612.             else
  613.             {
  614.                 if(Mode)
  615.                     SetFont(RPort,TextFont);
  616.                 else
  617.                     SetFont(RPort,GFX);
  618.  
  619.                 Mode ^= 1;
  620.  
  621.                 Text(RPort,Buffer++,1);
  622.             }
  623.         }
  624.  
  625.         if(!Mode)
  626.             SetFont(RPort,GFX);
  627.     }
  628.     else
  629.         Text(RPort,Buffer,Length);
  630. }
  631.  
  632.     /* ConWrite(UBYTE *Buffer,LONG Size):
  633.      *
  634.      *    Output a buffer of given size to the terminal
  635.      *    window.
  636.      */
  637.  
  638. STATIC VOID __regargs
  639. ConWrite(UBYTE *Buffer,LONG Size)
  640. {
  641.     if(ControllerActive)
  642.     {
  643.         if(Size)
  644.         {
  645.             if(!FWrite(PrinterCapture,Buffer,Size,1))
  646.             {
  647.                 BlockWindows();
  648.  
  649.                 if(!MyEasyRequest(NULL,LocaleString(MSG_CONSOLE_ERROR_WRITING_TO_PRINTER_TXT),LocaleString(MSG_CONSOLE_IGNORE_CLOSE_PRINTER_TXT)))
  650.                     ClosePrinterCapture(TRUE);
  651.  
  652.                 ReleaseWindows();
  653.             }
  654.         }
  655.     }
  656.     else
  657.     {
  658.         UBYTE    Scale,CharScale;
  659.         WORD    Offset,LastChar;
  660.  
  661.             /* Reposition the cursor and turn it off. */
  662.  
  663.         ClearCursor();
  664.  
  665.         Scale = RasterAttr[CursorY];
  666.  
  667.         if(Config . FontScale == SCALE_HALF)
  668.         {
  669.             switch(Scale)
  670.             {
  671.                 case SCALE_ATTR_TOP2X:
  672.                 case SCALE_ATTR_BOT2X:
  673.                 case SCALE_ATTR_NORMAL:    CharScale    = TRUE;
  674.                             LastChar    = LastColumn;
  675.                             break;
  676.  
  677.                 case SCALE_ATTR_2X:    CharScale    = FALSE;
  678.                             LastChar    = LastColumn;
  679.                             break;
  680.             }
  681.         }
  682.         else
  683.         {
  684.             switch(Scale)
  685.             {
  686.                 case SCALE_ATTR_TOP2X:
  687.                 case SCALE_ATTR_BOT2X:
  688.                 case SCALE_ATTR_2X:    CharScale    = TRUE;
  689.                             LastChar    = ((LastColumn + 1) / 2) - 1;
  690.                             break;
  691.  
  692.                 case SCALE_ATTR_NORMAL:    CharScale    = FALSE;
  693.                             LastChar    = LastColumn;
  694.                             break;
  695.             }
  696.         }
  697.  
  698.             /* Is any capture function active? */
  699.  
  700.         if(Config . CaptureFilter || !BufferFrozen || PrinterCapture)
  701.         {
  702.             if(CurrentFont == GFX)
  703.             {
  704.                     /* Do we still have a character in the
  705.                      * magnificient buffer?
  706.                      */
  707.  
  708.                 while(Size)
  709.                 {
  710.                     /* Cursor is positioned at
  711.                      * the right hand side of the
  712.                      * display. If auto-wrap is
  713.                      * enabled, perform some
  714.                      * kind of CR/LF, else leave
  715.                      * the cursor where it is and
  716.                      * quit the show.
  717.                      */
  718.  
  719.                     if(CursorX > LastChar)
  720.                     {
  721.                             /* Wrap cursor. */
  722.  
  723.                         if(Config . AutoWrap)
  724.                         {
  725.                                 /* Move to beginning of next line. */
  726.  
  727.                             CursorX = 0;
  728.  
  729.                             DownLine();
  730.  
  731.                             Capture("\n",1);
  732.  
  733.                             Scale = SCALE_ATTR_NORMAL;
  734.  
  735.                             CharScale = (Config . FontScale == SCALE_NORMAL) ? FALSE : TRUE;
  736.  
  737.                             LastChar = LastColumn;
  738.  
  739.                                 /* Reposition cursor, don't redraw it. */
  740.  
  741.                             ClipBlitCursor(FALSE,TRUE);
  742.                         }
  743.                         else
  744.                         {
  745.                                 /* Stop the cursor. */
  746.  
  747.                             CursorX = LastChar;
  748.  
  749.                             Capture(Buffer,Size);
  750.  
  751.                                 /* Make it reappear. */
  752.  
  753.                             SetCursor();
  754.  
  755.                             return;
  756.                         }
  757.                     }
  758.  
  759.                     if(CursorX <= LastChar)
  760.                     {
  761.                             /* We won't have to take
  762.                              * care of characters to shift.
  763.                              * We'll collect as many
  764.                              * characters in the buffer as will
  765.                              * fit into the current line
  766.                              * and print them.
  767.                              */
  768.  
  769.                         if((Offset = LastChar + 1 - CursorX) > Size)
  770.                         {
  771.                             Offset = Size;
  772.  
  773.                             if(Config . InsertChar)
  774.                             {
  775.                                 RasterShiftChar(Offset);
  776.  
  777.                                 ScrollLineShiftChar(Offset);
  778.  
  779.                                 ShiftChar(Offset);
  780.                             }
  781.                         }
  782.  
  783.                         RasterPutString(Buffer,Offset);
  784.  
  785.                         ScrollLinePutString(Offset);
  786.  
  787.                         if(CharScale)
  788.                             PrintScaled(Buffer,Offset,Scale);
  789.                         else
  790.                             GfxText(RPort,Buffer,Offset);
  791.  
  792.                         Capture(Buffer,Offset);
  793.  
  794.                         Buffer    += Offset;
  795.  
  796.                         Size    -= Offset;
  797.  
  798.                         CursorX    += Offset;
  799.                     }
  800.                 }
  801.             }
  802.             else
  803.             {
  804.                     /* Do we still have a character in the
  805.                      * magnificient buffer?
  806.                      */
  807.  
  808.                 while(Size)
  809.                 {
  810.                     /* Cursor is positioned at
  811.                      * the right hand side of the
  812.                      * display. If auto-wrap is
  813.                      * enabled, perform some
  814.                      * kind of CR/LF, else leave
  815.                      * the cursor where it is and
  816.                      * quit the show.
  817.                      */
  818.  
  819.                     if(CursorX > LastChar)
  820.                     {
  821.                             /* Wrap cursor. */
  822.  
  823.                         if(Config . AutoWrap)
  824.                         {
  825.                                 /* Move to beginning of next line. */
  826.  
  827.                             CursorX = 0;
  828.  
  829.                             DownLine();
  830.  
  831.                             Capture("\n",1);
  832.  
  833.                             Scale = SCALE_ATTR_NORMAL;
  834.  
  835.                             CharScale = (Config . FontScale == SCALE_NORMAL) ? FALSE : TRUE;
  836.  
  837.                             LastChar = LastColumn;
  838.  
  839.                                 /* Reposition cursor, don't redraw it. */
  840.  
  841.                             ClipBlitCursor(FALSE,TRUE);
  842.                         }
  843.                         else
  844.                         {
  845.                                 /* Stop the cursor. */
  846.  
  847.                             CursorX = LastChar;
  848.  
  849.                             Capture(Buffer,Size);
  850.  
  851.                                 /* Make it reappear. */
  852.  
  853.                             SetCursor();
  854.  
  855.                             return;
  856.                         }
  857.                     }
  858.  
  859.                     if(CursorX <= LastChar)
  860.                     {
  861.                             /* We won't have to take
  862.                              * care of characters to shift.
  863.                              * We'll collect as many
  864.                              * characters in the buffer as will
  865.                              * fit into the current line
  866.                              * and print them.
  867.                              */
  868.  
  869.                         if((Offset = LastChar + 1 - CursorX) > Size)
  870.                         {
  871.                             Offset = Size;
  872.  
  873.                             if(Config . InsertChar)
  874.                             {
  875.                                 RasterShiftChar(Offset);
  876.  
  877.                                 ScrollLineShiftChar(Offset);
  878.  
  879.                                 ShiftChar(Offset);
  880.                             }
  881.                         }
  882.  
  883.                         RasterPutString(Buffer,Offset);
  884.  
  885.                         ScrollLinePutString(Offset);
  886.  
  887.                         if(CharScale)
  888.                             PrintScaled(Buffer,Offset,Scale);
  889.                         else
  890.                             Text(RPort,Buffer,Offset);
  891.  
  892.                         Capture(Buffer,Offset);
  893.  
  894.                         Buffer    += Offset;
  895.  
  896.                         Size    -= Offset;
  897.  
  898.                         CursorX    += Offset;
  899.                     }
  900.                 }
  901.             }
  902.         }
  903.         else
  904.         {
  905.             if(CurrentFont == GFX)
  906.             {
  907.                 while(Size)
  908.                 {
  909.                     if(CursorX > LastChar)
  910.                     {
  911.                         if(Config . AutoWrap)
  912.                         {
  913.                             CursorX = 0;
  914.  
  915.                             DownLine();
  916.  
  917.                             Scale = SCALE_ATTR_NORMAL;
  918.  
  919.                             CharScale = (Config . FontScale == SCALE_NORMAL) ? FALSE : TRUE;
  920.  
  921.                             LastChar = LastColumn;
  922.  
  923.                             ClipBlitCursor(FALSE,TRUE);
  924.                         }
  925.                         else
  926.                         {
  927.                             CursorX = LastChar;
  928.  
  929.                             SetCursor();
  930.  
  931.                             return;
  932.                         }
  933.                     }
  934.  
  935.                     if(CursorX <= LastChar)
  936.                     {
  937.                         if((Offset = LastChar + 1 - CursorX) > Size)
  938.                         {
  939.                             Offset = Size;
  940.  
  941.                             if(Config . InsertChar)
  942.                             {
  943.                                 RasterShiftChar(Offset);
  944.  
  945.                                 ScrollLineShiftChar(Offset);
  946.  
  947.                                 ShiftChar(Offset);
  948.                             }
  949.                         }
  950.  
  951.                         RasterPutString(Buffer,Offset);
  952.  
  953.                         ScrollLinePutString(Offset);
  954.  
  955.                         if(CharScale)
  956.                             PrintScaled(Buffer,Offset,Scale);
  957.                         else
  958.                             GfxText(RPort,Buffer,Offset);
  959.  
  960.                         Buffer    += Offset;
  961.  
  962.                         Size    -= Offset;
  963.  
  964.                         CursorX    += Offset;
  965.                     }
  966.                 }
  967.             }
  968.             else
  969.             {
  970.                 while(Size)
  971.                 {
  972.                     if(CursorX > LastChar)
  973.                     {
  974.                         if(Config . AutoWrap)
  975.                         {
  976.                             CursorX = 0;
  977.  
  978.                             DownLine();
  979.  
  980.                             Scale = SCALE_ATTR_NORMAL;
  981.  
  982.                             CharScale = (Config . FontScale == SCALE_NORMAL) ? FALSE : TRUE;
  983.  
  984.                             LastChar = LastColumn;
  985.  
  986.                             ClipBlitCursor(FALSE,TRUE);
  987.                         }
  988.                         else
  989.                         {
  990.                             CursorX = LastChar;
  991.  
  992.                             SetCursor();
  993.  
  994.                             return;
  995.                         }
  996.                     }
  997.  
  998.                     if(CursorX <= LastChar)
  999.                     {
  1000.                         if((Offset = LastChar + 1 - CursorX) > Size)
  1001.                         {
  1002.                             Offset = Size;
  1003.  
  1004.                             if(Config . InsertChar)
  1005.                             {
  1006.                                 RasterShiftChar(Offset);
  1007.  
  1008.                                 ScrollLineShiftChar(Offset);
  1009.  
  1010.                                 ShiftChar(Offset);
  1011.                             }
  1012.                         }
  1013.  
  1014.                         RasterPutString(Buffer,Offset);
  1015.  
  1016.                         ScrollLinePutString(Offset);
  1017.  
  1018.                         if(CharScale)
  1019.                             PrintScaled(Buffer,Offset,Scale);
  1020.                         else
  1021.                             Text(RPort,Buffer,Offset);
  1022.  
  1023.                         Buffer    += Offset;
  1024.  
  1025.                         Size    -= Offset;
  1026.  
  1027.                         CursorX    += Offset;
  1028.                     }
  1029.                 }
  1030.             }
  1031.         }
  1032.  
  1033.             /* Make the cursor reappear. */
  1034.  
  1035.         SetCursor();
  1036.     }
  1037. }
  1038.  
  1039.     /* ConProcess(UBYTE *String,LONG Size):
  1040.      *
  1041.      *    Process the contents of a string to be sent to the
  1042.      *    console window.
  1043.      */
  1044.  
  1045. VOID __regargs
  1046. ConProcess(register UBYTE *String,register LONG Size)
  1047. {
  1048.         /* If the capture filter happens to be disabled, write the
  1049.          * raw data.
  1050.          */
  1051.  
  1052.     if(!Config . CaptureFilter)
  1053.         CaptureToFile(String,Size);
  1054.  
  1055.         /* Oh dear, an external emulation will take care of
  1056.          * displaying the data so we will need to make sure
  1057.          * that the data flow filter and the capture streams
  1058.          * are properly fed.
  1059.          */
  1060.  
  1061.     if(XEmulatorBase && Config . Emulation == EMULATION_EXTERNAL)
  1062.     {
  1063.         register LONG i;
  1064.  
  1065.             /* Feed the flow filter... */
  1066.  
  1067.         if(Config . StripBit8)
  1068.         {
  1069.             for(i = 0 ; i < Size ; i++)
  1070.                 FlowFilter(String[i] & 0x7F);
  1071.         }
  1072.         else
  1073.         {
  1074.             for(i = 0 ; i < Size ; i++)
  1075.                 FlowFilter(String[i]);
  1076.         }
  1077.  
  1078.             /* Are we to output data? */
  1079.  
  1080.         if(!Quiet)
  1081.         {
  1082.             XEmulatorWrite(XEM_IO,String,Size);
  1083.  
  1084.                 /* Build another string to contain
  1085.                  * the pure ASCII contents, i.e.
  1086.                  * not including any ESC control
  1087.                  * sequences.
  1088.                  */
  1089.  
  1090.             if(StripBuffer)
  1091.             {
  1092.                 XEM_HostData . Source        = String;
  1093.                 XEM_HostData . Destination    = StripBuffer;
  1094.  
  1095.                 if(i = XEmulatorHostMon(XEM_IO,&XEM_HostData,Size))
  1096.                     Capture(StripBuffer,i);
  1097.             }
  1098.         }
  1099.     }
  1100.     else
  1101.     {
  1102.         STATIC UBYTE TempBuffer[512];
  1103.  
  1104.             /* If the eighth bit is to be stripped from incoming
  1105.              * characters, let's process the whole stuff
  1106.              * in a different loop... (and that's all for the
  1107.              * sake of speed).
  1108.              */
  1109.  
  1110.         if(Config . StripBit8)
  1111.         {
  1112.                 /* In quiet mode no characters are echoed to the
  1113.                  * console window, they are just passed through
  1114.                  * the data flow filter. Usually, this mode is
  1115.                  * enabled by the dial panel.
  1116.                  */
  1117.  
  1118.             if(Quiet)
  1119.             {
  1120.                 register LONG i;
  1121.  
  1122.                 for(i = 0 ; i < Size ; i++)
  1123.                     FlowFilter(String[i] & 0x7F);
  1124.             }
  1125.             else
  1126.             {
  1127.                 register UBYTE    c;
  1128.                 register LONG    j = 0;
  1129.  
  1130.                     /* If still parsing a sequence,
  1131.                      * continue with it.
  1132.                      */
  1133.  
  1134.                 if(InSequence)
  1135.                 {
  1136.                     while(Size--)
  1137.                     {
  1138.                         c = *String++;
  1139.  
  1140.                         if(!(InSequence = (*AbortTable[c])(c)))
  1141.                             break;
  1142.                     }
  1143.                 }
  1144.  
  1145.                     /* Check which font we are in, if other than Topaz
  1146.                      * the only invalid char is a Null (0) which will
  1147.                      * display as a space if let to continue.
  1148.                      */
  1149.  
  1150.                 if(Config . Font == FONT_TOPAZ)
  1151.                 {
  1152.                     while(Size-- > 0)
  1153.                     {
  1154.                         FlowFilter(c = *String++ & 0x7F);
  1155.  
  1156.                         if(IsPrintable(c))
  1157.                         {
  1158.                             /* This character is associated with a
  1159.                              * special function (bell, xon, xoff, etc.).
  1160.                              */
  1161.  
  1162.                             if(SpecialTable[c])
  1163.                             {
  1164.                                 if(j)
  1165.                                 {
  1166.                                     ConWrite(TempBuffer,j);
  1167.  
  1168.                                     j = 0;
  1169.                                 }
  1170.  
  1171.                                     /* Does this character start
  1172.                                      * a control sequence?
  1173.                                      */
  1174.  
  1175.                                 if(InSequence = (*SpecialTable[c])(1))
  1176.                                 {
  1177.                                     while(Size-- > 0)
  1178.                                     {
  1179.                                         c = *String++;
  1180.  
  1181.                                         if(!(InSequence = (*AbortTable[c])(c)))
  1182.                                             break;
  1183.                                     }
  1184.                                 }
  1185.                             }
  1186.                             else
  1187.                             {
  1188.                                 /* Put the character into the buffer
  1189.                                  * and flush it if necessary.
  1190.                                  */
  1191.  
  1192.                                 TempBuffer[j++] = c;
  1193.  
  1194.                                 if(j == 512)
  1195.                                 {
  1196.                                     ConWrite(TempBuffer,j);
  1197.  
  1198.                                     j = 0;
  1199.                                 }
  1200.                             }
  1201.                         }
  1202.                     }
  1203.                 }
  1204.                 else
  1205.                 {
  1206.                     while(Size-- > 0)
  1207.                     {
  1208.                         if(c = (*String++ & 0x7F))
  1209.                         {
  1210.                             FlowFilter(c);
  1211.  
  1212.                             /* This character is associated with a
  1213.                              * special function (bell, xon, xoff, etc.).
  1214.                              */
  1215.  
  1216.                             if(SpecialTable[c])
  1217.                             {
  1218.                                 if(j)
  1219.                                 {
  1220.                                     ConWrite(TempBuffer,j);
  1221.  
  1222.                                     j = 0;
  1223.                                 }
  1224.  
  1225.                                 if(InSequence = (*SpecialTable[c])(1))
  1226.                                 {
  1227.                                     while(Size--)
  1228.                                     {
  1229.                                         c = *String++;
  1230.  
  1231.                                         if(!(InSequence = (*AbortTable[c])(c)))
  1232.                                             break;
  1233.                                     }
  1234.                                 }
  1235.                             }
  1236.                             else
  1237.                             {
  1238.                                 /* Put the character into the buffer
  1239.                                  * and flush it if necessary.
  1240.                                  */
  1241.  
  1242.                                 TempBuffer[j++] = c;
  1243.  
  1244.                                 if(j == 512)
  1245.                                 {
  1246.                                     ConWrite(TempBuffer,j);
  1247.  
  1248.                                     j = 0;
  1249.                                 }
  1250.                             }
  1251.                         }
  1252.                     }
  1253.                 }
  1254.  
  1255.                 if(j)
  1256.                     ConWrite(TempBuffer,j);
  1257.             }
  1258.         }
  1259.         else
  1260.         {
  1261.             if(Quiet)
  1262.             {
  1263.                 register LONG i;
  1264.  
  1265.                 for(i = 0 ; i < Size ; i++)
  1266.                     FlowFilter(String[i]);
  1267.             }
  1268.             else
  1269.             {
  1270.                 register UBYTE    c;
  1271.                 register LONG    j = 0;
  1272.  
  1273.                 if(InSequence)
  1274.                 {
  1275.                     while(Size--)
  1276.                     {
  1277.                         c = *String++;
  1278.  
  1279.                         if(!(InSequence = (*AbortTable[c])(c)))
  1280.                             break;
  1281.                     }
  1282.                 }
  1283.  
  1284.                 if(Config . Font == FONT_TOPAZ)
  1285.                 {
  1286.                     while(Size-- > 0)
  1287.                     {
  1288.                         FlowFilter(c = *String++);
  1289.  
  1290.                         if(IsPrintable(c))
  1291.                         {
  1292.                             if(SpecialTable[c])
  1293.                             {
  1294.                                 if(j)
  1295.                                 {
  1296.                                     ConWrite(TempBuffer,j);
  1297.  
  1298.                                     j = 0;
  1299.                                 }
  1300.  
  1301.                                 if(InSequence = (*SpecialTable[c])(1))
  1302.                                 {
  1303.                                     while(Size-- > 0)
  1304.                                     {
  1305.                                         c = *String++;
  1306.  
  1307.                                         if(!(InSequence = (*AbortTable[c])(c)))
  1308.                                             break;
  1309.                                     }
  1310.                                 }
  1311.                             }
  1312.                             else
  1313.                             {
  1314.                                 TempBuffer[j++] = c;
  1315.  
  1316.                                 if(j == 512)
  1317.                                 {
  1318.                                     ConWrite(TempBuffer,j);
  1319.  
  1320.                                     j = 0;
  1321.                                 }
  1322.                             }
  1323.                         }
  1324.                     }
  1325.                 }
  1326.                 else
  1327.                 {
  1328.                     while(Size-- > 0)
  1329.                     {
  1330.                         if(c = *String++)
  1331.                         {
  1332.                             FlowFilter(c);
  1333.  
  1334.                             if(SpecialTable[c])
  1335.                             {
  1336.                                 if(j)
  1337.                                 {
  1338.                                     ConWrite(TempBuffer,j);
  1339.  
  1340.                                     j = 0;
  1341.                                 }
  1342.  
  1343.                                 if(InSequence = (*SpecialTable[c])(1))
  1344.                                 {
  1345.                                     while(Size-- > 0)
  1346.                                     {
  1347.                                         c = *String++;
  1348.  
  1349.                                         if(!(InSequence = (*AbortTable[c])(c)))
  1350.                                             break;
  1351.                                     }
  1352.                                 }
  1353.                             }
  1354.                             else
  1355.                             {
  1356.                                 TempBuffer[j++] = c;
  1357.  
  1358.                                 if(j == 512)
  1359.                                 {
  1360.                                     ConWrite(TempBuffer,j);
  1361.  
  1362.                                     j = 0;
  1363.                                 }
  1364.                             }
  1365.                         }
  1366.                     }
  1367.                 }
  1368.  
  1369.                 if(j)
  1370.                     ConWrite(TempBuffer,j);
  1371.             }
  1372.         }
  1373.     }
  1374. }
  1375.  
  1376.     /* ConWrites(UBYTE *String,...):
  1377.      *
  1378.      *    Output a string to the console.
  1379.      */
  1380.  
  1381. VOID __stdargs
  1382. ConWrites(UBYTE *String,...)
  1383. {
  1384.     va_list    VarArgs;
  1385.  
  1386.     va_start(VarArgs,String);
  1387.     VSPrintf(SharedBuffer,String,VarArgs);
  1388.     va_end(VarArgs);
  1389.  
  1390.     ConProcess(SharedBuffer,strlen(SharedBuffer));
  1391. }
  1392.  
  1393.     /* DoBackspace():
  1394.      *
  1395.      *    Special function: perform backspace.
  1396.      */
  1397.  
  1398. BYTE
  1399. DoBackspace()
  1400. {
  1401.     Capture("\b",1);
  1402.  
  1403.     if(CursorX)
  1404.     {
  1405.         ClearCursor();
  1406.  
  1407.         CursorX--;
  1408.  
  1409.             /* If destructive, shift the remaining line
  1410.              * one character to the right.
  1411.              */
  1412.  
  1413.         if(Config . DestructiveBackspace)
  1414.         {
  1415.             WORD DeltaX,MinX;
  1416.  
  1417.             BackupRender();
  1418.  
  1419.             SetBPen(RPort,0);
  1420.  
  1421.             RasterEraseCharacters(1);
  1422.  
  1423.             if(Config . FontScale == SCALE_NORMAL)
  1424.             {
  1425.                 if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  1426.                 {
  1427.                     DeltaX    = TextFontWidth;
  1428.                     MinX    = CursorX * TextFontWidth;
  1429.                 }
  1430.                 else
  1431.                 {
  1432.                     DeltaX    = TextFontWidth / 2;
  1433.                     MinX    = CursorX * TextFontWidth / 2;
  1434.                 }
  1435.             }
  1436.             else
  1437.             {
  1438.                 if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  1439.                 {
  1440.                     DeltaX    = TextFontWidth / 2;
  1441.                     MinX    = CursorX * TextFontWidth / 2;
  1442.                 }
  1443.                 else
  1444.                 {
  1445.                     DeltaX    = TextFontWidth;
  1446.                     MinX    = CursorX * TextFontWidth;
  1447.                 }
  1448.             }
  1449.  
  1450.             ScrollLineEraseCharacters(1);
  1451.  
  1452.             ScrollLineRaster(RPort,DeltaX,0,MinX,CursorY * TextFontHeight,LastPixel,(CursorY + 1) * TextFontHeight - 1);
  1453.  
  1454.             BackupRender();
  1455.         }
  1456.  
  1457.         SetCursor();
  1458.     }
  1459.  
  1460.     return(FALSE);
  1461. }
  1462.  
  1463.     /* DoBeep():
  1464.      *
  1465.      *    The real interface to the beep routine.
  1466.      */
  1467.  
  1468. BYTE
  1469. DoBeep()
  1470. {
  1471.         /* Handle the visual part. */
  1472.  
  1473.     if(Config . VisibleBell || Config . SystemBeep)
  1474.     {
  1475.         if(StatusProcess)
  1476.             Signal(StatusProcess,SIGBREAKF_CTRL_D);
  1477.     }
  1478.  
  1479.         /* Let it beep. */
  1480.  
  1481.     if(Config . AudibleBell)
  1482.         Beep();
  1483.  
  1484.         /* Capture the bell. */
  1485.  
  1486.     if(!Config . CaptureFilter)
  1487.         Capture("\a",1);
  1488.  
  1489.     return(FALSE);
  1490. }
  1491.  
  1492.     /* DoxON():
  1493.      *
  1494.      *    Perform XON (stop data flow).
  1495.      */
  1496.  
  1497. BYTE
  1498. DoxON()
  1499. {
  1500.     if(Config . xONxOFF)
  1501.         Status = STATUS_HOLDING;
  1502.  
  1503.     return(FALSE);
  1504. }
  1505.  
  1506.     /* DoLF():
  1507.      *
  1508.      *    Special function: perform line feed.
  1509.      */
  1510.  
  1511. BYTE
  1512. DoLF()
  1513. {
  1514.     if(Config . ReceiveLF == LF_ASLFCR)
  1515.     {
  1516.         ClearCursor();
  1517.  
  1518.         CursorX = 0;
  1519.  
  1520.         DownLine();
  1521.  
  1522.         SetCursor();
  1523.  
  1524.         Capture("\n",1);
  1525.     }
  1526.     else
  1527.     {
  1528.         if(Config . ReceiveLF == LF_ASLF)
  1529.         {
  1530.             ClearCursor();
  1531.  
  1532.             DownLine();
  1533.  
  1534.             SetCursor();
  1535.         }
  1536.     }
  1537.  
  1538.     return(FALSE);
  1539. }
  1540.  
  1541.     /* DoShiftIn():
  1542.      *
  1543.      *    Special function: Shift into graphics mode
  1544.      */
  1545.  
  1546. BYTE
  1547. DoShiftIn()
  1548. {
  1549.     if(CharMode[1] == TABLE_GFX && GFX)
  1550.     {
  1551.         if(GFX -> tf_XSize == TextFont -> tf_XSize && GFX -> tf_YSize == TextFont -> tf_YSize)
  1552.             CurrentFont = GFX;
  1553.         else
  1554.             CurrentFont = TextFont;
  1555.     }
  1556.  
  1557.     if(CharMode[1] == TABLE_ASCII)
  1558.         CurrentFont = TextFont;
  1559.  
  1560.     SetFont(RPort,CurrentFont);
  1561.  
  1562.     Charset = 1;
  1563.  
  1564.     return(FALSE);
  1565. }
  1566.  
  1567.     /* DoShiftOut():
  1568.      *
  1569.      *    Special function: Shift out of graphics mode
  1570.      */
  1571.  
  1572. BYTE
  1573. DoShiftOut()
  1574. {
  1575.     if(CharMode[0] == TABLE_GFX && GFX)
  1576.     {
  1577.         if(GFX -> tf_XSize == TextFont -> tf_XSize && GFX -> tf_YSize == TextFont -> tf_YSize)
  1578.             CurrentFont = GFX;
  1579.         else
  1580.             CurrentFont = TextFont;
  1581.     }
  1582.  
  1583.     if(CharMode[0] == TABLE_ASCII)
  1584.         CurrentFont = TextFont;
  1585.  
  1586.     SetFont(RPort,CurrentFont);
  1587.  
  1588.     Charset = 0;
  1589.  
  1590.     return(FALSE);
  1591. }
  1592.  
  1593.     /* DoCR_LF():
  1594.      *
  1595.      *    Special function: perform carriage return and line feed.
  1596.      */
  1597.  
  1598. BYTE
  1599. DoCR_LF()
  1600. {
  1601.     ClearCursor();
  1602.  
  1603.     CursorX = 0;
  1604.  
  1605.     DownLine();
  1606.  
  1607.     SetCursor();
  1608.  
  1609.     Capture("\n",1);
  1610.  
  1611.     return(FALSE);
  1612. }
  1613.  
  1614.     /* DoFF():
  1615.      *
  1616.      *    Special function: perform form feed.
  1617.      */
  1618.  
  1619. BYTE
  1620. DoFF()
  1621. {
  1622.     if(Config . NewLine)
  1623.     {
  1624.         CursorX = 0;
  1625.  
  1626.         DoCR_LF();
  1627.     }
  1628.     else
  1629.     {
  1630.         EraseScreen("2");
  1631.  
  1632.         ClearCursor();
  1633.  
  1634.         CursorX = CursorY = 0;
  1635.  
  1636.         SetCursor();
  1637.  
  1638.         Capture("\n",1);
  1639.     }
  1640.  
  1641.     return(FALSE);
  1642. }
  1643.  
  1644.     /* DoLF_FF_VT():
  1645.      *
  1646.      *    Special function: handle line feed, form feed and vertical
  1647.      *    tab.
  1648.      */
  1649.  
  1650. BYTE
  1651. DoLF_FF_VT()
  1652. {
  1653.     if(Config . NewLine)
  1654.         DoCR_LF();
  1655.     else
  1656.         DoLF();
  1657.  
  1658.     return(FALSE);
  1659. }
  1660.  
  1661.     /* DoCR():
  1662.      *
  1663.      *    Special function: handle carriage return.
  1664.      */
  1665.  
  1666. BYTE
  1667. DoCR()
  1668. {
  1669.     if(Config . NewLine || Config . ReceiveCR == CR_ASCRLF)
  1670.         DoCR_LF();
  1671.     else
  1672.     {
  1673.         if(Config . ReceiveCR == CR_ASCR)
  1674.         {
  1675.             ClearCursor();
  1676.  
  1677.             CursorX = 0;
  1678.  
  1679.             SetCursor();
  1680.  
  1681.             Capture("\n",1);
  1682.         }
  1683.     }
  1684.  
  1685.     return(FALSE);
  1686. }
  1687.  
  1688.     /* DoTab():
  1689.      *
  1690.      *    Special function: handle tab, move cursor to next
  1691.      *    tab stop.
  1692.      */
  1693.  
  1694. BYTE
  1695. DoTab()
  1696. {
  1697.     WORD Column;
  1698.  
  1699.     if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  1700.         Column = LastColumn;
  1701.     else
  1702.         Column = ((LastColumn + 1) / 2) - 1;
  1703.  
  1704.     ClearCursor();
  1705.  
  1706.     if(Config . AutoWrap)
  1707.     {
  1708.         if(CursorX >= LastColumn)
  1709.         {
  1710.             CursorX = 0;
  1711.  
  1712.             DownLine();
  1713.         }
  1714.         else
  1715.         {
  1716.             while(CursorX < Column)
  1717.             {
  1718.                 CursorX++;
  1719.  
  1720.                 if(TabStops[CursorX])
  1721.                     break;
  1722.             }
  1723.         }
  1724.     }
  1725.     else
  1726.     {
  1727.         while(CursorX < Column)
  1728.         {
  1729.             CursorX++;
  1730.  
  1731.             if(TabStops[CursorX])
  1732.                 break;
  1733.         }
  1734.     }
  1735.  
  1736.     SetCursor();
  1737.  
  1738.     Capture("\t",1);
  1739.  
  1740.     return(FALSE);
  1741. }
  1742.  
  1743.     /* DoEnq():
  1744.      *
  1745.      *    Special function: send answerback message.
  1746.      */
  1747.  
  1748. BYTE
  1749. DoEnq()
  1750. {
  1751.     if(Config . AnswerBack[0])
  1752.         SerialCommand(Config . AnswerBack);
  1753.  
  1754.     return(FALSE);
  1755. }
  1756.  
  1757.     /* DoEsc():
  1758.      *
  1759.      *    Start new control sequence.
  1760.      */
  1761.  
  1762. BYTE
  1763. DoEsc()
  1764. {
  1765.     if(Config . Emulation == EMULATION_TTY)
  1766.         ConWrite("^",1);
  1767.  
  1768.     return(TRUE);
  1769. }
  1770.  
  1771.     /* DoCsi():
  1772.      *
  1773.      *    Start new control sequence.
  1774.      */
  1775.  
  1776. BYTE
  1777. DoCsi()
  1778. {
  1779.     if(Config . Emulation == EMULATION_TTY)
  1780.         ConWrite("^[",2);
  1781.  
  1782.     ParseCode('[');
  1783.  
  1784.     return(TRUE);
  1785. }
  1786.  
  1787.     /* DoNewEsc(UBYTE Char):
  1788.      *
  1789.      *    Start new control sequence.
  1790.      */
  1791.  
  1792. BYTE __regargs
  1793. DoNewEsc(UBYTE Char)
  1794. {
  1795.     if(Config . Emulation == EMULATION_TTY)
  1796.         ConWrite("^",1);
  1797.  
  1798.     DoCancel();
  1799.  
  1800.     return(TRUE);
  1801. }
  1802.  
  1803.     /* DoNewCsi(UBYTE Char):
  1804.      *
  1805.      *    Start new control sequence.
  1806.      */
  1807.  
  1808. BYTE __regargs
  1809. DoNewCsi(UBYTE Char)
  1810. {
  1811.     if(Config . Emulation == EMULATION_TTY)
  1812.         ConWrite("^[",2);
  1813.  
  1814.     DoCancel();
  1815.  
  1816.     return(ParseCode('['));
  1817. }
  1818.