!TITLE The TERMINALTYPE command
!
! This  command  is  used to discover the current terminal type.  It may
! also be used to set a terminal type if a phone or  PSS  connection  is
! being used.
!
!        TERMINALTYPE    prompts the user for the value to be set
!        TERMINALTYPE(?) gives the user's terminal type
!>
!STOP
!***********************************************************************
!*
!*            Routines to determine type of terminal in use
!*
!*                      University of Kent version
!*
!*              R.D. Eager  University of Kent   MCMLXXXIV
!*
!***********************************************************************
!
!
!***********************************************************************
!*
!*          Constants
!*
!***********************************************************************
!
constantinteger  no = 0, yes = 1
constantinteger  external = -1;         ! Terminal type for phone/PSS lines
constantinteger  not set = -100
constantinteger  unspecified video = 4
constantinteger  nterms = 31;           ! Max number of terminal types
constantinteger  max space = 224;       ! Space in terminal record
constantstring (1) snl = "
"
constantstring (18) chsfile = "SUBSYS.TERMCHSFILE"
                                        ! Terminal characteristics file
constantstring (18) termlocsfile = "SUBSYS.TERMLOCFILE"
                                        ! Terminal locations file
!
!
!***********************************************************************
!*
!*          Record and array formats
!*
!***********************************************************************
!
recordformat  hf(integer  dataend,datastart,filesize,filetype,sum,
                 datetime,format,mark,ntcps,tcpsoffset,nttys,
                 ttysoffset,nlocns,locnsoffset,sp0,sp1)
recordformat  rf(integer  conad,filetype,datastart,dataend)
!
recordformat  tcpf(string (15) name,string (31) location,
                   integer  maxline,linestart)
recordformat  ttyf(string (15) loclp,integer  type,string (31) building,
                   location)
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))
!
ownrecord (termf)arrayformat  termaf(1:4095)
!
!
!***********************************************************************
!*
!*          Own variables
!*
!***********************************************************************
!
externalinteger  curtype = not set;     ! Terminal type as a number
externalrecord (termf) term;            ! Record for 'curtype'
ownrecord (termf)arrayname  terms
!
!
!***********************************************************************
!*
!*          External references to screen control package
!*
!***********************************************************************
!
externalstringfunctionspec  term string(record (termf)name  term,
                                        byteintegername  ptr)
externalintegerfunctionspec  vdub(integer  n)
!
!
!***********************************************************************
!*
!*          Subsystem references
!*
!***********************************************************************
!
systemroutinespec  connect(string (31) file,integer  mode,hole,
                           prot,record (rf)name  r,integername  flag)
systemroutinespec  disconnect(string (31) file,integername  flag)
systemstringfunctionspec  failuremessage(integer  mess)
systemstringfunctionspec  itos(integer  n)
systemintegerfunctionspec  pstoi(string (63) s)
externalroutinespec  prompt(string (255) s)
systemintegerfunctionspec  querymode(integer  n)
systemroutinespec  setfname(string (63) s)
externalroutinespec  set return code(integer  i)
systemroutinespec  setuse(string (31) file,integer  mode,value)
systemroutinespec  uctranslate(integer  ad,len)
externalintegerfunctionspec  uinfi(integer  entry)
externalstringfunctionspec  uinfs(integer  entry)
!
externalroutinespec  option(string (255) s)
externalroutinespec  setmode(string (255) s)
!
!
!***********************************************************************
!*
!*          Service routines
!*
!***********************************************************************
!
routine  readline(stringname  s)
! Reads one line from the currently selected input  into  's'.   Leading
! and trailing spaces, and completely blank lines, are suppressed.
integer  c
!
s = ""
cycle 
   cycle 
      readsymbol(c)
      exit  if  c = nl
      s <- s.tostring(c)
   repeat 
   while  length(s) > 0 and  charno(s,length(s)) = ' ' cycle 
      length(s) = length(s) - 1
   repeat 
   while  length(s) # 0 and  charno(s,1) = ' ' cycle 
      s = substring(s,2,length(s))
   repeat 
   exit  unless  s = ""
repeat 
end ;   ! of readline
!
!-----------------------------------------------------------------------
!
routine  do setmode(integer  cols,lines)
! Checks  whether the terminal is correctly set up (PAD-wise) for number
! of columns (as given by 'cols') and video mode (as given by a  nonzero
! value  for  'lines').  If necessary, 'setmode' is called to update the
! settings.
integer  i
string (31) s
!
i = query mode(3);                      ! Get PAD setting for width
if  cols # i # -1 then  start ;         ! Setting obtained, but incorrect
   if  i # 0 then  s = "W=".itos(cols)."," else  s = ""
                                        ! Leave alone if wrap turned off
finish  else  s = ""
!
i = query mode(15);                     ! Get PAD setting for video mode
if  i > 0 and  lines = 0 then  start ;  ! Setting obtained, but incorrect
   s = s."V=OFF"
finish  else  c 
if  i = 0 and  lines # 0 then  start ;  ! Setting obtained, but incorrect
   s = s."V=ON"
finish 
!
setmode(s) if  s # ""
end ;   ! of do setmode
!
!-----------------------------------------------------------------------
!
routine  set terminal type(integer  n,ask)
integer  cols,lines,ch
string (255) s
!
curtype = n
if  n = 0 then  start 
   term = 0
   term_columns = 72
   cols = 72
   lines = 0
   s = "unspecified"
else 
   term = terms(n)
   cols = term_columns
   lines = term_lines
   s = term string(term,term_name)
finish 
!
printstring("Your terminal type is """.s."""".snl)
!
if  ask = yes then  start 
   printstring("Use this in future remote logons?".snl)
   prompt("Yes or no: ")
finish 
!
cycle 
   if  ask = yes then  readline(s) else  s = "N"
   uctranslate(addr(s)+1,length(s))
   ch = charno(s,1)
   continue  unless  ch = 'N' or  ch = 'Y'
   if  ch = 'Y' then  start 
      s = "TERMINAL=".itos(n).","
   finish  else  s = ""
   cols = cols - 1 if  n # 0 and  vdub(4) = yes
                                        ! Allow for any auto wrap at line end
   if  cols # uinfi(15) then  start 
      s = s."ITWIDTH=".itos(cols)
   finish 
   do setmode(cols, lines)
   if  s # "" then  option(s)
   exit 
repeat 
end ;   ! of set terminal type
!
!
!***********************************************************************
!*
!*          G E T   T E R M I N A L   T Y P E
!*
!***********************************************************************
!
externalroutine  get terminal type(integer  silent)
! Discovers  the  type  of  the  terminal  in use, and sets up 'curtype'
! accordingly.  If 'silent'  is  'yes',  the  user  is  given  no  error
! messages, and is not interrogated about PSS and phone lines.
integer  flag,lineno,i,tcpsad,tcpsize,ttysad,ttysize,ntcps,nttys,cols
string (31) s,tcpname,work
record (rf) rr
record (hf)name  h
record (tcpf)name  tcp
record (ttyf)name  tty
!
connect(chsfile,1,0,0,rr,flag)
-> err if  flag # 0
setuse(chsfile,1,0);                    ! Prevent disconnection
terms == array(rr_conad+rr_datastart,termaf)
!
tcpsize = sizeof(tcp)
ttysize = sizeof(tty)
!
connect(termlocsfile,1,0,0,rr,flag)
-> err if  flag # 0
!
h == record(rr_conad)
ntcps = h_ntcps
nttys = h_nttys
tcpsad = rr_conad + h_tcpsoffset
ttysad = rr_conad + h_ttysoffset
!
s = uinfs(14);                          ! Terminal address
uctranslate(addr(s)+1,length(s))
-> bad unless  s -> tcpname.(":").work.(":").s.(":")
lineno = pstoi(s)
!
flag = no
for  i = 1,1,ntcps cycle 
   tcp == record(tcpsad)
   if  tcpname = tcp_name then  start 
      flag = yes
      exit 
   finish 
   tcpsad = tcpsad + tcpsize
repeat 
-> bad if  flag = no;                   ! PAD name not found
-> bad unless  0 <= lineno <= tcp_maxline
!
tty == record(ttysad+(tcp_linestart+lineno)*ttysize)
curtype = tty_type
-> bad if  curtype = 0
!
! Handle phone and PSS lines
!
if  curtype = external then  start 
   curtype = uinfi(23);                 ! Get setting from options file
   if  curtype = 0 then  start 
      if  silent = yes then  start 
         curtype = external
         return 
      finish 
      printstring("You appear to be logged in via a telephone line or a PSS connection.  It".snl)
      printstring("is  thus  not  possible to determine the type of terminal you are using.".snl)
      printstring("Please use the command TERMINALTYPE to set up your terminal type.   This".snl)
      printstring("will be remembered for future remote logons if you wish.".snl)
      return 
   finish 
finish 
!
! Set up terminal record for future use
!
set:
term = terms(curtype)
-> bad unless  term_name # 0
!
cols = term_columns
cols = cols - 1 if  vdub(4) = yes;      ! Allow for any auto wrap at line end
!
if  cols # uinfi(15) then  start ;      ! ITWIDTH setting needs alteration
   option("ITWIDTH=".itos(cols))
finish 
do setmode(cols,term_lines)
disconnect(termlocsfile,flag);          ! Will not be needed again
return 
!
bad:
flag = 233;                             ! General error
setfname("Terminal name not known")
!
err:
if  silent = no then  start 
   printstring("Error -".failuremessage(flag))
   printstring("Unspecified video assumed".snl)
finish 
curtype = unspecified video
-> set
end ;   ! of get terminal type
!
!
!***********************************************************************
!*
!*          T E R M I N A L T Y P E
!*
!***********************************************************************
!
externalroutine  terminaltype(string (255) parms)
integer  i,list,ask
string (72) line,s
record (termf)name  t
!
get terminal type(yes) if  curtype = not set
!
if  parms = "?" then  start 
   if  1 <= curtype <= nterms then  start 
      printstring(term string(term,term_name))
   else 
      printstring("Unknown")
      if  curtype = external then  start 
         printstring(" (phone or PSS)")
         curtype = 0
      finish 
   finish 
   newline
else 
   ask = no
   list = 8
   cycle 
      i = pstoi(parms)
      exit  if  (1 <= i <= nterms and  terms(i)_name # 0) or  i = 0
      if  list > 7 then  start 
         list = 0
         printstring("Terminals supported are:".snl)
         line = " 0 unspecified"
         for  i = 1,1,nterms cycle 
            t == terms(i)
            if  t_name # 0 then  start 
               s = itos(i)
               s = " ".s if  i < 10
               s = s." ".term string(t,t_name)
               if  line = "" then  line = s else  start 
                  line = line."                                "
                  length(line) = 36
                  printstring(line.s.snl)
                  line = ""
               finish 
            finish 
         repeat 
         printstring(line.snl) unless  line = ""
         printstring(c 
          "Please type the number of your terminal and press 'return'")
         newline
         prompt("Terminal: ")
      finish 
      list = list + 1
      ask = yes
      readline(parms)
   repeat 
   set terminal type(i,ask)
finish 
!
set return code(0)
end ;   ! of terminaltype
endoffile