From 40e5a5811c6ffce9b0974e93cdd927cbcf60c157 Mon Sep 17 00:00:00 2001
From: Joe Hunkeler <jhunkeler@gmail.com>
Date: Tue, 11 Aug 2015 16:51:37 -0400
Subject: Repatch (from linux) of OSX IRAF

---
 sys/tty/doc/tty.hlp | 485 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 485 insertions(+)
 create mode 100644 sys/tty/doc/tty.hlp

(limited to 'sys/tty/doc/tty.hlp')

diff --git a/sys/tty/doc/tty.hlp b/sys/tty/doc/tty.hlp
new file mode 100644
index 00000000..62924590
--- /dev/null
+++ b/sys/tty/doc/tty.hlp
@@ -0,0 +1,485 @@
+.help tty Dec83 "Terminal Control Interface"
+.nh
+Introduction
+
+    The TTY interface is a table driven, device independent interface for
+controlling terminal and printer devices.  Devices are described either by
+environment definitions, or by an entry in the TTY database file.  The TTY
+database file is the standard Berkeley UNIX termcap terminal capability
+database file (a text file), to which we have added entries for our printer
+devices.  Accessing the UNIX termcap file directly without modification
+is sometimes awkward, but the benefits of accessing a widely used, standard
+database more than compensate for any clumsiness.
+
+When the CL starts up, the following environment variables are defined to
+describe the default terminal and printer devices.  The user may subsequently
+change the values of these variables with the SET statement or with the STTY
+program.
+
+
+.ks
+.nf
+	printer		default printer (i.e., "versatec")
+	terminal	default terminal (i.e., "vt100", "tek4012")
+	termcap		terminal/printer database filename
+	ttybaud		baud rate, default 9600
+	ttyncols	number of characters per line
+	ttynlines	number of lines per screen
+.fi
+.ke
+
+
+The variables defining the names of the default terminal and printer
+devices will normally correspond to the names of device entries in the
+termcap file.  The name of a file containing a single termcap entry
+for the device may optionally be given; the file name must contain a
+VFN or OSFN directory prefix to be recognized as a filename.  The default
+termcap file is dev$termcap.  Terminal initialization files (used to
+set tabstops) are files of the form dev$tty.tbi, where "tty" is the last
+field of the UNIX pathname in the "if" termcap entry.  If the first
+character of the "if" filename string is not a /, an IRAF VFN should
+be given.
+
+The value strings for the environment variables TTYNCOLS and TTYNLINES,
+defining the screen dimensions, are extracted from the termcap file by the
+STTY program during startup.  The screen dimensions are defined in the
+environment for two reasons: (1) efficiency (the TTY package is not needed
+to learn the screen dimensions), and (2) if a window is used, the logical
+screen dimensions may be less than the physical screen dimensions.
+Most applications programs should therefore use ENVGETI rather than TTYGETI
+to get the screen dimensions.  TTYGETI returns the physical screen dimensions
+as given in the termcap file.
+
+.nh
+Library Procedures
+
+    Before any TTY control sequences can be output, the TTY device descriptor
+must be read from the termcap file into a buffer for efficient access.
+TYODES is used to "open" the TTY descriptor; TTYCDES should be called when
+done to close the descriptor, returning all buffer space used.  If "ttyname"
+is "terminal" or "printer", the descriptor for the default terminal or printer
+is accessed.
+
+
+.ks
+.nf
+Open/Close descriptor:
+
+	tty =	ttyodes (ttyname)		# pointer ttyodes()
+		ttycdes (tty)
+.fi
+.ke
+
+
+.ks
+.nf
+Low level database access, tty control:
+
+	  int = ttygeti (tty, cap)
+	 real = ttygetr (tty, cap)
+	 bool = ttygetb (tty, cap)
+       nchars = ttygets (tty, cap, outstr, maxch)
+		ttyputs (fd, tty, ctrlstr, afflncnt)
+		ttysubi (ctrlstr, outstr, maxch, arg1, arg2)
+.fi
+.ke
+
+
+.ks
+.nf
+High level control
+
+       OK|ERR = ttyctrl (fd, tty, cap, afflncnt)
+
+		  ttyso (fd, tty, YES|NO)	# turn standout mode on|off
+		ttygoto (fd, tty, col, line)	# move cursor absolute
+NI		ttyhorz (fd, tty, from, to)	# move cursor on line
+NI		ttyvert (fd, tty, from, to)	# move cursor on column
+		ttyinit (fd, tty)		# send :is & :if, if defined
+	       ttyclear (fd, tty)		# clear screen
+	     ttyclearln (fd, tty)		# clear the current line
+	     ttyputline (fd, tty, textline, map_cc)	# put text line
+.fi
+.ke
+
+
+The TTYGET procedures are used to get capabilities from the database entry.
+If the named capability is not found, TTYGETI returns zero, TTYGETB returns
+false, and TTYGETS returns the null string.  TTYSUBI performs argument
+substitution on a control sequence containing at most two integer arguments
+(such as a cursor motion control sequence), generating an output sequence
+suitable for input to TTYPUTS.  TTYPUTS puts the control sequence to the
+output file, padding as required given the number of affected lines.
+The baud rate and pad character, used to generate padding, are evaluated at
+TTYODES time and are conveyed to TTYPUTS in the tty descriptor.
+
+TTYSO turns standout mode on or off.
+TTYCNTRL calls TTYGETS and TTYPUTS to process and output a control sequence
+(slightly less efficiently than if the control string is buffered by
+the user code).  TTYGOTO moves the cursor to the
+desired column and line.  TTYHORZ and TTYVERT move the cursor on a line
+or column, using knowledge of the terminal's capabilities to generate the
+most efficient sequence.
+
+TTYPUTLINE is like the FIO PUTLINE, except that it processes any form feeds,
+standout mode directives, and other control characters (including tabs)
+embedded in the text.  Lines longer than TTYNCOLS are broken into several
+output lines.  TTYPUTLINE is used by the help, page, type, and lprint utilities 
+to map tabs and standout mode directives for a particular output device.
+Standout mode is mapped as reverse video on most VDT's, and as underscore
+on most printers and on overstrike terminals such as the tek4012.
+
+.nh
+Implementation Notes
+
+    Of the low level routines, only TTYODES and TTYSUBI are at all complex.
+The high level routines can be fairly complex due to the logic required to
+perform a function on devices which may vary greatly in capabilities.
+
+.nh 2
+Structure
+
+.ks
+.nf
+open descriptor:
+
+	ttyodes
+	    envget[si]
+	    calloc			[alloc tty descriptor]
+	    open,close,seek		[read termcap file]
+	    tty_fetch_entry		[fetch entry from file]
+		getline,getc
+		realloc
+	    realloc
+	    tty_index_caplist		[encode, sort caplist]
+	    ttygeti			[set padchar]
+.fi
+.ke
+
+
+.ks
+.nf
+close descriptor:
+
+	ttycdes
+	    ttyctrl			[sometimes needed]
+	    mfree			[free tty descriptor]
+.fi
+.ke
+
+
+.ks
+.nf
+get integer capability:
+
+	ttygeti
+	    tty_find_capability		[binary search of caplist]
+	    ctoi
+.fi
+.ke
+
+
+.ks
+.nf
+get string capability:
+
+	ttygets
+	    tty_find_capability		[binary search caplist]
+	    tty_map_escapes		[get control string]
+.fi
+.ke
+
+
+.ks
+.nf
+perform argument substitution on control string:
+
+	ttysubi
+	    gltoc
+.fi
+.ke
+
+
+.ks
+.nf
+output control string:
+	ttyputs
+	    putc
+.fi
+.ke
+
+.nh 2
+Data Structures
+
+    The tty descriptor contains several parameters describing the most basic
+features of the device, the raw termcap entry, an encoded index into the
+termcap entry used to speed up searches, and any status variables for the
+device.  Since a fixed length array is used to index capabilities, there is
+an upper limit on the number of capabilities, but there is no limit on the
+length of a termcap entry.
+
+
+.ks
+.nf
+	struct tty_descriptor {
+		int	t_len		# length of descriptor
+		int	t_op		# offset into caplist
+		int	t_padchar	# pad character
+		int	t_baud		# baud rate, bits/sec
+		int	t_nlines	# lines per screen
+		int	t_ncols		# chars per line
+		int	t_ncaps		# number of capabilities
+		int	t_capcode	# sorted, encoded caplist
+		int	t_capindex	# indices of cap strings
+		char	caplist[ARB]	# termcap entry
+	}
+.fi
+.ke
+
+
+TTYODES "opens" the tty descriptor, i.e., allocates a descriptor,
+scans the termcap file and reads the terminal entry into the descriptor,
+expanding any tc references, and then sets the baud and padchar fields.
+There is no limit on the size of a termcap entry, unlike the UNIX
+implementation which uses a fixed size, 1024 character caplist buffer.
+
+
+.tp 10
+.nf
+procedure ttyodes (ttyname)
+
+begin
+	# Get device name or file name.
+	if (ttyname equals "terminal")
+	    ttysource = fetch environment variable "terminal"
+	else if (ttyname equals "printer")
+	    ttysource = fetch environment variable "printer"
+	else
+	    ttysource = ttyname
+
+	# Get device name AND file name.
+	if (ttysource is a filename) {
+	    file = ttysource
+	    entry = "" (first entry)
+	} else {
+	    file = fetch termcap filename from environment
+	    entry = ttysource
+	}
+
+	allocate tty descriptor structure "tty"
+	tty.len = default length of descriptor
+	tty.op = pointer to first char of caplist string
+
+	# Fetch termcap entry into tty descriptor, expanding any "tc"
+	# references to other records by rescanning the file.
+
+	fd = open (termcap file)
+	repeat {
+	    tty_fetch_entry (fd, entry, tty)
+	    if (last field of entry is a "tc") {
+		entry = value of "tc" field
+		set tty.op to overwrite tc field
+		rewind (fd)
+	    } else
+		break
+	} 
+	close (fd)
+
+	# Get pad character and baud rate and store explicitly in the
+	# descriptor, since these values are used in every TTYPUTS call.
+
+	call realloc to return unused space in tty descriptor
+	call tty_index_caplist to index the caplist for efficient
+	    searches
+	tty.baud = fetch "baud" from environment
+	tty.padchar = ttygeti (tty, "pc")
+
+	return (tty)
+end
+.fi
+
+
+Scan the termcap file until the desired entry is found.  Copy the entry
+into the caplist field of the tty descriptor.  If the caplist buffer
+overflows, reallocate a larger buffer.
+
+.nf
+procedure tty_fetch_entry (fd, entry, tty)
+
+begin
+	# Locate entry.
+	repeat {
+	    advance to next record
+	    if (at eof)
+		error: termcap entry not found
+	} until (positioned to the entry we are looking for)
+
+	# Fetch entry.
+	while (getc (fd, ch) != EOF) {
+	    if (ch equals \ and next ch is newline) {
+		throw both out
+	    } else if (ch equals newline) {
+		deposit EOS
+		return
+	    } else
+		deposit ch
+
+	    bump output pointer
+	    if (buffer is full)
+		allocate more space
+	}
+
+	error: EOF encountered while reading termcap entry
+end
+.fi
+
+
+Prepare the caplist index.  Each two-character capability name maps into
+an unique integer code.  We prepare an list of capcodes and an associated
+list of indices into the caplist, then sort the capcode list.  At runtime
+we will perform a binary search of the capcode list to find the desired
+capcode.
+
+.nf
+procedure tty_index_caplist (caplist, capcode_list, capindex_list)
+
+begin
+	for (each entry in caplist) {
+	    compute capcode
+	    if (capcode is not already in capcode_list) {
+		bump list pointer
+		if (list overflows)
+		    error: too many capabilities in termcap entry
+
+		# Termcap flags capabilities that are not available 
+		# with the char '@'.
+		if (first char of entry is '@')
+		    index = 0
+		save capcode, index in lists
+	    }
+	}
+
+	if (two or more elements in list)
+	    sort list
+end
+.fi
+
+
+Process a capability string containing arguments.  Examples of such capability
+strings are cursor motion to [x,y], and set scrolling region to [l1,l2].
+Note that arguments in the termcap database are zero-indexed by default,
+while the TTYSUBI arguments are one-indexed.  The control string given as
+input has already been processed to reduce all escape sequences to single
+characters.
+
+.nf
+procedure ttysubi (ctrlstr, outstr, maxch, arg1, arg2)
+
+ctrlstr:	device control string
+outstr:		receives processed string
+arg1,arg2:	on input, the arguments to be expanded in the control
+		    string.  on output, the difference between the
+		    input arg values and the values actually used
+		    to produce outstr; these may differ if necessary
+		    to avoid special control chars in outstr.
+
+begin
+	# Make a local copy of the arguments to make reversal easy.  Also
+	# switch to zero-indexing internally, since the termcap entry is
+	# zero-indexed.
+
+	arg[1] = arg1 - 1
+	arg1 = 0
+	arg[2] = arg2 - 1
+	arg2 = 0
+	argnum = 1
+
+	op = 1
+	for (ip=1;  ctrlstr[ip] != EOS;  ip=ip+1) {
+	    ch = ctrlstr[ip]
+	    if (ch != '%') {
+		put char in outstr, bump op
+		next
+	    }
+
+	    switch (ch)
+	    case 'd', '2', '3', '+':
+		format coord and concat to outstr
+		increment argnum
+
+	    case '.':
+		# Binary output format.  Coordinate output in binary is a
+		# problem because the OS driver may see a tab, newline, or
+		# whatever and map it into something else.  If the value of
+		# arg[argnum] corresponds to a special control character,
+		# we increment it until we have an acceptable value, leaving
+		# it up to our caller to do the rest.
+
+		while (arg[argnum] is a special control character) {
+		    increment arg[argnum]
+		    increment arg1 or arg2
+		}
+		put binary value of arg[argnum] to outstr
+		increment argnum
+
+	    case '>':
+		conditionally modify arg[argnum]
+	    case 'r':
+		swap arg[1] and arg[2]
+	    case 'i':
+		increment arg[1] and arg[2]
+	    case '%':
+		put % to outstr, bump op
+	    case 'B':
+		BCD encode next arg
+	    case 'D':
+		backwards BCD encode next arg (ugh)
+	    }
+	}
+
+	deposit EOS
+end
+.fi
+
+
+The technique used for cursor addressing depends on the characteristics
+of the terminal.  If the terminal has no cursor motion capability, we
+try to position the cursor using primitive motion commands.  Otherwise
+we use TTYSUBI to generate the cursor motion sequence.  If TTYSUBI returns
+a residual, we use primitive motion commands (up line and backspace) to go
+the rest of the way in.
+
+
+.nf
+procedure ttygoto (fd, tty, col, line)
+
+begin
+	if (tty has no cursor addressing capability) {
+	    # If possible, the calling program should keep track of the
+	    # cursor position and use primitive motion commands for
+	    # positioning when possible.  We do the best we can without
+	    # knowledge of the current position.
+
+	    # First get to a known position.
+	    goto home or lower-left, depending on which is closest to
+		desired position and on capabilities of terminal.
+
+	    # Now move to the desired position.
+	    step to desired line using ttyvert
+	    advance to desired column using ttyhorz
+
+	} else {
+	    get cursor motion control string
+	    call ttysubi to substitute in desired coordinates
+	    call ttyputs to put control string to file
+
+	    # In certain cases, ttysubi cannot get us all the way there,
+	    # and we have to step in the rest of the way.
+
+	    if (line residual)
+		call ttyhorz to adjust position within line
+	    if (col residual)
+		call ttyvert to adjust vertical position
+	}
+end
+.fi
-- 
cgit 

