.CM  SCRIPT , Version - 1.1 , last edited by B.Morgeneyer
.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$VIN51$
.tt 2 $$$
.TT 3 $$Logical Screen Layout$1995-11-01$
***********************************************************
.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_layout
=========
.sp
Purpose : Logical Screen: Layout/Split/Windows
 
&       if $OS=UNIX
&       define hifmode 1
&       else
&       ifdef WINDOWS
&       define hifmode 1
&       else
&       if $OS=MSDOS
&       define pcmode 1
&       endif
&       endif
&       endif
.CM *-END-* purpose -------------------------------------
.sp
Define  :
 
        PROCEDURE
              i51init;
 
        PROCEDURE
              i51initbasicwindow (
                    nr_screens : integer );
 
        PROCEDURE
              i51layout (
                    functionmenu_length : tin_natural;
                    inputarea_length    : tin_natural;
                    msglines            : tin_natural);
 
        PROCEDURE
              i51ownlayout (
                    defined_part : tin_ls_part;
                    first_pos    : tin_ls_position;
                    lines,cols   : tin_natural);
 
        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);
 
        PROCEDURE
              i51split (
                    screens : tin_natural);
 
        PROCEDURE
              i51splminmax (
                    screens   : tin_natural;
                    minimized : tsp00_Int2;
                    maximized : tsp00_Int2 );
 
        PROCEDURE
              i51splsize (
                    screens : tin_natural;
                    lines1  : tsp00_Int2;
                    lines2  : tsp00_Int2 );
 
        PROCEDURE
              i51onwindow (
                    defined_part : tin_ls_part;
                    VAR win      : tin_screen_window;
                    VAR ok       : boolean );
 
        PROCEDURE
              i51offwindow (
                    VAR restore : boolean );
 
        FUNCTION
              in5130 : tsp00_Int4;
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              global_variable : VIN01;
 
        VAR
              i01g : tin_global_in_vars;
&       ifdef WINDOWS
 
      ------------------------------ 
 
        FROM
              logical_screen : VIN50 ;
 
        PROCEDURE
              i50clear (
                    screen_part : tin_ls_part );
&       endif
 
      ------------------------------ 
 
        FROM
              logical_screen_variants : VIN52;
 
&       ifdef WINDOWS
        PROCEDURE
              i52winlayout (
                    inputarea_length : tin_natural;
                    msglines         : tin_natural);
&       else
&       ifdef PCMODE
 
        PROCEDURE
              i52pclayout (
                    workarea_length     : tsp00_Int2;
                    functionmenu_length : tin_natural;
                    inputarea_length    : tin_natural;
                    msglines            : tin_natural);
&       else
 
        PROCEDURE
              i52ibmlayout (
                    workarea_length     : tsp00_Int2;
                    functionmenu_length : tin_natural;
                    inputarea_length    : tin_natural;
                    msglines            : tin_natural);
 
        PROCEDURE
              i52unixlayout (
                    workarea_length     : tsp00_Int2;
                    functionmenu_length : tin_natural;
                    inputarea_length    : tin_natural;
                    msglines            : tin_natural);
&       ifdef hifmode
 
        PROCEDURE
              i52sklayout (
                    workarea_length  : tsp00_Int2;
                    inputarea_length : tin_natural;
                    msglines         : tin_natural);
&       endif
&       endif
&       endif
 
        PROCEDURE
              i52fromscreenpos (
                    VAR pos       : tin_ls_position;
                    VAR screenlno : tin_natural;
                    VAR screencol : tin_natural);
 
      ------------------------------ 
 
        FROM
              logical_screen_procedures : VIN53;
 
        PROCEDURE
              i53put2field (
                    VAR field        : tin_screenline;
                    length           : integer;
                    sno              : tsp00_Int2;
                    field_slno       : integer;
                    field_scol       : integer;
                    VAR field_type   : tin_ls_fieldtype;
                    maxlines,maxcols : integer;
                    vt_screen        : tsp00_ScreenBufAddr;
                    vt_att           : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53attchange (
                    sno              : tsp00_Int2;
                    win              : tin_ls_window;
                    VAR ft           : tin_ls_fieldtype;
                    maxcols          : integer;
                    vt_att           : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53clear (
                    att               : tin_ls_attribute_index;
                    maxlines, maxcols : integer;
                    vt_screen         : tsp00_ScreenBufAddr;
                    vt_att            : tsp00_ScreenBufAddr);
 
        PROCEDURE
              i53changelimits (
                    sno   : tsp00_Int2;
                    rowno : tsp00_Int2);
 
      ------------------------------ 
 
        FROM
              logical_screen_help_procedures : VIN54;
 
        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
              i54resolvedefaults (
                    part           : tin_ls_part;
                    VAR field_type : tin_ls_fieldtype);
&       ifdef WINDOWS
 
      ------------------------------ 
 
        FROM
              Windows_RTE_Extension : VEN102W ;
 
        PROCEDURE
              sqlwsplit (
                    VAR term_ref : tsp00_Int4;
                    nr_screens   : tsp00_Int2;
                    opt1         : tsp00_VtSplitoptaddr ;
                    VAR desc1    : tsp00_TerminalDescription;
                    opt2         : tsp00_VtSplitoptaddr ;
                    VAR desc2    : tsp00_TerminalDescription;
                    VAR ok       : boolean);
 
        PROCEDURE
              sqlwindow (
                    parent_ref   : tsp00_Int4;
                    VAR position : tsp00_VtRectangle;
                    VAR desc     : tsp00_TerminalDescription;
                    VAR win_ref  : tsp00_Int4;
                    VAR ok       : boolean);
 
        PROCEDURE
              sqlwoff (
                    win_ref        : tsp00_Int4;
                    VAR desc       : tsp00_TerminalDescription;
                    VAR parent_ref : tsp00_Int4 );
&       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_VtSplitopt) : tsp00_VtSplitoptaddr ;
&       ifdef WINDOWS
 
      ------------------------------ 
 
        FROM
              logical_screen_modules : VIN56;
 
        VAR
              i56desc2 : tsp00_TerminalDescription ;
&       endif
&       ifdef WINDOWS
 
        FUNCTION
              i56spartswitched (
                    screenpart : tin_ls_part ) : boolean;
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              i53put2field;
 
              tsp00_MoveObj tin_screenline
 
        FUNCTION
              s30gad;
 
              tsp00_MoveObj  tsp00_VtSplitopt
              tsp00_Addr tsp00_VtSplitoptaddr
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1986-06-27
.sp
.cp 3
.sp
.cp 3
Release :  6.1.2     Date : 1995-11-01
.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
      i51split (
            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
      i51splminmax (
            screens   : tin_natural;
            minimized : tsp00_Int2;
            maximized : tsp00_Int2 );
.sp;.fo;like i51split; additionally, for Windows envirionments, one or both of
the split windows can be minimized or maximized:
.sp;minimized = 0: none of the windows will be minimized
.br;minimized = 1: window #1 will be minimized
.br;minimized = 2: window #2 will be minimized
.br;minimized = 3: both windows will be maximized.
.sp;maximized = 0: none of the windows will be maximized
.br;maximized = 1: window #1 will be maximized and active
.br;maximized = 2: window #2 will be maximized and active
.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
      i50putlabels (
            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
      i50putframe (
            scroll : ti_scroll_direction);
.sp;.fo;prepares the output of the upper and lower margins of
the work window (horizontal lines).
.sp;In the case of SCROLL\=\LEFT_ONLY or
SCROLL\=\LEFT_AND_RIGHT, three angles pointing left are shown
at the left-hand edge of the delimiter bars; in the case of
SCROLL\=\RIGHT_ONLY or SCROLL\=\LEFT_AND_RIGHT, three angles
pointing right are shown at the right-hand edge.
.br;In the case of SCROLL\=\NO_SHIFT, these angles are omitted.
.se;.cm Output ...
.sp 2;.cp 14;
.sb;Passing the screen created to the virtual terminal
.sp 2;.nf
PROCEDURE
      i50ioscreen (
            options            : vt_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 with
.sp;.nf
        PROCEDURE
              i50getkey (
                    VAR key : vt_keystroke);
.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
      i51onwindow (
            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
         i51offwindowdow ;
.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
      i50ownlayout (
            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    :
 
 
&ifdef WINDOWS
CONST
      max_sqlwindows = 4;
 
TYPE
 
      sqlwin_stack = RECORD
            level : tsp00_Int2;
            sqlwin : ARRAY [ 1..max_sqlwindows  ] OF boolean;
      END;
 
 
VAR
      i51win : sqlwin_stack;
&     endif
 
 
(*------------------------------*) 
 
FUNCTION
      in5130 : tsp00_Int4;
 
BEGIN
(* linkcheck function *)
in5130 := 219020320;
END;
 
(*------------------------------*) 
 
PROCEDURE
      i51init;
 
BEGIN
&ifdef WINDOWS
i51win.level := 0;
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      i51initbasicwindow (
            nr_screens : integer);
 
VAR
      maxlines : integer;
      maxcols  : integer;
      sno      : integer;
 
BEGIN
i01g^.ls.nr_screens := nr_screens;
FOR sno := 1 TO nr_screens DO
    BEGIN
&   ifdef WINDOWS
    IF  sno = 2
    THEN
        BEGIN
        maxlines  := i56desc2.num_of_lines;
        maxcols  := i56desc2.num_of_cols;
        END
    ELSE
&       endif
        BEGIN
        maxlines  := i01g^.vt.desc.num_of_lines;
        maxcols  := i01g^.vt.desc.num_of_cols;
        END;
    (*ENDIF*) 
    (* basic window *)
    WITH i01g^.ls.description [sno] [ cin_ls_basic_window ] DO
        BEGIN
        first_line := 1;
        last_line := maxlines;
        first_col := 2;
        last_col := maxcols;
        END;
    (*ENDWITH*) 
    END;
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      i51layout (
            functionmenu_length : tin_natural;
            inputarea_length    : tin_natural;
            msglines            : tin_natural);
 
VAR
      workarea_length : tsp00_Int2;
      lines1          : tsp00_Int2;
      lines2          : tsp00_Int2;
 
BEGIN
IF  i01g^.ls.nr_screens = 1
THEN
    workarea_length := -1
ELSE
    BEGIN
    WITH i01g^.ls.description [1] [ cin_ls_workarea ] DO
        lines1 := last_line - first_line + 1;
    (*ENDWITH*) 
    WITH i01g^.ls.description [2] [ cin_ls_workarea ] DO
        lines2 := last_line - first_line + 1;
    (*ENDWITH*) 
    IF  lines1 = lines2
    THEN
        workarea_length := -1
    ELSE
        workarea_length := lines1;
    (*ENDIF*) 
    END;
(*ENDIF*) 
layout_i51 ( workarea_length, functionmenu_length, inputarea_length,
      msglines );
END;
 
(*------------------------------*) 
 
PROCEDURE
      layout_i51 (
            workarea_length     : tsp00_Int2;
            functionmenu_length : tin_natural;
            inputarea_length    : tin_natural;
            msglines            : tin_natural );
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
&   ifdef WINDOWS
    i52winlayout( inputarea_length, msglines);
&   else
&   ifndef PCMODE
    IF  ord(bsp_c1) <> 32
    THEN (* EBCDIC = IBM *)
        i52ibmlayout( workarea_length,
              functionmenu_length, inputarea_length, msglines)
    ELSE (* ASCII *)
&       ifdef hifmode
        IF  i01g^.vt.desc.labels <> no_sk_labels
        THEN
            i52sklayout(workarea_length, inputarea_length, msglines)
        ELSE
&           endif
&           endif
            BEGIN
&           ifdef PCMODE
            i52pclayout(workarea_length, functionmenu_length,
                  inputarea_length, msglines);
&           else
            i52unixlayout(workarea_length, functionmenu_length,
                  inputarea_length, msglines)
&                 endif
            END;
        (*ENDIF*) 
    (*ENDIF*) 
&   endif
    END;
(*ENDIF*) 
END; (* i51layout *)
 
(*------------------------------*) 
 
PROCEDURE
      i51ownlayout (
            defined_part : tin_ls_part;
            first_pos    : tin_ls_position;
            lines,cols   : tin_natural);
 
VAR
      ok : boolean;
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
    WITH i01g^.ls DO
        i54definelayoutwindow(first_pos,lines,cols,
              description [1] [ defined_part] ,ok);
    (*ENDWITH*) 
    END;
(*ENDIF*) 
END; (* i51ownlayout *)
 
(*------------------------------*) 
 
PROCEDURE
      i51size (
            screen_part    : tin_ls_part;
            VAR partlength : tin_natural;
            VAR partwidth  : tin_natural);
 
BEGIN
i51size2( i01g^.ls.nr_screens , screen_part, partlength, partwidth );
END;
 
(*------------------------------*) 
 
PROCEDURE
      i51size2 (
            sno            : integer;
            screen_part    : tin_ls_part;
            VAR partlength : tin_natural;
            VAR partwidth  : tin_natural);
 
VAR
      length : integer;
      width  : integer;
 
BEGIN
IF  screen_part = cin_ls_whole_screen
THEN
    BEGIN
    length := i01g^.vt.desc.num_of_lines;
    width := i01g^.vt.desc.num_of_cols;
    END
ELSE
&   ifdef WINDOWS
    IF  i56spartswitched ( screen_part )
    THEN
        BEGIN
        CASE screen_part OF
            cin_ls_whole_screen,
            cin_ls_basic_window,
            cin_ls_workarea:
                length := i01g^.vt.desc.num_of_lines;
            cin_ls_inputarea,
            cin_ls_sysline:
                length := 1;
            OTHERWISE
                length := 0;
            END;
        (*ENDCASE*) 
        width := mxin_screenline;
        END
    ELSE
&       endif
        BEGIN
        (*sno := i01g^.ls.nr_screens;*)
        WITH i01g^,ls,description [sno]  [ screen_part  ] DO
            BEGIN
            IF  first_line = 0
            THEN
                BEGIN
                length := 0;
                width := 0;
                END
            ELSE
                BEGIN
                length := last_line - first_line + 1;
                width  := last_col  - first_col  + 1;
                WITH vt.desc DO
                    IF  (first_line = num_of_lines)
                        AND (last_line = num_of_lines)
                        AND (last_col = num_of_cols) (*????????*)
                    THEN
                        width := width - 1;
                    (*ENDIF*) 
                (*ENDWITH*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        IF  (screen_part = cin_ls_sysline)
            AND i01g^.vt.desc.has_sysline
        THEN
            BEGIN
            (*Changed at 88/11/30*)
            IF  length = 0 (* not yet defined *)
            THEN
                BEGIN
&               ifdef WINDOWS
                width := i01g^.vt.desc.num_of_cols - cin_win_modefield_end;
&               else
                width := i01g^.vt.desc.num_of_cols - 2;
&               endif
                END;
            (*ENDIF*) 
            length := length + 1;
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDIF*) 
IF  length >= 0
THEN
    partlength := length
ELSE
    partlength := 0;
(*ENDIF*) 
IF  width >= 0
THEN
    partwidth := width
ELSE
    partwidth := 0;
(*ENDIF*) 
END; (* i51size *)
 
(*------------------------------*) 
 
PROCEDURE
      i51split (
            screens : tin_natural);
 
VAR
      ok : boolean;
 
BEGIN
ok := false;
IF  NOT i01g^.is_batch
THEN
    BEGIN
&   ifdef WINDOWS
    call_sqlwsplit(screens, 0, 0, 0, 0, ok);
&   endif
    IF  NOT ok
    THEN
        simulate_split (screens, 0);
    (*ENDIF*) 
    END;
(*ENDIF*) 
END; (* i51split *)
 
(*------------------------------*) 
 
PROCEDURE
      i51splminmax (
            screens   : tin_natural;
            minimized : tsp00_Int2;
            maximized : tsp00_Int2 );
 
VAR
      ok : boolean;
 
BEGIN
ok := false;
IF  NOT i01g^.is_batch
THEN
    BEGIN
&   ifdef WINDOWS
    call_sqlwsplit(screens, minimized, maximized, 0, 0, ok);
&   endif
    IF  NOT ok
    THEN
        simulate_split (screens, 0);
    (*ENDIF*) 
    END;
(*ENDIF*) 
END; (* i51split *)
 
(*------------------------------*) 
 
PROCEDURE
      i51splsize (
            screens : tin_natural;
            lines1  : tsp00_Int2;
            lines2  : tsp00_Int2 );
 
VAR
      ok : boolean;
 
BEGIN
ok := false;
IF  NOT i01g^.is_batch
THEN
    BEGIN
&   ifdef WINDOWS
    call_sqlwsplit(screens, 0, 0, lines1, lines2, ok );
&   endif
    IF  NOT ok
    THEN
        simulate_split (screens, lines1);
    (*ENDIF*) 
    END;
(*ENDIF*) 
END; (* i51split *)
 
&ifdef WINDOWS
(*------------------------------*) 
 
PROCEDURE
      call_sqlwsplit(
            screens      : tin_natural;
            minimized    : tsp00_Int2;
            maximized    : tsp00_Int2 ;
            lines1       : tsp00_Int2;
            lines2       : tsp00_Int2;
            VAR split_ok : boolean );
 
VAR
      functionmenu_length : tin_natural;
      inputarea_length    : tin_natural;
      msglines            : tin_natural;
 
BEGIN
WITH i01g^ DO
    IF  ls.nr_screens <> screens
    THEN
        BEGIN
        get_layout_parameters(functionmenu_length,inputarea_length,msglines);
        ls.nr_screens := screens;
        IF  screens = 1
        THEN
            BEGIN
            minimized := 0;
            maximized := 0;
            lines1    := 0;
            lines2    := 0;
            END;
        (*ENDIF*) 
        IF  ( minimized <> 0) OR (maximized <> 0)
        THEN
            call_sqlwsplit_minmax( screens, minimized, maximized, split_ok )
        ELSE
            IF  ( lines1 <> 0) OR (lines2 <> 0)
            THEN
                call_sqlwsplit_size( screens, lines1, lines2, split_ok )
            ELSE
                sqlwsplit ( vt.vt_ref, screens, NIL, vt.desc,
                      NIL, i56desc2, split_ok );
            (*ENDIF*) 
        (*ENDIF*) 
        IF  split_ok
        THEN
            BEGIN
            i51initbasicwindow ( screens );
            IF  screens = 2
            THEN
                i50clear( cin_ls_basic_window );
            (*ENDIF*) 
            IF  lines1 = 0
            THEN
                lines1 := -1;
            (*ENDIF*) 
            layout_i51( lines1,
                  functionmenu_length, inputarea_length, msglines);
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      call_sqlwsplit_minmax(
            screens      : tin_natural;
            minimized    : tsp00_Int2;
            maximized    : tsp00_Int2 ;
            VAR split_ok : boolean );
 
VAR
      opt1 : tsp00_VtSplitopt ;
      opt2 : tsp00_VtSplitopt ;
 
BEGIN
opt1.pos.top    := 0;
opt1.pos.bottom := 0;
opt1.pos.left   := 0;
opt1.pos.right  := 0;
opt2 := opt1;
CASE maximized OF
    1:
        BEGIN
        opt1.maximized := true;
        opt2.maximized := false;
        END;
    2:
        BEGIN
        opt1.maximized := false;
        opt2.maximized := true;
        END;
    3:
        BEGIN
        opt1.maximized := true;
        opt2.maximized := true;
        END;
    OTHERWISE
        BEGIN
        opt1.maximized := false;
        opt2.maximized := false;
        END;
    END;
(*ENDCASE*) 
CASE minimized OF
    1:
        BEGIN
        opt1.icon := true;
        opt2.icon := false;
        END;
    2:
        BEGIN
        opt1.icon := false;
        opt2.icon := true;
        END;
    3:
        BEGIN
        opt1.icon := true;
        opt2.icon := true;
        END;
    OTHERWISE
        BEGIN
        opt1.icon := false;
        opt2.icon := false;
        END;
    END;
(*ENDCASE*) 
WITH i01g^ DO
    sqlwsplit ( vt.vt_ref, screens, s30gad(opt1), vt.desc,
          s30gad(opt2), i56desc2, split_ok )
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      call_sqlwsplit_size (
            screens      : tin_natural;
            lines1       : tsp00_Int2;
            lines2       : tsp00_Int2 ;
            VAR split_ok : boolean );
 
VAR
      opt1 : tsp00_VtSplitopt ;
      opt2 : tsp00_VtSplitopt ;
 
BEGIN
opt1.maximized := false;
opt2.maximized := false;
opt1.icon := false;
opt2.icon := false;
default_splitopt( opt1 );
default_splitopt( opt2 );
IF  lines1 > 0
THEN
    BEGIN
    opt1.pos.top    := 1;
    opt1.pos.bottom := lines1;
    opt1.pos.left   := 1;
    opt1.pos.right  := 0;
    END;
(*ENDIF*) 
IF  lines2 > 0
THEN
    BEGIN
    opt2.pos.top    := 1;
    opt2.pos.bottom := lines2;
    opt2.pos.left   := 1;
    opt2.pos.right  := 0;
    END;
(*ENDIF*) 
WITH i01g^ DO
    sqlwsplit ( vt.vt_ref, screens, s30gad(opt1), vt.desc,
          s30gad(opt2), i56desc2, split_ok )
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      default_splitopt(
            VAR opt : tsp00_VtSplitopt );
 
BEGIN
WITH opt.pos DO
    BEGIN
    top    := 0;
    bottom := 0;
    left   := 0;
    right  := 0;
    END;
(*ENDWITH*) 
END;
 
&endif
(*------------------------------*) 
 
PROCEDURE
      simulate_split (
            screens : tin_natural;
            lines   : tsp00_Int2);
 
VAR
      functionmenu_length : tin_natural;
      inputarea_length    : tin_natural;
      msglines            : tin_natural;
      i                   : tin_ls_part;
 
BEGIN
WITH i01g^ DO
    IF  ls.nr_screens <> screens
    THEN
        BEGIN
        get_layout_parameters(functionmenu_length,inputarea_length,msglines);
        ls.nr_screens := screens;
        IF  screens = 2
        THEN
            BEGIN
            WITH i01g^.ls.description [2] [ cin_ls_basic_window ] DO
                BEGIN
                last_line := i01g^.ls.description [1]
                      [ cin_ls_basic_window] .last_line;
                END;
            (*ENDWITH*) 
            END
        ELSE
            BEGIN
            WITH i01g^.ls.description [1] [ cin_ls_basic_window ] DO
                last_line := i01g^.ls.description [2]
                      [ cin_ls_basic_window] .last_line;
            (*ENDWITH*) 
            FOR i := cin_ls_basic_window TO cin_ls_sysline DO
                i54disablescreenpart(2,i);
            (*ENDFOR*) 
            END;
        (*ENDIF*) 
        IF  lines <= 0
        THEN
            lines := -1;
        (*ENDIF*) 
        layout_i51( lines, functionmenu_length, inputarea_length, msglines);
        END;
    (*ENDIF*) 
(*ENDWITH*) 
END; (* simulate_split *)
 
(*------------------------------*) 
 
PROCEDURE
      i51onwindow (
            defined_part : tin_ls_part;
            VAR win      : tin_screen_window;
            VAR ok       : boolean );
 
BEGIN
IF  NOT i01g^.is_batch
THEN
    BEGIN
&   ifdef WINDOWS
    IF  (defined_part = cin_ls_basic_window)
        OR (defined_part = cin_ls_workarea)
    THEN
        call_sqlwindow ( win, ok )
    ELSE
&       endif
        simulate_window ( defined_part, win, ok );
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
&ifdef WINDOWS
(*------------------------------*) 
 
PROCEDURE
      call_sqlwindow (
            VAR win    : tin_screen_window;
            VAR win_ok : boolean );
 
VAR
      pos                 : tsp00_VtRectangle;
      win_ref             : tsp00_Int4;
      functionmenu_length : tin_natural;
      inputarea_length    : tin_natural;
      msglines            : tin_natural;
      leftline            : tin_natural;
      topline             : tin_natural;
      layout              : boolean;
 
BEGIN
IF  i51win.level >= max_sqlwindows
THEN
    win_ok := false
ELSE
    BEGIN
    layout := ( i01g^.ls.description [1]
          [  cin_ls_workarea ] .first_line > 0);
    IF  layout
    THEN
        get_layout_parameters(functionmenu_length,
              inputarea_length,msglines);
    (*ENDIF*) 
    i52fromscreenpos ( win.first_pos, topline, leftline );
    pos.top  := topline  ;
    pos.left := leftline ;
    pos.bottom := pos.top + win.lines - 1;
    pos.right := pos.left + win.cols - 1;
    WITH i01g^.vt DO
        BEGIN
        sqlwindow ( vt_ref, pos, desc, win_ref, win_ok );
        IF  win_ok
        THEN
            vt_ref := win_ref;
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
    IF  win_ok
    THEN
        BEGIN
        WITH i01g^.vt,desc DO
            i53clear (cin_ls_normal,
                  num_of_lines, num_of_cols,
                  content_buf, attribute_buf);
        (*ENDWITH*) 
        i53changelimits(1,1);
        i53changelimits(1,SCREEN_LINES_MXSP00);
        i51initbasicwindow( 1 );
        IF  layout
        THEN
            i51layout(functionmenu_length, inputarea_length, msglines);
        (*ENDIF*) 
        WITH i51win DO
            BEGIN
            level := level + 1;
            sqlwin [  level  ] := win_ok;
            END;
        (*ENDWITH*) 
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
&endif
(*------------------------------*) 
 
PROCEDURE
      simulate_window (
            defined_part : tin_ls_part;
            VAR win      : tin_screen_window;
            VAR ok       : boolean );
 
VAR
      functionmenu_length : tin_natural;
      inputarea_length    : tin_natural;
      msglines            : tin_natural;
      outer_window        : tin_ls_window;
      background          : tin_ls_window;
      prev_window_frame   : boolean;
      layout              : boolean;
 
BEGIN
ok := (defined_part <> cin_ls_whole_screen);
IF  ok
THEN
    BEGIN
    IF  i01g^.vt.wopt.background_part = cin_ls_whole_screen
    THEN
        WITH background DO
            BEGIN
            first_line := 1;
            first_col := 1;
            last_line := i01g^.vt.desc.num_of_lines;
            last_col := i01g^.vt.desc.num_of_cols;
            END
        (*ENDWITH*) 
    ELSE
        IF  i01g^.vt.wopt.background_part <> cin_ls_undef_part
        THEN
            background :=
                  i01g^.ls.description [1] [ i01g^.vt.wopt.background_part] ;
        (*ENDIF*) 
    (*ENDIF*) 
    layout := ( i01g^.ls.description [1]
          [  cin_ls_workarea ] .first_line > 0);
    IF  layout
    THEN
        get_layout_parameters(functionmenu_length,
              inputarea_length,msglines);
    (*ENDIF*) 
    push_window_stack(ok);
    IF  ok
    THEN
        BEGIN
        i01g^.i50.defined_part := defined_part;
        prev_window_frame := i01g^.i50.with_windowframe;
        i01g^.i50.with_windowframe := i01g^.vt.wopt.with_frame;
        WITH win DO
            i54definelayoutwindow(first_pos,lines,cols,outer_window,ok);
        (*ENDWITH*) 
        IF  ok
        THEN
            BEGIN
            i01g^.ls.description [1] [ defined_part ] := outer_window;
            WITH i01g^.ls.description [1] [ defined_part ] DO
                IF  i01g^.vt.wopt.with_frame
                THEN
                    BEGIN
                    first_line := first_line + 1;
                    last_line := last_line - 1;
                    first_col := first_col + 2;
                    last_col := last_col - 2;
                    END;
                (*ENDIF*) 
            (*ENDWITH*) 
            IF  (defined_part = cin_ls_basic_window) AND layout
            THEN
                BEGIN
                check_window_size(functionmenu_length,
                      inputarea_length, msglines,ok);
                IF  ok
                THEN
                    i51layout(functionmenu_length, inputarea_length, msglines);
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  ok
        THEN
            BEGIN
            IF  i01g^.vt.wopt.background_part <> cin_ls_undef_part
            THEN
                change_background_attributes( prev_window_frame,
                      background,i01g^.vt.wopt.background_ft,
                      outer_window);
            (*ENDIF*) 
            IF  i01g^.vt.wopt.with_frame
            THEN
                put_window_frame(outer_window,
                      i01g^.vt.wopt.frame_ft,defined_part);
            (*ENDIF*) 
            END
        ELSE
            pop_window_stack;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
END; (* i51onwindow *)
 
(*------------------------------*) 
 
PROCEDURE
      check_window_size (
            functionmenu_length : tin_natural;
            inputarea_length    : tin_natural;
            msglines            : tin_natural;
            VAR ok              : boolean);
 
CONST
      min_cols = 22;
 
VAR
      lines,cols : tin_natural;
      total      : integer;
 
BEGIN
i51size(cin_ls_basic_window,lines,cols);
ok := cols >= min_cols;
IF  ok
THEN
    BEGIN
    total := functionmenu_length + inputarea_length + msglines
          + 2 (* frame *) + 1 (* workarea *)
          + 1 (* headerline *);
    ok := total <= lines;
    END;
(*ENDIF*) 
END; (* check_window_size *)
 
(*------------------------------*) 
 
PROCEDURE
      change_background_attributes (
            outer_window_frame : boolean;
            background         : tin_ls_window;
            background_ft      : tin_ls_fieldtype;
            foreground         : tin_ls_window);
 
VAR
      small_rectangle : tin_ls_window;
 
BEGIN
IF  outer_window_frame
THEN
    WITH background DO
        BEGIN
        first_col := first_col - 1;
        last_col := last_col + 1;
        END;
    (*ENDWITH*) 
(*ENDIF*) 
background_ft.fieldmode := [  ] ;
(* top *)
small_rectangle := background;
WITH small_rectangle DO
    IF  foreground.first_line > 1
    THEN
        last_line := foreground.first_line - 1
    ELSE
        last_line := 0;
    (*ENDIF*) 
(*ENDWITH*) 
WITH i01g^.vt,desc DO
    i53attchange (1, small_rectangle, background_ft,
          num_of_cols, attribute_buf);
(*ENDWITH*) 
(* bottom *)
small_rectangle := background;
WITH small_rectangle DO
    first_line := foreground.last_line + 1;
(*ENDWITH*) 
WITH i01g^.vt,desc DO
    i53attchange (1, small_rectangle, background_ft,
          num_of_cols, attribute_buf );
(*ENDWITH*) 
(* left *)
small_rectangle := background;
WITH small_rectangle DO
    BEGIN
    IF  foreground.first_line > background.first_line
    THEN
        first_line := foreground.first_line
    ELSE
        first_line := background.first_line;
    (*ENDIF*) 
    IF  foreground.last_line < background.last_line
    THEN
        last_line := foreground.last_line
    ELSE
        last_line := background.last_line;
    (*ENDIF*) 
    IF  foreground.first_col > 1
    THEN
        last_col := foreground.first_col - 1
    ELSE
        last_col := 0;
    (*ENDIF*) 
    END;
(*ENDWITH*) 
WITH i01g^.vt,desc DO
    i53attchange (1, small_rectangle, background_ft,
          num_of_cols, attribute_buf);
(*ENDWITH*) 
(* right *)
small_rectangle := background;
WITH small_rectangle DO
    BEGIN
    IF  foreground.first_line > background.first_line
    THEN
        first_line := foreground.first_line
    ELSE
        first_line := background.first_line;
    (*ENDIF*) 
    IF  foreground.last_line < background.last_line
    THEN
        last_line := foreground.last_line
    ELSE
        last_line := background.last_line;
    (*ENDIF*) 
    first_col := foreground.last_col + 1;
    END;
(*ENDWITH*) 
WITH i01g^.vt,desc DO
    i53attchange (1, small_rectangle, background_ft,
          num_of_cols, attribute_buf );
(*ENDWITH*) 
END; (* change_background_ *)
 
(*------------------------------*) 
 
PROCEDURE
      put_window_frame (
            outer_window : tin_ls_window;
            frame_ft     : tin_ls_fieldtype;
            defined_part : tin_ls_part);
 
VAR
      lno       : integer;
      frameline : tin_screenline;
      length    : integer;
 
BEGIN
i54resolvedefaults (defined_part, frame_ft);
WITH frame_ft DO
    WITH outer_window DO
        BEGIN
        length := last_col - first_col + 1;
        SAPDB_PascalForcedFill (mxin_screenline,@frameline,1,length,csp_horizontal_bar );
        frameline [1]  :=  csp_u_left_corner ;
        frameline [length ] :=  csp_u_right_corner ;
        WITH i01g^.vt,desc DO
            i53put2field(frameline,length,1, first_line,first_col,
                  frame_ft,num_of_lines,num_of_cols,
                  content_buf ,attribute_buf );
        (*ENDWITH*) 
        frameline [1]  :=  csp_l_left_corner ;
        frameline [length ] :=  csp_l_right_corner ;
        WITH i01g^.vt,desc DO
            i53put2field(frameline,length,1, last_line,first_col,
                  frame_ft,num_of_lines,num_of_cols,
                  content_buf,attribute_buf);
        (*ENDWITH*) 
        frameline [1]  :=  csp_vertical_bar ;
        FOR lno := first_line + 1 TO last_line - 1 DO
            BEGIN
            WITH i01g^.vt,desc DO
                BEGIN
                i53put2field(frameline,1,1,lno,first_col,
                      frame_ft,num_of_lines,num_of_cols,
                      content_buf,attribute_buf);
                i53put2field(frameline,1,1,lno,last_col,
                      frame_ft,num_of_lines,num_of_cols,
                      content_buf,attribute_buf);
                END;
            (*ENDWITH*) 
            END;
        (*ENDFOR*) 
        END;
    (*ENDWITH*) 
(*ENDWITH*) 
END; (* put_window_frame *)
 
(*------------------------------*) 
 
PROCEDURE
      i51offwindow (
            VAR restore : boolean );
 
BEGIN
restore := false;
IF  NOT i01g^.is_batch
THEN
&   ifdef WINDOWS
    WITH i51win DO
        IF  (level > 0) AND sqlwin [ level  ]
        THEN
            call_sqlwoff
        ELSE
&           endif
            simulate_offwindow ( restore );
        (*ENDIF*) 
    (*ENDWITH*) 
(*ENDIF*) 
END; (* i51offwindow *)
 
&ifdef WINDOWS
(*------------------------------*) 
 
PROCEDURE
      call_sqlwoff;
 
VAR
      parent_ref          : tsp00_Int4;
      functionmenu_length : tin_natural;
      inputarea_length    : tin_natural;
      msglines            : tin_natural;
      layout              : boolean;
 
BEGIN
layout := ( i01g^.ls.description [1]
      [  cin_ls_workarea ] .first_line > 0);
IF  layout
THEN
    get_layout_parameters(functionmenu_length,
          inputarea_length,msglines);
(*ENDIF*) 
WITH i01g^.vt DO
    BEGIN
    sqlwoff ( vt_ref, desc, parent_ref );
    vt_ref := parent_ref ;
    END;
(*ENDWITH*) 
i51initbasicwindow ( 1 );
IF  layout
THEN
    i51layout(functionmenu_length, inputarea_length, msglines);
(*ENDIF*) 
WITH i51win DO
    level := level - 1;
(*ENDWITH*) 
END;
 
&endif
(*------------------------------*) 
 
PROCEDURE
      simulate_offwindow (
            VAR restore : boolean );
 
BEGIN
WITH i01g^.i50.stack DO
    IF  level > 0
    THEN
        BEGIN
        pop_window_stack;
        restore := true
        END
    ELSE
        restore := false;
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      push_window_stack (
            VAR ok : boolean);
 
VAR
      i : integer;
 
BEGIN
ok := i01g^.i50.stack.level + i01g^.ls.nr_screens
      <= mxin_window_stack;
IF  ok
THEN
    FOR i := 1 TO i01g^.ls.nr_screens DO
        BEGIN
        i01g^.i50.stack.level := i01g^.i50.stack.level + 1;
        WITH i01g^.i50.stack,stack [level ] DO
            BEGIN
            screen_nr := i;
            description := i01g^.ls.description [i] ;
            defined_part := i01g^.i50.defined_part;
            with_windowframe := i01g^.i50.with_windowframe;
            END;
        (*ENDWITH*) 
        END;
    (*ENDFOR*) 
(*ENDIF*) 
END; (* push_window_stack *)
 
(*------------------------------*) 
 
PROCEDURE
      pop_window_stack;
 
VAR
      nr_screens : integer;
      i          : integer;
 
BEGIN
WITH i01g^.i50.stack DO
    i01g^.ls.nr_screens := stack [level] .screen_nr;
(*ENDWITH*) 
FOR i := i01g^.ls.nr_screens DOWNTO 1 DO
    BEGIN
    WITH i01g^.i50.stack,stack [level ] DO
        BEGIN
        i01g^.ls.description [i]  := description;
        i01g^.i50.defined_part := defined_part;
        i01g^.i50.with_windowframe := with_windowframe;
        END;
    (*ENDWITH*) 
    WITH i01g^.i50.stack DO
        level := level - 1;
    (*ENDWITH*) 
    END;
(*ENDFOR*) 
END; (* pop_window_stack *)
 
(*------------------------------*) 
 
PROCEDURE
      get_layout_parameters (
            VAR functionmenu_length : tin_natural;
            VAR inputarea_length    : tin_natural;
            VAR msglines            : tin_natural);
 
VAR
      width : tin_natural;
 
BEGIN
i51size(cin_ls_functionmenu,functionmenu_length,width);
i51size(cin_ls_inputarea,inputarea_length,width);
i51size(cin_ls_sysline,msglines,width);
END; (* get_layout_paramet *)
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
