home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d534 / term.lha / Term / Source.LZH / Console.c < prev    next >
C/C++ Source or Header  |  1991-07-17  |  18KB  |  1,184 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by Olaf 'Olsen' Barthel & MXM
  4.  *
  5.  *    Name .....: Console.c
  6.  *    Created ..: Monday 21-Jan-91 20:12
  7.  *    Revision .: 1
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    14-Apr-91       Olsen           Rewrote double-dead-key support.
  12.  *    05-Feb-91       Olsen           Added double-dead-key support.
  13.  *    21-Jan-91       Olsen           Created this file!
  14.  *
  15.  * $Revision Header ********************************************************/
  16.  
  17. #include "TermGlobal.h"
  18.  
  19.     /* Capture(APTR Buffer,LONG Size):
  20.      *
  21.      *    Send the buffer contents to the display/disk capture.
  22.      */
  23.  
  24. VOID
  25. Capture(APTR Buffer,LONG Size)
  26. {
  27.     struct MenuItem *SomeItem;
  28.  
  29.         /* We are parsing a control sequence, don't buffer it! */
  30.  
  31.     if(!InSequence)
  32.         StoreBuffer(Buffer,Size);
  33.  
  34.         /* Write to capture file. */
  35.  
  36.     if(FileCapture)
  37.     {
  38.         if(!FWrite(FileCapture,Buffer,Size,1))
  39.         {
  40.             BlockWindows();
  41.  
  42.                 /* We had an error writing to the file. */
  43.  
  44.             switch(MyEasyRequest(NULL,"Error writing to capture\nfile %s!","Ignore Error|Close & Discard File|Close File",CaptureName))
  45.             {
  46.                 case 0:    break;
  47.  
  48.                 case 1:    Close(FileCapture);
  49.  
  50.                     DeleteFile(CaptureName);
  51.  
  52.                     if(SomeItem = FindThisItem(MEN_CAPTUREDISK))
  53.                         SomeItem -> Flags &= ~CHECKED;
  54.  
  55.                     FileCapture = NULL;
  56.  
  57.                     break;
  58.  
  59.                 case 2:    Close(FileCapture);
  60.  
  61.                     if(SomeItem = FindThisItem(MEN_CAPTUREDISK))
  62.                         SomeItem -> Flags &= ~CHECKED;
  63.  
  64.                     FileCapture = NULL;
  65.  
  66.                     if(!GetFileSize(CaptureName))
  67.                         DeleteFile(CaptureName);
  68.  
  69.                     break;
  70.             }
  71.  
  72.             ReleaseWindows();
  73.         }
  74.     }
  75.  
  76.         /* Send the buffer to the printer (ignore ANSI control
  77.          * sequences).
  78.          */
  79.  
  80.     if(PrinterCapture)
  81.     {
  82.         if(*((UBYTE *)Buffer) != '\033' && !InSequence)
  83.         {
  84.             if(!FWrite(FileCapture,Buffer,Size,1))
  85.             {
  86.                 BlockWindows();
  87.  
  88.                 if(!MyEasyRequest(NULL,"Error writing to printer!","Ignore Error|Close Printer"))
  89.                 {
  90.                     Close(PrinterCapture);
  91.  
  92.                     if(SomeItem = FindThisItem(MEN_CAPTUREPRINTER))
  93.                         SomeItem -> Flags &= ~CHECKED;
  94.  
  95.                     PrinterCapture = NULL;
  96.                 }
  97.  
  98.                 ReleaseWindows();
  99.             }
  100.         }
  101.     }
  102. }
  103.  
  104.     /* HandleCursor(UBYTE Char):
  105.      *
  106.      *    This routine handles the somewhat strange behaviour of
  107.      *    an assorted set of keys in VT100 applications mode.
  108.      */
  109.  
  110. BYTE
  111. HandleCursor(UBYTE Char)
  112. {
  113.     STATIC struct
  114.     {
  115.         UBYTE     Char;
  116.         UBYTE    *VanillaString;
  117.         UBYTE    *ApplicationString;
  118.     } Table[18] =
  119.     {
  120.         CUP,    "\033[A",    "\033OA",
  121.         CDN,    "\033[B",    "\033OB",
  122.         CFW,    "\033[C",    "\033OC",
  123.         CBK,    "\033[D",    "\033OD",
  124.  
  125.         '0',    "0",        "\033Op",
  126.         '1',    "1",        "\033Oq",
  127.         '2',    "2",        "\033Or",
  128.         '3',    "3",        "\033Os",
  129.         '4',    "4",        "\033Ot",
  130.         '5',    "5",        "\033Ou",
  131.         '6',    "6",        "\033Ov",
  132.         '7',    "7",        "\033Ow",
  133.         '8',    "8",        "\033Ox",
  134.         '9',    "9",        "\033Oy",
  135.         '-',    "-",        "\033Om",
  136.         '*',    "*",        "\033Ol",
  137.         '.',    ".",        "\033On",
  138.         '\r',    "\r",        "\033OM"
  139.     };
  140.  
  141.     BYTE i;
  142.  
  143.         /* Look for the cursor keys first. */
  144.  
  145.     for(i = 0 ; i < 4 ; i++)
  146.     {
  147.         if(Table[i] . Char == Char)
  148.         {
  149.             if(Config . CursorApp)
  150.                 SerWrite(Table[i] . ApplicationString,strlen(Table[i] . ApplicationString));
  151.             else
  152.                 SerWrite(Table[i] . VanillaString,strlen(Table[i] . VanillaString));
  153.  
  154.             return(TRUE);
  155.         }
  156.     }
  157.  
  158.         /* Then take a look at the numeric pad. */
  159.  
  160.     for(i = 4 ; i < 18 ; i++)
  161.     {
  162.         if(Table[i] . Char == Char)
  163.         {
  164.             if(Config . NumApp)
  165.                 SerWrite(Table[i] . ApplicationString,strlen(Table[i] . ApplicationString));
  166.             else
  167.             {
  168.                 if(i == 17)
  169.                 {
  170.                     switch(Config . SendCR)
  171.                     {
  172.                         case CR_IGNORE:    break;
  173.  
  174.                         case CR_ASCR:    SerWrite("\r",1);
  175.                                 break;
  176.  
  177.                         case CR_ASCRLF:    SerWrite("\r\n",2);
  178.                                 break;
  179.                     }
  180.                 }
  181.                 else
  182.                     SerWrite(Table[i] . VanillaString,strlen(Table[i] . VanillaString));
  183.             }
  184.  
  185.             return(TRUE);
  186.         }
  187.     }
  188.  
  189.     return(FALSE);
  190. }
  191.  
  192.     /* DoBackspace():
  193.      *
  194.      *    Special function: perform backspace.
  195.      */
  196.  
  197. VOID
  198. DoBackspace()
  199. {
  200.     Capture("\b",1);
  201.  
  202.     if(CursorX)
  203.     {
  204.         ClearCursor();
  205.  
  206.         CursorX--;
  207.  
  208.             /* If destructive, shift the remaining line
  209.              * one character to the right.
  210.              */
  211.  
  212.         if(Config . DestructiveBackspace)
  213.         {
  214.             BackupRender();
  215.  
  216.             SetBPen(RPort,0);
  217.  
  218.             RasterEraseCharacters(1);
  219.  
  220.             ScrollRaster(RPort,8,0,CursorX * 8,CursorY * 8,Window -> Width - 1,(CursorY + 1) * 8 - 1);
  221.  
  222.             BackupRender();
  223.         }
  224.  
  225.         SetCursor();
  226.     }
  227. }
  228.  
  229.     /* Raise(UWORD Colour):
  230.      *
  231.      *    Make an RGB value brighter.
  232.      */
  233.  
  234. STATIC UWORD
  235. Raise(UWORD Colour)
  236. {
  237.     SHORT r,g,b;
  238.  
  239.     r = ((Colour >> 8) & 0xF) + 4;
  240.     g = ((Colour >> 4) & 0xF) + 4;
  241.     b = ((Colour     ) & 0xF) + 4;
  242.  
  243.     if(r > 15)
  244.         r = 15;
  245.  
  246.     if(g > 15)
  247.         g = 15;
  248.  
  249.     if(b > 15)
  250.         b = 15;
  251.  
  252.     return(r << 8 | g << 4 | b);
  253. }
  254.  
  255.     /* VisualBeep():
  256.      *
  257.      *    `Beep' the screen visually.
  258.      */
  259.  
  260. STATIC BYTE
  261. VisualBeep()
  262. {
  263.     struct UCopList    *UserCopperList;
  264.  
  265.         /* Create a user copper list. */
  266.  
  267.     if(UserCopperList = (struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_PUBLIC|MEMF_CLEAR))
  268.     {
  269.         SHORT i;
  270.  
  271.             /* Initialize for 35 commands. */
  272.  
  273.         CINIT(UserCopperList,2 + 16 + 16 + 1);
  274.  
  275.             /* Wait until first line of window. */
  276.  
  277.         CWAIT(UserCopperList,Window -> TopEdge,0);
  278.  
  279.             /* Set the light colours. */
  280.  
  281.         for(i = 0 ; i < 16 ; i++)
  282.             CMOVE(UserCopperList,custom . color[i],Raise(GetRGB4(Screen -> ViewPort . ColorMap,i)));
  283.  
  284.             /* Wait until bottom of window. */
  285.  
  286.         CWAIT(UserCopperList,Window -> TopEdge + Window -> Height - 1,0);
  287.  
  288.             /* Set the standard colours. */
  289.  
  290.         for(i = 0 ; i < 16 ; i++)
  291.             CMOVE(UserCopperList,custom . color[i],GetRGB4(Screen -> ViewPort . ColorMap,i));
  292.  
  293.             /* Finish list. */
  294.  
  295.         CEND(UserCopperList);
  296.  
  297.             /* Lock the screen. */
  298.  
  299.         LockLayers(&Screen -> LayerInfo);
  300.  
  301.             /* Install user copper list... */
  302.  
  303.         Screen -> ViewPort . UCopIns = UserCopperList;
  304.  
  305.             /* ...and display it. */
  306.  
  307.         RethinkDisplay();
  308.  
  309.         return(TRUE);
  310.     }
  311. }
  312.  
  313.     /* DoSomeBeep():
  314.      *
  315.      *    Special function: beep the terminal.
  316.      */
  317.  
  318. VOID
  319. DoSomeBeep()
  320. {
  321.         /* Handle the visual part. */
  322.  
  323.     if(Config . VisibleBell)
  324.     {
  325.         if(VisualBeep())
  326.         {
  327.             if(Config . AudibleBell)
  328.                 Beep();
  329.  
  330.             Delay(25);
  331.  
  332.                 /* Remove the copper list. */
  333.  
  334.             FreeVPortCopLists(&Screen -> ViewPort);
  335.  
  336.                 /* Really remove it. */
  337.  
  338.             RemakeDisplay();
  339.  
  340.                 /* Unlock screen layers. */
  341.  
  342.             UnlockLayers(&Screen -> LayerInfo);
  343.         }
  344.         else
  345.         {
  346.             if(Config . AudibleBell)
  347.                 Beep();
  348.         }
  349.     }
  350.     else
  351.     {
  352.             /* Let it beep. */
  353.  
  354.         if(Config . AudibleBell)
  355.             Beep();
  356.  
  357.         Delay(25);
  358.     }
  359.  
  360.     if(!Config . CaptureFilter)
  361.         Capture("\a",1);
  362. }
  363.  
  364.     /* DoLF():
  365.      *
  366.      *    Special function: perform line feed.
  367.      */
  368.  
  369. VOID
  370. DoLF()
  371. {
  372.     ClearCursor();
  373.  
  374.     if(UseRegion)
  375.     {
  376.         if(CursorY == Bottom)
  377.             ScrollRegion(8);
  378.         else
  379.         {
  380.             CursorY++;
  381.  
  382.             SetCursor();
  383.         }
  384.     }
  385.     else
  386.     {
  387.         if(CursorY == LastLine)
  388.             ScrollRegion(8);
  389.         else
  390.         {
  391.             CursorY++;
  392.  
  393.             SetCursor();
  394.         }
  395.     }
  396. }
  397.  
  398.     /* DoIgnore():
  399.      *
  400.      *    Special function: don't do anything.
  401.      */
  402.  
  403. VOID
  404. DoIgnore()
  405. {
  406. }
  407.  
  408.     /* DoCR_LF():
  409.      *
  410.      *    Special function: perform carriage return and line feed.
  411.      */
  412.  
  413. VOID
  414. DoCR_LF()
  415. {
  416.     ClearCursor();
  417.  
  418.     CursorX = 0;
  419.  
  420.     if(UseRegion)
  421.     {
  422.         if(CursorY == Bottom)
  423.             ScrollRegion(8);
  424.         else
  425.         {
  426.             CursorY++;
  427.  
  428.             SetCursor();
  429.         }
  430.     }
  431.     else
  432.     {
  433.         if(CursorY == LastLine)
  434.             ScrollRegion(8);
  435.         else
  436.         {
  437.             CursorY++;
  438.  
  439.             SetCursor();
  440.         }
  441.     }
  442.  
  443.     if(Config . CaptureFilter)
  444.         Capture("\n",1);
  445.     else
  446.         Capture("\r\n",2);
  447. }
  448.  
  449.     /* DoFF():
  450.      *
  451.      *    Special function: perform form feed.
  452.      */
  453.  
  454. VOID
  455. DoFF()
  456. {
  457.     ClearCursor();
  458.  
  459.     if(Config . NewLine)
  460.     {
  461.         CursorX = 0;
  462.  
  463.         if(UseRegion)
  464.         {
  465.             if(CursorY == Bottom)
  466.                 ScrollRegion(8);
  467.             else
  468.             {
  469.                 CursorY++;
  470.  
  471.                 SetCursor();
  472.             }
  473.         }
  474.         else
  475.         {
  476.             if(CursorY == LastLine)
  477.                 ScrollRegion(8);
  478.             else
  479.             {
  480.                 CursorY++;
  481.  
  482.                 SetCursor();
  483.             }
  484.         }
  485.  
  486.         if(Config . CaptureFilter)
  487.             Capture("\n",1);
  488.         else
  489.             Capture("\r\n",2);
  490.     }
  491.     else
  492.     {
  493.         EraseScreen("2");
  494.  
  495.         CursorX = CursorY = 0;
  496.  
  497.         SetCursor();
  498.  
  499.         if(Config . CaptureFilter)
  500.             Capture("\n",1);
  501.         else
  502.             Capture("\f",1);
  503.     }
  504. }
  505.  
  506.     /* DoLF_FF_VT():
  507.      *
  508.      *    Special function: handle line feed, form feed and vertical
  509.      *    tab.
  510.      */
  511.  
  512. VOID
  513. DoLF_FF_VT()
  514. {
  515.     if(Config . NewLine)
  516.         DoCR_LF();
  517.     else
  518.         DoLF();
  519. }
  520.  
  521.     /* DoCR():
  522.      *
  523.      *    Special function: handle carriage return.
  524.      */
  525.  
  526. VOID
  527. DoCR()
  528. {
  529.     if(Config . NewLine)
  530.         DoCR_LF();
  531.     else
  532.     {
  533.         ClearCursor();
  534.  
  535.         CursorX = 0;
  536.  
  537.         SetCursor();
  538.  
  539.         if(Config . CaptureFilter)
  540.             Capture("\n",1);
  541.         else
  542.             Capture("\r",1);
  543.     }
  544. }
  545.  
  546.     /* DoTab():
  547.      *
  548.      *    Special function: handle tab, move cursor to next
  549.      *    tab stop.
  550.      */
  551.  
  552. VOID
  553. DoTab()
  554. {
  555.     ClearCursor();
  556.  
  557.     if(CursorX < LastColumn)
  558.     {
  559.         SHORT i;
  560.  
  561.         for(i = CursorX + 1 ; i <= LastColumn ; i++)
  562.         {
  563.             if(TabStops[i])
  564.             {
  565.                 CursorX = i;
  566.  
  567.                 SetCursor();
  568.  
  569.                 Capture("\t",1);
  570.  
  571.                 return;
  572.             }
  573.         }
  574.     }
  575.  
  576.     Capture("\t",1);
  577.  
  578.     CursorX = 0;
  579.  
  580.     if(UseRegion)
  581.     {
  582.         if(CursorY == Bottom)
  583.             ScrollRegion(8);
  584.         else
  585.         {
  586.             CursorY++;
  587.  
  588.             SetCursor();
  589.         }
  590.     }
  591.     else
  592.     {
  593.         if(CursorY == LastLine)
  594.             ScrollRegion(8);
  595.         else
  596.         {
  597.             CursorY++;
  598.  
  599.             SetCursor();
  600.         }
  601.     }
  602. }
  603.  
  604.     /* SpillTheBeans(UBYTE *Buffer,LONG Size):
  605.      *
  606.      *    Output a buffer of given size to the terminal
  607.      *    window.
  608.      */
  609.  
  610. VOID
  611. SpillTheBeans(UBYTE *Buffer,LONG Size)
  612. {
  613.         /* The slow method: insert characters at of the
  614.          * initial cursor position and shift the remaining
  615.          * screen characters to the right.
  616.          */
  617.  
  618.     if(Config . InsertChar)
  619.     {
  620.             /* Do we still have a character in the
  621.              * magnificient buffer?
  622.              */
  623.  
  624.         while(Size--)
  625.         {
  626.                 /* Shift the character(s) over. */
  627.  
  628.             if(CursorX != LastColumn)
  629.             {
  630.                 RasterShiftChar();
  631.  
  632.                 ShiftChar();
  633.             }
  634.  
  635.                 /* The cursor hasn't hit the right
  636.                  * margin, has it? So let's print a
  637.                  * single character.
  638.                  */
  639.  
  640.             ClearCursor();
  641.  
  642.             if(CursorX++ <= LastColumn)
  643.             {
  644.                     /* Real-time font scaling
  645.                      * enabled?
  646.                      */
  647.  
  648.                 if(Config . FontScale)
  649.                 {
  650.                     if(CursorX != LastColumn)
  651.                     {
  652.                         RasterShiftChar();
  653.  
  654.                         ShiftChar();
  655.                     }
  656.  
  657.                     CursorX--;
  658.  
  659.                     PrintScaled(*Buffer++);
  660.                 }
  661.                 else
  662.                 {
  663.                     RasterPutString(Buffer,1);
  664.  
  665.                     Text(RPort,Buffer,1);
  666.  
  667.                     Buffer++;
  668.                 }
  669.             }
  670.             else
  671.             {
  672.                     /* Cursor is positioned at
  673.                      * the right hand side of the
  674.                      * display. If auto-wrap is
  675.                      * enabled, perform some
  676.                      * kind of CR/LF, else leave
  677.                      * the cursor where it is.
  678.                      */
  679.  
  680.                 if(Config . AutoWrap)
  681.                 {
  682.                     if(UseRegion)
  683.                     {
  684.                         if(CursorY == Bottom)
  685.                             ScrollRegion(8);
  686.                         else
  687.                             CursorY++;
  688.  
  689.                         Capture("\n",1);
  690.                     }
  691.                     else
  692.                     {
  693.                         if(CursorY == LastLine)
  694.                             ScrollRegion(8);
  695.                         else
  696.                             CursorY++;
  697.  
  698.                         Capture("\n",1);
  699.                     }
  700.  
  701.                     CursorX = 0;
  702.                 }
  703.                 else
  704.                     CursorX = LastColumn;
  705.             }
  706.  
  707.             SetCursor();
  708.         }
  709.     }
  710.     else
  711.     {
  712.             /* Do we still have a character in the
  713.              * magnificient buffer?
  714.              */
  715.  
  716.         while(Size > 0)
  717.         {
  718.                 /* Cursor is positioned at
  719.                  * the right hand side of the
  720.                  * display. If auto-wrap is
  721.                  * enabled, perform some
  722.                  * kind of CR/LF, else leave
  723.                  * the cursor where it is and
  724.                  * quit the show.
  725.                  */
  726.  
  727.             ClearCursor();
  728.  
  729.             if(CursorX > LastColumn)
  730.             {
  731.                 if(Config . AutoWrap)
  732.                 {
  733.                     CursorX = 0;
  734.  
  735.                     if(UseRegion)
  736.                     {
  737.                         if(CursorY == Bottom)
  738.                             ScrollRegion(8);
  739.                         else
  740.                         {
  741.                             CursorY++;
  742.  
  743.                             SetCursor();
  744.                         }
  745.  
  746.                         Capture("\n",1);
  747.                     }
  748.                     else
  749.                     {
  750.                         if(CursorY == LastLine)
  751.                             ScrollRegion(8);
  752.                         else
  753.                         {
  754.                             CursorY++;
  755.  
  756.                             SetCursor();
  757.                         }
  758.  
  759.                         Capture("\n",1);
  760.                     }
  761.                 }
  762.                 else
  763.                 {
  764.                     CursorX = LastColumn;
  765.  
  766.                     SetCursor();
  767.  
  768.                     return;
  769.                 }
  770.             }
  771.             else
  772.             {
  773.                     /* Real-time font scaling
  774.                      * enabled?
  775.                      */
  776.  
  777.                 if(Config . FontScale)
  778.                 {
  779.                     while(CursorX <= LastColumn && Size)
  780.                     {
  781.                         PrintScaled(*Buffer++);
  782.  
  783.                         Size--;
  784.                     }
  785.  
  786.                     SetCursor();
  787.                 }
  788.                 else
  789.                 {
  790.                     SHORT Offset;
  791.  
  792.                         /* We won't have to take
  793.                          * care of characters to shift.
  794.                          * We'll collect as many
  795.                          * characters in the buffer as will
  796.                          * fit into the current line
  797.                          * and print them.
  798.                          */
  799.  
  800.                     if((Offset = LastColumn + 1 - CursorX) > Size)
  801.                         Offset = Size;
  802.  
  803.                     RasterPutString(Buffer,Offset);
  804.  
  805.                     Text(RPort,Buffer,Offset);
  806.  
  807.                     Size -= Offset;
  808.  
  809.                     CursorX += Offset;
  810.  
  811.                     SetCursor();
  812.                 }
  813.             }
  814.         }
  815.     }
  816. }
  817.  
  818.     /* ConWrite(APTR Buffer,LONG Size):
  819.      *
  820.      *    Write a string to the console window.
  821.      */
  822.  
  823. VOID
  824. ConWrite(APTR Buffer,LONG Size)
  825. {
  826.     STATIC UBYTE     StringBuffer[200],BufSize = 0;
  827.     UBYTE        *Char = Buffer;
  828.  
  829.         /* Run down the buffer. */
  830.  
  831.     while(Size--)
  832.     {
  833.             /* Are we parsing a control sequence? */
  834.  
  835.         if(InSequence)
  836.         {
  837.             if(*Char == ESC)
  838.             {
  839.                 DoCancel();
  840.                 InSequence = TRUE;
  841.  
  842.                 if(!Config . CaptureFilter)
  843.                     Capture("\033",1);
  844.             }
  845.             else
  846.             {
  847.                 if(!Config . CaptureFilter)
  848.                     Capture(Char,1);
  849.  
  850.                     /* See if we are already done. */
  851.  
  852.                 InSequence = ParseCode(*Char++);
  853.             }
  854.         }
  855.         else
  856.         {
  857.                 /* This looks like a control sequence
  858.                  * introducing character.
  859.                  */
  860.  
  861.             if(*Char == ESC || *Char == CSI)
  862.             {
  863.                 if(BufSize)
  864.                 {
  865.                     Capture(&StringBuffer[0],BufSize);
  866.  
  867.                     SpillTheBeans(&StringBuffer[0],BufSize);
  868.  
  869.                     BufSize = 0;
  870.                 }
  871.  
  872.                     /* So we're in TTY mode,
  873.                      * escape the `escape' character
  874.                      * and continue.
  875.                      */
  876.  
  877.                 if(Config . Emulation == EMULATION_TTY)
  878.                 {
  879.                     if(*Char == ESC)
  880.                     {
  881.                         StringBuffer[BufSize++] = '^';
  882.                         StringBuffer[BufSize++] = '[';
  883.  
  884.                         if(!Config . CaptureFilter)
  885.                             Capture("\033",1);
  886.                     }
  887.                     else
  888.                     {
  889.                             /* Fake a CSI. */
  890.  
  891.                         StringBuffer[BufSize++] = '^';
  892.                         StringBuffer[BufSize++] = '[';
  893.  
  894.                         if(!Config . CaptureFilter)
  895.                             Capture("\033[",2);
  896.                     }
  897.                 }
  898.                 else
  899.                 {
  900.                     if(*Char == ESC)
  901.                     {
  902.                         InSequence = TRUE;
  903.     
  904.                         if(!Config . CaptureFilter)
  905.                             Capture("\033",1);
  906.                     }
  907.                     else
  908.                         CSIFake();
  909.                 }
  910.  
  911.                 Char++;
  912.             }
  913.             else
  914.             {
  915.                     /* Stuff the character into
  916.                      * the buffer.
  917.                      */
  918.  
  919.                 StringBuffer[BufSize++] = *Char++;
  920.  
  921.                     /* If buffer is full, spill it. */
  922.  
  923.                 if(BufSize == 200)
  924.                 {
  925.                     Capture(&StringBuffer[0],BufSize);
  926.  
  927.                     SpillTheBeans(&StringBuffer[0],BufSize);
  928.  
  929.                     BufSize = 0;
  930.                 }
  931.             }
  932.         }
  933.     }
  934.  
  935.         /* Any characters in the buffer we didn't process yet? */
  936.  
  937.     if(!InSequence && BufSize)
  938.     {
  939.         Capture(&StringBuffer[0],BufSize);
  940.  
  941.         SpillTheBeans(&StringBuffer[0],BufSize);
  942.  
  943.         BufSize = 0;
  944.     }
  945. }
  946.  
  947.     /* ConProcess(UBYTE *String,LONG Size):
  948.      *
  949.      *    Process the contents of a string to be sent to the
  950.      *    console window.
  951.      */
  952.  
  953. VOID
  954. ConProcess(UBYTE *String,LONG Size)
  955. {
  956.     LONG i,j;
  957.  
  958.         /* In quiet mode no characters are echoed to the
  959.          * console window, they are just passed through
  960.          * the data flow filter. This mode is enabled
  961.          * by the dial panel.
  962.          */
  963.  
  964.     if(Quiet)
  965.     {
  966.         for(i = 0 ; i < Size ; i++)
  967.             FlowFilter(String[i]);
  968.     }
  969.     else
  970.     {
  971.             /* If the current font is Topaz, some bytes
  972.              * will need to be filtered since they are not
  973.              * defined as valid ASCII characters.
  974.              */
  975.  
  976.         if(Config . Font == FONT_TOPAZ)
  977.         {
  978.             for(i = 0, j = 0 ; i < Size ; i++)
  979.             {
  980.                 FlowFilter(String[i]);
  981.  
  982.                 if(IsPrintable(String[i]))
  983.                 {
  984.                         /* This character is
  985.                          * associated with a
  986.                          * special function
  987.                          * (bell, xon, xoff, etc.).
  988.                          */
  989.  
  990.                     if(SpecialMap[String[i]] != -1)
  991.                     {
  992.                         if(j)
  993.                         {
  994.                             ConWrite(SharedBuffer,j);
  995.  
  996.                             j = 0;
  997.                         }
  998.  
  999.                         SpecialKeys[SpecialMap[String[i]]] . Routine();
  1000.                     }
  1001.                     else
  1002.                     {
  1003.                             /* Put the character
  1004.                              * into the buffer
  1005.                              * and empty it if
  1006.                              * necessary.
  1007.                              */
  1008.  
  1009.                         SharedBuffer[j] = String[i];
  1010.  
  1011.                         if(j++ == 512)
  1012.                         {
  1013.                             ConWrite(SharedBuffer,j);
  1014.  
  1015.                             j = 0;
  1016.                         }
  1017.                     }
  1018.                 }
  1019.             }
  1020.         }
  1021.         else
  1022.         {
  1023.                 /* In IBM font mode, any character gives
  1024.                  * a sensible result.
  1025.                  */
  1026.  
  1027.             for(i = 0, j = 0 ; i < Size ; i++)
  1028.             {
  1029.                 FlowFilter(String[i]);
  1030.  
  1031.                 if(SpecialMap[String[i]] != -1)
  1032.                 {
  1033.                     if(j)
  1034.                     {
  1035.                         ConWrite(SharedBuffer,j);
  1036.  
  1037.                         j = 0;
  1038.                     }
  1039.  
  1040.                     SpecialKeys[SpecialMap[String[i]]] . Routine();
  1041.                 }
  1042.                 else
  1043.                 {
  1044.                     SharedBuffer[j] = String[i];
  1045.  
  1046.                     if(j++ == 512)
  1047.                     {
  1048.                         ConWrite(SharedBuffer,j);
  1049.  
  1050.                         j = 0;
  1051.                     }
  1052.                 }
  1053.             }
  1054.         }
  1055.  
  1056.         if(j)
  1057.             ConWrite(SharedBuffer,j);
  1058.     }
  1059. }
  1060.  
  1061.     /* ConWrites(UBYTE *String,...):
  1062.      *
  1063.      *    Output a string to the console.
  1064.      */
  1065.  
  1066. VOID __stdargs
  1067. ConWrites(UBYTE *String,...)
  1068. {
  1069.     va_list    VarArgs;
  1070.  
  1071.     va_start(VarArgs,String);
  1072.     VSPrintf(SharedBuffer,String,VarArgs);
  1073.     va_end(VarArgs);
  1074.  
  1075.     ConProcess(SharedBuffer,strlen(SharedBuffer));
  1076. }
  1077.  
  1078.     /* KeyConvert(struct IntuiMessage *Massage,UBYTE *Buffer):
  1079.      *
  1080.      *    Convert a raw key information according to the
  1081.      *    current keymap settings.
  1082.      */
  1083.  
  1084. UBYTE
  1085. KeyConvert(struct IntuiMessage *Massage,UBYTE *Buffer)
  1086. {
  1087.     if(Buffer)
  1088.         Buffer[0] = 0;
  1089.  
  1090.     if(Massage -> Class == IDCMP_RAWKEY)
  1091.     {
  1092.             /* These are the sequences mapped to special
  1093.              * control keys (cursor keys, function keys,
  1094.              * the help key).
  1095.              */
  1096.  
  1097.         STATIC struct
  1098.         {
  1099.             UBYTE *RawCode;
  1100.             UBYTE Result;
  1101.         } ConversionTable[16] =
  1102.         {
  1103.             (UBYTE *)"A",    CUP,
  1104.             (UBYTE *)"B",    CDN,
  1105.             (UBYTE *)"C",    CFW,
  1106.             (UBYTE *)"D",    CBK,
  1107.  
  1108.             (UBYTE *)"?~",    HLP,
  1109.  
  1110.             (UBYTE *)"0~",    FN1,
  1111.             (UBYTE *)"1~",    FN2,
  1112.             (UBYTE *)"2~",    FN3,
  1113.             (UBYTE *)"3~",    FN4,
  1114.             (UBYTE *)"4~",    FN5,
  1115.             (UBYTE *)"5~",    FN6,
  1116.             (UBYTE *)"6~",    FN7,
  1117.             (UBYTE *)"7~",    FN8,
  1118.             (UBYTE *)"8~",    FN9,
  1119.             (UBYTE *)"9~",    F10
  1120.         };
  1121.  
  1122.             /* Key was pressed, not released. */
  1123.  
  1124.         if(!(Massage -> Code & IECODE_UP_PREFIX))
  1125.         {
  1126.             UBYTE    ConvertBuffer[257],i;
  1127.             ULONG    Qualifier = Massage -> Qualifier;
  1128.  
  1129.                 /* If it's a function key clear the qualifier. */
  1130.  
  1131.             if(Massage -> Code >= 80 && Massage -> Code <= 89)
  1132.                 Qualifier = 0;
  1133.  
  1134.                 /* Clear the buffer. */
  1135.  
  1136.             memset(&ConvertBuffer[0],0,257);
  1137.  
  1138.                 /* Convert the key. */
  1139.  
  1140.             FakeInputEvent -> ie_Code        = Massage -> Code;
  1141.             FakeInputEvent -> ie_Qualifier        = Qualifier;
  1142.             FakeInputEvent -> ie_position . ie_addr    = *((APTR *)Massage -> IAddress);
  1143.  
  1144.             if(RawKeyConvert(FakeInputEvent,(UBYTE *)ConvertBuffer,257,NULL) > 0)
  1145.             {
  1146.                 if(ConvertBuffer[0])
  1147.                 {
  1148.                     if(Buffer)
  1149.                         strcpy(Buffer,ConvertBuffer);
  1150.  
  1151.                         /* Translated sequence starts
  1152.                          * with a CSI, let's have a look
  1153.                          * at the associated control
  1154.                          * key.
  1155.                          */
  1156.  
  1157.                     if(ConvertBuffer[0] == CSI)
  1158.                     {
  1159.                         for(i = 0 ; i < 16 ; i++)
  1160.                         {
  1161.                             if(!StrCmp(&ConvertBuffer[1],ConversionTable[i] . RawCode))
  1162.                             {
  1163.                                 ConvertBuffer[0] = ConversionTable[i] . Result;
  1164.  
  1165.                                 if(Buffer)
  1166.                                 {
  1167.                                     Buffer[0] = ConversionTable[i] . Result;
  1168.                                     Buffer[1] = 0;
  1169.                                 }
  1170.  
  1171.                                 break;
  1172.                             }
  1173.                         }
  1174.                     }
  1175.  
  1176.                     return(ConvertBuffer[0]);
  1177.                 }
  1178.             }
  1179.         }
  1180.     }
  1181.  
  1182.     return(0);
  1183. }
  1184.