home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / pibterm / pibt41s2.arc / PIBANSIA.MOD < prev    next >
Encoding:
Text File  |  1988-02-07  |  55.0 KB  |  1,393 lines

  1. (*----------------------------------------------------------------------*)
  2. (*                Emulate_ANSI  -- Controls VT100 emulation             *)
  3. (*----------------------------------------------------------------------*)
  4.  
  5. PROCEDURE Emulate_ANSI( VT100_Allowed : BOOLEAN );
  6.  
  7. (*----------------------------------------------------------------------*)
  8. (*                                                                      *)
  9. (*    Procedure: Emulate_ANSI                                           *)
  10. (*                                                                      *)
  11. (*    Purpose:   Controls ANSI terminal emulation                       *)
  12. (*                                                                      *)
  13. (*    Calling Sequence:                                                 *)
  14. (*                                                                      *)
  15. (*       Emulate_ANSI( VT100_allowed );                                 *)
  16. (*                                                                      *)
  17. (*          VT100_allowed --- TRUE to interpret private DEC sequences   *)
  18. (*                                                                      *)
  19. (*    Remarks:                                                          *)
  20. (*                                                                      *)
  21. (*       The ANSI and VT100 emulation are partly based upon TMODEM      *)
  22. (*       by Paul Meiners and partly upon ISP100 by Tim Krauskopf.       *)
  23. (*                                                                      *)
  24. (*       VT100/ANSI commands are interpreted directly by these          *)
  25. (*       routines -- the ANSI.SYS driver is not required and should     *)
  26. (*       probably not be used, as it will result in an unnecessary      *)
  27. (*       performance degradation.                                       *)
  28. (*                                                                      *)
  29. (*       This is by no means a complete VT100 or Ansi emulation.  It    *)
  30. (*       works well enough so that the full-screen editors EDT under    *)
  31. (*       VAX/VMS and FSE under CDC/NOS will perform properly.  That was *)
  32. (*       my primary intention.  You may want to add code to emulate     *)
  33. (*       other VT100/VT102/VT103/VT131 features not found here.  If you *)
  34. (*       do, please send me back a copy so that I can add your upgrades *)
  35. (*       to future releases of PibTerm.                                 *)
  36. (*                                                                      *)
  37. (*       ANSI/BBS mode assumes 25 lines on the screen.  VT100 mode      *)
  38. (*       assumes only has 24.                                           *)
  39. (*                                                                      *)
  40. (*       The following variables are of central interest in the         *)
  41. (*       emulation:                                                     *)
  42. (*                                                                      *)
  43. (*         Escape_Mode     --- TRUE if processing escape sequence       *)
  44. (*         Escape_Type     --- Type of escape sequence being processed  *)
  45. (*         Escape_Number   --- Number of numeric parameters in escape   *)
  46. (*                             sequence                                 *)
  47. (*         Escape_Register --- array of numeric parameters in escape    *)
  48. (*                             sequence                                 *)
  49. (*         Escape_Str      --- stores string of escape text; used to    *)
  50. (*                             gather up a musical score for BBS Ansi.  *)
  51. (*                                                                      *)
  52. (*----------------------------------------------------------------------*)
  53.  
  54. CONST
  55.    Allow_Doubling      : BOOLEAN     (* TRUE to allow double width      *)
  56.                          = TRUE;
  57.  
  58. VAR
  59.    Comm_Ch             : CHAR        (* Character read from comm port   *);
  60.    Double_Ch           : CHAR        (* Character for double-width mode *);
  61.    Kbd_Ch              : CHAR        (* Character read from keyboard    *);
  62.    Done                : BOOLEAN     (* TRUE to stop PIBTERM            *);
  63.    B                   : BOOLEAN     (* General purpose flag            *);
  64.    Graph_Ch            : BYTE        (* Graphics character              *);
  65.    Itab                : BYTE        (* Tab stop                        *);
  66.    Tabcol              : BYTE        (* Tab column                      *);
  67.    Print_Line          : AnyStr      (* Line to print if print mode on  *);
  68.    Local_Save          : Saved_Screen_Ptr;
  69.    Reset_Attr          : BOOLEAN;
  70.    SVal                : STRING[10];
  71.    Do_Graphics_Mode    : BOOLEAN;
  72.    ClrScr_Request      : BOOLEAN;
  73.    VT100_G0_Set        : CHAR;
  74.    VT100_G1_Set        : CHAR;
  75.    VT100_G0_State      : BOOLEAN;
  76.    Save_Dos_Con        : BOOLEAN;
  77.    Save_Do_Status      : BOOLEAN;
  78.    Save_Double         : BOOLEAN;
  79.  
  80. VAR                                  (* Special output characters *)
  81.  
  82.    Special_Comm  : ARRAY[0..255] OF BOOLEAN;
  83.  
  84.                                      (* VT100 tabs stops                *)
  85. VAR
  86.    Number_VT100_Tabs : INTEGER;
  87.  
  88.    VT100_Tabs:  Tab_Stop_Vector;
  89.  
  90. (*----------------------------------------------------------------------*)
  91. (*      Ansi_Check_Line_Attributes --- Checks attributes for a line     *)
  92. (*----------------------------------------------------------------------*)
  93.  
  94. PROCEDURE Ansi_Check_Line_Attributes( Y: INTEGER );
  95.  
  96. BEGIN (* Ansi_Check_Line_Attributes *)
  97.  
  98.    CASE Line_Attributes[ Y ] OF
  99.       3,
  100.       4,
  101.       6: Double_Width_Mode := Allow_Doubling;
  102.       ELSE
  103.          Double_Width_Mode := OFF;
  104.    END (* CASE *);
  105.  
  106. END   (* Ansi_Check_Line_Attributes *);
  107.  
  108. (*----------------------------------------------------------------------*)
  109. (*       Ansi_Scroll_Attributes --- Scrolls attributes for lines        *)
  110. (*----------------------------------------------------------------------*)
  111.  
  112. PROCEDURE Ansi_Scroll_Attributes( Y1, Y2, Lines : INTEGER );
  113.  
  114. VAR
  115.    I : INTEGER;
  116.    N : INTEGER;
  117.  
  118. BEGIN (* Ansi_Scroll_Attributes *)
  119.  
  120.    IF ( Lines = 0 ) THEN           (* Zero out line attributes *)
  121.       FOR I := Y1 TO Y2 DO
  122.          Line_Attributes[ I ] := 0
  123.  
  124.    ELSE IF ( Lines > 0 ) THEN      (* Scroll up the attr. array *)
  125.       BEGIN
  126.  
  127.          N := MAX( 0 , MIN( Lines , SUCC( Y2 - Y1 ) ) );
  128.  
  129.          MOVE( Line_Attributes[ Y2 ], Line_Attributes[ Y1 ], N );
  130.  
  131.          FOR I := PRED( Y1 + N ) TO Bottom_Scroll DO
  132.             Line_Attributes[ I ] := 0;
  133.  
  134.       END
  135.  
  136.    ELSE                            (* Scroll down the attr. array *)
  137.       BEGIN
  138.  
  139.          N := MAX( 0 , MIN( ABS( Lines ) , SUCC( Y2 - Y1 ) ) );
  140.  
  141.          MOVE( Line_Attributes[ Y1 ], Line_Attributes[ Y2 ], N );
  142.  
  143.          FOR I := Y1 TO PRED( Y2 ) DO
  144.             Line_Attributes[ I ] := 0;
  145.  
  146.       END;
  147.                                    (* Ensure last column hit is set FALSE *)
  148.    Last_Column_Hit := FALSE;
  149.  
  150. END   (* Ansi_Scroll_Attributes *);
  151.  
  152. (*----------------------------------------------------------------------*)
  153. (*           Ansi_WhereX --- What LOGICAL column is cursor in           *)
  154. (*----------------------------------------------------------------------*)
  155.  
  156. FUNCTION Ansi_WhereX : INTEGER;
  157.  
  158. VAR
  159.    X : INTEGER;
  160.  
  161. BEGIN (* Ansi_WhereX *)
  162.  
  163.    X := WhereX;
  164.  
  165.    IF Double_Width_Mode THEN
  166.       X := SUCC( X ) SHR 1;
  167.  
  168.    Ansi_WhereX := X;
  169.  
  170. END   (* Ansi_WhereX *);
  171.  
  172. (*----------------------------------------------------------------------*)
  173. (*            Set_Cursor --- Set cursor to specified screen location    *)
  174. (*----------------------------------------------------------------------*)
  175.  
  176. PROCEDURE Set_Cursor( X , Y : INTEGER );
  177.  
  178. VAR
  179.    XX : INTEGER;
  180.  
  181. BEGIN (* Set_Cursor *)
  182.  
  183.    Ansi_Check_Line_Attributes( Y );
  184.  
  185.    IF Double_Width_Mode THEN
  186.       BEGIN
  187.          XX := PRED( X * 2 );
  188.          IF ( XX > Wrap_Screen_Col ) THEN
  189.             CASE ODD( Wrap_Screen_Col ) OF
  190.                TRUE : XX := Wrap_Screen_Col;
  191.                FALSE: XX := PRED( Wrap_Screen_Col );
  192.             END (* CASE *);
  193.          GoToXY( XX , Y );
  194.       END
  195.    ELSE
  196.       GoToXY( X , Y );
  197.  
  198. END   (* Set_Cursor *);
  199.  
  200. (*----------------------------------------------------------------------*)
  201. (*             Ansi_Set_Graphics --- Set graphics display               *)
  202. (*----------------------------------------------------------------------*)
  203.  
  204. PROCEDURE Ansi_Set_Graphics;
  205.  
  206. (*----------------------------------------------------------------------*)
  207. (*                                                                      *)
  208. (*     Procedure: Ansi_Set_Graphics                                     *)
  209. (*                                                                      *)
  210. (*     Purpose:   Sets graphics rendition modes for ANSI/VT100          *)
  211. (*                                                                      *)
  212. (*     Calling Sequence:                                                *)
  213. (*                                                                      *)
  214. (*        Ansi_Set_Graphics;                                            *)
  215. (*                                                                      *)
  216. (*     Calls:                                                           *)
  217. (*                                                                      *)
  218. (*        Set_Global_Colors                                             *)
  219. (*                                                                      *)
  220. (*     Called by:  VT100_Process_Escape                                 *)
  221. (*                 Ansi_Process_Escape                                  *)
  222. (*                                                                      *)
  223. (*----------------------------------------------------------------------*)
  224.  
  225. VAR
  226.    I     : INTEGER;
  227.    J     : INTEGER;
  228.  
  229. BEGIN (* Ansi_Set_Graphics *)
  230.  
  231.    IF ( Escape_Number = 0 ) THEN
  232.       BEGIN
  233.          Escape_Number      := 1;
  234.          Escape_Register[1] := 0;
  235.       END;
  236.  
  237.    FOR I := 1 TO Escape_Number DO
  238.       BEGIN
  239.  
  240.          CASE Escape_Register[I] OF
  241.  
  242.             0 : BEGIN
  243.                    IF VT100_Allowed THEN
  244.                       BEGIN
  245.                          FG    := VT100_ForeGround_Color;
  246.                          BG    := VT100_BackGround_Color;
  247.                       END
  248.                    ELSE
  249.                       BEGIN
  250.                          FG    := LightGray;
  251.                          BG    := Black;
  252.                          Set_Border_Color( Black );
  253.                       END;
  254.                    Bolding_On  := FALSE;
  255.                    Blinking_On := FALSE;
  256.                 END;
  257.  
  258.             1 : BEGIN
  259.                    IF VT100_Allowed THEN
  260.                       FG          := Ansi_Bold_Color
  261.                    ELSE
  262.                       FG          := Bold_Colors[ FG ];
  263.                    Bolding_On  := TRUE;
  264.                 END;
  265.  
  266.             4 : BEGIN
  267.                                    (* NOTE: In mono mode BLUE will    *)
  268.                                    (* correctly produce an underline. *)
  269.  
  270.                    FG := Ansi_Underline_Color;
  271.  
  272.                    IF Bolding_On THEN
  273.                       FG := Bold_Colors[ FG ];
  274.  
  275.                 END;
  276.  
  277.             5 : Blinking_On := TRUE;
  278.  
  279.             7 : BEGIN
  280.                    IF VT100_Allowed THEN
  281.                       BEGIN
  282.                          FG := Ansi_BackGround_Color;
  283.                          IF Bolding_On THEN
  284.                             BG := Ansi_Bold_Color
  285.                          ELSE
  286.                             BG := Ansi_ForeGround_Color;
  287.                       END
  288.                    ELSE
  289.                       BEGIN
  290.                          FG := Black;
  291.                          BG := LightGray;
  292.                       END;
  293.                 END;
  294.  
  295.             8 : FG := BG;
  296.  
  297.         30..37: IF ( Text_Mode = C80 ) THEN
  298.                    BEGIN
  299.                       IF Bolding_On THEN
  300.                          FG := Bold_Colors_2[ Escape_Register[I] - 30 ]
  301.                       ELSE
  302.                          FG := Normal_Colors_2[ Escape_Register[I] - 30 ];
  303.                    END;
  304.  
  305.         40..47: IF ( Text_Mode = C80 ) THEN
  306.                    BEGIN
  307.                       IF Bolding_On THEN
  308.                          BG := Bold_Colors_2[ Escape_Register[I] - 40 ]
  309.                       ELSE
  310.                          BG := Normal_Colors_2[ Escape_Register[I] - 40 ];
  311.                    END;
  312.  
  313.          END (* CASE *);
  314.  
  315.       END;
  316.                                    (* Change the colors *)
  317.    IF Blinking_On THEN
  318.       FG := FG + Blink;
  319.  
  320.    Set_Global_Colors( FG , BG );
  321.  
  322. END   (* Ansi_Set_Graphics *);
  323.  
  324. (*----------------------------------------------------------------------*)
  325. (*             Ansi_Set_Cursor --- Set cursor position                  *)
  326. (*----------------------------------------------------------------------*)
  327.  
  328. PROCEDURE Ansi_Set_Cursor;
  329.  
  330. (*----------------------------------------------------------------------*)
  331. (*                                                                      *)
  332. (*     Procedure: Ansi_Set_Cursor                                       *)
  333. (*                                                                      *)
  334. (*     Purpose:   Sets cursor position                                  *)
  335. (*                                                                      *)
  336. (*     Calling Sequence:                                                *)
  337. (*                                                                      *)
  338. (*        Ansi_Set_Cursor;                                              *)
  339. (*                                                                      *)
  340. (*     Calls:                                                           *)
  341. (*                                                                      *)
  342. (*        Max                                                           *)
  343. (*        Min                                                           *)
  344. (*        UpperLeft                                                     *)
  345. (*        Set_Cursor                                                    *)
  346. (*                                                                      *)
  347. (*     Called by:  VT100_Process_Escape                                 *)
  348. (*                 Ansi_Process_Escape                                  *)
  349. (*                                                                      *)
  350. (*----------------------------------------------------------------------*)
  351.  
  352. VAR
  353.    Row    : INTEGER;
  354.    Col    : INTEGER;
  355.    RowNow : INTEGER;
  356.  
  357. BEGIN (* Ansi_Set_Cursor *)
  358.                                    (* Get current row position *)
  359.    RowNow := WhereY;
  360.                                    (* Determine new row and column *)
  361.    CASE Escape_Number OF
  362.                                    (* Home cursor if no coords given *)
  363.       0 : BEGIN
  364.              Row := 1;
  365.              Col := 1;
  366.           END;
  367.                                    (* Column 1 is default, row provided *)
  368.       1 : BEGIN
  369.              Col := 1;
  370.              Row := Escape_Register[1];
  371.           END;
  372.                                    (* Both row and column provided *)
  373.       ELSE
  374.              Col := Escape_Register[2];
  375.              Row := Escape_Register[1];
  376.  
  377.    END;
  378.                                    (* Handle origin mode    *)
  379.    IF Origin_Mode THEN
  380.       Row := Row + PRED( Top_Scroll );
  381.  
  382.                                    (* Clip to screen size   *)
  383.  
  384.    Row := MAX( MIN( Row , Ansi_Last_Line  ) , 1 );
  385.    Col := MAX( MIN( Col , Wrap_Screen_Col ) , 1 );
  386.  
  387.                                    (* If we moved down 1 line,  *)
  388.                                    (* update the review buffer. *)
  389.    IF ( Row <> RowNow ) THEN
  390.       BEGIN
  391.          Last_Column_Hit := FALSE;
  392.          IF Review_On THEN
  393.             IF ( ORD( Review_Line[0] ) > 0 ) THEN
  394.                Update_Review_Pointers;
  395.       END;
  396.                                    (* Treat as if line written to *)
  397.                                    (* capture file.               *)
  398.    IF Capture_On THEN
  399.       Capture_Char( CHR( LF ) );
  400.  
  401.                                    (* Move to new coordinates *)
  402.    Set_Cursor( Col , Row );
  403.  
  404. END   (* Ansi_Set_Cursor *);
  405.  
  406. (*----------------------------------------------------------------------*)
  407. (*             Ansi_Clear_Screen --- Clear segment of screen            *)
  408. (*----------------------------------------------------------------------*)
  409.  
  410. PROCEDURE Ansi_Clear_Screen;
  411.  
  412. (*----------------------------------------------------------------------*)
  413. (*                                                                      *)
  414. (*     Procedure: Ansi_Clear_Screen                                     *)
  415. (*                                                                      *)
  416. (*     Purpose:   Clears portion of screen                              *)
  417. (*                                                                      *)
  418. (*     Calling Sequence:                                                *)
  419. (*                                                                      *)
  420. (*        Ansi_Clear_Screen;                                            *)
  421. (*                                                                      *)
  422. (*     Called by:  VT100_Process_Escape                                 *)
  423. (*                 Ansi_Process_Escape                                  *)
  424. (*                                                                      *)
  425. (*----------------------------------------------------------------------*)
  426.  
  427. VAR
  428.    I:        INTEGER;
  429.    X:        INTEGER;
  430.    Y:        INTEGER;
  431.    C:        INTEGER;
  432.    Blank_Line : AnyStr;
  433.    ATT:      INTEGER;
  434.  
  435. BEGIN (* Ansi_Clear_Screen *)
  436.                                    (* Update the review buffer. *)
  437.    IF Review_On THEN
  438.       IF ( ORD( Review_Line[0] ) > 0 ) THEN
  439.          Update_Review_Pointers;
  440.                                    (* Update capture file *)
  441.    IF Capture_On THEN
  442.       Capture_Char( CHR( LF ) );
  443.                                    (* Get type of clear to perform *)
  444.    IF ( Escape_Number = 1 )  THEN
  445.       C := Escape_Register[1]
  446.    ELSE
  447.       C := 0;
  448.  
  449.    Save_FG1 := FG;
  450.    Save_BG1 := BG;
  451.  
  452.    IF VT100_Allowed THEN
  453.       Set_Global_Colors( Ansi_ForeGround_Color , Ansi_BackGround_Color );
  454.  
  455.    X     := WhereX;
  456.    Y     := WhereY;
  457.  
  458.    CASE C OF
  459.                                    (* Clear from cursor position to *)
  460.                                    (* end of screen                 *)
  461.       0:  BEGIN
  462.  
  463.              ClrEol;
  464.  
  465.              FOR I := ( Y + 1 ) TO Ansi_Last_Line DO
  466.                 BEGIN
  467.                    GoToXY( 1 , I );
  468.                    ClrEol;
  469.                    Line_Attributes[I] := 0;
  470.                 END;
  471.  
  472.              GoToXY( X , Y );
  473.  
  474.           END;
  475.                                    (* Clear start of screen to current *)
  476.                                    (* cursor position                  *)
  477.       1:  BEGIN
  478.  
  479.              IF ( Y > 1 ) THEN
  480.                 Scroll( 1, Y - 1, 1, Max_Screen_Col, 0, FG, BG );
  481.  
  482.              GoToXY( 1 , Y );
  483.  
  484.              FOR I := 1 TO X DO
  485.                 WRITE(' ');
  486.  
  487.              FOR I := 1 TO Y DO
  488.                 Line_Attributes[I] := 0;
  489.  
  490.           END;
  491.                                    (* Clear entire screen *)
  492.       2:  BEGIN
  493.  
  494.              Scroll( 1, Ansi_Last_Line, 1, Max_Screen_Col, 0, FG, BG );
  495. {
  496.              Blank_Line := DUPL( ' ' , Max_Screen_Col );
  497.              ATT        := ( ( BG AND 7 ) SHL 4 ) OR FG;
  498.              FOR I := 1 TO Ansi_Last_Line DO
  499.                 WriteSXY( Blank_Line, 1, I, ATT );
  500. }
  501.              FillChar( Line_Attributes, Max_Screen_Line, 0 );
  502.  
  503.              IF VT100_Allowed THEN
  504.                 GoToXY( X , Y )
  505.              ELSE
  506.                 GoToXY( 1 , 1 );
  507.  
  508.           END;
  509.  
  510.    END (* CASE *);
  511.  
  512.    Set_Global_Colors( Save_FG1 , Save_BG1 );
  513.  
  514. END   (* Ansi_Clear_Screen *);
  515.  
  516. (*----------------------------------------------------------------------*)
  517. (*             Ansi_Clear_Line --- Clear part of line in display        *)
  518. (*----------------------------------------------------------------------*)
  519.  
  520. PROCEDURE Ansi_Clear_Line;
  521.  
  522. (*----------------------------------------------------------------------*)
  523. (*                                                                      *)
  524. (*     Procedure: Ansi_Clear_Line                                       *)
  525. (*                                                                      *)
  526. (*     Purpose:   Clears portion of current line                        *)
  527. (*                                                                      *)
  528. (*     Calling Sequence:                                                *)
  529. (*                                                                      *)
  530. (*        Ansi_Clear_Line;                                              *)
  531. (*                                                                      *)
  532. (*     Called by:  VT100_Process_Escape                                 *)
  533. (*                 Ansi_Process_Escape                                  *)
  534. (*                                                                      *)
  535. (*----------------------------------------------------------------------*)
  536.  
  537. VAR
  538.    I:        INTEGER;
  539.    X:        INTEGER;
  540.    Y:        INTEGER;
  541.    C:        INTEGER;
  542.  
  543. BEGIN (* Ansi_Clear_Line *)
  544.  
  545.    IF ( Escape_Number = 1 )  THEN
  546.       C := Escape_Register[1]
  547.    ELSE
  548.       C := 0;
  549.  
  550.    Save_FG1 := FG;
  551.    Save_BG1 := BG;
  552.  
  553.    IF VT100_Allowed THEN
  554.       Set_Global_Colors( Ansi_ForeGround_Color , Ansi_BackGround_Color );
  555.  
  556.                                    (* Remember current position *)
  557.    X := WhereX;
  558.    Y := WhereY;
  559.  
  560.    CASE C OF
  561.                                    (* Clear cursor to end *)
  562.       0:  ClrEol;
  563.                                    (* Clear start to cursor *)
  564.       1:  BEGIN
  565.              GoToXY( 1 , Y );
  566.              FOR I := 1 TO X DO
  567.                 WRITE(' ');
  568.           END;
  569.                                    (* Clear entire line *)
  570.       2:  BEGIN
  571.              GoToXY( 1 , Y );
  572.              ClrEol;
  573.              GoToXY( X , Y );
  574.              Line_Attributes[Y] := 0;
  575.           END;
  576.  
  577.    END  (* CASE *);
  578.  
  579.    Set_Global_Colors( Save_FG1 , Save_BG1 );
  580.  
  581. END   (* Ansi_Clear_Line *);
  582.  
  583. (*----------------------------------------------------------------------*)
  584. (*          Ansi_Write_Escape --- Write out escape sequence to display  *)
  585. (*----------------------------------------------------------------------*)
  586.  
  587. PROCEDURE Ansi_Write_Escape;
  588.  
  589. (*----------------------------------------------------------------------*)
  590. (*                                                                      *)
  591. (*     Procedure: Ansi_Write_Escape                                     *)
  592. (*                                                                      *)
  593. (*     Purpose:   Writes unused escape sequence chars to display        *)
  594. (*                                                                      *)
  595. (*     Calling Sequence:                                                *)
  596. (*                                                                      *)
  597. (*        Ansi_Write_Escape;                                            *)
  598. (*                                                                      *)
  599. (*     Called by:  VT100_Process_Escape                                 *)
  600. (*                 Ansi_Process_Escape                                  *)
  601. (*                                                                      *)
  602. (*----------------------------------------------------------------------*)
  603.  
  604. VAR
  605.    I: INTEGER;
  606.  
  607. BEGIN (* Ansi_Write_Escape *)
  608.  
  609.    FOR I := 1 TO LENGTH( Escape_Str ) DO
  610.       Display_Character( Escape_Str[I] );
  611.  
  612.    Escape_Type    := ' ';
  613.  
  614. END   (* Ansi_Write_Escape *);
  615.  
  616. (*----------------------------------------------------------------------*)
  617. (*            Ansi_Next_Char --- Get next character in escape sequence  *)
  618. (*----------------------------------------------------------------------*)
  619.  
  620. FUNCTION Ansi_Next_Char : CHAR;
  621.  
  622. (*----------------------------------------------------------------------*)
  623. (*                                                                      *)
  624. (*     Function: Ansi_Next_Char                                         *)
  625. (*                                                                      *)
  626. (*     Purpose:  Waits for next character in escape sequence            *)
  627. (*                                                                      *)
  628. (*     Calling Sequence:                                                *)
  629. (*                                                                      *)
  630. (*        Ansi_Next_Char;                                               *)
  631. (*                                                                      *)
  632. (*     Called by:  VT100_Process_Escape                                 *)
  633. (*                 Ansi_Process_Escape                                  *)
  634. (*                                                                      *)
  635. (*     Remarks:                                                         *)
  636. (*                                                                      *)
  637. (*        This routine actually shouldn't be used, but I got lazy.      *)
  638. (*        Needs to be fixed next time around.                           *)
  639. (*                                                                      *)
  640. (*----------------------------------------------------------------------*)
  641.  
  642. VAR
  643.    Next_Ch: INTEGER;
  644.  
  645. BEGIN (* Ansi_Next_Char *)
  646.  
  647.    Async_Receive_With_Timeout( 5 , Next_Ch );
  648.  
  649.    IF Next_Ch > 0 THEN
  650.       Ansi_Next_Char := CHR( Next_Ch )
  651.    ELSE
  652.       Ansi_Next_Char := CHR( 0 );
  653.  
  654. END   (* Ansi_Next_Char *);
  655.  
  656. (*----------------------------------------------------------------------*)
  657. (*      Ansi_Set_Scrolling_Region --- Set scrolling region (window)     *)
  658. (*----------------------------------------------------------------------*)
  659.  
  660. PROCEDURE Ansi_Set_Scrolling_Region;
  661.  
  662. (*----------------------------------------------------------------------*)
  663. (*                                                                      *)
  664. (*     Procedure: Ansi_Set_Scrolling_Region                             *)
  665. (*                                                                      *)
  666. (*     Purpose:   Sets scrolling region (window)                        *)
  667. (*                                                                      *)
  668. (*     Calling Sequence:                                                *)
  669. (*                                                                      *)
  670. (*        Ansi_Set_Scrolling_Region;                                    *)
  671. (*                                                                      *)
  672. (*     Called by:  VT100_Process_Escape                                 *)
  673. (*                 Ansi_Process_Escape                                  *)
  674. (*                                                                      *)
  675. (*----------------------------------------------------------------------*)
  676.  
  677. VAR
  678.    Top:    INTEGER;
  679.    Bottom: INTEGER;
  680.  
  681. BEGIN (* Ansi_Set_Scrolling_Region *)
  682.  
  683.    CASE Escape_Number OF
  684.                                    (* Window is entire screen *)
  685.       0:  BEGIN
  686.              Top    := 1;
  687.              Bottom := Ansi_Last_Line;
  688.           END;
  689.                                    (* From specified line to end of screen *)
  690.       1:  BEGIN
  691.              Top    := MAX( Escape_Register[1] , 1 );
  692.              Bottom := Ansi_Last_Line;
  693.           END;
  694.                                    (* Both top and bottom specified *)
  695.       2:  BEGIN
  696.              Top    := MAX( Escape_Register[1] , 1  );
  697.              Bottom := MIN( Escape_Register[2] , Ansi_Last_Line );
  698.           END;
  699.  
  700.       ELSE
  701.              Top    := MAX( Escape_Register[1] , 1  );
  702.              Bottom := MIN( Escape_Register[2] , Ansi_Last_Line );
  703.  
  704.    END (* CASE *);
  705.  
  706.    IF Bottom < Top THEN Bottom := Ansi_Last_Line;
  707.    IF Bottom = 0   THEN Bottom := Ansi_Last_Line;
  708.  
  709.    IF Origin_Mode THEN
  710.       PibTerm_Window( 1, Top, Max_Screen_Col, Bottom );
  711.  
  712.    GoToXY( 1 , 1 );
  713.  
  714.    Top_Scroll    := Top;
  715.    Bottom_Scroll := Bottom;
  716.  
  717.    IF Origin_Mode THEN
  718.       PibTerm_Window( 1, 1, Max_Screen_Col, Ansi_Last_Line );
  719.  
  720. END   (* Ansi_Set_Scrolling_Region *);
  721.  
  722. (*----------------------------------------------------------------------*)
  723. (*                    Ansi_Cursor_Up --- Move cursor up                 *)
  724. (*----------------------------------------------------------------------*)
  725.  
  726. PROCEDURE Ansi_Cursor_Up;
  727.  
  728. (*----------------------------------------------------------------------*)
  729. (*                                                                      *)
  730. (*     Procedure: Ansi_Cursor_Up;                                       *)
  731. (*                                                                      *)
  732. (*     Purpose:   Moves cursor up specified number of lines             *)
  733. (*                                                                      *)
  734. (*     Calling Sequence:                                                *)
  735. (*                                                                      *)
  736. (*        Ansi_Cursor_Up;                                               *)
  737. (*                                                                      *)
  738. (*     Called by:  VT100_Process_Escape                                 *)
  739. (*                                                                      *)
  740. (*----------------------------------------------------------------------*)
  741.  
  742. VAR
  743.    Y    : INTEGER;
  744.    X    : INTEGER;
  745.    Regs : Registers;
  746.  
  747. BEGIN (* Ansi_Cursor_Up *)
  748.                                    (* Get current position.  If not in *)
  749.                                    (* scrolling region, we do nothing. *)
  750.    Regs.Ah            := 3;
  751.    Regs.Bh            := 0;
  752.    INTR( $10 , Regs );
  753.  
  754.    X := SUCC( Regs.Dl );
  755.    Y := SUCC( Regs.Dh );
  756. {
  757.    IF ( ( Y > Bottom_Scroll ) OR ( Y <= Top_Scroll ) ) THEN
  758.       EXIT;
  759. }
  760.    IF ( Y < Top_Scroll ) THEN
  761.       EXIT;
  762.                                    (* Get # of lines to move up *)
  763.    IF Escape_Number = 0 THEN
  764.       Reg_Val := 1
  765.    ELSE
  766.       Reg_Val := MAX( 1 , Escape_Register[1] );
  767.  
  768.    Set_Cursor( X , MAX( Y - Reg_Val , Top_Scroll ) );
  769.  
  770.    IF ( WhereY <> Y ) THEN
  771.       Last_Column_Hit := FALSE;
  772.  
  773. END   (* Ansi_Cursor_Up *);
  774.  
  775. (*----------------------------------------------------------------------*)
  776. (*                 Ansi_Cursor_Down --- Move cursor down                *)
  777. (*----------------------------------------------------------------------*)
  778.  
  779. PROCEDURE Ansi_Cursor_Down;
  780.  
  781. (*----------------------------------------------------------------------*)
  782. (*                                                                      *)
  783. (*     Procedure: Ansi_Cursor_Down;                                     *)
  784. (*                                                                      *)
  785. (*     Purpose:   Moves cursor down specified number of lines           *)
  786. (*                                                                      *)
  787. (*     Calling Sequence:                                                *)
  788. (*                                                                      *)
  789. (*        Ansi_Cursor_Down;                                             *)
  790. (*                                                                      *)
  791. (*     Called by:  VT100_Process_Escape                                 *)
  792. (*                                                                      *)
  793. (*----------------------------------------------------------------------*)
  794.  
  795. VAR
  796.    Y    : INTEGER;
  797.    X    : INTEGER;
  798.    Regs : Registers;
  799.  
  800. BEGIN (* Ansi_Cursor_Down *)
  801.                                    (* Get current position.  If not in *)
  802.                                    (* scrolling region, we do nothing. *)
  803.    Regs.Ah            := 3;
  804.    Regs.Bh            := 0;
  805.    INTR( $10 , Regs );
  806.  
  807.    X := SUCC( Regs.Dl );
  808.    Y := SUCC( Regs.Dh );
  809. {
  810.    IF ( ( Y >= Bottom_Scroll ) OR ( Y < Top_Scroll ) ) THEN
  811. }
  812.    IF ( Y >= Bottom_Scroll ) THEN
  813.       EXIT;
  814.                                    (* Get # of lines to move down *)
  815.    IF Escape_Number = 0 THEN
  816.       Reg_Val := 1
  817.    ELSE
  818.       Reg_Val := MAX( 1 , Escape_Register[1] );
  819.  
  820.    Set_Cursor( X, MIN( Y + Reg_Val , Bottom_Scroll ) );
  821.  
  822.    IF ( WhereY <> Y ) THEN
  823.       Last_Column_Hit := FALSE;
  824.  
  825. END   (* Ansi_Cursor_Down *);
  826.  
  827. (*----------------------------------------------------------------------*)
  828. (*                  Ansi_Cursor_Left --- Move cursor left               *)
  829. (*----------------------------------------------------------------------*)
  830.  
  831. PROCEDURE Ansi_Cursor_Left;
  832.  
  833. (*----------------------------------------------------------------------*)
  834. (*                                                                      *)
  835. (*     Procedure: Ansi_Cursor_Left;                                     *)
  836. (*                                                                      *)
  837. (*     Purpose:   Moves cursor left specified number of columns         *)
  838. (*                                                                      *)
  839. (*     Calling Sequence:                                                *)
  840. (*                                                                      *)
  841. (*        Ansi_Cursor_Left;                                             *)
  842. (*                                                                      *)
  843. (*     Called by:  VT100_Process_Escape                                 *)
  844. (*                                                                      *)
  845. (*----------------------------------------------------------------------*)
  846.  
  847. BEGIN (* Ansi_Cursor_Left *)
  848.  
  849.    IF Escape_Number = 0 THEN
  850.       Reg_Val := 1
  851.    ELSE
  852.       Reg_Val := MAX( 1 , Escape_Register[1] );
  853.  
  854.    Set_Cursor( MAX( Ansi_WhereX - Reg_Val , 1 ), WhereY );
  855.  
  856. END   (* Ansi_Cursor_Left *);
  857.  
  858. (*----------------------------------------------------------------------*)
  859. (*                 Ansi_Cursor_Right --- Move cursor right              *)
  860. (*----------------------------------------------------------------------*)
  861.  
  862. PROCEDURE Ansi_Cursor_Right;
  863.  
  864. (*----------------------------------------------------------------------*)
  865. (*                                                                      *)
  866. (*     Procedure: Ansi_Cursor_Right;                                    *)
  867. (*                                                                      *)
  868. (*     Purpose:   Moves cursor right specified number of columns        *)
  869. (*                                                                      *)
  870. (*     Calling Sequence:                                                *)
  871. (*                                                                      *)
  872. (*        Ansi_Cursor_Right;                                            *)
  873. (*                                                                      *)
  874. (*     Called by:  VT100_Process_Escape                                 *)
  875. (*                                                                      *)
  876. (*----------------------------------------------------------------------*)
  877.  
  878. BEGIN (* Ansi_Cursor_Right *)
  879.  
  880.    IF Escape_Number = 0 THEN
  881.       Reg_Val := 1
  882.    ELSE
  883.       Reg_Val := MAX( 1 , Escape_Register[1] );
  884.  
  885.    Set_Cursor( MIN( Ansi_WhereX + Reg_Val , Wrap_Screen_Col ), WhereY );
  886.  
  887. END   (* Ansi_Cursor_Right *);
  888.  
  889. (*----------------------------------------------------------------------*)
  890. (*              Ansi_Status_Report --- Provide terminal status          *)
  891. (*----------------------------------------------------------------------*)
  892.  
  893. PROCEDURE Ansi_Status_Report;
  894.  
  895. (*----------------------------------------------------------------------*)
  896. (*                                                                      *)
  897. (*     Procedure: Ansi_Status_Report;                                   *)
  898. (*                                                                      *)
  899. (*     Purpose:   Provides status reports to host enquiries             *)
  900. (*                                                                      *)
  901. (*     Calling Sequence:                                                *)
  902. (*                                                                      *)
  903. (*        Ansi_Status_Report;                                           *)
  904. (*                                                                      *)
  905. (*     Called by:  VT100_Process_Escape                                 *)
  906. (*                                                                      *)
  907. (*----------------------------------------------------------------------*)
  908.  
  909. VAR
  910.    Istatus  : INTEGER;
  911.    C_Column : STRING[10];
  912.    C_Row    : STRING[10];
  913.  
  914. BEGIN (* Ansi_Status_Report *)
  915.  
  916.    IF Escape_Number = 0 THEN
  917.       Istatus := 5
  918.    ELSE
  919.       Istatus := Escape_Register[ 1 ];
  920.  
  921.    CASE Istatus OF
  922.  
  923.       5:    Async_Send_String( CHR( 27 ) + '[0n' );
  924.  
  925.       6:    BEGIN
  926.                STR( Ansi_WhereX, C_Column );
  927.                STR( WhereY, C_Row    );
  928.                Async_Send_String( CHR( 27 ) + '[' +
  929.                                   C_Row + ';' + C_Column + 'R' );
  930.             END;
  931.  
  932.       ELSE;
  933.  
  934.    END   (* CASE *);
  935.  
  936. END   (* Ansi_Status_Report *);
  937.  
  938. (*----------------------------------------------------------------------*)
  939. (*              Ansi_Swap_Colors --- Swap foreground/background colors  *)
  940. (*----------------------------------------------------------------------*)
  941.  
  942. PROCEDURE Ansi_Swap_Colors;
  943.  
  944. VAR
  945.    K: INTEGER;
  946.  
  947. BEGIN (* Ansi_Swap_Colors *)
  948.  
  949.    K                     := Ansi_ForeGround_Color;
  950.    Ansi_ForeGround_Color := Ansi_BackGround_Color;
  951.    Ansi_BackGround_Color := K;
  952.  
  953.    K                := ForeGround_Color;
  954.    ForeGround_Color := BackGround_Color;
  955.    BackGround_Color := K;
  956.  
  957.    K  := FG;
  958.    FG := BG;
  959.    BG := K;
  960.  
  961.    Set_Global_Colors( ForeGround_Color , BackGround_Color );
  962.    Set_Border_Color ( BackGround_Color );
  963.  
  964.    Status_Line_Attr := 16 * ( ForeGround_Color AND 7 ) +
  965.                        BackGround_Color;
  966.  
  967. END   (* Ansi_Swap_Colors *);
  968.  
  969. (*----------------------------------------------------------------------*)
  970. (*              Ansi_Set_Mode --- Set a terminal mode                   *)
  971. (*----------------------------------------------------------------------*)
  972.  
  973. PROCEDURE Ansi_Set_Mode( Mode_Type : CHAR );
  974.  
  975. (*----------------------------------------------------------------------*)
  976. (*                                                                      *)
  977. (*     Procedure: Ansi_Set_Mode;                                        *)
  978. (*                                                                      *)
  979. (*     Purpose:   Set a terminal mode                                   *)
  980. (*                                                                      *)
  981. (*     Calling Sequence:                                                *)
  982. (*                                                                      *)
  983. (*        Ansi_Set_Mode( Mode_Type : CHAR );                            *)
  984. (*                                                                      *)
  985. (*           Mode_Type --- ' ' or '?' depending upon type of            *)
  986. (*                         parameter to set.                            *)
  987. (*                                                                      *)
  988. (*     Called by:  VT100_Process_Escape                                 *)
  989. (*                                                                      *)
  990. (*----------------------------------------------------------------------*)
  991.  
  992. VAR
  993.    I    : INTEGER;
  994.    Regs : Registers;
  995.  
  996. BEGIN (* Ansi_Set_Mode *)
  997.  
  998.    IF ( Mode_Type = '?' ) THEN
  999.       FOR I := 1 TO Escape_Number DO
  1000.  
  1001.          CASE Escape_Register[I] OF
  1002.  
  1003.             1:    IF Auto_Change_Arrows THEN
  1004.                      IF ( LENGTH( KeyPad_Appl_On_File ) > 0 ) THEN
  1005.                         Set_Input_Keys( KeyPad_Appl_On_File , FALSE );
  1006.  
  1007.             3:    BEGIN
  1008.                      IF ATI_Ega_Wonder THEN
  1009.                         BEGIN
  1010.                            IF Do_Xon_Xoff_Checks THEN
  1011.                               BEGIN
  1012.                                  Async_Send_Now( CHR( XOFF ) );
  1013.                                  IF Async_Wait_For_Quiet( 150 , 25 ) THEN;
  1014.                               END;
  1015.                            Regs.AX := $23;
  1016.                            INTR( $10, Regs );
  1017.                            Set_Border_Color( BG );
  1018.                            IF Do_Xon_Xoff_Checks THEN
  1019.                               Async_Send_Now( CHR( XON ) );
  1020.                            Max_Screen_Col  := 132;
  1021.                            Max_Screen_Line := 25;
  1022.                            PibTerm_Window( 1, 1, Max_Screen_Col, Ansi_Last_Line );
  1023.                            IF Do_Status_Line THEN
  1024.                               BEGIN
  1025.                                  Set_Status_Line_Name(Short_Terminal_Name);
  1026.                                  Write_To_Status_Line( Status_Line_Name, 1 );
  1027.                               END;
  1028.                            Last_Column_Hit := FALSE;
  1029.                         END;
  1030.                      Width_132          := TRUE;
  1031.                      Wrap_Screen_Col    := MIN( Max_Screen_Col , 132 );
  1032.                      Escape_Number      := 1;
  1033.                      Escape_Register[1] := 2;
  1034.                      Ansi_Clear_Screen;
  1035.                      GoToXY( 1 , 1 );
  1036.                      EXIT;
  1037.                   END;
  1038.  
  1039.             5:    IF ( NOT Reverse_On ) THEN
  1040.                      BEGIN
  1041.                         Ansi_Swap_Colors;
  1042.                         Set_Text_Attributes( 1, 1, Max_Screen_Col,
  1043.                                              Max_Screen_Line - 1,
  1044.                                              Ansi_Foreground_Color,
  1045.                                              Ansi_BackGround_Color );
  1046.                         Reverse_On := TRUE;
  1047.                         IF Do_Status_Line THEN
  1048.                            Write_To_Status_Line( Status_Line_Name, 1 );
  1049.                      END;
  1050.  
  1051.             6:    BEGIN
  1052.                      Origin_Mode := ON;
  1053.                      PibTerm_Window( 1, Top_Scroll, Max_Screen_Col, Bottom_Scroll );
  1054.                      GoToXY( 1 , 1 );
  1055.                      PibTerm_Window( 1, 1, Max_Screen_Col, Ansi_Last_Line );
  1056.                   END;
  1057.  
  1058.             7:    Auto_Wrap_Mode := ON;
  1059.  
  1060.             12:   Local_Echo     := ON;
  1061.  
  1062.             ELSE;
  1063.  
  1064.          END   (* CASE *)
  1065.    ELSE
  1066.       FOR I := 1 TO Escape_Number DO
  1067.  
  1068.          CASE Escape_Register[I] OF
  1069.  
  1070.              2:   (* Keyboard_Locked := ON *);
  1071.              4:   Insertion_Mode := ON;
  1072.             20:   New_Line       := ON;
  1073.             ELSE;
  1074.  
  1075.          END   (* CASE *);
  1076.  
  1077. END   (* Ansi_Set_Mode *);
  1078.  
  1079. (*----------------------------------------------------------------------*)
  1080. (*            Ansi_Reset_Mode --- Reset a terminal mode                 *)
  1081. (*----------------------------------------------------------------------*)
  1082.  
  1083. PROCEDURE Ansi_Reset_Mode( Mode_Type : CHAR; VAR Done: BOOLEAN );
  1084.  
  1085. (*----------------------------------------------------------------------*)
  1086. (*                                                                      *)
  1087. (*     Procedure: Ansi_Reset_Mode;                                      *)
  1088. (*                                                                      *)
  1089. (*     Purpose:   Resets a terminal mode                                *)
  1090. (*                                                                      *)
  1091. (*     Calling Sequence:                                                *)
  1092. (*                                                                      *)
  1093. (*        Ansi_Reset_Mode( Mode_Type : CHAR; VAR Done : BOOLEAN );      *)
  1094. (*                                                                      *)
  1095. (*           Mode_Type --- ' ' or '?' depending upon type of            *)
  1096. (*                         parameter to set.                            *)
  1097. (*           Done      --- TRUE if switch to VT52 done.                 *)
  1098. (*                                                                      *)
  1099. (*     Called by:  VT100_Process_Escape                                 *)
  1100. (*                                                                      *)
  1101. (*----------------------------------------------------------------------*)
  1102.  
  1103. VAR
  1104.    I : INTEGER;
  1105.    B : BOOLEAN;
  1106.    Ch: CHAR;
  1107.    Regs : Registers;
  1108.  
  1109. BEGIN (* Ansi_Reset_Mode *)
  1110.  
  1111.    IF ( Mode_Type = '?' ) THEN
  1112.       FOR I := 1 TO Escape_Number DO
  1113.  
  1114.          CASE Escape_Register[I] OF
  1115.  
  1116.             1:    IF Auto_Change_Arrows THEN
  1117.                      IF ( LENGTH( KeyPad_Appl_Off_File ) > 0 ) THEN
  1118.                         Set_Input_Keys( KeyPad_Appl_Off_File , FALSE );
  1119.  
  1120.                                    (* We cheat here in order to avoid        *)
  1121.                                    (* an unnecessary switch in the case      *)
  1122.                                    (* of ESC [?2l being followed immediately *)
  1123.                                    (* by ESC < -- i.e., return to ANSI mode. *)
  1124.             2:    BEGIN
  1125.                      DELAY( Tenth_Of_A_Second_Delay );
  1126.                      IF ( Async_Peek( 0 ) = CHR( ESC ) ) AND
  1127.                         ( Async_Peek( 1 ) = '<'        ) THEN
  1128.                         BEGIN
  1129.                            Graphics_Mode := FALSE;
  1130.                            B             := Async_Receive( Ch );
  1131.                            B             := Async_Receive( Ch );
  1132.                         END
  1133.                      ELSE
  1134.                         BEGIN
  1135.                            Terminal_To_Emulate := VT52;
  1136.                            Done                := TRUE;
  1137.                         END;
  1138.                   END;
  1139.  
  1140.             3:    BEGIN
  1141.                      IF ( ATI_Ega_Wonder AND Width_132 ) THEN
  1142.                         BEGIN
  1143.                            IF Do_Xon_Xoff_Checks THEN
  1144.                               BEGIN
  1145.                                  Async_Send_Now( CHR( XOFF ) );
  1146.                                  IF Async_Wait_For_Quiet( 150 , 25 ) THEN;
  1147.                               END;
  1148.                            Max_Screen_Col  := 80;
  1149.                            Max_Screen_Line := 25;
  1150.                            Regs.AX         := $03;
  1151.                            INTR( $10, Regs );
  1152.                            Set_Border_Color( BG );
  1153.                            IF Do_Xon_Xoff_Checks THEN
  1154.                               Async_Send_Now( CHR( XON ) );
  1155.                            IF Do_Status_Line THEN
  1156.                               BEGIN
  1157.                                  Set_Status_Line_Name(Short_Terminal_Name);
  1158.                                  Write_To_Status_Line( Status_Line_Name, 1 );
  1159.                               END;
  1160.                            Last_Column_Hit := FALSE;
  1161.                            PibTerm_Window( 1, 1, Max_Screen_Col, Ansi_Last_Line );
  1162.                            GoToXY( 1 , 1 );
  1163.                         END;
  1164.                      Width_132          := FALSE;
  1165.                      Wrap_Screen_Col    := MIN( Max_Screen_Col , 80 );
  1166.                      Escape_Number      := 1;
  1167.                      Escape_Register[1] := 2;
  1168.                      Ansi_Clear_Screen;
  1169.                      GoToXY( 1 , 1 );
  1170.                      EXIT;
  1171.                   END;
  1172.  
  1173.             5:    IF Reverse_On THEN
  1174.                      BEGIN
  1175.                         Ansi_Swap_Colors;
  1176.                         Set_Text_Attributes( 1, 1, Max_Screen_Col,
  1177.                                              Max_Screen_Line - 1,
  1178.                                              Ansi_Foreground_Color,
  1179.                                              Ansi_BackGround_Color );
  1180.                         Reverse_On := FALSE;
  1181.                         IF Do_Status_Line THEN
  1182.                            Write_To_Status_Line( Status_Line_Name, 1 );
  1183.                      END;
  1184.  
  1185.             6:    BEGIN
  1186.                      Origin_Mode := OFF;
  1187.                      PibTerm_Window( 1, 1, Max_Screen_Col, Ansi_Last_Line );
  1188.                      GoToXY( 1 , 1 );
  1189.                   END;
  1190.  
  1191.             7:    Auto_Wrap_Mode := OFF;
  1192.  
  1193.             12:   Local_Echo     := OFF;
  1194.  
  1195.             ELSE;
  1196.  
  1197.          END   (* CASE *)
  1198.    ELSE
  1199.       FOR I := 1 TO Escape_Number DO
  1200.  
  1201.          CASE Escape_Register[I] OF
  1202.  
  1203.              2:   (* Keyboard_Locked := OFF *);
  1204.              4:   Insertion_Mode := OFF;
  1205.             20:   New_Line       := OFF;
  1206.             ELSE;
  1207.  
  1208.          END   (* CASE *);
  1209.  
  1210. END   (* Ansi_Reset_Mode *);
  1211.  
  1212. (*----------------------------------------------------------------------*)
  1213. (*         Ansi_Printer_Control --- Sets printer control modes          *)
  1214. (*----------------------------------------------------------------------*)
  1215.  
  1216. PROCEDURE Ansi_Printer_Control( Mode_Type : CHAR );
  1217.  
  1218. (*----------------------------------------------------------------------*)
  1219. (*                                                                      *)
  1220. (*     Procedure: Ansi_Printer_Control;                                 *)
  1221. (*                                                                      *)
  1222. (*     Purpose:   Sets printer control modes                            *)
  1223. (*                                                                      *)
  1224. (*     Calling Sequence:                                                *)
  1225. (*                                                                      *)
  1226. (*        Ansi_Printer_Control;                                         *)
  1227. (*                                                                      *)
  1228. (*           Mode_Type --- ' ' or '?' depending upon type of            *)
  1229. (*                         parameter to set.                            *)
  1230. (*                                                                      *)
  1231. (*     Called by:  VT100_Process_Escape                                 *)
  1232. (*                                                                      *)
  1233. (*----------------------------------------------------------------------*)
  1234.  
  1235. VAR
  1236.    SaveM     : INTEGER;
  1237.    Text_Line : AnyStr;
  1238.  
  1239. BEGIN (* Ansi_Printer_Control *)
  1240.  
  1241.    IF ( Escape_Number = 0 ) THEN
  1242.       Escape_Register[1] := 0;
  1243.  
  1244.    CASE Mode_Type OF
  1245.  
  1246.       ' ': CASE Escape_Register[1] OF
  1247.               0: BEGIN (* Print screen *)
  1248.                     SaveM           := Max_Screen_Line;
  1249.                     Max_Screen_Line := Ansi_Last_Line;
  1250.                     Print_Screen;
  1251.                     Max_Screen_Line := SaveM;
  1252.                  END   (* Print screen *);
  1253.               4: Printer_Ctrl_Mode := OFF;
  1254.               5: Printer_Ctrl_Mode := ON;
  1255.            END (* CASE *);
  1256.  
  1257.       '?': CASE Escape_Register[1] OF
  1258.               1: BEGIN (* Print current line *)
  1259.                     Get_Screen_Text_Line( Text_Line,
  1260.                                           WhereY + Upper_Left_Row - 1, 1 );
  1261.                     Write_Prt_Str( Text_Line );
  1262.                     Write_Prt_Str( CRLF_String );
  1263.                  END   (* Print current line *);
  1264.               4: Auto_Print_Mode := OFF;
  1265.               5: Auto_Print_Mode := ON;
  1266.            END (* CASE *);
  1267.  
  1268.    END (* CASE *);
  1269.  
  1270. END   (* Ansi_Printer_Control *);
  1271.  
  1272. (*----------------------------------------------------------------------*)
  1273. (*            VT100_Set_Tab --- Sets a tab stop in VT100 mode           *)
  1274. (*----------------------------------------------------------------------*)
  1275.  
  1276. PROCEDURE VT100_Set_Tab;
  1277.  
  1278. (*----------------------------------------------------------------------*)
  1279. (*                                                                      *)
  1280. (*     Procedure: VT100_Set_Tab;                                        *)
  1281. (*                                                                      *)
  1282. (*     Purpose:   Sets tab stop in VT100 mode                           *)
  1283. (*                                                                      *)
  1284. (*     Calling Sequence:                                                *)
  1285. (*                                                                      *)
  1286. (*        VT100_Set_Tab;                                                *)
  1287. (*                                                                      *)
  1288. (*     Called by:  VT100_Process_Escape                                 *)
  1289. (*                                                                      *)
  1290. (*----------------------------------------------------------------------*)
  1291.  
  1292. VAR
  1293.    ITab   : INTEGER;
  1294.    JTab   : INTEGER;
  1295.    TabCol : INTEGER;
  1296.    KTab   : INTEGER;
  1297.  
  1298. BEGIN (* VT100_Set_Tab *)
  1299.  
  1300.    TabCol := WhereX;
  1301.    ITab   := 0;
  1302.  
  1303.    IF ( Number_VT100_Tabs = 0 ) THEN
  1304.       BEGIN
  1305.          Number_VT100_Tabs  := 1;
  1306.          VT100_Tabs[1]      := TabCol;
  1307.          VT100_Tabs[2]      := Wrap_Screen_Col;
  1308.       END
  1309.    ELSE
  1310.       BEGIN
  1311.  
  1312.          REPEAT
  1313.             INC( ITab );
  1314.          UNTIL ( ITab >= Number_VT100_Tabs  ) OR
  1315.                ( VT100_Tabs[ITab] >= TabCol );
  1316.  
  1317.          IF ( VT100_Tabs[ITab] <> TabCol ) THEN
  1318.             BEGIN
  1319.  
  1320.                IF ( VT100_Tabs[ITab] < TabCol ) THEN
  1321.                   KTab := SUCC( ITab )
  1322.                ELSE
  1323.                   KTab := ITab;
  1324.  
  1325.                FOR JTab := Number_VT100_Tabs DOWNTO KTab DO
  1326.                   VT100_Tabs[JTab + 1] := VT100_Tabs[JTab];
  1327.  
  1328.                INC( Number_VT100_Tabs );
  1329.  
  1330.                VT100_Tabs[KTab]  := TabCol;
  1331.  
  1332.             END;
  1333.  
  1334.       END;
  1335.  
  1336. END   (* VT100_Set_Tab *);
  1337.  
  1338. (*----------------------------------------------------------------------*)
  1339. (*        VT100_Clear_Tabs --- Clears tab stops in VT100 mode           *)
  1340. (*----------------------------------------------------------------------*)
  1341.  
  1342. PROCEDURE VT100_Clear_Tabs;
  1343.  
  1344. (*----------------------------------------------------------------------*)
  1345. (*                                                                      *)
  1346. (*     Procedure: VT100_Clear_Tabs;                                     *)
  1347. (*                                                                      *)
  1348. (*     Purpose:   Clears one or all tab stops in VT100 mode             *)
  1349. (*                                                                      *)
  1350. (*     Calling Sequence:                                                *)
  1351. (*                                                                      *)
  1352. (*        VT100_Clear_Tabs;                                             *)
  1353. (*                                                                      *)
  1354. (*     Called by:  VT100_Process_Escape                                 *)
  1355. (*                                                                      *)
  1356. (*----------------------------------------------------------------------*)
  1357.  
  1358. VAR
  1359.    ITab   : INTEGER;
  1360.    JTab   : INTEGER;
  1361.    TabCol : INTEGER;
  1362.  
  1363. BEGIN (* VT100_Clear_Tabs *)
  1364.  
  1365.    IF ( Number_VT100_Tabs > 0 ) THEN
  1366.       IF ( Escape_Register[1] = 3 ) THEN
  1367.          BEGIN
  1368.             Number_VT100_Tabs := 0;
  1369.             VT100_Tabs[1]     := Wrap_Screen_Col;
  1370.          END
  1371.       ELSE IF ( Escape_Register[1] = 0 ) THEN
  1372.          BEGIN
  1373.  
  1374.             TabCol := WhereX;
  1375.             ITab   := 0;
  1376.  
  1377.             REPEAT
  1378.                INC( ITab );
  1379.             UNTIL ( ITab >= Number_VT100_Tabs ) OR
  1380.                   ( VT100_Tabs[ITab] >= TabCol );
  1381.  
  1382.             IF ( VT100_Tabs[ITab] = TabCol ) THEN
  1383.                BEGIN
  1384.                   FOR JTab := ITab TO Number_VT100_Tabs DO
  1385.                      VT100_Tabs[JTab] := VT100_Tabs[SUCC( JTab )];
  1386.                   DEC( Number_VT100_Tabs );
  1387.                END;
  1388.  
  1389.          END;
  1390.  
  1391. END   (* VT100_Clear_Tabs *);
  1392.  
  1393.