.CM  SCRIPT , Version - 1.1 , last edited by holger
.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2004 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.TT 1 $SQL$Project Distributed Database System$VIN50$
.tt 2 $$$
.TT 3 $$Logischer Bildschirm$1998-09-15$
***********************************************************
.nf
 
.nf
 
 
    ========== licence begin  GPL
    Copyright (c) 2000-2004 SAP AG
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
 
    This program 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 General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
 
.fo
 
 
.fo
.nf
.sp
MODULE  : logical_screen
=========
.sp
Purpose : Logischer Bildschirm
 
&       if $OS=UNIX
&       define hifmode 1
&       else
&       ifdef WINDOWS
&       define hifmode 1
&       endif
&       endif
 
&     ifdef WINDOWS
&     define SCROLL 1
&     endif
.CM *-END-* purpose -------------------------------------
.sp
Define  :
 
        PROCEDURE
              i50on (
                    VAR ok : boolean);
 
        PROCEDURE
              i50mfset (
                    VAR msgnos : tin_msgnos);
 
        PROCEDURE
              i50standardattributes;
 
        PROCEDURE
              i50clear (
                    screen_part : tin_ls_part );
 
        PROCEDURE
              i50cl2(
                    sno : tsp00_Int2;
                    screen_part : tin_ls_part );
 
        PROCEDURE
              i50clwindow (
                    first_pos    : tin_ls_position;
                    window_len   : tin_natural;
                    window_width : tin_natural);
 
        PROCEDURE
              i50clscreenpart (
                    screen_no      : integer;
                    part           : tin_ls_part;
                    with_partframe : boolean);
 
        PROCEDURE
              i50attchange (
                    first_pos  : tin_ls_position;
                    lines,cols : tin_natural;
                    new_att    : tin_ls_fieldtype);
 
        PROCEDURE
              i50keymap;
 
        PROCEDURE
              i50info (
                    VAR modes : tsp00_VtAttrib;
                    VAR keys  : tin_ls_key_set);
 
        PROCEDURE
              i50off (
                    VAR msg : tin_screenline);
 
        PROCEDURE
              i50abspos (
                    VAR pos : tin_ls_position);
 
        PROCEDURE
              i50put1field (
                    VAR field  : tsp00_MoveObj;
                    length     : tin_natural;
                    field_pos  : tin_ls_position;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50put2field (
                    VAR field  : tsp00_MoveObj;
                    length     : tin_natural;
                    field_pos  : tin_ls_position;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50put3field (
                    VAR field  : tsp00_MoveObj;
                    length     : tin_natural;
                    field_pos  : tin_ls_position;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50put4field (
                    VAR field  : tsp00_MoveObj;
                    length     : tin_natural;
                    field_pos  : tin_ls_position;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50put5field (
                    VAR field  : tsp00_MoveObj;
                    length     : tin_natural;
                    field_pos  : tin_ls_position;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50put6field (
                    VAR field  : tsp00_MoveObj;
                    length     : tin_natural;
                    field_pos  : tin_ls_position;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50put7field (
                    VAR field  : tsp00_MoveObj;
                    length     : tin_natural;
                    field_pos  : tin_ls_position;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50put8field (
                    VAR field  : tsp00_MoveObj;
                    length     : tin_natural;
                    field_pos  : tin_ls_position;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50put9field (
                    VAR field  : tsp00_MoveObj;
                    length     : tin_natural;
                    field_pos  : tin_ls_position;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50erasefield (
                    field_pos : tin_ls_position);
 
        PROCEDURE
              i50putattribute (
                    field_pos  : tin_ls_position;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50fillattribute (
                    field_pos  : tin_ls_position;
                    count      : integer;
                    field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i50hscroll (
                    screen_nr    : integer;
                    screen_part  : tin_ls_part;
                    scroll_cols  : tsp00_Int2);
 
        PROCEDURE
              i50vscroll (
                    screen_nr    : integer;
                    screen_part  : tin_ls_part;
                    scroll_lines : tsp00_Int2);
 
        PROCEDURE
              i50insertlabel (
                    VAR lab : tsp00_VtLabel;
                    ft      : tin_ls_fieldtype;
                    pos     : tin_ls_position);
 
        PROCEDURE
              i50autoscroll;
 
        PROCEDURE
              i50getwindow (
                    first_pos          : tin_ls_position;
                    window_len         : tin_natural;
                    window_width       : tin_natural;
                    VAR window_changed : boolean);
 
        PROCEDURE
              i50getfield (
                    VAR vt_input    : tin_ls_input_field;
                    VAR field_found : boolean);
 
        PROCEDURE
              i50directgetfield (
                    VAR pos      : tin_ls_position;
                    length       : tsp00_Int2;
                    VAR vt_input : tin_ls_input_field);
 
        PROCEDURE
              i50savescreen(
                    screen_nr       : tsp00_Int2;
                    VAR save_screen : tsp00_MoveObj;
                    VAR save_att    : tsp00_MoveObj;
                    size            : integer;
                    VAR ok          : boolean);
 
        PROCEDURE
              i50restorescreen(
                    screen_nr       : tsp00_Int2;
                    VAR save_screen : tsp00_MoveObj;
                    VAR save_att    : tsp00_MoveObj);
 
        PROCEDURE
              i50putlineattributes (
                    VAR attr_line : tin_screenline;
                    field_pos     : tin_ls_position;
                    count         : integer );
 
        PROCEDURE
              i50getlineattributes (
                    VAR attr_line : tin_screenline;
                    field_pos     : tin_ls_position;
                    count         : integer );
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              global_variable : VIN01;
 
        VAR
              i01g : tin_global_in_vars;
&       ifdef TEST
 
      ------------------------------ 
 
        FROM
              Test-Treiber : VMT01;
 
        PROCEDURE
              m01inittest;
 
        PROCEDURE
              m01terminate_test;
&       endif
 
      ------------------------------ 
 
        FROM
              logical_screen_layout : VIN51;
 
        PROCEDURE
              i51init;
 
        PROCEDURE
              i51initbasicwindow (
                    nr_screens : integer );
 
        PROCEDURE
              i51size (
                    screen_part    : tin_ls_part;
                    VAR partlength : tin_natural;
                    VAR partwidth  : tin_natural);
 
        PROCEDURE
              i51size2 (
                    sno            : integer;
                    screen_part    : tin_ls_part;
                    VAR partlength : tin_natural;
                    VAR partwidth  : tin_natural);
 
      ------------------------------ 
 
        FROM
              logical_screen_variants : VIN52;
 
        PROCEDURE
              i52init;
 
        PROCEDURE
              i52mfset (
                    VAR msgnos : tin_msgnos);
 
        PROCEDURE
              i52pfkeymap;
&       ifdef hifmode
 
        PROCEDURE
              i52skkeymap;
&       endif
 
        FUNCTION
              i52rf (
                    rk : tsp00_VtKey) : tin_ls_releasemode;
 
        PROCEDURE
              i52fromscreenpos (
                    VAR pos       : tin_ls_position;
                    VAR screenlno : tin_natural;
                    VAR screencol : tin_natural);
 
        PROCEDURE
              i52toscreenpos (
                    lno            : tin_natural;
                    col            : tin_natural;
                    preferred_part : tin_ls_part;
                    VAR pos        : tin_ls_position);
 
      ------------------------------ 
 
        FROM
              logical_screen_procedures : VIN53;
 
        PROCEDURE
              i53check_field_for_multibyte (
                    VAR field  : tsp00_MoveObj;
                    length     : integer);
 
        PROCEDURE
              i53putlineattributes (
                    sno              : tsp00_Int2;
                    field_slno       : integer;
                    field_scol       : integer;
                    count            : integer;
                    VAR attr_line    : tin_screenline;
                    maxcols          : integer;
                    vt_att           : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53getlineattributes (
                    sno              : tsp00_Int2;
                    field_slno       : integer;
                    field_scol       : integer;
                    count            : integer;
                    VAR attr_line    : tin_screenline;
                    maxcols          : integer;
                    vt_att           : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53changelimits (
                    sno   : tsp00_Int2;
                    rowno : tsp00_Int2);
 
        PROCEDURE
              i53erasefield(
                    field_slno               : integer;
                    field_scol               : integer;
                    num_of_lines,num_of_cols : integer;
                    vt_screen                : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53clear (
                    att               : tin_ls_attribute_index;
                    maxlines, maxcols : integer;
                    vt_screen         : tsp00_ScreenBufAddr;
                    vt_att            : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53clwindow (
                    sno                      : tsp00_Int2;
                    first_row,first_col      : integer;
                    last_row, last_col       : integer;
                    ft                       : tin_ls_fieldtype;
                    num_of_lines,num_of_cols : integer;
                    vt_screen                : tsp00_ScreenBufAddr;
                    vt_att                   : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53put1field (
                    VAR field                : tsp00_MoveObj;
                    length                   : integer;
                    sno                      : tsp00_Int2;
                    field_slno               : integer;
                    field_scol               : integer;
                    VAR ft                   : tin_ls_fieldtype;
                    num_of_lines,num_of_cols : integer;
                    vt_screen                : tsp00_ScreenBufAddr;
                    vt_att                   : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53put2field (
                    VAR field                : tsp00_MoveObj;
                    length                   : integer;
                    sno                      : tsp00_Int2;
                    field_slno               : integer;
                    field_scol               : integer;
                    VAR ft                   : tin_ls_fieldtype;
                    num_of_lines,num_of_cols : integer;
                    vt_screen                : tin_lineaddr;
                    vt_att                   : tin_lineaddr);
 
        PROCEDURE
              i53put1attribute (
                    sno         : tsp00_Int2;
                    field_slno  : integer;
                    field_scol  : integer;
                    VAR ft      : tin_ls_fieldtype;
                    num_of_cols : integer;
                    vt_att      : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53put2attribute (
                    sno         : tsp00_Int2;
                    field_slno  : integer;
                    field_scol  : integer;
                    VAR ft      : tin_ls_fieldtype;
                    num_of_cols : integer;
                    vt_att      : tin_lineaddr);
 
        PROCEDURE
              i53fillattribute (
                    sno         : tsp00_Int2;
                    field_slno  : integer;
                    field_scol  : integer;
                    count       : integer;
                    VAR ft      : tin_ls_fieldtype;
                    num_of_cols : integer;
                    vt_att      : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53fieldtypetochars (
                    ft      : tin_ls_fieldtype;
                    VAR att : tsp00_C1);
 
        PROCEDURE
              i53nextfield (
                    VAR row,col       : integer;
                    VAR length        : integer;
                    VAR found         : boolean;
                    VAR field_changed : boolean;
                    num_of_lines      : integer;
                    num_of_cols       : integer;
                    vt_screen         : tsp00_ScreenBufAddr;
                    vt_att            : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53getfield (
                    row,col           : integer;
                    VAR length        : integer;
                    VAR input         : tin_screenline;
                    maxcols           : integer;
                    vt_screen         : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53attchange (
                    sno               : tsp00_Int2;
                    win               : tin_ls_window;
                    VAR ft            : tin_ls_fieldtype;
                    maxcols           : integer;
                    vt_att            : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53screenaddresses (
                    sno          : tsp00_Int2;
                    VAR screen   : tsp00_ScreenBufAddr;
                    VAR att      : tsp00_ScreenBufAddr;
                    VAR maxlines : tsp00_Int2;
                    VAR maxcols  : tsp00_Int2 );
 
        FUNCTION
              i53tobufpos (
                    lno, col : integer;
                    maxcols  : integer) : integer;
 
        FUNCTION
              i53fchanged (
                    vt_att   : tsp00_ScreenBufAddr;
                    lno, col : integer;
                    length   : integer;
                    maxcols  : integer ) : boolean;
 
      ------------------------------ 
 
        FROM
              logical_screen_help_procedures : VIN54;
 
        PROCEDURE
              i54gpartsdefaults (
                    part   : tin_ls_part;
                    VAR ft : tin_ls_fieldtype);
 
        PROCEDURE
              i54initls_pos (
                    VAR ls_pos : tin_ls_position);
 
        PROCEDURE
              i54disablescreenpart (
                    sno  : integer;
                    part : tin_ls_part);
 
        PROCEDURE
              i54definelayoutwindow (
                    pos             : tin_ls_position;
                    lines,cols      : integer;
                    VAR description : tin_ls_window;
                    VAR ok          : boolean);
 
        PROCEDURE
              i54setwindowlimits (
                    sno                 : tsp00_Int2;
                    first_lno,first_col : integer;
                    last_lno,last_col   : integer;
                    ft                  : tin_ls_fieldtype);
 
        PROCEDURE
              i54resolvedefaults (
                    part           : tin_ls_part;
                    VAR field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i54fieldtype (
                    VAR ft : tin_ls_fieldtype );
&       ifdef WINDOWS
 
      ------------------------------ 
 
        FROM
              logical_screen_modules : VIN56 ;
 
        VAR
              i56input_from_box : boolean;
              i56recursion      : tsp00_Int2;
              i56sysline2       : tsp00_Line;
              i56sysatt2        : tsp00_Line;
 
        PROCEDURE
              i56init;
 
        PROCEDURE
              i56todialogbox (
                    VAR field      : tsp00_MoveObj;
                    length         : tin_natural;
                    VAR field_pos  : tin_ls_position;
                    VAR field_type : tin_ls_fieldtype);
 
        PROCEDURE
              i56getwindow (
                    first_pos          : tin_ls_position;
                    VAR window_changed : boolean);
 
        PROCEDURE
              i56getfield (
                    VAR vt_input    : tin_ls_input_field;
                    VAR field_found : boolean);
 
        PROCEDURE
              i56hrange (
                    screen_nr  : integer;
                    VAR hrange : tin_display_range);
 
        PROCEDURE
              i56vrange (
                    screen_nr  : integer;
                    VAR lbl    : tsp00_C8;
                    VAR vrange : tin_display_range);
 
        PROCEDURE
              i56clwinheader (
                    screen_nr : integer );
 
        PROCEDURE
              i56dlgerase (
                    screen_part : tin_ls_part );
 
        FUNCTION
              i56spartswitched (
                    screenpart : tin_ls_part ) : boolean;
&       endif
 
      ------------------------------ 
 
        FROM
              logical_screen_IO : VIN57 ;
 
        PROCEDURE
              i57vtopt_init;
 
      ------------------------------ 
 
        FROM
              RTE_driver : VEN102;
 
        PROCEDURE
              sqlttable (
                    i          : tsp00_Int2;
                    att        : tsp00_VtAttrib;
                    foreground : tsp00_VtColor;
                    background : tsp00_VtColor);
 
        PROCEDURE
              sqlton (
                    multi_task   : boolean;
                    VAR term_ref : tsp00_Int4;
                    VAR desc     : tsp00_TerminalDescription;
                    VAR ok       : boolean);
 
        PROCEDURE
              sqltoff (
                    term_ref          : tsp00_Int4;
                    VAR screen_buf    : tsp00_ScreenBufAddr;
                    VAR attribute_buf : tsp00_ScreenBufAddr;
                    VAR msg           : tsp00_C80);
 
        PROCEDURE
              sqlwrite (
                    VAR text : tsp00_Line);
&       ifdef SCROLL
 
      ------------------------------ 
 
        FROM
              Windows_RTE_Extension : VEN102W ;
 
        PROCEDURE
              sqlwscroll (
                    term_ref : tsp00_Int4;
                    VAR rect : tsp00_VtRectangle;
                    displ_x  : tsp00_Int2;
                    displ_y  : tsp00_Int2;
                    VAR ok   : boolean);
&       endif
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalForcedFill (
                    size        : tsp00_Int4;
                    m           : tsp00_MoveObjPtr;
                    pos         : tsp00_Int4;
                    len         : tsp00_Int4;
                    fillchar    : char);
 
        PROCEDURE
              SAPDB_PascalForcedMove (
                    source_upb  : tsp00_Int4;
                    destin_upb  : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    source_pos  : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    destin_pos  : tsp00_Int4;
                    length      : tsp00_Int4);
 
        PROCEDURE
              s10mv (
                    source_upb  : tsp00_Int4;       
                    destin_upb  : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;    
                    source_pos  : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;    
                    destin_pos  : tsp00_Int4;
                    length      : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30 : VSP30 ;
 
        FUNCTION
              s30gad (
                    VAR b : tsp00_Line) : tin_lineaddr;
 
        FUNCTION
              s30gad1(
                    VAR b : tsp00_Line) : tsp00_ScreenBufAddr;
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              i53put2field;
 
              tsp00_ScreenBuf tsp00_Line
 
        PROCEDURE
              i53fieldtypetochars;
 
              char tsp00_C1
 
        PROCEDURE
              i56todialogbox;
 
              tsp00_Line tsp00_MoveObj
 
        PROCEDURE
              i53put2attribute;
 
              tin_ls_fieldtype tin_ls_fieldtype
              tsp00_ScreenBufAddr tin_lineaddr
 
        PROCEDURE
              i53attchange;
 
              tsp00_ScreenBufAddr tin_lineaddr
 
        FUNCTION
              s30gad;
 
              tsp00_MoveObj tsp00_Line
              tsp00_Addr tin_lineaddr
 
        FUNCTION
              s30gad1;
 
              tsp00_MoveObj tsp00_Line
              tsp00_Addr tsp00_ScreenBufAddr;
 
        PROCEDURE
              i53put2field;
 
              tsp00_ScreenBufAddr tin_lineaddr
 
        PROCEDURE
              sqlttable;
 
              tsp00_Int2     tsp00_Int2
              tsp00_VtAttrib tsp00_VtAttrib
              tsp00_VtColor  tsp00_VtColor
              tsp00_VtColor  tsp00_VtColor
 
        PROCEDURE
              sqlton;
 
              tsp00_Int4                tsp00_Int4
              tsp00_TerminalDescription tsp00_TerminalDescription
 
        PROCEDURE
              sqltoff;
 
              tsp00_Int4           tsp00_Int4
              tsp00_ScreenBufAddr  tsp00_ScreenBufAddr
              tsp00_ScreenBufAddr  tsp00_ScreenBufAddr
              tsp00_VtMsg          tsp00_C80
 
        PROCEDURE
              sqlwrite;
 
              tsp00_Line  tsp00_Line
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1986-06-27
.sp
.cp 3
.sp
.cp 3
Release :      Date : 1998-09-15
.sp
***********************************************************
.pa
.cp 10
.fo
.oc _/1
Specification:
.sp 2;.fo;This module maintains the logical screen.
.sp 2;The logical screen presents the user interface of the dialog
components.  If required by the runtime environment, this interface can be
adapted slightly by the transport programs.
.sb 1;General information on positioning on the screen
.sp 2;.fo
A series of windows can be defined on the logical screen (currently,
up to 5) and the coordinates for the output fields or cursor can
be specified in relative window coordinates.
.sp;The user can define this window in that he himself assigns the
appropriate arrays of the global record I01_G (as for FORM) or calls a
procedure (i51layout) of this module that formats the screen in the way
in which it is normally used by the REFLEX components.
.sp2;.cp 12
The screen of a REFLEX dialog component (under VM) typically has the
following layout:
.nf;.cp 20;.sp
*-----------------------------
| QUERY 2.4 INPUT                  <---- header
| --------------------- R E F L E X
| ===
| ===
| ===
| ===
 ...
 ...                                     work window
 ...
| ===
| ===
| ===
|-----------------------------
| 1=HELP 2=RESET ...               <---- function menu
| And to leave QUERY,              <---- system line
| ==>                              <---- input area
*-----------------------------
.sp;.cp 20;or as follows:
.sp
*-----------------------------
| EASY 2.4  QUERY TABLE:  H        <---- header
| --------------------- R E F L E X
|    1 NO.......... : ....
|    2 NAME........ : ........
|    3 POSTCODE.... : ....
 ...
 ...                                     work window
 ...
| | 13 HAIR DRESSER : .
| | 14 REMARKS..... : ........
| |                   ........
| V                   ........
|-----------------------------
|    1=INFO      3=MENU   4=DR     <---- function menu
|    6=INSERT                             (2 lines)
| 100 lines not found              <---- system line
| Sorting sequence: ........ .     <---- input area
| Table:    ...............               (2 lines)
*-----------------------------
.sp2;.fo;.cp 8
Thus the typical screen of a dialog component consists of the
following:
.hi 20;.sp;Header:  Header line with component name, version number, etc.
This line is the first line on the screen.
.sp;Work window:  This is the main work area to which the
scrolling functions refer.
.sp;Function menu:  Can consist of a maximum of 2 lines and is
output according to the operating system:  under VM, same as in
the examples, as PF-key menu beneath the work window; under UNIX,
in the case of the DAP4x, as soft-key menu (permanently defined
terminal line, fixed format)
.sp;System line:  the line on the screen to which the system messages
are output.  For DAP4x, this is the last line on the
terminal (in the case of 'windows', handled separately);
otherwise, it is located beneath the function menu but could be
placed above the work window (could even be set by the user).
.sp;Input area:  Can consist of a maximum of 2 lines.
.hi 0
.sp 2;It is also possible to divide the screen horizontally into
two halves with identical layout.
.sb;Constants and types for screen layout
.sp2 ;In order to describe this screen layout, the following types
and variables are redefined:
.sp 2;The global variable I01_G has a field
.sp;           LS         : LS_RECORD;
.sp;with the definition
.sp;.nf
      ti_ls_record   = RECORD
            nr_screens          : 1..2;
            defaults            : ARRAY [ 1..2 ] OF global_fieldtype;
            description         : ARRAY [ 1..2 ] OF ti_ls_description;
            cmdline             : boolean;
            cursorpos           : ti_ls_position;
            fctline_cursor      : ti_ls_releasemode;
            enter_is_cmd        : boolean;
      END;
.sp;in which NR_SCREENS stores the number of screens (normally 1;
when split, 2) and DESCRIPTION [i]  stores the screen layout of
the particular section of the screen.
.sp;DESCRIPTION is of the type
.sp;   ti_ls_description = ARRAY [  ti_ls_part  ] OF ti_ls_window;
.sp;mit
.sp;.nf
     ti_ls_part = 1 .. 5;
 
     ti_ls_window = RECORD
            first_line : integer;
            last_line  : integer;
            first_col  : integer;
            last_col   : integer;
     END;
.sp;.fo
This array can be assigned the margins of the window desired.
In the case of windows that are not needed, all positions are set to 0.
.sp;Care must be taken that windows 4 and 5 are reserved for the
function-key menu of the particular software or
the message line so that 3 windows can be freely defined.
.sp;For screen layout as generally required by the dialog
components, I01_G^.LS.DESCRIPTION is assigned with the procedure I50_LAYOUT.
(see below).
.sp;The windows are then assigned in the sequence established
by the constants
.sp;.nf
CONST
      ci_ls_header       = 1;
      ci_ls_workarea     = 2;
      ci_ls_inputarea    = 3;
      ci_ls_functionmenu = 4;
      ci_ls_sysline      = 5;
.fo
.sp;.cp 12;Instead of the absolute screen coordinates, the screen
position is specified via a record of the
.sp;.nf
TYPE
      ti_ls_position = RECORD
            screen_nr   : 1..2;
            screen_part : ti_ls_part;
            scol        : ti_natural;
            sline       : ti_natural;
            END;
.fo
If the screen is divided into two parts (with I50_SPLIT, see below),
SCREEN_NR indicates the part of the the screen to be described.
If the screen is not divided, this parameter does not need to be
assigned.
.se;.cm Type definitions
.se;.cm Layout ...
.sp 2;.cp 12
.sb;Function keys
.sp2;After the user presses a key, the logical screen returns a variable
of the following type:
.sp;.cp 7
TYPE
.hi 16;
ls_releasemode\=  (f1, f2, f3, f4, f5, f6, f7, f8, f9,
f_help, f_up, f_down, f_enter, f_clear,
f_left, f_right, f_pick,
f_put, f_mark, f_select, f_move,
f_copy, f_insert, f_delete, f_top,
f_bottom, f_cancel, f_undo, f_cmd, f_local, f_end);
.hi 0;.sp;It is required
.oc _/1;in any case
that a terminal be able to implement the
functions f1 to f9, f_help to f_clear
(i.e. via 12 PF keys).
The other functions are optional functions that do not always
have to be present but, when they are present, the calling environment
can reacte to them.  An information function (i50info) can be queried as
to whether these functions are present on the current terminal.
sp;The hardware keys of the various terminal types are mapped
onto this type.
.sp 2;In the case of DAP4x, for example, this assignment appears as
follows:
.sp;.cp 12;.nf;.in +20
f1     <-- vt_sk01
       ...
       ...
       ...
f9     <-- vt_sk09
f_help <-- vt_help_key
f_up   <-- vt_up_key
f_down <-- vt_down_key
.sp;.cp 12;.fo;.in -20
for PF keys, it is as follows:
.sp;.cp 12;.nf;.in +20
f1     <-- vt_pf05      f2     <-- vt_pf09
f3     <-- vt_pf12      f4     <-- vt_pf10
f5     <-- vt_pf11      f6     <-- vt_pf06
f7     <-- vt_pf02      f8     <-- vt_pf04
f9     <-- vt_pf03      f_help <-- vt_pf01
f_up   <-- vt_pf07      f_down <-- vt_pf08
.sp;.cp 12;.fo;.in -20
.sp;The calling program first activates those functions that the logical
screen is to return.  The other terminal functions that are not
activated are immediately intercepted by the logical screen with the
message "Taste nicht belegt" (key not assigned).
.sp;This activation of the user functions takes place via a field
KEY_TYPE in the global record I01_G:
.sp;.cp 12;.nf
TYPE
     ti_ls_key_type = RECORD
           activated  : SET OF ti_ls_releasemode;
           highlighted: SET OF ti_ls_releasemode;
           key_labels : ti_key_labels_tab;
           key_map    : ARRAY [  ti_prog_function  ] OF ti_vt_releasemode;
     END;
such that
     ti_prog_function = f1 .. f_down
is a subrange of ti_ls_releasemode.
.sp;.fo;A set of functions is activated by assigning the appropriate
keys to SET ACTIVATED, e.g.:
.sp;.nf; I01_G^.KEY_TYPE.ACTIVATED := [  F_ENTER,F1 .. F9, F_HELP ] ;
.sp;.fo;The labels for the function munu are stored in KEY_LABELS,
(e.g. with key_labels [\f_help\] \:=\'INFO\\\\').
This function menu
displays the logical screen in the system-specific form when the
procedure I50_PUTLABELS is called (see below).
.sp;The function f_local is a special case:
If f_local is activated, the virtual terminal also returns local
key functions.  For more details, see i50ioscreen.
.sp;Functions that are not activated or whose labels are empty
(consist of blanks) are not displayed in this function menu.
.sp;The KEY_LABELS are most easily assigned by moving the current
soft-key line to KEY_LABELS with a SAPDB_PascalForcedMove (for SK01 to SK09) and
by carrying out the same procedure with the labels for HELP_KEY, etc.
(For the second SAPDB_PascalForcedMove, with a length of 24 only!!)
The constant LS_LABELS_LENGTH has been defined for
specifying the maximum length for these MOVEs.
.sp;The KEY_MAP contains the assignment of the functions to the
terminal keys and is assigned by I50_ON.  (In DIALOG, this assignment
can be altered by the application programmer, if necessary ]
.se;.cm Function keys
.sb;Adaptation to future expansions
.sb;Terminal attributes
.sp 2;.fo
The type
.sp 2;.nf;.cp 12
     ti_ls_fieldtype = RECORD
                    foreground : vt_color;
                    background : vt_color;
                    field_att  : vt_attrib;
                    fieldmode  : vt_inputmode;
                    END;
.sp 2;.fo;is used for the assignment of screen attributes and colors.
.oc _/1;Remarks:
.hi 3;.sp
In this case, att\=\ [\ ] or
FOREGROUND\=\DEFAULT_COLOR
or BACKGROUND\=\DEFAULT_COLOR signifies output with default
presentation or default color.
.sp;This default setting is initialized with I50_ON and stored in
the array
.sp;.nf
     I01_g^.LS.DEFAULTS : GLOBAL_FIELDTYPE
.sp;mit                defaults        : global_fieldtype;
     GLOBAL_FIELDTYPE = ARRAY [  LS_PART  ] OF LS_FIELDTYPE;
.sp;.fo;  It could be set individually later on with SETPARMS or
changed by the calling component.
.hi 0;.sp;A field is therefore output to the screen with a record of
the type LS_FIELDTYPE instead of with a (one-dimensional) attribute.
.se;.cm Expanded terminal attributes
.sb;Expanded put_screen option
.sp2;For the final screen output, a record of the type
.sp;.nf
TYPE
      vt_options         = RECORD
            wait_for_input  : boolean;
            cr_is_nextfield : boolean;
            return_on_last  : boolean;
            return_on_first : boolean;
            returnkeys      : vt_keys;
            reject_keys     : vt_keys;
            bell            : boolean;
      END;
.fo;.sp;is passed that is defined in the virtual terminal
(see LZU 2.4).
.hi 0
.sp;These options are partially ignored in some operating systems.
.hi 15
.hi 0
.se;.cm Expanded put_screen_option
.se;.cm Adaptations ...
.cp 12;.sb;Procedures of the logical screen
.sb;General procedures
.sp 2;.nf
PROCEDURE
      i50on (
            VAR ok : boolean);
.sp 2;.fo
This procedure initializes all global structures required by
the logical screen.
OK is then set to FALSE if no terminal is currently connected
because, for example, the component is running in batch mode.
.sp 2;.nf
PROCEDURE
      i50keymap;
.sp 2;.fo
This procedure resets the assignments between hardware keys and
ti_ls_releasemode to the system-specific status if the assignment contained
its own values beforehand.
.oc _/1;During normal operation, it does not need to be called!
.sp 2;.nf
PROCEDURE
      i50info (
            VAR modes : ls_mode_set;
            VAR keys  : ti_ls_key_set);
.sp 2;.fo
This is a procedure that provides information on the special
characteristics of the current terminal:
.hi 12;.sp;modes: In this SET, all terminal attributes that the
terminal can implement are returned.
.sp;keys: ls_releasemodes that the terminal can implement.
.hi 0;.sp;The calling program does not necessarily have to query this
information since, in the case of terminals that do not possess
the maximum characteristics, the logical screen reactes accordingly
(e.g. converts terminal attributes).  This procedure is designed more
for components that actually want to take advantage of all the
possibilities of the terminal.
.sp 2;.nf
PROCEDURE
      i50off (
            VAR msg : ti_screenline);
.sp 2;.fo
terminates the logical screen and outputs the text in MSG to the
terminal (e.g. error message).
.sp2;The standard layout for the REFLEX dialog components is
determined via the procedure
.sp;.cp 12;.nf
PROCEDURE
      i51layout (
            functionmenu_length : ti_natural;
                  inputarea_length    : ti_natural;
                  msglines            : ti_natural);
.fo;.hi 15;.sp;functionmenu_length:
specifies the maximum length of the function menu.  The logical screen
can ignore this option and set this length to 1 if hardware allows no
other alternative.  (Example:  soft-key menu ]  In this case, certain
functions are not displayed.
.sp;inputarea_length: Number of lines in the input area
.sp;command_input: must be set to TRUE if the system line may be
superimposed with the input line.  (See DAP4x, to be omitted in the near
future ]
.hi 0;.sp 2;This procedure is called each time the screen layout changes,
especially, of course, at the beginning of the program.
.sp 2;.cp 8;.nf
PROCEDURE
      i50split (
            screens : ti_natural);
.sp;.fo;With SCREEN\=\2, the screen is divided horizontally into two
identical halves; with SCREEN\=\1, this division is cancelled.
Following I50_SPLIT, the same standard DESCRIPTION is used as before.
.sp 2;It may be necessary for creating the screen to know
the size of a special logical screen area:
.sp 2;.cp 8;.nf
PROCEDURE
      i51size (
            screen_part : ti_ls_part;
            VAR length  : ti_natural;
            VAR width   : ti_natural);
.sp;.fo;returns the length and width of the screen area that is
defined via SCREEN_PART.
.se
.sb;Describing the screen
.sp 2;.nf
PROCEDURE
      i50clear (
            screen_part : ti_ls_part );
.sp 2;.fo
This procedure clears the screen form for the virtual terminal and
assigns the default attributes and colors to the logical screen area.
.sp;It must always be called before an entirely new screen is to be
created with the I50_PUTx_Field procedures.  When initialization is
done via I50_ON, this procedure is called implicitly.
.sp 2;With
the procedure
.sp;.nf;.cp 8
PROCEDURE
      i50put1field (
            VAR field  : moveobject;
            length     : ti_natural;
            field_pos  : ti_ls_position;
            field_type : ti_ls_fieldtype);
.sp;.fo;the specified field is stored in the global screen buffers.
The screen position is passed with the type LS_POSITION and the
expanded attribute entry is passed with FIELD_TYPE.
.sp;There are corresponding procedures such as i50put2field, etc.
for application in synonyms.
.sp 2;.cp 8;.nf
PROCEDURE
      i56putlabels (
            fct_cursorpos      : ti_ls_releasemode;
                          functionline_label : boolean);
.sp;.fo;Stores the output fields of the function menu in the screen
buffer in the form determined by the logical screen based on hardware
requirements (e.g. PF-key menu or soft-key menu).
.sp;The individual fields of this menu are output with the
field_type i01g^.ls.defaults [ci_ls_functionmenu ] of the default setting
(in particular, when desired and possible, as input fields so that the
cursor can be placed there).
.sp 2;For user prompting, the assignments of keys that
are not physically marked are displayed on the screen
with the current functions.
.sp;.hi 20
fct_cursorpos: If a function is specified here that is also displayed
by the function menu (generally, f1 to f9 and, possibly, f_help, f_up,
f_down) and SCREEN_PART\=\LS_FUNCTION_MENU is entered in the cursor
position for the subsequent I15_PUT_SCREEN, the cursor is placed on the
appropriate label.  Prerequisite is that this also be allowed by the
hardware.  If it is not desirable to have the cursor on a label field,
simply enter f_clear in fct_cursorpos.
.sp;functionline_label: If set to TRUE, the PF-key line is prefixed
with a label
(e.g. "function keys     :"), when possible.
.hi 0;.sp 2;.cp 12;.nf
PROCEDURE
      i56putframe;
.sp;.fo;prepares the output of the upper and lower margins of
the work window (horizontal lines).
.se;.cm Output ...
.sp 2;.cp 14;
.sb;Passing the screen created to the virtual terminal
.sp 2;.nf
PROCEDURE
      i50ioscreen (
            options            : ls_options;
            VAR csr_pos        : ti_ls_position;
            VAR rf             : ti_ls_releasemode;
                  VAR screen_changed : boolean);
.sp;.fo;With this procedure, control is relinquished to the terminal;
the screen buffer, which has, up until now, contained (possibly more
than one) PUT_FIELD, is passed on to the terminal.  The cursor
position CSR_POS (type LS_POSITION) specifies the initial location of
the cursor.
.sp;In the OPTIONS, the output options are required in the form
prescribed by the runtime environment.
.sp;Exception:  The return keys and reject keys can generally be set
to [ ] .  The RETURNKEYS be set exactly as intended only if the function
f_local is activated.
.oc _/1;(All
keys that are to be returned are specified)
.sp;.fo;After a release key is pressed that was assigned a function by the
calling environment, control is returned.  The screen contents are
then located in the global screen buffer.
.sp 2
The input key (RF), the cursor position (CSR_POS) and a BOOLEAN
value indicating whether anything has been changed anywhere on the
screen are returned.
.sp;If f_local was activated and one of the keys set in
returnkeys has been pressed, the exact key function can be
queried from
.sp;.nf
        i01g^.vt.parms.key;
.fo
.sp 2;.nf
PROCEDURE
      i50getwindow (
            first_pos          : ti_ls_position;
            window_len         : ti_natural;
            window_width       : ti_natural;
                  VAR window_changed : boolean);
.sp 2;.fo
This procedure is used to define an input window on the logical
screen.  The subsequent read operations with i50getfield then return
only those fields that are located within this window.
.sp;The defined window can only be located within a screen area of
the logical screen; in the event of invalid entries of
WINDOW_LEN or WINDOW_WIDTH, the last line/column of the area is
assumed.
.br;In particular, an entire area can be defined as a window by setting
FIRST_POS.SLINE and .SCOL to 1 and WINDOW_LEN and
WINDOW_WIDTH to, for example, 999.
.sp;I50_GETWINDOW must not be called until a I50_INSCREEN
has occured.
.sp;If I50_GETWINDOW is not called, the window is superimposed on the
.oc _/1;entire screen.
Nevertheless, it is best to call i50getwindow in any case since
the sequence of the screen areas for output is not fixed.
.sp;After each call of i50getwindow, the read process again starts
at the upper left-hand corner of the window.
.sp;WINDOW_CHANGED indicates whether a field within the window has
been changed.
.sp;.nf
PROCEDURE
      i50getfield (
            VAR ls_input    : ti_ls_input_field;
                  VAR field_found : boolean);
.sp;.fo;With this procedure, the fields of the input window
that was previously defined (with I50_GETWINDOW or by default)
are sequentially passed by VT_BUFFER.
.sp;FIELD_FOUND is then FALSE when no more fields are located in the
window defined (i.e. after the first failed attempt to find the last
input field).
.sp;.cp 12;.nf
TYPE
     ti_ls_input_field = RECORD
                    buf         : ti_screenline;
                    len         : ti_natural;
                    fld_pos     : ti_ls_position;
                    left_trunc  : ti_natural;
                    right_trunc : ti_natural;
                    changed     : boolean;
                    END;
.sp 2;.fo
This type is returned in the case of an input operation.  The field
position and the information on the screen part, relative line no. and
column no. that has been gathered in the meantime are defined here.
.sp;LEFT_TRUNC and RIGHT_TRUNC indicate (for window operations) how
many characters are located outside of a defined window to the right
or to the left, respectively.
.sp;CHANGED is assigned TRUE if the user has defined the pertinent field.
.se;.cm Reading in ...
.se;.cm Procedures
.sb;Expansion features : Windows
.sp 2;.sb 1;Expansion of LS_PART
.sp 2;The type LS_PART is expanded by 2 constants:
.hi 20;.sp;ci_ls_whole_screen: sline and scol in the record LS_POSITION
are absolute coordinates.
.sp;ci_ls_basic_window:
sline and scol in LS_POSITION are coordinates relative to the definition
of the currently valid basic window that is to be imagined around
the current screen layout.
.sp 2;.hi 0
.se;.sb;New procedures for defining windows
.sp 2;The following are new procedures:
.sp;.nf
PROCEDURE
      i50onwindow (
            defined_part      : ti_ls_part;
                         VAR pos           : ti_ls_position;
                         lines,cols        : ti_natural;
                         with_frame        : boolean;
                         change_background : boolean;
                         background_ft     : ti_ls_fieldtype;
                         VAR ok            : boolean );
.sp;and
.sp
PROCEDURE
         i50offwindowdow ;
.sp;.fo;With these procedures, a new window is defined
(I50ONWINDOW) or reset to the previous status
(I50OFFWINDOWDOW).
.sp;Layout and default attributes and colors are stored in VIN50
before the call of I50_ON_WINDOW and regenerated with I50OFFWINDOW.
.sp;.cp 25;The parameters:
.hi 15
.sp;defined_part logical-screen area that is affected by the window
definition:
.sp;@ defined_part^= ^ci_ls_workarea signifies, for example, that only the
work area is affected by the window operation.  Other areas retain their
current size and position.
.sp;@ In the case of defined_part^= ^ci_ls_basic_window, the entire basic
window is reduced in size.  The previously defined layout is "inherited"
by the new basic window.  From now on, all logical-screen areas are
located within this window.
.sp;pos upper left-hand corner of the window to be defined in absolute
coordinates (POS.SCREEN_PART^= ^LS_WHOLE_SCREEN), relative to the current
basic window (POS.SCREEN_PART^= ^LS_BASIC_WINDOW) or relative to a
logical-screen area.
.sp;lines,cols size of the window in lines and columns
.sp;with_frame
if TRUE, a frame is drawn around the defined window.  The effectively
usable window is reduced by two lines and 4 columns.
.sp;change_background if TRUE, the background of the current
SCREEN_PART is output with the specified
BACKGROUND_FT.
.sp;@ The following rules apply:  If the foreground or background colors
for the background are specified with DEFAULT_COLOR, the color of the
window background is not changed.
FIELDMODE^= ^VT_OUTPUT sets all background fields to output-only
whereas VT_INPUT leaves the fields as they are.
.sp;ok
is then returned as FALSE if more I50_ON_WINDOW calls have occured than
implementation allows (currently 6).
.hi 0
.sp;.oc _/1;Remarks:
The "inheriting" of the layout occurs correctly only in the case of layouts
that have been defined with I50_LAYOUT.
In other cases, it must itself be redefined.
.se;.sb;New layout procedure
.sp 2;Besides the procedure I50_LAYOUT, a new procedure is provided, the
.sp;.nf
PROCEDURE
      i51ownlayout (
            screen_part : ti_ls_part;
                           first_pos   : ti_ls_position;
                           lines,cols  : ti_natural);
.fo
.sp 2;When called, a logical-screen area (SCREEN_PART) is defined.
Entries are made in the same way as with I50_ON_WINDOW; the
coordinates can be specified as absolute
(POS.SCREEN_PART^= ^LS_WHOLE_SCREEN),
relative to the current basic window
(POS.SCREEN_PART^= ^LS_BASIC_WINDOW) or
relative to the current layout.
.sp;.oc _/1;Special case
If LINES^= ^0 applies to an area, it is as if the area were not present.
When it is not desired that an area be defined, the area should be cleared
in this way!
.sp;The stack mechanism is not applied here; this procedure must not
be used to change the basic window (with
SCREEN_PART^= ^LS_BASIC_WINDOW).
.sp2;.se;.sb;Changes to existing procedures
.sp;.nf
PROCEDURE
      i50clear (
            screen_part : ti_ls_part );
.sp;.fo;the new parameter SCREEN_PART specifies the screen area that
is to be cleared.  In particular, in the case of LS_BASIC_WINDOW, the basic
window is cleared and, in the case of LS_WHOLE_SCREEN, the entire screen
is cleared.
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
 
.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
      blank_sk_label = '        ';
      undef_msgno    = csp_minint2;
&     ifdef WINDOWS
      first_sysline_col = 14 (* mxsp_c12 + 2 *);
      mx_sysline        = 128 (* LINE_MXSP00 - 4 *);
&     else
      first_sysline_col = 1;
      mx_sysline        = LINE_MXSP00 ;
&     endif
 
 
(*------------------------------*) 
 
PROCEDURE
      i50on (
            VAR ok : boolean);
 
VAR
      i        : tin_natural;
      j        : tin_ls_part;
      screen   : tsp00_ScreenBufAddr;
      att      : tsp00_ScreenBufAddr;
      maxlines : tsp00_Int2;
      maxcols  : tsp00_Int2 ;
 
BEGIN
i01g^.vt.ok := false;
set_default_termdesc;
i01g^.ls.nr_screens := 1;
IF  NOT i01g^.is_batch
THEN
    WITH i01g^.vt DO
        sqlton(false, vt_ref, desc, ok);
    (*ENDWITH*) 
(*ENDIF*) 
IF  i01g^.vt.ok
THEN
    BEGIN
    i51init;
    i50standardattributes;
    i57vtopt_init;
    init_ls_parms;
    correct_termdesc;
    init_key_comments;
    i53screenaddresses ( 1, screen, att, maxlines, maxcols );
    i53clear(cin_ls_normal, maxlines,maxcols, screen, att );
&   ifdef WINDOWS
    i53clear(cin_ls_normal, 1, LINE_MXSP00, s30gad1( i56sysline2 ),
          s30gad1( i56sysatt2 ) );
&   endif
    i53changelimits(1,1);
    i53changelimits(1,SCREEN_LINES_MXSP00);
&   ifdef TEST
    m01inittest;
&   endif
    i52init;
    i50keymap;
    i51initbasicwindow( 1 );
&   ifdef WINDOWS
    i56init ;
    i56recursion := 0;
&   endif
    i54disablescreenpart(2,cin_ls_basic_window);
    FOR i := 1 TO mxin_screens DO
        FOR j := cin_ls_header TO cin_ls_sysline DO
            BEGIN
            i54disablescreenpart(i,j);
            (* WITH i01_g^.ls.defaults [i] [  ls_functionmenu  ] DO
                  field_att := [  vt_bright ] ; *)
            END;
        (*ENDFOR*) 
    (*ENDFOR*) 
    i54initls_pos(i01g^.ls.cursorpos);
    i01g^.ls.fctline_cursor := f_clear;
    clear_hifparms(i01g^.i50.hif, 1, cin_ls_whole_screen);
    i01g^.key_type.highlighted := [ ] ;
    i01g^.vt.parms.key.key := vt_unknown;
    i01g^.i50.new_value := true;
    WITH i01g^.i50.stack DO
        level := 0;
    (*ENDWITH*) 
    i01g^.i50.defined_part := cin_ls_whole_screen;
    i01g^.i50.with_windowframe := false;
    WITH i01g^.key_type DO
        active_marked := [];
    (*ENDWITH*) 
    END;
(*ENDIF*) 
ok := i01g^.vt.ok;
END; (* i50on *)
 
(*------------------------------*) 
 
PROCEDURE
      i50mfset (
            VAR msgnos : tin_msgnos);
 
BEGIN
i52mfset( msgnos );
END;
 
(*------------------------------*) 
 
PROCEDURE
      set_default_termdesc ;
 
BEGIN
WITH i01g^.vt.desc DO
    BEGIN
    content_buf           := NIL;
    attribute_buf         := NIL;
    num_of_lines          := 24;
    num_of_cols           := 80;
    colors                := [ ] ;
    has_sysline           := false;
    labels                := no_sk_labels;
    returnkeys            := [ ] ;
    attributes            := [ ] ;
    graphic_chars         := false;
    mark                  := false;
    windows               := false;
    dbcs                  := no_dbcs;
    END;
(*ENDWITH*) 
correct_termdesc;
END; (* set_default_termdesc *)
 
(*------------------------------*) 
 
PROCEDURE
      i50standardattributes;
 
BEGIN
sqlttable(cin_ls_normal  , [  ] , vt_white, vt_blue);
sqlttable(cin_ls_enhanced, [  vt_bright ] , vt_white, vt_blue);
sqlttable(cin_ls_title, [ vt_inverse ] , vt_white, vt_blue);
sqlttable(cin_ls_blink, [  vt_blink, vt_inverse ] , vt_white, vt_blue);
sqlttable(cin_ls_infomsg, [ vt_bright ] , vt_yellow, vt_blue);
sqlttable(cin_ls_errormsg, [ vt_bright ] , vt_white, vt_red);
sqlttable(cin_ls_graphic, [ ] , vt_light_blue, vt_blue);
sqlttable(cin_ls_invisible, [ vt_invisible ] , vt_white, vt_blue);
&if $OS=UNIX
(* Bei libcurses kommt das vt_inverse Attribut nicht durch        *)
(* wenn das ansi-File beschreibt, dass der Bildschirm Farben hat. *)
(* B.J. 17.12.92 *)
IF  [ vt_red..vt_light_blue] * i01g^.vt.desc.colors = [   ]
THEN
    sqlttable(cin_ls_inverse, [  vt_inverse] , vt_white, vt_blue)
ELSE
    sqlttable(cin_ls_inverse, [  ], vt_blue, vt_white);
(*ENDIF*) 
&else
sqlttable(cin_ls_inverse, [  vt_inverse] , vt_white, vt_blue);
&endif
END; (* i50standardattributes *)
 
(*------------------------------*) 
 
PROCEDURE
      init_ls_parms;
 
BEGIN
WITH i01g^.vt.parms DO
    BEGIN
    reset_changed_bit  := true;
    standard_attributes := true;
    change_backgr_attr  := true;
    WITH mark_begin DO
        BEGIN
        screen_part := cin_ls_workarea;
        screen_nr := 1;
        sline := 0;
        scol := 1;
        END;
    (*ENDWITH*) 
    mark_end      := mark_begin;
    mark_end.scol := mark_begin.scol - 1;
    END;
(*ENDWITH*) 
WITH i01g^.vt.opt DO
    BEGIN
    mark                  := vt_mark_off;
    first_line_changed    := i01g^.vt.desc.num_of_lines + 1;
    screen2_first_changed := i01g^.vt.desc.num_of_lines + 1;
    last_line_changed     := 0;
    screen2_last_changed  := 0;
    END;
(*ENDWITH*) 
END; (* init_ls_parms *)
 
(*------------------------------*) 
 
PROCEDURE
      correct_termdesc;
 
BEGIN
WITH i01g^.vt.desc DO
    IF  dbcs <> dbcs_with_shifts
    THEN
        BEGIN
        si_char [1]  := chr(0);
        so_char [1]  := chr(0);
        END;
    (*ENDIF*) 
(*ENDWITH*) 
END; (* correct_termdesc *)
 
(*------------------------------*) 
 
PROCEDURE
      init_key_comments;
 
VAR
      f : tin_prog_function;
 
BEGIN
WITH i01g^.key_type DO
    FOR f := f1 TO f_down DO
        key_comments [f]  := undef_msgno;
    (*ENDFOR*) 
(*ENDWITH*) 
END; (* init_key_comments *)
 
(*------------------------------*) 
 
PROCEDURE
      clear_hifparms (
            VAR hif : tsp00_HifParms;
            sno     : tsp00_Int2;
            part    : tin_ls_part);
 
BEGIN
WITH hif DO
    BEGIN
    IF  (part = cin_ls_whole_screen)
        OR (part = cin_ls_basic_window)
        OR (part = cin_ls_functionmenu)
    THEN
        BEGIN
        clear_slabels(slabels);
        clear_llabels(llabels);
        END;
    (*ENDIF*) 
    IF  (part = cin_ls_whole_screen)
        OR (part = cin_ls_basic_window)
        OR (part = cin_ls_sysline)
    THEN
        BEGIN
&       ifdef WINDOWS
        IF  ( sno = 2 )
        THEN
            BEGIN
            SAPDB_PascalForcedFill(LINE_MXSP00,@i56sysline2,first_sysline_col,
                  LINE_MXSP00-first_sysline_col+1,bsp_c1);
            SAPDB_PascalForcedFill(LINE_MXSP00,@i56sysatt2,first_sysline_col,
                  LINE_MXSP00-first_sysline_col+1,chr(cin_ls_normal));
            END
        ELSE
&           endif
            BEGIN
            SAPDB_PascalForcedFill(LINE_MXSP00,@sys_text,first_sysline_col,
                  LINE_MXSP00-first_sysline_col+1,bsp_c1);
            SAPDB_PascalForcedFill(LINE_MXSP00,@sys_attr,first_sysline_col,
                  LINE_MXSP00-first_sysline_col+1,chr(cin_ls_normal));
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (part = cin_ls_whole_screen)
        OR (part = cin_ls_basic_window)
    THEN
        WITH insert_label DO
            BEGIN
            lno := 0;
            colnr := 0;
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END; (* clear_hifparms *)
 
(*------------------------------*) 
 
PROCEDURE
      clear_slabels (
            VAR slabels : tsp00_VtSlabels);
 
VAR
      i : integer;
 
BEGIN
FOR i := 1 TO csp_sk_number DO
    slabels [i]  := blank_sk_label;
(*ENDFOR*) 
END; (* clear_slabels *)
 
(*------------------------------*) 
 
PROCEDURE
      clear_llabels (
            VAR llabels : tsp00_VtLlabels);
 
VAR
      i,j : integer;
 
BEGIN
FOR i := 1 TO csp_sk_number DO
    FOR j := 1 TO 2 DO
        llabels [i]  [j]  := blank_sk_label;
    (*ENDFOR*) 
(*ENDFOR*) 
END; (* clear_llabels *)
 
&ifdef WINDOWS
(*------------------------------*) 
 
PROCEDURE
      i50clear (
            screen_part : tin_ls_part );
 
VAR
      sno      : integer;
      screen   : tsp00_ScreenBufAddr;
      att      : tsp00_ScreenBufAddr;
      maxlines : tsp00_Int2;
      maxcols  : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
&   ifdef WINDOWS
    i56dlgerase ( screen_part );
&   endif
    IF  ( (screen_part = cin_ls_whole_screen)
        OR (screen_part = cin_ls_basic_window)
        OR (screen_part = cin_ls_workarea) )
&       ifdef WINDOWS
        AND (NOT i56spartswitched (cin_ls_workarea) )
&       endif
    THEN
        BEGIN
        (*    WITH i01g^.vt,desc DO *)
        FOR sno := 1 TO i01g^.ls.nr_screens DO
            BEGIN
            i53screenaddresses( sno, screen, att, maxlines, maxcols );
            i53clear(cin_ls_normal, maxlines, maxcols,
                  screen, att );
            i53changelimits(sno, 1);
            i53changelimits(sno, SCREEN_LINES_MXSP00);
            END;
        (*ENDFOR*) 
        i01g^.i50.new_value := true;
        END;
    (*ENDIF*) 
    IF  (screen_part = cin_ls_whole_screen)
        OR (screen_part = cin_ls_basic_window)
        OR (screen_part = cin_ls_header)
    THEN
        FOR sno := 1 TO i01g^.ls.nr_screens DO
            i56clwinheader( sno );
        (*ENDFOR*) 
    (*ENDIF*) 
    FOR sno := 1 TO i01g^.ls.nr_screens DO
        BEGIN
        clear_hifparms(i01g^.i50.hif, sno, screen_part );
        clear_scrollparms ( sno, screen_part );
        END;
    (*ENDFOR*) 
    END;
(*ENDIF*) 
END; (* i50clear *)
 
(*------------------------------*) 
 
PROCEDURE
      i50cl2( sno : tsp00_Int2;
            screen_part : tin_ls_part );
 
VAR
      screen   : tsp00_ScreenBufAddr;
      att      : tsp00_ScreenBufAddr;
      maxlines : tsp00_Int2;
      maxcols  : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
&   ifdef WINDOWS
    i56dlgerase ( screen_part );
&   endif
    IF  ( (screen_part = cin_ls_whole_screen)
        OR (screen_part = cin_ls_basic_window)
        OR (screen_part = cin_ls_workarea) )
&       ifdef WINDOWS
        AND (NOT i56spartswitched (cin_ls_workarea) )
&       endif
    THEN
        BEGIN
        i53screenaddresses( sno, screen, att, maxlines, maxcols );
        i53clear(cin_ls_normal, maxlines, maxcols,
              screen, att );
        i53changelimits(sno, 1);
        i53changelimits(sno, SCREEN_LINES_MXSP00);
        i01g^.i50.new_value := true;
        END;
    (*ENDIF*) 
    IF  (screen_part = cin_ls_whole_screen)
        OR (screen_part = cin_ls_basic_window)
        OR (screen_part = cin_ls_header)
    THEN
        i56clwinheader( sno );
    (*ENDIF*) 
    clear_hifparms(i01g^.i50.hif, sno, screen_part );
    clear_scrollparms ( sno, screen_part );
    END;
(*ENDIF*) 
END; (* i50cl2 *)
 
&else
(*------------------------------*) 
 
PROCEDURE
      i50cl2( sno : tsp00_Int2;
            screen_part : tin_ls_part );
 
VAR
      j              : tin_ls_part;
      with_partframe : boolean;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    IF  (screen_part = cin_ls_whole_screen)
        OR ((screen_part = cin_ls_basic_window)
        AND (i01g^.ls.nr_screens > 1))
    THEN
        BEGIN
        WITH i01g^.vt,desc DO
            (* i53clear(ls_black, num_of_lines,num_of_cols,content_buf,
                  attribute_buf);*)
            (* Damit bei der ersten Ausgabe von SQL-PL keine *)
            (* schwarzen Blanks zwischen den Buchstaben      *)
            (* auftreten. B.J. 10.12.92                      *)
            i53clear (cin_ls_normal, num_of_lines, num_of_cols,
                  content_buf, attribute_buf);
        (*ENDWITH*) 
        i53changelimits(1,1);
        i53changelimits(1,SCREEN_LINES_MXSP00);
        i01g^.i50.new_value := true;
        END;
    (*ENDIF*) 
    IF  screen_part = cin_ls_basic_window
    THEN
        BEGIN
        IF  NOT all_screenparts_defined(sno)
        THEN
            i50clscreenpart(sno, cin_ls_basic_window,false);
        (*ENDIF*) 
        FOR j := cin_ls_header TO cin_ls_sysline DO
            BEGIN (* set background colours etc *)
            with_partframe := (j = cin_ls_workarea);
            i50clscreenpart(sno,j,with_partframe);
            END
        (*ENDFOR*) 
        END
    ELSE
        IF  (screen_part >= cin_ls_header)
            AND (screen_part <= cin_ls_sysline )
        THEN
            i50clscreenpart(sno, screen_part,false);
        (*ENDIF*) 
    (*ENDIF*) 
    clear_hifparms(i01g^.i50.hif, sno, screen_part );
    END;
(*ENDIF*) 
END; (* i50cl2 *)
 
(*------------------------------*) 
 
PROCEDURE
      i50clear (
            screen_part : tin_ls_part );
 
VAR
      sno            : tsp00_Int2;
      j              : tin_ls_part;
      with_partframe : boolean;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    IF  (screen_part = cin_ls_whole_screen)
        OR ((screen_part = cin_ls_basic_window)
        AND (i01g^.ls.nr_screens > 1))
    THEN
        BEGIN
        WITH i01g^.vt,desc DO
            (* i53clear(ls_black, num_of_lines,num_of_cols,content_buf,
                  attribute_buf);*)
            (* Damit bei der ersten Ausgabe von SQL-PL keine *)
            (* schwarzen Blanks zwischen den Buchstaben      *)
            (* auftreten. B.J. 10.12.92                      *)
            i53clear (cin_ls_normal, num_of_lines, num_of_cols,
                  content_buf, attribute_buf);
        (*ENDWITH*) 
        i53changelimits(1,1);
        i53changelimits(1,SCREEN_LINES_MXSP00);
        i01g^.i50.new_value := true;
        END;
    (*ENDIF*) 
    IF  screen_part = cin_ls_basic_window
    THEN
        FOR sno := 1 TO i01g^.ls.nr_screens DO
            BEGIN
            IF  NOT all_screenparts_defined( sno )
            THEN
                i50clscreenpart(sno,cin_ls_basic_window,false);
            (*ENDIF*) 
            FOR j := cin_ls_header TO cin_ls_sysline DO
                BEGIN (* set background colours etc *)
                with_partframe := (j = cin_ls_workarea);
                i50clscreenpart(sno,j,with_partframe);
                END
            (*ENDFOR*) 
            END
        (*ENDFOR*) 
    ELSE
        (*IF  screen_part IN [  ls_header..ls_sysline  ] *)
        IF  (screen_part >= cin_ls_header)
            AND (screen_part <= cin_ls_sysline )
        THEN
            FOR sno := 1 TO i01g^.ls.nr_screens DO
                i50clscreenpart(sno, screen_part,false);
            (*ENDFOR*) 
        (*ENDIF*) 
    (*ENDIF*) 
    clear_hifparms(i01g^.i50.hif, 1, screen_part );
    END;
(*ENDIF*) 
END; (* i50clear *)
 
&endif
(*------------------------------*) 
 
PROCEDURE
      i50clwindow (
            first_pos    : tin_ls_position;
            window_len   : tin_natural;
            window_width : tin_natural);
 
VAR
      length, width         : tin_natural;
      first_line, first_col : tin_natural;
      last_line, last_col   : tin_natural;
      field_type            : tin_ls_fieldtype;
      screen                : tsp00_ScreenBufAddr;
      att                   : tsp00_ScreenBufAddr;
      maxlines, maxcols     : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    IF  i01g^.ls.nr_screens = 1
    THEN
        first_pos.screen_nr := 1;
    (*ENDIF*) 
    i51size2(first_pos.screen_nr,first_pos.screen_part,length,width);
    IF  length > (first_pos.sline - 1)
    THEN
        length := length - first_pos.sline + 1
    ELSE
        length := 1;
    (*ENDIF*) 
    IF  width > (first_pos.scol - 1)
    THEN
        width := width - first_pos.scol + 1
    ELSE
        width := 1;
    (*ENDIF*) 
    IF  window_len < length
    THEN
        length := window_len;
    (*ENDIF*) 
    IF  window_width < width
    THEN
        width := window_width;
    (*ENDIF*) 
    i52fromscreenpos(first_pos,first_line,first_col);
    i54gpartsdefaults (first_pos.screen_part, field_type);
    IF  first_line = 0
    THEN
        first_line := 1;
    (*ENDIF*) 
    last_line := first_line + length - 1;
    IF  first_col = 0
    THEN
        first_col := 1;
    (*ENDIF*) 
    last_col := first_col + width - 1;
    i53screenaddresses( first_pos.screen_nr, screen, att,
          maxlines, maxcols );
    (* WITH i01g^.vt,desc DO *)
    i53clwindow(first_pos.screen_nr,
          first_line,first_col,last_line,last_col,field_type,
          maxlines, maxcols, screen, att );
    i54setwindowlimits(first_pos.screen_nr,
          first_line,first_col,last_line,last_col,field_type);
    END;
(*ENDIF*) 
END; (* i50clwindow *)
 
(*------------------------------*) 
 
PROCEDURE
      i50clscreenpart (
            screen_no      : integer;
            part           : tin_ls_part;
            with_partframe : boolean);
 
VAR
      field      : tsp00_C12;
      first_slno : tin_natural;
      first_scol : tin_natural;
      last_slno  : tin_natural;
      last_scol  : tin_natural;
      field_type : tin_ls_fieldtype;
      screen     : tsp00_ScreenBufAddr;
      att        : tsp00_ScreenBufAddr;
      maxlines   : tsp00_Int2;
      maxcols    : tsp00_Int2;
 
BEGIN
field [1]  := bsp_c1;
i53screenaddresses( screen_no, screen, att, maxlines, maxcols );
WITH i01g^.ls.description [screen_no]  [part ] DO
    BEGIN
    first_slno := first_line;
    IF  first_slno > 0
    THEN
        BEGIN
        last_slno := last_line;
        last_scol := last_col;
        IF  with_partframe
        THEN (* frame *)
            BEGIN
            IF  first_slno > 1
            THEN
                first_slno := first_slno - 1;
            (*ENDIF*) 
            IF  last_slno < maxlines
            THEN
                last_slno := last_slno + 1;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        first_scol := first_col;
        last_scol := last_col;
        IF  i01g^.i50.with_windowframe (* !!! 23.8.88 *)
        THEN
            BEGIN
            IF  first_scol > 1
            THEN
                first_scol := first_scol - 1; (* neu *)
            (*ENDIF*) 
            IF  last_scol < maxcols
            THEN
                last_scol := last_scol + 1; (* neu *)
            (*ENDIF*) 
            END;
        (* IF  part IN [  ls_header..ls_sysline  ] *)
        (*ENDIF*) 
        IF  (part >= cin_ls_header)
            AND (part <= cin_ls_sysline )
        THEN
            (* preliminary *)
            WITH field_type DO
                field_att := cin_ls_normal
            (*ENDWITH*) 
        ELSE
            i54fieldtype( field_type);
        (*ENDIF*) 
        field_type.fieldmode := [  ] ;
        i54resolvedefaults (part, field_type);
        (* WITH i01g^.vt,desc DO *)
        i53clwindow(screen_no,
              first_slno,first_scol,last_slno,last_scol,
              field_type, maxlines, maxcols, screen, att );
        IF  (NOT i01g^.i50.with_windowframe)
            AND ( (i01g^.i50.stack.level > 0)
            OR terminal_has_colors )
        THEN
            i54setwindowlimits(screen_no, first_slno,first_scol,
                  last_slno,last_scol,field_type);
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END; (* i50clscreenpart *)
 
(*------------------------------*) 
 
PROCEDURE
      i50keymap;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    WITH i01g^.vt.desc DO
&       ifdef hifmode
        IF  ( [  vt_sk01..vt_sk09, vt_up_key, vt_down_key, vt_help_key  ]
            <= returnkeys)
        THEN
            i52skkeymap
        ELSE
&           endif
            IF  ( [  vt_pf01..vt_pf12  ] <= returnkeys)
            THEN
                i52pfkeymap
            ELSE
                i52pfkeymap;
            (*ENDIF*) 
        (*ENDIF*) 
    (*ENDWITH*) 
    END;
(*ENDIF*) 
END; (* i50keymap *)
 
(*------------------------------*) 
 
PROCEDURE
      i50info (
            VAR modes : tsp00_VtAttrib;
            VAR keys  : tin_ls_key_set);
 
VAR
      rk : tin_vt_releasemode;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    keys := [  ] ;
    WITH i01g^.vt DO
        BEGIN
        modes := desc.attributes;
        FOR rk := vt_enter TO vt_end_key DO
            IF  rk IN desc.returnkeys
            THEN
                keys := keys + [  i52rf(rk) ] ;
            (*ENDIF*) 
        (*ENDFOR*) 
        END;
    (*ENDWITH*) 
    END;
(*ENDIF*) 
END; (* i50info *)
 
(*------------------------------*) 
 
PROCEDURE
      i50off (
            VAR msg : tin_screenline);
 
VAR
      l       : tsp00_C80;
      ok      : boolean;
      out_msg : tsp00_Line;
      length  : tsp00_Int2 ;
 
BEGIN
ok := NOT i01g^.is_batch;
IF  ok
THEN
    ok := i01g^.vt.ok;
(*ENDIF*) 
IF  ok
THEN
    BEGIN
    s10mv (mxin_screenline,80,
          @msg,1,
          @l,1,80);
&   ifdef TEST
    m01terminate_test;
&   endif
    WITH i01g^.vt, desc DO
        sqltoff (vt_ref, content_buf, attribute_buf, l);
    (*ENDWITH*) 
    END
ELSE
    BEGIN (* B.M. 02.02.95 Release 6.1.1 CL 12 *)
    IF  ( LINE_MXSP00 > mxin_screenline )
    THEN
        length := mxin_screenline
    ELSE
        length := LINE_MXSP00 ;
    (*ENDIF*) 
    s10mv (mxin_screenline,LINE_MXSP00,
          @msg,1,
          @out_msg,1,length );
    IF  ( length < LINE_MXSP00 )
    THEN
        SAPDB_PascalForcedFill ( LINE_MXSP00, @out_msg, length+1, LINE_MXSP00-length, bsp_c1 );
    (* E.Stils 08.07.92 *)
    (*ENDIF*) 
    sqlwrite (out_msg);
    END;
(*ENDIF*) 
END; (* i50off *)
 
(*------------------------------*) 
 
PROCEDURE
      i50abspos (
            VAR pos : tin_ls_position);
 
VAR
      lno : tin_natural;
      col : tin_natural;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    i52fromscreenpos(pos,lno,col);
    WITH pos DO
        BEGIN
        screen_nr := 1;
        screen_part := cin_ls_whole_screen;
        sline := lno;
        scol := col;
        END;
    (*ENDWITH*) 
    END;
(*ENDIF*) 
END; (* i50abspos *)
 
(*------------------------------*) 
 
PROCEDURE
      i50put1field (
            VAR field  : tsp00_MoveObj;
            length     : tin_natural;
            field_pos  : tin_ls_position;
            field_type : tin_ls_fieldtype);
 
VAR
      field_slno : tin_natural;
      field_scol : tin_natural;
      maxlength  : tin_natural;
      maxwidth   : tin_natural;
      intlen     : integer;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
&   ifdef WINDOWS
    IF  i56spartswitched ( field_pos.screen_part )
    THEN
        i56todialogbox ( field, length, field_pos, field_type )
    ELSE
&       endif
        BEGIN
        i51size( field_pos.screen_part , maxlength, maxwidth );
        IF  maxlength > 0
        THEN
            BEGIN
            i52fromscreenpos(field_pos,field_slno,field_scol);
            i54resolvedefaults (field_pos.screen_part, field_type);
            IF  field_scol > 0
            THEN
                BEGIN
                IF  field_pos.scol + length - 1 > maxwidth
                THEN
                    BEGIN
                    intlen := (maxwidth - field_pos.scol + 1);
                    (* h.b. 21.12.93 wegen core *)
                    IF  intlen < 0
                    THEN
                        length := 0
                    ELSE
                        length := maxwidth - field_pos.scol + 1;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  i01g^.multibyte.dblang <> bsp_knl_identifier
                THEN
                    i53check_field_for_multibyte (field, length);
                (*ENDIF*) 
                IF  (field_slno > 0)
                THEN
                    BEGIN
                    put_field_50 (field,length,
                          field_pos.screen_nr,
                          field_slno,field_scol,
                          field_type);
                    END
                ELSE
                    IF  (field_pos.screen_part = cin_ls_sysline)
                        AND (i01g^.vt.desc.has_sysline)
                    THEN
                        put_field_to_sysline(field,length,
                              field_pos.screen_nr,
                              field_pos.scol,field_type);
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDIF*) 
END; (* i50put1field *)
 
(*------------------------------*) 
 
PROCEDURE
      put_field_50 (
            VAR field  : tsp00_MoveObj;
            length     : integer;
            sno        : tsp00_Int2;
            field_slno : integer;
            field_scol : integer;
            VAR ft     : tin_ls_fieldtype);
 
VAR
      screen   : tsp00_ScreenBufAddr;
      att      : tsp00_ScreenBufAddr;
      maxlines : tsp00_Int2;
      maxcols  : tsp00_Int2;
 
BEGIN
IF  length > 0
THEN
    BEGIN
    i53screenaddresses( sno, screen, att, maxlines, maxcols ) ;
    (*WITH i01g^.vt,desc DO*)
    i53put1field(field,length,
          sno,
          field_slno,field_scol,
          ft, maxlines, maxcols,
          screen, att );
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      put_field_to_sysline (
            VAR field  : tsp00_MoveObj;
            length     : tin_natural;
            sno        : tsp00_Int2;
            scol       : integer;
            field_type : tin_ls_fieldtype);
 
VAR
      after_end : integer;
      screen    : tin_lineaddr;
      att       : tin_lineaddr;
 
BEGIN
scol := scol + first_sysline_col;
WITH i01g^.i50.hif DO
    BEGIN
&   ifdef WINDOWS
    IF  ( sno = 2)
    THEN
        BEGIN
        screen := s30gad( i56sysline2 );
        att := s30gad( i56sysatt2 );
        END
    ELSE
&       endif
        BEGIN
        screen := s30gad(sys_text);
        att := s30gad(sys_attr);
        END ;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
(* systemline max. 132 characters !!! *)
IF  ((scol + length) > mx_sysline)
THEN
    BEGIN
    IF  length < mx_sysline
    THEN
        scol := mx_sysline- length;
    (*ENDIF*) 
    END;
(**)
&ifdef WINDOWS
(*ENDIF*) 
IF  field_type.field_att <> cin_ls_enhanced
THEN
    field_type.field_att := cin_ls_normal;
&endif
(*ENDIF*) 
i53put2field(field,length,sno, 1,scol,
      field_type,
      1,mx_sysline, screen, att );
(**)
IF  (scol + length) > mx_sysline
THEN
    after_end := mx_sysline
ELSE
    after_end := scol + length;
(*ENDIF*) 
(**)
IF  ord(screen^ [after_end] ) <> 1 (* start of next field *)
THEN
    (* same background as previous field *)
    i53put2attribute (sno, 1, after_end, field_type, mx_sysline, att);
(*ENDIF*) 
END; (* put_field_to_sysline *)
 
(*------------------------------*) 
 
PROCEDURE
      i50put2field (
            VAR field  : tsp00_MoveObj;
            length     : tin_natural;
            field_pos  : tin_ls_position;
            field_type : tin_ls_fieldtype);
 
BEGIN
i50put1field(field,length,field_pos,field_type);
END; (* i50put2field *)
 
(*------------------------------*) 
 
PROCEDURE
      i50put3field (
            VAR field  : tsp00_MoveObj;
            length     : tin_natural;
            field_pos  : tin_ls_position;
            field_type : tin_ls_fieldtype);
 
BEGIN
i50put1field(field,length,field_pos,field_type);
END; (* i50put3field *)
 
(*------------------------------*) 
 
PROCEDURE
      i50put4field (
            VAR field  : tsp00_MoveObj;
            length     : tin_natural;
            field_pos  : tin_ls_position;
            field_type : tin_ls_fieldtype);
 
BEGIN
i50put1field(field,length,field_pos,field_type);
END; (* i50put4field *)
 
(*------------------------------*) 
 
PROCEDURE
      i50put5field (
            VAR field  : tsp00_MoveObj;
            length     : tin_natural;
            field_pos  : tin_ls_position;
            field_type : tin_ls_fieldtype);
 
BEGIN
i50put1field(field,length,field_pos,field_type);
END; (* i50put5field *)
 
(*------------------------------*) 
 
PROCEDURE
      i50put6field (
            VAR field  : tsp00_MoveObj;
            length     : tin_natural;
            field_pos  : tin_ls_position;
            field_type : tin_ls_fieldtype);
 
BEGIN
i50put1field(field,length,field_pos,field_type);
END; (* i50put6field *)
 
(*------------------------------*) 
 
PROCEDURE
      i50put7field (
            VAR field  : tsp00_MoveObj;
            length     : tin_natural;
            field_pos  : tin_ls_position;
            field_type : tin_ls_fieldtype);
 
BEGIN
i50put1field(field,length,field_pos,field_type);
END; (* i50put7field *)
 
(*------------------------------*) 
 
PROCEDURE
      i50put8field (
            VAR field  : tsp00_MoveObj;
            length     : tin_natural;
            field_pos  : tin_ls_position;
            field_type : tin_ls_fieldtype);
 
BEGIN
i50put1field(field,length,field_pos,field_type);
END; (* i50put8field *)
 
(*------------------------------*) 
 
PROCEDURE
      i50put9field (
            VAR field  : tsp00_MoveObj;
            length     : tin_natural;
            field_pos  : tin_ls_position;
            field_type : tin_ls_fieldtype);
 
BEGIN
i50put1field(field,length,field_pos,field_type);
END; (* i50put9field *)
 
(*------------------------------*) 
 
PROCEDURE
      i50erasefield (
            field_pos : tin_ls_position);
 
VAR
      field_slno : tin_natural;
      field_scol : tin_natural;
      maxlength  : tin_natural;
      maxwidth   : tin_natural;
      screen     : tsp00_ScreenBufAddr;
      att        : tsp00_ScreenBufAddr;
      maxlines   : tsp00_Int2;
      maxcols    : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    i51size( field_pos.screen_part , maxlength, maxwidth );
    IF  maxlength > 0
    THEN
        BEGIN
        i52fromscreenpos(field_pos,field_slno,field_scol);
        i53screenaddresses( field_pos.screen_nr, screen, att,
              maxlines, maxcols );
        i53erasefield (field_slno, field_scol,
              maxlines, maxcols, screen );
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
END; (* i50erasefield *)
 
(*------------------------------*) 
 
PROCEDURE
      i50putattribute (
            field_pos  : tin_ls_position;
            field_type : tin_ls_fieldtype);
 
VAR
      field_slno : tin_natural;
      field_scol : tin_natural;
      screen     : tsp00_ScreenBufAddr;
      att        : tsp00_ScreenBufAddr;
      maxlines   : tsp00_Int2;
      maxcols    : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    i52fromscreenpos(field_pos,field_slno,field_scol);
    i54resolvedefaults (field_pos.screen_part, field_type);
    i53screenaddresses( field_pos.screen_nr, screen, att,
          maxlines, maxcols );
    i53put1attribute(field_pos.screen_nr,
          field_slno, field_scol, field_type,
          maxcols, att );
    END;
(*ENDIF*) 
END; (* i50putattribute *)
 
(*------------------------------*) 
 
PROCEDURE
      i50fillattribute (
            field_pos  : tin_ls_position;
            count      : integer;
            field_type : tin_ls_fieldtype);
 
VAR
      field_slno : tin_natural;
      field_scol : tin_natural;
      screen     : tsp00_ScreenBufAddr;
      att        : tsp00_ScreenBufAddr;
      maxlines   : tsp00_Int2;
      maxcols    : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    i52fromscreenpos(field_pos,field_slno,field_scol);
    i54resolvedefaults (field_pos.screen_part, field_type);
    i53screenaddresses( field_pos.screen_nr, screen, att,
          maxlines, maxcols );
    (*  WITH i01g^.vt,desc DO *)
    i53fillattribute (field_pos.screen_nr,
          field_slno, field_scol, count,
          field_type, maxcols, att );
    END;
(*ENDIF*) 
END; (* i50fillattribute *)
 
(*------------------------------*) 
 
PROCEDURE
      i50getlineattributes (
            VAR attr_line : tin_screenline;
            field_pos     : tin_ls_position;
            count         : integer );
 
VAR
      field_slno : tin_natural;
      field_scol : tin_natural;
      screen     : tsp00_ScreenBufAddr;
      att        : tsp00_ScreenBufAddr;
      maxlines   : tsp00_Int2;
      maxcols    : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    i52fromscreenpos(field_pos,field_slno,field_scol);
    i53screenaddresses( field_pos.screen_nr, screen, att,
          maxlines, maxcols );
    i53getlineattributes(field_pos.screen_nr,
          field_slno, field_scol, count, attr_line,
          maxcols, att );
    END;
(*ENDIF*) 
END; (* i50getlineattributes *)
 
(*------------------------------*) 
 
PROCEDURE
      i50putlineattributes (
            VAR attr_line : tin_screenline;
            field_pos     : tin_ls_position;
            count         : integer );
 
VAR
      field_slno : tin_natural;
      field_scol : tin_natural;
      screen     : tsp00_ScreenBufAddr;
      att        : tsp00_ScreenBufAddr;
      maxlines   : tsp00_Int2;
      maxcols    : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    i52fromscreenpos(field_pos,field_slno,field_scol);
    i53screenaddresses( field_pos.screen_nr, screen, att ,
          maxlines, maxcols );
    i53putlineattributes(field_pos.screen_nr,
          field_slno, field_scol, count, attr_line,
          maxcols, att );
    i53changelimits(field_pos.screen_nr, field_slno );
    END;
(*ENDIF*) 
END; (* i50putlineattributes *)
 
(*------------------------------*) 
 
PROCEDURE
      i50hscroll (
            screen_nr    : integer;
            screen_part  : tin_ls_part;
            scroll_cols  : tsp00_Int2);
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    screen_scroll(screen_nr, screen_part, 0, scroll_cols );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      i50vscroll (
            screen_nr    : integer;
            screen_part  : tin_ls_part;
            scroll_lines : tsp00_Int2);
 
VAR
      lno           : tin_natural;
      col           : tin_natural;
      limit         : tin_natural;
      last_col      : tin_natural;
      dest_lno      : tin_natural;
      length        : integer;
      inc           : tsp00_Int2;
      pos, dest_pos : integer;
      finished      : boolean;
      ok            : boolean;
      screen        : tsp00_ScreenBufAddr;
      att           : tsp00_ScreenBufAddr;
      maxlines      : tsp00_Int2;
      maxcols       : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    i53screenaddresses( screen_nr, screen, att,
          maxlines, maxcols );
    WITH i01g^.ls DO
        BEGIN
        IF  scroll_lines < 0
        THEN
            BEGIN (* shift screen contents down *)
            inc := -maxcols;
            lno := description [screen_nr]  [screen_part] .last_line;
            limit := description [screen_nr]  [screen_part] .first_line;
            ok := (lno - limit + 1) > -scroll_lines;
            END
        ELSE
            BEGIN (* shift screen contents up *)
            inc := +maxcols;
            lno := description [screen_nr]  [screen_part] .first_line;
            limit := description [screen_nr]  [screen_part] .last_line;
            ok := (limit - lno + 1) > scroll_lines;
            END;
        (*ENDIF*) 
        col := description [screen_nr]  [screen_part] .first_col;
        last_col := description [screen_nr]  [screen_part] .last_col;
        END;
    (*ENDWITH*) 
    IF  ok
    THEN
        BEGIN
        dest_lno := lno;
        lno := lno + scroll_lines;
        length := last_col - col + 1;
        pos := i53tobufpos(lno, col, maxcols);
        dest_pos := i53tobufpos(dest_lno, col, maxcols);
        limit := i53tobufpos(limit, col, maxcols);
        finished := false;
        REPEAT
            s10mv(SCREEN_BUF_MXSP00,SCREEN_BUF_MXSP00,
                  @screen^,pos,
                  @screen^,dest_pos,length);
            s10mv(SCREEN_BUF_MXSP00,SCREEN_BUF_MXSP00,
                  @att^,pos,
                  @att^,dest_pos,length);
            IF  pos = limit
            THEN
                finished := true
            ELSE
                BEGIN
                pos := pos + inc;
                dest_pos := dest_pos + inc;
                END;
            (*ENDIF*) 
        UNTIL
            finished;
        (*ENDREPEAT*) 
        END;
    (*
          clear_empty_vscroll_region(screen_nr, screen_part, scroll_lines);
          *)
    (*ENDIF*) 
    scroll_mark_area;
    screen_scroll(screen_nr, screen_part, scroll_lines, 0);
    END;
(*ENDIF*) 
END; (* i50vscroll *)
 
(*------------------------------*) 
 
PROCEDURE
      scroll_mark_area;
 
VAR
      mark_active : boolean;
 
BEGIN
WITH i01g^.vt.parms DO
    BEGIN
    mark_active := (mark_begin.screen_part = cin_ls_workarea)
          AND (mark_end.screen_part = cin_ls_workarea);
    IF  mark_active
    THEN
        mark_active := (mark_begin.sline < mark_end.sline)
              OR ( (mark_begin.sline = mark_end.sline)
              AND (mark_begin.scol <= mark_end.scol) );
    (*ENDIF*) 
    IF  mark_active
    THEN
        BEGIN
        mark_begin.sline :=
              limited_screenline(mark_begin.sline - scroll_dir);
        mark_end.sline :=
              limited_screenline(mark_end.sline - scroll_dir);
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END; (* scroll_mark_area *)
 
(*------------------------------*) 
 
FUNCTION
      limited_screenline (
            lno : integer) : tin_natural;
 
VAR
      length, width : tin_natural;
 
BEGIN
i51size(cin_ls_workarea,length,width);
IF  lno < 1
THEN
    lno := 1;
(*ENDIF*) 
IF  lno > length
THEN
    lno := length;
(*ENDIF*) 
limited_screenline := lno;
END; (* limited_screenline *)
 
(*------------------------------*) 
 
PROCEDURE
      screen_scroll (
            screen_nr    : integer;
            screen_part  : tin_ls_part;
            scroll_lines : tsp00_Int2 ;
            scroll_cols  : tsp00_Int2);
&     ifdef SCROLL
 
VAR
      rect    : tsp00_VtRectangle;
      done    : boolean;
&     endif
 
BEGIN
&ifdef SCROLL
WITH i01g^.ls.description [screen_nr]  [screen_part ] DO
    BEGIN
    rect.top  := first_line;
    rect.left := first_col;
    rect.bottom := last_line;
    rect.right := last_col;
    END;
(*ENDWITH*) 
WITH i01g^.vt DO
    sqlwscroll (vt_ref, rect, scroll_cols, scroll_lines, done);
(*ENDWITH*) 
IF  NOT done
THEN
&   endif
    WITH i01g^.ls.description [screen_nr]  [screen_part ] DO
        BEGIN
        i53changelimits(screen_nr, first_line);
        i53changelimits(screen_nr, last_line);
        END;
    (*ENDWITH*) 
(*ENDIF*) 
END; (* screen_scroll *)
 
(*------------------------------*) 
 
PROCEDURE
      clear_empty_vscroll_region (
            screen_nr    : integer;
            screen_part  : tin_ls_part;
            scroll_lines : tsp00_Int2);
 
VAR
      ft          : tin_ls_fieldtype;
      first, last : integer;
      screen      : tsp00_ScreenBufAddr;
      att         : tsp00_ScreenBufAddr;
      maxlines    : tsp00_Int2;
      maxcols     : tsp00_Int2;
 
BEGIN
i53screenaddresses( screen_nr, screen, att, maxlines, maxcols );
ft.field_att := cin_ls_normal;
ft.fieldmode := [  ] ;
IF  scroll_lines < 0
THEN
    WITH i01g^.ls.description [screen_nr]  [screen_part] DO
        BEGIN
        last := first_line - scroll_lines - 1;
        IF  last > last_line
        THEN
            last := last_line;
        (*ENDIF*) 
        i53clwindow(screen_nr, first_line, first_col,
              last, last_col,
              ft, maxlines, maxcols,
              screen, att)
        END
    (*ENDWITH*) 
ELSE
    IF  scroll_lines > 0
    THEN
        WITH i01g^.ls.description [screen_nr]  [screen_part] DO
            BEGIN
            first := last_line - scroll_lines + 1;
            IF  first < first_line
            THEN
                first := first_line;
            (*ENDIF*) 
            i53clwindow(screen_nr, first, first_col,
                  last_line, last_col,
                  ft, maxlines, maxcols,
                  screen, att );
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
(*ENDIF*) 
END; (* clear_empty_vscroll_region *)
 
(*------------------------------*) 
 
PROCEDURE
      i50insertlabel (
            VAR lab : tsp00_VtLabel;
            ft      : tin_ls_fieldtype;
            pos     : tin_ls_position);
 
VAR
      ins_lno : tin_natural;
      ins_col : tin_natural;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    IF  (pos.sline > 0) AND (pos.scol > 0)
    THEN
        BEGIN
        i52fromscreenpos(pos, ins_lno, ins_col);
        i54resolvedefaults (pos.screen_part, ft);
        WITH i01g^.i50.hif.insert_label DO
            BEGIN
            text := lab;
            lno := ins_lno;
            colnr := ins_col;
            i53fieldtypetochars(ft,att);
            END;
        (*ENDWITH*) 
        END
    ELSE
        WITH i01g^.i50.hif.insert_label DO
            BEGIN
            lno := 0;
            colnr := 0;
            att [1]  := chr(0);
            END;
        (*ENDWITH*) 
    (*ENDIF*) 
    END;
(*ENDIF*) 
END; (* i50insertlabel *)
 
(*------------------------------*) 
 
PROCEDURE
      i50autoscroll;
 
BEGIN
END; (* i50autoscroll *)
 
(*------------------------------*) 
 
PROCEDURE
      i50getwindow (
            first_pos          : tin_ls_position;
            window_len         : tin_natural;
            window_width       : tin_natural;
            VAR window_changed : boolean);
 
VAR
      len           : integer;
      found         : boolean;
      field_changed : boolean;
      screen        : tsp00_ScreenBufAddr;
      att           : tsp00_ScreenBufAddr;
      maxlines      : tsp00_Int2;
      maxcols       : tsp00_Int2;
 
BEGIN
IF  i01g^.ls.nr_screens = 1
THEN
    first_pos.screen_nr := 1;
(*ENDIF*) 
IF  NOT i01g^.is_batch
THEN
&   ifdef WINDOWS
    IF  i56spartswitched( first_pos.screen_part )
    THEN
        BEGIN
        i56getwindow ( first_pos, window_changed);
        i56input_from_box := true;
        END
    ELSE
&       endif
        BEGIN
&       ifdef WINDOWS
        i56input_from_box := false;
&       endif
        WITH i01g^.i50.window DO
            BEGIN
            i51size2(first_pos.screen_nr, first_pos.screen_part,
                  length,width);
            length := length - first_pos.sline + 1;
            width := width - first_pos.scol + 1;
            IF  window_len < length
            THEN
                length := window_len;
            (*ENDIF*) 
            IF  window_width < width
            THEN
                width := window_width;
            (*ENDIF*) 
            i52fromscreenpos(first_pos,first_line,first_col);
            i01g^.i50.curr_sno := first_pos.screen_nr;
            i01g^.i50.curr_row := first_line;
            i01g^.i50.curr_col := first_col - 1;
            END;
        (*ENDWITH*) 
        window_changed := false;
        i53screenaddresses( i01g^.i50.curr_sno, screen, att,
              maxlines, maxcols );
        REPEAT
            WITH i01g^ DO
                i53nextfield (i50.curr_row, i50.curr_col,
                      len, found, field_changed,
                      maxlines, maxcols, screen, att );
            (*ENDWITH*) 
            IF  found
            THEN
                IF  pos_in_window(i01g^.i50.curr_row,i01g^.i50.curr_col,len)
                THEN
                    window_changed := window_changed OR field_changed;
                (*ENDIF*) 
            (*ENDIF*) 
        UNTIL
            NOT found;
        (*ENDREPEAT*) 
        i01g^.i50.curr_row := 1;
        i01g^.i50.curr_col := 0;
        END;
    (*ENDIF*) 
(*ENDIF*) 
END; (* i50getwindow *)
 
(*------------------------------*) 
 
PROCEDURE
      i50getfield (
            VAR vt_input    : tin_ls_input_field;
            VAR field_found : boolean);
 
VAR
      flength       : integer;
      field_changed : boolean;
      within_window : boolean;
      buff          : tin_screenline;
      screen        : tsp00_ScreenBufAddr;
      att           : tsp00_ScreenBufAddr;
      maxlines      : tsp00_Int2;
      maxcols       : tsp00_Int2;
 
BEGIN
within_window := false;
IF  NOT i01g^.is_batch
THEN
&   ifdef WINDOWS
    IF  i56input_from_box
    THEN
        i56getfield ( vt_input, field_found )
    ELSE
&       endif
        BEGIN
        i53screenaddresses( i01g^.i50.curr_sno, screen, att,
              maxlines, maxcols );
        REPEAT
            WITH i01g^ DO
                i53nextfield (i50.curr_row, i50.curr_col, flength,
                      field_found, field_changed,
                      maxlines, maxcols, screen, att );
            (*ENDWITH*) 
            IF  field_found
            THEN
                within_window :=
                      pos_in_window(i01g^.i50.curr_row,i01g^.i50.curr_col,flength);
            (*ENDIF*) 
        UNTIL
            within_window OR (NOT field_found);
        (*ENDREPEAT*) 
        field_found := field_found AND within_window;
        (*writeln('row, col, flength, found ',
              i01g^.i50.curr_row,i01g^.i50.curr_col,flength,field_found);*)
        IF  field_found
        THEN
            BEGIN
            WITH i01g^ DO
                i53getfield (i50.curr_row, i50.curr_col, flength, buff,
                      maxcols, screen );
            (*ENDWITH*) 
            WITH vt_input DO
                BEGIN
                buf := buff;
                len := flength;
                changed := field_changed;
                i52toscreenpos(i01g^.i50.curr_row,i01g^.i50.curr_col,
                      cin_ls_undef_part,fld_pos);
                set_left_right_trunc(vt_input);
                END;
            (*ENDWITH*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDIF*) 
END; (* i50getfield *)
 
(*------------------------------*) 
 
PROCEDURE
      i50directgetfield (
            VAR pos      : tin_ls_position;
            length       : tsp00_Int2;
            VAR vt_input : tin_ls_input_field);
 
VAR
      lno      : tin_natural;
      col      : tin_natural;
      flength  : integer;
      buff     : tin_screenline;
      screen   : tsp00_ScreenBufAddr;
      att      : tsp00_ScreenBufAddr;
      maxlines : tsp00_Int2;
      maxcols  : tsp00_Int2;
 
BEGIN
i52fromscreenpos ( pos, lno, col );
IF  i01g^.ls.nr_screens = 1
THEN
    pos.screen_nr := 1;
(*ENDIF*) 
flength := length;
i53screenaddresses( pos.screen_nr, screen, att, maxlines, maxcols );
i53getfield (lno, col, flength, buff,
      maxcols, screen );
vt_input.changed := i53fchanged ( att, lno, col, length, maxcols );
WITH vt_input DO
    BEGIN
    buf := buff;
    len := flength;
    fld_pos := pos;
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      set_left_right_trunc (
            VAR vt : tin_ls_input_field);
 
VAR
      right_col : integer;
      last_col  : integer;
 
BEGIN
WITH i01g^.i50 DO
    BEGIN
    IF  curr_col < window.first_col
    THEN
        vt.left_trunc :=
              window.first_col - curr_col
    ELSE
        vt.left_trunc := 0;
    (*ENDIF*) 
    right_col := curr_col + vt.len - 1;
    last_col := window.first_col + window.width - 1;
    IF  right_col > last_col
    THEN
        vt.right_trunc :=
              right_col - last_col
    ELSE
        vt.right_trunc := 0; (* !!! *)
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END; (* set_left_right_trunc *)
 
(*------------------------------*) 
 
PROCEDURE
      i50attchange (
            first_pos  : tin_ls_position;
            lines,cols : tin_natural;
            new_att    : tin_ls_fieldtype);
 
VAR
      win      : tin_ls_window;
      ok       : boolean;
      screen   : tsp00_ScreenBufAddr;
      att      : tsp00_ScreenBufAddr;
      maxlines : tsp00_Int2;
      maxcols  : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    i54definelayoutwindow(first_pos,lines,cols,win,ok);
    i53screenaddresses( first_pos.screen_nr, screen, att,
          maxlines, maxcols );
    i53attchange (first_pos.screen_nr, win,new_att,
          maxcols, att );
    END;
(*ENDIF*) 
END; (* i50attchange *)
 
(*------------------------------*) 
 
PROCEDURE
      i50savescreen(
            screen_nr       : tsp00_Int2;
            VAR save_screen : tsp00_MoveObj;
            VAR save_att    : tsp00_MoveObj;
            size            : integer;
            VAR ok          : boolean);
 
VAR
      length : integer;
      screen   : tsp00_ScreenBufAddr;
      att      : tsp00_ScreenBufAddr;
      maxlines : tsp00_Int2;
      maxcols  : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    i53screenaddresses( screen_nr, screen, att,
          maxlines, maxcols );
    IF  (screen <> NIL) AND (att <> NIL)
    THEN
        BEGIN
        length := maxlines * maxcols;
        ok := (length <= size);
        IF  ok
        THEN
            BEGIN
            s10mv(SCREEN_BUF_MXSP00,size,
                  @screen^,1,
                  @save_screen,1,length);
            s10mv(SCREEN_BUF_MXSP00,size,
                  @att^,1,
                  @save_att,1,length);
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
END; (* i50savescreen *)
 
(*------------------------------*) 
 
PROCEDURE
      i50restorescreen(
            screen_nr       : tsp00_Int2;
            VAR save_screen : tsp00_MoveObj;
            VAR save_att    : tsp00_MoveObj);
 
VAR
      size     : integer;
      screen   : tsp00_ScreenBufAddr;
      att      : tsp00_ScreenBufAddr;
      maxlines : tsp00_Int2;
      maxcols  : tsp00_Int2;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    i53screenaddresses( screen_nr, screen, att,
          maxlines, maxcols );
    IF  (screen <> NIL) AND (att <> NIL)
    THEN
        BEGIN
        size := maxlines * maxcols;
        s10mv(MOVEOBJ_MXSP00,SCREEN_BUF_MXSP00,
              @save_screen,1,
              @screen^,1,size);
        s10mv(MOVEOBJ_MXSP00,SCREEN_BUF_MXSP00,
              @save_att,1,
              @att^,1,size);
        (* For next i50ioscreen: whole screen changed *)
        i53changelimits(screen_nr,1);
        (* i53changelimits(screen_nr,size);*)
        i53changelimits(screen_nr,maxlines);
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
END; (* i50restorescreen *)
 
(*------------------------------*) 
 
FUNCTION
      all_screenparts_defined (
            sno : integer) : boolean;
 
VAR
      is_defined : boolean;
      part       : tin_ls_part;
 
BEGIN
is_defined := true;
FOR part := cin_ls_header TO cin_ls_sysline DO
    WITH i01g^.ls.description [sno]  [part ] DO
        IF  first_line <= 0
        THEN
            is_defined := false;
        (*ENDIF*) 
    (*ENDWITH*) 
(*ENDFOR*) 
all_screenparts_defined := is_defined;
END; (* all_screenparts_defined *)
 
(*------------------------------*) 
 
FUNCTION
      pos_in_window (
            row,col,flength : tin_natural) : boolean;
 
VAR
      ok      : boolean;
      lastpos : tin_natural;
 
BEGIN
lastpos := col + flength - 1;
WITH i01g^.i50.window DO
    BEGIN
    ok := (row >= first_line);
    IF  ok
    THEN
        ok := (row <= first_line + length - 1);
    (*ENDIF*) 
    IF  ok
    THEN
        ok := (col >= first_col)
              OR (lastpos >= first_col);
    (*ENDIF*) 
    IF  ok
    THEN
        ok := (col <= first_col + width - 1);
    (*ENDIF*) 
    END;
(*ENDWITH*) 
pos_in_window := ok;
END; (* pos_in_window *)
 
(*------------------------------*) 
 
FUNCTION
      terminal_has_colors : boolean;
 
VAR
      has    : boolean;
      colors : tsp00_VtColors;
 
BEGIN
has := vt_inverse IN i01g^.vt.desc.attributes;
IF  NOT has
THEN
    BEGIN
    colors := [ vt_red..vt_light_blue] ;
    has := ( colors
          * i01g^.vt.desc.colors <> [   ] );
    END;
(*ENDIF*) 
terminal_has_colors := has;
END; (* terminal_has_colors *)
 
&ifdef WINDOWS
(*------------------------------*) 
 
PROCEDURE
      clear_scrollparms (   sno : tsp00_Int2;
            screen_part : tin_ls_part);
 
VAR
      rge : tin_display_range;
      lbl : tsp00_C8;
      screen   : tsp00_ScreenBufAddr;
      att      : tsp00_ScreenBufAddr;
      maxlines : tsp00_Int2;
      maxcols  : tsp00_Int2 ;
 
BEGIN
IF  (screen_part = cin_ls_whole_screen)
    OR (screen_part = cin_ls_basic_window)
    OR (screen_part = cin_ls_workarea)
THEN
    BEGIN
    lbl := bsp_c8;
    i53screenaddresses ( sno, screen, att, maxlines, maxcols );
    WITH rge DO
        BEGIN
        total_begin := 1;
        total_end := maxlines;
        displ_begin := total_begin;
        displ_end := total_end;
        END;
    (*ENDWITH*) 
    i56vrange ( 1, lbl, rge );
    WITH rge DO
        BEGIN
        total_end := i01g^.vt.desc.num_of_cols;
        displ_end := total_end;
        END;
    (*ENDWITH*) 
    i56hrange ( 1, rge );
    END;
(*ENDIF*) 
END;
 
&endif
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
