{       operations for input/output of data from the terminal.
       Randall Venhola         5-May-1987 }

[environment('screenhandlers')] MODULE screenhandlers;


TYPE
   wordinteger = [WORD] 0..65535;
   byterange = [BYTE] 0..255;



VAR
terminalerror : [HIDDEN,STATIC] integer := 0;
cursorrow     : [HIDDEN,STATIC] wordinteger := 1;
cursorcolumn  : [HIDDEN,STATIC] wordinteger := 1;



[GLOBAL] PROCEDURE clearsubscreen( line, column : integer );

  FUNCTION LIB$ERASE_PAGE(lineno, colno : wordinteger) : integer; extern;

  VAR
    l, c : wordinteger;

BEGIN
 l := line;
 c := column;
 terminalerror := lib$erase_page(l,c);
END;




[GLOBAL] PROCEDURE clearscreen;

BEGIN
  clearsubscreen(1,1);
END;




[GLOBAL] PROCEDURE positioncursor( line, column : integer );

  FUNCTION LIB$SET_CURSOR( lineno, colno : wordinteger ) : integer; extern;

  VAR
    l, c : wordinteger;

BEGIN
  l := line;
  c := column;
  terminalerror := lib$set_cursor(l,c);
  cursorrow := line;
  cursorcolumn := column
END;


[GLOBAL] PROCEDURE rollttyforward;
BEGIN
  positioncursor(cursorrow+1, cursorcolumn)
END;


[GLOBAL] PROCEDURE rollttyback;
BEGIN
  if cursorrow > 1 then
     positioncursor(cursorrow-1, cursorcolumn)
END;


[GLOBAL] PROCEDURE putstringtoterminal( string : VARYING [limit] of CHAR;
                                          line, column : integer;
                                          reversevideo : boolean;
                                          blinking : boolean);
CONST
 maxscreenwidth = 132;

VAR
 l, c, flags, newcolumn : wordinteger;

 FUNCTION LIB$PUT_SCREEN(outtext : VARYING [C] OF CHAR;
                         lineno : wordinteger; colno : wordinteger;
                         flags : wordinteger) : integer; extern;


BEGIN
   l := line;
   c := column;
   if reversevideo then
     if blinking then
         flags := 3
     else
         flags := 2
   else
     flags := 0;
   terminalerror := lib$put_screen(string, l, c, flags);
   newcolumn :=  1 + length(string) + cursorcolumn;
   if newcolumn > maxscreenwidth then
      positioncursor(cursorrow + 1, 1)
   else
      positioncursor( cursorrow, newcolumn)
END;


[GLOBAL] PROCEDURE ttywriteln;
const
 carriagereturn = 13;
 linefeed = 10;

var
  endofline : [STATIC] VARYING[2] of char;
BEGIN
 endofline.body[1] := chr(carriagereturn);
 endofline.body[2] := chr(linefeed);
 endofline.length  := 2;
 putstringtoterminal(endofline, cursorrow, cursorcolumn, false, false);
 positioncursor(cursorrow + 1, 1)
END;




[GLOBAL] PROCEDURE ttyreadln( VAR string : VARYING [limit] of char );

  FUNCTION LIB$GET_SCREEN(VAR inputtext : VARYING [lim1] OF CHAR;
  promptstring : VARYING [lim2] OF CHAR; VAR outlen : wordinteger := %IMMED 0) : integer; extern;

  VAR
    len : wordinteger;
    prompt : [STATIC] VARYING [2] OF CHAR := '>';

BEGIN
  terminalerror := lib$get_screen(string, prompt, len);
  ttywriteln
END;



[GLOBAL] PROCEDURE findcursor( var line, column : integer );

BEGIN
  line := cursorrow;
  column := cursorcolumn;
END;



[GLOBAL] FUNCTION terminalerrorcode : integer;

BEGIN
  terminalerrorcode := terminalerror;
END;




[GLOBAL] PROCEDURE ttywritestring( string : VARYING [limit] OF CHAR);

BEGIN
  putstringtoterminal(string, cursorrow, cursorcolumn, false, false);
END;


[GLOBAL] PROCEDURE ttywriteint( int : integer );
const
  maxintchars = 20;
var
 s : varying[maxintchars] of char;
BEGIN
 writev(s, int:1);
 ttywritestring( s )
END;


[GLOBAL] PROCEDURE ttywritereal( floating : real; fieldwidth,
                                                   ndigits : integer);
const
 maxfieldwidth = 30;
var
s : varying[maxfieldwidth] of char;
BEGIN
  writev(s, floating:fieldwidth:ndigits);
  ttywritestring( s )
END;

END.