.CM  SCRIPT , Version - 1.1 , last edited by barbara
.ad 8
.bm 8
.fm 4
.bt $Copyright by   SAP AG, 2001$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VMT93$
.tt 2 $$$
.tt 3 $$Terminal-IO$1995-11-01$
***********************************************************
.nf
 
 
    ========== licence begin LGPL
    Copyright (C) 2000 SAP AG
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    ========== licence end
 
.fo
.nf
.sp
Module  :  Terminal-IO
=========
.sp
Purpose :  Terminalein-/Ausgabe mit Bildschirmspeicher
           Dieser Modul entspricht dem VTA03 des Kerns.
           Unterschied: es werden die Pascal/IO Prozeduren
           von VTA05 nicht benutzt.
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              m93initscreen (is_batch : boolean;
                    is_pascal_io : boolean;
                    local_sqlton : boolean;
                    VAR term_ref : tsp_int4;
                    VAR term_desc: tsp_terminal_description;
                    VAR batch_fn : tsp_vfilename;
                    VAR param_ln : tsp_line;
                    VAR is_ok    : boolean);
 
        PROCEDURE
              m93endscreen (
                    local_sqltoff: boolean );
 
        PROCEDURE
              m93putscreen (VAR text : tin_screenline);
 
        PROCEDURE
              m93put (VAR text : tin_screenline; ft : tin_ls_fieldtype);
 
        PROCEDURE
              m9320put_screen_20 (text : tsp_c20);
 
        PROCEDURE
              m9330put_screen_30 (text : tsp_c30);
 
        PROCEDURE
              m93getscreen (VAR text : tsp_line);
 
        PROCEDURE
              m93string_get_screen (VAR text : tsp_line;
                    VAR last_line : boolean);
 
        PROCEDURE
              m93undef_screen_header;
 
        PROCEDURE
              m93hold (on : boolean);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              Test_Procedures : VMT90;
 
        VAR
              m90tab : char;
 
      ------------------------------ 
 
        FROM
              logical_screen_procedures : VMT95;
 
        PROCEDURE
              m95clear (background : tsp_vt_color;
                    maxchars      : integer;
                    VAR vt_screen : tsp_screenbuf;
                    VAR vt_att    : tsp_screenbuf);
 
        PROCEDURE
              m95putfield (VAR field : tin_screenline;
                    length     : integer;
                    field_slno : integer;
                    field_scol : integer;
                    field_type : tin_ls_fieldtype;
                    maxlines,maxcols : integer;
                    VAR vt_screen : tsp_screenbuf;
                    VAR vt_att : tsp_screenbuf);
 
        PROCEDURE
              m95nextfield (VAR row,col : integer;
                    VAR length : integer;
                    VAR found : boolean;
                    VAR field_changed : boolean;
                    maxlines : integer;
                    maxcols : integer;
                    VAR vt_screen : tsp_screenbuf;
                    VAR vt_att : tsp_screenbuf);
 
        PROCEDURE
              m95getfield (row,col : integer;
                    VAR length : integer;
                    VAR input : tin_screenline;
                    maxcols : integer;
                    VAR vt_screen : tsp_screenbuf);
 
      ------------------------------ 
 
        FROM
              RTE_driver : VEN102;
 
        PROCEDURE
              sqlabort;
 
        PROCEDURE
              sqlton (multi_task  : boolean;
                    VAR term_ref : tsp_int4;
                    VAR desc     : tsp_terminal_description;
                    VAR ok       : boolean);
 
        PROCEDURE
              sqltio (term_ref          : tsp_int4;
                    VAR screen_buf     : tsp_screenbufaddr;
                    VAR attribute_buf  : tsp_screenbufaddr;
                    refresh            : boolean;
                    VAR cursorline     : tsp_int2;
                    VAR cursorcolumn   : tsp_int2;
                    VAR hif            : tsp_hif_parms;
                    VAR options        : tsp_vt_options;
                    VAR result         : tsp_vt_result;
                    VAR ok             : boolean);
 
        PROCEDURE
              sqltoff (
                    term_ref          : tsp_int4;
                    VAR screen_buf    : tsp_screenbufaddr;
                    VAR attribute_buf : tsp_screenbufaddr;
                    VAR msg           : tsp_vtmsg);
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              m95putfield;
 
              tsp_moveobj tin_screenline
 
        PROCEDURE
              sqlton;
 
              tsp00_Int4                tsp_int4
              tsp00_TerminalDescription tsp_terminal_description
 
        PROCEDURE
              sqltio;
 
              tsp00_Int4          tsp_int4
              tsp00_ScreenBufAddr tsp_screenbufaddr
              tsp00_ScreenBufAddr tsp_screenbufaddr
              tsp00_Int2          tsp_int2
              tsp00_Int2          tsp_int2
              tsp00_HifParms      tsp_hif_parms
              tsp00_VtOptions     tsp_vt_options
              tsp00_VtResult      tsp_vt_result
 
        PROCEDURE
              sqltoff;
 
              tsp00_Int4          tsp_int4
              tsp00_ScreenBufAddr tsp_screenbufaddr
              tsp00_ScreenBufAddr tsp_screenbufaddr
              tsp00_VtMsg         tsp_vtmsg
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : JuergenA / BarbaraJ
.sp
.cp 3
Created : 29.1.82
.sp
.cp 3
Version : 2001-03-19
.sp
.cp 3
Release :  6.1.2     Date : 1995-11-01
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
.pb '@'
.cp 7
M93INIT_SCREEN
.SP
Initialisierung des Bildschirmspeichers und der Ein-/Ausgabe.
Bei EXEC^= ^TRUE werden die Eingaben nicht vom Terminal sondern
aus der angegebenen Datei EXEC_FN mit dem Filetype 'VDNTEST' und
dem Filemode '*' geholt. Ist STANDARD_IO^= ^TRUE
dann erfolgen die Ein-/Ausgaben nicht ?uber das virtuelle Terminal
sondern durch Pascal read/write.
.sp 2;.cp 3
M93END_SCREEN
.sp
Terminal-IO wird beendet.
.sp 2;.cp 5
M93PUT_SCREEN
.sp
Die ersten 79 Zeichen der Zeile TEXT
werden protected auf dem Bildschirm ausgegeben.
TEXT darf nur druckbare Zeichen enthalten.
.sp 2;.cp 5
M93PUT
.sp
Die ersten 79 Zeichen der Zeile TEXT werden entsprechend dem
VT-Attribut TEXT_ATTR auf dem Bildschirm ausgegeben.
TEXT darf nur druckbare Zeichen enthalten.
.sp 2;.cp 4
M9320PUT_SCREEN_20
.sp
Die 20 Zeichen lange Zeile TEXT wird protected auf dem
Bildschirm ausgegeben.
.sp 2;.cp 4
M93PUT20
.sp
Die 20 Zeichen lange Zeile TEXT wird entsprechend dem VT-Attribut
TEXT_ATTR auf dem Bildschirm ausgegeben.
.sp 2;.cp 4
M9330PUT_SCREEN_30
.sp
Die 30 Zeichen lange Zeile TEXT wird protected auf dem
Bildschirm ausgegeben.
.sp 2;.cp 4
M93PUT30
.sp
Die 30 Zeichen lange Zeile TEXT wird entsprechend dem VT-Attribut
TEXT_ATTR auf dem Bildschirm ausgegeben.
.sp 2;.cp 4
M93PUT60
.sp
Die 60 Zeichen lange Zeile TEXT wird entsprechend dem VT-Attribut
TEXT_ATTR auf dem Bildschirm ausgegeben.
.sp 2;.cp 4
M93GET1NAME
.sp
Ein Feld der L?ange MAXNAMELENGTH wird eingelesen,
indem auf einer Zeile beginnend an der Position
GET1NAME_MSG_POS die MSG entsprechend dem VT-Attribut MSG_ATTR und
an der Position GET1NAME_IN_POS das editierbare Feld
IN_NAME entsprechend dem VT-Attribut IN_ATTR ausgegeben wird, d.h. an
IN_NAME mu?z vor dem Prozeduraufruf ein Default-Wert zugwiesen werden.
Ist UPPER_CASE = true, so wird IN_NAME in Gro?zschreibung konvertiert.
PFKEY gibt die zuletzt bet?atigte Funktionstaste an.
Beim Standard-IO oder bei der Dateieingabe ist der Defaultwert unwirksam.
.sp 2;.cp 4
M93GET2NAME
.sp
Analog zu GET1NAME werden zwei Felder der L?ange MAXNAMELENGTH
eingelesen, indem auf einer Zeile beginnend an der Position
GET1NAME_MSG_POS die MSG1 und bei GET2NAME_MSG_POS die MSG2
entsprechend den VT-Attributen MSG1_ATTR bzw. MSG2_ATTR und
an den Position GET1NAME_IN_POS und GET2NAME_IN_POS die
editierbaren Felder IN1_NAME bzw. IN2_NAME entsprechend den VT-Attributen
IN_ATTR1/2 ausgegeben werden, d.h. an beide Eingabevariablen
mu?z vor dem Prozeduraufruf ein Default-Wert zugwiesen werden.
IN1_NAME bzw. IN2_NAME werden in Gro?zschreibung konvertiert,
falls UPPER_CASE1 bzw. UPPER_CASE2 true ist.
PFKEY gibt die zuletzt bet?atigte Funktionstaste an.
Bei Standard-IO oder bei der Dateieingabe ist der Defaultwert unwirksam.
.sp 2;.cp 4
M93GETHOSTNAME
.sp
Ein Feld der L?ange MAXHOSTNAMELENGTH wird eingelesen,
indem auf einer Zeile beginnend an der Position
GET1NAME_MSG_POS die MSG entsprechend dem VT-Attribut MSG_ATTR und
an der Position GET1NAME_IN_POS das editierbare Feld
IN_NAME entsprechend dem VT-Attribut IN_ATTR ausgegeben wird, d.h. an
IN_NAME mu?z vor dem Prozeduraufruf ein Default-Wert zugwiesen werden.
PFKEY gibt die zuletzt bet?atigte Funktionstaste an.
Beim Standard-IO oder bei der Dateieingabe ist der Defaultwert unwirksam.
.sp 2;.cp 4
M93MASK
.sp
Es wird eine Bildschirm-Maske mit COUNT_NAMES Feldern der L?ange
MAXNAMELENGTH und COUNT_HOSTNAMES Feldern der L?ange MAXHOSTNAMELENGTH
analog zu den zeilenorientierten Prozeduren GET1/2NAME bzw.
GETHOSTNAME erzeugt. Die Felder m?ussen durch Defaultwerte vorbelegt
sein, die aber bei Standard-IO oder bei der Dateieingabe unwirksam sind.
Die Felder des Arrays IN_NAME werden in Gro?zschreibung konvertiert,
falls UPPER_CASE true ist.
PFKEY gibt die zuletzt bet?atigte Funktionstaste an.
.sp 2;.cp 4
M93MENU
.sp
Es wird am Bildschirm ein Menue erzeugt, das aus SIZE Feldern
aus dem Array MSG besteht. Die Felder werden entsprechend dem
VT-Attribut MSG_ATTR ausgegeben. Felder, die nur aus Leerzeichen
bestehen, werden ohne Nummer als Zwischenraum angezeigt. Entsprechend
?andert sich die Numerierung auf dem Bildschirm. Es k?onnen dann
die Nummern auf dem Bildschirm oder die Bezeichnungen der Felder
(KEINE Umwandlung in Gro?zbuchstaben!) eingegeben werden.
Als Ergebnis der Auswahl wird der Integer SELECTED geliefert, der
sich nach dem ?ubergebenen MSG-Array richtet und
im Bereich 1 bis SIZE liegt. Nach Bet?atigen
einer Funktionstaste wird diese durch PFKEY geliefert und
SELECTED auf 1 gesetzt.
.sp 2;.cp 4
M93MSGPUT_SCREEN_MSG
.sp
Eine Zeile wird als Message auf der untersten Zeile
bright_protected ausgegeben.
.sp 2;.cp 5
M93GET
.sp
Eine Zeile wird unprotected vom Bildschirm eingelesen und mit mit
Leerzeichen aufgef?ullt. PFKEY liefert die evtl. bet?atigte
Funktionstaste.
.sp 2;.cp 4
M93GET_SCREEN
.sp
Eine Zeile wird unprotected vom Bildschirm gelesen
und mit Leerzeichen aufgef?ullt.
.sp 2;.cp 3
M93PASSWORD_GET_SCREEN
.sp
Ein Password wird invisible gelesen und mit Leerzeichen aufgef?ullt.
.sp 2;.cp 7
M93READ_SCREEN_STRING
.sp
Durch Eingaben am Terminal wird der Bildschirmspeicher mittels
M93GET_SCREEN gef?ullt bis
eine Zeile durch gelesen wird, die
au?zerhalb eines Strings das Endezeichen enth?alt.
Die Zeilen k?onnen anschlie?zend mit T01STRING_GET_SCREEN
aus dem Bildschirmspeicher geholt werden.
.sp 2;.cp 6
M93STRING_GET_SCREEN
.SP
?Ubertr?agt eine Zeile, die zuvor bei M93READ_SCREEN_STRING
eingegeben wurde, aus dem Bildschirmspeicher.
Wenn es sich um die letzte Zeile handelt,
wird LAST_LINE auf true gesetzt.
.sp 2;.cp 7
M93CLEAR_SCREEN_STRING
.sp
L?oscht den String, der durch M93READ_SCREEN_STRING definiert wurde.
Diese Prozedur wird ben?otigt,
wenn nicht alle Zeilen durch M93STRING_GET_SCREEN ?ubertragen
wurden. M93Clear_SCREEN_STRING hat keinen Effekt, wenn alle Zeilen
gelesen wurden.
.sp 2;.cp 4
M93DEF_SCREEN_HEADER
.sp
Ein Seitenkopf wird mit der angegebenen Titelzeile f?ur jede
Bildschirmseite definiert und eine neue Seite auf dem Bildschirm erzeugt.
.sp 2;.cp 6
M93MSG_HEADER
.sp
In der Titelzeile werden beginnend an der Position POS 20 Zeichen
durch den Text MSG ersetzt. Die ge?anderte Titelzeile
wird auf dem Bildschirm ausgegeben und bleibt nur bis zum n?achsten
Bildschirmaufbau erhalten.
.sp 2;.cp 5
M93PERM_MSG_HEADER
.sp
In der Titelzeile werden beginnend an der Position POS 30 Zeichen
durch den Text MSG ersetzt. Die ge?anderte Titelzeile
wird erst mit dem n?achsten Bildschirmaufbau ausgegeben und bleibt
bis zu einem entsprechendem M93PERM_MSG_HEADER oder bis
M93DEF/UNDEF_SCREEN_HEADER erhalten.
.sp 2;.cp 5
M93UNDEF_SCREEN_HEADER
.sp
Der Seitenkopf wird gel?oscht, auf eine Bildschirmlayout ohne
Rahmen umgeschaltet und eine neue Seite auf dem Bildschirm
erzeugt.
.sp 2;.cp 4
M93FRAME
.sp
Umsetzung des Bildschirmlayouts. Ein Rahmen wird erzeugt, wenn
ON true ist. M93FRAME erzeugt keinen neuen Bildschirm. Daher
sollte unmittelbar nach dieser Prozedur M93DEF_SCREEN_HEADER
aufgerufen werden. Das Zur?ucksetzen auf ein Layout ohne Rahmen
kann auch impliziet mittels M93UNDEF_SCREEN_HEADER erfolgen.
.sp 2;.cp 4
M93NEW_SCREEN_PAGE
.sp
Eine neue Bildschirmseite wird erzeugt und der Cursor auf den Anfang der
ersten Zeile (unterhalb des Seitenkopfes) gesetzt.
.sp 2;.cp 5
M93HOLDING_SCREEN
.sp
Nach der Ausgabe der Holding-Message wird auf das Dr?ucken der
Enter-Taste oder einer Funktionstaste gewartet.
PFKEY gibt die bet?atigte Funktionstaste an.
.sp 2;.cp 4
M93RESET_SCREEN
.sp
Der Bildschirminhalt wird neu ausgegeben.
.sp 2;.cp 5
M93SET_SCREEN_INPUT
.sp
Die Eingaben werden aus der angegebenen Datei FN mit dem Filetype
VDNMAC und dem Filemode '*' gelesen.
Bei EOF wird mit dem urspr?unglichen Eingabemodus fortgefahren.
Eine Rekursion von VDNMAC-Files ist nicht m?oglich.
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
.cp 6;.oc _/1
Funktionstasten
.sp;.of 7
PF01 Die PFKEY-Belegung 'PF_HELP' wird gesetzt.
.sp;.of 7;.cp 2
PF02 Break: Die globale Variable IS_BREAK wird gesetzt.
Au?zerdem wird die PFKEY-Belegung 'PF_CANCEL' gesetzt.
.sp;.of 7
PF03 Die PFKEY-Belegung 'PF_END' wird gesetzt.
.sp;.cp 4;.of 7
PF04 Der interne Hold-Mechanismus wird neu gesetzt (Default ist full
screenpage). PF04 schaltet die Zeilenanzahl der vor der Ausgabe auf dem
Bildschirm gespeicherten Zeilen weiter: full^screenpage -> no line ->
5@lines -> half^screenpage -> full^screenpage^->@...
.sp;.cp 3;.of 7
PF05 Holding wird bis zum n?achsten m93getscreen, das au?zerhalb eines
Files aufgerufen wird, abgeschaltet. Au?zerdem wird die Zeile, auf der
der Cursor steht, wie bei der Entertaste ?ubertragen.
.sp;.of 7
PF07 Ausgabe der vorhergehenden Bildschirmseite.
.sp;.cp 2;.of 7
PF08 Ausgabe der n?achsten Bildschirmseite oder der nachfolgenden Zeilen,
deren Anzahl durch die Holdangabe festgelegt ist.
.sp;.of 7
PF09 Ausgabe des letzten Kommandos
.of;.sp;.cp 2
.sp;.of 7
PF11 An der Cursorposition wird die Zeile dupliziert.
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
CONST
      endsign2           = '|';
      param_sign         = '&';
      prompting_sign     = '>';
      string_delimiter   = '''';
      blank_msg          = '                    ';
      break_msg          = 'BREAK               ';
      file_not_found_msg = 'FILE NOT FOUND      ';
      hold_full_msg      = 'HOLD FULL SCREENPAGE';
      hold_half_msg      = 'HOLD HALF SCREENPAGE';
      hold_0_msg         = 'HOLD NO LINES       ';
      hold_5_msg         = 'HOLD 5 LINES        ';
      holding_msg        = 'HOLDING             ';
      illegal_input_msg  = 'ILLEGAL INPUT       ';
      nohold_msg         = 'HOLDING OFF         ';
      too_many_files_msg = 'TOO MANY FILES      ';
      get1name_in_pos    =  22;
      get1name_msg_pos   =   1;
      get2name_in_pos    =  62;
      get2name_msg_pos   =  41;
      max_last_cmd_lines =  10;
      max_last_cmds      =   5;
      max_lines          =  30;
      max_param          =   9;
      space_stream_size  =  83;
      terminal_lines     =  23; (* es gibt Terminals mit nur 23 Zeilen*)
      top_msg_size       =  20;
      nr_header_lines    =   3;
      mt_linelength = 70;
 
TYPE
      type_last_cmd = ARRAY [ 1..max_last_cmd_lines ] OF tin_screenline;
      param_pos     = ARRAY [ 1..max_param ] OF integer;
 
      termprot_piece = RECORD
            text : tin_screenline;
            len : integer;
            row : integer;
            col : integer;
            ft : tin_ls_fieldtype;
      END;
 
 
      terminal_states = RECORD
            bottom_msg        : termprot_piece;
            frame_stream      : termprot_piece;
            header            : termprot_piece;
            count_cmd_lines   : ARRAY [ 1..max_last_cmds ] OF integer;
            is_new_page       : ARRAY [ 1..max_lines ] OF boolean;
            last_cmd_lines    :ARRAY [1..max_last_cmds] OF type_last_cmd;
            lines             : ARRAY [ 1..max_lines ] OF tin_screenline;
            line_attr         : ARRAY [ 1..max_lines ] OF tin_ls_fieldtype;
            space_stream      : termprot_piece;
            top_msg           : termprot_piece;
            blank_screenline : tin_screenline;
            blankline         : tsp_line;
            bottom                : integer;
            currcol               : integer;
            currline              : integer;
            first_cmd_line        : integer;
            holding_linecount     : integer;
            last_cmd_line         : integer;
            last_cmd_no           : integer;
            max_holding_linecount : integer;
            max_window_lines      : integer;
            prev_window_linecount : integer;
            top                   : integer;
            window_bottom         : integer;
            window_currline       : integer;
            window_left_col       : integer;
            window_top            : integer;
            is_batch       : boolean;
            is_holding     : boolean;
            is_pascal_io   : boolean;
            is_protected   : boolean;
      END;
 
      pfkeytype     = (pf_none, pf_cancel, pf_down, pf_end, pf_help,
            pf_left, pf_next, pf_prev, pf_print, pf_right,
            pf_run, pf_up);
      (*!!!*)
 
      vt_parms = RECORD
            cline,ccol : integer;
            wait_for_input : boolean;
            tsp_key : tsp_vt_key;
      END;
 
 
VAR
      m93v : terminal_states;
      m93hif : tsp_hif_parms;
      m93row : integer;
      m93col : integer;
      m93rk : tsp_vt_key;
      m93cline, m93ccol : tsp_int2;
      m93desc : tsp_terminal_description;
      m93hld : boolean;
      m93tref : tsp_int4;
 
 
(*------------------------------*) 
 
PROCEDURE
      m93initscreen (is_batch : boolean;
            is_pascal_io : boolean;
            local_sqlton : boolean;
            VAR term_ref : tsp_int4;
            VAR term_desc: tsp_terminal_description;
            VAR batch_fn : tsp_vfilename;
            VAR param_ln : tsp_line;
            VAR is_ok    : boolean);
 
VAR
      i        : integer;
      k        : integer;
      ok       : boolean;
 
BEGIN
is_ok := true;
m93v.is_batch     := is_batch;
m93v.is_pascal_io := is_pascal_io;
m93v.is_holding     := true;
m93v.is_protected   := true;
m93v.max_window_lines := terminal_lines - nr_header_lines - 1;
FOR i := 1 TO mt_linelength DO
    m93v.blank_screenline  [i]  := ' ';
(*ENDFOR*) 
FOR i := 1 TO mxsp_line DO
    m93v.blankline  [i]  := ' ';
(*ENDFOR*) 
FOR i := 1 TO max_lines DO
    BEGIN
    m93v.lines        [i]  := m93v.blank_screenline;
    m93v.is_new_page  [i]  := false;
    set_default_line_attr(m93v.line_attr  [i] );
    END;
(*ENDFOR*) 
FOR k := 1 TO max_last_cmds DO
    BEGIN
    FOR i := 1 TO max_last_cmd_lines DO
        m93v.last_cmd_lines  [k]   [i]  := m93v.blank_screenline;
    (*ENDFOR*) 
    m93v.count_cmd_lines  [k]  := 0
    END;
(*ENDFOR*) 
m93v.last_cmd_no := 1;
init_termprot_piece(m93v.bottom_msg,bsp_c1,
      terminal_lines,3, cin_ls_enhanced);
init_termprot_piece(m93v.header,bsp_c1,1,2,cin_ls_normal);
init_termprot_piece(m93v.top_msg,bsp_c1,2,5,cin_ls_enhanced);
init_termprot_piece(m93v.space_stream,chr(0),99,2,cin_ls_enhanced);
init_termprot_piece(m93v.frame_stream,'-',99,1,cin_ls_normal);
WITH m93v DO
    BEGIN
    top             := 1;
    bottom          := 1;
    currline        := 0;
    currcol         := 1;
    window_top      := 0;
    window_bottom   := 0;
    window_currline := 0;
    first_cmd_line  := 0;
    max_holding_linecount := m93v.max_window_lines;
    holding_linecount     := 0;
    prev_window_linecount := 0
    END;
(*ENDWITH*) 
IF  NOT is_pascal_io
THEN
    BEGIN
    IF  local_sqlton
    THEN
        BEGIN
        sqlton(false,m93tref,m93desc,is_ok);
        IF  NOT is_ok
        THEN
            sqlabort;
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        m93tref := term_ref;
        m93desc := term_desc;
        END;
    (*ENDIF*) 
    m93hld := false;
    WITH m93desc DO
        m95clear(vt_black,m93desc.num_of_cols*m93desc.num_of_lines,
              content_buf^, attribute_buf^);
    (*ENDWITH*) 
    m93def_screen_header (m93v.blank_screenline);
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      set_default_line_attr(VAR ft : tin_ls_fieldtype);
 
BEGIN
WITH ft DO
    BEGIN
    field_att := cin_ls_normal;
    fieldmode := [  ] ;
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      init_termprot_piece(VAR piece : termprot_piece;
            c : char;
            lno : integer;
            colno : integer;
            att : tin_ls_attribute_index);
 
VAR
      i : integer;
 
BEGIN
WITH piece DO
    BEGIN
    WITH ft DO
        BEGIN
        field_att := att;
        fieldmode := [  ] ;
        END;
    (*ENDWITH*) 
    FOR i := 1 TO mt_linelength DO
        text  [i]  := ' ';
    (*ENDFOR*) 
    len := mt_linelength - colno - 1;
    row := lno;
    col := colno;
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      ilo ( i : tsp_int2 ) : char ;
 
VAR
 
      x : RECORD
            CASE boolean OF
                TRUE :
                    ( ip : tsp_int2 );
                FALSE :
                    ( ch2 : tsp_c2 ) ;
                END ;
            (*ENDCASE*) 
 
 
BEGIN
x.ip := i ;
ilo := x.ch2 [1] ;
END ;
 
(*------------------------------*) 
 
FUNCTION
      ihi ( i : tsp_int2 ) : char ;
 
VAR
 
      x : RECORD
            CASE boolean OF
                TRUE :
                    (ip : tsp_int2);
                FALSE :
                    (ch2 : tsp_c2);
                END ;
            (*ENDCASE*) 
 
 
BEGIN
x.ip := i ;
ihi := x.ch2 [2] ;
END ;
 
(*------------------------------*) 
 
PROCEDURE
      m93endscreen (
            local_sqltoff: boolean );
 
VAR
      close_err : tsp_vf_return;
      vtmsg     : tsp_vtmsg;
      hfe       : tsp_int2;
      i         : integer;
 
BEGIN
FOR i := 1 TO mxsp_vtmsg DO
    vtmsg [i]  := bsp_c1;
(*ENDFOR*) 
IF  local_sqltoff
THEN
    WITH m93desc DO
        sqltoff ( m93tref, content_buf, attribute_buf, vtmsg );
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      next_line;
 
BEGIN
IF  m93v.currline = m93v.window_bottom
THEN
    BEGIN
    IF  m93v.window_bottom = m93v.bottom
    THEN
        BEGIN
        m93v.bottom := (m93v.bottom MOD max_lines) + 1;
        set_default_line_attr(m93v.line_attr [ m93v.bottom] );
        IF  m93v.bottom = m93v.top
        THEN
            m93v.top := (m93v.top MOD max_lines) + 1;
        (*ENDIF*) 
        m93v.lines [ m93v.bottom ] := m93v.blank_screenline
        END;
    (*ENDIF*) 
    m93v.window_bottom := (m93v.window_bottom MOD max_lines) + 1;
    IF  m93v.window_bottom <> m93v.window_top
    THEN
        m93v.is_new_page [ m93v.window_bottom ] := false
    (*ENDIF*) 
    END;
(*ENDIF*) 
m93v.currline := (m93v.currline MOD max_lines) + 1;
IF  m93v.window_currline >= m93v.max_window_lines
THEN
    m93v.window_top := (m93v.window_top MOD max_lines) + 1
ELSE
    m93v.window_currline := m93v.window_currline + 1;
(*ENDIF*) 
m93v.currcol := 1;
END;
 
(*------------------------------*) 
 
PROCEDURE
      build_page(is_input : boolean);
 
VAR
      i               : integer;
      curr            : integer;
      line_count      : integer;
      length          : integer;
      pos             : integer;
      attr            : tin_ls_fieldtype;
      piece : termprot_piece;
 
BEGIN
m93v.holding_linecount := 0;
m93v.is_protected := true;
line_count    := 0;
WITH m93desc,m93v.header DO
    m95putfield(text,len,row,col,ft,
          m93desc.num_of_lines,m93desc.num_of_cols,
          content_buf^, attribute_buf^);
(*ENDWITH*) 
WITH m93desc,m93v.top_msg DO
    m95putfield(text,len,row,col,ft,
          m93desc.num_of_lines,m93desc.num_of_cols,
          content_buf^, attribute_buf^);
(*ENDWITH*) 
m93v.space_stream.row := nr_header_lines;
WITH m93desc,m93v.space_stream DO
    m95putfield(text,len,row,col,ft,
          m93desc.num_of_lines,m93desc.num_of_cols,content_buf^,
          attribute_buf^);
(*ENDWITH*) 
curr := m93v.window_top;
IF  m93v.window_currline > 0
THEN
    REPEAT
        line_count := line_count + 1;
        pos         := 1;
        length      := mt_linelength - 2; (* !!! *)
        attr        := m93v.line_attr [curr] ;
        IF  ls_input IN m93v.line_attr [curr] .fieldmode
        THEN
            m93v.is_protected := false;
        (*ENDIF*) 
        WITH piece DO
            BEGIN
            len := length;
            row := nr_header_lines + line_count;
            col := pos;
            ft := attr;
            text := m93v.lines [curr] ;
            END;
        (*ENDWITH*) 
        WITH m93desc,piece DO
            m95putfield(text,len,row,col,ft,
                  m93desc.num_of_lines,m93desc.num_of_cols,content_buf^,
                  attribute_buf^);
        (*ENDWITH*) 
        curr := (curr MOD max_lines) + 1;
    UNTIL
        (line_count >= m93v.max_window_lines)
        OR m93v.is_new_page [ curr ]
        OR (curr = (m93v.window_bottom MOD max_lines)+1);
    (*ENDREPEAT*) 
(*ENDIF*) 
FOR curr := line_count+1 TO m93v.prev_window_linecount DO
    BEGIN
    m93v.space_stream.row := nr_header_lines + curr;
    WITH m93desc,m93v.space_stream DO
        m95putfield(text,len,row,col,ft,
              m93desc.num_of_lines,m93desc.num_of_cols,content_buf^,
              attribute_buf^);
    (*ENDWITH*) 
    END;
(*ENDFOR*) 
m93v.prev_window_linecount := line_count;
out_termprot(is_input);
END;
 
(*------------------------------*) 
 
PROCEDURE
      out_termprot(is_input : boolean);
 
VAR
      options        : tsp_vt_options;
      result         : tsp_vt_result;
      ok : boolean;
 
BEGIN
m93cline := m93v.window_currline + nr_header_lines;
m93ccol := m93v.currcol;
WITH options DO
    BEGIN
    wait_for_input  := is_input OR m93hld;
    usage_mode      := vt_form;
    return_on_last  := false;
    return_on_first := false;
    returnkeys      := [  vt_enter, vt_do_key ] ;
    reject_keys     := [  ] ;
    bell := false;
    mark               := vt_mark_off;
    first_line_changed := 1;
    last_line_changed := m93desc.num_of_lines;
    overtype := false;
    END;
(*ENDWITH*) 
result.keystroke.key := vt_enter; (* !!! *)
WITH m93desc DO
    sqltio(m93tref, content_buf, attribute_buf,
          false, m93cline, m93ccol, m93hif, options, result, ok);
(*ENDWITH*) 
IF  options.wait_for_input
THEN
    m93rk := result.keystroke.key;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93putscreen (VAR text : tin_screenline);
 
VAR
      ft : tin_ls_fieldtype;
 
BEGIN
set_default_line_attr(ft);
m93put (text, ft);
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93put (VAR text : tin_screenline; ft : tin_ls_fieldtype);
 
BEGIN
next_line;
m93v.lines [ m93v.currline ] := text;
m93v.line_attr [ m93v.currline ] := ft;
m93v.holding_linecount := m93v.holding_linecount + 1;
IF  m93v.holding_linecount >= m93v.max_holding_linecount
THEN
    build_page(false);
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      m9320put_screen_20 (text : tsp_c20);
 
VAR
      ft : tin_ls_fieldtype;
 
BEGIN
set_default_line_attr(ft);
m93put20 (text, ft)
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93put20 (text : tsp_c20; ft : tin_ls_fieldtype);
 
VAR
      i : integer;
      ln : tin_screenline;
 
BEGIN
ln := m93v.blank_screenline;
FOR i:=1 TO 20 DO
    ln  [i]  := text  [i] ;
(*ENDFOR*) 
m93put (ln, ft);
END;
 
(*------------------------------*) 
 
PROCEDURE
      m9330put_screen_30 (text : tsp_c30);
 
VAR
      ft : tin_ls_fieldtype;
 
BEGIN
set_default_line_attr(ft);
m93put30 (text, ft)
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93put30 (text : tsp_c30; ft : tin_ls_fieldtype);
 
VAR
      i  : integer;
      ln : tin_screenline;
 
BEGIN
ln := m93v.blank_screenline;
FOR i:=1 TO 30 DO
    ln  [i]  := text  [i] ;
(*ENDFOR*) 
m93put (ln, ft);
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93getscreen (VAR text : tsp_line);
 
VAR
      dummy_pfkey : pfkeytype;
 
BEGIN
m93get (text, dummy_pfkey)
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93get (VAR text : tsp_line; VAR pfkey : pfkeytype);
 
VAR
      i : integer;
 
BEGIN
pfkey := pf_none;
next_line;
m93v.is_holding := true;
IF  NOT m93v.is_batch
THEN
    BEGIN
    IF  (m93v.line_attr [m93v.currline] .fieldmode = [   ] )
    THEN
        BEGIN
        set_default_line_attr(m93v.line_attr [ m93v.currline] );
        m93v.line_attr [ m93v.currline] .fieldmode := [  ls_input ] ;
        m93v.lines [m93v.currline ] := m93v.blank_screenline
        END;
    (*ENDIF*) 
    m93v.lines [ m93v.currline ] [1]  := prompting_sign;
    m93v.currcol := 2;
    terminal_read(pfkey);
    END;
(*ENDIF*) 
text := m93v.blankline;
IF  m93v.lines [ m93v.currline ] [1]  = prompting_sign
THEN
    FOR i := 1 TO mt_linelength-1 DO
        text [i]  := m93v.lines [m93v.currline]  [1+i ]
    (*ENDFOR*) 
ELSE
    FOR i := 1 TO mt_linelength DO
        text  [i]  := m93v.lines [ m93v.currline ] [i] ;
    (*ENDFOR*) 
(*ENDIF*) 
IF  m93v.count_cmd_lines [ (m93v.last_cmd_no MOD max_last_cmds)+1 ] = 0
THEN
    BEGIN
    m93v.last_cmd_no := (m93v.last_cmd_no MOD max_last_cmds) + 1;
    m93v.count_cmd_lines [ m93v.last_cmd_no ] := 1;
    m93v.last_cmd_lines [ m93v.last_cmd_no ]  [1]  :=
          m93v.lines [m93v.currline ]
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      terminal_read (VAR pfkey : pfkeytype);
 
VAR
      cmd_no      : integer;
      curr        : integer;
      i           : integer;
      pos         : integer;
      stream_pos  : integer;
      vt_enter_line  : tsp_int2;
      vt_enter_col   : tsp_int2;
      length : integer;
      input : tin_screenline;
      found : boolean;
      field_changed : boolean;
 
BEGIN
cmd_no := m93v.last_cmd_no;
pfkey := pf_none;
REPEAT
    build_page(true);
    vt_enter_line := m93cline;
    vt_enter_col := m93ccol;
    m93row := 0;
    m93col := 0;
    REPEAT
        REPEAT
            WITH m93desc DO
                m95nextfield(m93row,m93col, length,
                      found,field_changed,
                      m93desc.num_of_lines,m93desc.num_of_cols,
                      content_buf^, attribute_buf^);
            (*ENDWITH*) 
            IF  m93v.is_protected
            THEN
                found := false;
            (*ENDIF*) 
            IF  found
            THEN
                BEGIN
                WITH m93desc DO
                    m95getfield(m93row,m93col,length,input,
                          m93desc.num_of_cols,content_buf^);
                (*ENDWITH*) 
                IF  (m93rk=vt_clear) OR (m93rk=vt_unknown)
                THEN
                    BEGIN
                    m93reset_screen;
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        UNTIL
            ((m93rk <> vt_clear) AND (m93rk <> vt_unknown))
            OR (NOT found);
        (*ENDREPEAT*) 
        IF  found
        THEN
            BEGIN
            curr := m93row;
            IF  (length > 0) AND (curr > nr_header_lines) AND
                (curr <= nr_header_lines +
                m93v.max_window_lines)
            THEN
                BEGIN
                curr := (curr - nr_header_lines
                      + m93v.window_top - 1) MOD max_lines;
                IF  curr = 0
                THEN
                    curr := max_lines;
                (*ENDIF*) 
                pos := m93col;
                stream_pos := 1;
                m93v.lines [curr] := m93v.blank_screenline;
                WHILE (stream_pos <= length) AND
                      (pos <= mt_linelength) DO
                    BEGIN
                    m93v.lines [curr]  [pos ] :=
                          input [stream_pos] ;
                    stream_pos := stream_pos + 1;
                    pos := pos + 1
                    END
                (*ENDWHILE*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
    UNTIL
        NOT found;
    (*ENDREPEAT*) 
    m93v.is_protected := true;
    m93v.currcol := vt_enter_col;
    m93v.window_currline := vt_enter_line - nr_header_lines;
    IF  (m93v.window_currline < 1) OR
        (m93v.window_currline > m93v.max_window_lines)
    THEN
        m93v.window_currline := 1;
    (*ENDIF*) 
    m93v.currline:= (m93v.window_top + m93v.window_currline - 1)
          MOD max_lines;
    IF  m93v.currline = 0
    THEN
        m93v.currline := max_lines;
    (*ENDIF*) 
    CASE m93rk OF
        vt_do_key, vt_cmd_key, vt_enter:
            m93v.currcol := 1;
        vt_help_key, vt_sk01, vt_pf01:
            pfkey := pf_help;
        vt_cancel_key, vt_sk02, vt_pf02:
            BEGIN
            pfkey := pf_cancel;
            m93v.currcol := 1;
            END;
        vt_end_key, vt_sk03, vt_pf03:
            pfkey := pf_end;
        OTHERWISE:
            m93reset_screen
        END
    (*ENDCASE*) 
UNTIL
    m93rk in [  vt_do_key, vt_cmd_key, vt_enter, vt_help_key,
    vt_sk01, vt_pf01, vt_cancel_key, vt_sk02, vt_pf02,
    vt_end_key, vt_sk03, vt_pf03, vt_sk05, vt_pf05 ]
(*ENDREPEAT*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93string_get_screen (VAR text : tsp_line; VAR last_line : boolean);
 
VAR
      i : integer;
 
BEGIN
IF  m93v.first_cmd_line < 1
THEN
    BEGIN
    m93v.first_cmd_line := m93v.currline;
    m93v.last_cmd_line := m93v.currline
    END;
(*ENDIF*) 
text := m93v.blankline;
IF  m93v.lines [ m93v.first_cmd_line ]  [1]  = prompting_sign
THEN
    FOR i := 1 TO mt_linelength-1 DO
        text  [i]  := m93v.lines [ m93v.first_cmd_line]  [1+i ]
    (*ENDFOR*) 
ELSE
    FOR i := 1 TO mt_linelength DO
        text  [i]  := m93v.lines [ m93v.first_cmd_line ] [i] ;
    (*ENDFOR*) 
(*ENDIF*) 
IF  m93v.first_cmd_line = m93v.last_cmd_line
THEN
    BEGIN
    last_line := true;
    m93v.first_cmd_line := 0
    END
ELSE
    BEGIN
    last_line := false;
    m93v.first_cmd_line := (m93v.first_cmd_line MOD max_lines) + 1
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93new_screen_page;
 
VAR
      pfkey     : pfkeytype;
      close_err : tsp_vf_return;
      hfe       : tsp_int2;
 
BEGIN
pfkey := pf_none;
IF  (m93v.holding_linecount > 0)
THEN
    build_page(false);
(*ENDIF*) 
m93v.window_currline := 0;
m93v.currcol := 1;
m93v.window_top := (m93v.currline MOD max_lines) + 1;
m93v.is_new_page [ m93v.window_top ] := true
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93reset_screen;
 
VAR
      i      : integer;
 
BEGIN
IF  NOT m93v.is_pascal_io
THEN
    BEGIN
    WITH m93desc DO
        m95clear(vt_black,m93desc.num_of_cols*m93desc.num_of_lines,
              content_buf^, attribute_buf^);
    (*ENDWITH*) 
    m93v.prev_window_linecount := 0;
    WITH m93desc,m93v.header DO
        m95putfield(text,len,row,col,ft,
              m93desc.num_of_lines,m93desc.num_of_cols,content_buf^,
              attribute_buf^);
    (*ENDWITH*) 
    WITH m93desc,m93v.top_msg DO
        m95putfield(text,len,row,col,ft,
              m93desc.num_of_lines,m93desc.num_of_cols,content_buf^,
              attribute_buf^);
    (*ENDWITH*) 
    WITH m93desc,m93v.bottom_msg DO
        m95putfield(text,len,row,col,ft,
              m93desc.num_of_lines,m93desc.num_of_cols,content_buf^,
              attribute_buf^);
    (*ENDWITH*) 
    build_page(false);
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93def_screen_header (htext : tin_screenline);
 
VAR
      holding : boolean;
      i       : integer;
 
BEGIN
holding := m93v.is_holding;
m93v.is_holding := false;
WITH m93desc,m93v.bottom_msg DO
    m95putfield(htext,len,row,col,ft,
          m93desc.num_of_lines,m93desc.num_of_cols,content_buf^,
          attribute_buf^);
(*ENDWITH*) 
m93new_screen_page;
m93reset_screen;
m93v.is_holding := holding
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93undef_screen_header;
 
VAR
      i       : integer;
      holding : boolean;
 
BEGIN
IF  NOT m93v.is_pascal_io
THEN
    BEGIN
    holding := m93v.is_holding;
    m93v.is_holding := false;
    m93new_screen_page;
    m93frame;
    FOR i := 1 TO mt_linelength DO
        m93v.header.text  [i]  := ' ';
    (*ENDFOR*) 
    m93reset_screen;
    m93v.is_holding := holding
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93frame;
 
BEGIN
m93v.top_msg.row := 2;
m93v.max_window_lines := terminal_lines - nr_header_lines - 1;
IF  m93v.max_holding_linecount > 1
THEN
    m93v.max_holding_linecount := m93v.max_window_lines
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      m93hold (on : boolean);
 
BEGIN
m93hld := on;
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
*-PRETTY-*  statements    :        278
*-PRETTY-*  lines of code :        907        PRETTYX 3.10 
*-PRETTY-*  lines in file :       1420         1997-12-10 
.PA 
