home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / virterm / vt2.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  219.5 KB  |  6,379 lines

  1.  
  2. -------- SIMTEL20 Ada Software Repository Prologue ------------
  3. --                                                           -*
  4. -- Unit name    : Virtual Terminal Protocol 
  5. -- Version      : 1.0
  6. -- Contact      : Lt. Colonel Falgiano
  7. --              : ESD/SCW
  8. --              : Hanscom AFB, MA  01731
  9. -- Author       : John Foreman
  10. --              : Texas Instruments, Inc.
  11. --              : P.O. Box 801 MS 8007
  12. --              : McKinney, TX  75069
  13. -- DDN Address  :
  14. -- Copyright    : (c) 1985 Texas Instruments, Inc.
  15. -- Date created : 9 November 1984
  16. -- Release date : March 1985
  17. -- Last update  : 
  18. --                                                           -*
  19. ---------------------------------------------------------------
  20. --                                                           -*
  21. -- Keywords     : 
  22. ----------------:
  23. --
  24. -- Abstract     : The ANSI virtual terminal is a program level
  25. ----------------: interface providing support for scroll, page
  26. ----------------: and form-mode terminals.  This package uses
  27. ----------------: a terminal capabilities database to determine
  28. ----------------: the capabilities of a variety of terminals.
  29. ----------------: This package was designed to enhance the 
  30. ----------------: transportability of the source code and 
  31. ----------------: interoperability of the terminal capabilities      
  32. ----------------: database.
  33. ----------------:
  34. ----------------: This tool was developed as a precursor for 
  35. ----------------: the WMCCS Information System (WIS).  An
  36. ----------------: executable version of the tool has been 
  37. ----------------: demonstrated.  This source code has sub-
  38. ----------------: sequently been recompiled but has not under-
  39. ----------------: gone extensive testing.
  40. ----------------:
  41. --                                                           -*
  42. ------------------ Revision history ---------------------------
  43. --                                                           -*
  44. -- DATE         VERSION AUTHOR                  HISTORY 
  45. -- 03/85          1.0   John Foreman            Initial Release
  46. --                                                           -*
  47. ------------------ Distribution and Copyright -----------------
  48. --                                                           -*
  49. -- This prologue must be included in all copies of this software.
  50. -- 
  51. -- This software is copyright by the author.
  52. -- 
  53. -- This software is released to the Ada community.
  54. -- This software is released to the Public Domain (note:
  55. --   software released to the Public Domain is not subject
  56. --   to copyright protection).
  57. -- Restrictions on use or distribution:  NONE
  58. --                                                           -*
  59. ----------------- Disclaimer ----------------------------------
  60. --                                                           -*
  61. -- This software and its documentation are provided "AS IS" and
  62. -- without any expressed or implied warranties whatsoever.
  63. --
  64. -- No warranties as to performance, merchantability, or fitness
  65. -- for a particular purpose exist.
  66. --
  67. -- Because of the diversity of conditions and hardware under
  68. -- which this software may be used, no warranty of fitness for
  69. -- a particular purpose is offered.  The user is advised to 
  70. -- test the software thoroughly before relying on it.  The user
  71. -- must assume the entire risk and liability of using this 
  72. -- software.
  73. --
  74. -- In no event shall any person or organization of people be
  75. -- held responsible for any direct, indirect, consequential
  76. -- or inconsequential damages or lost profits.
  77. --                                                          -*
  78. ----------------- END-PROLOGUE -------------------------------
  79. ::::::::::
  80. vt_cmp.dis
  81. ::::::::::
  82. -- Ada source file in compilation order
  83. -- The names of the following files were changed in order to
  84. -- maintain a 9-character unique limit:
  85. --    Old Name            New Name
  86. --    REDISPLAY_BODY.ADA        REDISP_BODY.ADA
  87. --    REDISPLAY_SPEC.ADA        REDISP_SPEC.ADA
  88. --
  89. vtcontent_spec.ada
  90. sysdep_spec.ada
  91. tcf_spec.ada
  92. scroll_spec.ada
  93. page_spec.ada
  94. form_spec.ada
  95. vtinput_spec.ada
  96. driver_spec.ada
  97. redisp_spec.ada
  98. sysdep_body.ada
  99. tcf_body.ada
  100. driver_body.ada
  101. vtinput_body.ada
  102. redisp_body.ada
  103. scroll_body.ada
  104. page_body.ada
  105. form_body.ada
  106. activate_form.ada
  107. ::::::::::
  108. vt_src.dis
  109. ::::::::::
  110. -- Ada source file in compilation order
  111. -- The names were changed on the following files to put them
  112. -- into the 9-character unique limit:
  113. --    Old Name            New Name
  114. --    REDISPLAY_BODY.ADA        REDISP_BODY.ADA
  115. --    REDISPLAY_SPEC.ADA        REDISP_SPEC.ADA
  116. --
  117. vtcontent_spec.ada
  118. sysdep_spec.ada
  119. tcf_spec.ada
  120. scroll_spec.ada
  121. page_spec.ada
  122. form_spec.ada
  123. vtinput_spec.ada
  124. driver_spec.ada
  125. redisp_spec.ada
  126. sysdep_body.ada
  127. tcf_body.ada
  128. driver_body.ada
  129. vtinput_body.ada
  130. redisp_body.ada
  131. scroll_body.ada
  132. page_body.ada
  133. form_body.ada
  134. activate_form.ada
  135. --
  136. -- Data files
  137. --
  138. tcf
  139. term
  140. recompile.cli
  141. ::::::::::
  142. vtcontent_spec.ada
  143. ::::::::::
  144. -- ----------------------------------------------------------------------------
  145. -- ABSTRACT:  This package consisting only of a specification, contains
  146. --            the supporting constant and type definitions used by other
  147. --            packages in defining and manipulating a virtual display.
  148. --            Many of the enumerated types use names that match the names
  149. --            in the ANSI X3.64 [ANSI74] standard.
  150. -- -----------------------------------------------------------------------------
  151.  
  152. PACKAGE vt_content IS
  153.  
  154.   TYPE graphic_rendition_enum IS
  155.                   (   sgpr,     -- primary rendition
  156.                       sgri,     -- reverse image
  157.                       sgno );   -- no rendition (blank)
  158.  
  159.   TYPE area_qualifiers_enum IS
  160.                   (   dqnn,      -- accept no input (protected)
  161.                       dqag,      -- accept graphic input
  162.                       dqan );    -- accept numeric input
  163.  
  164.   max_row : CONSTANT integer := 60;
  165.   max_column : CONSTANT integer := 132;
  166.  
  167.   SUBTYPE column_range IS positive  RANGE 1..max_column;
  168.  
  169.   SUBTYPE row_range IS positive  RANGE 1..max_row;
  170.  
  171.   height : row_range;
  172.   width : column_range;
  173.  
  174.   TYPE vt_position_xy_record IS
  175.                   RECORD
  176.                     row_position     :row_range;
  177.                     col_position     :column_range;
  178.                   END RECORD;
  179.  
  180.   TYPE tabs_array IS ARRAY( column_range ) OF BOOLEAN;
  181.  
  182.   TYPE vt_position_record IS
  183.                   RECORD
  184.                       qualifier_head :boolean ;
  185.                       rendition      :graphic_rendition_enum;
  186.                       qualifiers     :area_qualifiers_enum;
  187.                   END RECORD; -- vt_position_record
  188.  
  189.   TYPE vt_column_descriptors IS
  190.                   ARRAY( column_range ) OF vt_position_record;
  191.  
  192.   TYPE vt_column_record IS
  193.                   RECORD
  194.                       corresponding_line : natural;
  195.                       descriptors : vt_column_descriptors;
  196.                       data : string( column_range );
  197.                       length : natural;  -- when this is zero line is blank
  198.                   END RECORD; -- vt_column_record
  199.  
  200.   TYPE vt_content_array IS
  201.                   ARRAY( row_range ) OF vt_column_record;
  202.  
  203.   TYPE vt_content_record IS
  204.                   RECORD
  205.                       active_position
  206.                                      :vt_position_xy_record;
  207.                       insert_mode    :boolean;
  208.                       current_rendition : graphic_rendition_enum;
  209.                       tabs           :tabs_array;
  210.                       element        :vt_content_array;
  211.                   END RECORD; -- vt_content_record
  212.  
  213.   TYPE vt_content_access IS ACCESS vt_content_record;
  214.  
  215. END vt_content;
  216. ::::::::::
  217. sysdep_spec.ada
  218. ::::::::::
  219. -- ---------------------------------------------------------------------------
  220. -- ABSTRACT:  This system dependency package is the only package that
  221. --            needs modifications when rehosting the Virtual Terminal tool
  222. --            to another environment.
  223. --            The supported functions are:
  224. --                * open the physical terminal,
  225. --                * close the physical terminal,
  226. --                * put strings to the physical terminal,
  227. --                * get strings form the physical terminal,
  228. --                * get terminal capabilities file (TCF) name,
  229. --                * get the terminal's name (to be subsequently looked up in TCF
  230. --                * check the validity of a particular character.
  231. --
  232. -- ----------------------------------------------------------------------------
  233.  
  234. PACKAGE sysdep IS
  235.  
  236.     PROCEDURE open;
  237.     --
  238.     -- Open the console for binary I/O, no echo.
  239.     --
  240.  
  241.     PROCEDURE close;
  242.     --
  243.     -- Close the console.  Parameters should be reset to original condition.
  244.     --
  245.  
  246.     PROCEDURE put ( data : IN string );
  247.  
  248.     --
  249.     -- Put a string to the terminal.  There should be no translation of
  250.     -- the characters. There can be exceptions to this rule (like CTRL-S and
  251.     -- CTRL-Q)  and these exceptions must be identified in valid_character
  252.     -- below.
  253.     --
  254.  
  255.     PROCEDURE get ( data : OUT string;
  256.                     last : OUT natural );
  257.  
  258.     --
  259.     -- Get a string from the terminal keyboard.  This ocurrs with no echo
  260.     -- and no translations.
  261.     --
  262.  
  263.     PROCEDURE tcf_name ( name : OUT string;
  264.                          last : OUT natural );
  265.     --
  266.     -- Returns the name of the terminal capabilities file as a string.
  267.     -- You better pass in a string of sufficient length to handle the name
  268.     -- that is returned or you will get a constraint error.  80 is a good
  269.     -- random number.
  270.     --
  271.  
  272.     PROCEDURE  terminal_name ( name : OUT string;
  273.                                last : OUT natural );
  274.     --
  275.     -- Returns the name of the terminal.  This name of a string like "tv970".
  276.     -- If the name cannot be determined then last is returned as 0 (zero).
  277.     -- Again,  you better make the name parameter big enough to hold the
  278.     -- value returned.
  279.     --
  280.     -- A DG implementation note:  This procedure looks for a file called
  281.     -- TERM on your searchlist.
  282.     --
  283.  
  284.     FUNCTION valid_character ( item : IN character ) RETURN boolean;
  285.  
  286.     --
  287.     -- Returns a boolean value identifying whether the character passed in
  288.     -- is safe to use in the environment.  Suspicious characters include
  289.     -- CTRL-S  CTRL-Q  CTRL-C  CTRL-Y.
  290.  
  291. END sysdep;
  292. ::::::::::
  293. tcf_spec.ada
  294. ::::::::::
  295. -- ----------------------------------------------------------------------------
  296. -- ABSTRACT:  This package incorporates a variation of the UNIX terminal
  297. --            capabilities data base which is used to define the mapping.
  298. --            The TCF package defines one procedure initialize.  This
  299. --            initialize procedure opens the TCF data base file, fills in
  300. --            the data structures and then closes the TCF data base file.
  301. --            The 'name' parameter passed in holds the terminal name.  This
  302. --            parameter is used to search the TCF file for the terminal
  303. --            characteristics associated with the terminal name.  Theses
  304. --            characteristics are then put into the termcap_operations
  305. --            variable.  The variable termcap_operations is used by both
  306. --            the DRIVER  package and the VT_INPUT  package.
  307. --
  308. -- -----------------------------------------------------------------------------
  309.  
  310. PACKAGE tcf IS
  311.  
  312. --  Constants
  313.  
  314.           max_termcap_entry : CONSTANT integer := 1920;
  315.           max_string_data   : CONSTANT integer := 100;
  316.  
  317. --  Types
  318.  
  319.           SUBTYPE string_data_array IS string( 1..max_string_data );
  320.  
  321.           SUBTYPE termcap_entry_array IS string( 1..max_termcap_entry );
  322.  
  323.           TYPE termcap_entries_enum IS
  324.                          ( cd,  -- clear to end of display
  325.                            ce,  -- clear to end of line
  326.                            cm,  -- cursor movement
  327.                            i_s, -- initialization string
  328.                            al,  -- insert line
  329.                            dl,  -- delete line
  330.                            dc,  -- delete character
  331.                            vb,  -- bell
  332.                            nl,  -- new line
  333.                            so,  -- start standout mode
  334.                            im,  -- enter insert mode
  335.                            ei,  -- end insert mode
  336.                            sf,  -- scroll up
  337.                            sr,  -- scroll down
  338.                            l1,  -- function key 1 label
  339.                            l2,  -- function key 2 label
  340.                            l3,  -- function key 3 label
  341.                            l4,  -- function key 4 label
  342.                            l5,  -- function key 5 label
  343.                            l6,  -- function key 6 label
  344.                            l7,  -- function key 7 label
  345.                            l8,  -- function key 8 label
  346.                            l9,  -- function key 9 label
  347.                            y0,  -- function key 10 label
  348.                            y1,  -- function key 11 label
  349.                            y2,  -- function key 12 label
  350.                            y3,  -- function key 13 label
  351.                            y4,  -- function key 14 label
  352.                            y5,  -- function key 15 label
  353.                            y6,  -- function key 16 label
  354.                            y7,  -- function key 17 label
  355.                            y8,  -- function key 18 label
  356.                            y9,  -- function key 19 label
  357.                            h0,  -- function key 20 label
  358.                            h1,  -- function key 21 label
  359.                            h2,  -- function key 22 label
  360.                            h3,  -- function key 23 label
  361.                            h4,  -- function key 24 label
  362.                            h5,  -- function key 25 label
  363.                            h6,  -- function key 26 label
  364.                            h7,  -- function key 27 label
  365.                            h8,  -- function key 28 label
  366.                            h9,  -- function key 29 label
  367.                            v0,  -- function key 30 label
  368.                            v1,  -- function key 31 label
  369.                            v2,  -- function key 32 label
  370.                            ku,  -- cursor up key
  371.                            kd,  -- cursor down key
  372.                            kl,  -- cursor left key
  373.                            kr,  -- cursor right key
  374.                            k1,  -- function 1 key
  375.                            k2,  -- function 2 key
  376.                            k3,  -- function 3 key
  377.                            k4,  -- function 4 key
  378.                            k5,  -- function 5 key
  379.                            k6,  -- function 6 key
  380.                            k7,  -- function 7 key
  381.                            k8,  -- function 8 key
  382.                            k9,  -- function 9 key
  383.                            x0,  -- function 10 key
  384.                            x1,  -- function 11 key
  385.                            x2,  -- function 12 key
  386.                            x3,  -- function 13 key
  387.                            x4,  -- function 14 key
  388.                            x5,  -- function 15 key
  389.                            x6,  -- function 16 key
  390.                            x7,  -- function 17 key
  391.                            x8,  -- function 18 key
  392.                            x9,  -- function 19 key
  393.                            g0,  -- function 20 key
  394.                            g1,  -- function 21 key
  395.                            g2,  -- function 22 key
  396.                            g3,  -- function 23 key
  397.                            g4,  -- function 24 key
  398.                            g5,  -- function 25 key
  399.                            g6,  -- function 26 key
  400.                            g7,  -- function 27 key
  401.                            g8,  -- function 28 key
  402.                            g9,  -- function 29 key
  403.                            t0,  -- function 30 key
  404.                            t1,  -- function 31 key
  405.                            t2,  -- function 32 key
  406.                            wr,  -- wraps at end of line
  407.                            su,  -- scrolls up at bottom
  408.                            li,  -- number of lines
  409.                            se,  -- end standout mode
  410.                            an,  -- ansi terminal
  411.                            vt,  -- vt terminal
  412.                            ca,  -- clear all of line
  413.                            cl,  -- clear screen
  414.                            ds,  --
  415.                            co   -- number of columns
  416.  
  417.                               );
  418.  
  419.           SUBTYPE key_range IS termcap_entries_enum RANGE ku..t2;
  420.  
  421.           TYPE termcap_operation_record IS
  422.           RECORD
  423.                 encoded_data              : string_data_array;
  424.                 encoded_data_length       : integer;
  425.                 parameter                 : integer;
  426.                 bool_parameter            : boolean;
  427.           END RECORD;
  428.  
  429.           TYPE termcap_operation_array is
  430.               array(termcap_entries_enum) of termcap_operation_record;
  431.  
  432. -- Variables
  433.  
  434.           termcap_operations       : termcap_operation_array;
  435.  
  436. -- Procedures
  437.  
  438.           PROCEDURE initialize ( name : IN string);
  439.  
  440. -- Exceptions
  441.  
  442.           tcf_error   : EXCEPTION;
  443.           unsupported_terminal : EXCEPTION;
  444.  
  445. END tcf;
  446. ::::::::::
  447. scroll_spec.ada
  448. ::::::::::
  449. -- ---------------------------------------------------------------------------
  450. -- ABSTRACT:  A user's program can WITH this package to provide a device-
  451. --            independent terminal interface that is functionally equivalent
  452. --            to a scroll-terminal.  This is the simplest form of terminal that
  453. --            this virtual terminal suports.  This package should be chosen for
  454. --            any of the following reasons:
  455. --
  456. --            1. The user's terminal is primitive.  Either it could be a CRT
  457. --               with little functionality, or a printing terminal.
  458. --            2. The user wants maximum transportability.
  459. --            3. The user does not need advanced capabiltiies for the
  460. --               application.
  461. --            4. The user's application may run over low speed communication
  462. --               lines, making the page and form mode unacceptable.
  463. -- -----------------------------------------------------------------------------
  464.  
  465.   PACKAGE scroll_terminal IS
  466.  
  467.       TYPE function_key_enum IS
  468.         ( up_arrow,       down_arrow,     left_arrow,     right_arrow,
  469.           f1,     f2,     f3,     f4,     f5,     f6,     f7,     f8,
  470.           f9,     f10,    f11,    f12,    f13,    f14,    f15,    f16,
  471.           f17,    f18,    f19,    f20,    f21,    f22,    f23,    f24,
  472.           f25,    f26,    f27,    f28,    f29,    f30,    f31,    f32 );
  473.  
  474.       TYPE function_key_descriptor( length : positive := 32)
  475.                                 IS PRIVATE;
  476.  
  477.       PROCEDURE open (name     : IN string := "none" );
  478.  
  479.       PROCEDURE close;
  480.  
  481.       PROCEDURE set_position (position : IN     positive);
  482.  
  483.       FUNCTION  position RETURN positive;
  484.  
  485.       FUNCTION  size RETURN positive;
  486.  
  487.       PROCEDURE set_tab;
  488.       PROCEDURE clear_tab;
  489.  
  490.       PROCEDURE tab       (count    : IN     positive := 1);
  491.  
  492.       PROCEDURE new_line  (count    : IN     positive := 1);
  493.  
  494.       PROCEDURE new_page  (count    : IN     positive := 1);
  495.  
  496.       PROCEDURE put (item     : IN     character);
  497.       PROCEDURE put (item     : IN     string);
  498.  
  499.       PROCEDURE update_line;
  500.  
  501.       PROCEDURE get( data : OUT string;
  502.                      last : OUT natural;
  503.                      keys : OUT function_key_descriptor;
  504.                   timeout : IN  duration := duration'last );
  505.  
  506.       FUNCTION function_count(keys : IN function_key_descriptor)
  507.           RETURN natural;
  508.  
  509.       PROCEDURE function_key(keys: IN function_key_descriptor;
  510.                              index : IN positive;
  511.                              key_identifier :    OUT function_key_enum;
  512.                              previous_position :    OUT natural);
  513.  
  514.       PROCEDURE function_key_name
  515.         ( key_identifier : IN     function_key_enum;
  516.           key_name       :    OUT string;
  517.           last           :    OUT natural);
  518.  
  519.       PROCEDURE bell;
  520.  
  521.       uninitialized          : EXCEPTION;
  522.       tcf_error              : EXCEPTION;
  523.       terminal_too_primitive : EXCEPTION;
  524.       unsupported_terminal   : EXCEPTION;
  525.       invalid_function_key   : EXCEPTION;
  526.  
  527.       PRIVATE
  528.  
  529.           TYPE keystroke_record IS
  530.           RECORD
  531.               key : function_key_enum;
  532.               position : positive;
  533.           END RECORD;
  534.  
  535.           TYPE function_key_array IS
  536.                   ARRAY( positive RANGE <> ) OF keystroke_record;
  537.  
  538.           TYPE function_key_descriptor( length : positive := 32 ) IS
  539.           RECORD
  540.               no_of_keys : natural := 0;
  541.               keys : function_key_array( 1..length );
  542.           END RECORD;
  543.  
  544.     END scroll_terminal;
  545. ::::::::::
  546. page_spec.ada
  547. ::::::::::
  548. -- ----------------------------------------------------------------------------
  549. -- ABSTRACT:  A user's program can WITH this package to provide a device-
  550. --            independent terminal interface that is functionally equivalent
  551. --            to a page_terminal.  This is the most advanced form of terminal
  552. --            that this virtual terminal supports.  This package should be
  553. --            chosen for any of the following reasons:
  554. --
  555. --            1. The user's terminal has advanced features.  The terminal is
  556. --               directly addressable, with erase to end of line, and erase
  557. --               to end of screen capabilities.
  558. --            2. The user wants advanced capabilities and is willing to
  559. --               sacrifice  some transportability.
  560. -- -----------------------------------------------------------------------------
  561.  
  562.     PACKAGE page_terminal IS
  563.  
  564.       TYPE function_key_enum IS
  565.         ( up_arrow,       down_arrow,     left_arrow,     right_arrow,
  566.           f1,     f2,     f3,     f4,     f5,     f6,     f7,     f8,
  567.           f9,     f10,    f11,    f12,    f13,    f14,    f15,    f16,
  568.           f17,    f18,    f19,    f20,    f21,    f22,    f23,    f24,
  569.           f25,    f26,    f27,    f28,    f29,    f30,    f31,    f32 );
  570.  
  571.       TYPE function_key_descriptor( length : positive := 32)
  572.                                 IS PRIVATE;
  573.  
  574.       TYPE xy_position IS
  575.       RECORD
  576.           line    : positive;
  577.           column  : positive;
  578.       END RECORD;
  579.  
  580.       TYPE select_enumeration IS (from_xy_position_to_end,
  581.                                   from_start_to_xy_position,
  582.                                   all_positions);
  583.  
  584.       TYPE graphic_rendition_enumeration IS
  585.                                  (primary_rendition,
  586.                                   reverse_image,
  587.                                   no_image     );
  588.  
  589.       PROCEDURE open (name : IN string := "none" );
  590.  
  591.       PROCEDURE close;
  592.  
  593.       PROCEDURE set_position (position : IN     xy_position);
  594.  
  595.       FUNCTION  position RETURN xy_position;
  596.  
  597.       FUNCTION  size RETURN xy_position;
  598.  
  599.       PROCEDURE delete_character (count    : IN     positive := 1);
  600.       PROCEDURE delete_line      (count    : IN     positive := 1);
  601.  
  602.       PROCEDURE erase_in_display (selection : select_enumeration);
  603.       PROCEDURE erase_in_line    (selection : select_enumeration);
  604.  
  605.       PROCEDURE enter_insert_mode;
  606.       PROCEDURE exit_insert_mode;
  607.  
  608.       PROCEDURE insert_line      (count     : IN     positive := 1);
  609.  
  610.       PROCEDURE select_graphic_rendition
  611.                        (selection : IN     graphic_rendition_enumeration);
  612.  
  613.       PROCEDURE set_tab;
  614.       PROCEDURE clear_tab;
  615.  
  616.       PROCEDURE tab       (count    : IN     positive := 1);
  617.  
  618.       PROCEDURE put (item     : IN     character);
  619.       PROCEDURE put (item     : IN     string);
  620.  
  621.       PROCEDURE update_screen
  622.                     ( top_line : IN positive;
  623.                       bottom_line : IN positive );
  624.  
  625.       PROCEDURE update_line( the_line : IN positive );
  626.  
  627.       PROCEDURE update_cursor;
  628.  
  629.       PROCEDURE redraw_screen;
  630.  
  631.       PROCEDURE get( data : OUT string;
  632.                      last : OUT natural;
  633.                      keys : OUT function_key_descriptor;
  634.                   timeout : IN  duration := duration'last );
  635.  
  636.       FUNCTION function_count(keys : IN function_key_descriptor)
  637.           RETURN natural;
  638.  
  639.       PROCEDURE function_key(keys: IN function_key_descriptor;
  640.                              index : IN positive;
  641.                              key_identifier :    OUT function_key_enum;
  642.                              previous_position :    OUT natural);
  643.  
  644.       PROCEDURE function_key_name
  645.         ( key_identifier : IN function_key_enum;
  646.           key_name       :    OUT string;
  647.           last           :    OUT natural);
  648.  
  649.       PROCEDURE bell;
  650.  
  651.       uninitialized          : EXCEPTION;
  652.       tcf_error              : EXCEPTION;
  653.       terminal_too_primitive : EXCEPTION;
  654.       unsupported_terminal   : EXCEPTION;
  655.       invalid_function_key   : EXCEPTION;
  656.  
  657.       PRIVATE
  658.  
  659.           TYPE keystroke_record IS
  660.           RECORD
  661.               key : function_key_enum;
  662.               position : positive;
  663.           END RECORD;
  664.  
  665.           TYPE function_key_array IS
  666.                   ARRAY( positive RANGE <> ) OF keystroke_record;
  667.  
  668.           TYPE function_key_descriptor( length : positive := 32 ) IS
  669.           RECORD
  670.               no_of_keys : natural := 0;
  671.               keys : function_key_array( 1..length );
  672.           END RECORD;
  673.  
  674.   END page_terminal;
  675. ::::::::::
  676. form_spec.ada
  677. ::::::::::
  678. -- -----------------------------------------------------------------------------
  679. -- ABSTRACT:  A user's program may WITH this package to provide a device-
  680. --            independent terminal interface that is functionally equivalent to
  681. --            a form terminal.
  682. --            The display of a form-mode terminal is divided into qualified
  683. --            areas that have the same attributes.  The user program defines
  684. --            qualified areas on the virtual display by making calls on
  685. --            form_terminal.set_position and form_terminal.define_qualified_area
  686. --            A call upon form_terminal.activate_form will map the virtual
  687. --            terminal display into the actual terminal display and allow
  688. --            editing of the form without user program intervention.  When
  689. --            the user has finished editing the form the user presses a
  690. --            function key (as defined in the terminal capabilities file)
  691. --            which returns control to the user's program.
  692. -- ----------------------------------------------------------------------------
  693.  
  694.   PACKAGE form_terminal IS
  695.  
  696.       TYPE xy_position IS
  697.       RECORD
  698.           line    : positive;
  699.           column  : positive;
  700.       END RECORD;
  701.  
  702.       TYPE termination_key_range IS RANGE 1..32;
  703.  
  704.       TYPE area_intensity  IS (none, normal, high);
  705.       TYPE area_protection IS (unprotected, protected);
  706.       TYPE area_input      IS (graphic_characters, numerics );
  707.  
  708.       PROCEDURE open (name     : IN string := "none");
  709.  
  710.       PROCEDURE close;
  711.  
  712.       PROCEDURE set_position (position : IN     xy_position);
  713.  
  714.       FUNCTION  position RETURN xy_position;
  715.  
  716.       FUNCTION  size RETURN xy_position;
  717.  
  718.       PROCEDURE define_qualified_area
  719.                        (intensity  : IN     area_intensity  := normal;
  720.                         protection : IN     area_protection := protected;
  721.                         input      : IN     area_input
  722.                                                  := graphic_characters );
  723.  
  724.       PROCEDURE clear_qualified_area;
  725.  
  726.       PROCEDURE tab;
  727.       PROCEDURE put (item     : IN     character);
  728.       PROCEDURE put (item     : IN     string);
  729.  
  730.       PROCEDURE get (item     :    OUT character);
  731.       PROCEDURE get (item     :    OUT string);
  732.  
  733.       PROCEDURE erase_area;
  734.       PROCEDURE erase_display;
  735.       PROCEDURE activate_form;
  736.  
  737.       FUNCTION  is_form_updated RETURN boolean;
  738.       FUNCTION  area_qualifier_requires_space RETURN boolean;
  739.       FUNCTION  termination_key RETURN termination_key_range;
  740.  
  741.  
  742.       uninitialized          : EXCEPTION;
  743.       tcf_error              : EXCEPTION;
  744.       terminal_too_primitive : EXCEPTION;
  745.       unsupported_terminal   : EXCEPTION;
  746.       invalid_function_key   : EXCEPTION;
  747.  
  748.   END form_terminal;
  749. ::::::::::
  750. vtinput_spec.ada
  751. ::::::::::
  752. -- -----------------------------------------------------------------------------
  753. -- ABSTRACT:  This package provides an interface to get keystrokes from the
  754. --            actual terminals keyboard.  The keystrokes include regular ASCII
  755. --            keys and function keys (including the arrow keys).  The function
  756. --            and arrow keys are identified throught the use of the terminal
  757. --            capabilities data base.  There can be up to 32 function keys.
  758. --            There will always be 4 arrow keys.
  759. -- -----------------------------------------------------------------------------
  760.  
  761. PACKAGE vt_input IS
  762.  
  763.   TYPE function_key_enum IS
  764.        ( up_arrow,       down_arrow,     left_arrow,     right_arrow,
  765.          f1,     f2,     f3,     f4,     f5,     f6,     f7,     f8,
  766.          f9,     f10,    f11,    f12,    f13,    f14,    f15,    f16,
  767.          f17,    f18,    f19,    f20,    f21,    f22,    f23,    f24,
  768.          f25,    f26,    f27,    f28,    f29,    f30,    f31,    f32 );
  769.  
  770. -- These could be private if I could simply figure out how to window
  771. -- the page_terminal to see these things efficiently...
  772. -- v------v--------v--------v---------v---------v---------v---------v-----v
  773.   TYPE keystroke_record IS
  774.   RECORD
  775.       key : function_key_enum;
  776.       position : positive;
  777.   END RECORD;
  778.  
  779.   TYPE function_key_array IS
  780.           ARRAY( positive RANGE <> ) OF keystroke_record;
  781.  
  782.   TYPE function_key_descriptor( length : positive := 32 ) IS
  783.   RECORD
  784.       no_of_keys : natural := 0;
  785.       keys : function_key_array( 1..length );
  786.   END RECORD;
  787. -- ^------^--------^--------^---------^---------^---------^---------^-----^
  788.  
  789.      PROCEDURE get( data : OUT string;
  790.                     last : OUT natural;
  791.                     keys : IN OUT function_key_descriptor;
  792.                  timeout : IN  duration := duration'last );
  793.  
  794.      FUNCTION function_count(keys : IN function_key_descriptor)
  795.          RETURN natural;
  796.  
  797.      PROCEDURE function_key(keys           : IN     function_key_descriptor;
  798.                             index          : IN     positive;
  799.                             key_identifier :    OUT function_key_enum;
  800.                          previous_position :    OUT natural);
  801.  
  802.      PROCEDURE function_key_name
  803.        ( key_identifier : IN     function_key_enum;
  804.          key_name       :    OUT string;
  805.          last           :    OUT natural);
  806.  
  807.      invalid_function_key  : EXCEPTION;
  808.      uninitialized         : EXCEPTION;
  809.  
  810. END vt_input;
  811. ::::::::::
  812. driver_spec.ada
  813. ::::::::::
  814. -- ----------------------------------------------------------------------------
  815. -- ABSTRACT:  The DRIVER package performs the following functions:
  816. --                * initialize the actual terminal,
  817. --                * initialize the TCF,
  818. --                * interpret the ANSI compatible character codes and translate
  819. --                  them into device specific character codes,
  820. --                * close the actual terminal
  821. -- ----------------------------------------------------------------------------
  822.  
  823. PACKAGE driver IS
  824.  
  825. -- Types
  826.  
  827.            TYPE terminal_capabilities_enum IS
  828.                     ( erase_to_end_of_screen_is,
  829.                       erase_to_end_of_line_is,
  830.                       move_the_cursor_is,
  831.                       insert_line_is,
  832.                       delete_line_is,
  833.                       delete_character_is,
  834.                       beep_is,
  835.                       highlight_is,
  836.                       erase_all_of_display_is,
  837.                       erase_all_of_line_is,
  838.                       new_line_is,
  839.                       insert_mode_is ) ;
  840.  
  841.            TYPE terminal_capabilities_set IS
  842.                     array( terminal_capabilities_enum ) OF boolean;
  843.  
  844.  
  845.  
  846. -- Variables
  847.  
  848.             supported_functions : terminal_capabilities_set;
  849.  
  850. -- Procedures
  851.  
  852. PROCEDURE vt_initialize(
  853.                 name  : IN string;
  854.                 lines : OUT integer;
  855.               columns : OUT integer );
  856.  
  857. PROCEDURE close_virtual_terminal;
  858.  
  859. PROCEDURE interpret ( command_string : IN string);
  860.  
  861. uninitialized        : EXCEPTION;
  862. tcf_error            : EXCEPTION;
  863. unsupported_terminal : EXCEPTION;
  864.  
  865. END driver;
  866. ::::::::::
  867. redisp_spec.ada
  868. ::::::::::
  869. -- -----------------------------------------------------------------------------
  870. -- ABSTRACT:  The REDISPLAY package perfroms the function of mappeing
  871. --            characters and lines from the data structures of the VT_CONTENT
  872. --            package to the actual display.
  873. --
  874. --            This package WITH's the VT_CONTENT package to make the data
  875. --            structures in VT_CONTENT visible to redisplay.  The VT_CONTENT
  876. --            data structures describe how the image on the actual display
  877. --            looks after REDISPLAY package is invoked and how the image of
  878. --            actual display looks before the REDISPLAY package is invoked.
  879. --            When a change is made to the data structures in VT_CONTENT, the
  880. --            image on the actual display must be updated to reflect the change.
  881. -- -----------------------------------------------------------------------------
  882.  
  883. WITH vt_content;
  884.  
  885. PACKAGE redisplay IS
  886.  
  887.     PROCEDURE fix_cursor( old_screen : IN OUT vt_content.vt_content_access;
  888.                           new_screen : IN OUT vt_content.vt_content_access );
  889.  
  890.     PROCEDURE redraw_screen(
  891.                        old_screen : IN OUT vt_content.vt_content_access;
  892.                        new_screen : IN vt_content.vt_content_access;
  893.                        top_line : vt_content.row_range;
  894.                        bottom_line : vt_content.row_range );
  895.  
  896.     PROCEDURE redisplay_screen_with_movement(
  897.                        old_screen : IN OUT vt_content.vt_content_access;
  898.                        new_screen : IN vt_content.vt_content_access;
  899.                        top_line : vt_content.row_range;
  900.                        bottom_line : vt_content.row_range );
  901.  
  902.  
  903.     PROCEDURE redisplay_screen_with_redraw(
  904.                        old_screen : IN OUT vt_content.vt_content_access;
  905.                        new_screen : IN vt_content.vt_content_access;
  906.                        top_line : IN vt_content.row_range;
  907.                        bottom_line : IN vt_content.row_range );
  908.  
  909.  
  910.     PROCEDURE redisplay_line_with_redraw(
  911.                        old_screen : IN OUT vt_content.vt_content_access;
  912.                        new_screen : IN vt_content.vt_content_access;
  913.                        old_line : IN vt_content.row_range;
  914.                        new_line : IN vt_content.row_range );
  915.  
  916. END redisplay;
  917. ::::::::::
  918. sysdep_body.ada
  919. ::::::::::
  920. -- ----------------------------------------------------------------------------
  921. -- ABSTRACT:  This system dependency package is the only package to be changed
  922. --            when rehosting the Virtual Terminal tool to another environment.
  923. --            The supported functions are:
  924. --                * open the physical terminal,
  925. --                * close the physical terminal,
  926. --                * put strings to the physical terminal,
  927. --                * get strings from the physical terminal,
  928. --                * get the terminal capabilities file (TCF) name,
  929. --                * get the terminal's name (to be subsequently looked up in TCF
  930. --                * check the validity of a particular character.
  931. -- -----------------------------------------------------------------------------
  932.  
  933. WITH tty_io,
  934.      text_io,
  935.      sys_calls,
  936.      file_definitions,
  937.      file_io,
  938.      bit_ops,
  939.      current_exception;
  940.  
  941. PACKAGE BODY sysdep IS
  942.  
  943.     buffer_byte_ptr : integer;
  944.     buffer : integer;
  945.  
  946.     invalid_chars_array : ARRAY( 1..2 ) OF character;
  947.  
  948.     terminal : file_definitions.channel_number;
  949.     tty : tty_io.file_type;
  950.  
  951.     previously_opened : boolean := false;
  952.  
  953.     temp_buffer_last : natural;
  954.  
  955.     PRAGMA page;
  956.     TASK tty_server IS
  957.         ENTRY go;
  958.         ENTRY start_get;
  959.         ENTRY get( data : OUT string;
  960.                    last : OUT natural );
  961.     END tty_server;
  962.  
  963.     TASK BODY tty_server IS
  964.         bytes_read : integer;
  965.         error_code : integer;
  966.     BEGIN
  967.         ACCEPT go;
  968.         LOOP
  969.             SELECT
  970.  
  971.                 ACCEPT start_get;
  972.                     file_io.read( terminal,
  973.                                   error_code,
  974.                                   bytes_read,
  975.                                   buffer_byte_ptr,
  976.                                   file_definitions.binary_io,
  977.                                   1 );
  978.                     buffer := bit_ops.logical_right_shift( buffer, 24 );
  979.  
  980.                 ACCEPT get( data : OUT string;
  981.                             last : OUT natural ) DO
  982.                     last := 1;
  983.                     data( 1 ) := character'val( buffer );
  984.                 END get;
  985.             OR
  986.  
  987.                 TERMINATE;
  988.  
  989.             END SELECT;
  990.         END LOOP;
  991.  
  992.     END tty_server;
  993.  
  994.  
  995.     PROCEDURE open IS
  996.     console_characteristics : file_io.device_characteristics;
  997.     error_code : integer;
  998.     ac0, ac1, ac2 : integer;
  999.     name : sys_calls.call_name;
  1000.     error_id : sys_calls.error_code;
  1001.     BEGIN
  1002.  
  1003.       IF NOT previously_opened
  1004.       THEN
  1005.  
  1006.        tty_io.open( tty, tty_io.inout_file, "@console" );
  1007.  
  1008.        -- turn off the keyboard interrupt capabilities
  1009.  
  1010.        ac0 := 0;
  1011.        ac1 := 0;
  1012.        ac2 := 0;
  1013.        name := sys_calls.kioff;
  1014.        sys_calls.long_sys( name, ac0, ac1, ac2, error_id );
  1015.  
  1016.        file_io.open( "@console", terminal, error_code,
  1017.                   file_definitions.open_for_input_output +
  1018.                   file_definitions.binary_io +
  1019.                   file_definitions.variable_length  );
  1020.  
  1021.        file_io.get_characteristics( terminal,
  1022.                   console_characteristics, error_code );
  1023.        console_characteristics.echo := file_io.no_echo;
  1024.        console_characteristics.characteristics(
  1025.                   file_io.non_ansi_standard_device ) := false;
  1026.        file_io.set_characteristics( terminal,
  1027.                   console_characteristics, error_code );
  1028.  
  1029.        buffer_byte_ptr := integer'val( buffer'address );
  1030.        buffer_byte_ptr := bit_ops.left_shift_by_1( buffer_byte_ptr );
  1031.  
  1032.        tty_server.go;
  1033.  
  1034.        previously_opened := true;
  1035.      END IF;
  1036.  
  1037.     END open;
  1038.  
  1039.     PROCEDURE close IS
  1040.     error_code : integer;
  1041.     BEGIN
  1042.        -- lets not do anything and let AOS clean up after me.
  1043. --     file_io.close( terminal, error_code );
  1044.        NULL;
  1045.     END close;
  1046.  
  1047.  
  1048.     PROCEDURE put ( data : IN string ) IS
  1049.     BEGIN
  1050.        tty_io.put( tty, data );
  1051.     END put;
  1052.  
  1053.     PROCEDURE get ( data : OUT string;
  1054.                     last : OUT natural ) IS
  1055.     BEGIN
  1056.         tty_server.start_get;
  1057.         tty_server.get( data, last );
  1058.     END get;
  1059.  
  1060.  
  1061.     PROCEDURE tcf_name ( name : OUT string;
  1062.                          last : OUT natural ) IS
  1063.     BEGIN
  1064.        last := name'first+2;
  1065.        name( name'first..(name'first)+2 ) := "TCF";
  1066.     END tcf_name;
  1067.  
  1068.  
  1069.     PROCEDURE  terminal_name ( name : OUT string;
  1070.                                last : OUT natural ) IS
  1071.        terminal_name_file : text_io.file_type;
  1072.        line_buffer : string( 1..80 );
  1073.        last_char_on_line : natural;
  1074.     BEGIN
  1075.        text_io.open( terminal_name_file, text_io.in_file, "TERM" );
  1076.        text_io.reset(terminal_name_file);
  1077.        text_io.get_line( terminal_name_file, line_buffer, last_char_on_line );
  1078.        name( name'first..(name'first)+last_char_on_line-1 ) :=
  1079.                                 line_buffer( 1..last_char_on_line );
  1080.        last := name'first + last_char_on_line - 1;
  1081.        text_io.close( terminal_name_file );
  1082.     EXCEPTION
  1083.        WHEN others => last := 0;
  1084.     END terminal_name;
  1085.  
  1086.  
  1087.     FUNCTION valid_character ( item : IN character ) RETURN boolean IS
  1088.        valid_flag : boolean;
  1089.     BEGIN
  1090.        valid_flag := true;
  1091.        FOR i IN 1..8
  1092.        LOOP
  1093.           IF invalid_chars_array( i )=item
  1094.           THEN valid_flag := false;
  1095.           END IF;
  1096.        END LOOP;
  1097.        RETURN valid_flag;
  1098.     END valid_character;
  1099.  
  1100. BEGIN
  1101.  
  1102.     -- please refer to AOS/VS Programmer's Manual, Volume 1, System Concepts
  1103.     -- page 5-20 for a description of these character codes.
  1104.  
  1105.     invalid_chars_array( 1 ) := ascii.dc3;  -- CTRL-S
  1106.     invalid_chars_array( 2 ) := ascii.dc1;  -- CTRL-Q
  1107.  
  1108. END sysdep;
  1109. ::::::::::
  1110. tcf_body.ada
  1111. ::::::::::
  1112. -- ----------------------------------------------------------------------------
  1113. -- ABSTRACT:  This package incorporates a variation of the UNIX terminal
  1114. --            capabilities data base which is used to define the mapping.
  1115. --            The TCF package defines one procedure called initialize.
  1116. --            This initialize procedure opens the TCF data base file,
  1117. --            fills in the data structures and then closes the TCF data
  1118. --            base file.  The 'name' parameter passed in holds the
  1119. --            terminal name.  This parameter is used to search the TCF
  1120. --            file for the terminal characteristics associated with the
  1121. --            terminal name.  These characteristics are then put into the
  1122. --            termcap_operations variable.  The variable termcap_operations
  1123. --            is used by both the driver package and the vt_input package.
  1124. -- -----------------------------------------------------------------------------
  1125.  
  1126. WITH sysdep, text_io;
  1127.  
  1128. PACKAGE BODY tcf IS
  1129.  
  1130. -- ------------------------------------------------------------------------
  1131. -- initialize procedure initializes the terminal by opening the TERMCAP
  1132. -- (TCF).
  1133. -- searching the TCF for the terminal name
  1134. -- associating the terminal characteristics in the TCF to the
  1135. -- data structures in the TCF_SPEC.
  1136. -- -------------------------------------------------------------------------
  1137.  
  1138. PROCEDURE initialize ( name : IN string) IS
  1139.  
  1140.  SUBTYPE gen_string IS STRING(1..80);
  1141.  
  1142.  found : boolean;
  1143.  termcap_file : text_io.file_type;
  1144.  read_buffer :  STRING(1..1920);
  1145.  continue : boolean;
  1146.  termcap_entry : termcap_entry_array;
  1147.  i,j,k : integer;
  1148.  tcf_last   : natural;
  1149.  term_file :   gen_string;
  1150.  term_name : string(1..80);
  1151.  term_name_last : natural;
  1152.  
  1153. -- ---------------------------------------------------------------------------
  1154. -- this procedure blanks out the data structures that will
  1155. -- hold the terminal characteristics.
  1156.  
  1157.    PROCEDURE initialize_termcap_entry_fields IS
  1158.  
  1159.        i : termcap_entries_enum;
  1160.  
  1161.    BEGIN -- initialize_termcap_entry_fields
  1162.  
  1163.          -- for each entry in the termcap_operations variable, initialize to
  1164.          -- appropriate default value.
  1165.  
  1166.      FOR i IN cd..co
  1167.      LOOP
  1168.        termcap_operations(i).encoded_data_length := 0;
  1169.        termcap_operations(i).parameter := 0;
  1170.        termcap_operations(i).bool_parameter := false;
  1171.      END LOOP;
  1172.  
  1173.    END initialize_termcap_entry_fields;
  1174.  
  1175. -- -----------------------------------------------------------------------------
  1176.  
  1177.    PROCEDURE get_termcap_entry_fields(entry_length : IN integer) IS
  1178.  
  1179.    TYPE fields_entry_enum IS
  1180.  
  1181.                          ( cd,  -- clear to end of display
  1182.                            ce,  -- clear to end of line
  1183.                            cm,  -- cursor movement
  1184.                            i_s, -- initialization string
  1185.                            al,  -- insert line
  1186.                            dl,  -- delete line
  1187.                            dc,  -- delete character
  1188.                            vb,  -- bell
  1189.                            nl,  -- new line
  1190.                            so,  -- start standout mode
  1191.                            im,  -- enter insert mode
  1192.                            ei,  -- end insert mode
  1193.                            sf,  -- scroll up
  1194.                            sr,  -- scroll down
  1195.                            l1,  -- function key 1 label
  1196.                            l2,  -- function key 2 label
  1197.                            l3,  -- function key 3 label
  1198.                            l4,  -- function key 4 label
  1199.                            l5,  -- function key 5 label
  1200.                            l6,  -- function key 6 label
  1201.                            l7,  -- function key 7 label
  1202.                            l8,  -- function key 8 label
  1203.                            l9,  -- function key 9 label
  1204.                            y0,  -- function key 10 label
  1205.                            y1,  -- function key 11 label
  1206.                            y2,  -- function key 12 label
  1207.                            y3,  -- function key 13 label
  1208.                            y4,  -- function key 14 label
  1209.                            y5,  -- function key 15 label
  1210.                            y6,  -- function key 16 label
  1211.                            y7,  -- function key 17 label
  1212.                            y8,  -- function key 18 label
  1213.                            y9,  -- function key 19 label
  1214.                            h0,  -- function key 20 label
  1215.                            h1,  -- function key 21 label
  1216.                            h2,  -- function key 22 label
  1217.                            h3,  -- function key 23 label
  1218.                            h4,  -- function key 24 label
  1219.                            h5,  -- function key 25 label
  1220.                            h6,  -- function key 26 label
  1221.                            h7,  -- function key 27 label
  1222.                            h8,  -- function key 28 label
  1223.                            h9,  -- function key 29 label
  1224.                            v0,  -- function key 30 label
  1225.                            v1,  -- function key 31 label
  1226.                            v2,  -- function key 32 label
  1227.                            ku,  -- cursor up key
  1228.                            kd,  -- cursor down key
  1229.                            kl,  -- cursor left key
  1230.                            kr,  -- cursor right key
  1231.                            k1,  -- function 1 key
  1232.                            k2,  -- function 2 key
  1233.                            k3,  -- function 3 key
  1234.                            k4,  -- function 4 key
  1235.                            k5,  -- function 5 key
  1236.                            k6,  -- function 6 key
  1237.                            k7,  -- function 7 key
  1238.                            k8,  -- function 8 key
  1239.                            k9,  -- function 9 key
  1240.                            x0,  -- function 10 key
  1241.                            x1,  -- function 11 key
  1242.                            x2,  -- function 12 key
  1243.                            x3,  -- function 13 key
  1244.                            x4,  -- function 14 key
  1245.                            x5,  -- function 15 key
  1246.                            x6,  -- function 16 key
  1247.                            x7,  -- function 17 key
  1248.                            x8,  -- function 18 key
  1249.                            x9,  -- function 19 key
  1250.                            g0,  -- function 20 key
  1251.                            g1,  -- function 21 key
  1252.                            g2,  -- function 22 key
  1253.                            g3,  -- function 23 key
  1254.                            g4,  -- function 24 key
  1255.                            g5,  -- function 25 key
  1256.                            g6,  -- function 26 key
  1257.                            g7,  -- function 27 key
  1258.                            g8,  -- function 28 key
  1259.                            g9,  -- function 29 key
  1260.                            t0,  -- function 30 key
  1261.                            t1,  -- function 31 key
  1262.                            t2,  -- function 32 key
  1263.                            wr,  -- wraps at end of line
  1264.                            su,  -- scrolls up at bottom
  1265.                            li,  -- number of lines
  1266.                            se,  -- end standout mode
  1267.                            an,  -- ansi terminal
  1268.                            vt,  -- vt100 terminal
  1269.                            ca,  -- clear all of line
  1270.                            cl,  -- clear screen
  1271.                            ds,  --
  1272.                            co   -- number of columns
  1273.                               );
  1274.  
  1275.      i,j : INTEGER;
  1276.      field_entries_list : CONSTANT STRING :=
  1277.                         "cdcecmisaldldcvbnlsoimeisfsrl1l2l3l4l5l6" &
  1278.                         "l7l8l9y0y1y2y3y4y5y6y7y8y9h0h1h2h3h4h5h6" &
  1279.                         "h7h8h9v0v1v2kukdklkrk1k2k3k4k5k6k7k8k9x0" &
  1280.                         "x1x2x3x4x5x6x7x8x9g0g1g2g3g4g5g6g7g8g9t0" &
  1281.                         "t1t2wrsuliseanvtcacldsco" ;
  1282.  
  1283. -- ----------------------------------------------------------------------------
  1284.    PROCEDURE store_entry(entry1 : IN termcap_entries_enum;
  1285.                          position : IN OUT integer ) IS
  1286.  
  1287.    i : integer;
  1288.  
  1289. -- --------------------------------------------------------------------
  1290.      PROCEDURE decode_entry(data : IN OUT termcap_operation_record ) IS
  1291.  
  1292.      i,j : integer;
  1293.      store_temp : string_data_array;
  1294.      store_octal : integer;
  1295.      mil_padding : integer;
  1296.  
  1297.      BEGIN -- decode_entry
  1298.  
  1299.       mil_padding := 0;
  1300.       i := 1;
  1301.       j := 0;
  1302.  
  1303.       WHILE data.encoded_data(i) IN '0'..'9'
  1304.       LOOP
  1305.         mil_padding := (mil_padding*10) + (character'pos(data.encoded_data(i)) -
  1306.                                          character'pos('0'));
  1307.         i:= i + 1;
  1308.       END LOOP;
  1309.  
  1310.       IF data.encoded_data(i) /= '*'
  1311.       THEN i := i - 1;
  1312.       END IF;
  1313.  
  1314.       LOOP
  1315.         i := i + 1;
  1316.         j := j + 1;
  1317.  
  1318.         CASE data.encoded_data(i) IS
  1319.  
  1320.          WHEN '^' =>
  1321.                     i := i + 1;
  1322.                     store_temp (j) := character'val(character'pos(
  1323.                                          data.encoded_data(i))-64);
  1324.  
  1325.          WHEN '\' =>
  1326.                     i := i + 1;
  1327.                     CASE data.encoded_data(i) IS
  1328.  
  1329.                          WHEN 'e'|'E' =>
  1330.                                store_temp(j) := character'val(27); --ESC
  1331.                          WHEN '^' =>
  1332.                                store_temp(j) := '^';
  1333.                          WHEN 'n'|'N' =>
  1334.                                store_temp(j) := character'val(10); --LF
  1335.                          WHEN '\' =>
  1336.                                store_temp(j) := '\';
  1337.                          WHEN 'r'|'R' =>
  1338.                                store_temp(j) := character'val(13); --CR
  1339.                          WHEN 't'|'T' =>
  1340.                                store_temp(j) := character'val(9);  -- TAB
  1341.                          WHEN 'b'|'B' =>
  1342.                                store_temp(j) := character'val(8);  -- BS
  1343.                          WHEN 'f'|'F' =>
  1344.                                store_temp(j) := character'val(12);  -- FF
  1345.                          WHEN OTHERS => -- must be an octal number
  1346.                              store_octal := 0;
  1347.                              WHILE (data.encoded_data(i) IN '0'..'7' )
  1348.                              LOOP
  1349.                                 store_octal := (store_octal * 8) +
  1350.                                     (character'pos(data.encoded_data(i))-
  1351.                                      character'pos('0'));
  1352.                                 i := i + 1;
  1353.                              END LOOP;
  1354.                              i := i - 1;
  1355.                              store_temp(j) := character'val(store_octal);
  1356.                           END CASE;
  1357.                       WHEN OTHERS =>
  1358.                               store_temp(j) := data.encoded_data(i);
  1359.                    END CASE;
  1360.  
  1361.  
  1362.                    EXIT WHEN i = data.encoded_data_length;
  1363.                   END LOOP;
  1364.  
  1365.                   data.encoded_data_length := j;
  1366.                   FOR j IN 1..data.encoded_data_length
  1367.                   LOOP
  1368.                       data.encoded_data(j) := store_temp(j);
  1369.                   END LOOP;
  1370.               END decode_entry;
  1371.  
  1372. -- -----------------------------------------------------------------------------
  1373.  
  1374.    BEGIN -- store_entry
  1375.  
  1376.          -- scan the termcap entry to determine if it is an value assignment(#),
  1377.          -- a boolean value(:), or an escape sequence to decode (=).
  1378.  
  1379.      position := position + 2;
  1380.  
  1381.      CASE termcap_entry(position) IS
  1382.           WHEN '=' =>
  1383.             position := position + 1; -- position on the first character
  1384.             i := 1;
  1385.             WHILE termcap_entry(position) /= ':'
  1386.             LOOP
  1387.                termcap_operations(entry1).encoded_data(i) :=
  1388.                               termcap_entry(position);
  1389.                i := i + 1;
  1390.                position := position + 1;
  1391.             END LOOP;
  1392.             termcap_operations(entry1).encoded_data_length := i - 1;
  1393.             decode_entry(termcap_operations(entry1));
  1394.           WHEN  ':' =>
  1395.              termcap_operations(entry1).bool_parameter := true;
  1396.           WHEN  '#' =>
  1397.              LOOP
  1398.                position := position + 1;
  1399.                termcap_operations(entry1).parameter :=
  1400.                 (termcap_operations(entry1).parameter * 10) +
  1401.                 (character'pos(termcap_entry(position)) -
  1402.                  character'pos('0'));
  1403.                EXIT WHEN NOT (termcap_entry(position+1) IN  '0'..'9');
  1404.               END LOOP;
  1405.  
  1406.              position := position + 1;
  1407.           WHEN OTHERS => null;
  1408.       END CASE;
  1409.  END store_entry;
  1410.  
  1411. -- -------------------------------------------------------------------------
  1412.  
  1413.      BEGIN -- get_termcap_entries_fields
  1414.  
  1415. -- initialize data structures that will hold termcap entries to default values.
  1416.  
  1417.               initialize_termcap_entry_fields;
  1418.  
  1419.               i := 1;
  1420.  
  1421. -- associate terminal capabilties to appropriate data structures
  1422.  
  1423.               WHILE i < entry_length
  1424.               LOOP
  1425.                 IF ( termcap_entry( i ) = ':' ) AND
  1426.                    ( termcap_entry( i + 1) /= '\' )
  1427.                 THEN
  1428.                   j := field_entries_list'first - 2;
  1429.                   i := i + 1;
  1430.                   LOOP
  1431.                     j := j + 2;
  1432.                     EXIT WHEN ( j >= field_entries_list'last ) OR ELSE
  1433.                       ((termcap_entry( i ) = field_entries_list ( j )) AND
  1434.                       (termcap_entry(i+1) = field_entries_list (j+1)));
  1435.                   END LOOP;
  1436.                   IF j < field_entries_list'last
  1437.  
  1438.                   THEN
  1439.                     CASE j IS
  1440.                       WHEN 1 =>
  1441.                                 store_entry( cd,i);
  1442.  
  1443.                       WHEN 3 =>
  1444.                                 store_entry(ce,i);
  1445.  
  1446.                       WHEN 5 =>
  1447.                                 store_entry(cm,i);
  1448.  
  1449.                       WHEN 7 =>
  1450.                                 store_entry(i_s,i);
  1451.  
  1452.                       WHEN 9 =>
  1453.                                 store_entry(al,i);
  1454.  
  1455.                       WHEN 11 =>
  1456.                                 store_entry(dl,i);
  1457.  
  1458.                       WHEN 13 =>
  1459.                                 store_entry(dc,i);
  1460.  
  1461.                       WHEN 15 =>
  1462.                                 store_entry(vb,i);
  1463.                       WHEN 17 =>
  1464.                                 store_entry(nl,i);
  1465.  
  1466.                       WHEN 19 => store_entry(so,i);
  1467.                       WHEN 21 =>
  1468.                                  store_entry(im,i);
  1469.  
  1470.                       WHEN 23 => store_entry(ei,i);
  1471.                       WHEN 25 => store_entry(sf,i);
  1472.  
  1473.                       WHEN 27 =>
  1474.                                  store_entry(sr,i);
  1475.  
  1476.                       WHEN 29 => store_entry(l1,i);
  1477.                       WHEN 31 => store_entry(l2,i);
  1478.                       WHEN 33 => store_entry(l3,i);
  1479.                       WHEN 35 => store_entry(l4,i);
  1480.                       WHEN 37 => store_entry(l5,i);
  1481.                       WHEN 39 => store_entry(l6,i);
  1482.                       WHEN 41 => store_entry(l7,i);
  1483.                       WHEN 43 => store_entry(l8,i);
  1484.                       WHEN 45 => store_entry(l9,i);
  1485.                       WHEN 47 => store_entry(y0,i);
  1486.                       WHEN 49 => store_entry(y1,i);
  1487.                       WHEN 51 => store_entry(y2,i);
  1488.                       WHEN 53 => store_entry(y3,i);
  1489.                       WHEN 55 => store_entry(y4,i);
  1490.                       WHEN 57 => store_entry(y5,i);
  1491.                       WHEN 59 => store_entry(y6,i);
  1492.                       WHEN 61 => store_entry(y7,i);
  1493.                       WHEN 63 => store_entry(y8,i);
  1494.                       WHEN 65 => store_entry(y9,i);
  1495.                       WHEN 67 => store_entry(h0,i);
  1496.                       WHEN 69 => store_entry(h1,i);
  1497.                       WHEN 71 => store_entry(h2,i);
  1498.                       WHEN 73 => store_entry(h3,i);
  1499.                       WHEN 75 => store_entry(h4,i);
  1500.                       WHEN 77 => store_entry(h5,i);
  1501.                       WHEN 79 => store_entry(h6,i);
  1502.                       WHEN 81 => store_entry(h7,i);
  1503.                       WHEN 83 => store_entry(h8,i);
  1504.                       WHEN 85 => store_entry(h9,i);
  1505.                       WHEN 87 => store_entry(v0,i);
  1506.                       WHEN 89 => store_entry(v1,i);
  1507.                       WHEN 91 => store_entry(v2,i);
  1508.                       WHEN 93 => store_entry(ku,i);
  1509.                       WHEN 95 => store_entry(kd,i);
  1510.                       WHEN 97 => store_entry(kl,i);
  1511.                       WHEN 99 => store_entry(kr,i);
  1512.                       WHEN 101 => store_entry(k1,i);
  1513.                       WHEN 103 => store_entry(k2,i);
  1514.                       WHEN 105 => store_entry(k3,i);
  1515.                       WHEN 107 => store_entry(k4,i);
  1516.                       WHEN 109 => store_entry(k5,i);
  1517.                       WHEN 111 => store_entry(k6,i);
  1518.                       WHEN 113 => store_entry(k7,i);
  1519.                       WHEN 115 => store_entry(k8,i);
  1520.                       WHEN 117 => store_entry(k9,i);
  1521.                       WHEN 119 => store_entry(x0,i);
  1522.                       WHEN 121 => store_entry(x1,i);
  1523.                       WHEN 123 => store_entry(x2,i);
  1524.                       WHEN 125 => store_entry(x3,i);
  1525.                       WHEN 127 => store_entry(x4,i);
  1526.                       WHEN 129 => store_entry(x5,i);
  1527.                       WHEN 131 => store_entry(x6,i);
  1528.                       WHEN 133 => store_entry(x7,i);
  1529.                       WHEN 135 => store_entry(x8,i);
  1530.                       WHEN 137 => store_entry(x9,i);
  1531.                       WHEN 139 => store_entry(g0,i);
  1532.                       WHEN 141 => store_entry(g1,i);
  1533.                       WHEN 143 => store_entry(g2,i);
  1534.                       WHEN 145 => store_entry(g3,i);
  1535.                       WHEN 147 => store_entry(g4,i);
  1536.                       WHEN 149 => store_entry(g5,i);
  1537.                       WHEN 151 => store_entry(g6,i);
  1538.                       WHEN 153 => store_entry(g7,i);
  1539.                       WHEN 155 => store_entry(g8,i);
  1540.                       WHEN 157 => store_entry(g9,i);
  1541.                       WHEN 159 => store_entry(t0,i);
  1542.                       WHEN 161 => store_entry(t1,i);
  1543.                       WHEN 163 => store_entry(t2,i);
  1544.                       WHEN 165 => store_entry(wr,i);
  1545.                       WHEN 167 => store_entry(su,i);
  1546.                       WHEN 169 => store_entry(li,i);
  1547.                       WHEN 171 => store_entry(se,i);
  1548.                       WHEN 173 => store_entry(an,i);
  1549.                       WHEN 175 => store_entry(vt,i);
  1550.                       WHEN 177 => store_entry(ca,i);
  1551.                       WHEN 179 => store_entry(cl,i);
  1552.                       WHEN 181 => store_entry(ds,i);
  1553.                       WHEN 183 => store_entry(co,i);
  1554.                       WHEN OTHERS => null;
  1555.                   END CASE;
  1556.             END IF;
  1557.         ELSE i := i + 1;
  1558.         END IF;
  1559.      END  LOOP;
  1560.  
  1561. END get_termcap_entry_fields;
  1562.  
  1563. -- -------------------------------------------------------------------
  1564. -- open the TCF
  1565.  
  1566.   PROCEDURE inittcf is
  1567.  
  1568.   BEGIN -- inittcf
  1569.  
  1570.   text_io.open(termcap_file,text_io.in_file,term_file(1..tcf_last));
  1571.  
  1572.   EXCEPTION
  1573.         WHEN OTHERS => RAISE tcf_error;
  1574.  
  1575.   END inittcf;
  1576.  
  1577. -- --------------------------------------------------------------------
  1578.  
  1579. BEGIN -- initialize
  1580.  
  1581. -- determine if user supplied terminal name
  1582. -- if not, call sysdep.terminal_name to get default terminal_name.
  1583.  
  1584.        IF ((name'last - name'first) = 3 ) AND THEN
  1585.           name(name'first..name'first+3) = "none"
  1586.        THEN
  1587.             sysdep.terminal_name(term_name,term_name_last);
  1588.        ELSE
  1589.            term_name(1..name'length) := name;
  1590.            term_name_last := name'length;
  1591.        END IF;
  1592.  
  1593.  
  1594. -- find the name of the tcf
  1595.  
  1596.        sysdep.tcf_name(term_file,tcf_last);
  1597.  
  1598. -- open the tcf
  1599.  
  1600.        inittcf;
  1601.  
  1602.        found := false;
  1603.  
  1604. -- search the tcf for the terminal name passed in
  1605.  
  1606.        WHILE (NOT found) AND (NOT text_io.end_of_file( termcap_file))
  1607.  
  1608.        LOOP
  1609.               LOOP
  1610.                    text_io.get_line( termcap_file, read_buffer, i );
  1611.               EXIT WHEN ((read_buffer( 1 ) /= ' ') AND
  1612.                          (read_buffer( 1 ) /= character'val(9)) AND
  1613.  
  1614.                          (read_buffer( 1 ) /= '#')) OR
  1615.                           text_io.end_of_file( termcap_file );
  1616.               END LOOP;
  1617.  
  1618.               i := 0;
  1619.               LOOP
  1620.                      i := i + 1;
  1621.               EXIT WHEN ( read_buffer( i ) = '|' ) OR
  1622.                         ( read_buffer( i ) = ':' );
  1623.               END LOOP;
  1624.  
  1625.               IF read_buffer( i ) /= ':'
  1626.               THEN
  1627.                       i := i + 1;
  1628.                       j := term_name'first;
  1629.                       continue := true;
  1630.  
  1631.                       WHILE (j <= term_name_last) AND continue
  1632.  
  1633.                       LOOP
  1634.                             IF read_buffer( i ) /= term_name( j )
  1635.                             THEN continue := false;
  1636.                             END IF;
  1637.                             j := j + 1;
  1638.                             i := i + 1;
  1639.                       END LOOP;
  1640.                       IF (read_buffer ( i ) = '|' ) AND continue
  1641.                       THEN found := true;
  1642.                       END IF;
  1643.                 END IF;
  1644.     END LOOP;
  1645.  
  1646.  
  1647. -- found terminal name
  1648.  
  1649.  IF found
  1650.  THEN
  1651.                 k := 1;
  1652.                 text_io.get_line( termcap_file, read_buffer, i );
  1653.  
  1654.                 WHILE (read_buffer( 1 ) = ' ') OR
  1655.                       (read_buffer( 1 ) = character'val(9))
  1656.                 LOOP
  1657.  
  1658.                         FOR j IN 1..i
  1659.                         LOOP
  1660.                               termcap_entry( k ) := read_buffer( j );
  1661.                               k := k + 1;
  1662.                         END LOOP;
  1663.                         text_io.get_line( termcap_file, read_buffer, i);
  1664.                         IF text_io.end_of_line( termcap_file )
  1665.                         THEN read_buffer( 1 ) := '#';
  1666.                         END IF;
  1667.                  END LOOP;
  1668.  
  1669.                  get_termcap_entry_fields(k);
  1670.  
  1671.                  IF termcap_operations(i_s).encoded_data_length /= 0
  1672.  
  1673.                  THEN sysdep.put(termcap_operations(i_s).encoded_data(1..
  1674.                           termcap_operations(i_s).encoded_data_length));
  1675.  
  1676.                  END IF;
  1677.  
  1678.   ELSE
  1679.  
  1680. -- couldn't find terminal name in tcf file, raise exception
  1681.  
  1682.         RAISE unsupported_terminal;
  1683.   END IF;
  1684.  
  1685. EXCEPTION
  1686.         WHEN text_io.end_error =>
  1687.                                   raise unsupported_terminal;
  1688.         WHEN unsupported_terminal => raise;
  1689.         WHEN tcf_error            => raise;
  1690.         WHEN OTHERS => RAISE tcf_error;
  1691. END initialize;
  1692.  
  1693.  
  1694. END tcf;
  1695. ::::::::::
  1696. driver_body.ada
  1697. ::::::::::
  1698. -- ----------------------------------------------------------------------------
  1699. -- ABSTRACT:  The DRIVER package performs the following functions:
  1700. --                * initialize the actual terminal,
  1701. --                * initialize the TCF,
  1702. --                * interpret the ANSI compatible character codes and
  1703. --                  translate them into device specific character codes,
  1704. --                * close the actual terminal.
  1705. -- -----------------------------------------------------------------------------
  1706.  
  1707. WITH sysdep, text_io, tcf;
  1708.  
  1709. PACKAGE BODY driver IS
  1710.  
  1711.  out_buffer : STRING(1..1920);
  1712.  initialized : BOOLEAN := false;
  1713.  
  1714.     PROCEDURE vt_initialize(
  1715.                       name   :  IN string;
  1716.                       lines  :  OUT integer;
  1717.                       columns:  OUT integer ) is
  1718.  
  1719.  
  1720. -- open the virtual terminal by calling sysdep.open
  1721. -- initialize the virtual terminal by calling tcf.initialize
  1722. -- passing the name of the terminal as a parameter.
  1723.  
  1724. -- associate the terminal characteristics to the
  1725. -- supported functions variable.
  1726.  
  1727.        BEGIN -- virtual_terminal_initialize
  1728.  
  1729.   -- initialize the terminal
  1730.  
  1731.          sysdep.open;
  1732.  
  1733.          tcf.initialize(name);
  1734.  
  1735.          lines := tcf.termcap_operations(tcf.li).parameter;
  1736.          columns := tcf.termcap_operations(tcf.co).parameter;
  1737.  
  1738.          supported_functions :=
  1739.                             terminal_capabilities_set'(erase_to_end_of_screen_is
  1740.                             ..insert_mode_is => false);
  1741.  
  1742.  
  1743.          IF tcf.termcap_operations(tcf.cd).encoded_data_length > 0
  1744.                    then supported_functions(erase_to_end_of_screen_is)
  1745.                                                  := true;
  1746.          END IF;
  1747.  
  1748.          IF tcf.termcap_operations(tcf.ce).encoded_data_length > 0
  1749.                        THEN supported_functions(erase_to_end_of_line_is)
  1750.                                                  := true;
  1751.          END IF;
  1752.  
  1753.          IF tcf.termcap_operations(tcf.cm).encoded_data_length > 0
  1754.                        THEN supported_functions(move_the_cursor_is)
  1755.                                                  := true;
  1756.          END IF;
  1757.  
  1758.          IF tcf.termcap_operations(tcf.al).encoded_data_length > 0
  1759.                        THEN supported_functions(insert_line_is)
  1760.                                                  := true;
  1761.          END IF;
  1762.  
  1763.          IF tcf.termcap_operations(tcf.dl).encoded_data_length > 0
  1764.                        THEN supported_functions(delete_line_is)
  1765.                                                  := true;
  1766.          END IF;
  1767.  
  1768.          IF tcf.termcap_operations(tcf.dc).encoded_data_length > 0
  1769.                        THEN supported_functions(delete_character_is)
  1770.                                                  := true;
  1771.          END IF;
  1772.          IF tcf.termcap_operations(tcf.vb).encoded_data_length > 0
  1773.                        THEN supported_functions(beep_is)
  1774.                                                  := true;
  1775.          END IF;
  1776.          IF tcf.termcap_operations(tcf.so).encoded_data_length > 0
  1777.                        THEN supported_functions(highlight_is)
  1778.                                                  := true;
  1779.          END IF;
  1780.  
  1781.          IF tcf.termcap_operations(tcf.im).encoded_data_length > 0
  1782.                        THEN supported_functions(insert_mode_is)
  1783.                                                  := true;
  1784.          END IF;
  1785.  
  1786.          IF tcf.termcap_operations(tcf.ca).encoded_data_length > 0
  1787.                        THEN  supported_functions(erase_all_of_display_is)
  1788.                                                   := true;
  1789.          END IF;
  1790.  
  1791.          IF tcf.termcap_operations(tcf.cl).encoded_data_length > 0
  1792.                        THEN supported_functions(erase_all_of_line_is)
  1793.                                                   := true;
  1794.          END IF;
  1795.  
  1796.          IF tcf.termcap_operations(tcf.nl).encoded_data_length > 0
  1797.                        THEN supported_functions(new_line_is) := true;
  1798.          END IF;
  1799.  
  1800. -- successful opening of terminal.
  1801.  
  1802.          initialized := true;
  1803.  
  1804.     EXCEPTION
  1805.  
  1806. -- unsuccessful initialization of terminal
  1807.          WHEN tcf.unsupported_terminal => RAISE unsupported_terminal;
  1808.          WHEN tcf.tcf_error => RAISE tcf_error;
  1809.          WHEN OTHERS => RAISE uninitialized;
  1810.  
  1811.  
  1812.    END vt_initialize;
  1813.  
  1814.  
  1815.  PROCEDURE close_virtual_terminal is
  1816.  
  1817. -- close the virtual terminal by calling sysdep.close
  1818.  
  1819.   BEGIN -- close_virtual_terminal
  1820.  
  1821.           initialized := false;
  1822.           IF tcf.termcap_operations(tcf.ds).encoded_data_length /= 0
  1823.           THEN
  1824.             sysdep.put(tcf.termcap_operations(tcf.ds).encoded_data(1..
  1825.                         tcf.termcap_operations(tcf.ds).encoded_data_length));
  1826.           END IF;
  1827.           sysdep.close;
  1828.  
  1829.  END close_virtual_terminal;
  1830.  
  1831. -- -------------------------------------------------------------------------
  1832.  
  1833. PROCEDURE  erase_to_end_of_screen(
  1834.                                   pos      : IN OUT INTEGER ) IS
  1835.  
  1836. BEGIN -- erase_to_end_of_screen
  1837.  
  1838.  pos := pos + 1;
  1839.  out_buffer(pos..pos+(tcf.termcap_operations(tcf.cd).encoded_data_length-1)) :=
  1840.           tcf.termcap_operations(tcf.cd).encoded_data(1..tcf.termcap_operations(
  1841.                                          tcf.cd).encoded_data_length);
  1842.  pos := pos + (tcf.termcap_operations(tcf.cd).encoded_data_length-1);
  1843.  
  1844. END erase_to_end_of_screen;
  1845.  
  1846. -- ---------------------------------------------------------------------------
  1847.  
  1848. PROCEDURE erase_all_of_display(
  1849.                                pos      : IN OUT INTEGER ) IS
  1850.  
  1851. BEGIN -- erase_all_of_display
  1852.  
  1853.  pos := pos + 1;
  1854.  out_buffer(pos..pos+(tcf.termcap_operations(tcf.cl).encoded_data_length-1)) :=
  1855.           tcf.termcap_operations(tcf.cl).encoded_data(1..tcf.termcap_operations(
  1856.                                          tcf.cl).encoded_data_length);
  1857.  pos := pos + (tcf.termcap_operations(tcf.cl).encoded_data_length-1);
  1858.  
  1859. END  erase_all_of_display;
  1860.  
  1861. -- -----------------------------------------------------------------------------
  1862.  
  1863. PROCEDURE erase_all_of_line(
  1864.                             pos      : IN OUT INTEGER ) IS
  1865.  
  1866. BEGIN -- erase_all_of_line
  1867.  
  1868.  pos := pos + 1;
  1869.  out_buffer(pos..pos+(tcf.termcap_operations(tcf.ca).encoded_data_length-1)) :=
  1870.           tcf.termcap_operations(tcf.ca).encoded_data(1..tcf.termcap_operations(
  1871.                                          tcf.ca).encoded_data_length);
  1872.  pos := pos + (tcf.termcap_operations(tcf.ca).encoded_data_length-1);
  1873.  
  1874.  END erase_all_of_line;
  1875.  
  1876. -- -----------------------------------------------------------------------------
  1877.  
  1878. PROCEDURE erase_to_end_of_line(
  1879.                                pos      : IN OUT INTEGER) IS
  1880.  
  1881. BEGIN -- erase_to_end_of_line
  1882.  
  1883.  pos := pos + 1;
  1884.  out_buffer(pos..pos+(tcf.termcap_operations(tcf.ce).encoded_data_length-1)) :=
  1885.           tcf.termcap_operations(tcf.ce).encoded_data(1..tcf.termcap_operations(
  1886.                                            tcf.ce).encoded_data_length);
  1887.  pos := pos + (tcf.termcap_operations(tcf.ce).encoded_data_length-1);
  1888.  
  1889. END erase_to_end_of_line;
  1890.  
  1891. -- -----------------------------------------------------------------------------
  1892.  
  1893. PROCEDURE move_the_cursor_to(p_x : IN positive;
  1894.                              p_y : IN positive;
  1895.                              pos  : IN OUT INTEGER ) IS
  1896.  
  1897.  
  1898.  digit_width : CONSTANT integer := 5;
  1899.  
  1900.  SUBTYPE digit_array IS string(1..digit_width);
  1901.  
  1902.  exchange : integer;
  1903.  i,j      : integer;
  1904.  x,y      : integer;
  1905.  xdigits,ydigits : digit_array;
  1906. processedx,processedy : boolean;
  1907.  hold : integer;
  1908. -- -------------------------------------------------------------------
  1909.   PROCEDURE to_digits(p_value : IN integer;
  1910.                       result  : IN OUT digit_array ) IS
  1911.  
  1912.    leftover, value, saved  : INTEGER;
  1913.    i,j,result_index        : INTEGER;
  1914.  
  1915.    BEGIN -- to_digits
  1916.  
  1917.     value := p_value;
  1918.     FOR i IN 1..digit_width
  1919.     LOOP
  1920.       result(i) := '0';
  1921.     END LOOP;
  1922.  
  1923.     result_index := digit_width;
  1924.  
  1925.     WHILE value > 0
  1926.     LOOP
  1927.       saved := value;
  1928.       value := value / 10;
  1929.       leftover := saved - (value*10);
  1930.       result(result_index) := character'val(leftover +
  1931.                                 character'pos('0'));
  1932.       result_index := result_index - 1;
  1933.     END LOOP;
  1934.    END to_digits;
  1935. -- ---------------------------------------------------------------------
  1936.  
  1937.    BEGIN -- move_the_cursor_to
  1938.  
  1939.     x := p_x - 1;
  1940.     y := p_y - 1;
  1941.     hold := pos;
  1942.     processedx := false;
  1943.     processedy := false;
  1944.  
  1945.     i := 0;
  1946.     LOOP
  1947.       i := i + 1;
  1948.       IF tcf.termcap_operations(tcf.cm).encoded_data(i) /= '%'
  1949.       THEN
  1950.         pos := pos + 1;
  1951.         out_buffer(pos) := tcf.termcap_operations(tcf.cm).encoded_data(i);
  1952.  
  1953.       ELSE
  1954.         i := i + 1;
  1955.         CASE tcf.termcap_operations(tcf.cm).encoded_data(i) IS
  1956.           WHEN '2' =>
  1957.                    IF NOT processedx
  1958.                    THEN
  1959.                      to_digits(x,xdigits);
  1960.                      FOR j IN digit_width-1..digit_width
  1961.                      LOOP
  1962.                        pos := pos+1;
  1963.                        out_buffer(pos) := xdigits(j);
  1964.                      END LOOP;
  1965.                      processedx := true;
  1966.                    ELSE
  1967.                      to_digits(y,ydigits);
  1968.                      FOR j IN  digit_width-1..digit_width
  1969.                      LOOP
  1970.                        pos := pos + 1;
  1971.                        out_buffer(pos) := ydigits(j);
  1972.                      END LOOP;
  1973.                      processedy := true;
  1974.                    END IF;
  1975.          WHEN '3' =>
  1976.                   IF NOT processedx
  1977.                   THEN
  1978.                     to_digits(x,xdigits);
  1979.                     FOR j In digit_width-2..digit_width
  1980.                     LOOP
  1981.                       pos := pos + 1;
  1982.                       out_buffer(pos) := xdigits(j);
  1983.                     END LOOP;
  1984.                     processedx := true;
  1985.                   ELSE
  1986.                     to_digits(y,ydigits);
  1987.                     FOR j IN digit_width-2..digit_width
  1988.                     LOOP
  1989.                       pos := pos + 1;
  1990.                       out_buffer(pos) := ydigits(j);
  1991.                     END LOOP;
  1992.                     processedy := true;
  1993.                   END IF;
  1994.          WHEN '.' =>
  1995.                   IF NOT processedx
  1996.                   THEN
  1997.                       pos := pos + 1;
  1998.                       out_buffer(pos) :=character'val(x);
  1999.                       processedx := true;
  2000.                   ELSE
  2001.                       pos := pos + 1;
  2002.                       out_buffer(pos) := character'val(y);
  2003.                       processedy := true;
  2004.                   END IF;
  2005.           WHEN '+' =>
  2006.                    IF NOT processedx
  2007.                    THEN
  2008.                        i := i + 1;
  2009.                        pos := pos + 1;
  2010.                        out_buffer(pos) :=
  2011.  
  2012.                                 character'val(x+character'pos(
  2013.                                               tcf.termcap_operations(tcf.cm).
  2014.                                                   encoded_data(i)));
  2015.                        processedx := true;
  2016.                     ELSE
  2017.                         i := i + 1;
  2018.                         pos := pos + 1;
  2019.                         out_buffer(pos) :=
  2020.                                  character'val(y+character'pos(
  2021.                                                tcf.termcap_operations(tcf.cm).
  2022.                                                    encoded_data(i)));
  2023.                         processedy := true;
  2024.                     END IF;
  2025.           WHEN '<' =>
  2026.                     IF NOT processedx
  2027.                     THEN
  2028.                        i := i + 1;
  2029.                        IF x < character'pos(
  2030.                               tcf.termcap_operations(tcf.cm).encoded_data(i))
  2031.                        THEN
  2032.                           pos := pos + 1;
  2033.                           out_buffer(pos) := character'val(x +(character'pos(
  2034.                                        tcf.termcap_operations(tcf.cm).
  2035.                                        encoded_data(i+1))));
  2036.                           processedx := true;
  2037.                           i := i + 1;
  2038.                        ELSE
  2039.                           pos := pos + 1;
  2040.                           out_buffer(pos) := character'val(x);
  2041.                           processedx := true;
  2042.                           i := i + 1;
  2043.                        END IF;
  2044.                     ELSE
  2045.                        i := i + 1;
  2046.                        IF y < character'pos(
  2047.                               tcf.termcap_operations(tcf.cm).encoded_data(i))
  2048.                        THEN
  2049.                           pos := pos + 1;
  2050.                           out_buffer(pos) := character'val(y+(character'pos(
  2051.                                            tcf.termcap_operations(tcf.cm).
  2052.                                            encoded_data(i+1))));
  2053.                           processedy := true;
  2054.                           i := i + 1;
  2055.                        ELSE
  2056.                           pos := pos + 1;
  2057.                           out_buffer(pos) := character'val(x);
  2058.                           processedy := true;
  2059.                           i := i + 1;
  2060.                        END IF;
  2061.                     END IF;
  2062.           WHEN 'r' =>
  2063.                      exchange := x;
  2064.                      x := y;
  2065.                      y := exchange;
  2066.           WHEN 'i' =>
  2067.                      x := x+1;
  2068.                      y := y + 1;
  2069.           WHEN '%' =>
  2070.                      pos := pos + 1;
  2071.                      out_buffer(pos) := '%';
  2072.  
  2073.           WHEN 'd' =>
  2074.                      IF NOT processedx
  2075.                      THEN
  2076.                         to_digits(x,xdigits);
  2077.  
  2078.                        -- scan for leading zeroes
  2079.                         j := 1;
  2080.                         WHILE(xdigits(j) = '0')
  2081.                          LOOP
  2082.                             j := j + 1;
  2083.                          END LOOP;
  2084.                         -- found first significant digit
  2085.                         FOR k IN j..digit_width
  2086.                         LOOP
  2087.                             pos := pos + 1;
  2088.                             out_buffer(pos) := xdigits(k);
  2089.                         END LOOP;
  2090.                         processedx := true;
  2091.                      ELSE
  2092.                         j := 1;
  2093.                         to_digits(y,ydigits);
  2094.                         WHILE(ydigits(j) = '0')
  2095.                          LOOP
  2096.                             j := j + 1;
  2097.                          END LOOP;
  2098.                         FOR k IN j..digit_width
  2099.                         LOOP
  2100.                            pos := pos + 1;
  2101.                            out_buffer(pos) := ydigits(k);
  2102.                         END LOOP;
  2103.                         processedy := true;
  2104.                      END IF;
  2105.  
  2106.           WHEN OTHERS => null;
  2107.         END CASE;
  2108.  END IF;
  2109.  EXIT WHEN i=tcf.termcap_operations(tcf.cm).encoded_data_length;
  2110.  END LOOP;
  2111.  
  2112. END move_the_cursor_to;
  2113.  
  2114. -- -----------------------------------------------------------------------------
  2115.  
  2116. PROCEDURE insert_line(
  2117.                       pos      : IN OUT INTEGER;
  2118.                       p_num    : IN OUT INTEGER ) IS
  2119.  
  2120. BEGIN -- insert_line
  2121.  
  2122. WHILE p_num /= 0
  2123.  LOOP
  2124.   pos := pos + 1;
  2125.   out_buffer(pos..pos+(tcf.termcap_operations(tcf.al).encoded_data_length-1)) :=
  2126.            tcf.termcap_operations(tcf.al).encoded_data(1..
  2127.                             tcf.termcap_operations(tcf.al).encoded_data_length);
  2128.    p_num := p_num - 1;
  2129.    pos := pos +(tcf.termcap_operations(tcf.al).encoded_data_length-1);
  2130.  END LOOP;
  2131.  
  2132. END insert_line;
  2133.  
  2134. -- -----------------------------------------------------------------------------
  2135.  
  2136. PROCEDURE delete_line(
  2137.                       pos      : IN OUT INTEGER;
  2138.                       p_num    : IN OUT INTEGER ) IS
  2139.  
  2140. BEGIN -- delete_line
  2141.  
  2142.  
  2143. WHILE p_num /= 0
  2144.  LOOP
  2145.   pos := pos + 1;
  2146.   out_buffer(pos..pos+(tcf.termcap_operations(tcf.dl).encoded_data_length-1)) :=
  2147.            tcf.termcap_operations(tcf.dl).encoded_data(1..
  2148.                             tcf.termcap_operations(tcf.dl).encoded_data_length);
  2149.   p_num := p_num - 1;
  2150.   pos := pos +(tcf.termcap_operations(tcf.dl).encoded_data_length-1);
  2151.  END LOOP;
  2152.  
  2153. END delete_line;
  2154.  
  2155. -- -----------------------------------------------------------------------------
  2156.  
  2157.  
  2158. PROCEDURE  delete_character(
  2159.                             pos      : IN OUT INTEGER;
  2160.                             p_num    : IN OUT INTEGER )  IS
  2161.  
  2162. BEGIN -- delete_character
  2163.  
  2164.  
  2165. WHILE p_num /= 0
  2166.  LOOP
  2167.   pos := pos + 1;
  2168.   out_buffer(pos..pos+(tcf.termcap_operations(tcf.dc).encoded_data_length-1)) :=
  2169.            tcf.termcap_operations(tcf.dc).encoded_data(1..
  2170.                             tcf.termcap_operations(tcf.dc).encoded_data_length);
  2171.   p_num := p_num - 1;
  2172.   pos := pos +(tcf.termcap_operations(tcf.dc).encoded_data_length-1);
  2173.  END LOOP;
  2174.  
  2175. END delete_character;
  2176.  
  2177. -- -----------------------------------------------------------------------------
  2178.  
  2179. PROCEDURE beep(
  2180.                pos      : IN OUT INTEGER ) IS
  2181.  
  2182. BEGIN -- beep
  2183.  pos := pos + 1;
  2184.  out_buffer(pos..pos+(tcf.termcap_operations(tcf.vb).encoded_data_length-1)) :=
  2185.           tcf.termcap_operations(tcf.vb).encoded_data(1..tcf.termcap_operations(
  2186.                                           tcf.vb).encoded_data_length);
  2187.  
  2188.  pos := pos +(tcf.termcap_operations(tcf.vb).encoded_data_length-1);
  2189.  
  2190. END beep;
  2191.  
  2192. -- ----------------------------------------------------------------------------
  2193.  
  2194. PROCEDURE new_line(
  2195.                    pos      : IN OUT INTEGER ) IS
  2196.  
  2197. BEGIN  -- new_line
  2198.  pos := pos + 1;
  2199.  out_buffer(pos..pos+(tcf.termcap_operations(tcf.nl).encoded_data_length-1)) :=
  2200.           tcf.termcap_operations(tcf.nl).encoded_data(1..tcf.termcap_operations(
  2201.                                          tcf.nl).encoded_data_length);
  2202. pos := pos +(tcf.termcap_operations(tcf.nl).encoded_data_length-1);
  2203.  
  2204. END new_line;
  2205.  
  2206. -- -----------------------------------------------------------------------------
  2207.  
  2208. PROCEDURE turn_on_highlighting(
  2209.                                pos      : IN OUT INTEGER ) IS
  2210.  
  2211. BEGIN -- turn_on_highlighting
  2212.  
  2213.  pos := pos + 1;
  2214.  out_buffer(pos..pos+(tcf.termcap_operations(tcf.so).encoded_data_length-1)) :=
  2215.           tcf.termcap_operations(tcf.so).encoded_data(1..tcf.termcap_operations(
  2216.                                          tcf.so).encoded_data_length);
  2217.  pos := pos + (tcf.termcap_operations(tcf.so).encoded_data_length-1);
  2218.  
  2219. END  turn_on_highlighting;
  2220.  
  2221. -- -----------------------------------------------------------------------------
  2222.  
  2223. PROCEDURE turn_off_highlighting(
  2224.                                 pos      : IN OUT INTEGER ) IS
  2225.  
  2226. BEGIN -- turn_off_highlighting
  2227.  
  2228.  pos := pos + 1;
  2229.  out_buffer(pos..pos+(tcf.termcap_operations(tcf.se).encoded_data_length-1)) :=
  2230.           tcf.termcap_operations(tcf.se).encoded_data(1..tcf.termcap_operations(
  2231.                                          tcf.se).encoded_data_length);
  2232.  pos := pos + (tcf.termcap_operations(tcf.se).encoded_data_length-1);
  2233.  
  2234. END turn_off_highlighting;
  2235.  
  2236. -- ---------------------------------------------------------------------------
  2237.  
  2238. PROCEDURE enter_insert_mode(
  2239.                             pos      : IN OUT INTEGER ) IS
  2240.  
  2241. BEGIN -- enter_insert_mode
  2242.  
  2243.  pos := pos + 1;
  2244.  out_buffer(pos..pos+(tcf.termcap_operations(tcf.im).encoded_data_length-1)) :=
  2245.           tcf.termcap_operations(tcf.im).encoded_data(1..tcf.termcap_operations(
  2246.                                          tcf.im).encoded_data_length);
  2247.  pos := pos + (tcf.termcap_operations(tcf.im).encoded_data_length-1);
  2248.  
  2249. END enter_insert_mode;
  2250.  
  2251. -- ----------------------------------------------------------------------------
  2252.  
  2253. PROCEDURE exit_insert_mode(
  2254.                            pos      : IN OUT INTEGER ) IS
  2255.  
  2256. BEGIN -- exit_insert_mode
  2257.  
  2258.  pos := pos + 1;
  2259.  out_buffer(pos..pos+(tcf.termcap_operations(tcf.ei).encoded_data_length-1)) :=
  2260.           tcf.termcap_operations(tcf.ei).encoded_data(1..tcf.termcap_operations(
  2261.                                          tcf.ei).encoded_data_length);
  2262.  pos := pos + (tcf.termcap_operations(tcf.ei).encoded_data_length-1);
  2263.  
  2264. END exit_insert_mode;
  2265.  
  2266. -- ---------------------------------------------------------------------------
  2267. PROCEDURE interpret ( command_string : IN string ) IS
  2268.  
  2269.  j,k,x      : INTEGER;
  2270.  param      : INTEGER;
  2271.  found      : BOOLEAN;
  2272.  param2     : INTEGER;
  2273.  
  2274.  ansi_CSI   : CONSTANT STRING (1..2) := ascii.esc & '[';
  2275.  ansi_EDe   : CONSTANT STRING (1..2) := "0J";
  2276.  ansi_EDa   : CONSTANT STRING (1..2) := "2J";
  2277.  ansi_ELe   : CONSTANT STRING (1..2) := "0K";
  2278.  ansi_ELa   : CONSTANT STRING (1..2) := "2K";
  2279.  ansi_SGP   : CONSTANT STRING (1..2) := "0m";
  2280.  ansi_SGR   : CONSTANT STRING (1..2) := "7m";
  2281.  ansi_IMs   : CONSTANT STRING (1..2) := "4h";
  2282.  ansi_IMr   : CONSTANT STRING (1..2) := "4l";
  2283.  
  2284. -- -----------------------------------------------------------------------------
  2285.  
  2286.  
  2287. PROCEDURE get_number(c_str : IN string;
  2288.                      last_pos : IN OUT integer;
  2289.                      result   : OUT integer) IS
  2290.  
  2291. c_p : integer;
  2292.  
  2293. BEGIN -- get_number
  2294.  
  2295.  c_p := last_pos + 1;
  2296.  WHILE (c_str(c_p) IN '0'..'9' AND c_p /= c_str'last)
  2297.   LOOP
  2298.       c_p := c_p + 1;
  2299.   END LOOP;
  2300.  c_p := c_p - 1;
  2301.  result := INTEGER'VALUE(c_str(last_pos..c_p));
  2302.  last_pos := c_p;
  2303.  
  2304. END get_number;
  2305.  
  2306. -- --------------------------------------------------------------------------
  2307.  
  2308. -- scan incoming for incoming ansi sequences, map to terminal specific
  2309. -- sequences, and put to terminal.
  2310.  
  2311.   BEGIN -- interpret
  2312.  
  2313.   IF NOT initialized
  2314.   THEN
  2315.      RAISE uninitialized;
  2316.   END IF;
  2317.  
  2318.   IF tcf.termcap_operations(tcf.an).bool_parameter = true
  2319.   THEN
  2320.       sysdep.put(command_string);
  2321.       GOTO exit_quick;
  2322.   END IF;
  2323.  
  2324.   j := 1;
  2325.   x := 0;
  2326.   k := 0;
  2327.  
  2328. -- check for end of the command string
  2329.  
  2330.   WHILE ((j-1) /= command_string'last )
  2331.   LOOP
  2332.       -- scan for esc character
  2333.       IF command_string(j) = ascii.esc AND j /= command_string'last
  2334.       THEN  -- have esc, start of ansi sequence
  2335.           -- mark position of esc character with variable k
  2336.           k := j;
  2337.           -- check next position for [
  2338.  
  2339.           IF command_string(j+1) = '['  -- have CSI
  2340.           THEN
  2341.               j := j + 2;
  2342.               IF command_string(j) IN '0'..'9'
  2343.               THEN
  2344.                   get_number(command_string,j,param);
  2345.  
  2346.               j := j + 1;
  2347.               -- match against ansi constants
  2348.  
  2349.               IF command_string(k+2..j) = ANSI_ELe
  2350.               THEN
  2351.               -- check to see if function is supported by the vt
  2352.  
  2353.                     IF supported_functions(erase_to_end_of_line_is) = true
  2354.                     THEN
  2355.                         erase_to_end_of_line(x);
  2356.                         j := j + 1;
  2357.                      ELSE
  2358.                          x := x + 1;
  2359.                          out_buffer(x..j) := command_string(k..j);
  2360.                          x := j;
  2361.                          j := j + 1;
  2362.                      END IF;
  2363.                  ELSIF
  2364.                    command_string(k+2..j) = ANSI_ELa
  2365.                    THEN
  2366.                        IF supported_functions(erase_all_of_line_is) = true
  2367.                        THEN
  2368.                           erase_all_of_line(x);
  2369.                           j := j + 1;
  2370.                        ELSE
  2371.                           x := x + 1;
  2372.                           out_buffer(x..j) := command_string(k..j);
  2373.                           x := j;
  2374.                           j := j + 1;
  2375.                        END IF;
  2376.  
  2377.                  ELSIF
  2378.                    command_string(k+2..j) = ANSI_EDe
  2379.                    THEN
  2380.                        IF supported_functions(erase_to_end_of_screen_is) = true
  2381.                        THEN
  2382.                            erase_to_end_of_screen(x);
  2383.                            j := j + 1;
  2384.                        ELSE
  2385.                            x := x + 1;
  2386.                            out_buffer(x..j) := command_string(k..j);
  2387.                            x := j;
  2388.                            j := j + 1;
  2389.                        END IF;
  2390.  
  2391.                  ELSIF
  2392.                    command_string(k+2..j) = ANSI_EDa
  2393.                    THEN
  2394.                        IF supported_functions(erase_all_of_display_is)=
  2395.                                                     true AND
  2396.                           supported_functions(move_the_cursor_is) = true
  2397.                        THEN
  2398.                            move_the_cursor_to(1,1,x);
  2399.                            erase_all_of_display(x);
  2400.                            j := j + 1;
  2401.                        ELSE
  2402.                            x := x + 1;
  2403.                            out_buffer(x..j) := command_string(k..j);
  2404.                            x := j;
  2405.                            j := j + 1;
  2406.                        END IF;
  2407.  
  2408.                  ELSIF
  2409.                    command_string(k+2..j) = ANSI_SGP
  2410.                    THEN
  2411.                        IF supported_functions(highlight_is) = true
  2412.                        THEN
  2413.                            turn_off_highlighting(x);
  2414.                            j := j + 1;
  2415.                        ELSE
  2416.                            x := x + 1;
  2417.                            out_buffer(x..j) := command_string(k..j);
  2418.                            x := j;
  2419.                            j := j + 1;
  2420.                        END IF;
  2421.                  ELSIF
  2422.                    command_string(k+2..j) = ANSI_SGR
  2423.                    THEN
  2424.                        IF supported_functions(highlight_is) = true
  2425.                        THEN
  2426.                            turn_on_highlighting(x);
  2427.                            j := j + 1;
  2428.                        ELSE
  2429.                            x := x + 1;
  2430.                            out_buffer(x..j) := command_string(k..j);
  2431.                            x := j;
  2432.                            j := j + 1;
  2433.                        END IF;
  2434.                  ELSIF
  2435.                    command_string(k+2..j) = ANSI_IMs
  2436.                    THEN
  2437.                        IF supported_functions(insert_mode_is) = true
  2438.                        THEN
  2439.                            enter_insert_mode(x);
  2440.                            j := j + 1;
  2441.                        ELSE
  2442.                             x := x + 1;
  2443.                             out_buffer(x..j) := command_string(k..j);
  2444.                             x := j;
  2445.                             j := j + 1;
  2446.                        END IF;
  2447.                  ELSIF
  2448.                    command_string(k+2..j) = ANSI_IMr
  2449.                    THEN
  2450.                        IF supported_functions(insert_mode_is) = true
  2451.                        THEN
  2452.                            exit_insert_mode(x);
  2453.                            j := j + 1;
  2454.                        ELSE
  2455.                             x := x + 1;
  2456.                             out_buffer(x..j) := command_string(k..j);
  2457.                             x := j;
  2458.                             j := j + 1;
  2459.                        END IF;
  2460.  
  2461.                  ELSIF
  2462.                    command_string(j) = 'P'
  2463.                    THEN
  2464.                        IF supported_functions(delete_character_is) = true
  2465.                        THEN
  2466.                            delete_character(x,param);
  2467.                            j := j + 1;
  2468.                        ELSE
  2469.                             x := x + 1;
  2470.                             out_buffer(x..j) := command_string(k..j);
  2471.                             x := j;
  2472.                             j := j + 1;
  2473.                        END IF;
  2474.  
  2475.                   ELSIF
  2476.                     command_string(j) = 'M'
  2477.                     THEN
  2478.                         IF supported_functions(delete_line_is) = true
  2479.                         THEN
  2480.                             delete_line(x,param);
  2481.                             j := j + 1;
  2482.                         ELSE
  2483.                             x := x + 1;
  2484.                             out_buffer(x..j) := command_string(k..j);
  2485.                             x := j;
  2486.                             j := j + 1;
  2487.                         END IF;
  2488.  
  2489.                   ELSIF
  2490.                     command_string(j) = 'L'
  2491.                     THEN
  2492.                         IF supported_functions(insert_line_is) = true
  2493.                         THEN
  2494.                             insert_line(x,param);
  2495.                             j := j + 1;
  2496.                         ELSE
  2497.                             x := x + 1;
  2498.                             out_buffer(x..j) := command_string(k..j);
  2499.                             x := j;
  2500.                             j := j + 1;
  2501.                         END IF;
  2502.  
  2503.                    ELSIF
  2504.                      command_string(j) = ';'
  2505.                      THEN
  2506.                          j := j + 1;
  2507.                          get_number(command_string,j,param2);
  2508.                          j := j + 1;
  2509.                          IF  command_string(j) = 'H'
  2510.                          THEN
  2511.                              IF supported_functions(move_the_cursor_is) = true
  2512.                              THEN
  2513.                                 move_the_cursor_to(param,param2,x);
  2514.                                 j := j + 1;
  2515.                              ELSE
  2516.                                  x := x + 1;
  2517.                                 out_buffer(x..j) := command_string(k..j);
  2518.                                  x := j;
  2519.                                  j := j + 1;
  2520.                              END IF;
  2521.                           ELSE
  2522.                               x := x + 1;
  2523.                               out_buffer(x..j) := command_string(k..j);
  2524.                               x := j;
  2525.                               j := j + 1;
  2526.                           END IF;
  2527.                      ELSE
  2528.                          x := x + 1;
  2529.                          out_buffer(x..j) := command_string(k..j);
  2530.                          x := j;
  2531.                          j := j + 1;
  2532.                      END IF;
  2533.  
  2534.             ELSE -- have esc[non-numeric junk
  2535.                x := x + 1;
  2536.                out_buffer(x..j-1) := command_string(k..j-1);
  2537.                x := j - 1;
  2538.             END IF;
  2539.  
  2540.            ELSE  -- have esc+junk
  2541.                x := x + 1;
  2542.                out_buffer(x) := command_string(k);
  2543.                j := j + 1;
  2544.            END IF;
  2545.  
  2546. -- if not an ansi sequence put in output buffer
  2547.  
  2548.            ELSE  -- no esc, check for bell
  2549.                IF command_string(j) = ascii.bel
  2550.                THEN  -- have bell
  2551.                    IF supported_functions(beep_is) = true
  2552.                    THEN  -- bell supported
  2553.                        beep(x);
  2554.                        j := j + 1;
  2555.                    ELSE
  2556.                        x := x + 1;
  2557.                        out_buffer(x) := command_string(j);
  2558.                        j := j + 1;
  2559.                    END IF;
  2560.                ELSIF
  2561.                     command_string(j) = ascii.lf
  2562.                   THEN -- have a line feed
  2563.                     IF supported_functions(new_line_is) = true
  2564.                     THEN
  2565.                        new_line(x);
  2566.                        j := j + 1;
  2567.                     ELSE
  2568.                         x := x + 1;
  2569.                         out_buffer(x) := command_string(j);
  2570.                         j := j + 1;
  2571.                     END IF;
  2572.                ELSE
  2573.                     x := x + 1;
  2574.                     out_buffer(x) := command_string(j);
  2575.                     j := j + 1;
  2576.                END IF;
  2577.  
  2578.           END IF;
  2579.  
  2580.  
  2581.    END LOOP;
  2582.  
  2583. -- check for anything left in output buffer and put to screen
  2584.  
  2585. IF x > 0
  2586. THEN
  2587.      sysdep.put(out_buffer(1..x));
  2588.  
  2589. -- blank out buffer
  2590.  
  2591.      out_buffer := string'(out_buffer'first..out_buffer'last => ' ');
  2592. END IF;
  2593.  
  2594. <<exit_quick>> null;
  2595.  
  2596. EXCEPTION
  2597.        WHEN tcf.tcf_error => RAISE tcf_error;
  2598.        WHEN tcf.unsupported_terminal => RAISE unsupported_terminal;
  2599.  
  2600.  
  2601.  END interpret;
  2602.  
  2603. END driver;
  2604. ::::::::::
  2605. vtinput_body.ada
  2606. ::::::::::
  2607. -- -----------------------------------------------------------------------------
  2608. -- ABSTRACT:  This package provides an interface to get keystrokes from the
  2609. --            actual terminals keyboard.  The keystrokes include regular ASCII
  2610. --            keys and function keys (including the arrow keys).  The function
  2611. --            and arrow keys are identified throught the use of the terminal
  2612. --            capabilities data base.  There can be up to 32 function keys.
  2613. --            There will always be 4 arrow keys.
  2614. -- -----------------------------------------------------------------------------
  2615.  
  2616. WITH tcf,
  2617.      sysdep;
  2618.  
  2619. PACKAGE BODY vt_input IS
  2620.  
  2621.      initialized : boolean := false;
  2622.      function_key_count : natural := 0;
  2623.      current_function_key : natural;
  2624.  
  2625.      PRAGMA page;
  2626.      PROCEDURE get( data : OUT string;
  2627.                     last : OUT natural;
  2628.                     keys : IN OUT function_key_descriptor;
  2629.                  timeout : IN  duration := duration'last ) IS
  2630.  
  2631.         max_string : CONSTANT positive := 80;
  2632.         SUBTYPE work_string IS string( 1..max_string );
  2633.  
  2634.         tty_last : natural;
  2635.         tty_string : work_string;
  2636.         pos : natural := 0;
  2637.  
  2638.         remainder : work_string;
  2639.         remainder_last : natural := 0;
  2640.  
  2641.         f_key : function_key_enum;
  2642.  
  2643.         temp_last : natural := 0;
  2644.  
  2645.         char : character;
  2646.  
  2647. -- ----------------
  2648.  
  2649.          PROCEDURE next_character
  2650.                         ( pos : IN OUT natural;
  2651.                           char : OUT character ) IS
  2652.          BEGIN
  2653.  
  2654.             IF pos = 0
  2655.             THEN
  2656.                 sysdep.get( tty_string, tty_last );
  2657.                 pos := 1;
  2658.             END IF;
  2659.  
  2660.             IF pos <= tty_last
  2661.             THEN
  2662.                 char := tty_string( pos );
  2663.                 pos := pos + 1;
  2664.             ELSE
  2665.                 sysdep.get( tty_string, tty_last );
  2666.                 pos := 1;
  2667.                 next_character( pos, char );
  2668.             END IF;
  2669.          END next_character;
  2670.  
  2671. -- ----------------
  2672.  
  2673.          FUNCTION last_character( pos : IN natural ) RETURN boolean IS
  2674.          BEGIN
  2675.             IF pos > tty_last
  2676.             THEN RETURN true;
  2677.             ELSE RETURN false;
  2678.             END IF;
  2679.          END last_character;
  2680.  
  2681. -- ----------------
  2682.  
  2683.          PROCEDURE check_function_key
  2684.                         ( data : IN string;
  2685.                           current_position : IN OUT tcf.key_range;
  2686.                           found : OUT boolean;
  2687.                           more : OUT boolean ) IS
  2688.          BEGIN
  2689.              more := false;
  2690.              found := false;
  2691.  
  2692.              FOR i IN current_position..tcf.key_range'LAST
  2693.              LOOP
  2694.                 IF (tcf.termcap_operations( i ).encoded_data_length >=
  2695.                         data'LENGTH)
  2696.                 AND THEN (tcf.termcap_operations( i ).
  2697.                             encoded_data( 1..data'LENGTH ) =
  2698.                          data)
  2699.                 THEN
  2700.  
  2701.                     IF tcf.termcap_operations( i ).encoded_data_length =
  2702.                        data'LENGTH
  2703.                     THEN
  2704.                         more := false; -- finished, no more left
  2705.                         found := true;  -- It is good
  2706.                     ELSE
  2707.                         more := true;  -- more to come, candidate is found
  2708.                         found := false; -- not done yet
  2709.                     END IF;
  2710.  
  2711.                     current_position := i;
  2712.                     EXIT;
  2713.  
  2714.                 END IF;
  2715.              END LOOP;
  2716.  
  2717.          END check_function_key;
  2718.  
  2719. -- ----------------
  2720.  
  2721.          PROCEDURE get_function_key
  2722.                         ( remainder : IN OUT string;
  2723.                           rem_last : IN OUT natural;
  2724.                           f_key : IN OUT function_key_enum ) IS
  2725.          candidate_key : boolean;
  2726.          finished : boolean;
  2727.          key_position : tcf.key_range := tcf.key_range'FIRST;
  2728.          char : character;
  2729.          BEGIN
  2730.  
  2731.             next_character( pos, char );
  2732.  
  2733.             rem_last := 1;
  2734.             remainder( rem_last ) := char;
  2735.  
  2736.             check_function_key( remainder( 1..rem_last ),
  2737.                                 key_position,
  2738.                                 finished, candidate_key );
  2739.  
  2740.             WHILE (NOT finished) AND candidate_key
  2741.             LOOP
  2742.                next_character( pos, char );
  2743.                rem_last := rem_last + 1;
  2744.                remainder( rem_last ) := char;
  2745.                check_function_key( remainder( 1..rem_last ),
  2746.                                    key_position,
  2747.                                    finished, candidate_key );
  2748.             END LOOP;
  2749.  
  2750.             IF finished AND (NOT candidate_key)
  2751.             THEN -- found a function key
  2752.                 CASE key_position IS
  2753.                 WHEN tcf.ku     => f_key := up_arrow;
  2754.                 WHEN tcf.kd     => f_key := down_arrow;
  2755.                 WHEN tcf.kl     => f_key := left_arrow;
  2756.                 WHEN tcf.kr     => f_key := right_arrow;
  2757.                 WHEN tcf.k1     => f_key := f1;
  2758.                 WHEN tcf.k2     => f_key := f2;
  2759.                 WHEN tcf.k3     => f_key := f3;
  2760.                 WHEN tcf.k4     => f_key := f4;
  2761.                 WHEN tcf.k5     => f_key := f5;
  2762.                 WHEN tcf.k6     => f_key := f6;
  2763.                 WHEN tcf.k7     => f_key := f7;
  2764.                 WHEN tcf.k8     => f_key := f8;
  2765.                 WHEN tcf.k9     => f_key := f9;
  2766.                 WHEN tcf.x0     => f_key := f10;
  2767.                 WHEN tcf.x1     => f_key := f11;
  2768.                 WHEN tcf.x2     => f_key := f12;
  2769.                 WHEN tcf.x3     => f_key := f13;
  2770.                 WHEN tcf.x4     => f_key := f14;
  2771.                 WHEN tcf.x5     => f_key := f15;
  2772.                 WHEN tcf.x6     => f_key := f16;
  2773.                 WHEN tcf.x7     => f_key := f17;
  2774.                 WHEN tcf.x8     => f_key := f18;
  2775.                 WHEN tcf.x9     => f_key := f19;
  2776.                 WHEN tcf.g0     => f_key := f20;
  2777.                 WHEN tcf.g1     => f_key := f21;
  2778.                 WHEN tcf.g2     => f_key := f22;
  2779.                 WHEN tcf.g3     => f_key := f23;
  2780.                 WHEN tcf.g4     => f_key := f24;
  2781.                 WHEN tcf.g5     => f_key := f25;
  2782.                 WHEN tcf.g6     => f_key := f26;
  2783.                 WHEN tcf.g7     => f_key := f27;
  2784.                 WHEN tcf.g8     => f_key := f28;
  2785.                 WHEN tcf.g9     => f_key := f29;
  2786.                 WHEN tcf.t0     => f_key := f30;
  2787.                 WHEN tcf.t1     => f_key := f31;
  2788.                 WHEN tcf.t2     => f_key := f32;
  2789.                 WHEN OTHERS => NULL;
  2790.                 END CASE;
  2791.                 rem_last := 0;
  2792.             END IF;
  2793.  
  2794.          END get_function_key;
  2795.  
  2796. -- ----------------
  2797.  
  2798.          PROCEDURE store_data_string
  2799.                         ( in_data : IN string ) IS
  2800.          BEGIN
  2801.             data( temp_last+1..temp_last+in_data'LENGTH ) :=
  2802.                         in_data;
  2803.             temp_last := temp_last + in_data'LENGTH;
  2804.          END store_data_string;
  2805.  
  2806. -- ----------------
  2807.  
  2808.          PROCEDURE store_f_key
  2809.                         ( f_key : IN function_key_enum ) IS
  2810.          BEGIN
  2811.             keys.no_of_keys := keys.no_of_keys + 1;
  2812.             keys.keys( keys.no_of_keys ).key := f_key;
  2813.             keys.keys( keys.no_of_keys ).position := temp_last + 1;
  2814.          END store_f_key;
  2815.  
  2816.  
  2817. -- ----------------
  2818.      BEGIN -- get
  2819.         keys.no_of_keys := 0;
  2820.  
  2821.         LOOP
  2822.             get_function_key( remainder, remainder_last, f_key );
  2823.  
  2824.             IF remainder_last /= 0
  2825.             THEN
  2826.                 store_data_string( remainder( 1..remainder_last ) );
  2827.             ELSE
  2828.                 store_f_key( f_key );
  2829.             END IF;
  2830.  
  2831.         EXIT WHEN last_character( pos );
  2832.         END LOOP;
  2833.  
  2834.         last := temp_last;
  2835.  
  2836.      END get;
  2837.  
  2838.      PRAGMA page;
  2839.      FUNCTION function_count(keys : IN function_key_descriptor)
  2840.          RETURN natural IS
  2841.      BEGIN
  2842.         RETURN keys.no_of_keys;
  2843.      END function_count;
  2844.  
  2845.      PRAGMA page;
  2846.      PROCEDURE function_key(keys           : IN     function_key_descriptor;
  2847.                             index          : IN     positive;
  2848.                             key_identifier :    OUT function_key_enum;
  2849.                          previous_position :    OUT natural) IS
  2850.      BEGIN
  2851.         key_identifier := keys.keys( index ).key;
  2852.         previous_position := keys.keys( index ).position;
  2853.      END function_key;
  2854.  
  2855.      PRAGMA page;
  2856.      PROCEDURE function_key_name
  2857.        ( key_identifier : IN     function_key_enum;
  2858.          key_name       :    OUT string;
  2859.          last           :    OUT natural) IS
  2860.  
  2861.         temp_key : tcf.termcap_entries_enum;
  2862.         temp_last : natural;
  2863.  
  2864.         up_name : CONSTANT string := "Up Arrow";
  2865.         down_name : CONSTANT string := "Down Arrow";
  2866.         right_name : CONSTANT string := "Right Arrow";
  2867.         left_name : CONSTANT string := "Left Arrow";
  2868.  
  2869.      BEGIN
  2870.         IF key_identifier IN f1..f32
  2871.         THEN
  2872.             CASE key_identifier IS
  2873.               WHEN f1     => temp_key := tcf.l1;
  2874.               WHEN f2     => temp_key := tcf.l2;
  2875.               WHEN f3     => temp_key := tcf.l3;
  2876.               WHEN f4     => temp_key := tcf.l4;
  2877.               WHEN f5     => temp_key := tcf.l5;
  2878.               WHEN f6     => temp_key := tcf.l6;
  2879.               WHEN f7     => temp_key := tcf.l7;
  2880.               WHEN f8     => temp_key := tcf.l8;
  2881.               WHEN f9     => temp_key := tcf.l9;
  2882.               WHEN f10    => temp_key := tcf.y0;
  2883.               WHEN f11    => temp_key := tcf.y1;
  2884.               WHEN f12    => temp_key := tcf.y2;
  2885.               WHEN f13    => temp_key := tcf.y3;
  2886.               WHEN f14    => temp_key := tcf.y4;
  2887.               WHEN f15    => temp_key := tcf.y5;
  2888.               WHEN f16    => temp_key := tcf.y6;
  2889.               WHEN f17    => temp_key := tcf.y7;
  2890.               WHEN f18    => temp_key := tcf.y8;
  2891.               WHEN f19    => temp_key := tcf.y9;
  2892.               WHEN f20    => temp_key := tcf.h0;
  2893.               WHEN f21    => temp_key := tcf.h1;
  2894.               WHEN f22    => temp_key := tcf.h2;
  2895.               WHEN f23    => temp_key := tcf.h3;
  2896.               WHEN f24    => temp_key := tcf.h4;
  2897.               WHEN f25    => temp_key := tcf.h5;
  2898.               WHEN f26    => temp_key := tcf.h6;
  2899.               WHEN f27    => temp_key := tcf.h7;
  2900.               WHEN f28    => temp_key := tcf.h8;
  2901.               WHEN f29    => temp_key := tcf.h9;
  2902.               WHEN f30    => temp_key := tcf.v0;
  2903.               WHEN f31    => temp_key := tcf.v1;
  2904.               WHEN f32    => temp_key := tcf.v2;
  2905.               WHEN OTHERS => NULL;
  2906.             END CASE;
  2907.             temp_last := key_name'first +
  2908.                 tcf.termcap_operations( temp_key ).encoded_data_length - 1;
  2909.  
  2910.             IF temp_last /= 0
  2911.             THEN
  2912.               key_name(
  2913.                 key_name'first..key_name'first +
  2914.                 tcf.termcap_operations( temp_key ).encoded_data_length - 1
  2915.                     ) :=
  2916.                 tcf.termcap_operations( temp_key ).encoded_data(
  2917.                 1..tcf.termcap_operations( temp_key ).encoded_data_length
  2918.                                                                 );
  2919.             END IF;
  2920.  
  2921.         ELSE
  2922.             CASE key_identifier IS
  2923.  
  2924.             WHEN up_arrow       =>
  2925.                 key_name( key_name'first..
  2926.                         key_name'first+up_name'last-up_name'first ) :=
  2927.                         up_name;
  2928.                 temp_last := up_name'last - up_name'first + 1;
  2929.  
  2930.             WHEN down_arrow     =>
  2931.                 key_name( key_name'first..
  2932.                         key_name'first+down_name'last-down_name'first ) :=
  2933.                         down_name;
  2934.                 temp_last := down_name'last - down_name'first + 1;
  2935.  
  2936.             WHEN left_arrow     =>
  2937.                 key_name( key_name'first..
  2938.                         key_name'first+left_name'last-left_name'first ) :=
  2939.                         left_name;
  2940.                 temp_last := left_name'last - left_name'first + 1;
  2941.  
  2942.             WHEN right_arrow    =>
  2943.                 key_name( key_name'first..
  2944.                         key_name'first+right_name'last-right_name'first ) :=
  2945.                         right_name;
  2946.                 temp_last := right_name'last - right_name'first + 1;
  2947.  
  2948.             WHEN OTHERS => NULL;
  2949.  
  2950.             END CASE;
  2951.         END IF;
  2952.  
  2953.         last := temp_last;
  2954.  
  2955.      END function_key_name;
  2956.  
  2957.  
  2958.  
  2959. BEGIN -- vt_input
  2960.     NULL;
  2961. END vt_input;
  2962. ::::::::::
  2963. redisp_body.ada
  2964. ::::::::::
  2965. -- ----------------------------------------------------------------------------
  2966. -- ABSTRACT:  The REDISPLAY package WITH's the VT_CONTENT package to make the
  2967. --            data structures in vt_content visible to REDISPLAY.  The
  2968. --            VT_CONTENT data structures describe how the image on the actual
  2969. --            display looks after the REDISPLAY package is invoked and how
  2970. --            the image of the actual display looks before the REDISPLAY
  2971. --            is invoked.  When a change is made to the data structures in
  2972. --            VT_CONTENT, the image on the actual display must be udpated to
  2973. --            reflect the change.
  2974. -- -----------------------------------------------------------------------------
  2975.  
  2976. WITH
  2977.      vt_content,
  2978.      driver;
  2979. USE vt_content;
  2980.  
  2981. PACKAGE BODY redisplay IS
  2982.  
  2983.     ansi_CSI : CONSTANT string( 1..2 ) := ascii.esc & '[';
  2984.  
  2985. --  these next three are constructed below in the appropriate procedures.
  2986. --  They actually have parameters.
  2987. --
  2988. --  ansi_DCH : CONSTANT string( 1..3 ) := ansi_CSI & 'P';
  2989. --
  2990. --  ansi_DL  : CONSTANT string( 1..3 ) := ansi_CSI & 'M';
  2991. --  ansi_IL  : CONSTANT string( 1..3 ) := ansi_CSI & 'L';
  2992.  
  2993.     ansi_EDe : CONSTANT string( 1..4 ) := ansi_CSI & "0J";
  2994.     ansi_EDs : CONSTANT string( 1..4 ) := ansi_CSI & "1J";
  2995.     ansi_EDa : CONSTANT string( 1..4 ) := ansi_CSI & "2J";
  2996.  
  2997.     ansi_ELe : CONSTANT string( 1..4 ) := ansi_CSI & "0K";
  2998.     ansi_ELs : CONSTANT string( 1..4 ) := ansi_CSI & "1K";
  2999.     ansi_ELa : CONSTANT string( 1..4 ) := ansi_CSI & "2K";
  3000.  
  3001.     ansi_SGP : CONSTANT string( 1..4 ) := ansi_CSI & "0m";
  3002.     ansi_SGR : CONSTANT string( 1..4 ) := ansi_CSI & "7m";
  3003.  
  3004.     ansi_IMs : CONSTANT string( 1..4 ) := ansi_CSI & "4h";
  3005.     ansi_IMr : CONSTANT string( 1..4 ) := ansi_CSI & "4l";
  3006.  
  3007. --  v----v----v----v----v----v----v----v
  3008.     -- this is a temporary for use by any procedure or function.
  3009.     -- it is put here for efficiency.  Ideally it would go in the
  3010.     -- appropriate procedure or function.
  3011.  
  3012.  
  3013.     output_buffer : string( 1..255 );
  3014. --  ^----^----^----^----^----^----^----^
  3015.  
  3016. -- ---------------------------------------------------------------------------
  3017.     FUNCTION value_string( value : IN positive ) RETURN string IS
  3018.         value_image : CONSTANT string := positive'image( value );
  3019.     BEGIN
  3020.             RETURN value_image( (value_image'first + 1)..value_image'last );
  3021.     END;
  3022.  
  3023. -- ---------------------------------------------------------------------------
  3024.  
  3025.     PROCEDURE put_the_cursor_at( row, col : IN positive ) IS
  3026.     ansi_buffer : CONSTANT string :=
  3027.                         string'(ansi_CSI &
  3028.                                 value_string( row ) &
  3029.                                 ";" &
  3030.                                 value_string( col ) &
  3031.                                 "H" );
  3032.     BEGIN
  3033.         driver.interpret( ansi_buffer );
  3034.     END put_the_cursor_at;
  3035.  
  3036.     PRAGMA page;
  3037.  
  3038. -- ---------------------------------------------------------------------------
  3039.  
  3040.     PROCEDURE check_cursor
  3041.                   ( old_screen : IN OUT vt_content.vt_content_access;
  3042.                     line : IN positive;
  3043.                     column : IN positive )  IS
  3044.  
  3045.     BEGIN
  3046.         IF old_screen.active_position /=
  3047.              vt_content.vt_position_xy_record'(line,column)
  3048.         THEN
  3049.            put_the_cursor_at(line,column);
  3050.            old_screen.active_position :=
  3051.                      vt_content.vt_position_xy_record'(line,column);
  3052.         END IF;
  3053.     END check_cursor;
  3054.  
  3055.     PRAGMA page;
  3056.  
  3057. -- ----------------------------------------------------------------------------
  3058.  
  3059.     PROCEDURE fix_cursor
  3060.                 ( old_screen : IN OUT vt_content.vt_content_access;
  3061.                   new_screen : IN OUT vt_content.vt_content_access ) IS
  3062.     BEGIN
  3063.         IF old_screen.active_position /=
  3064.            new_screen.active_position
  3065.         THEN
  3066.             put_the_cursor_at
  3067.                 ( new_screen.active_position.row_position,
  3068.                   new_screen.active_position.col_position );
  3069.             old_screen.active_position := new_screen.active_position;
  3070.         END IF;
  3071.     END fix_cursor;
  3072.  
  3073.     PRAGMA page;
  3074. -- --------------------------------------------------------------------------
  3075.  
  3076.     PROCEDURE redraw_line( old_screen : IN OUT vt_content.vt_content_access;
  3077.                            new_screen : IN  vt_content.vt_content_access;
  3078.                            old_line : IN vt_content.row_range;
  3079.                            new_line : IN vt_content.row_range ) IS
  3080.  
  3081.     buffer_index : natural := 0;
  3082.  
  3083.     done : boolean := false;
  3084.  
  3085.     no_diff_up_front : boolean := true;
  3086.     no_diff_at_end : boolean := true;
  3087.  
  3088.     start_update_position : positive := 1;
  3089.     end_update_position : natural := new_screen.element( new_line ).length;
  3090.  
  3091.  
  3092.     BEGIN
  3093.  
  3094.         IF new_screen.element( new_line ).length = 0
  3095.         THEN
  3096.             old_screen.element( old_line ).length := 0;
  3097.             GOTO quick_out;
  3098.         END IF;
  3099.  
  3100.  
  3101.         FOR i IN 1..new_screen.element(new_line).length
  3102.         LOOP
  3103.  
  3104.             IF driver.supported_functions( driver.highlight_is )
  3105.             THEN
  3106.               IF old_screen.current_rendition /=
  3107.                   new_screen.element( new_line ).descriptors( i ).rendition
  3108.               THEN
  3109.  
  3110.                   CASE new_screen.element( new_line ).
  3111.                         descriptors( i ).rendition IS
  3112.                   WHEN vt_content.sgpr =>
  3113.                       output_buffer(
  3114.                           buffer_index+1..buffer_index+ansi_SGP'LENGTH ) :=
  3115.                           ansi_SGP;
  3116.                       buffer_index := buffer_index + ansi_SGP'LENGTH;
  3117.  
  3118.                   WHEN vt_content.sgri =>
  3119.                       output_buffer(
  3120.                           buffer_index+1..buffer_index+ansi_SGR'LENGTH ) :=
  3121.                           ansi_SGR;
  3122.                       buffer_index := buffer_index + ansi_SGR'LENGTH;
  3123.  
  3124.                   WHEN vt_content.sgno =>
  3125.                       NULL;
  3126.  
  3127.                   END CASE;
  3128.  
  3129.                   -- set the default rendition
  3130.                   old_screen.current_rendition :=
  3131.                    new_screen.element( new_line ).descriptors( i ).rendition;
  3132.  
  3133.                  END IF;
  3134.             END IF;
  3135.  
  3136.  
  3137.             -- now move the data into the output buffer
  3138.  
  3139.             buffer_index := buffer_index + 1;
  3140.  
  3141.             IF new_screen.element( new_line ).descriptors( i ).rendition =
  3142.                vt_content.sgno
  3143.             THEN
  3144.                 output_buffer( buffer_index ) := ' ';
  3145.             ELSE
  3146.                 output_buffer( buffer_index ) :=
  3147.                         new_screen.element( new_line ).data( i );
  3148.             END IF;
  3149.  
  3150.         END LOOP;
  3151.  
  3152.         -- put the data out
  3153.  
  3154.         check_cursor( old_screen, new_line, start_update_position );
  3155.         driver.interpret( output_buffer( 1..buffer_index ) );
  3156.  
  3157.         IF old_screen.active_position.col_position+buffer_index >
  3158.            vt_content.width
  3159.         THEN old_screen.active_position.col_position := vt_content.width;
  3160.         ELSE old_screen.active_position.col_position :=
  3161.              old_screen.active_position.col_position + buffer_index;
  3162.         END IF;
  3163.  
  3164.         IF old_screen.element( old_line ).length >
  3165.            new_screen.element( new_line ).length
  3166.         THEN
  3167.             driver.interpret( ansi_ELe );
  3168.         END IF;
  3169.  
  3170.         old_screen.element( old_line ):= new_screen.element( new_line );
  3171.  
  3172.     <<quick_out>>
  3173.         NULL;
  3174.  
  3175.     END redraw_line;
  3176.  
  3177. -- -------------------------------------------------------------------------
  3178.  
  3179.     PRAGMA page;
  3180.     PROCEDURE redraw_screen(
  3181.                        old_screen : IN OUT vt_content.vt_content_access;
  3182.                        new_screen : IN vt_content.vt_content_access;
  3183.                        top_line : vt_content.row_range;
  3184.                        bottom_line : vt_content.row_range ) IS
  3185.     BEGIN
  3186.         put_the_cursor_at(1,1);
  3187.         driver.interpret(ansi_ede);
  3188.         FOR i In top_line..bottom_line
  3189.         LOOP
  3190.             redraw_line( old_screen, new_screen, i ,i);
  3191.         END LOOP;
  3192.     END redraw_screen;
  3193.  
  3194.     PRAGMA page;
  3195.  
  3196. -- -------------------------------------------------------------------------
  3197.  
  3198.     PROCEDURE redisplay_screen_with_movement(
  3199.                        old_screen : IN OUT vt_content.vt_content_access;
  3200.                        new_screen : IN vt_content.vt_content_access;
  3201.                        top_line : vt_content.row_range;
  3202.                        bottom_line : vt_content.row_range ) IS
  3203.  
  3204.         tmp_line : positive;
  3205.         the_line : positive := top_line;
  3206.         insert_count : integer;
  3207.         offset : natural := 0;
  3208.         i : integer;
  3209.  
  3210. -- --------------------------------------------------------------------------
  3211.  
  3212.         PROCEDURE next_change( current_position : IN OUT positive;
  3213.                                count            : IN OUT integer   ) IS
  3214.         BEGIN
  3215.            -- determine the number of lines inserted
  3216.            -- current_position defines the line of the last insertion
  3217.  
  3218.             count := 0;
  3219.  
  3220.             WHILE ( new_screen.element( current_position ).
  3221.                         corresponding_line = 0 )    AND
  3222.                   ( current_position <= bottom_line )
  3223.             LOOP
  3224.                 current_position := current_position + 1;
  3225.                 count := count + 1;
  3226.             END LOOP;
  3227.  
  3228.         END next_change;
  3229.  
  3230. -- -----------------------------------------------------------------------
  3231.  
  3232.     PROCEDURE fix_deletes IS
  3233.  
  3234.      zero_count : integer := 0;
  3235.  
  3236.     BEGIN
  3237.          -- search for lines to be deleted, call driver.interpret
  3238.          -- to perform deletions.
  3239.  
  3240.          the_line := top_line;
  3241.          LOOP
  3242.             IF the_line /= top_line
  3243.             THEN
  3244.                 -- scanning line other than top line
  3245.                 IF new_screen.element(the_line).corresponding_line = 0
  3246.                 THEN
  3247.                     -- keeps track of number of insertions
  3248.                    zero_count := zero_count + 1;
  3249.  
  3250.                 ELSIF new_screen.element(the_line).corresponding_line-
  3251.                       new_screen.element(the_line-1).corresponding_line > 1
  3252.                    AND
  3253.                       new_screen.element(the_line-1).corresponding_line /=0
  3254.                    THEN
  3255.                       -- a deletion(s) occurred between the_line and the
  3256.                       -- previous line
  3257.                       check_cursor(old_screen,the_line-zero_count,1);
  3258.                       driver.interpret(ansi_CSI &
  3259.                         value_string(new_screen.element(the_line).
  3260.                                      corresponding_line - new_screen.
  3261.                                      element(the_line-1).corresponding_line -1)
  3262.                                      &  "M" );
  3263.                 ELSIF
  3264.                      new_screen.element(the_line-1).corresponding_line = 0
  3265.                      AND
  3266.                      new_screen.element(the_line).corresponding_line /= 1
  3267.                    THEN
  3268.                       -- the previous line is 0 (insertion)
  3269.                       IF new_screen.element(the_line).corresponding_line
  3270.                            - new_screen.element(the_line-zero_count-1).
  3271.                              corresponding_line > 1
  3272.                       THEN
  3273.                          -- compare the line with the previous non-zero line
  3274.                          check_cursor(old_screen,the_line-zero_count,1);
  3275.                          driver.interpret(ansi_CSI &
  3276.                                  value_string(new_screen.element(the_line).
  3277.                                  corresponding_line -
  3278.                                  new_screen.element(the_line-zero_count- 1).
  3279.                                  corresponding_line-1) & "M");
  3280.                       END IF;
  3281.                END IF;
  3282.  
  3283.         ELSE
  3284.             -- if top line, compare corresponding_line against the_line
  3285.             -- if greater than 1, call driver.interpret to delete lines
  3286.             IF new_screen.element(the_line).corresponding_line = 0
  3287.             THEN
  3288.                zero_count := zero_count + 1;
  3289.             ELSIF
  3290.                new_screen.element(the_line).corresponding_line -
  3291.                        the_line >= 1
  3292.             THEN
  3293.                check_cursor(old_screen,the_line-zero_count,1);
  3294.                driver.interpret(ansi_CSI &
  3295.                  value_string(new_screen.element(the_line).corresponding_line
  3296.                  - (the_line)) & "M" );
  3297.             END IF;
  3298.         END IF;
  3299.  
  3300.         the_line := the_line+1;
  3301.         EXIT WHEN the_line > bottom_line;
  3302.  
  3303.      END LOOP;
  3304.      the_line := top_line;
  3305.  
  3306.     END  fix_deletes;
  3307.  
  3308. -- ----------------------------------------------------------------------------
  3309.  
  3310.    PROCEDURE fix_inserts IS
  3311.  
  3312.     tmp_line : positive;
  3313.  
  3314.    BEGIN
  3315.        -- scan for lines to be inserted
  3316.        the_line := top_line;
  3317.        LOOP
  3318.             IF new_screen.element(the_line).corresponding_line = 0
  3319.             THEN
  3320.                -- found a line to be inserted
  3321.                -- call next_change to determine if following lines
  3322.                -- need to be inserted
  3323.                tmp_line := the_line;
  3324.                next_change(the_line,insert_count);
  3325.                check_cursor(old_screen,tmp_line,1);
  3326.                driver.interpret(ansi_CSI & value_string(insert_count) & "L");
  3327.             ELSE
  3328.                the_line := the_line + 1;
  3329.             END IF;
  3330.            EXIT WHEN (the_line) > bottom_line;
  3331.           END LOOP;
  3332.     END fix_inserts;
  3333.  
  3334. -- ---------------------------------------------------------------------------
  3335.  
  3336.    BEGIN
  3337.    -- scan the new_screen for deletes and perform,
  3338.    -- scan the new_screen for inserts and perform,
  3339.  
  3340.    fix_deletes;
  3341.    fix_inserts;
  3342.  
  3343.    -- if an insert line, redraw it
  3344.    -- if anything else, redisplay line with redraw
  3345.  
  3346.    FOR i IN top_line..bottom_line
  3347.    LOOP
  3348.       IF new_screen.element(i).corresponding_line = 0
  3349.       THEN
  3350.          redraw_line(old_screen,new_screen,i,i);
  3351.       ELSIF
  3352.          new_screen.element(i).corresponding_line > 0
  3353.       THEN
  3354.          redisplay_line_with_redraw(old_screen,
  3355.                                     new_screen,
  3356.                                     new_screen.element(i).corresponding_line,
  3357.                                     i);
  3358.       END IF;
  3359.    END LOOP;
  3360.  
  3361. -- reset the old_screen to look like the physical screen
  3362.  
  3363.     FOR i IN top_line..bottom_line
  3364.     LOOP
  3365.        old_screen.element(i) := new_screen.element(i);
  3366.        new_screen.element(i).corresponding_line := i;
  3367.     END LOOP;
  3368.  
  3369.    END redisplay_screen_with_movement;
  3370.  
  3371. -- -------------------------------------------------------------------------
  3372.  
  3373.     PRAGMA page;
  3374.     PROCEDURE redisplay_screen_with_redraw(
  3375.                        old_screen : IN OUT vt_content.vt_content_access;
  3376.                        new_screen : IN vt_content.vt_content_access;
  3377.                        top_line : IN vt_content.row_range;
  3378.                        bottom_line : IN vt_content.row_range ) IS
  3379.     BEGIN
  3380.         FOR i IN top_line..bottom_line
  3381.         LOOP
  3382.             redisplay_line_with_redraw
  3383.                 ( old_screen, new_screen, i, i );
  3384.         END LOOP;
  3385.     END redisplay_screen_with_redraw;
  3386.  
  3387. -- --------------------------------------------------------------------------
  3388.  
  3389.     PRAGMA page;
  3390.     PROCEDURE redisplay_line_with_redraw(
  3391.                        old_screen : IN OUT vt_content.vt_content_access;
  3392.                        new_screen : IN vt_content.vt_content_access;
  3393.                        old_line : IN vt_content.row_range;
  3394.                        new_line : IN vt_content.row_range ) IS
  3395.  
  3396.     buffer_index : natural := 0;
  3397.  
  3398.     done : boolean := false;
  3399.  
  3400.     no_diff_up_front : boolean := true;
  3401.     no_diff_at_end : boolean := true;
  3402.  
  3403.     start_update_position : positive := 1;
  3404.     end_update_position : natural := new_screen.element( new_line ).length;
  3405.  
  3406.  
  3407.     BEGIN
  3408.  
  3409.         IF new_screen.element( new_line ).length = 0
  3410.         THEN
  3411.             -- erase all of line
  3412.             IF old_screen.element( old_line ).length /= 0
  3413.             THEN
  3414.                 check_cursor( old_screen,new_line, 1 );
  3415.                 -- move the cursor to the beginning of the line
  3416.                 driver.interpret( ansi_ELe ); -- erase to end of line
  3417.                 old_screen.element( old_line ).length := 0;
  3418.             END IF;
  3419.             GOTO quick_out;
  3420.         END IF;
  3421.  
  3422.         LOOP
  3423.             EXIT WHEN
  3424.                 (NOT no_diff_up_front) OR
  3425.                 (start_update_position >
  3426.                  old_screen.element( old_line ).length) OR
  3427.                 (start_update_position >
  3428.                  new_screen.element( new_line ).length );
  3429.  
  3430.             IF ( old_screen.element( old_line ).
  3431.                         descriptors( start_update_position ) /=
  3432.                  new_screen.element( new_line ).
  3433.                         descriptors( start_update_position ) ) OR
  3434.                ( old_screen.element( old_line ).
  3435.                         data( start_update_position ) /=
  3436.                  new_screen.element( new_line ).
  3437.                         data( start_update_position ) )
  3438.             THEN
  3439.                 no_diff_up_front := false;
  3440.             ELSE
  3441.             start_update_position := start_update_position + 1;
  3442.             END IF;
  3443.         END LOOP;
  3444.  
  3445.         IF old_screen.element( old_line ).length =
  3446.            new_screen.element( new_line ).length
  3447.         THEN
  3448.             WHILE no_diff_at_end AND
  3449.                 ( start_update_position <= end_update_position )
  3450.             LOOP
  3451.                 IF ( old_screen.element( old_line ).
  3452.                         descriptors( end_update_position ) /=
  3453.                      new_screen.element( new_line ).
  3454.                         descriptors( end_update_position ) ) OR
  3455.                    ( old_screen.element( old_line ).
  3456.                         data( end_update_position ) /=
  3457.                      new_screen.element( new_line ).
  3458.                         data( end_update_position ) )
  3459.                 THEN no_diff_at_end := false;
  3460.                 ELSE end_update_position := end_update_position - 1;
  3461.                 END IF;
  3462.             END LOOP;
  3463.         END IF;
  3464.  
  3465.         IF start_update_position > end_update_position
  3466.         THEN
  3467.             IF old_screen.element( old_line ).length >
  3468.                new_screen.element( new_line ).length
  3469.             THEN
  3470.                 check_cursor( old_screen,new_line, end_update_position+1 );
  3471.                 driver.interpret( ansi_ELe );
  3472.                 old_screen.element( old_line ) :=
  3473.                         new_screen.element( new_line );
  3474.             END IF;
  3475.             GOTO quick_out;
  3476.         END IF;
  3477.  
  3478.         FOR i IN start_update_position..end_update_position
  3479.         LOOP
  3480.  
  3481.             IF driver.supported_functions( driver.highlight_is )
  3482.             THEN
  3483.               IF old_screen.current_rendition /=
  3484.                   new_screen.element( new_line ).descriptors( i ).rendition
  3485.               THEN
  3486.  
  3487.                   CASE new_screen.element( new_line ).
  3488.                         descriptors( i ).rendition IS
  3489.                   WHEN vt_content.sgpr =>
  3490.                       output_buffer(
  3491.                           buffer_index+1..buffer_index+ansi_SGP'LENGTH ) :=
  3492.                           ansi_SGP;
  3493.                       buffer_index := buffer_index + ansi_SGP'LENGTH;
  3494.  
  3495.                   WHEN vt_content.sgri =>
  3496.                       output_buffer(
  3497.                           buffer_index+1..buffer_index+ansi_SGR'LENGTH ) :=
  3498.                           ansi_SGR;
  3499.                       buffer_index := buffer_index + ansi_SGR'LENGTH;
  3500.  
  3501.                   WHEN vt_content.sgno =>
  3502.                       NULL;
  3503.  
  3504.                   END CASE;
  3505.  
  3506.                   -- set the default rendition
  3507.                   old_screen.current_rendition :=
  3508.                    new_screen.element( new_line ).descriptors( i ).rendition;
  3509.  
  3510.                  END IF;
  3511.             END IF;
  3512.  
  3513.  
  3514.             -- now move the data into the output buffer
  3515.  
  3516.             buffer_index := buffer_index + 1;
  3517.  
  3518.             IF new_screen.element( new_line ).descriptors( i ).rendition =
  3519.                vt_content.sgno
  3520.             THEN
  3521.                 output_buffer( buffer_index ) := ' ';
  3522.             ELSE
  3523.                 output_buffer( buffer_index ) :=
  3524.                         new_screen.element( new_line ).data( i );
  3525.             END IF;
  3526.  
  3527.         END LOOP;
  3528.  
  3529.         -- put the data out
  3530.  
  3531.         check_cursor( old_screen,new_line, start_update_position );
  3532.         driver.interpret( output_buffer( 1..buffer_index ) );
  3533.  
  3534.         IF old_screen.active_position.col_position+buffer_index >
  3535.            vt_content.width
  3536.         THEN old_screen.active_position.col_position := vt_content.width;
  3537.         ELSE old_screen.active_position.col_position :=
  3538.              old_screen.active_position.col_position + buffer_index;
  3539.         END IF;
  3540.  
  3541.         IF old_screen.element( old_line ).length >
  3542.            new_screen.element( new_line ).length
  3543.         THEN
  3544.             driver.interpret( ansi_ELe );
  3545.         END IF;
  3546.  
  3547.         old_screen.element( old_line ):= new_screen.element( new_line );
  3548.  
  3549.     <<quick_out>>
  3550.         NULL;
  3551.  
  3552.     END redisplay_line_with_redraw;
  3553.  
  3554. -- ----------------------------------------------------------------------------
  3555.  
  3556. BEGIN -- redisplay
  3557.     NULL;
  3558. END redisplay;
  3559. ::::::::::
  3560. scroll_body.ada
  3561. ::::::::::
  3562. -- ----------------------------------------------------------------------------
  3563. -- ABSTRACT:  A user's program can WITH this package to provide a device-
  3564. --            independent terminal interface that is functionally equivalent
  3565. --            to a scroll-terminal.  This is the simplest form of terminal that
  3566. --            this virtual terminal supports.  This package should be chosen for
  3567. --            any of the following reasons:
  3568. --
  3569. --            1. The user's terminal is primitive.  Either it could be a CRT
  3570. --               with little functionality, or a printing terminal.
  3571. --            2. The user wants maximum transportability.
  3572. --            3. The user does not need advanced capabilities for the
  3573. --               application.
  3574. --            4. The user's application may run over low speed communication
  3575. --               lines, making the page and form mode unacceptable.
  3576. -- -----------------------------------------------------------------------------
  3577.  
  3578. WITH
  3579.     sysdep,
  3580.     driver,
  3581.     vt_input,
  3582.     vt_content;
  3583.  
  3584. USE
  3585.     vt_content;  -- resolves visibility problems
  3586.  
  3587.   PACKAGE BODY scroll_terminal IS
  3588.  
  3589.     actual_screen,
  3590.     virtual_screen  : vt_content.vt_content_access;
  3591.     immediate : boolean := false;
  3592.     initialized :boolean := false;
  3593.     active_line : CONSTANT positive := 24 ;
  3594.  
  3595.     PRAGMA page;
  3596.     PROCEDURE open (name     : IN string := "none" ) IS
  3597.  
  3598.     BEGIN
  3599.         driver.vt_initialize( name, vt_content.height, vt_content.width) ;
  3600.  
  3601.         virtual_screen := NEW vt_content.vt_content_record ;
  3602.         actual_screen := NEW vt_content.vt_content_record ;
  3603.  
  3604.         virtual_screen.current_rendition := vt_content.sgpr ;
  3605.         virtual_screen.active_position.row_position := active_line ;
  3606.  
  3607.         FOR i IN 1..vt_content.width
  3608.         LOOP
  3609.            virtual_screen.element(active_line).descriptors(i).
  3610.              rendition := vt_content.sgpr ;
  3611.            virtual_screen.tabs(i) := FALSE ;
  3612.         END LOOP ;
  3613.  
  3614.         FOR i IN 1..vt_content.height
  3615.         LOOP
  3616.            virtual_screen.element(i).length := 0 ;
  3617.  
  3618.         END LOOP ;
  3619.  
  3620.         initialized := true ;
  3621.         actual_screen.ALL := virtual_screen.ALL ;
  3622.  
  3623.     EXCEPTION
  3624.         WHEN driver.tcf_error =>  RAISE  tcf_error ;
  3625.         WHEN driver.unsupported_terminal => RAISE unsupported_terminal ;
  3626.         WHEN driver.uninitialized => RAISE uninitialized ;
  3627.  
  3628.     END open ;
  3629.     PRAGMA page;
  3630.  
  3631.     PROCEDURE close IS
  3632.     BEGIN
  3633.  
  3634.         IF NOT initialized
  3635.         THEN  RAISE  uninitialized ;
  3636.         END IF ;
  3637.  
  3638.         initialized := false ;
  3639.         driver.close_virtual_terminal ;
  3640.  
  3641.  
  3642.     END close;
  3643.     PRAGMA page;
  3644.  
  3645.     PROCEDURE set_position (position : IN     positive) IS
  3646.     BEGIN
  3647.  
  3648.         IF NOT initialized
  3649.         THEN  RAISE  uninitialized ;
  3650.         END IF ;
  3651.  
  3652.         IF position > vt_content.width
  3653.            THEN
  3654.                virtual_screen.active_position.col_position :=
  3655.                    vt_content.width ;
  3656.            ELSE
  3657.                virtual_screen.active_position.col_position := position ;
  3658.         END IF ;
  3659.  
  3660.  
  3661.     END set_position;
  3662.     PRAGMA page;
  3663.  
  3664.     FUNCTION  position RETURN positive IS
  3665.     BEGIN
  3666.  
  3667.         IF NOT initialized
  3668.         THEN  RAISE  uninitialized ;
  3669.         END IF ;
  3670.  
  3671.         RETURN (virtual_screen.active_position.col_position) ;
  3672.  
  3673.  
  3674.     END position;
  3675.  
  3676.     PRAGMA page;
  3677.     FUNCTION  size RETURN positive IS
  3678.     BEGIN
  3679.  
  3680.         IF NOT initialized
  3681.         THEN  RAISE  uninitialized ;
  3682.         END IF ;
  3683.  
  3684.         RETURN (vt_content.width) ;
  3685.  
  3686.  
  3687.     END size;
  3688.  
  3689.     PRAGMA page;
  3690.     PROCEDURE set_tab IS
  3691.     BEGIN
  3692.  
  3693.         IF NOT initialized
  3694.         THEN  RAISE  uninitialized ;
  3695.         END IF ;
  3696.  
  3697.         virtual_screen.tabs(virtual_screen.active_position.col_position)
  3698.               := TRUE ;
  3699.  
  3700.     END set_tab;
  3701.  
  3702.     PRAGMA page;
  3703.     PROCEDURE clear_tab IS
  3704.     BEGIN
  3705.  
  3706.         IF NOT initialized
  3707.         THEN  RAISE  uninitialized ;
  3708.         END IF ;
  3709.  
  3710.         virtual_screen.tabs(virtual_screen.active_position.col_position)
  3711.               := FALSE ;
  3712.  
  3713.     END clear_tab;
  3714.  
  3715.     PRAGMA page;
  3716.     PROCEDURE tab       (count    : IN     positive := 1) IS
  3717.     temp_col : positive := virtual_screen.active_position.col_position ;
  3718.     found_next_tab_stop : BOOLEAN := false ;
  3719.  
  3720.     BEGIN
  3721.  
  3722.        IF NOT initialized
  3723.        THEN  RAISE  uninitialized ;
  3724.        END IF ;
  3725.  
  3726.        FOR i IN 1..count
  3727.        LOOP
  3728.           found_next_tab_stop := false ;
  3729.  
  3730.           LOOP
  3731.              temp_col := temp_col + 1 ;
  3732.  
  3733.              IF virtual_screen.tabs(temp_col)
  3734.              THEN found_next_tab_stop := TRUE ;
  3735.              END IF ;
  3736.  
  3737.              EXIT WHEN found_next_tab_stop  OR
  3738.                         (temp_col = vt_content.width) ;
  3739.           END LOOP ;
  3740.  
  3741.           EXIT WHEN temp_col = vt_content.width ;
  3742.           virtual_screen.active_position.col_position := temp_col ;
  3743.  
  3744.        END LOOP ;
  3745.  
  3746.        IF found_next_tab_stop
  3747.        THEN
  3748.            virtual_screen.active_position.col_position := temp_col ;
  3749.        END IF  ;
  3750.  
  3751.  
  3752.     END tab;
  3753.  
  3754.     PRAGMA page;
  3755.     PROCEDURE new_line  (count    : IN     positive := 1) IS
  3756.  
  3757.     BEGIN
  3758.  
  3759.        IF NOT initialized
  3760.        THEN  RAISE  uninitialized ;
  3761.        END IF ;
  3762.        -- update the line, move cursor, reset active line to null
  3763.  
  3764.        update_line ;
  3765.        FOR i IN 1..count
  3766.        LOOP
  3767.           driver.interpret( ascii.cr & ascii.lf ) ;
  3768.        END LOOP ;
  3769.  
  3770.        virtual_screen.element(active_line).length := 0 ;
  3771.        virtual_screen.active_position.col_position := 1 ;
  3772.  
  3773.  
  3774.     END new_line;
  3775.  
  3776.     PRAGMA page;
  3777.     PROCEDURE new_page  (count    : IN     positive := 1) IS
  3778.     buffer : string(1..1) := string'(1 => ascii.ff ) ;
  3779.  
  3780.     BEGIN
  3781.  
  3782.        IF NOT initialized
  3783.        THEN  RAISE  uninitialized ;
  3784.        END IF ;
  3785.  
  3786.        update_line ;
  3787.        FOR i IN 1..count
  3788.        LOOP
  3789.           driver.interpret( buffer ) ;
  3790.        END LOOP ;
  3791.  
  3792.        virtual_screen.active_position.col_position := 1 ;
  3793.        virtual_screen.element(active_line).length := 0 ;
  3794.  
  3795.  
  3796.     END new_page;
  3797.  
  3798.     PRAGMA page;
  3799.     PROCEDURE put (item     : IN     character) IS
  3800.     buffer : string(1..1) ;
  3801.  
  3802.     BEGIN
  3803.  
  3804.        IF NOT initialized
  3805.        THEN  RAISE  uninitialized ;
  3806.        END IF ;
  3807.  
  3808.        buffer(1) := item ;
  3809.        put(buffer) ;
  3810.  
  3811.     END put;
  3812.  
  3813.     PRAGMA page;
  3814.     PROCEDURE put (item     : IN     string) IS
  3815.     temp_col : positive := virtual_screen.active_position.col_position ;
  3816.     stop_pos : positive ;
  3817.  
  3818.     BEGIN
  3819.  
  3820.        IF NOT initialized
  3821.        THEN  RAISE  uninitialized ;
  3822.        END IF ;
  3823.  
  3824.         -- first blank out area between current line length and
  3825.         -- the active position
  3826.  
  3827.         FOR i IN virtual_screen.element(active_line).length + 1..
  3828.                  virtual_screen.active_position.col_position - 1
  3829.         LOOP
  3830.            virtual_screen.element(active_line).data(i) := ' ' ;
  3831.         END LOOP ;
  3832.  
  3833.        IF temp_col + item'LENGTH -1 >= vt_content.width
  3834.        THEN
  3835.             stop_pos := vt_content.width - temp_col + 1 ;
  3836.             virtual_screen.element(active_line).data(temp_col..
  3837.                vt_content.width) := item(1..stop_pos) ;
  3838.  
  3839.             temp_col := vt_content.width ;
  3840.             virtual_screen.element(active_line).length := vt_content.width;
  3841.  
  3842.        ELSE
  3843.             virtual_screen.element(active_line).data(temp_col..
  3844.                temp_col+item'LENGTH -1 ) := item ;
  3845.  
  3846.             temp_col := temp_col + item'LENGTH - 1 ;
  3847.             virtual_screen.element(active_line).length := temp_col ;
  3848.             temp_col := temp_col + 1 ;
  3849.  
  3850.        END IF ;
  3851.  
  3852.           virtual_screen.active_position.col_position := temp_col ;
  3853.  
  3854.  
  3855.     END put;
  3856.  
  3857.     PRAGMA page;
  3858.     PROCEDURE update_line IS
  3859.  
  3860.     BEGIN
  3861.  
  3862.        IF NOT initialized
  3863.        THEN  RAISE  uninitialized ;
  3864.        END IF ;
  3865.  
  3866.         IF virtual_screen.element(active_line).length /= 0
  3867.         THEN
  3868.             driver.interpret(virtual_screen.element(active_line).data(1..
  3869.               virtual_screen.element(active_line).length) ) ;
  3870.         END IF ;
  3871.  
  3872.         virtual_screen.element(active_line).length := 0 ;
  3873.         virtual_screen.active_position.col_position:= 1 ;
  3874.  
  3875.     END update_line;
  3876.  
  3877.     PRAGMA page;
  3878.     FUNCTION valid_character( item : IN character ) RETURN boolean IS
  3879.     BEGIN
  3880.  
  3881.        IF NOT initialized
  3882.        THEN  RAISE  uninitialized ;
  3883.        END IF ;
  3884.  
  3885.        RETURN (sysdep.valid_character( item ) ) ;
  3886.  
  3887.     END valid_character;
  3888.  
  3889.     PRAGMA page;
  3890.  
  3891.     FUNCTION convert_key_enum( key_id : IN vt_input.function_key_enum )
  3892.                 RETURN function_key_enum IS
  3893.         temp_id : function_key_enum;
  3894.     BEGIN
  3895.  
  3896.         CASE key_id IS
  3897.         WHEN vt_input.up_arrow           => temp_id := up_arrow;
  3898.         WHEN vt_input.down_arrow         => temp_id := down_arrow;
  3899.         WHEN vt_input.left_arrow         => temp_id := left_arrow;
  3900.         WHEN vt_input.right_arrow        => temp_id := right_arrow;
  3901.         WHEN vt_input.f1                 => temp_id := f1;
  3902.         WHEN vt_input.f2                 => temp_id := f2;
  3903.         WHEN vt_input.f3                 => temp_id := f3;
  3904.         WHEN vt_input.f4                 => temp_id := f4;
  3905.         WHEN vt_input.f5                 => temp_id := f5;
  3906.         WHEN vt_input.f6                 => temp_id := f6 ;
  3907.         WHEN vt_input.f7                 => temp_id := f7 ;
  3908.         WHEN vt_input.f8                 => temp_id := f8 ;
  3909.         WHEN vt_input.f9                 => temp_id := f9 ;
  3910.         WHEN vt_input.f10                => temp_id := f10;
  3911.         WHEN vt_input.f11                => temp_id := f11;
  3912.         WHEN vt_input.f12                => temp_id := f12;
  3913.         WHEN vt_input.f13                => temp_id := f13;
  3914.         WHEN vt_input.f14                => temp_id := f14;
  3915.         WHEN vt_input.f15                => temp_id := f15;
  3916.         WHEN vt_input.f16                => temp_id := f16;
  3917.         WHEN vt_input.f17                => temp_id := f17;
  3918.         WHEN vt_input.f18                => temp_id := f18;
  3919.         WHEN vt_input.f19                => temp_id := f19;
  3920.         WHEN vt_input.f20                => temp_id := f20;
  3921.         WHEN vt_input.f21                => temp_id := f21;
  3922.         WHEN vt_input.f22                => temp_id := f22;
  3923.         WHEN vt_input.f23                => temp_id := f23;
  3924.         WHEN vt_input.f24                => temp_id := f24;
  3925.         WHEN vt_input.f25                => temp_id := f25;
  3926.         WHEN vt_input.f26                => temp_id := f26;
  3927.         WHEN vt_input.f27                => temp_id := f27;
  3928.         WHEN vt_input.f28                => temp_id := f28;
  3929.         WHEN vt_input.f29                => temp_id := f29;
  3930.         WHEN vt_input.f30                => temp_id := f30;
  3931.         WHEN vt_input.f31                => temp_id := f31;
  3932.         WHEN vt_input.f32                => temp_id := f32;
  3933.         WHEN OTHERS => NULL;
  3934.         END CASE;
  3935.  
  3936.         RETURN temp_id;
  3937.  
  3938.     END convert_key_enum;
  3939.  
  3940.     FUNCTION convert_key_enum( key_id : IN function_key_enum )
  3941.                 RETURN vt_input.function_key_enum IS
  3942.         temp_id : vt_input.function_key_enum;
  3943.     BEGIN
  3944.         CASE key_id IS
  3945.         WHEN up_arrow           => temp_id := vt_input.up_arrow;
  3946.         WHEN down_arrow         => temp_id := vt_input.down_arrow;
  3947.         WHEN left_arrow         => temp_id := vt_input.left_arrow;
  3948.         WHEN right_arrow        => temp_id := vt_input.right_arrow;
  3949.         WHEN f1                 => temp_id := vt_input.f1;
  3950.         WHEN f2                 => temp_id := vt_input.f2;
  3951.         WHEN f3                 => temp_id := vt_input.f3;
  3952.         WHEN f4                 => temp_id := vt_input.f4;
  3953.         WHEN f5                 => temp_id := vt_input.f5;
  3954.         WHEN f6                 => temp_id := vt_input.f6 ;
  3955.         WHEN f7                 => temp_id := vt_input.f7 ;
  3956.         WHEN f8                 => temp_id := vt_input.f8 ;
  3957.         WHEN f9                 => temp_id := vt_input.f9 ;
  3958.         WHEN f10                => temp_id := vt_input.f10;
  3959.         WHEN f11                => temp_id := vt_input.f11;
  3960.         WHEN f12                => temp_id := vt_input.f12;
  3961.         WHEN f13                => temp_id := vt_input.f13;
  3962.         WHEN f14                => temp_id := vt_input.f14;
  3963.         WHEN f15                => temp_id := vt_input.f15;
  3964.         WHEN f16                => temp_id := vt_input.f16;
  3965.         WHEN f17                => temp_id := vt_input.f17;
  3966.         WHEN f18                => temp_id := vt_input.f18;
  3967.         WHEN f19                => temp_id := vt_input.f19;
  3968.         WHEN f20                => temp_id := vt_input.f20;
  3969.         WHEN f21                => temp_id := vt_input.f21;
  3970.         WHEN f22                => temp_id := vt_input.f22;
  3971.         WHEN f23                => temp_id := vt_input.f23;
  3972.         WHEN f24                => temp_id := vt_input.f24;
  3973.         WHEN f25                => temp_id := vt_input.f25;
  3974.         WHEN f26                => temp_id := vt_input.f26;
  3975.         WHEN f27                => temp_id := vt_input.f27;
  3976.         WHEN f28                => temp_id := vt_input.f28;
  3977.         WHEN f29                => temp_id := vt_input.f29;
  3978.         WHEN f30                => temp_id := vt_input.f30;
  3979.         WHEN f31                => temp_id := vt_input.f31;
  3980.         WHEN f32                => temp_id := vt_input.f32;
  3981.         WHEN OTHERS => NULL;
  3982.         END CASE;
  3983.  
  3984.         RETURN temp_id;
  3985.  
  3986.     END convert_key_enum;
  3987.  
  3988.     PROCEDURE convert_descriptor( keys : IN function_key_descriptor;
  3989.                         key_temp : OUT vt_input.function_key_descriptor ) IS
  3990.     BEGIN
  3991.         key_temp.no_of_keys := keys.no_of_keys;
  3992.         FOR i IN 1..keys.no_of_keys
  3993.         LOOP
  3994.             key_temp.keys( i ).key := convert_key_enum( keys.keys( i ).key );
  3995.             key_temp.keys( i ).position := keys.keys( i ).position;
  3996.         END LOOP;
  3997.     END convert_descriptor;
  3998.  
  3999.     PROCEDURE convert_descriptor( keys : IN vt_input.function_key_descriptor;
  4000.                 key_temp : OUT function_key_descriptor ) IS
  4001.     BEGIN
  4002.         key_temp.no_of_keys := keys.no_of_keys;
  4003.         FOR i IN 1..keys.no_of_keys
  4004.         LOOP
  4005.             key_temp.keys( i ).key := convert_key_enum( keys.keys( i ).key );
  4006.             key_temp.keys( i ).position := keys.keys( i ).position;
  4007.         END LOOP;
  4008.     END convert_descriptor;
  4009.  
  4010.  
  4011.     PRAGMA page;
  4012.     PROCEDURE get( data : OUT string;
  4013.                    last : OUT natural;
  4014.                    keys : OUT function_key_descriptor;
  4015.                    timeout : IN  duration := duration'last ) IS
  4016.         key_temp : vt_input.function_key_descriptor( 32 );
  4017.     BEGIN
  4018.  
  4019.         IF NOT initialized
  4020.         THEN  RAISE uninitialized ;
  4021.         END IF ;
  4022.  
  4023.         vt_input.get( data,
  4024.                       last,
  4025.                       key_temp,
  4026.                       timeout );
  4027.  
  4028.         convert_descriptor( key_temp, keys );
  4029.  
  4030.  
  4031.     END get;
  4032.  
  4033.     PRAGMA page;
  4034.     FUNCTION function_count(keys : IN function_key_descriptor)
  4035.         RETURN natural IS
  4036.         key_temp : vt_input.function_key_descriptor( 32 );
  4037.     BEGIN
  4038.  
  4039.         IF NOT initialized
  4040.         THEN  RAISE uninitialized ;
  4041.         END IF ;
  4042.  
  4043.         convert_descriptor( keys, key_temp );
  4044.         RETURN vt_input.function_count( key_temp );
  4045.  
  4046.     END function_count;
  4047.  
  4048.     PRAGMA page;
  4049.     PROCEDURE function_key(keys           : IN     function_key_descriptor;
  4050.                            index          : IN     positive;
  4051.                            key_identifier :    OUT function_key_enum;
  4052.                         previous_position :    OUT natural) IS
  4053.         key_temp : vt_input.function_key_descriptor( 32 );
  4054.         id_temp : vt_input.function_key_enum;
  4055.     BEGIN
  4056.  
  4057.         IF NOT initialized
  4058.         THEN  RAISE uninitialized ;
  4059.         END IF ;
  4060.  
  4061.         convert_descriptor( keys, key_temp );
  4062.         vt_input.function_key( key_temp,
  4063.                                index,
  4064.                                id_temp,
  4065.                                previous_position );
  4066.         key_identifier := convert_key_enum( id_temp );
  4067.  
  4068.     END function_key;
  4069.  
  4070.     PRAGMA page;
  4071.     PROCEDURE function_key_name
  4072.       ( key_identifier : IN function_key_enum;
  4073.         key_name : OUT string;
  4074.         last : OUT natural) IS
  4075.         key_temp : vt_input.function_key_enum;
  4076.     BEGIN
  4077.  
  4078.         IF NOT initialized
  4079.         THEN  RAISE uninitialized ;
  4080.         END IF ;
  4081.  
  4082.         key_temp := convert_key_enum( key_identifier );
  4083.  
  4084.         vt_input.function_key_name( key_temp,
  4085.                                     key_name,
  4086.                                     last );
  4087.  
  4088.  
  4089.     END function_key_name;
  4090.  
  4091.     PRAGMA page;
  4092.  
  4093.  
  4094.     PROCEDURE bell IS
  4095.     buffer : string(1..1) := string'(1 => ascii.bel ) ;
  4096.     BEGIN
  4097.  
  4098.         IF NOT initialized
  4099.         THEN  RAISE uninitialized ;
  4100.         END IF ;
  4101.  
  4102.         driver.interpret( buffer ) ;
  4103.  
  4104.     END bell;
  4105.  
  4106.  
  4107. BEGIN -- scroll_terminal
  4108.     NULL;
  4109. EXCEPTION
  4110.     WHEN driver.tcf_error =>  RAISE  tcf_error ;
  4111.     WHEN driver.unsupported_terminal => RAISE unsupported_terminal ;
  4112.     WHEN driver.uninitialized => RAISE uninitialized ;
  4113.  
  4114. END scroll_terminal;
  4115. ::::::::::
  4116. page_body.ada
  4117. ::::::::::
  4118. -- ----------------------------------------------------------------------------
  4119. -- ABSTRACT:  A user's program can WITH this package to provide a device-
  4120. --            independent terminal interface that is functionally equivalent
  4121. --            to a page-terminal.  This is the most advanced form of terminal
  4122. --            that this virtual terminal supports.  This package should be
  4123. --            chosen for any of the following reasons:
  4124. --
  4125. --            1. The user's terminal has advanced features.  The terminal is
  4126. --               directly addressable, with erase to end of line, and erase
  4127. --               to end of screen capabilities.
  4128. --            2. The user wants advanced capabilities and is willing to
  4129. --               sacrifice some transportability.
  4130. -- -----------------------------------------------------------------------------
  4131.  
  4132. WITH
  4133.     driver,
  4134.     redisplay,
  4135.     vt_input,
  4136.     sysdep,             -- only for valid_character function !
  4137.     vt_content;
  4138.  
  4139. USE
  4140.     vt_content;  -- resolves visibility problems with operators
  4141.  
  4142.   PACKAGE BODY page_terminal IS
  4143.  
  4144.     ansi_CSI : CONSTANT string( 1..2 ) := ascii.esc & '[';
  4145.  
  4146. --  these next three are constructed below in the appropriate procedures.
  4147. --  They actually have parameters.
  4148. --
  4149. --  ansi_DCH : CONSTANT string( 1..3 ) := ansi_CSI & 'P';
  4150. --
  4151. --  ansi_DL  : CONSTANT string( 1..3 ) := ansi_CSI & 'M';
  4152. --  ansi_IL  : CONSTANT string( 1..3 ) := ansi_CSI & 'L';
  4153.  
  4154.     ansi_EDe : CONSTANT string( 1..4 ) := ansi_CSI & "0J";
  4155.     ansi_EDs : CONSTANT string( 1..4 ) := ansi_CSI & "1J";
  4156.     ansi_EDa : CONSTANT string( 1..4 ) := ansi_CSI & "2J";
  4157.  
  4158.     ansi_ELe : CONSTANT string( 1..4 ) := ansi_CSI & "0K";
  4159.     ansi_ELs : CONSTANT string( 1..4 ) := ansi_CSI & "1K";
  4160.     ansi_ELa : CONSTANT string( 1..4 ) := ansi_CSI & "2K";
  4161.  
  4162.     ansi_SGP : CONSTANT string( 1..4 ) := ansi_CSI & "0m";
  4163.     ansi_SGR : CONSTANT string( 1..4 ) := ansi_CSI & "7m";
  4164.  
  4165.     ansi_IMs : CONSTANT string( 1..4 ) := ansi_CSI & "4h";
  4166.     ansi_IMr : CONSTANT string( 1..4 ) := ansi_CSI & "4l";
  4167.  
  4168.     actual_screen,
  4169.     virtual_screen  : vt_content.vt_content_access;
  4170.  
  4171.     initialized : boolean := false;
  4172.  
  4173.     PRAGMA page;
  4174.     FUNCTION value_string( value : IN positive ) RETURN string IS
  4175.         value_image : CONSTANT string := positive'image( value );
  4176.     BEGIN
  4177.             RETURN value_image( (value_image'first + 1)..value_image'last );
  4178.     END;
  4179.  
  4180.     PROCEDURE blank_columns( row : IN positive;
  4181.                              start_col : IN natural;
  4182.                              end_col : IN natural ) IS
  4183.     BEGIN
  4184.         FOR temp_col IN start_col..end_col
  4185.         LOOP
  4186.             virtual_screen.element( row ).data( temp_col ) := ' ';
  4187.             virtual_screen.element( row ).descriptors( temp_col ).rendition :=
  4188.                 vt_content.sgpr;
  4189.         END LOOP;
  4190.     END blank_columns;
  4191.  
  4192.  
  4193.     PRAGMA page;
  4194.     PROCEDURE open (name : IN string := "none" ) IS
  4195.     BEGIN
  4196.  
  4197.            driver.vt_initialize
  4198.                 ( name, vt_content.height, vt_content.width );
  4199.  
  4200.         IF NOT (driver.supported_functions(driver.erase_to_end_of_screen_is) AND
  4201.            driver.supported_functions(driver.erase_to_end_of_line_is) AND
  4202.            driver.supported_functions(driver.move_the_cursor_is))
  4203.         THEN
  4204.            RAISE terminal_too_primitive;
  4205.         END IF;
  4206.  
  4207.         actual_screen := NEW vt_content.vt_content_record;
  4208.         virtual_screen := NEW vt_content.vt_content_record;
  4209.  
  4210.         initialized := true;
  4211.  
  4212.         -- erase all of display
  4213.  
  4214.         driver.interpret
  4215.                 ( ansi_CSI & value_string( 1 ) & ";" &
  4216.                   value_string( 1 ) & "H" &
  4217.                   ansi_EDe );
  4218.  
  4219.         virtual_screen.current_rendition := vt_content.sgpr;
  4220.         virtual_screen.insert_mode := false;
  4221.  
  4222.         -- no tabs initially
  4223.         FOR col IN 1..vt_content.width
  4224.         LOOP
  4225.             virtual_screen.tabs( col ) := false;
  4226.         END LOOP;
  4227.  
  4228.         FOR row IN 1..vt_content.height
  4229.         LOOP
  4230.             virtual_screen.element( row ).corresponding_line := row;
  4231.         END LOOP;
  4232.  
  4233.         -- make the actual look like the virtual
  4234.         actual_screen.ALL := virtual_screen.ALL;
  4235.  
  4236.  
  4237.  
  4238.     EXCEPTION
  4239.         WHEN driver.tcf_error  => RAISE tcf_error;
  4240.         WHEN driver.unsupported_terminal => RAISE unsupported_terminal;
  4241.         WHEN driver.uninitialized => RAISE uninitialized;
  4242.  
  4243.     END open;
  4244.  
  4245.     PRAGMA page;
  4246.     PROCEDURE close IS
  4247.     BEGIN
  4248.  
  4249.         IF driver.supported_functions( driver.highlight_is )
  4250.         THEN
  4251.             CASE actual_screen.current_rendition IS
  4252.             WHEN vt_content.sgpr  => NULL;
  4253.             WHEN vt_content.sgri  => driver.interpret( ansi_SGP );
  4254.             WHEN vt_content.sgno  => NULL;
  4255.             END CASE;
  4256.         END IF;
  4257.         initialized := false;
  4258.         driver.close_virtual_terminal;
  4259.  
  4260.     END close;
  4261.  
  4262.     PRAGMA page;
  4263.     PROCEDURE set_position (position : IN     xy_position) IS
  4264.  
  4265.     buffer : CONSTANT string :=
  4266.                         ansi_CSI &
  4267.                         value_string( position.line ) & ';' &
  4268.                         value_string( position.column ) & 'H'  ;
  4269.     temp_lin : positive;
  4270.     temp_col : positive;
  4271.  
  4272.     BEGIN -- set_position
  4273.  
  4274.     -- if terminal has not been opened raise uninitialized
  4275.  
  4276.         IF NOT initialized
  4277.         THEN
  4278.             RAISE uninitialized;
  4279.         END IF;
  4280.  
  4281.         temp_lin := position.line;
  4282.         temp_col := position.column;
  4283.  
  4284.         -- If out of bounds on either line or column, set the values
  4285.         -- the max and continue.
  4286.  
  4287.         IF temp_lin > vt_content.height
  4288.         THEN temp_lin := vt_content.height;
  4289.         END IF;
  4290.  
  4291.         IF temp_col > vt_content.width
  4292.         THEN temp_col := vt_content.width;
  4293.         END IF;
  4294.  
  4295.           -- alter the virtual data structure.
  4296.  
  4297.         virtual_screen.active_position :=
  4298.                 vt_content.vt_position_xy_record'(
  4299.                         temp_lin, temp_col );
  4300.  
  4301.     END set_position;
  4302.  
  4303.     PRAGMA page;
  4304.     FUNCTION  position RETURN xy_position IS
  4305.     BEGIN
  4306.  
  4307.     -- raise exception if terminal has not been opened
  4308.  
  4309.         IF NOT initialized
  4310.         THEN
  4311.             RAISE uninitialized;
  4312.         END IF;
  4313.  
  4314.         RETURN xy_position'( virtual_screen.active_position.row_position,
  4315.                              virtual_screen.active_position.col_position );
  4316.  
  4317.     END  position;
  4318.  
  4319.     PRAGMA page;
  4320.     FUNCTION  size RETURN xy_position IS
  4321.     BEGIN
  4322.  
  4323.         IF NOT initialized
  4324.         THEN
  4325.             RAISE uninitialized;
  4326.         END IF;
  4327.  
  4328.         RETURN xy_position'( vt_content.height, vt_content.width );
  4329.  
  4330.     END  size;
  4331.  
  4332.     PRAGMA page;
  4333.     PROCEDURE delete_character (count    : IN     positive := 1) IS
  4334.     buffer : CONSTANT string := ansi_CSI &
  4335.                                 value_string( count ) & 'P';
  4336.     temp_row : positive := virtual_screen.active_position.row_position;
  4337.     temp_col : positive := virtual_screen.active_position.col_position;
  4338.     temp_len : natural := virtual_screen.element( temp_row ).length;
  4339.     BEGIN
  4340.     -- raise exception when terminal not open
  4341.  
  4342.         IF NOT initialized
  4343.         THEN
  4344.             RAISE uninitialized;
  4345.         END IF;
  4346.  
  4347.         IF temp_len /= 0
  4348.         THEN
  4349.  
  4350.             IF temp_col <= temp_len
  4351.             THEN
  4352.                 IF count >= temp_len-temp_col+1
  4353.                 THEN
  4354.                     virtual_screen.element( temp_row ).length :=
  4355.                            temp_col - 1;
  4356.                 ELSE
  4357.  
  4358.                     virtual_screen.element( temp_row ).
  4359.                         data( temp_col..temp_len-count ) :=
  4360.                             virtual_screen.element( temp_row ).
  4361.                             data( temp_col+count..temp_len );
  4362.  
  4363.                     virtual_screen.element( temp_row ).
  4364.                         descriptors( temp_col..temp_len-count ) :=
  4365.                             virtual_screen.element( temp_row ).
  4366.                             descriptors( temp_col+count..temp_len );
  4367.  
  4368.                     virtual_screen.element( temp_row ).length :=
  4369.                             temp_len - count;
  4370.  
  4371.                 END IF;
  4372.  
  4373.             END IF;
  4374.         END IF;
  4375.  
  4376.     END delete_character;
  4377.  
  4378.     PRAGMA page;
  4379.     PROCEDURE delete_line      (count    : IN     positive := 1) IS
  4380.         buffer : CONSTANT string := ansi_CSI &
  4381.                                     value_string( count ) & 'M';
  4382.         temp_row : positive;
  4383.     BEGIN
  4384.     -- raise exception when terminal not open
  4385.  
  4386.         IF NOT initialized
  4387.         THEN
  4388.             RAISE uninitialized;
  4389.         END IF;
  4390.  
  4391.         temp_row := virtual_screen.active_position.row_position;
  4392.  
  4393.         IF count >= (vt_content.height - temp_row + 1)
  4394.         THEN
  4395.             FOR i IN temp_row..vt_content.height
  4396.             LOOP
  4397.                 virtual_screen.element( i ).length := 0;
  4398.                 virtual_screen.element( i ).corresponding_line := 0;
  4399.             END LOOP;
  4400.         ELSE
  4401.             virtual_screen.element( temp_row..vt_content.height-count ) :=
  4402.                 virtual_screen.element( temp_row+count..vt_content.height );
  4403.             FOR i IN vt_content.height-count+1..vt_content.height
  4404.             LOOP
  4405.                 virtual_screen.element( i ).length := 0;
  4406.                 virtual_screen.element( i ).corresponding_line := 0;
  4407.             END LOOP;
  4408.         END IF;
  4409.  
  4410.     END delete_line;
  4411.  
  4412.     PRAGMA page;
  4413.     PROCEDURE erase_in_display (selection : select_enumeration) IS
  4414.  
  4415.         PROCEDURE erase_lines ( top_line : IN positive;
  4416.                                 bottom_line : IN positive ) IS
  4417.         BEGIN -- erase_lines
  4418.             FOR temp_row IN top_line..bottom_line
  4419.             LOOP
  4420.                 -- initially every line is empty
  4421.                 virtual_screen.element( temp_row ).length := 0;
  4422.             END LOOP;
  4423.  
  4424.         END erase_lines;
  4425.  
  4426.     BEGIN -- erase_in_display
  4427.  
  4428.     -- raise exception when terminal not open
  4429.         IF NOT initialized
  4430.         THEN
  4431.             RAISE uninitialized;
  4432.         END IF;
  4433.  
  4434.         CASE selection IS
  4435.                 WHEN from_xy_position_to_end =>
  4436.                     -- cursor remains where it is.
  4437.                     erase_in_line( from_xy_position_to_end );
  4438.                     erase_lines(
  4439.                         virtual_screen.active_position.row_position + 1,
  4440.                         vt_content.height );
  4441.  
  4442.                 WHEN from_start_to_xy_position =>
  4443.                     -- cursor remain where it is.
  4444.                     erase_in_line( from_start_to_xy_position );
  4445.                     erase_lines(
  4446.                         1, virtual_screen.active_position.row_position - 1 );
  4447.  
  4448.                 WHEN all_positions =>
  4449.  
  4450.                     -- place the active position at 1,1
  4451.                     virtual_screen.active_position :=
  4452.                         vt_content.vt_position_xy_record'( 1, 1 );
  4453.  
  4454.                     -- now erase all of virtual screen
  4455.                     erase_lines( 1, vt_content.height );
  4456.  
  4457.         END CASE;
  4458.  
  4459.     END erase_in_display;
  4460.  
  4461.     PRAGMA page;
  4462.     PROCEDURE erase_in_line    (selection : select_enumeration) IS
  4463.        temp_row : positive;
  4464.        line_len : natural;
  4465.        temp_col : positive;
  4466.     BEGIN
  4467.     -- raise exception uninitialized when terminal not open
  4468.  
  4469.         IF NOT initialized
  4470.         THEN
  4471.             RAISE uninitialized;
  4472.         END IF;
  4473.  
  4474.         temp_row := virtual_screen.active_position.row_position;
  4475.         temp_col := virtual_screen.active_position.col_position;
  4476.         line_len := virtual_screen.element( temp_row ).length;
  4477.  
  4478.         -- do nothing and get out quick when the active position is located
  4479.         -- out beyond the length of the current line.
  4480.  
  4481.         IF line_len < temp_col
  4482.         THEN GOTO quick_out;
  4483.         END IF;
  4484.  
  4485.         CASE selection IS
  4486.  
  4487.             WHEN from_xy_position_to_end =>
  4488.                 virtual_screen.element( temp_row ).length := temp_col-1;
  4489.  
  4490.             WHEN from_start_to_xy_position =>
  4491.                 virtual_screen.element( temp_row ).data(1..temp_col) :=
  4492.                   string'( 1..temp_col => ' ' );
  4493.  
  4494.                 FOR i IN 1..temp_col
  4495.                 LOOP
  4496.                     virtual_screen.element( temp_row ).
  4497.                       descriptors( i ).rendition :=
  4498.                       vt_content.sgpr;
  4499.                 END LOOP;
  4500.  
  4501.             WHEN all_positions =>
  4502.                 virtual_screen.element( temp_row ).length := 0;
  4503.         END CASE;
  4504.  
  4505. <<quick_out>>
  4506.         NULL;
  4507.  
  4508.     END erase_in_line;
  4509.  
  4510.     PRAGMA page;
  4511.     PROCEDURE enter_insert_mode IS
  4512.     BEGIN
  4513.  
  4514.     -- raise exception when terminal not open
  4515.         IF NOT initialized
  4516.         THEN
  4517.             RAISE uninitialized;
  4518.         END IF;
  4519.  
  4520.         virtual_screen.insert_mode := true;
  4521.  
  4522.     END enter_insert_mode;
  4523.  
  4524.     PRAGMA page;
  4525.     PROCEDURE exit_insert_mode IS
  4526.     BEGIN
  4527.     -- raise exception when terminal not open
  4528.  
  4529.         IF NOT  initialized
  4530.         THEN
  4531.             RAISE uninitialized;
  4532.         END IF;
  4533.  
  4534.         virtual_screen.insert_mode := false;
  4535.  
  4536.     END exit_insert_mode;
  4537.  
  4538.     PRAGMA page;
  4539.     PROCEDURE insert_line      (count     : IN     positive := 1) IS
  4540.         buffer : CONSTANT string := ansi_CSI &
  4541.                                     value_string( count ) & 'L';
  4542.         temp_row : positive := virtual_screen.active_position.row_position;
  4543.     BEGIN
  4544.     -- raise exception when terminal not open
  4545.  
  4546.         IF NOT initialized
  4547.         THEN
  4548.             RAISE uninitialized;
  4549.         END IF;
  4550.  
  4551.         IF count >= (vt_content.height - temp_row + 1)
  4552.         THEN
  4553.             FOR i IN temp_row..vt_content.height
  4554.             LOOP
  4555.                 virtual_screen.element( i ).length := 0;
  4556.                 virtual_screen.element( i ).corresponding_line := 0;
  4557.             END LOOP;
  4558.         ELSE
  4559.             virtual_screen.element( temp_row+count..vt_content.height ) :=
  4560.             virtual_screen.element( temp_row..vt_content.height-count );
  4561.             FOR i IN temp_row..temp_row+count-1
  4562.             LOOP
  4563.                 virtual_screen.element( i ).length := 0;
  4564.                 virtual_screen.element( i ).corresponding_line := 0;
  4565.             END LOOP;
  4566.         END IF;
  4567.  
  4568.     END insert_line;
  4569.  
  4570.     PRAGMA page;
  4571.     PROCEDURE select_graphic_rendition
  4572.                      (selection : IN     graphic_rendition_enumeration) IS
  4573.     BEGIN
  4574.  
  4575.     -- raise exception when terminal not open
  4576.  
  4577.         IF NOT initialized
  4578.         THEN
  4579.             RAISE uninitialized;
  4580.         END IF;
  4581.  
  4582.         CASE selection IS
  4583.                 WHEN primary_rendition =>
  4584.                      virtual_screen.current_rendition := vt_content.sgpr;
  4585.                 WHEN reverse_image =>
  4586.                      virtual_screen.current_rendition := vt_content.sgri;
  4587.                 WHEN no_image =>
  4588.                      virtual_screen.current_rendition := vt_content.sgno;
  4589.         END CASE;
  4590.  
  4591.     END select_graphic_rendition;
  4592.  
  4593.     PRAGMA page;
  4594.     PROCEDURE set_tab IS
  4595.     BEGIN
  4596.     -- raise exception when terminal not  open
  4597.  
  4598.         IF NOT initialized
  4599.         THEN
  4600.             RAISE uninitialized;
  4601.         END IF;
  4602.  
  4603.         virtual_screen.tabs( virtual_screen.active_position.col_position )
  4604.                 := true;
  4605.  
  4606.     END set_tab;
  4607.  
  4608.     PRAGMA page;
  4609.     PROCEDURE clear_tab IS
  4610.     BEGIN
  4611.     -- raise exception when terminal not open
  4612.  
  4613.         IF NOT initialized
  4614.         THEN
  4615.             RAISE uninitialized;
  4616.         END IF;
  4617.  
  4618.         virtual_screen.tabs( virtual_screen.active_position.col_position )
  4619.                 := false;
  4620.  
  4621.     END clear_tab;
  4622.  
  4623.     PRAGMA page;
  4624.     PROCEDURE tab       (count    : IN     positive := 1) IS
  4625.     temp_col : positive := virtual_screen.active_position.col_position;
  4626.     found_next_tab_stop : boolean := false;
  4627.     BEGIN
  4628.         -- raise exception when terminal not open
  4629.  
  4630.         IF NOT initialized
  4631.         THEN
  4632.             RAISE uninitialized;
  4633.         END IF;
  4634.  
  4635.         FOR i IN 1..count
  4636.         LOOP
  4637.           found_next_tab_stop := false ;
  4638.  
  4639.           -- find the next tab.  If there are no tabs set then do nothing.
  4640.           LOOP
  4641.             temp_col := temp_col + 1;
  4642.  
  4643.             IF virtual_screen.tabs( temp_col )
  4644.             THEN found_next_tab_stop := TRUE;
  4645.             END IF;
  4646.  
  4647.             EXIT WHEN found_next_tab_stop OR
  4648.                   (temp_col = vt_content.width);
  4649.           END LOOP;
  4650.  
  4651.           EXIT WHEN temp_col = vt_content.width ;
  4652.           virtual_screen.active_position.col_position := temp_col ;
  4653.  
  4654.         END LOOP ;
  4655.  
  4656.         IF found_next_tab_stop
  4657.         THEN
  4658.              virtual_screen.active_position.col_position := temp_col;
  4659.         END IF;
  4660.  
  4661.     END tab;
  4662.  
  4663.     PRAGMA page;
  4664.     PROCEDURE put (item     : IN     character) IS
  4665.         buffer : string( 1..1 );
  4666.     BEGIN
  4667.     -- raise exception when terminal not open
  4668.  
  4669.         IF NOT initialized
  4670.         THEN
  4671.              RAISE uninitialized;
  4672.         END IF;
  4673.  
  4674.         buffer( 1 ) := item;
  4675.         put( buffer ) ;
  4676.  
  4677.     END put;
  4678.  
  4679.     PRAGMA page;
  4680.     PROCEDURE put (item     : IN     string) IS
  4681.         item_len : positive;
  4682.         line_len : natural;
  4683.         temp_row : positive;
  4684.         temp_col : positive;
  4685.     BEGIN
  4686.     -- raise exception when terminal not open
  4687.  
  4688.         IF NOT initialized
  4689.         THEN
  4690.             RAISE uninitialized;
  4691.         END IF;
  4692.  
  4693.  
  4694.         item_len := item'length;
  4695.  
  4696.         temp_row := virtual_screen.active_position.row_position;
  4697.         temp_col := virtual_screen.active_position.col_position;
  4698.  
  4699.         line_len := virtual_screen.element( temp_row ).length;
  4700.  
  4701.         IF NOT virtual_screen.insert_mode
  4702.         THEN
  4703.             IF temp_col+item_len-1 > vt_content.width
  4704.             THEN item_len := vt_content.width - temp_col + 1;
  4705.             END IF;
  4706.         ELSE
  4707.             IF line_len+item_len > vt_content.width
  4708.             THEN
  4709.                 IF temp_col+item_len-1 > vt_content.width
  4710.                 THEN
  4711.                     line_len := temp_col - 1;
  4712.                     item_len := vt_content.width-temp_col + 1;
  4713.                 ELSE
  4714.                     line_len := vt_content.width-item_len;
  4715.                 END IF;
  4716.             END IF;
  4717.         END IF;
  4718.  
  4719.         IF temp_col > line_len
  4720.         THEN -- outside previous line boundary
  4721.             blank_columns( temp_row, line_len+1, temp_col-1 );
  4722.  
  4723.             virtual_screen.element( temp_row ).
  4724.                 data( temp_col..temp_col+item_len-1 ) :=
  4725.                 item( item'first..item'first+item_len-1 );
  4726.  
  4727.             FOR i IN temp_col..temp_col+item_len-1
  4728.             LOOP
  4729.                 virtual_screen.element( temp_row ).descriptors( i ).
  4730.                         rendition := virtual_screen.current_rendition;
  4731.             END LOOP;
  4732.             line_len := temp_col + item_len - 1;
  4733.  
  4734.             IF line_len/=vt_content.width
  4735.             THEN virtual_screen.active_position.col_position := line_len + 1;
  4736.             ELSE virtual_screen.active_position.col_position := line_len;
  4737.             END IF;
  4738.  
  4739.         ELSE
  4740.             IF NOT virtual_screen.insert_mode
  4741.             THEN -- no insert mode, intra line editing
  4742.                 virtual_screen.element( temp_row ).
  4743.                     data( temp_col..temp_col+item_len-1 ) :=
  4744.                     item( item'first..item'first+item_len-1 );
  4745.  
  4746.                 FOR i IN temp_col..temp_col+item_len-1
  4747.                 LOOP
  4748.                     virtual_screen.element( temp_row ).descriptors( i ).
  4749.                             rendition := virtual_screen.current_rendition;
  4750.                 END LOOP;
  4751.  
  4752.                 IF temp_col+item_len-1 > line_len
  4753.                 THEN line_len := temp_col + item_len - 1;
  4754.                 END IF;
  4755.  
  4756.                 IF virtual_screen.active_position.col_position +
  4757.                    item_len < vt_content.width
  4758.                 THEN virtual_screen.active_position.col_position :=
  4759.                     virtual_screen.active_position.col_position +
  4760.                        item_len;
  4761.                 ELSE virtual_screen.active_position.col_position :=
  4762.                         vt_content.width;
  4763.                 END IF;
  4764.  
  4765.             ELSE -- insert mode, intra line editing
  4766.  
  4767.                 virtual_screen.element( temp_row ).
  4768.                     data( temp_col+item_len..line_len+item_len ) :=
  4769.                   virtual_screen.element( temp_row ).
  4770.                     data( temp_col..line_len );
  4771.  
  4772.                 virtual_screen.element( temp_row ).
  4773.                     descriptors( temp_col+item_len..line_len+item_len ) :=
  4774.                     virtual_screen.element( temp_row ).
  4775.                     descriptors( temp_col..line_len );
  4776.  
  4777.                 virtual_screen.element( temp_row ).
  4778.                     data( temp_col..temp_col+item_len-1 ) :=
  4779.                     item( item'first..item'first+item_len-1 );
  4780.  
  4781.                 FOR i IN temp_col..temp_col+item_len-1
  4782.                 LOOP
  4783.                     virtual_screen.element( temp_row ).
  4784.                         descriptors( i ).rendition :=
  4785.                                 virtual_screen.current_rendition;
  4786.                 END LOOP;
  4787.  
  4788.                 line_len := line_len + item_len;
  4789.  
  4790.                 IF virtual_screen.active_position.col_position +
  4791.                    item_len < vt_content.width
  4792.                 THEN virtual_screen.active_position.col_position :=
  4793.                     virtual_screen.active_position.col_position +
  4794.                        item_len;
  4795.                 ELSE virtual_screen.active_position.col_position :=
  4796.                         vt_content.width;
  4797.                 END IF;
  4798.  
  4799.             END IF;
  4800.         END IF;
  4801.  
  4802.         virtual_screen.element( temp_row ).length := line_len;
  4803.  
  4804.     END put;
  4805.  
  4806.     PRAGMA page;
  4807.     PROCEDURE update_screen
  4808.                 ( top_line : IN positive;
  4809.                   bottom_line : IN positive ) IS
  4810.     BEGIN
  4811.  
  4812.     -- raise exception when terminal not open
  4813.  
  4814.         IF NOT initialized
  4815.         THEN
  4816.             RAISE uninitialized;
  4817.         END IF;
  4818.  
  4819.         IF driver.supported_functions( driver.insert_line_is ) AND
  4820.            driver.supported_functions( driver.delete_line_is )
  4821.         THEN
  4822.  
  4823.             redisplay.redisplay_screen_with_movement
  4824.                 ( actual_screen, virtual_screen, top_line, bottom_line );
  4825.  
  4826.             redisplay.fix_cursor
  4827.                         ( actual_screen, virtual_screen );
  4828.  
  4829.         ELSE
  4830.             redisplay.redisplay_screen_with_redraw
  4831.                 ( actual_screen, virtual_screen, top_line, bottom_line );
  4832.             redisplay.fix_cursor
  4833.                         ( actual_screen, virtual_screen );
  4834.         END IF;
  4835.  
  4836.     END update_screen;
  4837.  
  4838.     PRAGMA page;
  4839.     PROCEDURE update_line( the_line : IN positive ) IS
  4840.     BEGIN
  4841.  
  4842.     -- raise exception when terminal not open
  4843.  
  4844.         IF NOT initialized
  4845.         THEN
  4846.             RAISE uninitialized;
  4847.         END IF;
  4848.  
  4849.             redisplay.redisplay_line_with_redraw
  4850.                         ( actual_screen,
  4851.                           virtual_screen,
  4852.                           the_line,
  4853.                           the_line  );
  4854.             redisplay.fix_cursor
  4855.                         ( actual_screen,
  4856.                           virtual_screen );
  4857.  
  4858.     END update_line;
  4859.  
  4860.  
  4861.     PRAGMA page;
  4862.     PROCEDURE update_cursor IS
  4863.     BEGIN
  4864.  
  4865.     -- raise exception when terminal not open
  4866.  
  4867.         IF NOT initialized
  4868.         THEN
  4869.             RAISE uninitialized;
  4870.         END IF;
  4871.  
  4872.             redisplay.fix_cursor
  4873.                     ( actual_screen,
  4874.                       virtual_screen );
  4875.     END update_cursor;
  4876.  
  4877.     PRAGMA page;
  4878.     PROCEDURE redraw_screen IS
  4879.     BEGIN
  4880.  
  4881.     -- raise exception when terminal not open
  4882.  
  4883.         IF NOT initialized
  4884.         THEN
  4885.             RAISE uninitialized;
  4886.         END IF;
  4887.  
  4888.         redisplay.redraw_screen( actual_screen,
  4889.                                  virtual_screen,
  4890.                                  1,
  4891.                                  vt_content.height );
  4892.         redisplay.fix_cursor
  4893.                 ( actual_screen,
  4894.                  virtual_screen );
  4895.  
  4896.     END redraw_screen;
  4897.  
  4898.     PRAGMA page;
  4899.     FUNCTION valid_character( item : IN character ) RETURN boolean IS
  4900.     BEGIN
  4901.  
  4902.     -- raise exception when terminal not open
  4903.  
  4904.         IF NOT initialized
  4905.         THEN
  4906.             RAISE uninitialized;
  4907.         END IF;
  4908.  
  4909.         RETURN sysdep.valid_character( item );
  4910.  
  4911.     END valid_character;
  4912.  
  4913.     FUNCTION convert_key_enum( key_id : IN vt_input.function_key_enum )
  4914.                 RETURN function_key_enum IS
  4915.         temp_id : function_key_enum;
  4916.     BEGIN
  4917.         CASE key_id IS
  4918.         WHEN vt_input.up_arrow           => temp_id := up_arrow;
  4919.         WHEN vt_input.down_arrow         => temp_id := down_arrow;
  4920.         WHEN vt_input.left_arrow         => temp_id := left_arrow;
  4921.         WHEN vt_input.right_arrow        => temp_id := right_arrow;
  4922.         WHEN vt_input.f1                 => temp_id := f1;
  4923.         WHEN vt_input.f2                 => temp_id := f2;
  4924.         WHEN vt_input.f3                 => temp_id := f3;
  4925.         WHEN vt_input.f4                 => temp_id := f4;
  4926.         WHEN vt_input.f5                 => temp_id := f5;
  4927.         WHEN vt_input.f6                 => temp_id := f6 ;
  4928.         WHEN vt_input.f7                 => temp_id := f7 ;
  4929.         WHEN vt_input.f8                 => temp_id := f8 ;
  4930.         WHEN vt_input.f9                 => temp_id := f9 ;
  4931.         WHEN vt_input.f10                => temp_id := f10;
  4932.         WHEN vt_input.f11                => temp_id := f11;
  4933.         WHEN vt_input.f12                => temp_id := f12;
  4934.         WHEN vt_input.f13                => temp_id := f13;
  4935.         WHEN vt_input.f14                => temp_id := f14;
  4936.         WHEN vt_input.f15                => temp_id := f15;
  4937.         WHEN vt_input.f16                => temp_id := f16;
  4938.         WHEN vt_input.f17                => temp_id := f17;
  4939.         WHEN vt_input.f18                => temp_id := f18;
  4940.         WHEN vt_input.f19                => temp_id := f19;
  4941.         WHEN vt_input.f20                => temp_id := f20;
  4942.         WHEN vt_input.f21                => temp_id := f21;
  4943.         WHEN vt_input.f22                => temp_id := f22;
  4944.         WHEN vt_input.f23                => temp_id := f23;
  4945.         WHEN vt_input.f24                => temp_id := f24;
  4946.         WHEN vt_input.f25                => temp_id := f25;
  4947.         WHEN vt_input.f26                => temp_id := f26;
  4948.         WHEN vt_input.f27                => temp_id := f27;
  4949.         WHEN vt_input.f28                => temp_id := f28;
  4950.         WHEN vt_input.f29                => temp_id := f29;
  4951.         WHEN vt_input.f30                => temp_id := f30;
  4952.         WHEN vt_input.f31                => temp_id := f31;
  4953.         WHEN vt_input.f32                => temp_id := f32;
  4954.         WHEN OTHERS => NULL;
  4955.         END CASE;
  4956.  
  4957.         RETURN temp_id;
  4958.  
  4959.     END convert_key_enum;
  4960.  
  4961.     FUNCTION convert_key_enum( key_id : IN function_key_enum )
  4962.                 RETURN vt_input.function_key_enum IS
  4963.         temp_id : vt_input.function_key_enum;
  4964.     BEGIN
  4965.         CASE key_id IS
  4966.         WHEN up_arrow           => temp_id := vt_input.up_arrow;
  4967.         WHEN down_arrow         => temp_id := vt_input.down_arrow;
  4968.         WHEN left_arrow         => temp_id := vt_input.left_arrow;
  4969.         WHEN right_arrow        => temp_id := vt_input.right_arrow;
  4970.         WHEN f1                 => temp_id := vt_input.f1;
  4971.         WHEN f2                 => temp_id := vt_input.f2;
  4972.         WHEN f3                 => temp_id := vt_input.f3;
  4973.         WHEN f4                 => temp_id := vt_input.f4;
  4974.         WHEN f5                 => temp_id := vt_input.f5;
  4975.         WHEN f6                 => temp_id := vt_input.f6 ;
  4976.         WHEN f7                 => temp_id := vt_input.f7 ;
  4977.         WHEN f8                 => temp_id := vt_input.f8 ;
  4978.         WHEN f9                 => temp_id := vt_input.f9 ;
  4979.         WHEN f10                => temp_id := vt_input.f10;
  4980.         WHEN f11                => temp_id := vt_input.f11;
  4981.         WHEN f12                => temp_id := vt_input.f12;
  4982.         WHEN f13                => temp_id := vt_input.f13;
  4983.         WHEN f14                => temp_id := vt_input.f14;
  4984.         WHEN f15                => temp_id := vt_input.f15;
  4985.         WHEN f16                => temp_id := vt_input.f16;
  4986.         WHEN f17                => temp_id := vt_input.f17;
  4987.         WHEN f18                => temp_id := vt_input.f18;
  4988.         WHEN f19                => temp_id := vt_input.f19;
  4989.         WHEN f20                => temp_id := vt_input.f20;
  4990.         WHEN f21                => temp_id := vt_input.f21;
  4991.         WHEN f22                => temp_id := vt_input.f22;
  4992.         WHEN f23                => temp_id := vt_input.f23;
  4993.         WHEN f24                => temp_id := vt_input.f24;
  4994.         WHEN f25                => temp_id := vt_input.f25;
  4995.         WHEN f26                => temp_id := vt_input.f26;
  4996.         WHEN f27                => temp_id := vt_input.f27;
  4997.         WHEN f28                => temp_id := vt_input.f28;
  4998.         WHEN f29                => temp_id := vt_input.f29;
  4999.         WHEN f30                => temp_id := vt_input.f30;
  5000.         WHEN f31                => temp_id := vt_input.f31;
  5001.         WHEN f32                => temp_id := vt_input.f32;
  5002.         WHEN OTHERS => NULL;
  5003.         END CASE;
  5004.  
  5005.         RETURN temp_id;
  5006.  
  5007.     END convert_key_enum;
  5008.  
  5009.     PROCEDURE convert_descriptor( keys : IN function_key_descriptor;
  5010.                         key_temp : OUT vt_input.function_key_descriptor ) IS
  5011.     BEGIN
  5012.         key_temp.no_of_keys := keys.no_of_keys;
  5013.         FOR i IN 1..keys.no_of_keys
  5014.         LOOP
  5015.             key_temp.keys( i ).key := convert_key_enum( keys.keys( i ).key );
  5016.             key_temp.keys( i ).position := keys.keys( i ).position;
  5017.         END LOOP;
  5018.     END convert_descriptor;
  5019.  
  5020.     PROCEDURE convert_descriptor( keys : IN vt_input.function_key_descriptor;
  5021.                 key_temp : OUT function_key_descriptor ) IS
  5022.     BEGIN
  5023.         key_temp.no_of_keys := keys.no_of_keys;
  5024.         FOR i IN 1..keys.no_of_keys
  5025.         LOOP
  5026.             key_temp.keys( i ).key := convert_key_enum( keys.keys( i ).key );
  5027.             key_temp.keys( i ).position := keys.keys( i ).position;
  5028.         END LOOP;
  5029.     END convert_descriptor;
  5030.  
  5031.  
  5032.     PRAGMA page;
  5033.     PROCEDURE get( data : OUT string;
  5034.                    last : OUT natural;
  5035.                    keys : OUT function_key_descriptor;
  5036.                    timeout : IN  duration := duration'last ) IS
  5037.         key_temp : vt_input.function_key_descriptor( 32 );
  5038.     BEGIN
  5039.      -- raise exception when terminal not open
  5040.  
  5041.         IF NOT initialized
  5042.         THEN
  5043.              RAISE uninitialized;
  5044.         END IF;
  5045.  
  5046.         vt_input.get( data,
  5047.                       last,
  5048.                       key_temp,
  5049.                       timeout );
  5050.  
  5051.         convert_descriptor( key_temp, keys );
  5052.  
  5053.     END get;
  5054.  
  5055.     PRAGMA page;
  5056.     FUNCTION function_count(keys : IN function_key_descriptor)
  5057.         RETURN natural IS
  5058.  
  5059.         key_temp : vt_input.function_key_descriptor( 32 );
  5060.     BEGIN
  5061.          IF NOT  initialized
  5062.          THEN
  5063.              RAISE uninitialized;
  5064.          END IF;
  5065.  
  5066.         convert_descriptor( keys, key_temp );
  5067.         RETURN vt_input.function_count( key_temp );
  5068.  
  5069.     END function_count;
  5070.  
  5071.     PRAGMA page;
  5072.     PROCEDURE function_key(keys           : IN     function_key_descriptor;
  5073.                            index          : IN     positive;
  5074.                            key_identifier :    OUT function_key_enum;
  5075.                         previous_position :    OUT natural) IS
  5076.         key_temp : vt_input.function_key_descriptor( 32 );
  5077.     id_temp : vt_input.function_key_enum;
  5078.     BEGIN
  5079.     -- raise exception when terminal not open
  5080.  
  5081.         IF NOT initialized
  5082.         THEN
  5083.             RAISE uninitialized;
  5084.         END IF;
  5085.  
  5086.         convert_descriptor( keys, key_temp );
  5087.         vt_input.function_key( key_temp,
  5088.                                index,
  5089.                                id_temp,
  5090.                                previous_position );
  5091.         key_identifier := convert_key_enum( id_temp );
  5092.  
  5093.     END function_key;
  5094.  
  5095.     PRAGMA page;
  5096.     PROCEDURE function_key_name
  5097.       ( key_identifier : IN function_key_enum;
  5098.         key_name : OUT string;
  5099.         last : OUT natural) IS
  5100.         key_temp : vt_input.function_key_enum;
  5101.     BEGIN
  5102.     -- raise exception when terminal not open
  5103.  
  5104.         IF NOT initialized
  5105.         THEN
  5106.             RAISE uninitialized;
  5107.         END IF;
  5108.  
  5109.         key_temp := convert_key_enum( key_identifier );
  5110.  
  5111.         vt_input.function_key_name( key_temp,
  5112.                                     key_name,
  5113.                                     last );
  5114.  
  5115.     END function_key_name;
  5116.  
  5117.     PRAGMA page;
  5118.     PROCEDURE bell IS
  5119.         buffer : string( 1..1 );
  5120.     BEGIN
  5121.      -- raise exception when terminal not open
  5122.  
  5123.         IF NOT initialized
  5124.         THEN
  5125.               RAISE uninitialized;
  5126.         END IF;
  5127.  
  5128.         buffer( 1 ) := ascii.bel;
  5129.         driver.interpret( buffer );
  5130.  
  5131.     END bell;
  5132.  
  5133. END page_terminal;
  5134. ::::::::::
  5135. form_body.ada
  5136. ::::::::::
  5137. -- -----------------------------------------------------------------------------
  5138. -- ABSTRACT:  A user's program may WITH this package to provide a device-
  5139. --            independent terminal interface that is functionally equivalent to
  5140. --            a form terminal.
  5141. --            The display of a form-mode terminal is divided into qualified
  5142. --            areas that have the same attributes.  The user program defines
  5143. --            qualified areas on the virtual display by making calls on
  5144. --            form_terminal.set_position and form_terminal.define_qualified_area
  5145. --            A call upon form_terminal.activate_form will map the virtual
  5146. --            display into the actual terminal display and allow editing of the
  5147. --            form without user program intervention.  When the user has
  5148. --            finished editing the form the user presses a function key (as
  5149. --            defined in the terminal capabilities file) which returns control
  5150. --            to the user's program.
  5151. -- ----------------------------------------------------------------------------
  5152.  
  5153. WITH
  5154.      vt_input,
  5155.      vt_content ,
  5156.      driver ;
  5157.  
  5158. USE
  5159.      vt_content ;
  5160.  
  5161. PACKAGE BODY form_terminal IS
  5162.  
  5163.     ansi_CSI : CONSTANT STRING(1..2) := ascii.esc & '[' ;
  5164.  
  5165.     actual_screen,
  5166.     virtual_screen : vt_content.vt_content_access ;
  5167.     form_is_modified : BOOLEAN := FALSE ;
  5168.     number_of_qualified_areas : NATURAL := 0 ;
  5169.     function_key_struck : vt_input.function_key_enum ;
  5170.     function_key_struck_last : natural ;
  5171.     initialized : boolean := false ;
  5172.  
  5173.     PRAGMA page;
  5174.  
  5175.     FUNCTION value_string( value : IN positive ) RETURN STRING IS
  5176.        value_image : CONSTANT STRING := positive'image( value ) ;
  5177.     BEGIN
  5178.        RETURN value_image( (value_image'first +1)..(value_image'last) ) ;
  5179.     END value_string ;
  5180.  
  5181.     PROCEDURE next_position( row, col : IN OUT POSITIVE )  IS
  5182.  
  5183.     BEGIN
  5184.        col := col + 1 ;
  5185.        IF col > vt_content.width
  5186.        THEN  col := 1 ;
  5187.              row := row + 1 ;
  5188.        END IF ;
  5189.        IF row > vt_content.height
  5190.        THEN  row := 1 ;
  5191.        END IF ;
  5192.  
  5193.     END next_position ;
  5194.  
  5195.     PROCEDURE  previous_position ( row, col : IN OUT positive) IS
  5196.     BEGIN
  5197.          IF col = 1
  5198.          THEN
  5199.              col := vt_content.width ;
  5200.              IF row = 1
  5201.              THEN                               --stepping back
  5202.                  row := vt_content.height ;     --up the screen with
  5203.              ELSE                               --line and screen
  5204.                  row := row - 1 ;               --wrap
  5205.              END IF ;
  5206.          ELSE
  5207.              col := col - 1 ;
  5208.          END IF ;
  5209.  
  5210.     END previous_position ;
  5211.     PRAGMA page ;
  5212.  
  5213.     PROCEDURE blank_columns( row : IN positive ;
  5214.                        start_col : IN natural  ;
  5215.                         stop_col : IN natural ) IS
  5216.     BEGIN
  5217.         FOR i IN start_col..stop_col
  5218.         LOOP
  5219.            virtual_screen.element(row).data(i) := ' ' ;
  5220.         END LOOP ;
  5221.     END blank_columns ;
  5222.  
  5223.  
  5224.     PROCEDURE  back_tab  IS
  5225.  
  5226.     temp_row : positive := virtual_screen.active_position.row_position ;
  5227.     temp_col : positive := virtual_screen.active_position.col_position ;
  5228.     found_qualifier_head : BOOLEAN := FALSE ;
  5229.  
  5230.     BEGIN
  5231.         LOOP
  5232.            IF virtual_screen.element(temp_row).descriptors(temp_col).
  5233.                 qualifier_head
  5234.            THEN
  5235.                 found_qualifier_head := TRUE ;
  5236.            END IF ;
  5237.  
  5238.            EXIT WHEN  found_qualifier_head ;
  5239.  
  5240.            previous_position(temp_row, temp_col) ;
  5241.         END LOOP ;
  5242.  
  5243.         virtual_screen.active_position.row_position := temp_row ;
  5244.         virtual_screen.active_position.col_position := temp_col ;
  5245.     END back_tab ;
  5246.     PRAGMA page ;
  5247.  
  5248.  
  5249.     PROCEDURE open( name : IN  string := "none") IS
  5250.     ansi_EDa : string(1..4) := ansi_CSI & "2J" ;
  5251.  
  5252.  
  5253.     BEGIN
  5254.         --
  5255.         driver.vt_initialize( name, vt_content.height, vt_content.width) ;
  5256.  
  5257.         IF NOT (driver.supported_functions(driver.erase_to_end_of_screen_is)
  5258.            AND  driver.supported_functions(driver.erase_to_end_of_line_is)
  5259.            AND  driver.supported_functions(driver.move_the_cursor_is))
  5260.         THEN
  5261.             RAISE  terminal_too_primitive ;
  5262.         END IF ;
  5263.  
  5264.         actual_screen := NEW vt_content.vt_content_record ;
  5265.         virtual_screen := NEW vt_content.vt_content_record ;
  5266.  
  5267.         FOR i IN 1..vt_content.height
  5268.            LOOP
  5269.              virtual_screen.element(i).length := 0 ;
  5270.              FOR j IN 1..vt_content.width
  5271.                 LOOP
  5272.                   virtual_screen.element(i).descriptors(j).
  5273.                     qualifier_head := FALSE ;
  5274.                   virtual_screen.element(i).descriptors(j).
  5275.                     rendition := vt_content.sgpr ;
  5276.                   virtual_screen.element(i).descriptors(j).
  5277.                     qualifiers:= vt_content.dqnn ;
  5278.  
  5279.                 END LOOP ;
  5280.  
  5281.            END LOOP ;
  5282.         initialized := true ;
  5283.         driver.interpret( ansi_EDa ) ;    -- erase display
  5284.  
  5285.         actual_screen.ALL := virtual_screen.ALL ;
  5286.  
  5287.     EXCEPTION
  5288.        WHEN driver.uninitialized  => RAISE uninitialized ;
  5289.        WHEN driver.tcf_error   => RAISE  tcf_error  ;
  5290.        WHEN driver.unsupported_terminal => RAISE  unsupported_terminal ;
  5291.  
  5292.     END open;
  5293.     PRAGMA page ;
  5294.  
  5295.     PROCEDURE close IS
  5296.     ansi_SGP : CONSTANT string( 1..4 ) := string'( ascii.esc & "[0m" );
  5297.     BEGIN
  5298.  
  5299.         IF NOT initialized
  5300.         THEN  RAISE uninitialized ;
  5301.         END IF ;
  5302.  
  5303.         IF driver.supported_functions( driver.highlight_is )
  5304.         THEN
  5305.             CASE actual_screen.current_rendition IS
  5306.             WHEN vt_content.sgpr  => NULL;
  5307.             WHEN vt_content.sgri  => driver.interpret( ansi_SGP );
  5308.             WHEN vt_content.sgno  => NULL;
  5309.             END CASE;
  5310.         END IF;
  5311.  
  5312.         initialized := false ;
  5313.         driver.close_virtual_terminal ;
  5314.  
  5315.     END close;
  5316.     PRAGMA page ;
  5317.  
  5318.     PROCEDURE set_position (position : IN     xy_position) IS
  5319.  
  5320.     buffer : CONSTANT STRING := ansi_CSI &
  5321.                         value_string( position.line ) & ';' &
  5322.                         value_string( position.column) & 'H' ;
  5323.  
  5324.     temp_lin : positive := position.line ;
  5325.     temp_col : positive := position.column ;
  5326.  
  5327.     BEGIN
  5328.  
  5329.       IF NOT initialized
  5330.       THEN  RAISE uninitialized ;
  5331.       END IF ;
  5332.  
  5333.       -- if either line or column is greater than max, then
  5334.       -- set to max and continue
  5335.  
  5336.       IF temp_lin > vt_content.height
  5337.       THEN
  5338.           temp_lin := vt_content.height ;
  5339.       END IF ;
  5340.  
  5341.       IF temp_col > vt_content.width
  5342.       THEN
  5343.           temp_col := vt_content.width ;
  5344.       END IF ;
  5345.  
  5346.       -- change virtual representation
  5347.  
  5348.       virtual_screen.active_position := vt_content.
  5349.                    vt_position_xy_record'( temp_lin, temp_col ) ;
  5350.  
  5351.  
  5352.     END set_position;
  5353.     PRAGMA page ;
  5354.  
  5355.     FUNCTION  position RETURN xy_position IS
  5356.     BEGIN
  5357.  
  5358.         IF NOT initialized
  5359.         THEN  RAISE uninitialized ;
  5360.         END IF ;
  5361.  
  5362.         RETURN xy_position'( virtual_screen.active_position.row_position,
  5363.                              virtual_screen.active_position.col_position ) ;
  5364.  
  5365.  
  5366.     END  position;
  5367.     PRAGMA page ;
  5368.  
  5369.     FUNCTION  size RETURN xy_position IS
  5370.     BEGIN
  5371.  
  5372.         IF NOT initialized
  5373.         THEN  RAISE uninitialized ;
  5374.         END IF ;
  5375.  
  5376.         RETURN xy_position'( vt_content.height, vt_content.width ) ;
  5377.  
  5378.     END  size;
  5379.     PRAGMA page ;
  5380.  
  5381.     PROCEDURE define_qualified_area
  5382.                      (intensity  : IN     area_intensity  := normal;
  5383.                       protection : IN     area_protection := protected;
  5384.                       input      : IN     area_input
  5385.                                                := graphic_characters ) IS
  5386.  
  5387.     temp_row : positive := virtual_screen.active_position.row_position ;
  5388.     temp_col : positive := virtual_screen.active_position.col_position ;
  5389.     acceptable_input : vt_content.area_qualifiers_enum ;
  5390.     area_intensity : vt_content.graphic_rendition_enum ;
  5391.     prev_field_ri : boolean := false ;
  5392.     line_length : natural ;
  5393.  
  5394.     BEGIN
  5395.  
  5396.         IF NOT initialized
  5397.         THEN  RAISE uninitialized ;
  5398.         END IF ;
  5399.  
  5400.       IF virtual_screen.element(temp_row).descriptors(temp_col).
  5401.           rendition = vt_content.sgri
  5402.       THEN
  5403.           prev_field_ri := TRUE  ;
  5404.           line_length := temp_col - 1 ;
  5405.       END IF ;
  5406.  
  5407.       virtual_screen.element(temp_row).descriptors(temp_col)
  5408.             .qualifier_head := TRUE ;
  5409.  
  5410.       -- qualifier head is always primary rendition and protected
  5411.       -- and blank
  5412.       virtual_screen.element(temp_row).data(temp_col) := ' ' ;
  5413.  
  5414.       CASE  intensity  IS
  5415.             WHEN  normal => area_intensity := vt_content.sgpr ;
  5416.  
  5417.             WHEN  none   => area_intensity := vt_content.sgno ;
  5418.  
  5419.             WHEN  high   => area_intensity := vt_content.sgri ;
  5420.  
  5421.       END CASE ;
  5422.  
  5423.       -- if reverse image, put blanks from present length to qual. head
  5424.       --
  5425.       IF area_intensity = vt_content.sgri
  5426.       THEN
  5427.          FOR i IN virtual_screen.element(temp_row).length + 1..
  5428.                   temp_col - 1
  5429.          LOOP
  5430.             virtual_screen.element(temp_row).data(i) := ' ' ;
  5431.          END LOOP ;
  5432.       END IF ;
  5433.  
  5434.       virtual_screen.element(temp_row).descriptors(temp_col)
  5435.             .rendition := vt_content.sgpr ;
  5436.       virtual_screen.element(temp_row).descriptors(temp_col)
  5437.             .qualifiers := vt_content.dqnn ;
  5438.       next_position( temp_row, temp_col ) ;
  5439.  
  5440.       number_of_qualified_areas := number_of_qualified_areas + 1 ;
  5441.  
  5442.       -- set protection of qualified area
  5443.  
  5444.       IF protection = protected
  5445.       THEN
  5446.          -- accept no input
  5447.          acceptable_input := vt_content.dqnn ;
  5448.       ELSE
  5449.          --  area is unprotected, set the type of characters allowed
  5450.          --  in the qualified area
  5451.  
  5452.          CASE input IS
  5453.               WHEN  graphic_characters   =>
  5454.                       -- accept graphic characters
  5455.                       acceptable_input := vt_content.dqag ;
  5456.  
  5457.               WHEN  numerics =>
  5458.                       -- accept numeric characters
  5459.                       acceptable_input := vt_content.dqan ;
  5460.  
  5461.               WHEN  OTHERS   =>  NULL ;
  5462.          END CASE ;
  5463.  
  5464.       --  set the intensity allowed in the qualified area
  5465.  
  5466.       END IF ;
  5467.  
  5468.  
  5469.       -- put attributes in all positions of qualified area
  5470.  
  5471.       LOOP
  5472.          EXIT WHEN
  5473.              virtual_screen.element(temp_row).descriptors(temp_col).
  5474.              qualifier_head ;
  5475.  
  5476.          virtual_screen.element(temp_row).descriptors(temp_col).
  5477.             qualifiers := acceptable_input ;
  5478.  
  5479.          virtual_screen.element(temp_row).descriptors(temp_col).
  5480.             rendition  := area_intensity   ;
  5481.  
  5482.          IF (area_intensity = vt_content.sgri) AND (virtual_screen.
  5483.              element(temp_row).length < temp_col)
  5484.          THEN
  5485.              virtual_screen.element(temp_row).data(temp_col) := ' ' ;
  5486.              virtual_screen.element(temp_row).length := temp_col ;
  5487.          END IF ;
  5488.  
  5489.          IF (prev_field_ri) AND (area_intensity /= vt_content.sgri)
  5490.          THEN
  5491.              IF virtual_screen.element(temp_row).data(temp_col) /= ' '
  5492.              THEN  line_length := temp_col ;
  5493.              END IF ;
  5494.  
  5495.              IF temp_col = vt_content.width
  5496.              THEN
  5497.                  virtual_screen.element(temp_row).length := line_length ;
  5498.                  line_length := 0 ;
  5499.              END IF ;
  5500.          END IF ;
  5501.  
  5502.          next_position(temp_row, temp_col) ;
  5503.  
  5504.       END LOOP ;
  5505.  
  5506.       IF (prev_field_ri) and (area_intensity /= vt_content.sgri)
  5507.           and (temp_col > virtual_screen.element(temp_row).length)
  5508.       THEN
  5509.           virtual_screen.element(temp_row).length := line_length ;
  5510.       END IF ;
  5511.  
  5512.  
  5513.       END define_qualified_area ;
  5514.       PRAGMA page ;
  5515.  
  5516.  
  5517.     PROCEDURE clear_qualified_area IS
  5518.       temp_qualifiers : vt_content.area_qualifiers_enum ;
  5519.       temp_rendition  : vt_content.graphic_rendition_enum ;
  5520.       temp_row : positive ;
  5521.       temp_col : positive ;
  5522.  
  5523.     BEGIN
  5524.        IF NOT initialized
  5525.        THEN  RAISE uninitialized ;
  5526.        END IF ;
  5527.  
  5528.        IF number_of_qualified_areas > 0
  5529.        THEN
  5530.            back_tab ;
  5531.            temp_row := virtual_screen.active_position.row_position ;
  5532.            temp_col := virtual_screen.active_position.col_position ;
  5533.            virtual_screen.element(temp_row).descriptors(temp_col).
  5534.                qualifier_head := FALSE ;
  5535.  
  5536.            IF number_of_qualified_areas = 1
  5537.            THEN  --special case, set screen to protected
  5538.                  --and primary rendition
  5539.  
  5540.                FOR i IN 1..vt_content.height LOOP
  5541.                   FOR j IN 1..vt_content.width LOOP
  5542.  
  5543.                       virtual_screen.element(i).descriptors(j).
  5544.                          rendition := vt_content.sgpr ;
  5545.                       virtual_screen.element(i).descriptors(j).
  5546.                          qualifiers := vt_content.dqnn ;
  5547.  
  5548.                   END LOOP ;
  5549.                END LOOP ;
  5550.  
  5551.            ELSE
  5552.                --get previous areas attributes
  5553.                previous_position(temp_row, temp_col) ;
  5554.  
  5555.                temp_qualifiers := virtual_screen.element(temp_row).
  5556.                  descriptors(temp_col).qualifiers ;
  5557.                temp_rendition  := virtual_screen.element(temp_row).
  5558.                  descriptors(temp_col).rendition  ;
  5559.  
  5560.                --get back to the correct position
  5561.                next_position(temp_row, temp_col) ;
  5562.                LOOP
  5563.                   virtual_screen.element(temp_row).descriptors
  5564.                     (temp_col).qualifiers := temp_qualifiers ;
  5565.                   virtual_screen.element(temp_row).descriptors
  5566.                     (temp_col).rendition  := temp_rendition  ;
  5567.  
  5568.                   next_position(temp_row, temp_col) ;
  5569.                   EXIT WHEN virtual_screen.element(temp_row).
  5570.                         descriptors(temp_col).qualifier_head ;
  5571.                END LOOP ;
  5572.  
  5573.            END IF ;
  5574.            number_of_qualified_areas := number_of_qualified_areas - 1 ;
  5575.        END IF ;
  5576.  
  5577.     END clear_qualified_area;
  5578.     PRAGMA page ;
  5579.  
  5580.     PROCEDURE tab IS
  5581.  
  5582.     temp_row : positive := virtual_screen.active_position.row_position ;
  5583.     temp_col : positive := virtual_screen.active_position.col_position ;
  5584.     found_next_qual_area : boolean := false ;
  5585.     all_positions_checked: natural := vt_content.height * vt_content.width ;
  5586.  
  5587.     BEGIN
  5588.  
  5589.       IF NOT initialized
  5590.       THEN  RAISE uninitialized ;
  5591.       END IF ;
  5592.  
  5593.       IF  number_of_qualified_areas > 0
  5594.       THEN
  5595.          LOOP
  5596.  
  5597.             -- move to the next position
  5598.             next_position( temp_row, temp_col ) ;
  5599.  
  5600.             IF virtual_screen.element(temp_row).descriptors(temp_col)
  5601.                 .qualifier_head
  5602.             THEN
  5603.                 found_next_qual_area := true ;
  5604.             END IF ;
  5605.  
  5606.             EXIT  WHEN  found_next_qual_area ;
  5607.  
  5608.          END LOOP ;
  5609.  
  5610.          IF  found_next_qual_area
  5611.          THEN
  5612.  
  5613.             virtual_screen.active_position.row_position := temp_row ;
  5614.             virtual_screen.active_position.col_position := temp_col ;
  5615.  
  5616.          END IF ;
  5617.  
  5618.       END IF ;
  5619.  
  5620.     END tab;
  5621.     PRAGMA page ;
  5622.  
  5623.     PROCEDURE put (item     : IN     character) IS
  5624.       buffer : STRING( 1..1 ) ;
  5625.  
  5626.     BEGIN
  5627.  
  5628.         IF NOT initialized
  5629.         THEN  RAISE uninitialized ;
  5630.         END IF ;
  5631.  
  5632.         buffer( 1 ) := item ;
  5633.         put(buffer) ;
  5634.  
  5635.     END put;
  5636.     PRAGMA page ;
  5637.  
  5638.     PROCEDURE put (item     : IN     string) IS
  5639.     temp_row : positive := virtual_screen.active_position.row_position ;
  5640.     temp_col : positive := virtual_screen.active_position.col_position ;
  5641.  
  5642.     BEGIN
  5643.  
  5644.         IF NOT initialized
  5645.         THEN  RAISE uninitialized ;
  5646.         END IF ;
  5647.  
  5648.         blank_columns( temp_row, virtual_screen.element(temp_row)
  5649.                .length + 1 , temp_col - 1 ) ;
  5650.  
  5651.         FOR i IN 1..item'LENGTH
  5652.         LOOP
  5653.            virtual_screen.element(temp_row).data(temp_col) :=
  5654.              item(i) ;
  5655.  
  5656.            IF temp_col = vt_content.width
  5657.            THEN virtual_screen.element(temp_row).length :=
  5658.                   vt_content.width ;
  5659.            END IF ;
  5660.  
  5661.            next_position( temp_row, temp_col ) ;
  5662.         END LOOP ;
  5663.  
  5664.         -- reset the line length if need be
  5665.  
  5666.         IF virtual_screen.element(temp_row).length < temp_col - 1
  5667.         THEN virtual_screen.element(temp_row).length := temp_col - 1;
  5668.         END IF ;
  5669.  
  5670.         -- set  active position
  5671.  
  5672.         virtual_screen.active_position.row_position := temp_row ;
  5673.         virtual_screen.active_position.col_position := temp_col ;
  5674.  
  5675.  
  5676.     END put;
  5677.     PRAGMA page ;
  5678.  
  5679.     PROCEDURE get (item     :    OUT character) IS
  5680.     buffer : string(1..1) ;
  5681.     BEGIN
  5682.  
  5683.         IF NOT initialized
  5684.         THEN  RAISE uninitialized ;
  5685.         END IF ;
  5686.  
  5687.         get( buffer ) ;
  5688.         item := buffer(1) ;
  5689.  
  5690.     END get;
  5691.     PRAGMA page ;
  5692.  
  5693.     PROCEDURE get (item     :    OUT string) IS
  5694.     temp_row : positive := virtual_screen.active_position.row_position ;
  5695.     temp_col : positive := virtual_screen.active_position.col_position ;
  5696.     pad_it : BOOLEAN := false ;
  5697.     i : natural ;
  5698.  
  5699.     BEGIN
  5700.  
  5701.         IF NOT initialized
  5702.         THEN  RAISE uninitialized ;
  5703.         END IF ;
  5704.  
  5705.         FOR i IN item'FIRST..item'LAST
  5706.            LOOP
  5707.              IF virtual_screen.element(temp_row).length < temp_col
  5708.              THEN  EXIT ;
  5709.                    pad_it := true ;
  5710.              END IF ;
  5711.  
  5712.              item( i ) := virtual_screen.element(temp_row).
  5713.                       data(temp_col) ;
  5714.              next_position( temp_row, temp_col ) ;
  5715.  
  5716.            END LOOP ;
  5717.  
  5718.         -- pad the output string, if necessary
  5719.  
  5720.         IF pad_it
  5721.         THEN
  5722.            FOR j IN i..item'LAST
  5723.            LOOP
  5724.               item(j) := ' ' ;
  5725.            END LOOP ;
  5726.         END IF ;
  5727.  
  5728.  
  5729.         -- move active position to next position
  5730.         next_position( temp_row, temp_col ) ;
  5731.         virtual_screen.active_position.row_position := temp_row ;
  5732.         virtual_screen.active_position.col_position := temp_col ;
  5733.  
  5734.     END get;
  5735.     PRAGMA page ;
  5736.  
  5737.     PROCEDURE erase_area IS
  5738.     space  : CONSTANT CHARACTER  := ' ' ;
  5739.  
  5740.     save_row,
  5741.     temp_row : natural := virtual_screen.active_position.row_position ;
  5742.     save_col,
  5743.     temp_col : natural := virtual_screen.active_position.col_position ;
  5744.     start_col,stop_col,start_row,stop_row : positive ;
  5745.  
  5746.     BEGIN
  5747.  
  5748.       IF NOT initialized
  5749.       THEN  RAISE uninitialized ;
  5750.       END IF ;
  5751.  
  5752.       IF number_of_qualified_areas = 0
  5753.       THEN
  5754.         FOR i IN 1..vt_content.height LOOP
  5755.            virtual_screen.element(i).length := 0 ;
  5756.         END LOOP ;
  5757.       ELSE
  5758.         -- find qualifier head and next qualifier head
  5759.         -- save these values
  5760.         back_tab ;
  5761.         start_row := virtual_screen.active_position.row_position ;
  5762.         start_col := virtual_screen.active_position.col_position ;
  5763.         tab ;
  5764.         stop_row := virtual_screen.active_position.row_position ;
  5765.         stop_col := virtual_screen.active_position.col_position ;
  5766.  
  5767.         IF start_row = stop_row
  5768.         THEN  -- next qual. area starts on the same line
  5769.               --
  5770.               IF virtual_screen.element(start_row).length < start_col
  5771.               THEN NULL ;
  5772.               ELSE
  5773.                    blank_columns(start_row, start_col, stop_col-1) ;
  5774.               END IF ;
  5775.         ELSE  -- next qual. area starts on a following line
  5776.               --
  5777.               -- First, blank out appropriate positions on the
  5778.               -- starting line
  5779.  
  5780.               IF virtual_screen.element(start_row).length > start_col
  5781.               THEN
  5782.                 virtual_screen.element(start_row).length :=start_col-1 ;
  5783.               END IF ;
  5784.  
  5785.               -- Then blank out all full lines between the two qual.
  5786.               -- heads, if any exist.
  5787.  
  5788.               temp_row := start_row ;
  5789.               LOOP
  5790.                  temp_row := temp_row + 1 ;
  5791.                  IF temp_row > vt_content.height
  5792.                  THEN temp_row := 1 ;
  5793.                  END IF ;
  5794.  
  5795.                  EXIT WHEN temp_row = stop_row ;
  5796.  
  5797.                  virtual_screen.element(temp_row).length := 0 ;
  5798.               END LOOP ;
  5799.  
  5800.               -- Finally, blank out appropriate positions on the line
  5801.               -- where the next qual. area begins
  5802.  
  5803.               IF virtual_screen.element(temp_row).length < stop_col
  5804.               THEN virtual_screen.element(temp_row).length := 0 ;
  5805.               ELSE
  5806.                    blank_columns(stop_row, 1, stop_col - 1) ;
  5807.               END IF ;
  5808.  
  5809.         END IF ;
  5810.  
  5811.       -- reset active position to original values
  5812.  
  5813.       virtual_screen.active_position.row_position := save_row ;
  5814.       virtual_screen.active_position.col_position := save_col ;
  5815.  
  5816.       END IF ;
  5817.  
  5818.     END erase_area;
  5819.     PRAGMA page ;
  5820.  
  5821.     PROCEDURE erase_display IS
  5822.     save_pos : vt_content.vt_position_xy_record := virtual_screen.
  5823.                  active_position ;
  5824.  
  5825.     BEGIN
  5826.  
  5827.       IF NOT initialized
  5828.       THEN  RAISE uninitialized ;
  5829.       END IF ;
  5830.  
  5831.        --set active position at (1, 1) and then
  5832.        --erase all lines
  5833.  
  5834.        virtual_screen.active_position := vt_content.
  5835.           vt_position_xy_record'(1, 1) ;
  5836.        FOR i IN 1..vt_content.height
  5837.           LOOP
  5838.              virtual_screen.element( i ).length := 0 ;
  5839.           END LOOP ;
  5840.  
  5841.        --clear all qualified areas on the virtual display
  5842.  
  5843.        FOR i IN 1..number_of_qualified_areas LOOP
  5844.           --tab to each qualified area and clear it
  5845.           --screen should be protected and primary rendition
  5846.           --when finished
  5847.  
  5848.           tab ;
  5849.           clear_qualified_area ;
  5850.        END LOOP ;
  5851.  
  5852.        -- reset active position
  5853.        virtual_screen.active_position := save_pos ;
  5854.  
  5855.     END erase_display ;
  5856.     PRAGMA page ;
  5857.  
  5858.     PROCEDURE activate_form IS SEPARATE ;
  5859.     PRAGMA page ;
  5860.  
  5861.     FUNCTION  is_form_updated RETURN boolean IS
  5862.     BEGIN
  5863.  
  5864.       IF NOT initialized
  5865.       THEN  RAISE uninitialized ;
  5866.       END IF ;
  5867.  
  5868.       RETURN form_is_modified ;
  5869.  
  5870.     END  is_form_updated;
  5871.     PRAGMA page ;
  5872.  
  5873.     FUNCTION area_qualifier_requires_space RETURN boolean IS
  5874.     BEGIN
  5875.  
  5876.       IF NOT initialized
  5877.       THEN  RAISE uninitialized ;
  5878.       END IF ;
  5879.  
  5880.       RETURN true ;
  5881.  
  5882.     END  area_qualifier_requires_space ;
  5883.     PRAGMA page ;
  5884.  
  5885.     FUNCTION  termination_key RETURN termination_key_range IS
  5886.     temp_value : termination_key_range ;
  5887.     BEGIN
  5888.  
  5889.       IF NOT initialized
  5890.       THEN  RAISE uninitialized ;
  5891.       END IF ;
  5892.  
  5893.       CASE  function_key_struck IS
  5894.  
  5895.         WHEN vt_input.f1                 => temp_value := 1;
  5896.         WHEN vt_input.f2                 => temp_value := 2;
  5897.         WHEN vt_input.f3                 => temp_value := 3;
  5898.         WHEN vt_input.f4                 => temp_value := 4;
  5899.         WHEN vt_input.f5                 => temp_value := 5;
  5900.         WHEN vt_input.f6                 => temp_value := 6;
  5901.         WHEN vt_input.f7                 => temp_value := 7;
  5902.         WHEN vt_input.f8                 => temp_value := 8 ;
  5903.         WHEN vt_input.f9                 => temp_value := 9 ;
  5904.         WHEN vt_input.f10                => temp_value := 10;
  5905.         WHEN vt_input.f11                => temp_value := 11;
  5906.         WHEN vt_input.f12                => temp_value := 12;
  5907.         WHEN vt_input.f13                => temp_value := 13;
  5908.         WHEN vt_input.f14                => temp_value := 14;
  5909.         WHEN vt_input.f15                => temp_value := 15;
  5910.         WHEN vt_input.f16                => temp_value := 16;
  5911.         WHEN vt_input.f17                => temp_value := 17;
  5912.         WHEN vt_input.f18                => temp_value := 18;
  5913.         WHEN vt_input.f19                => temp_value := 19;
  5914.         WHEN vt_input.f20                => temp_value := 20;
  5915.         WHEN vt_input.f21                => temp_value := 21;
  5916.         WHEN vt_input.f22                => temp_value := 22;
  5917.         WHEN vt_input.f23                => temp_value := 23;
  5918.         WHEN vt_input.f24                => temp_value := 24;
  5919.         WHEN vt_input.f25                => temp_value := 25;
  5920.         WHEN vt_input.f26                => temp_value := 26;
  5921.         WHEN vt_input.f27                => temp_value := 27;
  5922.         WHEN vt_input.f28                => temp_value := 28;
  5923.         WHEN vt_input.f29                => temp_value := 29;
  5924.         WHEN vt_input.f30                => temp_value := 30;
  5925.         WHEN vt_input.f31                => temp_value := 31;
  5926.         WHEN vt_input.f32                => temp_value := 32;
  5927.         WHEN OTHERS => NULL;
  5928.       END CASE ;
  5929.  
  5930.         RETURN (temp_value) ;
  5931.  
  5932.     END  termination_key;
  5933.     PRAGMA page ;
  5934.  
  5935.   BEGIN -- form_terminal
  5936.         NULL;
  5937. END form_terminal;
  5938. ::::::::::
  5939. activate_form.ada
  5940. ::::::::::
  5941. -- -----------------------------------------------------------------------------
  5942. -- ABSTRACT:  This procedure is part of the FORM_TERMINAL package.
  5943. --            A call upon form_terminal.activate_form will map the virtual
  5944. --            terminal display into the actual terminal display and allow
  5945. --            editing of the form without user program intervention.  When
  5946. --            the user has finished editing the form the user presses a
  5947. --            function key ( as defined in the terminal capabilities file)
  5948. --            which returns control to the user's program.
  5949. -- ----------------------------------------------------------------------------
  5950.  
  5951.   WITH
  5952.        driver,
  5953.        redisplay ,
  5954.        vt_input ;
  5955.  
  5956.   SEPARATE( form_terminal )
  5957.  
  5958.   PROCEDURE activate_form IS
  5959.  
  5960.      key_name : string(1..11) ;
  5961.      key_id : vt_input.function_key_enum ;
  5962.      prev_pos : natural ;
  5963.      leave_body : BOOLEAN := FALSE ;
  5964.      count : natural := 0 ;
  5965.      data : string(1..80) ;
  5966.      last : natural ;
  5967.      keys : vt_input.function_key_descriptor( 32 ) ;
  5968.      number_of_function_keys : natural ;
  5969.      last_position : natural ;
  5970.      i : positive ;
  5971.      bell : string(1..1) := string'(1 => ascii.bel) ;
  5972.  
  5973.      PROCEDURE handle_function_key ( key_id : IN vt_input.
  5974.                                          function_key_enum ;
  5975.                                   leave_body : OUT BOOLEAN  ) IS
  5976.  
  5977.      temp_row : positive := virtual_screen.active_position.row_position;
  5978.      temp_col : positive := virtual_screen.active_position.col_position;
  5979.  
  5980.      BEGIN
  5981.          IF key_id IN   vt_input.f1..vt_input.f32
  5982.          THEN
  5983.              leave_body := TRUE ;
  5984.          ELSE
  5985.              leave_body := FALSE;
  5986.              CASE  key_id  IS
  5987.  
  5988.                WHEN vt_input.up_arrow   =>
  5989.                                   IF temp_row = 1
  5990.                                   THEN temp_row := vt_content.height ;
  5991.                                   ELSE temp_row := temp_row - 1 ;
  5992.                                   END IF ;
  5993.  
  5994.                WHEN vt_input.down_arrow =>
  5995.                                   IF temp_row = vt_content.height
  5996.                                   THEN temp_row := 1 ;
  5997.                                   ELSE temp_row := temp_row + 1 ;
  5998.                                   END IF ;
  5999.  
  6000.                WHEN vt_input.left_arrow =>
  6001.                                   previous_position( temp_row, temp_col ) ;
  6002.  
  6003.                WHEN vt_input.right_arrow =>
  6004.                                   next_position( temp_row, temp_col ) ;
  6005.  
  6006.                WHEN OTHERS =>     NULL ;
  6007.  
  6008.              END CASE ;
  6009.  
  6010.              virtual_screen.active_position.row_position := temp_row ;
  6011.              virtual_screen.active_position.col_position := temp_col ;
  6012.  
  6013.              redisplay.fix_cursor( actual_screen, virtual_screen ) ;
  6014.  
  6015.          END IF ;
  6016.  
  6017.      END handle_function_key ;
  6018.      PRAGMA page ;
  6019.  
  6020.      PROCEDURE handle_string( data : IN string ;
  6021.                               last : IN natural ) IS
  6022.      top_line,
  6023.      bottom_line,
  6024.      temp_row : positive := virtual_screen.active_position.row_position ;
  6025.      temp_col : positive := virtual_screen.active_position.col_position ;
  6026.      ok : BOOLEAN ;
  6027.      count : NATURAL := 0 ;
  6028.      input_type : vt_content.area_qualifiers_enum ;
  6029.      save_row, save_col : positive ;
  6030.      only_cursor_movement : BOOLEAN := true ;
  6031.  
  6032.      BEGIN -- handle string
  6033.  
  6034.          FOR  i IN 1..last
  6035.          LOOP
  6036.             CASE  data(i)  IS
  6037.  
  6038.                WHEN ascii.cr =>
  6039.                                 temp_row := virtual_screen.active_position
  6040.                                  .row_position ;
  6041.                                 temp_col := virtual_screen.active_position
  6042.                                  .col_position ;
  6043.                                 temp_col := 1 ;
  6044.                                 IF temp_row = vt_content.height
  6045.                                 THEN temp_row := 1 ;
  6046.                                 ELSE temp_row := temp_row + 1 ;
  6047.                                 END IF ;
  6048.                                 virtual_screen.active_position.
  6049.                                   row_position:= temp_row ;
  6050.                                 virtual_screen.active_position.
  6051.                                   col_position:= temp_col ;
  6052.  
  6053.                WHEN ascii.del=> temp_row := virtual_screen.active_position
  6054.                                  .row_position ;
  6055.                                 temp_col := virtual_screen.active_position
  6056.                                  .col_position ;
  6057.  
  6058.                                 previous_position( temp_row, temp_col ) ;
  6059.                                 IF (virtual_screen.element(temp_row).
  6060.                                    descriptors(temp_col).qualifiers =
  6061.                                    vt_content.dqnn)
  6062.                                 THEN
  6063.                                    driver.interpret( bell ) ;
  6064.                                 ELSE
  6065.                                    form_is_modified := true ;
  6066.                                    virtual_screen.element(temp_row).data
  6067.                                    (temp_col) := ' ' ;
  6068.                                 END IF ;
  6069.  
  6070.                                 only_cursor_movement := false ;
  6071.                                 virtual_screen.active_position.
  6072.                                   row_position:= temp_row ;
  6073.                                 virtual_screen.active_position.
  6074.                                   col_position:= temp_col ;
  6075.  
  6076.                WHEN ascii.ht => count := 0 ;
  6077.                                 save_row := virtual_screen.active_position.
  6078.                                       row_position ;
  6079.                                 save_col := virtual_screen.active_position.
  6080.                                       col_position ;
  6081.                                 LOOP
  6082.                                   tab ;
  6083.  
  6084.                                   next_position(
  6085.                                     virtual_screen.active_position.
  6086.                                       row_position,
  6087.                                     virtual_screen.active_position.
  6088.                                      col_position ) ;
  6089.  
  6090.                                   IF virtual_screen.element(
  6091.                                    virtual_screen.active_position.
  6092.                                    row_position).descriptors(virtual_screen.
  6093.                                    active_position.col_position).
  6094.                                    qualifier_head
  6095.                                   THEN
  6096.                                      -- special case, two qualiifer heads
  6097.                                      -- in immediate succession
  6098.                                      next_position(
  6099.                                       virtual_screen.active_position.
  6100.                                       row_position,
  6101.                                       virtual_screen.active_position.
  6102.                                       col_position ) ;
  6103.                                   END IF ;
  6104.  
  6105.                                   count := count + 1;
  6106.                                   EXIT WHEN (virtual_screen.element(
  6107.                                    virtual_screen.active_position.
  6108.                                    row_position).descriptors(virtual_screen.
  6109.                                    active_position.col_position).qualifiers
  6110.                                    /= vt_content.dqnn)  OR  (count >
  6111.                                    number_of_qualified_areas) ;
  6112.  
  6113.                                 END LOOP ;
  6114.  
  6115.                                 IF count > number_of_qualified_areas
  6116.                                 THEN virtual_screen.active_position.
  6117.                                        row_position := save_row ;
  6118.                                      virtual_screen.active_position.
  6119.                                        col_position := save_col ;
  6120.                                 END IF ;
  6121.  
  6122.                WHEN OTHERS   =>
  6123.                                 temp_row := virtual_screen.active_position
  6124.                                  .row_position ;
  6125.                                 temp_col := virtual_screen.active_position
  6126.                                  .col_position ;
  6127.  
  6128.                                 only_cursor_movement := false ;
  6129.                                 input_type := virtual_screen.element
  6130.                                  (temp_row).descriptors(temp_col).
  6131.                                  qualifiers ;
  6132.  
  6133.                                  CASE input_type IS
  6134.                                    WHEN vt_content.dqnn => ok := FALSE ;
  6135.  
  6136.                                    WHEN vt_content.dqag =>
  6137.                                          IF data(i) IN ' '..'~'
  6138.                                          THEN ok := TRUE ;
  6139.                                          ELSE ok := FALSE;
  6140.                                          END IF ;
  6141.  
  6142.                                    WHEN vt_content.dqan =>
  6143.                                          IF data(i) IN '0'..'9'
  6144.                                          THEN ok := TRUE ;
  6145.                                          ELSE ok := FALSE;
  6146.                                          END IF ;
  6147.                                  END CASE ;
  6148.  
  6149.                                  IF ok
  6150.                                  THEN put(data(i) ) ;
  6151.                                       form_is_modified := true ;
  6152.                                       IF virtual_screen.active_position.
  6153.                                          row_position IN top_line..bottom_line
  6154.                                       THEN NULL ;
  6155.                                       ELSIF virtual_screen.active_position.
  6156.                                             row_position < top_line
  6157.                                       THEN
  6158.                                          top_line := virtual_screen.
  6159.                                           active_position.row_position ;
  6160.                                       ELSE
  6161.                                          bottom_line := virtual_screen.
  6162.                                           active_position.row_position ;
  6163.                                       END IF ;
  6164.  
  6165.  
  6166.                                  ELSE driver.interpret( bell ) ;
  6167.                                  END IF ;
  6168.  
  6169.                END CASE ;
  6170.          END LOOP ;
  6171.  
  6172.          -- redisplay line with new additions
  6173.  
  6174.          IF only_cursor_movement
  6175.          THEN redisplay.fix_cursor( actual_screen, virtual_screen ) ;
  6176.          ELSE
  6177.              IF top_line = bottom_line
  6178.              THEN redisplay.redisplay_line_with_redraw( actual_screen,
  6179.                    virtual_screen, top_line, top_line ) ;
  6180.              ELSE redisplay.redisplay_screen_with_redraw( actual_screen,
  6181.                    virtual_screen, top_line, bottom_line ) ;
  6182.              END IF ;
  6183.  
  6184.              redisplay.fix_cursor( actual_screen, virtual_screen ) ;
  6185.  
  6186.          END IF ;
  6187.  
  6188.  
  6189.      END handle_string ;
  6190.      PRAGMA page ;
  6191.  
  6192.  
  6193.   BEGIN  -- activate form
  6194.  
  6195.       IF NOT initialized
  6196.       THEN RAISE uninitialized ;
  6197.       END IF ;
  6198.  
  6199.       form_is_modified := false ;
  6200.  
  6201.       IF number_of_qualified_areas = 0
  6202.       THEN  -- set screen protected and primary rendition
  6203.  
  6204.          set_position( xy_position'(1, 1) ) ;
  6205.          FOR i IN 1..vt_content.height LOOP
  6206.              FOR j IN 1..vt_content.width LOOP
  6207.                  virtual_screen.element(i).descriptors(j).
  6208.                      qualifiers := vt_content.dqnn ;
  6209.                  virtual_screen.element(i).descriptors(j).
  6210.                      rendition := vt_content.sgpr ;
  6211.              END LOOP ;
  6212.          END LOOP ;
  6213.  
  6214.       ELSE  -- move cursor to first unprotected area on the
  6215.             -- display if one exists
  6216.  
  6217.          set_position( xy_position'(vt_content.height,
  6218.                                     vt_content.width - 1) ) ;
  6219.          LOOP
  6220.            tab ;
  6221.  
  6222.             next_position(
  6223.                     virtual_screen.active_position.row_position,
  6224.                     virtual_screen.active_position.col_position ) ;
  6225.  
  6226.            count := count + 1 ;
  6227.            EXIT WHEN
  6228.                  (virtual_screen.element(virtual_screen.active_position
  6229.                         .row_position).descriptors(virtual_screen.
  6230.                         active_position.col_position).qualifiers
  6231.                         /= vt_content.dqnn) OR  (count >
  6232.                         number_of_qualified_areas) ;
  6233.          END LOOP ;
  6234.  
  6235.          IF count > number_of_qualified_areas
  6236.          THEN -- no unprotected areas defined, set act pos to 1,1
  6237.             set_position( xy_position'(1, 1) ) ;
  6238.  
  6239.          END IF ;
  6240.  
  6241.       END IF ;
  6242.  
  6243.          redisplay.redisplay_screen_with_redraw( actual_screen,
  6244.                virtual_screen, 1, vt_content.height ) ;
  6245.          redisplay.fix_cursor( actual_screen, virtual_screen ) ;
  6246.  
  6247.          -- begin local editting
  6248.  
  6249.          local_editting_loop :
  6250.          LOOP
  6251.  
  6252.             vt_input.get( data, last, keys ) ;
  6253.             number_of_function_keys := vt_input.function_count( keys ) ;
  6254.  
  6255.             IF last = 0
  6256.             THEN
  6257.                  IF number_of_function_keys = 0
  6258.                  THEN
  6259.                      NULL ;
  6260.                  ELSE
  6261.                      FOR i IN 1..number_of_function_keys
  6262.                      LOOP
  6263.  
  6264.                         vt_input.function_key( keys, i, key_id, prev_pos ) ;
  6265.                         handle_function_key( key_id, leave_body ) ;
  6266.  
  6267.                         IF leave_body
  6268.                         THEN EXIT local_editting_loop ;
  6269.                         END IF ;
  6270.  
  6271.                      END LOOP ;
  6272.                  END IF ;
  6273.  
  6274.             ELSE
  6275.                  IF number_of_function_keys = 0
  6276.                  THEN
  6277.                       handle_string( data, last ) ;
  6278.                  ELSE
  6279.                       last_position := 1 ;
  6280.                       FOR i IN 1..number_of_function_keys  LOOP
  6281.  
  6282.                          vt_input.function_key( keys, i,
  6283.                                       key_id, prev_pos ) ;
  6284.                          IF prev_pos /= 0
  6285.                          THEN
  6286.                              handle_string( data(last_position..
  6287.                                prev_pos), (prev_pos - last_position + 1)) ;
  6288.  
  6289.                              last_position := prev_pos + 1;
  6290.                          END IF ;
  6291.  
  6292.                          handle_function_key( key_id, leave_body ) ;
  6293.                          IF leave_body
  6294.                          THEN  EXIT local_editting_loop ;
  6295.                          END IF ;
  6296.  
  6297.                       END LOOP ;
  6298.  
  6299.                       IF last_position <= last
  6300.                       THEN
  6301.                            handle_string( data( last_position..last ),
  6302.                                    (last - last_position + 1)) ;
  6303.                       END IF ;
  6304.  
  6305.                  END IF ;
  6306.  
  6307.             END IF ;
  6308.  
  6309.          END LOOP local_editting_loop ;
  6310.  
  6311.   function_key_struck := key_id   ;
  6312.  
  6313.   END activate_form ;
  6314. ::::::::::
  6315. tcf
  6316. ::::::::::
  6317. t1|tv970|tv-970|televideo 970:\
  6318.         :al=1*\E[1L:am:bs:cd=\E[J:ce=\E[K:cl=\E[2J:cm=\E[%i%2;%2H:co#80:\
  6319.         :dc=\E[1P:dl=1*\E[1M:dn=\E[1B:ei=\E[4l:ho=\E[H:im=\E[4h:li#24:mi:\
  6320.         :nd=\E[1C:as=\E[10m:ae=\E[11m:ms:pt:se=\E[0m:so=\E[7m:up=\E[1A:\
  6321.         :vs=\E[>4h:ve=\E[>4l:kb=^h:ku=\E[1A:kd=\E[1B:kl=\E[1D:kr=\E[1C:\
  6322.         :kh=\E[H:kn#8:k1=\EOS:k2=\EOT:k3=\EOU:k4=\EOV:k5=\EOW:l6=blue:\
  6323.         :sr=\EM:is=\E<\E[2J:\
  6324.         :ca=\E[2K:ds=\E[?2l:\
  6325.         :l1=F1:l2=F2:l3=F3:l4=F4:l5=F5:l6=F6:l7=F7:l8=F8:l9=F9:y0=F10:\
  6326.         :y1=F11:y2=F12:y3=F13:y4=F14:y5=F15:y6=F16:\
  6327.         :y7=Shift F1:y8=Shift F2:y9=Shift F3:h0=Shift F4:h1=Shift F5:\
  6328.         :h2=Shift F6:h3=Shift F7:h4=Shift F8:h5=Shift F9:h6=Shift F10:\
  6329.         :h7=Shift F11:h8=Shift F12:h9=Shift F13:v0=Shift F14:v1=Shift F15:\
  6330.         :v2=Shift F16:an:\
  6331.         :k1=\E?a:k2=\E?b:k3=\E?c:k4=\E?d:k5=\E?e:k6=\E?f:k7=\E?g:k8=\E?h:\
  6332.         :k9=\E?i:x0=\E?j:x1=\E?k:x2=\E?l:x3=\E?m:x4=\E?n:x5=\E?o:x6=\E?p:\
  6333.         :x7=\E?A:x8=\E?B:x9=\E?C:g0=\E?D:g1=\E?E:g2=\E?F:g3=\E?G:g4=\E?H:\
  6334.         :g5=\E?I:g6=\E?J:g7=\E?K:g8=\E?L:g9=\E?M:t0=\E?N:t1=\E?O:t2=\E?P:\
  6335.         :ku=\E[A:kd=\E[B:kr=\E[C:kl=\E[D:
  6336. d1|vt100|vt-100|pt100|pt-100|dec vt100:\
  6337.         :co#80:li#24:am:cl=50\E[;H\E[2J:bs:cm=5\E[%i%2;%2H:nd=2\E[C:up=2\E[A:\
  6338.         :ce=3\E[K:cd=50\E[J:so=2\E[7m:se=2\E[m:us=2\E[4m:ue=2\E[m:\
  6339.         :is=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:ks=\E[?1h\E=:ke=\E[?1l\E>:\
  6340.         :if=/usr/lib/tabset/vt100:ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:\
  6341.         :kh=\E[H:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:pt:sr=5\EM:
  6342. dv|vt52|dec vt52:\
  6343.         :bs:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :co#80:li#24:nd=\EC:\
  6344.         :pt:sr=\EI:up=\EA:ku=\EA:kd=\EB:kr=\EC:kl=\ED:
  6345. d5|vi50|Visual 50:\
  6346.         :al=\EL:ca=\015\EK:\
  6347.         :l1=F1:k1=\EP:l2=F2:k2=\EQ:\
  6348.         :pt:bs:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :co#80:dl=\EM:\
  6349.         :li#24:nd=\EC:pt:se=\ET:so=\EU:sf=\ED:sr=\EI:up=\EA:\
  6350.         :kl=\ED:vb=\E9@\E9P\E9@\E9P\E9@\E9P\E9@\E9P:
  6351. #
  6352. #
  6353. ::::::::::
  6354. term
  6355. ::::::::::
  6356. tv970
  6357. this is a dummy line to get around the END_ERROR problem
  6358. ::::::::::
  6359. recompile.cli
  6360. ::::::::::
  6361. ada vtcontent_spec
  6362. ada sysdep_spec
  6363. ada tcf_spec
  6364. ada scroll_spec
  6365. ada page_spec
  6366. ada form_spec
  6367. ada vtinput_spec
  6368. ada driver_spec
  6369. ada redisplay_spec
  6370. ada sysdep_body
  6371. ada tcf_body
  6372. ada driver_body
  6373. ada vtinput_body
  6374. ada redisplay_body
  6375. ada scroll_body
  6376. ada page_body
  6377. ada form_body
  6378. ada activate_form
  6379.