!TITLE Screen Control Procedures
! 
! The  following  Sections  describe  the procedures available to a user
! program.  These procedures return information about how to  drive  the
! type  of  terminal  currently  in  use.   In the case of phone and PSS
! connections, the TERMINALTYPE command must be used at  some  point  to
! set this up.
!
!<VDUI
!
! %externalintegerfunctionspec vdui(%integer n)
!
! This  function  returns  various  integer   characteristics   of   the
! terminal. A result of zero is usually an error.
!
!     n = 1   Terminal type
!     n = 2   Columns per line
!     n = 3   Lines per page (zero for hard copy)
!     n = 4   ASCII code for recommended interrupt character
!     n = 5   Base character for X position
!     n = 6   Base character for Y position
!>
!<VDUB
!
! This function returns various boolean characteristics of the terminal.
! A  result  of  zero  indicates  'no'  or  'false',  and  a result of 1
! indicates 'yes' or 'true'.  A result of -1 indicates an error.
!
! %externalintegerfunctionspec vdub(%integer n)
!
!     n = 1    Home moves cursor to top line
!     n = 2    Terminal can operate in page mode
!     n = 3    Y coordinate comes first
!     n = 4    Terminal auto wraps at line end
!>
!<VDUC

! This  function  returns  a string which, if sent to the terminal, will
! move the cursor to specified coordinates. A null result indicates that
! the terminal is incapable of controlled cursor positioning.
!
! %externalstringfunctionspec vduc(%integer x,y)
!
! The values 'x' and 'y' have an origin of zero (e.g. top left is 0,0).
!>
!<VDUS
!
! %externalstringfunctionspec vdus(%integer n)
!
! This function returns a string.  Sometimes this is a name, but usually
! it  is a value which must be 'printch'd to achieve a particular effect
! on the terminal. A null result indicates that  the  operation  is  not
! supported by that terminal.
!
!     n = 0   Terminal name
!     n = 1   Clear screen (cursor moved to home)
!     n = 2   Cursor home
!     n = 3   Clear to end of line
!     n = 4   Clear to end of screen
!     n = 5   Initialise terminal
!     n = 6   Cursor up
!     n = 7   Cursor down
!     n = 8   Cursor left
!     n = 9   Cursor right
!     n = 10  Insert line
!     n = 11  Delete line
!     n = 12  Set terminal into page mode
!     n = 13  Set terminal into roll mode
!     n = 14  String to append to start of cursor X movement
!     n = 15  String to append to start of cursor Y movement
!     n = 16  Two character Unix name for terminal type
!     n = 17  Start standout mode
!     n = 18  End standout mode
!     n = 19  Raw cursor positioning string
!>
!<PRINTCHS
!KEY
!
! %externalroutinespec printchs(%string(255) s)
!
! If the length of 's' is > 0, this routine effectively calls  'printch'
! for  each  character  of the string. If the length of 's' is zero, the
! routine has no effect.
!>
!STOP
!***********************************************************************
!*
!*                        Screen control package
!*
!*              R.D. Eager  University of Kent   MCMLXXXIV
!*
!***********************************************************************
!
!
!***********************************************************************
!*
!*          Constants
!*
!***********************************************************************
!
constantinteger  no = 0, yes = 1
constantinteger  not set = -100
constantinteger  nterms = 31;           ! Max number of terminal types
constantinteger  max space = 224;       ! Space in terminal record
!
!
!***********************************************************************
!*
!*          Record and array formats
!*
!***********************************************************************
!
recordformat  descf(integer  dr0,dr1 or  c 
                    longinteger  dr)
recordformat  termf(byteinteger  type,name,columns,lines,leadin,
                    clearscreen,home,endofline,endofscreen,init,int,
                    cursor up,cursor down,cursor left,cursor right,
                    insert line,delete line,home at top,page mode,
                    roll mode,can do page mode,xbase,ybase,xintro,
                    yintro,yfirst,auto wrap,uname,start standout,
                    end standout,cursor pos,
                    (byteinteger  string ptr or  c 
                    string (max space) string space))
!
!
!***********************************************************************
!*
!*          External references to TERMTYPE package
!*
!***********************************************************************
!
externalroutinespec  get terminal type(integer  n)
!
externalintegerspec  curtype;           ! Terminal type as a number
externalrecord (termf)spec  term;       ! Record for 'curtype'
!
!
!***********************************************************************
!*
!*          Subsystem references
!*
!***********************************************************************
!
systemintegerfunctionspec  iocp(integer  ep,parm)
systemstringfunctionspec  itos(integer  n)
!
!
!***********************************************************************
!*
!*          T E R M   S T R I N G
!*
!***********************************************************************
!
externalstringfunction  term string(record (termf)name  term,
                                    byteintegername  ptr)
! Returns  the string associated with the item described by 'ptr' in the
! record 'term'.
result  = "" if  ptr = 0
result  = string(addr(term_string space)+ptr)
end ;   ! of term string
!
!
!***********************************************************************
!*
!*          V D U I
!*
!***********************************************************************
!
externalintegerfunction  vdui(integer  n)
constantinteger  maxvdui = 6
switch  sw(1:maxvdui)
!
result  = 0 unless  0 < n <= maxvdui
!
get terminal type(no) if  curtype = not set
result  = 0 unless  1 <= curtype <= nterms
   !
   -> sw(n)
   !
sw(1):                                  ! Terminal type
   result  = curtype
   !
sw(2):                                  ! Columns per line
   result  = term_columns
   !
sw(3):                                  ! Lines per page
   result  = term_lines
   !
sw(4):                                  ! Interrupt character
   result  = term_int
   !
sw(5):                                  ! Base for X position
   result  = term_xbase
   !
sw(6):                                  ! Base for Y position
   result  = term_ybase
end ;   ! of vdui
!
!
!***********************************************************************
!*
!*          V D U B
!*
!***********************************************************************
!
externalintegerfunction  vdub(integer  n)
constantinteger  maxvdub = 4
switch  sw(1:maxvdub)
!
result  = -1 unless  0 < n <= maxvdub
!
get terminal type(no) if  curtype = not set
result  = -1 unless  1 <= curtype <= nterms
   !
   -> sw(n)
   !
sw(1):                                  ! Home at top
   result  = term_home at top
   !
sw(2):                                  ! Terminal can operate in page mode
   result  = term_can do page mode
   !
sw(3):                                  ! Y coordinate comes first
   result  = term_yfirst
   !
sw(4):                                  ! Terminal auto wraps at line end
   result  = term_auto wrap
end ;   ! of vdub
!
!
!***********************************************************************
!*
!*          V D U S
!*
!***********************************************************************
!
externalstringfunction  vdus(integer  n)
constantinteger  maxvdus = 19
byteinteger  key
switch  sw(0:maxvdus)
!
result  = "" unless  0 <= n <= maxvdus
!
get terminal type(no) if  curtype = not set
result  = "" unless  1 <= curtype <= nterms
   !
   -> sw(n)
   !
sw(0):                                  ! Terminal name
   key = term_name
   -> get
   !
sw(1):                                  ! Clear screen
   key = term_clearscreen
   -> get
   !
sw(2):                                  ! Home
   key = term_home
   -> get
   !
sw(3):                                  ! End of line
   key = term_endofline
   -> get
   !
sw(4):                                  ! End of screen
   key = term_endofscreen
   -> get
   !
sw(5):                                  ! Initialisation string
   key = term_init
   -> get
   !
sw(6):                                  ! Cursor up
   key = term_cursor up
   -> get
   !
sw(7):                                  ! Cursor down
   key = term_cursor down
   -> get
   !
sw(8):                                  ! Cursor left
   key = term_cursor left
   -> get
   !
sw(9):                                  ! Cursor right
   key = term_cursor right
   -> get
   !
sw(10):                                 ! Insert line
   key = term_insert line
   -> get
   !
sw(11):                                 ! Delete line
   key = term_delete line
   -> get
   !
sw(12):                                 ! Set page mode
   key = term_page mode
   -> get
   !
sw(13):                                 ! Set roll mode
   key = term_roll mode
   -> get
   !
sw(14):                                 ! String for start of cursor X movement
   key = term_xintro
   -> get
   !
sw(15):                                 ! String for start of cursor Y movement
   key = term_yintro
   -> get
   !
sw(16):                                 ! Unix name for terminal
   key = term_uname
   -> get
   !
sw(17):                                 ! String to start standout mode
   key = term_start standout
   -> get
   !
sw(18):                                 ! String to end standout mode
   key = term_end standout
   -> get
   !
sw(19):                                 ! Raw cursor positioning
   key = term_cursor pos
   -> get
   !
get:
   result  = term string(term,key)
end ;   ! of vdus
!
!
!***********************************************************************
!*
!*          V D U C
!*
!***********************************************************************
!
externalstringfunction  vduc(integer  y,x)
! Note  that  the formal parameters 'x' and 'y' are inverted because the
! cursor positioning string is 'back to front'. This is so that the same
! string is used as that on a UNIX system (for convenience).
integer  i,temp,c,max,next
string (255) res,s,work
!
get terminal type(no) if  curtype = not set
!
s = term string(term,term_cursor pos)
result  = "" if  s = "";                ! Cannot do cursor positioning
!
res = ""
next = x
max = length(s)
!
for  i = 1,1,max cycle 
   c = charno(s,i)
   !
   if  c # '%' or  i = max then  start 
      res = res.tostring(c)
   else 
      i = i + 1;                        ! Move to next character
      c = charno(s,i);                  ! Flag character
      if  'A' <= c <= 'Z' then  c = c - 'A' + 'a'
      if  c = '%' then  start 
         res = res."%"
      finish  else  c 
      if  c = 'd' then  start 
         res = res.itos(next)
         next = y
      finish  else  c 
      if  c = '2' or  c = '3' then  start 
         work = itos(next)
         work = "0".work while  length(work) < c - '0'
         res = res.work
         next = y
      finish  else  c 
      if  c = '.' then  start 
         res = res.tostring(next)
         next = y
      finish  else  c 
      if  c = 'r' then  start 
         temp = x
         x = y
         next = y
         y = temp
      finish  else  c 
      if  c = 'i' then  start 
         next = next + 1
         y = y + 1
      finish  else  c 
      if  c = '+' then  start 
         i = i + 1
         if  i <= max then  c = charno(s,i) else  c = 0
         res = res.tostring(next+c)
         next = y
      finish 
   finish 
repeat 
!
result  = res
end ;   ! of vduc
!
!
!***********************************************************************
!*
!*          P R I N T C H S
!*
!***********************************************************************
!
externalroutine  printchs(string (255) s)
integer  res
record (descf) desc
!
desc_dr0 = length(s)
return  if  desc_dr0 = 0
desc_dr1 = addr(s) + 1
res = iocp(19,addr(desc))
end ;   ! of printchs
endoffile