{	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.
