[mod.sources] PD Terminfo/Curses

sources@genrad.UUCP (12/16/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each module should end with the line "exit".
This code is completely public domain, originally written by Pavel Curtis
of Cornell University.  This version has some small improvements and bug fixes.

This unit contains:

	doc/Installation	- installation guide
	doc/changes.ms		- changes to curses
	doc/compile.1           - compile the terminfo database
	doc/dump.1              - dump a compiled terminfo data module

Part 2 and 3 will be the rest of the documentation

----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =doc
then
    echo 'Making directory "=doc"'
    mkdir =doc
fi
echo 'x - =doc/Installation'
sed 's/^X//' <<'//go.sysin dd *' >=doc/Installation
How to install Curses/Terminfo on your system (Beta-one test release)
---------------------------------------------------------------------

Assumptions: You have unpacked the tar-file into an empty directory.
You found this file in a subdirectory of that one called '=doc'.
There are three other subdirectories, called '=src', '=test', and '=data'.

[ Actually, if you recieved this file as part of the mod.sources
  distribution, you got this distribution as eleven shar format archive
  files, which (when passed through "sh" to unbundle them) create the
  exact same source heirarchy              - John Nelson (mod.sources)]

If any of these assumptions is false, I make no claims for the
correctness of the following instructions.

1.  Decide where you want to put the object files and source files
    of terminal descriptions.  On our system (and I recommend it for
    you), the directory /etc/term is used.  If you really can't stand
    the idea (remember, this is not where the C language source code
    to the library will go; this is where the actual terminal
    descriptions and their object files will go), you'll need to do
    these steps (skip these if you're being reasonable or lazy):
	a. Keep in mind that this directory should probably be
	   in your root filesystem so that programs which use terminfo
	   can be used even when the system is only up single-user.
	b. Change the value of the variable SRCDIR in =src/Makefile
	   to the name of the directory you've chosen.
	c. Change the man pages in =doc to reflect the name-change.

2.  Copy everything in the subdirectory =data into the directory
    chosen in step 1.

3.  Change to the subdirectory =src and type 'make'.  Absolutely no
    error-messages should be produced.  This should compile the library
    (two versions, normal and debugging), the terminfo compiler and the
    dump program. Then type 'make install' to copy the header files into
    /usr/include, copy the compiler and dump programs into the directory
    chosen in step 1, and copy the versions of the library into /usr/lib.
    You will probably need to be super-user to do this.

4.  Change to the directory chosen in step 1 and type 'make'.  This should
    compile the database.  Again, no error-messages of any sort should be
    produced.

5.  Change to the subdirectory =test and type 'make'.  This should compile
    all of the test programs in the release.  Once again, there should be
    no errors.

6.  You may want to install the test programs, make copies of the 
    documentation, etc.

NOTES:
	This release of terminfo/curses will not work on any PDP-11 UNIX
	systems I know of because the Pre-processor to the C compiler
	can't hack the number of #define's in term.h.  If you get this
	up on an eleven, let me know.  Real systems hackers can probably
	find a nice constant to change in their cpp code, but I hesitate
	to try to tell you where to find it.

	The library is stored in /usr/lib/libncurses.a, unless you changed
	the Makefile.  Note the 'n'!!  Programs wishing to use the new
	package should say "-lncurses" on their 'cc' command while those
	wanting the old package should still say '-lcurses'.

	Similarly, the curses header file should be included using
			#include <ncurses.h>

	The header file <terminfo.h> has been included so that programs
        which work only at the terminfo-level need not worry about name
	conflicts with the rest of the package.  By including
	<terminfo.h> instead of <ncurses.h>, they will get everything
	needed for the terminfo-level routines.

	You, dear reader, are truly a guinea pig.  If there's anything
	wrong with this package, these instructions, etc., you're
	supposed to tell me about it.  I'm going to be very depressed if
	I send this out and get no response at all.   So, save me the
	agony of loneliness and write to me your impressions/complaints/
	suggestions!

	[ actually, this is being posted two years after the original
	  distribution.  Most of the bugs should be out, but of course,
	  there are no guarantees        - John Nelson (mod.sources) ]

	Oh, yes.  Thank you.
	
	        Pavel Curtis
		Computer Science Dept.
		405 Upson Hall
		Cornell University
		Ithaca, NY 14853
		
		Ph- (607) 256-4934
		
		decvax!cornell!pavel		(UUCP)
		Pavel.Cornell@Udel-Relay	(ARPA)
//go.sysin dd *
echo 'x - =doc/changes.ms'
sed 's/^X//' <<'//go.sysin dd *' >=doc/changes.ms
X.po +.5i
X.TL
New Features in Curses and Terminfo
X.AU
Pavel Curtis
X.NH
Introduction
X.PP
This document describes new features that are being added to the
Berkeley \fBcurses\fP subroutine package.
It also describes the new \fBterminfo\fP database, which
replaces the Berkeley \fBtermcap\fP database.  The emphasis is on the
new features.
X.NH
New Features in Curses
X.PP
This section describes the enhancements to curses.  Briefly, the
enhancements are:
X.de Np
X.IP \\n+(l%.
X..
X.nr l% 0 1
X.af l% a
X.Np
Curses is smarter.  It can take advantage of insert/delete
line/character.  (By default, it will not use insert/delete
line.  See \fIidlok()\fR.)
X.Np  
Curses uses the new \fBterminfo\fP data base, as described in the
next section.
X.Np  
Curses works on more terminals.
X.Np  
It is possible to use more than one terminal at a time.
X.Np  
Video attributes can be displayed in any combination.
X.Np  
Curses handles terminals with the ``magic cookie'' video
attribute glitch.
X.Np  
The function and arrow keys on terminals can be input as
though they were a single character.
X.Np  
There is a user accessible scrolling region, like the DEC
VT100.
X.Np  
If the programmer restricts his code to a subset of the full
curses, the \fBMINICURSES\fP version can be used, which is smaller
and faster.
X.Np  
Two routines are provided for setting the tty bits to the
proper state for shell escapes and control-Z suspensions.
X.Np  
On systems that support it (currently only 4.1BSD), if the
user types something during an update, the update will stop,
pending a future update.  This is useful when the user hits
several keys, each of which causes a good deal of output.
X.Np  
The routine \fBgetstr()\fP is smarter - it handles the users erase
and kill characters, and echos its input.
X.Np  
The function \fBlongname()\fP is now useful and actually works.
X.Np  
Nodelay mode allows ``real time'' programs to be written
with the same interface on both systems.  Setting the flag
causes \fBgetch\fP to return -1 if no input is waiting.
X.Np  
Several useful routines are provided to enhance portability.
X.NH 2
Curses is Smarter
X.PP
The algorithm used by curses has been replaced with an algorithm
that takes into account insert and delete line and character
functions, if available, in the terminal.  By default, curses
will not use insert/delete line.  This was not done for
performance reasons, since there is no speed penalty involved.  Rather,
it was found that some programs do not need this facility, and
that if curses uses insert/delete line, the result on the screen
can be visually annoying.  Since most simple programs using
curses do not need this, and since the old curses did not use it,
the default is to avoid insert/delete line.  Call the routine
X.DS
\fBidlok(stdscr, TRUE);\fP
X.DE
to enable insert/delete line, if your application needs it.
Insert/delete character is always considered.
X.NH 2
Additional Terminals
X.PP
Curses works on a larger class of terminals than the previous
version.  Terminfo is able to address the cursor on more kinds of
terminals.  Curses will work even if absolute cursor addressing
is not possible, as long as the cursor can be moved from any
location to any other location.  It considers local motions,
parameterized motions, home, and carriage return.
X.PP
Curses is still aimed at full duplex, alphanumeric, video
terminals.  No attempt is made to handle half-duplex, synchronous,
hard copy, or bitmapped terminals.
X.PP
Curses handles terminals with the ``magic cookie glitch'' in
their video attributes.\u*\d
X.FS
\u*\dThis feature is not supported in the current test release.  It will
be implemented in the official distribution.
X.FE
This glitch means that a change in video
attributes is implemented by storing a ``magic cookie'' in a
location on the screen.  This ``cookie'' takes up a space,
preventing an exact implementation of what the programmer wanted.
Curses takes the extra space into account, and moves part of the
line to the right, as necessary.  In some cases, this will
unavoidably result in losing text from the right hand edge of the
screen.  Existing spaces are taken advantage of.
X.NH 2
Multiple Terminals
X.PP
Some applications need to display text on more than one terminal,
controlled by the same process.  Even if the terminals are
different, the new curses can handle this.
X.PP
All information about the current terminal is kept in a global
variable
X.DS
\fBstruct screen\fP *SP;
X.DE
Although the screen structure is hidden from the user, the C
compiler will accept declarations of variables which are pointers.
The user program should declare one screen pointer variable for
each terminal it wishes to handle.  The routine
X.DS
\fBstruct screen *
\fInewterm\fR(type, fd)
\fBchar\fP *type;
XFILE *fp;
X.DE
will set up a new terminal of the given terminal type which does
output on file pointer fp.  A call to \fIinitscr()\fP is essentially
\fInewterm\fP(\fIgetenv\fP(``TERM''), \fBstdout\fR).
A program wishing to use more
than one terminal should use \fInewterm()\fP for each terminal and save
the value returned as a reference to that terminal.
X.PP
To switch to a different terminal, call
X.DS
\fBstruct screen\fP *
\fIset_term\fP(term)
\fBstruct screen\fP *term;
X.DE
The old value of SP will be returned.  You should not assign
directly to SP because certain other global variables must also
be changed.
X.PP
All curses routines always affect the current terminal.  To
handle several terminals, switch to each one in turn with \fIset_term()\fP,
and then access it.  Each terminal must be set up with \fInewterm()\fP,
and closed down with \fIendwin()\fP.
X.NH 2
Video Attributes
X.PP
Video attributes can be displayed in any combination on terminals
with this capability.  They are treated as an extension of the
standout capability, which is still present.
X.PP
Each character position on the screen has 16 bits of information
associated with it.  7 of these bits are the character to be
displayed, leaving separate bits for 9 video attributes.  These
bits are used for standout, underline, reverse video, blink, dim,
bold, blank, protect, and alternate character set.  Standout is
taken to be whatever highlighting works best on the terminal, and
should be used by any program that does not need specific or
combined attributes.  Underlining, reverse video, blink, dim, and
bold are the usual video attributes.  Blank means that the
character is displayed as a space, for security reasons.  Protected
and alternate character set are dependent on the particular
terminal.  The use of these last three bits is subject to change and
not recommended.
X.PP
The routines to use these attributes include
X.DS
X.ta 2i
\fIattrset\fP(attrs)	\fIwattrset\fP(attrs)
\fIattron\fP(attrs)	\fIwattron\fP(attrs)
\fIattroff\fP(attrs)	\fIwattroff\fP(attrs)
\fIstandout\fP()	\fIwstandout\fP()
\fIstandend\fP()	\fIwstandend\fP()
X.DE
X.PP
Attributes, if given, can be any combination of A_STANDOUT,
A_UNDERLINE, A_REVERSE, A_BLINK, A_DIM, A_BOLD, A_INVIS,
A_PROTECT, and A_ALTCHARSET.  These constants, defined in
curses.h, can be combined with the C | (or) operator to get
multiple attributes.  \fIAttrset()\fP sets the current attributes to the
given \fIattr\fP; \fIattron()\fP turns on the given \fIattrs\fP in addition to any
attributes that are already on; \fIattroff()\fP turns off the given
attributes, without affecting any others.  \fIstandout()\fP and \fIstandend()\fP
are equivalent to \fIattron\fP(A_STANDOUT) and \fIattroff\fP(A_STANDOUT).
X.PP
Since standout is stored in the 8th bit of the text byte, it is
possible to recompile curses so that only 8 bits are stored for
each character, making a smaller curses, and still be able to use
standout.  Also, programs that restrict themselves to the
routines \fIstandout()\fP and \fIstandend()\fP will work with both
the new and old curses.
X.PP
If the particular terminal does not have the particular attribute
or combination requested, curses will attempt to use some other
attribute in its place.  If the terminal has no highlighting at
all, all attributes will be ignored.
X.NH 2
XFunction Keys
X.PP
Many terminals have special keys, such as arrow keys, keys to
erase the screen, insert or delete text, and keys intended for
user functions.  The particular sequences these terminals send
differs from terminal to terminal.  Curses allows the programmer
to handle these keys.
X.PP
A program using function keys should turn on the keypad by
calling
X.DS
\fIkeypad\fP(\fBstdscr\fP, TRUE)
X.DE
at initialization.  This will cause special characters to be
passed through to the program by the function \fIgetch()\fP.  These keys
have constants which are defined in curses.h.  They have values
starting at 0401, so they should not be stored in a \fBchar\fP
variable, as significant bits will be lost.
X.PP
A program using function keys should avoid using the \s-2ESCAPE\s0 key,
since most sequences start with escape, creating an ambiguity.
Curses will set a one second alarm to deal with this ambiguity,
which will cause delayed response to the escape key.  It is a
good idea to avoid escape in any case, since there is eventually
pressure for nearly \fIany\fP screen oriented program to accept arrow
key input.
X.NH 2
Scrolling Region
X.PP
There is a user accessible scrolling region, like the DEC VT100.
Normally, it is set to the entire window, but the calls
X.DS
\fIsetscrreg\fP(top, bot)
\fIwsetscrreg\fP(win, top, bot)
X.DE
set the scrolling region for \fBstdscr\fP or the given window to any
combination of top and bottom margins.  If scrolling has been
enabled with \fIscrollok\fP, scrolling will take place only within that
window.  See the \fICurses Reference Manual\fP for the detailed semantics
of this construct.
X.NH 2
Mini-Curses\u*\d
X.FS
\u*\dThis feature is not supported in the current test release.  It will
be implemented in the official distribution.
X.FE
X.PP
The new curses is bigger than the old one, and has to copy from
the current window to an internal screen image for every call to
\fIrefresh()\fP.  If the programmer is only interested in screen output
optimization, and does not want the windowing or input functions,
an interface to the lower level routines is available.  This will
make the program somewhat smaller and faster.  The interface is a
subset of full curses, so that conversion between the levels is
not necessary to switch from mini-curses to full curses.
X.PP
The subset mainly requires you to avoid use of more than the one
window \fBstdscr\fP.  Thus, all functions beginning with ``w'' are
generally undefined.  Certain high level functions that are
convenient but not essential are also not available, including
\fIprintw()\fP and \fIscanw()\fP  Also, the input routine \fIgetch()\fP
cannot be used
with mini-curses.  Features implemented at a low level, such as
use of hardware insert/delete line and video attributes, are
available in both versions.  Also, mode setting routines such as
\fIcbreak()\fP and \fInoecho()\fP are allowed.
See the manual page for the exact
list of routines allowed with mini-curses.
X.PP
To access mini-curses, add \fB-DMINICURSES\fP to the CFLAGS in your
makefile.  If you ask for routines that are not in the subset,
the loader will print error messages such as
X.DS
Undefined:
no_getch
no_waddch
X.DE
to tell you that the routines \fIgetch()\fP and \fIwaddch()\fP were used but are
not available in the subset.  Since the preprocessor is involved
in the implementation of mini-curses, you must recompile the
entire program if you change from one version to the other.
Similarly, programs compiled with the old curses must be
recompiled for the new curses.
X.NH 2
TTY Mode Functions
X.PP
In addition to the save/restore routines \fIsavetty()\fP and \fIresetty()\fP,
standard routines are available for going into and out of normal
tty mode.  These routines are \fIresetterm()\fP, which puts the
terminal back in the mode it was in when curses was started, and \fIfixterm()\fP,
which undoes the effects of \fIresetterm()\fP, that is, restores
the ``current curses mode''.  \fIendwin()\fP automatically calls
\fIresetterm()\fP, and the routine to handle control-Z (on 4.1BSD systems with
process control) also uses \fIresetterm()\fP and \fIfixterm()\fP.  The programmer
should use these routines before and after shell escapes, and
also if he writes his own routine to handle control-Z.  These
routines are also available at the \fIterminfo\fP level.
X.NH 2
Typeahead Check\u*\d
X.FS
\u*\dThis feature is not supported in the current test release.  It will
be implemented in the official distribution.
X.FE
X.PP
On systems that support it (current only 4.1BSD), if the user
types something during an update, the update will stop, pending a
future update.  This is useful when the user rapidly hits several
keys, each of which causes a good deal of output.  This feature
is automatic and cannot be disabled.
X.NH 2
Getstr()
X.PP
The routine \fIgetstr()\fP is smarter.  The semantics are slightly
different from the old \fIgetstr()\fP, but no incompatibilities are
anticipated.  No matter what the setting of \fIecho\fP is, strings typed in
here are echoed at the current cursor location.  The users erase
and kill characters are understood and handled.  This makes it
unnecessary for an interactive program to deal with erase, kill,
and echoing when the user is typing a line of text.
X.NH 2
Longname()
X.PP
The function \fIlongname()\fP is now useful and actually works.  The
previous version required the programmer to call \fItgetent()\fP directly
and pass the resulting string, along with a buffer, to \fIlongname()\fP.
The string actually returned was the second alias for the
terminal, not the long name.
X.PP
The new \fIlongname()\fP function does not take any arguments.  It
returns a pointer to a static area containing the actual long
name of the terminal.  No call to \fItgetent()\fP is needed, in fact,
that routine no longer exists.
X.NH 2
Nodelay Mode
X.PP
The call
X.DS
\fInodelay\fP(\fBstdscr\fP, TRUE)
X.DE
will put the terminal in ``nodelay mode''.  While in this mode,
any call to \fIgetch()\fP will return -1 if there is nothing waiting to
be read immediately.  This is useful for writing programs
requiring ``real time'' behavior where the user watches action on the
screen and presses a key when he wants something to happen.  For
example, the cursor can be moving across the screen, and the user
can press an arrow key to change direction.  This mode is
especially useful for games such as PacMan and Space Invaders.
X.NH 2
Portability
X.PP
Several useful routines are provided to enhance portability.
While these routines do not directly relate to terminal handling,
their implementation is different from system to system, and the
differences can be isolated from the user program by including
them in curses.
X.PP
XFunctions \fIerasechar()\fP and \fIkillchar()\fP return the characters which
erase one character, and kill the entire input line,
respectively.  The function \fIbaudrate()\fP will return the current baud
rate, as an integer.  (For example, at 9600 baud, the integer
9600 will be returned, not the value B9600 from <sgtty.h>.) The
routine \fIflushinp()\fP will cause all typeahead to be thrown away.
X.NH 2
XFeatures No Longer Supported
X.PP
In general, an effort has been made to support old features where
possible.  However, there are some features of the old curses
that cannot be supported, due to the change to terminfo, or due
to other miscelaneous causes.
X.PP
The old curses defined a number of two letter variables, such as
CM, containing termcap capabilities.  These variables are no
longer accessible to the user.  In general, their semantics are
different, as are their names.  A program using primarily these
variables is really written at the termcap level.  Also
unavailable are the related variables NONL, GT, and UPPERCASE.
X.PP
Such programs should be recoded to avoid these capabilities, if
at all possible, instead using the higher level curses functions.
If this is not possible, recode at the terminfo level.  A program
making only light use can probably be easily changed to avoid
these variables completely.  A program at the terminfo level that
only needs motion optimization should probably still be recoded
to use the high level routines, in order to work on more
terminals.  If this is not possible, recode at the terminfo level,
continuing to use \fImvcur()\fP, which is still supported.  It is not
necessary to call \fImvcur()\fP to move to the lower left corner of the
screen before calling \fIendwin()\fP.
X.PP
Some programs (notably rogue) use varibles in <curses.h> which
begin with an underline.  Use of these variables and fields is to
be avoided.  Most of the internal structures used by curses are
hidden from the user.  The variables _tty and _tty_ch are no
longer accessible.  (Since _tty was a version 7 dependent
structure, it was not portable to use it anyway.) Useful fields, such
as the erase and kill characters, and the baud rate, can be
discovered using the portable functions described above.
X.NH
Termlib-Level Changes
X.PP
The termcap(3) (termlib) library has been consolidated with the
curses(3) library to form a new curses(3) library.  The termlib
level is very different in the new version.  The routines
\fItgetent()\fP, \fItgetnum()\fP, \fItgetstr()\fP, and \fItgetflag()\fP are gone.
Initialization is instead done by calling
X.DS
\fIsetupterm\fP(termtype, filedes, errret)
\fBchar\fP *termtype;
\fBint\fP filedes;
\fBint\fP *errret;
X.DE
This routine takes care of all reading in of capabilities, and
any other system dependent initialization.  The terminal type can
be passed as 0, causing \fIsetupterm()\fP to use \fIgetenv\fP(``TERM'') as a
default.  \fIerrret\fP is a pointer to an integer used to return a
status value.  The value returned is 0 if there is no such
terminal type, 1 if all went well, or -1 for some trouble.  A null
pointer can be passed for this value, telling \fIsetupterm()\fP to print
an error message and exit if the terminal cannot be found.
X.PP
When exiting, or calling a shell escape, the user program should
call \fIresetterm()\fP to restore the tty modes.  After the shell
escape, \fIfixterm()\fP can be called to set the tty modes back to
their internal settings.  These calls are now \fBrequired\fP, since
they perform system dependent processing.  They do not output the
\fBenter_ca_mode\fP and \fBexit_ca_mode\fP strings (\fBti\fP and \fBte\fP
in termcap) but
should be called at the same times.
\fISetupterm()\fP calls \fIfixterm()\fP.
X.PP
\fItgoto()\fP has been replaced by \fItparm()\fP, which is a more powerful
parameterized string mechanism.  The \fItgoto()\fP routine is still
available for compatibility.  \fItputs()\fP is unchanged.
X.PP
The external variables \fBUP\fP, \fBBC\fP, \fBPC\fP, and \fBospeed\fP
no longer exist.
The programmer need not worry about these, as their function is
now handled internally.
X.NH
Changes from Termcap to Terminfo
X.PP
This section describes the extensions in terminfo that were not
present in termcap, and the incompatible changes that were made.
It is intended for a programmer or termcap author who is familiar
with termcap and wishes to become familiar with terminfo.  The
emphasis is on the database, not on the programmer interface.
X.NH 2
Syntax
X.PP
The first thing you will notice upon scanning terminfo is that it
looks cosmetically different from termcap.  All the backslashes
are gone from ends of lines.  Fields are separated with commas
instead of colons, and white space after the commas makes them
more readable.  Continuation lines are now defined as lines
beginning with a blank or tab, not lines following a backslash.
These changes make terminfo easier to read and to modify.
X.NH 2
Names
X.PP
The names of the capabilities are no longer limited to two
letters.  There is no longer a hard limit to the names, but an
informal limit of 5 characters is used.  Since the two letter
limit is gone, many of the capabilities have been renamed.  They
now correspond as closely as possible the the ANSI standard
XX3.64.  While learning the new set of names will be tricky at
first, eventually life will be simpler, since most new terminals
use the ANSI abbreviations.
X.NH 2
Defaults
X.PP
A change that is perhaps not so obvious is that certain defaults
are no longer implied.  In termcap, \er was assumed to be a
carriage return unless \fBnc\fP was present, indicating that it did not
work, or \fBcr\fP was present, indicating an alternative.  In terminfo,
if \fBcr\fP is present, the string so given works, otherwise it should
be assumed \fInot\fP to work.  The \fBbs\fP and \fBbc\fP capabilities are replaced
by \fBcub\fP and \fBcub1\fP.  (The former takes a parameter, moving left that
many spaces.  The latter is probably more common in terminals and
moves left one space.)  \fBnl\fP (linefeed) has been split into two
functions: \fBcud1\fP (moves the cursor down one line) and \fBind\fP (scroll
forward).  \fBcud1\fP applies when the cursor is not on the bottom
line, \fBind\fP applies when it is on the bottom line.  The bell
capability is now explicitly given as \fBbel\fP.
X.NH 2
Compilation
X.PP
The terminfo database is compiled, unlike termcap.  This means
that a terminfo source file (describing some set of terminals) is
processed by the terminfo compiler, producing a binary
description of the terminal in a file under /etc/term.  The setupterm
routine reads in this file.
X.PP
The advantage to compilation is that starting up a program using
terminfo is faster.  It is no longer necessary to carry around
the variable TERMCAP in the environment.  It is actually faster
to start up a compiled terminfo \fIwithout\fP the environment variable,
than it is to start up an uncompiled termcap \fIwith\fP the environment
variable.  The increase in speed comes partly from not having to
skip past other terminal descriptions, and partly from the
compiler having sorted the capabilities into order so that a linear
scan can read them in.  (The termcap initialization algorithm is
quadratic on the size of the capability.  The more capabilities
you are interested in, the worse this gets.  It had gotten to the
point where it took 2 CPU seconds on a VAX 11/750 to start up a
process using an uncompiled terminfo!)
X.PP
There exists an environment variable TERMINFO which is taken by the compiler
to be the destination directory of the new object files.  It is also used by
\fIsetupterm()\fP to find an entry for a given terminal.  First it looks in
the directory given in TERMINFO and, if not found there, checks /etc/term.
\fBNote\fP, however, that, unlike the old TERMCAP variable, you may not
put the source for an entry in the TERMINFO variable.  \fIAll\fP
terminfo entries must be compiled.
X.NH 2
Parameterised Strings
X.PP
The old \fItgoto()\fP mechanism, which was designed for cursor addressing
only, has been replaced by a more general parameter mechanism,
accessed through the function \fItparm()\fP.  Since the parameters are
not compatible in the terminfo database, a termcap \fBcm\fI description
must be converted manually to terminfo.
X.PP
The new mechanism is based on a stack.  % operations are used to
push parameters and constants onto the stack, do arithmetic and
other operations on the top of the stack, and print out values in
various formats.  This makes it possible to handle a larger class
of terminals, such as the AED 512, which addresses the cursor in
terms of pixels, not character positions, and the TEC scope,
which numbers the rows and columns from the lower right hand
corner of the screen.  Any number of parameters from 1 to 9 is
possible, whereas \fItgoto()\fP allowed only two parameters. 
If-then-else testing is possible, as is storage in a limited number of
variables.  There is no provision for loops or printing strings
in any format other than %s.  The full details are described in
terminfo(5).
X.PP
A few brief examples are included here to show common
conversions.  For more examples, compare the termcap \fBcm\fP and terminfo
\fBcup\fP entries for your favorite terminal.  ``%+ '' (add space and
print as a character) would be treated as ``%p1%' '%+%c'', that
is, push the first parameter, push space, add the top two numbers
on the stack, and output the top item on the stack using
character (%c) format.  (Of course, for the second parameter, the %p1
must be changed to %p2.) ``%.'' (print as a character) would be
``%p1%c''.  ``%d'' (print in decimal) would be ``%p1%d''.  As
with \fItgoto()\fP, characters standing by themselves (no % sign) are
output as is.
X.NH 2
More Capabilities
X.PP
There are a number of new capabilities.  The set of new
capabilities may vary, depending on the version of termcap you are used
to.  It is probably worthwhile to read terminfo(5) for a complete
list.  This section describes capabilities new to terminfo that
were never put in termcap.
X.PP
There are provisions for dealing with more video attributes.
Termcap had strings to turn on and off standout and underline
modes.  Terminfo has these and several more.  There are strings
to turn on bold, inverse video, blinking, dim, protected, and
blanking.  Rather than have separate string for turning off each
of these, a single capability: \fBsgr0\fP, turns them all off.
X.PP
The effect of turning on more than one attribute at a time with
the separate strings is undefined.  A parameterized string, \fBsgr\fP,
can be used to turn them on in combination.
X.PP
More function keys are defined now.  There are provisions for f0
through f10 as well as keys such as erase, insert mode, insert
line, delete line, delete character, print, and so on.  All of
these keys can be accessed through curses as if they were single
characters.  Also, \fBvi\fP version 3.8 has default meanings for many
of them.
X.PP
Several new uses are made of parameterized strings.  For example,
capabilities exist to move the cursor to a particular column in
the current row, a particular row in the current column, and to
move left, right, up, or down a given number of spaces.  These
capabilities make a big difference on some terminals, such as the
Tektronix 4025.  Also, column addressing is useful for filters
that do not know what row they are in, or as a shorter form of
cursor addressing when the target is in the same row.
X.PP
There are now capabilities to turn on and off a local printer,
and to print the current page.  Also, there are provisions for
moving the cursor to and from a status line.  These capabilities
can be used by a background status program, such as \fIsysline\fP, to
keep status information in the status line without bothering
foreground processes.  This only works on terminals with a
writable status line, such as the h19 or tvi950, or on terminals
where one can be simulated, such as the hp2626, vt100, or
ambassador, by allocating one of the ordinary screen lines for a
status line.
X.NH 2
How to Convert from Termcap to Terminfo
X.PP
This section is intended for programmers who need to convert
programs that use termcap to the new terminfo database.  It
describes the steps needed for the conversion.
X.PP
If you must make the conversion, you are strongly urged to
convert to curses, rather than converting to terminfo.  The curses
interface is higher level and will probably do a better job of
optimizing your output.  Your program will work on a wider range
of terminals if you use curses.  It will also become more
portable.  The effort to convert to curses is probably about the same
as to convert to terminfo.
X.PP
There are some programs for which curses is not a possibility.
Curses takes over the CRT screen, and this implies initially
clearing the screen.  For some programs, such as filters, this
may not make sense.  Also, if you are writing a special purpose
program which uses some terminfo capability that curses does not
use, it will probably be necessary to use the terminfo level
interface.
X.NH 2
Conversion
X.PP
The first step is to include the headers <curses.h> and <term.h>
(in that order).  These headers will bring into existence a set
of ``variables'' (actually macros) that contain values of
capabilities.  For example, the macro \fBcursor_address\fP will be defined,
replacing the termcap \fBcm\fP
capability.  You should remove the declarations for all variables
you use for capabilities returned by \fItgetflag()\fP, \fItgetnum()\fP, and
\fItgetstr()\fP.
X.PP
The most difficult step is that all variables removed in the
previous step must be renamed the standard names.  For example, if
you stored \fBcm\fP in the variable CM, you would change
\fItputs\fP(\fItgoto\fP(\fBCM\fP, i, j), 1, outch) to
\fItputs\fP(\fItgoto\fP(\fBcursor_address\fP, i, j), 1, outch).
Consult terminfo(5) for a list of standard
names.  A \fBsed\fP script is often useful for this step.  Care must be
taken to avoid mention of the variable as part of a longer word
(a version of \fBsed\fP supporting the \fBex\fP \<word\> convention is useful
here.) Also, you should proofread the results, since sometimes
comments and strings get substituted that shouldn't have been.
X.PP
Remove all your termcap initialization code.  This code typically
calls \fItgetent()\fP, \fItgetstr()\fP, \fItgetflag()\fP, and \fItgetnum()\fP.
You can also
remove declarations used only for this initialization, usually
including buffers for the entry and string values.  Replace it
with a single call to \fIsetupterm\fP(0, 1, 0).  This call will never
return if something goes wrong, that is, if there is no $TERM in
the environment or there is no such terminal, the routine will
print an error and exit.  If you need an error indication passed
back for more sophisticated error recovery, pass an integer
variable in the third parameter, i.e.  setupterm(0, 1, &i).  The
value returned in \fBi\fP will be the same as that previously returned
by \fItgetent()\fP.  Other more sophisticated calls to \fIsetupterm()\fP are
possible, see the documentation if some terminal other than $TERM or
some file descriptor other than \fBstdout\fP are involved.
X.PP
Before the program exits, insert a call to \fIresetterm()\fP.  This
will restore the tty modes to their state before setupterm was
called, and do any other system dependent exit processing.  This
routine can also be called before a shell escape, you should call
\fIfixterm()\fP after the shell escape to restore the tty modes to
those needed by terminfo.  (Currently \fIsetupterm()\fP will turn off the
XXTABS bit in the tty driver, since some terminals need to send
control I for escape sequences.  You should be sure to expand any
tabs in your software if necessary.)
X.PP
XFrom the programmers viewpoint, the routine \fItputs()\fP is exactly as
in termcap.  The padding syntax in the capability is different,
but this only affects the capabilities in the terminfo database.
No change to a program will be needed for \fItputs()\fP.
X.PP
The \fItgoto()\fP routine is kept around for upward compatibility, but
you should probably replace calls to \fItgoto()\fP by calls to \fItparm()\fP.
The call \fItgoto\fP(cap, y, x) will call \fItparm\fP(cap, x, y).  Note that
the order of the last two arguments is reversed - it was
backwards in \fItgoto()\fP from what it probably should have been.  In
addition to the capability, \fItparm()\fP can now take up to nine parameters,
or as few as one.
X.PP
If you use certain capabilities, there are a few convention
changes you should be aware of.  These do not affect very many
programs, but will require some minor recoding of a few programs.
In termcap, the cursor is moved left by control-H if \fBbs\fP is
present, otherwise, if \fBbc\fP is present, that character is used.  In
terminfo, the cursor is moved left with \fBcub1\fP, if present, or by
\fBcub\fP, if present.  If neither is there, there is no implied
control-H.  Similarly, termcap assumed that control-M was carriage
return unless \fBnc\fP or \fBcr\fP was specified.  In terminfo, carriage
return is always the string specified by \fBcr\fP, and if not present,
there is no carriage return capability.  In termcap, linefeed is
assumed to both move the cursor down (if it is not on the bottom
line) and to scroll one line (if it is on the bottom line),
unless \fBns\fP is present.  \fBsf\fP and \fBdo\fP capabilities were present but
little used, and some software assumed that \fBsf\fP worked with the
cursor anywhere on the screen.  In terminfo, there is no implied
linefeed - moving the cursor down is done with \fBcud1\fP or \fBcud\fP and
scrolling is done with \fBind\fP.  \fBind\fP is only defined when the cursor
is at the bottom of the screen.  Finally, the implied control G
used to ring the bell unless \fBvb\fP was present has been replaced
with an explicit \fBbel\fP.
X.PP
Replace references in your makefile from -ltermcap or -ltermlib
with references to -lcurses.
X.PP
Now recompile your program.  It should run properly using
terminfo.
X.NH 2
Space Conditions
X.PP
The expansion of a macro name into a structure reference 
will probably make your program a bit bigger.  If space is a
problem, one thing you can do is add \fB-DSINGLE\fP to the CFLAGS in
your makefile.  This causes the macros to expand to a static
reference instead of a dynamic reference, resulting in smaller
code.  It cannot be used if you intend to involve more than one
terminal from a single process.  Since very few programs talk to
two terminals at once, it is almost always safe to define SINGLE.
X.PP
If your program was pushing the limit on a small machine, it may
not fit with terminfo unless you trim it down some.  While the
startup routines are faster, they tend to generate larger code
than those of termcap.  Also, \fItputs()\fP and \fItparm()\fP are more
sophisticated and larger.
//go.sysin dd *
echo 'x - =doc/compile.1'
sed 's/^X//' <<'//go.sysin dd *' >=doc/compile.1
X.TH COMPILE 1 Terminfo/Curses
X.SH NAME
compile \- Compile the terminfo database
X.SH SYNOPSIS
X.B /etc/term/compile
[\fB-v\fR[\fIn\fR]] source-file
X.SH DESCRIPTION
X.I Compile
is the program which translates the source files in the terminfo
terminal capability database into their object format.  The given
X.I file
is expected to contain one or more terminfo entries, as described in
X.IR terminfo (5).
This file is expected to be self-contained, i.e., it may not
contain ``\fBuse\fP'' entries which refer to terminals not described fully
in the same file.
X.PP
The object files are normally placed in subdirectories of the directory
X/etc/term (see
X.IR term (5)),
but if the environment variable TERMINFO is defined, it is taken to be the
name of an alternate directory to use.
X.PP
Debugging and tracing information may be obtained by use of the
X.B -v
flag.
The number after the flag controls the amount of debugging information
given, according to the following table:
X.IP 1
Names of files created and linked
X.IP 2
Information related to the ``\fBuse\fR'' facility
X.IP 3
Statistics from the hashing algorithm
X.IP 5
String-table memory allocations
X.IP 7
Entries into the string-table
X.IP 8
List of tokens encountered by scanner
X.IP 9
All values computed in construction of the hash table
X.in -0.5i
X.sp
If \fIn\fP is not given, it is taken to be one.
X.SH FILES
X/etc/term/*	Default location of object files
X.SH SEE ALSO
terminfo(5), term(5), dump(1).
X.SH AUTHOR
Pavel Curtis, Cornell University
X.br
(decvax!cornell!pavel  or  Pavel.Cornell@Udel-Relay)
X.SH BUGS
You tell me.
//go.sysin dd *
echo 'x - =doc/dump.1'
sed 's/^X//' <<'//go.sysin dd *' >=doc/dump.1
X.TH DUMP 1 Terminfo/Curses
X.SH NAME
dump \- Print the contents of a compiled terminfo file in human-readable form
X.SH SYNOPSIS
X.B /etc/term/dump 
file ...
X.SH DESCRIPTION
X.I Dump 
reads the given files and decodes their contents to derive a reasonable
representation of the terminfo entry which produced the file originally.
It should be noted, in case of emergency, that the output of
X.I dump
is perfectly usable as the input to
X.IR compile (1).
X.SH SEE ALSO
compile(1), term(5), terminfo(5)
X.SH AUTHOR
Pavel Curtis, Cornell University
X.br
(decvax!cornell!pavel or Pavel.Cornell@Udel-Relay)
//go.sysin dd *
exit

sources@genrad.UUCP (12/16/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) This code is completely public domain, originally
written by Pavel Curtis of Cornell University.  This version has some small
improvements and bug fixes.

This unit contains:

	doc/manual.tbl.ms	- curses documentaion (tbl | nroff -ms)
	doc/ncurses.3		- curses man page

Part 3 will contain the terminfo documentation

----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =doc
then
    echo 'Making directory "=doc"'
    mkdir =doc
fi
echo 'x - =doc/manual.tbl.ms'
sed 's/^X//' <<'//go.sysin dd *' >=doc/manual.tbl.ms
X.po +.5i
X.TL
The Curses Reference Manual
X.AU
Pavel Curtis
X.NH
Introduction
X.LP
Terminfo is a database describing many capabilities of over 150
different terminals.  Curses is a subroutine package which
presents a high level screen model to the programmer, while
dealing with issues such as terminal differences and optimization of
output to change one screenfull of text into another.
X.LP
Terminfo is based on Berkeley's termcap database, but contains a
number of improvements and extensions.  Parameterized strings are
introduced, making it possible to describe such capabilities as
video attributes, and to handle far more unusual terminals than
possible with termcap.
X.LP
Curses is also based on Berkeley's curses package, with many
improvements.  The package makes use of the insert and delete
line and character features of terminals so equipped, and
determines how to optimally use these features with no help from the
programmer.  It allows arbitrary combinations of video attributes
to be displayed, even on terminals that leave ``magic cookies''
on the screen to mark changes in attributes.
X.NH
An Overview of the Package
X.NH 2
Terminology
X.PP
In this document,
the following terminology is kept to with reasonable consistency:
X.IP \fIwindow\fP 10
An internal representation
containing an image of what a section of the terminal screen may look like
at some point in time.
This subsection can either encompass the entire terminal screen,
or any smaller portion down to a single character within that screen.
X.IP \fIterminal\fP 10
Sometimes called \fIterminal screen\fP.
The package's idea of what the terminal's screen currently looks like,
i.e., what the user sees now.
This is a special \fIscreen\fP:
X.IP \fIscreen\fP 10
This is a subset of windows which are as large as the terminal screen,
i.e., they start at the upper left hand corner
and encompass the lower right hand corner.
One of these, \fIstdscr\fP,
is automatically provided for the programmer.
X.NH 2
Compiling Programs using the Package
X.PP
In order to use the library,
it is necessary to have certain types and variables defined.
Therefore, the programmer must have a line:
X.DS
X.B "#include <ncurses.h>"
X.DE
at the top of the program source.
The header file
X.B <ncurses.h>
needs to include
X.B <sgtty.h> ,
so the one should not do so oneself.\u*\d
X.FS
\u*\dThe screen package also uses the Standard I/O library,
so \fB<ncurses.h>\fP includes \fB<stdio.h>\fP.
It is redundant (but harmless) for the programmer to do it, too.
X.FE
Also,
compilations should have the following form:
X.DS
\fBcc\fR [ \fIflags\fR ] file ... \fB\-lbcurses\fR
X.DE
X.NH 2
Updating the Screen
X.PP
In order to update the screen optimally,
it is necessary for the routines to know what the screen currently looks like
and what the programmer wants it to look like next.
XFor this purpose, a data type (structure) named \fIWINDOW\fP
is defined which describes a window image to the routines,
including its starting position on the screen
(the (y, x) coordinates of the upper left hand corner)
and its size.
One of these (called \fIcurscr\fP, for \fIcurrent screen\fP)
is a screen image of what the terminal currently looks like.
Another screen (called \fIstdscr\fP, for \fIstandard screen\fP)
is provided by default to make changes on.
X.PP
A window is a purely internal representation.
It is used to build and store
a potential image of a portion of the terminal.
It doesn't bear any necessary relation
to what is really on the terminal screen.
It is more like an array of characters on which to make changes.
X.PP
When one has a window which describes
what some part of the terminal screen should look like,
the routine \fIrefresh()\fP (or \fIwrefresh()\fP if the window is not
\fIstdscr\fP) is called.
\fIRefresh()\fP in the area covered by the window,
look like that window.
Note, therefore, that changing something on a window
\fIdoes not change the terminal\fP.
Actual updates to the terminal screen are made only by calling
\fIrefresh()\fP or \fIwrefresh()\fP.
This allows the programmer to maintain several different ideas
of what a portion of the terminal screen should look like.
Also, changes can be made to windows in any order,
without regard to motion efficiency.
Then, at will, the programmer can effectively say
``make it look like this,''
and let the package worry about the best way to do this.
X.NH 2
Naming Conventions
X.PP
As hinted above, the routines can use several windows,
but two are automatically given:
\fIcurscr\fP, which knows what the terminal looks like,
and \fIstdscr\fP,
which is what the programmer wants the terminal to look like next.
The user should never really access \fIcurscr\fP directly.
Changes should be made to the appropriate screen,
and then the routine \fIrefresh()\fP (or \fIwrefresh()\fP)
should be called.
X.PP
Many functions are set up to deal with \fIstdscr\fP as a default screen.
XFor example, to add a character to \fIstdscr\fP,
one calls \fIaddch()\fP with the desired character.
If a different window is to be used, the routine \fIwaddch()\fP
(for `w'indow-specific \fIaddch()\fP) is provided.\u*\d
X.FS
\u*\dActually, \fIaddch()\fP is really a ``#define'' macro with arguments,
as are most of the ``functions'' which deal with \fIstdscr\fP
as a default.
X.FE
This convention of prepending function names with a ``w''
when they are to be applied to specific windows is consistent.
The only routines which do \fInot\fP do this are those
to which a window must always be specified.
X.PP
In order to move the current (y, x) coordinates from one point to another,
the routines \fImove()\fP and \fIwmove()\fP are provided.
However, it is often desirable to first move and then perform some I/O
operation.
In order to avoid clumsyness, most I/O routines can be preceded by the prefix
``mv'' and the desired (y, x) coordinates then can be added to the arguments
to the function.
XFor example, the calls
X.DS
move(y, x);
addch(ch);
X.DE
can be replaced by
X.DS
mvaddch(y, x, ch);
X.DE
and
X.DS
wmove(win, y, x);
waddch(win, ch);
X.DE
can be replaced by
X.DS
mvwaddch(win, y, x, ch);
X.DE
Note that the window description pointer (\fIwin\fP)
comes before the added (y, x) coordinates.
If such pointers are need, they are always the first parameters passed.
X.NH 1
Variables
X.PP
Many variables which are used to describe the terminal environment
are available to the programmer. They are:
X.TS
expand;
lw(6m) lw(8n) lw(50n).
type	name	description
_
WINDOW *	curscr	T{
X.fi
current version of the screen (terminal screen).
T}
WINDOW *	stdscr	T{
standard screen.  Most updates are usually done here.
T}
int	LINES	T{
number of lines on the terminal
T}
int	COLS	T{
number of columns on the terminal
T}
int	ERR	T{
error flag returned by routines on a fail.
T}
int	OK	T{
error flag returned by routines when things go right.
T}
X.TE
X.LP
There are also several ``#define'' constants and types
which are of general usefulness:
X.ta 11n
X.DS L
bool		boolean type, actually a ``char'' (e.g., \fIbool doneit;\fR\|)
TRUE		boolean ``true'' flag (1).
XFALSE		boolean ``false'' flag (0).
X.DE
X.NH 1
Usage
X.PP
This is a description of how to actually use the screen package.
In it, we assume all updating, reading, etc. is applied to
\fIstdscr\fP.
All instructions will work on any window,
with changing the function name and parameters as mentioned above.
X.NH 2
Starting up
X.PP
In order to use the screen package,
the routines must know about terminal characteristics, and the space for
\fIcurscr\fP and \fIstdscr\fP must be allocated.
These functions are performed by \fIinitscr()\fP.
Since it must allocate space for the windows,
it can overflow core when attempting to do so.
On this rather rare occasion, \fIinitscr()\fP
returns ERR.
\fIinitscr()\fP must \fIalways\fP
be called before any of the routines which affect windows are used.
If it is not, the program will core dump as soon as either
\fIcurscr\fP or \fIstdscr\fP are referenced.
However, it is usually best to wait to call it
until after you are sure you will need it,
like after checking for startup errors.
Terminal status changing routines like \fInl()\fP and \fIcbreak()\fP
should be called after \fIinitscr()\fP.
X.PP
Now that the screen windows have been allocated,
you can set them up for the run.
If you want to, say, allow the window to scroll, use \fIscrollok()\fP.
If you want the cursor to be left after the last change, use
\fIleaveok()\fP.
If this isn't done, \fIrefresh()\fP
will move the cursor to the window's current (y, x) coordinates
after updating it.
New windows of your own can be created, too, by using the functions
\fInewwin()\fP and \fIsubwin()\fP.
\fIdelwin()\fP will allow you to get rid of old windows.
X.NH 2
Output
X.PP
Now that we have set things up, we will want to actually update the terminal.
The basic functions used to change what will go on a window are \fIaddch()\fP
and \fImove()\fP.
\fIaddch()\fP adds a character at the current (y, x) coordinates,
returning ERR if it would cause the window to illegally scroll,
i.e., printing a character in the lower right-hand corner
of a terminal which automatically scrolls if scrolling is not allowed.
\fImove()\fP changes the current (y, x) coordinates to whatever you want
them to be.
It returns ERR if you try to move off the window.
As mentioned above, you can combine the two into \fImvaddch()\fP
to do both things at once.
X.PP
The other output functions, such as \fIaddstr()\fP
and \fIprintw()\fP, all call \fIaddch()\fP to add characters to the window.
X.PP
After you have put on the window what you want there,
when you want the portion of the terminal covered by the window
to be made to look like it, you must call \fIrefresh()\fP.
In order to optimize finding changes, \fIrefresh()\fP
assumes that any part of the window not changed since the last
\fIrefresh()\fP of that window has not been changed on the terminal, i.e.,
that you have not refreshed a portion of the terminal
with an overlapping window.
If this is not the case, the routine \fItouchwin()\fP
is provided to make it look like the entire window has been changed,
thus making \fIrefresh()\fP check the whole subsection of the terminal for
changes.
X.PP
If you call \fIwrefresh()\fP with \fIcurscr()\fP,
it will make the screen look like \fIcurscr\fP thinks it looks like.
This is useful for implementing a command
which would redraw the screen in case it get messed up.
X.NH 2
Input
X.PP
Input is essentially a mirror image of output.
The complementary function to \fIaddch()\fP is \fIgetch()\fP which,
if echo is set, will call \fIaddch()\fP to echo the character.
Since the screen package needs to know what is on the terminal at all times,
if characters are to be echoed, the tty must be in raw or cbreak mode.
If it is not, \fIgetch()\fP sets it to be cbreak, reads in the character,
and then sets it back the way it was.
X.NH 2
Miscellaneous
X.PP
A plethora of other functions exist for maintaining and changing information
about the windows.
XFor the most part, the descriptions in section 5 should suffice.
X.NH 2
XFinishing Up
X.PP
In order to do certain optimizations, and, on some terminals,
to work at all, some things must be done before the screen routines start up.
In order to clean up after the routines, the routine \fIendwin()\fP
is provided.
It restores tty modes to what they were when \fIinitscr()\fP
was first called, moves the cursor down to the lower-left corner, etc.
Thus, anytime after the call to initscr, \fIendwin()\fP
should be called before exiting.
X.NH
Descriptions of the Functions
X.de Lp
X.sp
X.LP
X..
X.LP
This section describes all the functions available to the
programmer in the curses package.  For an alphabetical list, see the
manual page \fIncurses\fP(3).
X.NH 2
Initialization
X.LP
These functions are called when initializing a program.
X.Lp
\fBinitscr\fP()
X.br
The first function called should always be \fBinitscr\fP.  This will
determine the terminal type and initialize curses data
structures.  \fBinitscr\fP also arranges that the first
call to \fBrefresh\fP will clear the screen.
X.Lp
\fBendwin\fP()
X.br
A program should always call \fBendwin\fP before exiting.  This
function will restore tty modes, move the cursor to the lower left
corner of the screen, reset the terminal into the proper
nonvisual mode.
X.Lp
\fBnewterm\fP(type, fp)
X.br
A program which outputs to more than one terminal should use
\fBnewterm\fP instead of \fBinitscr\fP.  \fBnewterm\fP should be called once for
each terminal.  It returns a variable of type \fBstruct\fP \fBscreen\fP \fB*\fP
which should be saved as a reference to that terminal.  The
arguments are the type of the terminal (a string) and a stdio FILE
pointer for output to the terminal.  The FILE pointer
should be open for both reading and writing, if input from the
terminal is desired.
The program should also call \fBendwin\fP for each terminal being used.
X.Lp
\fBset_term\fP(new)
X.br
This function is used to switch to a different terminal.  The
screen reference for the new terminal is passed as the parameter.
The previous terminal is returned by the function.  All other
calls affect only the current terminal.
X.Lp
\fBlongname\fP()
X.br
This function returns a pointer to a static area containing a
verbose description of the current terminal.  It is defined only
after a call to \fBinitscr\fP or \fBnewterm\fP.
X.NH 2
Option Setting
X.LP
These functions set options within curses.  In each case, \fIwin\fP is
the window affected, and \fIbf\fP is a boolean flag with value \fBTRUE\fP or
\fBFALSE\fP indicating whether to enable or disable the option.  All
options are initially \fBFALSE.\fP  It is not necessary to turn these
options off before calling \fBendwin\fP.
X.Lp
\fBclearok\fP(win,bf)
X.br
If set, the next call to \fBwrefresh\fP with this window will clear the
screen and redraw the entire screen.  If \fIwin\fP is \fBcurscr\fP, the next
call to \fIwrefresh\fP with any window will cause the screen to be
cleared.  This is useful when the contents of the screen are
uncertain, or in some cases for a more pleasing visual effect.
X.Lp
\fBidlok\fP(win,bf)
X.br
If enabled, curses will consider using the hardware insert/delete
line feature of terminals so equipped.  If disabled, curses will
never use this feature.  The insert/delete character feature is
always considered.  Enable this option only if your application
needs insert/delete line, for example, for a screen editor.  It
is disabled by default because insert/delete line is visually
annoying when used in applications where it isn't really needed.
X.Lp
\fBkeypad\fP(win,bf)
X.br
This option enables the keypad of the users terminal.  If
enabled, the user can press a function key (such as an arrow key)
and \fBgetch\fP will return a single value representing the function
key.  If disabled, curses will not treat function keys specially.
If the keypad in the terminal can be turned on (made to transmit)
and off (made to work locally), turning on this option will turn
on the terminal keypad.
X.Lp
\fBleaveok\fP(win,bf)
X.br
Normally, the hardware cursor is left at the location of the
window cursor being refreshed.  This option allows the cursor to be
left wherever the update happens to leave it.  It is useful for
applications where the cursor is not used, since it saves cursor
motions.  If possible, the cursor is made invisible when this
option is enabled.
X.Lp
\fBmeta\fP(win,bf)
X.br
If enabled, characters returned by \fBgetch\fP are transmitted with all
8 bits, instead of stripping the highest bit.  It is useful for
extending the non-text command set in applications where the
terminal has a meta shift key, such as EMACS.  \fINOTE\fP: This function
is currently unsupported, due to lack of support in current
teletype drivers for 8 bit input in non-raw mode.
X.Lp
\fBnodelay\fP(win,bf)
X.br
This option causes \fBgetch\fP to be a non-blocking call.  If no input
is ready, \fBgetch\fP will return -1.
If disabled, \fBgetch\fP will hang until a key is pressed.
X.Lp
\fBscrollok\fP(win,bf)
X.br
This option controls what happens when the cursor of a window is
moved off the edge of the window, either from a newline on the
bottom line, or typing the last character of the last line.  If
disabled, the cursor is left on the bottom line.  If enabled,
\fBwrefresh\fP is called on the window, and then the physical terminal
and window are scrolled up one line.
X.Lp
\fBsetscrreg\fP(t,b)
X.br
\fBwsetscrreg\fP(win,t,b)
X.br
These functions allow the user to set a software scrolling region
in a window \fIwin\fP or \fBstdscr\fP.
\fIt\fP and \fIb\fP are the line numbers of the
top and bottom margin of the scrolling region.  (Line 0 is the
top line of the screen.) If this option and \fBscrollok\fP are enabled,
an attempt to move off the bottom margin line will cause all
lines in the scrolling region to scroll up one line.  Note that
this has nothing to do with use of a physical scrolling region
capability in the terminal, like that in the VT100.  Only the
text of the window is scrolled.
X.LP
The scrolling region really acts as a sort of barrier, limiting the
area of a window over which changes take place.  For this reason, an
attempt to create a scrolling region in an area of the screen which
does not contain the current (y, x) coordinates for that window is an
error.
Similarly, attempts to move the (y, x) coordinates out of the region will
also fail with an ERR return.
X.LP
When a scrolling region is in place, all changes are limited to the region.
XFor example, \fIerase()\fP will only erase the area inside the region;
\fIinsertln()\fP will only shift lines down to the bottom of the region,
etc.  It is anticipated that this method of controlling the area of change
will prove quite handy in a number of applications.
X.LP
To disable the scrolling region, once defined, simply redefine it to be
the whole window.  For example, to disable the scrolling region on
\fIstdscr\fP, the following call would be used:
X.DS
\fBsetscrreg(0, LINES - 1)\fP
X.DE
XFor other windows, the height of the window should be used instead of
(LINES - 1).
X.NH 2
Terminal Mode Setting
X.LP
These functions are used to set modes in the tty driver.  The
initial mode usually depends on the setting when the program was
called: the initial modes documented here represenet the normal
situation.
X.Lp
\fBcbreak\fP()
X.br
\fBnocbreak\fP()
X.br
\fBcrmode\fP()
X.br
\fBnocrmode\fP()
X.br
These functions put the terminal into and out of \fBCBREAK\fP mode.
In this mode, characters typed by the user are immediately
available to the program.  When out of this mode, the teletype driver
will buffer characters typed until newline is typed.  Interrupt
and flow control characters are unaffected by this mode. 
Initially the terminal is not in \fBCBREAK\fP mode.  Most interactive
programs using curses will set this mode.
X.LP
The functions \fBcrmode\fP() and \fBnocrmode\fP() are the result of an
accident in the first version of curses and are retained solely for
upward compatibility.  \fBcrmode\fP() is the same as \fBcbreak\fP() and
\fBnocrmode\fP() is the same as \fBnocbreak\fP().
X.Lp
\fBraw\fP()
X.br
\fBnoraw\fP()
X.br
These functions put the terminal into and out of \fBRAW\fP mode.
\fBRAW\fP mode is just like \fBCBREAK\fP mode except that \fIno\fP
special character processing is done (e.g. the interrupt character will
be passed through to the program, uninterpreted, as will the kill
character, etc.) and all 8 bits of the input character are retained;
in \fBCBREAK\fP mode, the eighth bit is stripped off before it is
given to the program.  Because of the lack of interpretation of
special characters, it is not recommended that programs use this
mode.
X.Lp
\fBecho\fP()
X.br
\fBnoecho\fP()
X.br
These functions control whether characters typed by the user are
echoed as typed.  Initially, characters typed are echoed by the
teletype driver.  Authors of most interactive programs prefer to
do their own echoing in a controlled area of the screen, or not
to echo at all, so they disable echoing.
X.Lp
\fBnl\fP()
X.br
\fBnonl\fP()
X.br
These functions control whether newline is translated into
carriage return and linefeed on output, and whether return is
translated into newline on input.  Initially, the translations do
occur.  By disabling these translations, curses is able to make
better use of the linefeed capability, resulting in faster cursor
motion.
X.Lp
\fBresetty\fP()
X.br
\fBsavetty\fP()
X.br
These functions save and restore the state of the tty modes.
\fBsavetty\fP saves the current state in a buffer, \fBresetty\fP restores the
state to what it was at the last call to \fBsavetty\fP.
X.NH 2
Window Manipulation
X.LP
\fBnewwin\fP(num_lines, num_cols, begy, begx)
X.br
Create a new window with the given number of lines and columns.
The upper left corner of the window is at line \fBbegy\fP column \fBbegx\fP.
If either \fInum_lines\fP or \fInum_cols\fP is zero,
they will be defaulted
to \fBLINES\fP-\fIbegy\fP and \fBCOLS\fP-\fIbegx\fP.
A new full-screen window is
created by calling \fBnewwin\fP(0,0,0,0).
X.Lp
\fBsubwin\fP(orig, num_lines, num_cols, begy, begx)
X.br
Create a new window with the given number of lines and columns.
The window is at position (\fIbegy\fP, \fIbegx\fP) on the screen.  (It is
relative to the screen, not \fIorig\fP.) The window is made in the
middle of the window \fIorig\fP, so that changes made to one window
will affect both windows.  When using this function, often it
will be necessary to call \fItouchwin\fP before calling \fIwrefresh\fP.
X.Lp
\fBdelwin\fP(win)
X.br
Deletes the named window, freeing up all memory associated with
it.  In the case of sub-windows, they should be deleted before the main
window.
X.Lp
\fBmvwin\fP(win, by, bx)
X.br
Move the window so that the upper left corner will be at position
(\fIby\fP, \fIbx\fP).  If the move would cause the window to be off the
screen, it is an error and the window is not moved.
X.Lp
\fBtouchwin\fP(win)
X.br
Throw away all optimization information about which parts of the
window have been touched, by pretending the entire window has
been drawn on.  This is sometimes necessary when using
overlapping windows, since a change to one window will affect the other
window, but the optimization records of the other window will not
reflect the change.
X.Lp
\fBoverlay\fP(win1, win2)
X.br
\fBoverwrite\fP(win1, win2)
X.br
These functions overlay \fIwin1\fP on top of \fIwin2\fP, that is, all text in
\fIwin1\fP is copied into \fIwin2\fP, after lining up the two windows'
origins.
The difference between the functions is that \fBoverlay\fP is
nondestructive (blanks are not copied) while \fBoverwrite\fP is
destructive.
X.NH 2
Causing Output to the Terminal
X.LP
\fBrefresh\fP()
X.br
\fBwrefresh\fP(win)
X.br
These functions must be called to actually get any output on the
terminal, as other routines merely manipulate data structures.
\fBwrefresh\fP copies the named window to the physical terminal screen,
taking into account what is already there in order to do
optimizations.
\fBrefresh\fP is the same, using \fBstdscr\fP as a default screen.
Unless \fBleaveok\fP has been enabled, the physical cursor of the
terminal is left at the location of the window's cursor.
X.Lp
\fBdoupdate\fP()
X.br
\fBwnoutrefresh\fP(win)
X.br
These two functions allow multiple updates with more efficiency
than \fBwrefresh.\fP  To use them, it is important to understand how
curses works.  In addition to all the window structures, curses
keeps two data structures representing the terminal screen: a
\fIphysical\fP screen, describing what is actually on the screen, and a
\fIvirtual\fP screen, describing what the programmer \fIwants\fP to have on
the screen.  \fBwrefresh\fP works by first copying the named window to
the virtual screen (\fBwnoutrefresh\fP), and then calling the routine
to update the screen (\fBdoupdate\fP).  If the programmer wishes to
output several windows at once, a series of calls to \fBwrefresh\fP
will result in alternating calls to \fBwnoutrefresh\fP and \fBdoupdate\fP,
causing several bursts of output to the screen.  By calling
\fBwnoutrefresh\fP for each window, it is then possible to call
\fBdoupdate\fP once, resulting in only one burst of output, with probably
fewer total characters transmitted.
X.NH 2
Writing on Window Structures
X.LP
These routines are used to ``draw'' text on windows.  In all
cases, a missing \fIwin\fP is taken to be \fBstdscr\fP.
\fIy\fP and \fIx\fP are the row
and column, respectively.  The upper left corner is always (0, 0) not (1, 1).
The \fBmv\fP functions imply a call to \fBmove\fP before the call to the
other function.
X.NH 3
Moving the Cursor
X.LP
\fBmove\fP(y, x)
X.br
\fBwmove\fP(win, y, x)
X.br
The cursor associated with the window is moved to the given
location.  This does not move the physical cursor of the terminal
until \fBrefresh\fP is called.
X.NH 3
Writing One Character
X.LP
\fBaddch\fP(ch)
X.br
\fBwaddch\fP(win, ch)
X.br
\fBmvaddch\fP(y, x, ch)
X.br
\fBmvwaddch\fP(win, y, x, ch)
X.br
The character \fIch\fP is put in the window at the current cursor
position of the window.  If \fIch\fP is a tab, newline, or backspace, the
cursor will be moved appropriately in the window.  If \fIch\fP is a
different control character, it will be drawn in the ^X notation.
The position of the window cursor is advanced.  At the right
margin, an automatic newline is performed.  At the bottom of the
scrolling region, if \fBscrollok\fP is enabled, the scrolling region
will be scrolled up one line.
X.NH 3
Writing a String
X.LP
\fBaddstr\fP(str)
X.br
\fBwaddstr\fP(win,str)
X.br
\fBmvaddstr\fP(y,x,str)
X.br
\fBmvwaddstr\fP(win,y,x,str)
X.br
These functions write all the characters of the null terminated
character string \fIstr\fP on the given window.  They are identical to
a series of calls to \fBaddch\fP.
X.NH 3
Clearing Areas of the Screen
X.LP
\fBerase\fP()
X.br
\fBwerase\fP(win)
X.br
These functions copy blanks to every position in the window.
X.Lp
\fBclear\fP()
X.br
\fBwclear\fP(win)
X.br
These functions are like \fBerase\fP and \fBwerase\fP but they also call
\fBclearok\fP, arranging that the screen will be cleared on the next
\fBrefresh\fP.
X.Lp
\fBclrtobot\fP()
X.br
\fBwclrtobot\fP(win)
X.br
All lines below the cursor in this window are erased.  Also, the
current line to the right of the cursor is erased.
X.Lp
\fBclrtoeol\fP()
X.br
\fBwclrtoeol\fP(win)
X.br
The current line to the right of the cursor is erased.
X.NH 3
Inserting and Deleting Text
X.LP
\fBdelch\fP()
X.br
\fBwdelch\fP(win)
X.br
\fBmvdelch\fP(y,x)
X.br
\fBmvwdelch\fP(win,y,x)
X.br
The character under the cursor in the window is deleted.  All
characters to the right on the same line are moved to the left
one position.  This does not imply use of the hardware delete
character feature.
X.Lp
\fBdeleteln\fP()
X.br
\fBwdeleteln\fP(win)
X.br
The line under the cursor in the window is deleted.  All lines
below the current line are moved up one line.  The bottom line of
the window is cleared.  This does not imply use of the hardware
delete line feature.
X.Lp
\fBinsch\fP(c)
X.br
\fBwinsch\fP(win, c)
X.br
\fBmvinsch\fP(y,x,c)
X.br
\fBmvwinsch\fP(win,y,x,c)
X.br
The character \fIc\fP is inserted before the character under the
cursor.  All characters to the right are moved one space to the
right, possibly losing the rightmost character on the line.  This
does not imply use of the hardware insert character feature.
X.Lp
\fBinsertln\fP()
X.br
\fBwinsertln\fP(win)
X.br
A blank line is inserted above the current line.  The bottom line
is lost.  This does not imply use of the hardware insert line
feature.
X.NH 3
XFormatted Output
X.LP
\fBprintw\fP(fmt, args)
X.br
\fBwprintw\fP(win, fmt, args)
X.br
\fBmvprintw\fP(y, x, fmt, args)
X.br
\fBmvwprintw\fP(win, y, x, fmt, args)
X.br
These functions correspond to \fIprintf\fP.  The characters which would
be output by \fIprintf\fP are instead output using \fIwaddch\fP on the given
window.
X.NH 3
Miscelaneous
X.LP
\fBbox\fP(win, vert, hor)
X.br
A box is drawn around the edge of the window.  \fIvert\fP and \fIhor\fP are
the characters the box is to be drawn with.
X.Lp
\fBscroll\fP(win)
X.br
The window is scrolled up one line.  This involves moving the
lines in the window data structure.
X.NH 2
Querying the Contents of a Window
X.LP
\fBgetyx\fP(win,y,x)
X.br
The cursor position of the window is placed in the two integer
variables \fIy\fP and \fIx\fP.  Since this is a macro, no & is necessary.
X.Lp
\fBinch\fP()
X.br
\fBwinch\fP(win)
X.br
\fBmvinch\fP(y,x)
X.br
\fBmvwinch\fP(win,y,x)
X.br
The character at the current position in the named window is
returned.
X.NH 2
Input from the Terminal
X.LP
\fBgetch\fP()
X.br
\fBwgetch\fP(win)
X.br
\fBmvgetch\fP(y,x)
X.br
\fBmvwgetch\fP(win,y,x)
X.br
A character is read from the terminal associated with the window.
In nodelay mode, if there is no input waiting, the value -1 is
returned.  In delay mode, the program will hang until a character is typed.
X.Lp
If \fIkeypad\fP mode is enabled, and a function key is pressed, the
code for that function key will be returned instead of the raw
characters.  Possible function keys are defined with integers
beginning with 0401, whose names begin with KEY_, defined in
<ncurses.h>.  If a character is received that could be the
beginning of a function key (such as escape), curses will set a one
second timer.  If the remainder of the sequence does not come in
within one second, the character will be passed through,
otherwise the function key value will be returned.  For this reason,
on many terminals, there will be a one second delay after a user
presses the escape key.  (Use by a programmer of the escape key
for a single character function is discouraged.)
X.Lp
\fBgetstr\fP(str)
X.br
\fBwgetstr\fP(win,str)
X.br
\fBmvgetstr\fP(y,x,str)
X.br
\fBmvwgetstr\fP(win,y,x,str)
X.br
A series of calls to \fIgetch\fP is made, until a newline is received.
The resulting value is placed in the area pointed at by the
character pointer \fIstr\fP.  The users erase and kill characters are
interpreted, and the string is echoed.
X.Lp
\fBscanw\fP(fmt, args)
X.br
\fBwscanw\fP(win, fmt, args)
X.br
\fBmvscanw\fP(y, x, fmt, args)
X.br
\fBmvwscanw\fP(win, y, x, fmt, args)
X.br
This function corresponds to \fIscanf\fP.  \fIwgetstr\fP is called on the
window, and the resulting line is used as input for the scan.
X.NH 2
Video Attributes
X.LP
\fBattroff\fP(at)
X.br
\fBwattroff\fP(win, attrs)
X.br
\fBattron\fP(at)
X.br
\fBwattron\fP(win, attrs)
X.br
\fBattrset\fP(at)
X.br
\fBwattrset\fP(win, attrs)
X.br
\fBstandout\fP()
X.br
\fBstandend\fP()
X.br
\fBwstandout\fP(win)
X.br
\fBwstandend\fP(win)
X.br
These functions set the \fIcurrent\fP \fIattributes\fP of the named window.
These attributes can be any combination of \fBA_STANDOUT\fP, \fBA_REVERSE\fP,
\fBA_BOLD\fP, \fBA_DIM\fP, \fBA_BLINK\fP, \fBA_BLANK\fP, \fBA_UNDERLINE\fP,
\fBA_PROTECT\fP, and \fBA_ALTCHARSET\fP.
These constants are defined in <ncurses.h> and can
be combined with the C | (or) operator.
X.LP
The current attributes of a window are applied to all characters
that are written into the window.  Attributes are a
property of the character, and move with the character through
any scrolling and insert/delete line/character operations.  To
the extent possible on the particular terminal, they will be
displayed as the graphic rendition of characters put on the
screen.
X.LP
\fIattrset\fP(at) sets the current attributes of the given window to
\fIat\fP.  \fIattroff\fP(at) turns off the named attributes without affecting
any other attributes.  \fIattron\fP(at) turns on the named attributes
without affecting any others.  \fIstandout\fP is the same as
\fIattrset\fP(A_STANDOUT) \fIstandend\fP is the same as \fIattrset\fP(0),
that is, it turns off all attributes.
X.NH 2
Bells and Flashing Lights
X.LP
\fBbeep\fP()
X.br
\fBflash\fP()
X.br
These functions are used to signal the programmer.  \fIbeep\fP will
sound the audible alarm on the terminal, if possible, and if not,
will flash the screen (visible bell), if that is possible.  \fIflash\fP
will flash the screen, and if that is not possible, will sound
the audible signal.  If neither signal is possible, nothing will
happen.  Nearly all terminals have an audible signal (bell or
beep) but only some can flash the screen.
X.NH 2
Portability Functions
X.LP
These functions do not have anything to do with terminal
dependent character output, but tend to be needed by programs that use
curses.  Unfortunately, their implemention varies from one
version of UNIX\u*\d to another.  They have been included here to
enhance the portability of programs using curses.
X.FS
\u*\d UNIX is a trademark of Bell Laboratories.
X.FE
X.Lp
\fBbaudrate\fP()
X.br
\fIbaudrate\fP returns the output speed of the terminal.  The number
returned is the integer baud rate, for example, 9600, rather than
a table index such as \fBB9600\fP.
X.Lp
\fBerasechar\fP()
X.br
The erase character chosen by the user is returned.  This is the
character typed by the user to erase the character just typed.
X.Lp
\fBkillchar\fP()
X.br
The line kill character chosen by the user is returned.  This is
the character typed by the user to forget the entire line being
typed.
X.Lp
\fBflushinp\fP()
X.br
\fIflushinp\fP throws away any typeahead that has been typed by the
user and has not yet been read by the program.
X.NH 2
Debugging
X.LP
These functions are useful when debugging a program with curses.
X.Lp
\fBunctrl\fP(ch)
X.br
This macro expands to a character string which is a printable
representation of the character \fIch\fP.  The program must include the
file <unctrl.h>.  Control characters are displayed in the ^x
notation.  Printing characters are displayed as is.
X.Lp
\fBtraceoff\fP()
X.br
\fBtraceon\fP()
X.br
It is possible to compile a debugging version of curses with
tracing turned on, and with the -g option for sdb.  This library
may be available on your system as -ldcurses.  When using this
version, the file ``trace'' will be created each time the program
is run, containing verbose information showing each step done by
curses.  This output is useful for finding bugs in curses, and
may be useful for finding bugs in user programs.  Since the
output is so verbose, with any bug that cannot be easily and quickly
reproduced, it may be necessary to turn the debugging output off
in some parts of the program.  These functions can be used to
turn tracing off and back on.  When \fIinitscr\fP is first called,
tracing is automatically turned on.
X.NH 2
Lower Level Functions
X.LP
These functions are provided for programs not needing the screen
optimization capabilities of curses.  Programs are discouraged
from working at this level, since they must handle various
glitches in certain terminals.  However, a program can be smaller
if it only brings in the low level routines.
X.NH 3
Cursor Motion
X.Lp
\fBgettmode\fP()
X.br
\fBsetterm\fP(type)
X.br
These two initialization routines are provided for upward
compatibility with the old curses.  \fIgettmode\fP does nothing.
\fIsetterm\fP
results in a call to \fIsetupterm\fP with appropriate arguments.
X.Lp
\fBmvcur\fP(oldrow, oldcol, newrow, newcol)
X.br
This routine optimally moves the cursor from (oldrow, oldcol) to
(newrow, newcol).  The user program is expected to keep track of
the current cursor position.  Note that unless a full screen
image is kept, curses will have to make pessimistic assumptions,
sometimes resulting in less than optimal cursor motion.  For
example, moving the cursor a few spaces to the right can be done
by transmitting the characters being moved over, but if curses
does not have access to the screen image, it doesn't know what
these characters are.
X.LP
If either of oldcol or oldrow are negative, \fImvcur()\fP will refrain
from using any relative motions.  This is handy for occasions when
a program is unsure as to the current cursor location.
X.NH 3
Terminfo Level
X.LP
These routines are called by low level
programs that need access to specific capabilities of terminfo.
A program working at this level should include both <ncurses.h>
and <term.h>.  After a call to \fIsetupterm\fP, the
capabilities will be available with macro names defined in
<term.h>.  See \fBterminfo\fP(5) for a detailed description of the
capabilies.  If the program only needs to handle one terminal,
the definition \fB-DSINGLE\fP can be passed to the C compiler,
resulting in static references to capabilities instead of dynamic
references.  This can result in smaller code, but prevents use of
more than one terminal at a time.  Very few programs use more
than one terminal, so almost all programs can use this flag.
X.Lp
\fBsetupterm\fP(term, filenum, errret)
X.br
This routine is called to initialize a terminal.  \fIterm\fP is the
character string representing the name of the terminal being
used.  \fIfilenum\fP is the UNIX file descriptor of the terminal being
used for output.  \fIerrret\fP is a pointer to an integer, in which a
success or failure indication is returned.  The values returned
can be 1 (all is well), 0 (no such terminal), or -1 (some problem
locating the terminfo database).
X.LP
The value of \fIterm\fP can be given as 0, which will cause the value
of TERM in the environment to be used.  The \fIerrret\fP pointer can
also be given as 0, meaning no error code is wanted.  If \fIerrret\fP
is defaulted, and something goes wrong, \fIsetupterm\fP will print an
appropriate error message and exit, rather than returning.  Thus,
a simple program can call \fIsetupterm\fP(0, 1, 0) and not worry about
initialization errors.
X.LP
\fIsetupterm\fP will check the tty driver mode bits, and change any
that might prevent the correct operation of other low level
routines.  Currently, the mode that expands tabs into spaces is
disabled, because the tab character is sometimes used for different
functions by different terminals.  (Some terminals use it to move
right one space.  Others use it to address the cursor to row or
column 9.) If the system is expanding tabs, \fIsetupterm\fP will remove
the definition of the \fBtab\fP and \fBbacktab\fP functions, assuming that
since the user is not using hardware tabs, they may not be
properly set in the terminal.
X.LP
After the call to \fIsetupterm\fP, the global variable \fIcur_term\fP is set
to point to the current structure of terminal capabilities.  By
calling \fIsetupterm\fP for each terminal, and saving and restoring
\fIcur_term\fP, it is possible for a program to use two or more
terminals at once.  \fISetupterm\fP also stores the names section of the
terminal description in the global character array \fIttytype[]\fP.
Subsequent calls to \fIsetupterm\fP will overwrite this array, so you'll
have to save it yourself if need be.
X.LP
The mode that turns newlines into CRLF on output is not disabled.
Programs that use \fBcud1\fP or \fBind\fP should avoid these capabilities if
their value is linefeed unless they disable this mode.  \fIsetupterm\fP
calls \fIfixterm\fP after any changes it makes.
X.Lp
\fBfixterm\fP()
X.br
\fBresetterm\fP()
X.br
\fBsaveterm\fP()
X.br
These routines can be used to change the tty modes between the
two states: \fInormal\fP (the mode they were in before the program was
started) and \fIprogram\fP (the mode needed by the program).  \fIfixterm\fP
puts the terminal into program mode, and \fIresetterm\fP puts the
terminal into normal mode.  These functions are useful for shell
escapes and control-Z suspensions.  In addition, all programs
must call \fIresetterm\fP before they exit.
X.LP
The routine \fBsaveterm\fP saves the current state of the tty modes
so that the next time \fBfixterm\fP is called, the same modes will be
used.  This is useful for programs which use some of the functions
described in section 2.3 to tailor the modes.
X.LP
Normal mode is stored in \fIcur_term\fP->\fIOttyb\fP, and program mode is in
\fIcur_term\fP->\fINttyb\fP.  These structures are both of type SGTTYB (which
varies depending on the system).  Currently the only possible type
is \fBstruct\fP \fBsgttyb\fP.
X.Lp
\fBvidattr\fP(newmode)
X.br
\fBvidputs\fP(newmode, outc)
X.br
\fInewmode\fP is any combination of attributes, defined in <ncurses.h>.
The proper string to put the terminal in the given video mode is
output. The routine \fBvidattr\fP() sends the output characters to
\fBputchar\fP; \fBvidputs\fP sends them to the given routine \fIoutc\fP,
one character at a time.  That routine should therefore expect one
\fBchar\fP parameter.
The previous mode is remembered by this routine.
X.Lp
\fBtparm\fP(instring, p1, p2, p3, p4, p5, p6, p7, p8, p9)
X.br
\fItparm\fP is used to instantiate a parameterized string.  The
character string returned is suitable for \fItputs\fP.  Up to 9
parameters can be passed, in addition to the parameterized string.
X.Lp
\fBtputs\fP(cp, affcnt, outc)
X.br
A string capability, possibly containing padding information, is
processed.  Enough padding characters to delay for the specified
time replace the padding specification, and the resulting string
is passed, one character at a time, to the routine \fIoutc\fP, which
should expect one character parameter.  (This routine often just
calls \fIputchar\fP.) \fIcp\fP is the capability string.  \fIaffcnt\fP is the
number of units affected by the capability, which varies with the
particular capability.  (For example, the \fIaffcnt\fP for \fIinsert_line\fP
is the number of lines below the inserted line on the screen,
that is, the number of lines that will have to be moved by the
terminal.) \fIaffcnt\fP is used by the padding information of some
terminals as a multiplication factor.  If the capability does not
have a factor, the value 1 should be passed.
X.Lp
\fBputp\fP(str)
X.br
This is a convenient function to output a capability with no
\fIaffcnt\fP.
The string is output to \fIputchar\fP with an \fIaffcnt\fP of 1.
It can be used in simple applications that do not need to process
the output of \fItputs\fP.
//go.sysin dd *
echo 'x - =doc/ncurses.3'
sed 's/^X//' <<'//go.sysin dd *' >=doc/ncurses.3
X.TH NCURSES 3
X.UC 4
X.SH NAME
ncurses \- terminal-independent screen management package
X.SH SYNOPSIS
#include <ncurses.h>
X.sp
X.B cc
[ flags ] files
X.B \-lncurses
[ libraries ]
X.SH DESCRIPTION
These routines give the user a method
of updating screens with reasonable optimization and terminal independence.
They keep an image of the current screen,
and the user sets up an image of a new one.
Then the
X.I refresh()
call tells the routines to make the current screen look
like the new one.
In order to initialize the routines,
the routine
X.I initscr()
must be called before any of the other routines
that deal with windows and screens
are used.
The routine
X.I endwin()
should be called before exiting.
X.SH SEE ALSO
X.I "The Curses Reference Manual",
Curtis
X.br
terminfo(5)
X.SH AUTHOR
Pavel Curtis
X.SH FUNCTIONS
X.nf
X.ds w \fIwin\fR
X.ds s \fIstdscr\fR
X.ta 3i
addch(ch)	add a character to \*s
addstr(str)	add a string to \*s
attroff(at)	turn off video attributes on \*s
attron(at)	turn on video attributes on \*s
attrset(at)	set video attributes on \*s
baudrate()	return baudrate of current terminal
beep()	sound audible bell
box(win,vert,hor)	draw a box around a window
cbreak()	set cbreak mode
crmode()	set cbreak mode
clear()	clear \*s
clearok(scr,boolf)	set clear flag for \fIscr\fR
clrtobot()	clear to bottom on \*s
clrtoeol()	clear to end of line on \*s
delch()	delete a character
deleteln()	delete a line
delwin(win)	delete \*w
doupdate()	update the physical screen
echo()	set echo mode
endwin()	end window modes
erase()	erase \*s
erasechar()	return erase character of current terminal
fixterm()	set terminal into program mode
flash()	execute visible bell
flushinp()	flush outstanding input on current terminal
getch()	get a char through \*s
getcap(name)	get terminal capability \fIname\fR
getstr(str)	get a string through \*s
gettmode()	no-op
getyx(win,y,x)	get (y,x) coordinates
idlok(win,flag)	enable insert/delete lines operations
inch()	get char at current (y,x) coordinates
initscr()	initialize screens
insch(c)	insert a char
insertln()	insert a line
keypad(win,flag)	enable keypad-sequence mapping
killchar()	return kill character of current terminal
leaveok(win,boolf)	set leave flag for \*w
longname(termbuf,name)	get long name from \fItermbuf\fR
meta(win,flag)	enable use of the `meta' key
move(y,x)	move to (y,x) on \*s
mvcur(lasty,lastx,newy,newx)	actually move cursor
newterm(type,fp)	initialise a new terminal
newwin(lines,cols,begin_y,begin_x)\ 	create a new window
nl()	set newline mapping
nocbreak()	unset cbreak mode
nocrmode()	unset cbreak mode
nodelay(win,flag)	make getch() non-blocking
noecho()	unset echo mode
nonl()	unset newline mapping
noraw()	unset raw mode
overlay(win1,win2)	overlay win1 on win2
overwrite(win1,win2)	overwrite win1 on top of win2
printw(fmt,arg1,arg2,...)	printf on \*s
putp(string)	tputs() with affcnt=1 and outc=putchar
raw()	set raw mode
refresh()	make current screen look like \*s
resetterm()	set terminal into normal mode
resetty()	reset tty flags to stored value
savetty()	store current tty flags
saveterm()	save current state of tty
scanw(fmt,arg1,arg2,...)	scanf through \*s
scroll(win)	scroll \*w one line
scrollok(win,boolf)	set scroll flag
setscrreg(top,bottom)	set up scrolling region on \*s
setterm(name)	set term variables for name
set_term(new)	change current terminal
setupterm(term,fd,errret)	initialise terminal capabilities
standend()	end standout mode
standout()	start standout mode
subwin(win,lines,cols,begin_y,begin_x)\ 	create a subwindow
touchwin(win)	\*(lqchange\*(rq all of \*w
tparm(string,p1..p9)	instantiate a parameterised string
tputs(string,affcnt,outc)	process a capability string
traceoff()	turn off debugging output
traceon()	turn on debugging output
unctrl(ch)	printable version of \fIch\fR
vidattr(newmode)	set terminal's video attributes
vidputs(newmode,outc)	set video attributes into a function
waddch(win,ch)	add char to \*w
waddstr(win,str)	add string to \*w
wattroff(win,at)	turn off video attributes on \*w
wattron(win,at)	turn on video attributes on \*w
wattrset(win,at)	set video attributes on \*w
wclear(win)	clear \*w
wclrtobot(win)	clear to bottom of \*w
wclrtoeol(win)	clear to end of line on \*w
wdelch(win,c)	delete char from \*w
wdeleteln(win)	delete line from \*w
werase(win)	erase \*w
wgetch(win)	get a char through \*w
wgetstr(win,str)	get a string through \*w
winch(win)	get char at current (y,x) in \*w
winsch(win,c)	insert char into \*w
winsertln(win)	insert line into \*w
wmove(win,y,x)	set current (y,x) co-ordinates on \*w
wnoutrefresh(win)	copy \*w to virtual screen
wprintw(win,fmt,arg1,arg2,...)\ 	printf on \*w
wrefresh(win)	make screen look like \*w
wscanw(win,fmt,arg1,arg2,...)\ 	scanf through \*w
wsetscrreg(win,top,bottom)	set up scrolling region on \*w
wstandend(win)	end standout mode on \*w
wstandout(win)	start standout mode on \*w
//go.sysin dd *
exit

sources@genrad.UUCP (12/17/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit".  This code is completely public domain, originally written by Pavel
Curtis of Cornell University.  This version has some small improvements and
bug fixes.

This unit contains:

	doc/term.5		- compiled terminfo data format
	doc/terminfo.5		- terminfo data base documentation

Part 4 will be the first installment of the sources - the terminfo data
  compiler.

----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =doc
then
    echo 'Making directory "=doc"'
    mkdir =doc
fi
echo 'x - =doc/term.5'
sed 's/^X//' <<'//go.sysin dd *' >=doc/term.5
X.TH TERM 5
X.SH NAME
term \- format of compiled term file.
X.SH SYNOPSIS
X.B term
X.SH DESCRIPTION
X.PP
Compiled terminfo descriptions are placed under the directory /etc/term.
In order to avoid a linear search of a huge UNIX directory, a two
level scheme is used: /etc/term/c/name
where
X.B name
is the name of the terminal, and
X.B c
is the first character of
X.BR name .
Thus,
X.B act4
can be found in the file ``/etc/term/a/act4''.
Synonyms for the same terminal are implemented by multiple
links to the same compiled file.
X.PP
The format has been chosen so that it will be the same on all hardware.
An 8 or more bit byte is assumed, but no assumptions about byte ordering
or sign extension are made.
X.PP
The compiled file is created with the
X.I compile
program, and read by the routine
X.IR setupterm .
Both of these pieces of software are part of
X.IR curses (3).
The file is divided into six parts:
the header,
terminal names,
boolean flags,
numbers,
strings,
and
string table.
X.PP
The header section begins the file.
This section contains six short integers in the format
described below.
These integers are
(1) the magic number (octal 0432);
(2) the size, in bytes, of the names section;
(3) the number of bytes in the boolean section;
(4) the number of short integers in the numbers section;
(5) the number of offsets (short integers) in the strings section;
(6) the size, in bytes, of the string table.
X.PP
Short integers are stored in two 8 bit bytes.
The first byte contains the least significant 8 bits of the value,
and the second byte contains the most significant 8 bits.
(Thus, the value represented is 256*second+first.)
The value \-1 is represented by 0377, 0377, other negative
value are illegal.
\-1 generally means that a capability is missing from this terminal.
Note that this format corresponds to the hardware of the VAX and PDP-11.
Machines where this does not correspond to the hardware read the
integers as two bytes and compute the result.
X.PP
The terminal names section comes next.
It contains the first line of the terminfo description,
listing the various names for the terminal,
separated by the `|' character.
The section is terminated with an ASCII NUL character.
X.PP
The boolean flags have one byte for each flag.
This byte is either 0 or 1 as the flag is present or absent.
The capabilities are in the same order as the file <term.h>.
X.PP
Between the boolean section and the number section,
a null byte will be inserted, if necessary,
to ensure that the number section begins on an even byte.
All short integers are aligned on a short word boundary.
X.PP
The numbers section is similar to the flags section.
Each capability takes up two bytes,
and is stored as a short integer.
If the value represented is \-1, the capability is taken to be missing.
X.PP
The strings section is also similar.
Each capability is stored as a short integer, in the format above.
A value of \-1 means the capability is missing.
Otherwise, the value is taken as an offset from the beginning
of the string table.
Special characters in ^X or \ec notation are stored in their
interpreted form, not the printing representation.
Padding information $<nn> and parameter information %x are
stored intact in uninterpreted form.
X.PP
The final section is the string table.
It contains all the values of string capabilities referenced in
the string section.
Each string is null terminated.
X.PP
Note that it is possible for
X.I setupterm
to expect a different set of capabilities
than are actually present in the file.
Either the database may have been updated since
X.I setupterm
has been recompiled
(resulting in extra unrecognized entries in the file)
or the program may have been recompiled more recently
than the database was updated
(resulting in missing entries).
X.I setupterm
must be prepared for both possibilities \-
this is why the numbers and sizes are included.
Also, new capabilities must always be added at the end of the lists
of boolean, number, and string capabilities.
X.PP
As an example, an octal dump of the description for the Microterm ACT 4
is included:
X.nf
X.sp
microterm|act4|microterm act iv,
    cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H,
    ed=^_, el=^^, clear=^L, cup=^T%p1%c%p2%c,
    cols#80, lines#24, cuf1=^X, cuu1=^Z, home=^],
X.sp
X.in 0
X.ft CW
000 032 001      \e0 025  \e0  \eb  \e0 212  \e0   "  \e0   m   i   c   r
020   o   t   e   r   m   |   a   c   t   4   |   m   i   c   r   o
040   t   e   r   m       a   c   t       i   v  \e0  \e0 001  \e0  \e0
060  \e0  \e0  \e0  \e0  \e0  \e0  \e0  \e0  \e0  \e0  \e0  \e0  \e0  \e0  \e0  \e0
100  \e0  \e0   P  \e0 377 377 030  \e0 377 377 377 377 377 377 377 377
120 377 377 377 377  \e0  \e0 002  \e0 377 377 377 377 004  \e0 006  \e0
140  \eb  \e0 377 377 377 377  \en  \e0 026  \e0 030  \e0 377 377 032  \e0
160 377 377 377 377 034  \e0 377 377 036  \e0 377 377 377 377 377 377
200 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377
*
520 377 377 377 377      \e0 377 377 377 377 377 377 377 377 377 377
540 377 377 377 377 377 377 007  \e0  \er  \e0  \ef  \e0 036  \e0 037  \e0
560 024   %   p   1   %   c   %   p   2   %   c  \e0  \en  \e0 035  \e0
600  \eb  \e0 030  \e0 032  \e0  \en  \e0
X.ft R
X.fi
X.PP
Some limitations: total compiled entries cannot exceed 4096 bytes.
The name field cannot exceed 128 bytes.
X.SH FILES
X/etc/term/*/*	compiled terminal capability data base
X.SH "SEE ALSO"
terminfo(5), curses(3)
//go.sysin dd *
echo 'x - =doc/terminfo.5'
sed 's/^X//' <<'//go.sysin dd *' >=doc/terminfo.5
X.tr ||
X.TH TERMINFO 5 8/16/82
X.UC 4
X.SH NAME
terminfo \- terminal capability data base
X.SH SYNOPSIS
X/etc/terminfo
X.SH DESCRIPTION
X.I Terminfo
is a data base describing terminals.
It is used, for example, by
X.IR vi (1)
and
X.IR curses (3).
Terminals are described in
X.I terminfo
by giving a set of capabilities which they have and by describing
how operations are performed.
Padding requirements and initialization sequences
are included in
X.I terminfo.
X.PP
Entries in
X.I terminfo
consist of a number of comma-separated fields.
White space after each comma is ignored.
The first entry for each terminal gives the names which are known for the
terminal, separated by `|' characters.
The first name given is the most common abbreviation for the terminal,
the last name given should be a long name fully identifying the terminal,
and all others are understood as synonyms for the terminal name.
All names but the last should be in lower case and contain no blanks;
the last name may well contain upper case and blanks for readability.
X.PP
Terminal names (except for the last, verbose entry) should
be chosen using the following conventions.
The particular piece of hardware making up the terminal should
have a root name chosen, thus ``hp2621''.
This name should not contain hyphens, except that synonyms may
be chosen that do not conflict with other names.
Modes that the hardware can be in, or user preferences, should
be indicated by appending a hyphen and an indicator of the mode.
Thus, a vt100 in 132 column mode would be vt100-w.
The following suffixes should be used where possible:
X.LP
X.nf
X.ta 1i 5i
\fBSuffix	Meaning	Example\fP
-w	Wide mode (more than 80 columns)	vt100-w
-am	With auto. margins (usually default)	vt100-am
-nam	Without automatic margins	vt100-nam
-\fIn\fP	Number of lines on the screen	aaa-60
-na	No arrow keys (leave them in local)	c100-na
-\fIn\fPp	Number of pages of memory	c100-4p
-rv	Reverse video	c100-rv
X.fi
X.SH CAPABILITIES
The variable is the name by which the programmer (at the terminfo level)
accesses the capability.
The capname is the short name used in the text of the database,
and is used by a person updating the database.
X.P
Capability names have no hard length limit, but an informal limit of 5
characters has been adopted to keep them short.
Whenever possible, names are chosen to be the same as or similar to
the ANSI X3.64-1979 standard.  Semantics are also intended to match
those of the specification.
X.LP
X.nf
(P)	indicates padding may be specified
(G)	indicates that the string is passed through tparm with
	parms as given (#\fIi\fP).
(*)	indicates that padding may be based on the number of
	lines affected
(#\fIi\fP)	indicates the \fIi\fP\uth\d parameter.

X.ta \w'enter_alt_charset_mode  'u +\w'Capname  'u
\fBVariable	Capname	Description\fR
X.I Booleans:
auto_left_margin,	bw	cub1 wraps from column 0 to last column
auto_right_margin,	am	Terminal has automatic margins
beehive_glitch,	xsb	Beehive (f1=escape, f2=ctrl C)
ceol_standout_glitch,	xhp	Standout not erased by overwriting (hp)
eat_newline_glitch,	xenl	newline ignored after 80 cols (Concept)
erase_overstrike,	eo	Can erase overstrikes with a blank
generic_type,	gn	Generic line type (e.g. dialup, switch).
hard_copy,	hc	Hardcopy terminal
has_meta_key,	km	Has a meta key (shift, sets parity bit)
has_status_line,	hs	Has extra ``status line''
insert_null_glitch,	in	Insert mode distinguishes nulls
memory_above,	da	Display may be retained above the screen
memory_below,	db	Display may be retained below the screen
move_insert_mode,	mir	Safe to move while in insert mode
move_standout_mode,	msgr	Safe to move in standout modes
over_strike,	os	Terminal overstrikes
status_line_esc_ok,	eslok	Escape can be used on the status line
teleray_glitch,	xt	Tabs destructive, magic so char (Teleray 1061)
tilde_glitch,	hz	Hazeltine; can't print ~'s
transparent_underline,	ul	underline character overstrikes
xon_xoff,	xon	Terminal uses xon/xoff handshaking

X.I Numbers:
columns,	cols	Number of columns in a line
init_tabs,	it	Tabs initially every # spaces
lines,	lines	Number of lines on screen or page
lines_of_memory,	lm	Lines of memory if > lines.  0 means varies
magic_cookie_glitch,	xmc	Number of blank chars left by smso or rmso
padding_baud_rate,	pb	Lowest baud rate where cr/nl padding is needed
virtual_terminal,	vt	Virtual terminal number (CB/Unix)
width_status_line,	wsl	No. columns in status line

X.I Strings:
back_tab,	cbt	Back tab (P)
bell,	bel	Audible signal (bell) (P)
carriage_return,	cr	Carriage return (P*)
change_scroll_region,	csr	change to lines #1 through #2 (vt100) (PG)
clear_all_tabs,	tbc	Clear all tab stops. (P)
clear_screen,	clear	Clear screen (P*)
clr_eol,	el	Clear to end of line (P)
clr_eos,	ed	Clear to end of display (P*)
column_address,	hpa	Set cursor column (PG)
command_character,	CC	Term. settable cmd char in prototype
cursor_address,	cup	Screen relative cursor motion to row #1 col #2 (PG)
cursor_down,	cud1	Down one line
cursor_home,	home	Home cursor (if no cup)
cursor_invisible,	civis	Make cursor invisible
cursor_left,	cub1	Move cursor left one space.
cursor_mem_address,	mrcup	Memory relative cursor addressing
cursor_normal,	cnorm	Make cursor appear normal (undo vs/vi)
cursor_right,	cuf1	Non-destructive space (cursor right)
cursor_to_ll,	ll	Last line, first column (if no cup)
cursor_up,	cuu1	Upline (cursor up)
cursor_visible,	cvvis	Make cursor very visible
delete_character,	dch1	Delete character (P*)
delete_line,	dl1	Delete line (P*)
dis_status_line,	dsl	Disable status line
down_half_line,	hd	Half-line down (forward 1/2 linefeed)
enter_alt_charset_mode,	smacs	Start alternate character set (P)
enter_blink_mode,	blink	Turn on blinking
enter_bold_mode,	bold	Turn on bold (extra bright) mode
enter_ca_mode,	smcup	String to begin programs that use cup
enter_delete_mode,	smdc	Delete mode (enter)
enter_dim_mode,	dim	Turn on half-bright mode
enter_insert_mode,	smir	Insert mode (enter);
enter_protected_mode,	prot	Turn on protected mode
enter_reverse_mode,	rev	Turn on reverse video mode
enter_secure_mode,	invis	Turn on blank mode (chars invisible)
enter_standout_mode,	smso	Begin stand out mode
enter_underline_mode,	smul	Start underscore mode
erase_chars	ech	Erase #1 characters (PG)
exit_alt_charset_mode,	rmacs	End alternate character set (P)
exit_attribute_mode,	sgr0	Turn off all attributes
exit_ca_mode,	rmcup	String to end programs that use cup
exit_delete_mode,	rmdc	End delete mode
exit_insert_mode,	rmir	End insert mode
exit_standout_mode,	rmso	End stand out mode
exit_underline_mode,	rmul	End underscore mode
flash_screen,	flash	Visible bell (may not move cursor)
form_feed,	ff	Hardcopy terminal page eject (P*)
from_status_line,	fsl	Return from status line
init_1string,	is1	Terminal initialization string
init_2string,	is2	Terminal initialization string
init_3string,	is3	Terminal initialization string
init_file,	if	Name of file containing is
insert_character,	ich1	Insert character (P)
insert_line,	il1	Add new blank line (P*)
insert_padding,	ip	Insert pad after character inserted (P*)
key_backspace,	kbs	Sent by backspace key
key_catab,	ktbc	Sent by clear-all-tabs key.
key_clear,	kclr	Sent by clear screen or erase key.
key_ctab,	kctab	Sent by clear-tab key
key_dc,	kdch1	Sent by delete character key.
key_dl,	kdl1	Sent by delete line key.
key_down,	kcud1	Sent by terminal down arrow key
key_eic,	krmir	Sent by rmir or smir in insert mode.
key_eol,	kel	Sent by clear-to-end-of-line key.
key_eos,	ked	Sent by clear-to-end-of-screen key.
key_f0,	kf0	Sent by function key f0.
key_f1,	kf1	Sent by function key f1.
key_f10,	kf10	Sent by function key f10.
key_f2,	kf2	Sent by function key f2.
key_f3,	kf3	Sent by function key f3.
key_f4,	kf4	Sent by function key f4.
key_f5,	kf5	Sent by function key f5.
key_f6,	kf6	Sent by function key f6.
key_f7,	kf7	Sent by function key f7.
key_f8,	kf8	Sent by function key f8.
key_f9,	kf9	Sent by function key f9.
key_home,	khome	Sent by home key.
key_ic,	kich1	Sent by ins char/enter ins mode key.
key_il,	kil1	Sent by insert line.
key_left,	kcub1	Sent by terminal left arrow key
key_npage,	knp	Sent by next-page key
key_ppage,	kpp	Sent by previous-page key
key_right,	kcuf1	Sent by terminal right arrow key
key_sf,	kind	Sent by scroll-forward/down key
key_sr,	kri	Sent by scroll-backward/up key
key_stab,	khts	Sent by set-tab key
key_up,	kcuu1	Sent by terminal up arrow key
keypad_local,	rmkx	Out of "keypad transmit" mode
keypad_xmit,	smkx	Put terminal in "keypad transmit" mode
label_f0,	lf0	Labels on function key f0 if not f0
label_f1,	lf1	Labels on function key f1 if not f1
label_f10,	lf10	Labels on function key f10 if not f10
label_f2,	lf2	Labels on function key f2 if not f2
label_f3,	lf3	Labels on function key f3 if not f3
label_f4,	lf4	Labels on function key f4 if not f4
label_f5,	lf5	Labels on function key f5 if not f5
label_f6,	lf6	Labels on function key f6 if not f6
label_f7,	lf7	Labels on function key f7 if not f7
label_f8,	lf8	Labels on function key f8 if not f8
label_f9,	lf9	Labels on function key f9 if not f9
meta_on,	smm	Turn on "meta mode" (8th bit)
meta_off,	rmm	Turn off "meta mode"
newline,	nel	Newline (behaves like cr followed by lf)
pad_char,	pad	Pad character (rather than null)
parm_dch,	dch	Delete #1 chars (PG*)
parm_delete_line,	dl	Delete #1 lines (PG*)
parm_down_cursor,	cud	Move cursor down #1 lines. (PG*)
parm_ich,	ich	Insert #1 blank chars (PG*)
parm_index,	indn	Scroll forward #1 lines (PG)
parm_insert_line,	il	Add #1 new blank lines (PG*)
parm_left_cursor,	cub	Move cursor left #1 spaces (PG)
parm_right_cursor,	cuf	Move cursor right #1 spaces. (PG*)
parm_rindex,	rin	Scroll backward #1 lines (PG)
parm_up_cursor,	cuu	Move cursor up #1 lines. (PG*)
pkey_key,	pfkey	Prog funct key #1 to type string #2
pkey_local,	pfloc	Prog funct key #1 to execute string #2
pkey_xmit,	pfx	Prog funct key #1 to xmit string #2
print_screen,	mc0	Print contents of the screen
prtr_off,	mc4	Turn off the printer
prtr_on,	mc5	Turn on the printer
repeat_char,	rep	Repeat char #1 #2 times.  (PG*)
reset_1string,	rs1	Reset terminal completely to sane modes.
reset_2string,	rs2	Reset terminal completely to sane modes.
reset_3string,	rs3	Reset terminal completely to sane modes.
reset_file,	rf	Name of file containing reset string.
restore_cursor,	rc	Restore cursor to position of last sc.
row_address,	vpa	Vertical position absolute (set row). (PG)
save_cursor,	sc	Save cursor position. (P)
scroll_forward,	ind	Scroll text up (P)
scroll_reverse,	ri	Scroll text down (P)
set_attributes,	sgr	Define the video attributes (PG9)
set_tab,	hts	Set a tab in all rows, current column.
set_window,	wind	Current window is lines #1-#2 cols #3-#4
tab,	ht	Tab to next 8 space hardware tab stop.
to_status_line,	tsl	Go to status line, column #1
underline_char,	uc	Underscore one char and move past it
up_half_line,	hu	Half-line up (reverse 1/2 linefeed)
X.fi
X.PP
X.B A Sample Entry
X.PP
The following entry, which describes the Concept\-100, is among the more
complex entries in the
X.I terminfo
file as of this writing.
X.PP
X.nf
X.ta .3i
concept100\||\|c100|\|\|concept\||\|c104\||\|c100-4p\||\|concept 100,
	is2=\eEU\eEf\eE7\eE5\eE8\eEl\eENH\eEK\eE\e200\eEo&\e200\eEo\e47\eE,
	cr=^M, cud1=^J, ind=^J, bel=^G, smcup=\eEU\eEv  8p\eEp\er,
	rmcup=\eEv    $<6>\eEp\er\en, il1=\eE^R$<3*>, am, cub1=^H,
	ed=\eE^C$<16*>, el=\eE^U$<16>, clear=^L$<2*>,
	cup=\eEa%p1%' '%+%c%p2%' '%+%c, cols#80, dch1=\eE^A$<16*>,
	dl1=\eE^B$<3*>, rmir=\eE\e200, eo, smir=\eE^P, in, ip=$<16*>,
	lines#24, mir, cuf1=\eE=, ht=\et$<8>, kbs=^h, ul, cuu1=\eE;,
	db, smul=\eEG, rmul=\eEg, xenl, cvvis=\eEW, cnorm=\eEw,
	flash=\eEk$<20>\eEK, pb#9600, vt#8, smul=\eEG, rmul=\eEg,
	smso=\eEE\eED, rmso=\eEd\eEe, dim=\eEE, rev=\eED, blink=\eEC,
	prot=\eEI, invis=\eEH, sgr0=\eEN\e200, rep=\eEr%p1%c%p2%' '%+%c$<.2*>,
	smkx=\eEX, rmkx=\eEx, kcuu1=\eE;, kcud1=\eE<, kcub1=\eE>,
	kcuf1=\eE=, khome=\eE?, kf1=\eE5, kf2=\eE6, kf3=\eE7,
X.fi
X.PP
Entries may continue onto multiple lines by placing white space at
the beginning of each line except the first.
Comments may be included on lines beginning with ``#''.
Capabilities in
X.I terminfo
are of three types:
Boolean capabilities which indicate that the terminal has
some particular feature, numeric capabilities giving the size of the terminal
or the size of particular delays, and string
capabilities, which give a sequence which can be used to perform particular
terminal operations.
X.PP
X.B Types of Capabilities
X.PP
All capabilities have short codes.  For instance, the fact that
the Concept has \*(lqautomatic margins\*(rq (i.e. an automatic return and linefeed
when the end of a line is reached) is indicated by the capability \fBam\fR.
Hence the description of the Concept includes \fBam\fR.
Numeric capabilities are followed by the character `#' and then the value.
Thus \fBcols\fR which indicates the number of columns the terminal has
gives the value `80' for the Concept.
X.PP
XFinally, string valued capabilities, such as \fBel\fR (clear to end of line
sequence) are given by the two character code, an `=', and then a string
ending at the next following `,'.  A delay in milliseconds may appear
anywhere in such a capability, enclosed in $<..> brackets,
as in \fBel\fP=\eEK$<3>,
and padding characters are supplied by
X.I tputs
to provide this delay.
The delay can be either a number, e.g. `20', or a number followed by
an `*', i.e. `3*'.  A `*' indicates that the padding required is proportional
to the number of lines affected by the operation, and the amount given is
the per-affected-unit padding required.
(In the case of insert character, the factor is still the number of
X.IR lines
affected.
This is always one unless the terminal has \fBxenl\fP and the software uses it.)
When a `*' is specified, it is sometimes useful to give a delay of the form
`3.5' to specify a delay per unit to tenths of milliseconds.
(Only one decimal place is allowed.)
X.PP
A number of escape sequences are provided in the string valued capabilities
for easy encoding of characters there.  A \fB\eE\fR (or \fB\ee\fP)
maps to an \s-2ESCAPE\s0
character, \fB^x\fR maps to a control-x for any appropriate x, and the sequences
\fB\en \er \et \eb \ef \es\fR give a newline,
return, tab, backspace, formfeed and space, respectively.
XFinally, characters may be given as three octal digits after a \fB\e\fR,
and the characters \fB^\fR, \fB\e\fR and comma may be given
as \fB\e^\fR, \fB\e\e\fR and \fB\e,\fR.
X.PP
XFor convenience when testing entries, individual capabilities may be easily
commented out by directly preceding the name of the capability by a period.
Thus the entry
X.DT
X.nf
	33\||\|tty33\||\|tty\||\|model 33 teletype,
		cr=^M, cud1=^J, .ind=^J, bel=^G, cols#72, hc, os,
X.fi
X.ad
is equivalent to the entry
X.DT
X.nf
	33\||\|tty33\||\|tty\||\|model 33 teletype,
		cr=^M, cud1=^J, bel=^G, cols#72, hc, os,
X.fi
X.ad
the \fBind\fP capability having been 'commented out'.
X.br
X.ne 5
X.PP
X.B Preparing Descriptions
X.PP
We now outline how to prepare descriptions of terminals.
The most effective way to prepare a terminal description is by imitating
the description of a similar terminal in
X.I terminfo
and to build up a description gradually, using partial descriptions
with
X.I vi
to check that they are correct.
Be aware that a very unusual terminal may expose deficiencies in
the ability of the
X.I terminfo
file to describe it
or bugs in
X.I vi.
To easily test a new terminal description you can set the environment variable
TERMINFO to a pathname of a file containing the description you are working
on and the editor will look there rather than in
X.I /etc/terminfo.
To get the padding for insert line right (if the terminal manufacturer
did not document it) a severe test is to edit /etc/passwd at 9600 baud,
delete 16 or so lines from the middle of the screen, then hit the `u'
key several times quickly.
If the terminal messes up, more padding is usually needed.
A similar test can be used for insert character.
X.PP
X.B Basic capabilities
X.PP
The number of columns on each line for the terminal is given by the
\fBcols\fR numeric capability.  If the terminal is a \s-2CRT\s0, then the
number of lines on the screen is given by the \fBlines\fR capability.
If the terminal wraps around to the beginning of the next line when
it reaches the right margin, then it should have the \fBam\fR capability.
If the terminal can clear its screen, then this is given by the
\fBclear\fR string capability.
If the terminal overstrikes
(rather than clearing a position when a character is struck over)
then it should have the \fBos\fR capability.
If the terminal is a printing terminal, with no soft copy unit,
give it both
X.B hc
and
X.BR os .
X.RB ( os
applies to storage scope terminals, such as Tektronix 4010
series, as well as hard copy and APL terminals.)
If there is a code to move the cursor to the left edge of the current
row, give this as
X.BR cr .
(Normally this will be carriage return, control M.)
If there is a code to produce an audible signal (bell, beep, etc)
give this as
X.BR bel .
X.PP
If there is a code to move the cursor one position to the left
(such as backspace) that capability should be given as
X.BR cub1 .
Similarly, codes to move forward, up, and down should be
given as
X.BR cuf1 ,
X.BR cuu1 ,
and
X.BR cud1 .
These local cursor motions should not alter the text they pass over,
for example, you would not normally use `\fBcuf1\fP=\es' because the
space would erase the character moved over.
X.PP
A very important point here is that the local cursor motions encoded
in
X.I terminfo
are undefined at the left and top edges of a \s-2CRT\s0 terminal.
Programs should never attempt to backspace around the left edge,
unless
X.B bw
is given,
and never attempt to go up locally off the top.
In order to scroll text up, a program will go to the bottom of the screen
and send the
X.B ind
(index) string.
X.PP
To scroll text down, a program goes to the top of the screen and sends the
X.B ri
(reverse index) string.
The strings
X.B ind
and
X.B ri
are undefined when not on their respective edges of the screen.
X.PP
The \fBam\fR capability tells whether the cursor sticks at the right
edge of the screen when text is output, but this does not necessarily
apply to a
X.B cuf1
from the last column.
The only local motion which is defined from the left edge is if
X.B bw
is given, then a
X.B cub1
from the left edge will move to the right edge of the previous row.
If
X.B bw
is not given, the effect is undefined.
This is useful for drawing a box around the edge of the screen, for example.
If the terminal has switch selectable automatic margins,
the
X.I terminfo
file usually assumes that this is on, i.e. \fBam\fR.
If the terminal has a command which moves to the first column of the next
line, that command can be given as
X.B nel
(newline).
It does not matter if the command clears the remainder of the current line,
so if the terminal has no
X.B cr
and
X.B lf
it may still be possible to craft a working
X.B nel
out of one or both of them.
X.PP
These capabilities suffice to describe hardcopy and \*(lqglass-tty\*(rq terminals.
Thus the model 33 teletype is described as
X.PP
X.DT
X.nf
	33\||\|tty33\||\|tty\||\|model 33 teletype,
		cr=^M, cud1=^J, ind=^J, bel=^G, cols#72, hc, os,
X.PP
while the Lear Siegler \s-2ADM\-3\s0 is described as
X.PP
X.DT
X.nf
	adm3\||\|3\||\|lsi adm3,
		cr=^M, cud1=^J, ind=^J, bel=^G,
		am, cub1=^H, clear=^Z, lines#24, cols#80,
X.fi
X.PP
X.B Parameterized Strings
X.PP
Cursor addressing and other strings requiring parameters
in the terminal are described by a
parameterized string capability, with 
X.IR printf (3s)
like escapes \fB%x\fR in it.
XFor example, to address the cursor, the
X.B cup
capability is given, using two parameters:
the row and column to address to.
(Rows and columns are numbered from zero and refer to the
physical screen visible to the user, not to any unseen memory.)
If the terminal has memory relative cursor addressing,
that can be indicated by
X.BR mrcup .
X.PP
The parameter mechanism uses a stack and special \fB%\fP codes
to manipulate it.  Typically a sequence will push one of the
parameters onto the stack and then print it in some format.
Often more complex operations are necessary.
X.PP
The \fB%\fR encodings have the following meanings:
X.PP
X.DT
X.nf
X.ta .5i 1.5i
	%%	outputs `%'
	%d	print pop() as in printf
	%2d	print pop() like %2d
	%02d	print pop() like %02d
	%3d	print pop() like %3d
	%03d	print pop() like %03d
	%c	print pop() like %c
	%s	print pop() like %s

	%p[1-9]	push ith parm
	%P[a-z]	set variable [a-z] to pop()
	%g[a-z]	get variable [a-z] and push it
	%'c'	char constant c
	%{nn}	integer constant nn

	%+ %- %* %/ %m
		arithmetic (%m is mod): push(pop() op pop())
	%& %| %^	bit operations: push(pop() op pop())
	%= %> %<	logical operations: push(pop() op pop())
	%! %~	unary operations push(op pop())
	%i	add 1 to first two parms (for ANSI terminals)

	%? expr %t thenpart %e elsepart %;
		if-then-else, %e elsepart is optional.
		else-if's are possible ala Algol 68:
		%? c1 %t %e c2 %t %e c3 %t %e c4 %t %e %;
X.fi
X.PP
It should be noted that the binary operators above (e.g. %+, %-, %m, etc.)
all work in the usual fashion, i.e.
X.ce
%gx %gy %m
yields \fBx mod y\fR not \fBy mod x\fR.
X.PP
Consider the HP2645, which, to get to row 3 and column 12, needs
to be sent \eE&a12c03Y padded for 6 milliseconds.  Note that the order
of the rows and columns is inverted here, and that the row and column
are printed as two digits.
Thus its \fBcup\fR capability is \*(lqcup=\eE&%p2%2dc%p1%2dY$<6>\*(rq.
X.PP
The Microterm \s-2ACT-IV\s0 needs the current row and column sent
preceded by a \fB^T\fR, with the row and column simply encoded in binary,
\*(lqcup=^T%p1%c%p2%c\*(rq.
Terminals which use \*(lq%c\*(rq need to be able to
backspace the cursor (\fBcub1\fR),
and to move the cursor up one line on the screen (\fBcuu1\fR).
This is necessary because it is not always safe to transmit \fB\en\fR,
\fB^D\fR and \fB\er\fR, as the system may change or discard them.
(The library routines dealing with terminfo set tty modes so that
tabs are never expanded, so \et is safe to send.
This turns out to be essential for the Ann Arbor 4080.)
X.PP
A final example is the \s-2LSI ADM\s0-3a, which uses row and column
offset by a blank character, thus \*(lqcup=\eE=%p1%' '%+%c%p2%' '%+%c\*(rq.
After sending `\eE=', this pushes the first parameter, pushes the
ASCII value for a space (32), adds them (pushing the sum on the stack
in place of the two previous values) and outputs that value as a character.
Then the same is done for the second parameter.
More complex arithmetic is possible using the stack.
X.PP
If the terminal has row or column absolute cursor addressing,
these can be given as single parameter capabilities
X.B hpa
(horizontal position absolute)
and
X.B vpa
(vertical position absolute).
Sometimes these are shorter than the more general two parameter
sequence (as with the hp2645) and can be used in preference to
X.B cup .
If there are parameterized local motions (e.g. move
X.I n
spaces to the right) these can be given as
X.BR cud ,
X.BR cub ,
X.BR cuf ,
and
X.BR cuu
with a single parameter indicating how many spaces to move.
These are primarily useful if the terminal does not have
X.BR cup ,
such as the Tektronix 4025.
X.PP
X.B Cursor motions
X.PP
If the terminal has a fast way to home the cursor
(to very upper left corner of screen) then this can be given as
\fBhome\fR; similarly a fast way of getting to the lower left hand corner
can be given as \fBll\fR; this may involve going up with \fBcuu1\fR
from the home position,
but a program should never do this itself (unless \fBll\fR does) because it
can make no assumption about the effect of moving up from the home position.
Note that the home position is the same as addressing to (0,0):
to the top left corner of the screen, not of memory.
(Thus, the \eEH sequence on HP terminals cannot be used for
X.BR home .)
X.PP
X.B Area clears
X.PP
If the terminal can clear from the current position to the end of the
line, leaving the cursor where it is, this should be given as \fBel\fR.
If the terminal can clear from the current position to the end of the
display, then this should be given as \fBed\fR.
\fBed\fR is only defined from the first column of a line.
(Thus, it can be simulated by a request to delete a large number of lines,
if a true
X.B ed
is not available.)
X.PP
X.B Insert/delete line
X.PP
If the terminal can open a new blank line before the line where the cursor
is, this should be given as \fBil1\fR; this is done only from the first
position of a line.  The cursor must then appear on the newly blank line.
If the terminal can delete the line which the cursor is on, then this
should be given as \fBdl1\fR; this is done only from the first position on
the line to be deleted.
Versions of
X.B il1
and
X.B dl1
which take a single parameter and insert or delete that many lines can
be given as
X.B il
and
X.BR dl .
If the terminal has a settable scrolling region (like the vt100)
the command to set this can be described with the
X.B csr
capability, which takes two parameters:
the top and bottom lines of the scrolling region.
The cursor position is, alas, undefined after using this command.
It is possible to get the effect of insert or delete line using
this command \- the
X.B sc
and
X.B rc
(save and restore cursor) commands are also useful.
Inserting lines at the top or bottom of the screen can also be
done using
X.B ri
or
X.B ind
on many terminals without true insert/delete line,
and are often faster even on terminals with those features.
X.PP
If the terminal has the ability to define a window as part of
memory, which all commands affect,
it should be given as the parameterized string
X.BR wind .
The four parameters are the starting and ending lines in memory
and the starting and ending columns in memory, in that order.
X.PP
If the terminal can retain display memory above then the
\fBda\fR capability should be given; if display memory can be retained
below then \fBdb\fR should be given.  These indicate
that deleting a line or scrolling may bring non-blank lines up from below
or that scrolling back with \fBri\fR may bring down non-blank lines.
X.PP
X.B Insert/delete character
X.PP
There are two basic kinds of intelligent terminals with respect to
insert/delete character which can be described using
X.I terminfo.
The most common insert/delete character operations affect only the characters
on the current line and shift characters off the end of the line rigidly.
Other terminals, such as the Concept 100 and the Perkin Elmer Owl, make
a distinction between typed and untyped blanks on the screen, shifting
upon an insert or delete only to an untyped blank on the screen which is
either eliminated, or expanded to two untyped blanks.  You can find out
which kind of terminal you have by clearing the screen and then typing
text separated by cursor motions.  Type \*(lqabc\ \ \ \ def\*(rq using local
cursor motions (not spaces) between the \*(lqabc\*(rq and the \*(lqdef\*(rq.
Then position the cursor before the \*(lqabc\*(rq and put the terminal in insert
mode.  If typing characters causes the rest of the line to shift
rigidly and characters to fall off the end, then your terminal does
not distinguish between blanks and untyped positions.  If the \*(lqabc\*(rq
shifts over to the \*(lqdef\*(rq which then move together around the end of the
current line and onto the next as you insert, you have the second type of
terminal, and should give the capability \fBin\fR, which stands for
\*(lqinsert null\*(rq.
While these are two logically separate attributes (one line vs. multi line
insert mode, and special treatment of untyped spaces) we have seen no
terminals whose insert mode cannot be described with the single attribute.
X.PP
Termcap can describe both terminals which have an insert mode, and terminals
which send a simple sequence to open a blank position on the current line.
Give as \fBsmir\fR the sequence to get into insert mode.
Give as \fBrmir\fR the sequence to leave insert mode.
Now give as \fBich1\fR any sequence needed to be sent just before sending
the character to be inserted.  Most terminals with a true insert mode
will not give \fBich1\fR, terminals which send a sequence to open a screen
position should give it here.  (Insert mode is usually
preferable to the sequence
to open a position on the screen if your terminal has both.)
If post insert padding is needed, give this as a number of milliseconds
in \fBip\fR (a string option).  Any other sequence which may need to be
sent after an insert of a single character may also be given in \fBip\fR.
If your terminal needs both to be placed into an `insert mode' and
a special code to precede each inserted character, then both
X.BR smir / rmir
and
X.B ich1
can be given, and both will be used.
The
X.B ich
capability, with one parameter,
X.IR n ,
will repeat the effects of
X.B ich1
X.I n
times.
X.PP
It is occasionally necessary to move around while in insert mode
to delete characters on the same line (e.g. if there is a tab after
the insertion position).  If your terminal allows motion while in
insert mode you can give the capability \fBmir\fR to speed up inserting
in this case.  Omitting \fBmir\fR will affect only speed.   Some terminals
(notably Datamedia's) must not have \fBmir\fR because of the way their
insert mode works.
X.PP
XFinally, you can specify
X.B dch1
to delete a single character,
X.B dch
with one parameter,
X.IR n ,
to delete
X.I n characters,
and delete mode by giving \fBsmdc\fR and \fBrmdc\fR
to enter and exit delete mode (any mode the terminal needs to be placed
in for
X.B dch1
to work).
X.PP
A command to erase
X.I n
characters (equivalent to outputting
X.I n
blanks without moving the cursor)
can be given as
X.B ech
with one parameter.
X.PP
X.B "Highlighting, underlining, and visible bells"
X.PP
If your terminal has one or more kinds of display attributes,
these can be represented in a number of different ways.
You should choose one display form as
X.I standout mode ,
representing a good, high contrast, easy on the eyes,
format for highlighting error messages and other attention getters.
(If you have a choice, reverse video plus half bright is good,
or reverse video alone.)
The sequences to enter and exit standout mode
are given as \fBsmso\fR and \fBrmso\fR respectively.
If the code to change into or out of standout
mode leaves one or even two blank spaces on the screen,
as the TVI 912 and Teleray 1061 do,
then \fBxmc\fR should be given to tell how many spaces are left.
X.PP
Codes to begin underlining and end underlining can be given as \fBsmul\fR
and \fBrmul\fR respectively.
If the terminal has a code to underline the current character and move
the cursor one space to the right, 
such as the Microterm Mime,
this can be given as \fBuc\fR.
X.PP
Other capabilities to enter various highlighting modes include
X.B blink
(blinking)
X.B bold
(bold or extra bright)
X.B dim
(dim or half bright)
X.B invis
(blanking or invisible text)
X.B prot
(protected)
X.B rev
(reverse video)
X.B sgr0
(turn off
X.I all
attribute modes)
X.B smacs
(enter alternate character set mode)
and
X.B rmacs
(exit alternate character set mode).
Turning on any of these modes singly may or may not turn off other modes.
X.PP
If there is a sequence to set arbitrary combinations of modes,
this should be given as
X.B sgr
(set attributes),
taking 9 parameters.
Each parameter is either 0 or 1, as the corresponding attribute is on or off.
The 9 parameters are, in order:
standout, underline, reverse, blink, dim, bold, invis, protect, alternate
character set.
Not all modes need be supported by
X.BR sgr ,
only those for which corresponding separate attribute commands exist.
X.PP
Terminals with the ``magic cookie'' glitch
X.RB ( xmc )
deposit special ``cookies'' when they receive mode setting sequences,
which affect the display algorithm, rather than having extra bits for
each character.
Some terminals, such as the HP 2621, automatically leave standout
mode when they move to a new line or the cursor is addressed.
Programs using standout mode should exit standout mode before
moving the cursor or sending a newline,
unless the
X.B msgr
capability, asserting that it is safe to move in standout mode, is present.
X.PP
If the terminal has
a way of flashing the screen to indicate an error quietly (a bell replacement)
then this can be given as \fBflash\fR; it must not move the cursor.
X.PP
If the cursor needs to be made more visible than normal when it is
not on the bottom line (to make, for example, a non-blinking underline into an
easier to find block or blinking underline)
give this sequence as
X.BR cvvis .
If there is a way to make the cursor completely invisible, give that as
X.BR civis .
The capability
X.BR cnorm
should be given which undoes the effects of both of these modes.
X.PP
If the terminal needs to be in a special mode when running
a program that uses these capbilities,
the codes to enter and exit this mode can be given as \fBsmcup\fR and \fBrmcup\fR.
This arises, for example, from terminals like the Concept with more than
one page of memory.
If the terminal has only memory relative cursor addressing and not screen
relative cursor addressing, a one screen-sized window must be fixed into
the terminal for cursor addressing to work properly.
This is also used for the Tektronix 4025,
where
X.B smcup
sets the command character to be the one used by terminfo.
X.PP
If your terminal correctly generates underlined characters
(with no special codes needed)
even though it does not overstrike,
then you should give the capability \fBul\fR.
If overstrikes are erasable with a blank,
then this should be indicated by giving \fBeo\fR.
X.PP
X.B Keypad
X.PP
If the terminal has a keypad that transmits codes when the keys are pressed,
this information can be given. Note that it is not possible to handle
terminals where the keypad only works in local (this applies, for example,
to the unshifted HP 2621 keys).
If the keypad can be set to transmit or not transmit,
give these codes as \fBsmkx\fR and \fBrmkx\fR.
Otherwise the keypad is assumed to always transmit.
The codes sent by the left arrow, right arrow, up arrow, down arrow,
and home keys can be given as \fBkcub1, kcuf1, kcuu1, kcud1,
\fRand\fB khome\fR respectively.
If there are function keys such as f0, f1, ..., f10, the codes they send
can be given as \fBkf0, kf1, ..., kf10\fR.
If these keys have labels other than the default f0 through f10, the labels
can be given as \fBlf0, lf1, ..., lf10\fR.
The codes transmitted by certain other special keys can be given:
X.B kbs
(backspace),
X.B ktbc
(clear all tabs),
X.B kctab
(clear the tab stop in this column),
X.B kclr
(clear screen or erase key),
X.B kdch1
(delete character),
X.B kdl1
(delete line),
X.B krmir
(exit insert mode),
X.B kel
(clear to end of line),
X.B ked
(clear to end of screen),
X.B kich1
(insert character or enter insert mode),
X.B kil1
(insert line),
X.B knp
(next page),
X.B kpp
(previous page),
X.B kind
(scroll forward/down),
X.B kri
(scroll backward/up),
X.B khts
(set a tab stop in this column).
X.PP
X.B Tabs and Initialization
X.PP
If the terminal has hardware tabs, the command to advance to the next
tab stop can be given as
X.B ht
(usually control I).
A ``backtab'' command which moves leftward to the next tab stop can
be given as
X.BR cbt .
By convention, if the teletype modes indicate that tabs are being
expanded by the computer rather than being sent to the terminal,
programs should not use
X.B ht
or
X.B cbt
even if they are present, since the user may not have the tab stops
properly set.
If the terminal has hardware tabs activated by control I, then
X.B tabs
is given, in addition to
X.BR ht .
This is normally used by the
X.IR tset (1)
command to determine whether to set the mode for hardware tab expansion.
X.PP
Other capabilities
include
X.BR is1 ,
X.BR is2 ,
and
X.BR is3 ,
initialization strings for the terminal,
and \fBif\fR, the name of a file containing long initialization strings.
These strings are expected to set the terminal into modes consistent
with the rest of the terminfo description.
They are normally sent to the terminal, by the
X.IR tset (1)
program, each time the user logs in.
They will be printed in the following order:
X.BR is1 ;
X.BR is2 ;
setting tabs using
X.B tbc
and
X.BR hts ;
X.BR if ;
and finally
X.BR is3 .
Most initialization is done with
X.B is2 .
Special terminal modes can be set up without duplicating strings
by putting the common sequences in
X.B is2
and special cases in
X.B is1
and
X.BR is3 .
A pair of sequences that does a harder reset from a totally unknown state
can be analogously given as
X.BR rs1 ,
X.BR rs2 ,
X.BR rf ,
and
X.BR rs3 ,
analogous to
X.B is2
and
X.BR if .
These strings are output by the
X.IR reset (1)
program, which is used when the terminal gets into a wedged state.
Commands are normally placed in
X.B rs2
and
X.B rf
only if they produce annoying effects on the screen and are not
necessary when logging in.
XFor example, the command to set the vt100 into 80 column mode would
normally be part of
X.BR is2 ,
but it causes an annoying glitch of the screen and is not normally
needed since the terminal is usually already in 80 column mode.
X.PP
If there are commands to set and clear tab stops, they can be given as
X.B tbc
(clear all tab stops)
and
X.B hts
(set a tab stop in the current column of every row).
If a more complex sequence is needed to set the tabs than can be
described by this, the sequence can be placed in
X.B is2
or
X.BR if .
X.PP
X.B Delays
X.PP
Certain capabilities control padding in the teletype driver.
These are primarily needed by hard copy terminals, and are used
by the
X.IR tset (1)
program to set teletype modes appropriately.
Delays embedded in the capabilities
X.B cr ,
X.B ind ,
X.B cub1 ,
X.B ff ,
and
X.B tab
will cause the appropriate delay bits to be set in the teletype driver.
If
X.B pb
(padding baud rate)
is given,
these values can be ignored at baud rates below the value of
X.B pb .
X.PP
X.B Miscellaneous
X.PP
If the terminal requires other than a null (zero) character as a pad,
then this can be given as \fBpad\fR.
Only the first character of the
X.B pad
string is used.
X.PP
If the terminal has an extra ``status line'' that is not normally
used by software, this fact can be indicated.
If the status line is viewed as an extra line below the bottom line,
into which one can cursor address normally,
(such as the Heathkit h19's 25th line, or the 24th line of a vt100
which is set to a 23 line scrolling region)
the capability
X.B hs
should be given.
Special strings to go to the beginning of the status
line and to return from the status line can be given as
X.B tsl
and
X.BR fsl .
X.RB ( fsl
must leave the cursor position in the same place it was before
X.BR tsl .)
X.B tsl
takes one parameter, which is the column number of the status line
the cursor is to be moved to.
If escape sequences and other special commands, such as tab, work
while in the status line, the flag
X.B eslok
can be given.
A string which turns off the status line (or otherwise erases its
contents) should be given as
X.B dsl .
If the terminal has commands to save and restore the position of the cursor,
give them as
X.B sc
and
X.BR rc .
The status line is normally assumed to be the same width as the rest
of the screen, e.g.
X.B cols .
If the status line is a different width (possibly because the terminal
does not allow an entire line to be loaded) the width, in columns,
can be indicated with the numeric parameter
X.B wsl .
X.PP
If the terminal can move up or down half a line,
this can be indicated with
X.B hu
(half line up)
and
X.B hd
(half line down).
This is primarily useful for superscripts and subscripts on hardcopy terminals.
If a hardcopy terminal can eject to the next page (form feed), give this as
X.B ff
(usually control L).
X.PP
If there is a command to repeat a given character a given number of
times (to save time transmitting a large number of identical characters)
this can be indicated with the parameterized string
X.BR rep .
The first parameter is the character to be repeated and the second
is the number of times to repeat it.
Thus, tparm(repeat_char, 'x', 10) is the same as `xxxxxxxxxx'.
X.PP
If the terminal has a settable command character, such as the Tektronix 4025,
this can be indicated with
X.BR CC .
A prototype command character is chosen which is used in all capabilities.
This character is given in the
X.B CC
capability to identify it.
The following convention is supported on some UNIX systems:
The environment is to be searched for a
X.B CC
variable, and if found, all
occurrances of the prototype character are replaced with the character
in the environment variable.
X.PP
Terminal descriptions that do not represent a specific kind of known
terminal, such as
X.IR switch ,
X.IR dialup ,
X.IR patch ,
and
X.IR network ,
should include the
X.B gn
(generic) capability so that programs can complain that they don't know
how to talk to the terminal.
(This capability does not apply to
X.I virtual
terminal descriptions for which the escape sequences are known.)
X.PP
If the terminal uses xon/xoff handshaking for flow control, give
X.BR xon .
Padding information should still be included so that routines can
make better decisions about costs, but actual pad characters may
not be transmitted.
X.PP
If the terminal has a ``meta key'' which acts as a shift key,
setting the 8th bit of any character transmitted, this fact can
be indicated with
X.BR km .
Otherwise, software will assume that the 8th bit is parity and it
will usually be cleared.
If strings exist to turn this ``meta mode'' on and off, they
can be given as
X.B smm
and
X.BR rmm .
X.PP
If the terminal has more lines of memory than will fit on the screen
at once, the number of lines of memory can be indicated with
X.BR lm .
A value of 0 indicates that the number of lines is not fixed,
but that there is still more memory than fits on the screen.
X.PP
If the terminal is one of those supported by the CB-UNIX virtual
terminal protocol, the terminal number can be given as
X.BR vt .
X.PP
Media copy
strings which control an auxillary printer connected to the terminal
can be given as
X.BR mc0 :
print the contents of the screen,
X.BR mc4 :
turn on the printer, and
X.BR mc5 :
turn off the printer.
When the printer is on, all text sent to the terminal will be sent
to the printer.
It is undefined whether the text is also displayed on the terminal screen
when the printer is on.
X.PP
Strings to program function keys can be given as
X.BR pfkey ,
X.BR pfloc ,
and
X.BR pfx .
Each of these strings takes two parameters: the function key number to
program (from 0 to 10) and the string to program it with.
XFunction key numbers out of this range may program undefined keys in
a terminal dependent manner.
The difference between the capabilities is that
X.B pfkey
causes pressing the given key to be the same as the user typing the
given string,
X.B pfloc
causes the string to be executed by the terminal in local, and
X.B pfx
causes the string to be transmitted to the computer.
X.PP
X.B Glitches and Braindamage
X.PP
Hazeltine terminals, which don't allow `~' characters to be displayed should
indicate \fBhz\fR.
X.PP
Terminals which ignore a linefeed immediately after an \fBam\fR wrap,
such as the Concept and vt100,
should indicate \fBxenl\fR.
X.PP
If
X.B el
is required to get rid of standout
(instead of merely writing normal text on top of it),
\fBxhp\fP should be given.
X.PP
Teleray terminals, where tabs turn all characters moved over to blanks,
should indicate \fBxt\fR (destructive tabs).
This glitch is also taken to mean that it is not possible to position
the cursor on top of a ``magic cookie'',
that to erase standout mode it is instead necessary to use
delete and insert line.
X.PP
The Beehive Superbee, which is unable to correctly transmit the escape
or control C characters, has
X.BR xsb ,
indicating that the f1 key is used for escape and f2 for control C.
(Only certain superbees have this problem, depending on the ROM.)
X.PP
Other specific terminal problems may be corrected by adding more
capabilities of the form \fBx\fIx\fR.
X.PP
X.B Similar Terminals
X.PP
If there are two very similar terminals,
one can be defined as being just like the other with certain exceptions.
The string capability \fBuse\fR can be given
with the name of the similar terminal.
The capabilities given before
X.B use
override those in the terminal type invoked by
X.BR use .
A capability can be cancelled with \fBxx@\fR where xx is the capability.
XFor example, the entry
X.PP
	2621-nl, smkx@, rmkx@, use=2621,
X.PP
defines a 2621-nl that does not have the \fBsmkx\fR or \fBrmkx\fR capabilities,
and hence does not turn on the function key labels when in visual mode.
This is useful for different modes for a terminal, or for different
user preferences.  An terminal may have as many \fBuse\fR entries as needed.
They are handled in the order given in the description, that is, later
X.BR use 's
will not overwrite capabilities defined earlier in the entry.
X.SH FILES
X.DT
X/etc/terminfo	file containing terminal descriptions
X.br
X/etc/term/?/*	directories containing compiled descriptions
X.SH SEE ALSO
ex(1), curses(3), tset(1), vi(1), ul(1), more(1)
X.SH AUTHOR
Pavel Curtis
//go.sysin dd *
exit

sources@genrad.UUCP (12/17/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit".  This code is completely public domain, originally written by Pavel
Curtis of Cornell University.  This version has some small improvements and
bug fixes.

This unit contains:

	The terminfo compiler (actually two header files are missing - they
	will be supplied in the next module).

Part 5 will contain the rest of the headers, the Makefile, and some
awk scripts for transforming the sources when the Caps file changes.
----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =src
then
    echo 'Making directory "=src"'
    mkdir =src
fi
echo 'x - =src/comp_captab.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/comp_captab.c
X/*
 *	comp_captab.c -- The names of the capabilities in a form ready for
 *		         the making of a hash table for the compiler.
 *
 */


#include "compiler.h"
#include "term.h"


struct name_table_entry	cap_table[] =
{
	0,           "bw",	BOOLEAN,	  0,
	0,           "am",	BOOLEAN,	  1,
	0,          "xsb",	BOOLEAN,	  2,
	0,          "xhp",	BOOLEAN,	  3,
	0,         "xenl",	BOOLEAN,	  4,
	0,           "eo",	BOOLEAN,	  5,
	0,           "gn",	BOOLEAN,	  6,
	0,           "hc",	BOOLEAN,	  7,
	0,           "km",	BOOLEAN,	  8,
	0,           "hs",	BOOLEAN,	  9,
	0,           "in",	BOOLEAN,	 10,
	0,           "da",	BOOLEAN,	 11,
	0,           "db",	BOOLEAN,	 12,
	0,          "mir",	BOOLEAN,	 13,
	0,         "msgr",	BOOLEAN,	 14,
	0,           "os",	BOOLEAN,	 15,
	0,        "eslok",	BOOLEAN,	 16,
	0,           "xt",	BOOLEAN,	 17,
	0,           "hz",	BOOLEAN,	 18,
	0,           "ul",	BOOLEAN,	 19,
	0,          "xon",	BOOLEAN,	 20,
	0,         "cols",	NUMBER,		  0,
	0,           "it",	NUMBER,		  1,
	0,        "lines",	NUMBER,		  2,
	0,           "lm",	NUMBER,		  3,
	0,          "xmc",	NUMBER,		  4,
	0,           "pb",	NUMBER,		  5,
	0,           "vt",	NUMBER,		  6,
	0,          "wsl",	NUMBER,		  7,
	0,         "nlab",	NUMBER,		  8,
	0,           "lh",	NUMBER,		  9,
	0,           "lw",	NUMBER,		 10,
	0,          "cbt",	STRING,		  0,
	0,          "bel",	STRING,		  1,
	0,           "cr",	STRING,		  2,
	0,          "csr",	STRING,		  3,
	0,          "tbc",	STRING,		  4,
	0,        "clear",	STRING,		  5,
	0,           "el",	STRING,		  6,
	0,           "ed",	STRING,		  7,
	0,          "hpa",	STRING,		  8,
	0,           "CC",	STRING,		  9,
	0,          "cup",	STRING,		 10,
	0,         "cud1",	STRING,		 11,
	0,         "home",	STRING,		 12,
	0,        "civis",	STRING,		 13,
	0,         "cub1",	STRING,		 14,
	0,        "mrcup",	STRING,		 15,
	0,        "cnorm",	STRING,		 16,
	0,         "cuf1",	STRING,		 17,
	0,           "ll",	STRING,		 18,
	0,         "cuu1",	STRING,		 19,
	0,        "cvvis",	STRING,		 20,
	0,         "dch1",	STRING,		 21,
	0,          "dl1",	STRING,		 22,
	0,          "dsl",	STRING,		 23,
	0,           "hd",	STRING,		 24,
	0,        "smacs",	STRING,		 25,
	0,        "blink",	STRING,		 26,
	0,         "bold",	STRING,		 27,
	0,        "smcup",	STRING,		 28,
	0,         "smdc",	STRING,		 29,
	0,          "dim",	STRING,		 30,
	0,         "smir",	STRING,		 31,
	0,        "invis",	STRING,		 32,
	0,         "prot",	STRING,		 33,
	0,          "rev",	STRING,		 34,
	0,         "smso",	STRING,		 35,
	0,         "smul",	STRING,		 36,
	0,          "ech",	STRING,		 37,
	0,        "rmacs",	STRING,		 38,
	0,         "sgr0",	STRING,		 39,
	0,        "rmcup",	STRING,		 40,
	0,         "rmdc",	STRING,		 41,
	0,         "rmir",	STRING,		 42,
	0,         "rmso",	STRING,		 43,
	0,         "rmul",	STRING,		 44,
	0,        "flash",	STRING,		 45,
	0,           "ff",	STRING,		 46,
	0,          "fsl",	STRING,		 47,
	0,          "is1",	STRING,		 48,
	0,          "is2",	STRING,		 49,
	0,          "is3",	STRING,		 50,
	0,           "if",	STRING,		 51,
	0,         "ich1",	STRING,		 52,
	0,          "il1",	STRING,		 53,
	0,           "ip",	STRING,		 54,
	0,          "kbs",	STRING,		 55,
	0,         "ktbc",	STRING,		 56,
	0,         "kclr",	STRING,		 57,
	0,        "kctab",	STRING,		 58,
	0,        "kdch1",	STRING,		 59,
	0,         "kdl1",	STRING,		 60,
	0,        "kcud1",	STRING,		 61,
	0,        "krmir",	STRING,		 62,
	0,          "kel",	STRING,		 63,
	0,          "ked",	STRING,		 64,
	0,          "kf0",	STRING,		 65,
	0,          "kf1",	STRING,		 66,
	0,         "kf10",	STRING,		 67,
	0,          "kf2",	STRING,		 68,
	0,          "kf3",	STRING,		 69,
	0,          "kf4",	STRING,		 70,
	0,          "kf5",	STRING,		 71,
	0,          "kf6",	STRING,		 72,
	0,          "kf7",	STRING,		 73,
	0,          "kf8",	STRING,		 74,
	0,          "kf9",	STRING,		 75,
	0,        "khome",	STRING,		 76,
	0,        "kich1",	STRING,		 77,
	0,         "kil1",	STRING,		 78,
	0,        "kcub1",	STRING,		 79,
	0,          "kll",	STRING,		 80,
	0,          "knp",	STRING,		 81,
	0,          "kpp",	STRING,		 82,
	0,        "kcuf1",	STRING,		 83,
	0,         "kind",	STRING,		 84,
	0,          "kri",	STRING,		 85,
	0,         "khts",	STRING,		 86,
	0,        "kcuu1",	STRING,		 87,
	0,         "rmkx",	STRING,		 88,
	0,         "smkx",	STRING,		 89,
	0,          "lf0",	STRING,		 90,
	0,          "lf1",	STRING,		 91,
	0,         "lf10",	STRING,		 92,
	0,          "lf2",	STRING,		 93,
	0,          "lf3",	STRING,		 94,
	0,          "lf4",	STRING,		 95,
	0,          "lf5",	STRING,		 96,
	0,          "lf6",	STRING,		 97,
	0,          "lf7",	STRING,		 98,
	0,          "lf8",	STRING,		 99,
	0,          "lf9",	STRING,		100,
	0,          "rmm",	STRING,		101,
	0,          "smm",	STRING,		102,
	0,          "nel",	STRING,		103,
	0,          "pad",	STRING,		104,
	0,          "dch",	STRING,		105,
	0,           "dl",	STRING,		106,
	0,          "cud",	STRING,		107,
	0,          "ich",	STRING,		108,
	0,         "indn",	STRING,		109,
	0,           "il",	STRING,		110,
	0,          "cub",	STRING,		111,
	0,          "cuf",	STRING,		112,
	0,          "rin",	STRING,		113,
	0,          "cuu",	STRING,		114,
	0,        "pfkey",	STRING,		115,
	0,        "pfloc",	STRING,		116,
	0,          "pfx",	STRING,		117,
	0,          "mc0",	STRING,		118,
	0,          "mc4",	STRING,		119,
	0,          "mc5",	STRING,		120,
	0,          "rep",	STRING,		121,
	0,          "rs1",	STRING,		122,
	0,          "rs2",	STRING,		123,
	0,          "rs3",	STRING,		124,
	0,           "rf",	STRING,		125,
	0,           "rc",	STRING,		126,
	0,          "vpa",	STRING,		127,
	0,           "sc",	STRING,		128,
	0,          "ind",	STRING,		129,
	0,           "ri",	STRING,		130,
	0,          "sgr",	STRING,		131,
	0,          "hts",	STRING,		132,
	0,         "wind",	STRING,		133,
	0,           "ht",	STRING,		134,
	0,          "tsl",	STRING,		135,
	0,           "uc",	STRING,		136,
	0,           "hu",	STRING,		137,
	0,        "iprog",	STRING,		138,
	0,          "ka1",	STRING,		139,
	0,          "ka3",	STRING,		140,
	0,          "kb2",	STRING,		141,
	0,          "kc1",	STRING,		142,
	0,          "kc3",	STRING,		143,
	0,         "mc5p",	STRING,		144,
	0,          "rmp",	STRING,		145,
	0,         "acsc",	STRING,		146,
	0,          "pln",	STRING,		147,
};

struct name_table_entry *cap_hash_table[360];

int	Hashtabsize = 360;
int	Captabsize = 180;


#if (BOOLCOUNT!=21)||(NUMCOUNT!=11)||(STRCOUNT!=148)
	--> term.h and comp_captab.c disagree about the <--
	--> numbers of booleans, numbers and/or strings <--
#endif
//go.sysin dd *
echo 'x - =src/comp_error.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/comp_error.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	comp_error.c -- Error message routines
 *
 *  $Log:	RCS/comp_error.v $
 * Revision 2.1  82/10/25  14:45:31  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:16:32  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:29:31  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:09:44  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:36:02  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/comp_error.v  Revision 2.1  82/10/25  14:45:31  pavel  Exp$";

#include "compiler.h"

extern char *string_table;
extern short term_names;

warning(fmt, a1, a2, a3, a4, a5, a6)
char	*fmt, *a1, *a2, *a3, *a4, *a5, *a6;
{
    fprintf (stderr, "compile: Warning: near line %d: ", curr_line);
    fprintf (stderr, "terminal '%s', ", string_table+term_names);
    fprintf (stderr, fmt, a1, a2, a3, a4, a5, a6);
    fprintf (stderr, "\n");
}


err_abort(fmt, a1, a2, a3, a4, a5, a6)
char	*fmt, *a1, *a2, *a3, *a4, *a5, *a6;
{
    fprintf (stderr, "compile: Line %d: ", curr_line);
    fprintf (stderr, "terminal '%s', ", string_table+term_names);
    fprintf (stderr, fmt, a1, a2, a3, a4, a5, a6);
    fprintf (stderr, "\n");
    exit(1);
}


syserr_abort(fmt, a1, a2, a3, a4, a5, a6)
char	*fmt, *a1, *a2, *a3, *a4, *a5, *a6;
{
    fprintf (stderr, "PROGRAM ERROR: Line %d: ", curr_line);
    fprintf (stderr, "terminal '%s', ", string_table+term_names);
    fprintf (stderr, fmt, a1, a2, a3, a4, a5, a6);
    fprintf (stderr, "\n");
    abort();
}
//go.sysin dd *
echo 'x - =src/comp_hash.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/comp_hash.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	comp_hash.c --- Routines to deal with the hashtable of capability
 *			names.
 *
 *  $Log:	RCS/comp_hash.v $
 * Revision 2.1  82/10/25  14:45:34  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:16:34  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:29:33  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:09:46  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:36:23  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/comp_hash.v  Revision 2.1  82/10/25  14:45:34  pavel  Exp$";

#include "compiler.h"
#include "term.h"



X/*
 *	make_hash_table()
 *
 *	Takes the entries in cap_table[] and hashes them into cap_hash_table[]
 *	by name.  There are Captabsize entries in cap_table[] and Hashtabsize
 *	slots in cap_hash_table[].
 *
 */

make_hash_table()
{
	int	i;
	int	hashvalue;
	int	collisions = 0;

	for (i=0; i < Captabsize; i++)
	{
	    hashvalue = hash_function(cap_table[i].nte_name);       
	    DEBUG(9, "%d\n", hashvalue);

	    if (cap_hash_table[hashvalue] != (struct name_table_entry *) 0)
		collisions++;

	    cap_table[i].nte_link = cap_hash_table[hashvalue];
	    cap_hash_table[hashvalue] = &cap_table[i];
	}

	DEBUG(3, "Hash table complete\n%d collisions ", collisions);
	DEBUG(3, "out of %d entries\n", Captabsize);
}



X/*
 *	int hash_function(string)
 *
 *	Computes the hashing function on the given string.
 *
 *	The current hash function is the sum of each consectutive pair
 *	of characters, taken as two-byte integers, mod Hashtabsize.
 *
 */

static
int
hash_function(string)
char	*string;
{
	long	sum = 0;

	while (*string)
	{
	    sum += *string + (*(string + 1) << 8);
	    string++;
	}

	return (sum % Hashtabsize);
}



X/*
 *	struct name_table_entry *
 *	find_entry(string)
 *
 *	Finds the entry for the given string in the hash table if present.
 *	Returns a pointer to the entry in the table or 0 if not found.
 *
 */

struct name_table_entry *
find_entry(string)
char	*string;
{
	int	hashvalue;
	struct name_table_entry	*ptr;

	hashvalue = hash_function(string);

	ptr = cap_hash_table[hashvalue];

	while (ptr != (struct name_table_entry *) 0  &&
			       	           strcmp(ptr->nte_name, string) != 0)
	    ptr = ptr->nte_link;

	return (ptr);
}
//go.sysin dd *
echo 'x - =src/comp_main.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/comp_main.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	comp_main.c --- Main program for terminfo compiler
 *
 *  $Log:	RCS/comp_main.v $
 * Revision 2.1  82/10/25  14:45:37  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:16:37  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:29:36  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:09:49  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:36:55  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/comp_main.v  Revision 2.1  82/10/25  14:45:37  pavel  Exp$";


#include <sys/types.h>
#include <sys/stat.h>
#include "compiler.h"

char	*source_file = "/etc/terminfo";
char	*destination = SRCDIR;
char	*usage_string = "\tcompile [-v[n]] source-file\n";
char	check_only = 0;


main (argc, argv)
int	argc;
char	*argv[];
{
	int	i;
	int	argflag = FALSE;

	debug_level = 0;

	for (i=1; i < argc; i++)
	{
	    if (argv[i][0] == '-')
	    {
		switch (argv[i][1])
		{
		    case 'c':
			check_only = 1;
			break;

		    case 'v':
			debug_level = argv[i][2]  ?  atoi(&argv[i][2])  :  1;
			break;

		    default:
			fprintf(stderr, "%s: Unknown option. Usage is:\n\t%s\n",
						       argv[0], usage_string);
			exit(1);
		}
	    }
	    else if (argflag)
	    {
		fprintf(stderr, "%s: Too many file names.  Usage is:\n\t%s\n",
							argv[0], usage_string);
		exit(1);
	    }
	    else
	    {
		argflag = TRUE;
		source_file = argv[i];
	    }
	}

	init(argv[0]);
	make_hash_table();
	compile();

	exit(0);
}




X/*
 *	init(progname)
 *
 *	Miscelaneous initialisations
 *
 *	Open source file as standard input
 *	Check for access rights to destination directories
 *	Create any directories which don't exist.
 *
 */

init(progname)
char	*progname;
{
	struct stat	statbuf;
	char		*dirnames = "abcdefghijklmnopqrstuvwxyz0123456789";
	char		*getenv();
	char		dir[2];

	start_time = time(0);

	curr_line = 0;

	if (freopen(source_file, "r", stdin) == NULL)
	{
	    fprintf(stderr, "%s: Can't open %s\n", progname, source_file);
	    exit(1);
	}

	if (getenv("TERMINFO") != NULL)
	    destination = getenv("TERMINFO");

	if (access(destination, 7) < 0)
	{
	    fprintf(stderr, "%s: %s non-existant or permission denied\n",
							progname, destination);
	    exit(1);
	}

	if (chdir(destination) < 0)
	{
	    fprintf(stderr, "%s: %s is not a directory\n",
							progname, destination);
	    exit(1);
	}
	
	dir[1] = '\0';
	for (dir[0] = *dirnames; *dirnames != '\0'; dir[0] = *(++dirnames))
	{
	    if (stat(dir, &statbuf) < 0)
	    {
		mkdir(dir);
		chmod(dir, 0755);
	    }
	    else if (access(dir, 7) < 0)
	    {
		fprintf(stderr, "%s: %s/%s: Permission denied\n",
						    progname, destination, dir);
		exit(1);
	    }
	    else if ((statbuf.st_mode & S_IFMT) != S_IFDIR)
	    {
		fprintf(stderr, "%s: %s/%s: Not a directory\n",
						    progname, destination, dir);
		exit(1);
	    }
	}
}



X/*
 *	mkdir(dirname)
 *
 *	forks and execs the mkdir program to create the given directory
 *
 */

mkdir(dirname)
char	*dirname;
{
	int	fork_rtn;
	int	status;

	fork_rtn = fork();

	switch (fork_rtn)
	{
	    case 0:		/* Child */
		execl("/bin/mkdir", "mkdir", dirname, 0);
		exit(1);

	    case -1:		/* Error */
		fprintf(stderr, "compile: SYSTEM ERROR!! Fork failed!!!\n");
		abort();

	    default:
		wait(&status);
		if (status != 0)
		    syserr_abort("mkdir returned bad status");
		break;
	}
}
//go.sysin dd *
echo 'x - =src/comp_parse.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/comp_parse.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	comp_parse.c -- The high-level (ha!) parts of the compiler,
 *			that is, the routines which drive the scanner,
 *			etc.
 *
 *   $Log:	comp_parse.c,v $
 * Revision 3.1  84/12/13  11:19:32  john
 * Revisions by Mark Horton
 * 
 * Revision 2.1  82/10/25  14:45:43  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:16:39  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:29:39  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:09:53  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:37:12  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header: comp_parse.c,v 3.1 84/12/13 11:19:32 john Exp $";

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include "compiler.h"
#include "term.h"
#include "object.h"


char	*string_table;
int	next_free;	/* next free character in string_table */
int	table_size = 0; /* current string_table size */
short	term_names;	/* string table offset - current terminal */
int	part2 = 0;	/* set to allow old compiled defns to be used */
int	complete = 0;	/* 1 if entry done with no forward uses */

struct use_item
{
	long	offset;
	struct use_item	*fptr, *bptr;
};

struct use_header
{
	struct use_item	*head, *tail;
};

struct use_header	use_list = {NULL, NULL};
int			use_count = 0;

X/*
 *  The use_list is a doubly-linked list with NULLs terminating the lists:
 *
 *	   use_item    use_item    use_item
 *	  ---------   ---------   ---------
 *	  |       |   |       |   |       |   offset
 *        |-------|   |-------|   |-------|
 *	  |   ----+-->|   ----+-->|  NULL |   fptr
 *	  |-------|   |-------|   |-------|
 *	  |  NULL |<--+----   |<--+----   |   bptr
 *	  ---------   ---------   ---------
 *	  ^                       ^
 *	  |  ------------------   |
 *	  |  |       |        |   |
 *	  +--+----   |    ----+---+
 *	     |       |        |
 *	     ------------------
 *	       head     tail
 *	          use_list
 *
 */


X/*
 *	compile()
 *
 *	Main loop of the compiler.
 *
 *	get_token()
 *	if curr_token != NAMES
 *	    err_abort()
 *	while (not at end of file)
 *	    do an entry
 *
 */

compile()
{
	char			line[1024];
	int			token_type;
	struct use_item	*ptr;
	int			old_use_count;

	token_type = get_token();

	if (token_type != NAMES)
	    err_abort("File does not start with terminal names in column one");
	
	while (token_type != EOF)
	    token_type = do_entry(NULL);

	DEBUG(2, "Starting handling of forward USE's\n", "");

	for (part2=0; part2<2; part2++) {
	    old_use_count = -1;
	DEBUG(2, "\n\nPART %d\n\n", part2);
	    while (use_list.head != NULL  &&  old_use_count != use_count)
	    {
		old_use_count = use_count;
		for (ptr = use_list.tail; ptr != NULL; ptr = ptr->bptr)
		{
		    fseek(stdin, ptr->offset, 0);
		    reset_input();
		    if ((token_type = get_token()) != NAMES)
			syserr_abort("Token after a seek not NAMES");
		    (void) do_entry(ptr);
		    if (complete)
			dequeue(ptr);
		}

		for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr)
		{
		    fseek(stdin, ptr->offset, 0);
		    reset_input();
		    if ((token_type = get_token()) != NAMES)
			syserr_abort("Token after a seek not NAMES");
		    (void) do_entry(ptr);
		    if (complete)
			dequeue(ptr);
		}
		
		DEBUG(2, "Finished a pass through enqueued forward USE's\n", "");
	    }
	}

	if (use_list.head != NULL)
	{
	    fprintf(stderr, "\nError in following up use-links.  Either there is\n");
	    fprintf(stderr, "a loop in the links or they reference non-existant\n");
	    fprintf(stderr, "terminals.  The following is a list of the entries\n");
	    fprintf(stderr, "involved:\n\n");

	    for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr)
	    {
		fseek(stdin, ptr->offset, 0);
		fgets(line, 1024, stdin);
		fprintf(stderr, "%s", line);
	    }

	    exit(1);
	}
}

dump_list(str)
char *str;
{
	struct use_item *ptr;
	char line[512];

	fprintf(stderr, "dump_list %s\n", str);
	for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr)
	{
		fseek(stdin, ptr->offset, 0);
		fgets(line, 1024, stdin);
		fprintf(stderr, "ptr %x off %d bptr %x fptr %x str %s",
		ptr, ptr->offset, ptr->bptr, ptr->fptr, line);
	}
	fprintf(stderr, "\n");
}



X/*
 *	int
 *	do_entry(item_ptr)
 *
 *	Compile one entry.  During the first pass, item_ptr is NULL.  In pass
 *	two, item_ptr points to the current entry in the use_list.
 *
 *	found-forward-use = FALSE
 *	re-initialise internal arrays
 *	save names in string_table
 *	get_token()
 *	while (not EOF and not NAMES)
 *	    if found-forward-use
 *		do nothing
 *	    else if 'use'
 *		if handle_use() < 0
 *		    found-forward-use = TRUE
 *          else
 *	        check for existance and type-correctness
 *	        enter cap into structure
 *	        if STRING
 *	            save string in string_table
 *	    get_token()
 *      if ! found-forward-use
 *	    clear CANCELS out of the structure
 *	    dump compiled entry into filesystem
 *
 */

int
do_entry(item_ptr)
struct use_item	*item_ptr;
{
	long					entry_offset;
	int					i;
	register int				token_type;
	register struct name_table_entry	*entry_ptr;
	int					found_forward_use = FALSE;
	char					Booleans[BOOLCOUNT];
	short					Numbers[NUMCOUNT],
						Strings[STRCOUNT];

	init_structure(Booleans, Numbers, Strings);
	complete = 0;
	term_names = save_str(curr_token.tk_name);
	DEBUG(2, "Starting '%s'\n", curr_token.tk_name);
	entry_offset = curr_file_pos;

	for (token_type = get_token();
		token_type != EOF  &&  token_type != NAMES;
		token_type = get_token())
	{
	    if (found_forward_use)
		/* do nothing */ ;
	    else if (strcmp(curr_token.tk_name, "use") == 0)
	    {
		if (handle_use(item_ptr, entry_offset,
					Booleans, Numbers, Strings) < 0)
		    found_forward_use = TRUE;
	    }
	    else
	    {
		entry_ptr = find_entry(curr_token.tk_name);

		if (entry_ptr == NOTFOUND) {
		    warning("Unknown Capability - '%s'",
                                                          curr_token.tk_name);
		    continue;
		}


		if (token_type != CANCEL
                                        &&  entry_ptr->nte_type != token_type)
		    warning("Wrong type used for capability '%s'",
							  curr_token.tk_name);
		switch (token_type)
		{
		    case CANCEL:
			switch (entry_ptr->nte_type)
			{
			    case BOOLEAN:
				Booleans[entry_ptr->nte_index] = -2;
				break;

			    case NUMBER:
				Numbers[entry_ptr->nte_index] = -2;
				break;

			    case STRING:
				Strings[entry_ptr->nte_index] = -2;
				break;
			}
			break;
		
		    case BOOLEAN:
			Booleans[entry_ptr->nte_index] = TRUE;
			break;
		    
		    case NUMBER:
			Numbers[entry_ptr->nte_index] =
                                                      curr_token.tk_valnumber;
			break;

		    case STRING:
			Strings[entry_ptr->nte_index] =
                                            save_str(curr_token.tk_valstring);
			break;

		    default:
			warning("Unknown token type");
			panic_mode(',');
			continue;
		}
	    } /* end else cur_token.name != "use" */

	} /* endwhile (not EOF and not NAMES) */

	if (found_forward_use)
	    return(token_type);

	for (i=0; i < BOOLCOUNT; i++)
	{
	    if (Booleans[i] == -2)
		Booleans[i] = FALSE;
	}

	for (i=0; i < NUMCOUNT; i++)
	{
	    if (Numbers[i] == -2)
		Numbers[i] = -1;
	}

	for (i=0; i < STRCOUNT; i++)
	{
	    if (Strings[i] == -2)
		Strings[i] = -1;
	}

	dump_structure(term_names, Booleans, Numbers, Strings);

	complete = 1;
	return(token_type);
}




X/*
 *	enqueue(offset)
 *
 *      Put a record of the given offset onto the use-list.
 *
 */

enqueue(offset)
long	offset;
{
	struct use_item	*item;
	char			*malloc();

	item = (struct use_item *) malloc(sizeof(struct use_item));

	if (item == NULL)
	    syserr_abort("Not enough memory for use_list element");

	item->offset = offset;

	if (use_list.head != NULL)
	{
	    item->bptr = use_list.tail;
	    use_list.tail->fptr = item;
	    item->fptr = NULL;
	    use_list.tail = item;
	}
	else
	{
	    use_list.tail = use_list.head = item;
	    item->fptr = item->bptr = NULL;
	}

	use_count ++;
}




X/*
 *	dequeue(ptr)
 *
 *	remove the pointed-to item from the use_list
 *
 */

dequeue(ptr)
struct use_item	*ptr;
{
	if (ptr->fptr == NULL)
	    use_list.tail = ptr->bptr;
	else
	    (ptr->fptr)->bptr = ptr->bptr;

	if (ptr->bptr == NULL)
	    use_list.head = ptr->fptr;
	else
	    (ptr->bptr)->fptr = ptr->fptr;
	
	use_count --;
}



X/*
 *	dump_structure()
 *
 *	Save the compiled version of a description in the filesystem.
 *
 *	make a copy of the name-list
 *	break it up into first-name and all-but-last-name
 *	creat(first-name)
 *	write object information to first-name
 *	close(first-name)
 *      for each name in all-but-last-name
 *	    link to first-name
 *
 */

dump_structure(term_names, Booleans, Numbers, Strings)
short	term_names;
char	Booleans[];
short	Numbers[];
short	Strings[];
{
	struct stat	statbuf;
	FILE		*fp;
	char		name_list[1024];
	register char	*first_name, *other_names;
	register char	*ptr;
	char		filename[50];
	char		linkname[50];
	extern char check_only;

	strcpy(name_list, term_names + string_table);
	DEBUG(7, "Name list = '%s'\n", name_list);

	first_name = name_list;

	ptr = &name_list[strlen(name_list) - 1];
	other_names = ptr + 1;

	while (ptr > name_list  &&  *ptr != '|')
	    ptr--;

	if (ptr != name_list)
	{
	    *ptr = '\0';

	    for (ptr = name_list; *ptr != '\0'  &&  *ptr != '|'; ptr++)
		;
	    
	    if (*ptr == '\0')
		other_names = ptr;
	    else
	    {
		*ptr = '\0';
		other_names = ptr + 1;
	    }
	}

	if (check_only) {
		DEBUG(1, "Checked %s\n", first_name);
		return;
	}

	DEBUG(7, "First name = '%s'\n", first_name);
	DEBUG(7, "Other names = '%s'\n", other_names);

	if (strlen(first_name) > 100)
	    warning("'%s': terminal name too long.", first_name);

	check_name(first_name);

	sprintf(filename, "%c/%s", first_name[0], first_name);

	if (stat(filename, &statbuf) >= 0  &&  statbuf.st_mtime >= start_time)
	{
	    warning("'%s' defined in more than one entry.", first_name);
	    fprintf(stderr, "Entry being used is '%s'.\n",
			    (unsigned) term_names + string_table);
	}

	unlink(filename);
	fp = fopen(filename, "w");
	if (fp == NULL)
	{
	    perror(filename);
	    syserr_abort("Can't open %s/%s\n", destination, filename);
	}
	DEBUG(1, "Created %s\n", filename);

	if (write_object(fp, term_names, Booleans, Numbers, Strings) < 0)
	{
	    syserr_abort("Error in writing %s/%s", destination, filename);
	}
	fclose(fp);

	while (*other_names != '\0')
	{
	    ptr = other_names++;
	    while (*other_names != '|'  &&  *other_names != '\0')
		other_names++;

	    if (*other_names != '\0')
		*(other_names++) = '\0';

	    if (strlen(ptr) > 100)
	    {
		warning("'%s': terminal name too long.", ptr);
		continue;
	    }

	    sprintf(linkname, "%c/%s", ptr[0], ptr);

	    if (strcmp(filename, linkname) == 0)
	    {
		warning("Terminal name '%s' synonym for itself", first_name);
	    }
	    else if (stat(linkname, &statbuf) >= 0  &&
						statbuf.st_mtime >= start_time)
	    {
		warning("'%s' defined in more than one entry.", ptr);
		fprintf(stderr, "Entry being used is '%s'.\n",
			    (unsigned) term_names + string_table);
	    }
	    else
	    {
		unlink(linkname);
		if (link(filename, linkname) < 0)
		    syserr_abort("Can't link %s to %s", filename, linkname);
		DEBUG(1, "Linked %s\n", linkname);
	    }
	}
}




X/*
 *	int
 *	write_object(fp, term_names, Booleans, Numbers, Strings)
 *
 *	Write out the compiled entry to the given file.
 *	Return 0 if OK or -1 if not.
 *
 */

#define swap(x)		(((x >> 8) & 0377) + 256 * (x & 0377))

#define might_swap(x)	(must_swap()  ?  swap(x)  :  (x))


int
write_object(fp, term_names, Booleans, Numbers, Strings)
XFILE	*fp;
short	term_names;
char	Booleans[];
short	Numbers[];
short	Strings[];
{
    	struct header	header;
	char		*namelist;
	short		namelen;
	char		zero = '\0';
	int		i;

	namelist = term_names + string_table;
	namelen = strlen(namelist) + 1;

	if (must_swap())
	{
	    header.magic = swap(MAGIC);
	    header.name_size = swap(namelen);
	    header.bool_count = swap(BOOLCOUNT);
	    header.num_count = swap(NUMCOUNT);
	    header.str_count = swap(STRCOUNT);
	    header.str_size = swap(next_free);
	}
	else
	{
	    header.magic = MAGIC;
	    header.name_size = namelen;
	    header.bool_count = BOOLCOUNT;
	    header.num_count = NUMCOUNT;
	    header.str_count = STRCOUNT;
	    header.str_size = next_free;
	}

	if (fwrite(&header, sizeof(header), 1, fp) != 1
		||  fwrite(namelist, sizeof(char), namelen, fp) != namelen
		||  fwrite(Booleans, sizeof(char), BOOLCOUNT, fp) != BOOLCOUNT)
	    return(-1);
	
	if ((namelen+BOOLCOUNT) % 2 != 0  &&  fwrite(&zero, sizeof(char), 1, fp) != 1)
	    return(-1);

	if (must_swap())
	{
	    for (i=0; i < NUMCOUNT; i++)
		Numbers[i] = swap(Numbers[i]);
	    for (i=0; i < STRCOUNT; i++)
		Strings[i] = swap(Strings[i]);
	}

	if (fwrite(Numbers, sizeof(short), NUMCOUNT, fp) != NUMCOUNT
	       ||  fwrite(Strings, sizeof(short), STRCOUNT, fp) != STRCOUNT
	       ||  fwrite(string_table, sizeof(char), next_free, fp)
								  != next_free)
	    return(-1);

}



X/*
 *	check_name(name)
 *
 *	Generate an error message if given name does not begin with a
 *	digit or lower-case letter.
 *
 */

check_name(name)
char	*name;
{
	if (! isdigit(name[0])  &&  ! islower(name[0]))
	{
	    fprintf(stderr, "compile: Line %d: Illegal terminal name - '%s'\n",
							    curr_line, name);
	    fprintf(stderr,
			"Terminal names must start with lowercase or digit\n");
	    exit(1);
	}
}



X/*
 *	int
 *	save_str(string)
 *
 *	copy string into next free part of string_table, doing a realloc()
 *	if necessary.  return offset of beginning of string from start of
 *	string_table.
 *
 */

int
save_str(string)
char	*string;
{
	char	*malloc(), *realloc();
	int	old_next_free = next_free;

	if (table_size == 0)
	{
	    if ((string_table = malloc(1024)) == NULL)
		syserr_abort("Out of memory");
	    table_size = 1024;
	    DEBUG(5, "Made initial string table allocation.  Size is %d\n",
								    table_size);
	}

	while (table_size < next_free + strlen(string))
	{
	    if ((string_table = realloc(string_table, table_size + 1024))
									== NULL)
		syserr_abort("Out of memory");
	    table_size += 1024;
	    DEBUG(5, "Extended string table.  Size now %d\n", table_size);
	}

	strcpy(&string_table[next_free], string);
	DEBUG(7, "Saved string '%s' ", string);
	DEBUG(7, "at location %d\n", next_free);
	next_free += strlen(string) + 1;

	return(old_next_free);
}



X/*
 *	init_structure(Booleans, Numbers, Strings)
 *
 *	Initialise the given arrays
 *	Reset the next_free counter to zero.
 *
 */

init_structure(Booleans, Numbers, Strings)
char	Booleans[];
short	Numbers[], Strings[];
{
	int	i;

	for (i=0; i < BOOLCOUNT; i++)
	    Booleans[i] = FALSE;
	
	for (i=0; i < NUMCOUNT; i++)
	    Numbers[i] = -1;

	for (i=0; i < STRCOUNT; i++)
	    Strings[i] = -1;

	next_free = 0;
}



X/*
**	int
**	handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings)
**
**	Merge the compiled file whose name is in cur_token.valstring
**	with the current entry.
**
**		if it's a forward use-link
**	    	    if item_ptr == NULL
**		        queue it up for later handling
**	            else
**		        ignore it (we're already going through the queue)
**	        else it's a backward use-link
**	            read in the object file for that terminal
**	            merge contents with current structure
**
**	Returned value is 0 if it was a backward link and we
**	successfully read it in, -1 if a forward link.
*/

int
handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings)
long		entry_offset;
struct use_item	*item_ptr;
char		Booleans[];
short		Numbers[];
short		Strings[];
{
	struct term	use_term;
	struct stat	statbuf;
	char		filename[50];
        int             i;

	check_name(curr_token.tk_valstring);

	sprintf(filename, "%c/%s", curr_token.tk_valstring[0],
                                                     curr_token.tk_valstring);

	if (stat(filename, &statbuf) < 0  ||  part2==0 && statbuf.st_mtime < start_time)
	{
	    DEBUG(2, "Forward USE to %s", curr_token.tk_valstring);

 	    if (item_ptr == NULL)
 	    {
 		DEBUG(2, " (enqueued)\n", "");
 		enqueue(entry_offset);
 	    }
 	    else 
 		DEBUG(2, " (skipped)\n", "");
	    
	    return(-1);
	}
	else
	{
	    DEBUG(2, "Backward USE to %s\n", curr_token.tk_valstring);
	    if (read_entry(filename, &use_term) < 0)
		syserr_abort("Error in re-reading compiled file %s", filename);

	    for (i=0; i < BOOLCOUNT; i++)
	    {
		if (Booleans[i] == FALSE  &&  use_term.Booleans[i] == TRUE)
		    Booleans[i] = TRUE;
	    }

	    for (i=0; i < NUMCOUNT; i++)
	    {
		if (Numbers[i] == -1  &&  use_term.Numbers[i] != -1)
		    Numbers[i] = use_term.Numbers[i];
	    }

	    for (i=0; i < STRCOUNT; i++)
	    {
		if (Strings[i] == -1  &&  use_term.Strings[i] != (char *) 0)
		    Strings[i] = save_str(use_term.Strings[i]);
	    }

	}
}
//go.sysin dd *
echo 'x - =src/comp_scan.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/comp_scan.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	comp_scan.c --- Lexical scanner for terminfo compiler.
 *
 *   $Log:	RCS/comp_scan.v $
 * Revision 2.1  82/10/25  14:45:55  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:17:12  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:30:03  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:10:06  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:37:46  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/comp_scan.v  Revision 2.1  82/10/25  14:45:55  pavel  Exp$";

#include <stdio.h>
#include <ctype.h>
#include "compiler.h"

#define iswhite(ch)	(ch == ' '  ||  ch == '\t')


static int	first_column;		/* See 'next_char()' below */



X/*
 *	int
 *	get_token()
 *
 *	Scans the input for the next token, storing the specifics in the
 *	global structure 'curr_token' and returning one of the following:
 *
 *		NAMES		A line beginning in column 1.  'name'
 *				will be set to point to everything up to
 *				but not including the first comma on the line.
 *		BOOLEAN		An entry consisting of a name followed by
 *				a comma.  'name' will be set to point to the
 *				name of the capability.
 *		NUMBER		An entry of the form
 *					name#digits,
 *				'name' will be set to point to the capability
 *				name and 'valnumber' to the number given.
 *		STRING		An entry of the form
 *					name=characters,
 *				'name' is set to the capability name and
 *				'valstring' to the string of characters, with
 *				input translations done.
 *		CANCEL		An entry of the form
 *					name@,
 *				'name' is set to the capability name and
 *				'valnumber' to -1.
 *		EOF		The end of the file has been reached.
 *
 */

int
get_token()
{
	long		number;
	int		type;
	register char	ch;
	static char	buffer[1024];
	register char	*ptr;
	int		dot_flag = FALSE;

	while ((ch = next_char()) == '\n'  ||  iswhite(ch))
	    ;
	
	if (ch == EOF)
	    type = EOF;
	else
	{
	    if (ch == '.')
	    {
		dot_flag = TRUE;

		while ((ch = next_char()) == ' '  ||  ch == '\t')
		    ;
	    }

	    if (! isalnum(ch))
	    {
		 warning("Illegal character - '%c'", ch);
		 panic_mode(',');
	    }

	    ptr = buffer;
	    *(ptr++) = ch;

	    if (first_column)
	    {
		while ((ch = next_char()) != ',' && ch != '\n' && ch != EOF)
		    *(ptr++) = ch;
		
		if (ch == EOF)
		    err_abort("Premature EOF");
		else if (ch == '\n') {
		    warning("Newline in middle of terminal name");
		    panic_mode(',');
		}
		
		*ptr = '\0';
		curr_token.tk_name = buffer;
		type = NAMES;
	    }
	    else
	    {
		ch = next_char();
		while (isalnum(ch))
		{
		    *(ptr++) = ch;
		    ch = next_char();
		}

		*ptr++ = '\0';
		switch (ch)
		{
		    case ',':
			curr_token.tk_name = buffer;
			type = BOOLEAN;
			break;

		    case '@':
			if (next_char() != ',')
			    warning("Missing comma");
			curr_token.tk_name = buffer;
			type = CANCEL;
			break;

		    case '#':
			number = 0;
			while (isdigit(ch = next_char()))
			    number = number * 10 + ch - '0';
			if (ch != ',')
			    warning("Missing comma");
			curr_token.tk_name = buffer;
			curr_token.tk_valnumber = number;
			type = NUMBER;
			break;
		    
		    case '=':
			ch = trans_string(ptr);
			if (ch != ',')
			    warning("Missing comma");
			curr_token.tk_name = buffer;
			curr_token.tk_valstring = ptr;
			type = STRING;
			break;

		    default:
			warning("Illegal character - '%c'", ch);
		}
	    } /* end else (first_column == FALSE) */
	} /* end else (ch != EOF) */

	if (dot_flag == TRUE)
	    DEBUG(8, "Commented out ", "");

	if (debug_level >= 8)
	{
	    fprintf(stderr, "Token: ");
	    switch (type)
	    {
		case BOOLEAN:
		    fprintf(stderr, "Boolean;  name='%s'\n",
                                                          curr_token.tk_name);
		    break;
		
		case NUMBER:
		    fprintf(stderr, "Number; name='%s', value=%d\n",
				curr_token.tk_name, curr_token.tk_valnumber);
		    break;
		
		case STRING:
		    fprintf(stderr, "String; name='%s', value='%s'\n",
				curr_token.tk_name, curr_token.tk_valstring);
		    break;
		
		case CANCEL:
		    fprintf(stderr, "Cancel; name='%s'\n",
                                                          curr_token.tk_name);
		    break;
		
		case NAMES:

		    fprintf(stderr, "Names; value='%s'\n",
                                                          curr_token.tk_name);
		    break;

		case EOF:
		    fprintf(stderr, "End of file\n");
		    break;

		default:
		    warning("Bad token type");
	    }
	}

	if (dot_flag == TRUE)		/* if commented out, use the next one */
	    type = get_token();

	return(type);
}



X/*
 *	char
 *	next_char()
 *
 *	Returns the next character in the input stream.  Comments and leading
 *	white space are stripped.  The global state variable 'firstcolumn' is
 *	set TRUE if the character returned is from the first column of the input
 * 	line.  The global variable curr_line is incremented for each new line.
 *	The global variable curr_file_pos is set to the file offset of the
 *	beginning of each line.
 *
 */

int	curr_column = -1;
char	line[1024];

char
next_char()
{
	char	*rtn_value;
	long	ftell();

	if (curr_column < 0  ||  curr_column > 1023  ||
						    line[curr_column] == '\0')
	{
	    do
	    {
		curr_file_pos = ftell(stdin);

		if ((rtn_value = fgets(line, 1024, stdin)) != NULL)
		    curr_line++;
	    } while (rtn_value != NULL  &&  line[0] == '#');

	    if (rtn_value == NULL)
		return (EOF);

	    curr_column = 0;
	    while (iswhite(line[curr_column]))
		curr_column++;
	}

	if (curr_column == 0  &&  line[0] != '\n')
	    first_column = TRUE;
	else
	    first_column = FALSE;
	
	return (line[curr_column++]);
}


backspace()
{
	curr_column--;

	if (curr_column < 0)
	    syserr_abort("Backspaced off beginning of line");
}



X/*
 *	reset_input()
 *
 *	Resets the input-reading routines.  Used after a seek has been done.
 *
 */

reset_input()
{
	curr_column = -1;
}



X/*
 *	char
 *	trans_string(ptr)
 *
 *	Reads characters using next_char() until encountering a comma, newline
 *	or end-of-file.  The returned value is the character which caused
 *	reading to stop.  The following translations are done on the input:
 *
 *		^X  goes to  ctrl-X (i.e. X & 037)
 *		{\E,\n,\r,\b,\t,\f}  go to
 *			{ESCAPE,newline,carriage-return,backspace,tab,formfeed}
 *		{\^,\\}  go to  {carat,backslash}
 *		\ddd (for ddd = up to three octal digits)  goes to
 *							the character ddd
 *
 *		\e == \E
 *		\0 == \200
 *
 */

char
trans_string(ptr)
char	*ptr;
{
	register int	count = 0;
	int		number;
	int		i;
        char		ch;

	while ((ch = next_char()) != ','  &&  ch != EOF)
	{
	    if (ch == '^')
	    {
		ch = next_char();
		if (ch == EOF)
		    err_abort("Premature EOF");

		if (! isprint(ch))
		{
		    warning("Illegal ^ character - '%c'", ch);
		}

		*(ptr++) = ch & 037;
	    }
	    else if (ch == '\\')
	    {
		ch = next_char();
		if (ch == EOF)
		    err_abort("Premature EOF");
		
		if (ch >= '0'  &&  ch <= '7')
		{
		    number = ch - '0';
		    for (i=0; i < 2; i++)
		    {
			ch = next_char();
			if (ch == EOF)
			    err_abort("Premature EOF");
			
			if (ch < '0'  ||  ch > '7')
			{
			    backspace();
			    break;
			}

			number = number * 8 + ch - '0';
		    }

		    if (number == 0)
			number = 0200;
		    *(ptr++) = (char) number;
		}
		else
		{
		    switch (ch)
		    {
			case 'E':
			case 'e':	*(ptr++) = '\033';	break;
			
			case 'l':
			case 'n':	*(ptr++) = '\n';	break;
			
			case 'r':	*(ptr++) = '\r';	break;
			
			case 'b':	*(ptr++) = '\008';	break;

			case 's':	*(ptr++) = ' ';		break;
			
			case 'f':	*(ptr++) = '\014';	break;
			
			case 't':	*(ptr++) = '\t';	break;
			
			case '\\':	*(ptr++) = '\\';	break;
			
			case '^':	*(ptr++) = '^';		break;

			case ',':	*(ptr++) = ',';		break;

			case ':':	*(ptr++) = ':';		break;

			default:
			    warning("Illegal character in \\ sequence");
			    *(ptr++) = ch;
		    } /* endswitch (ch) */
		} /* endelse (ch < '0' ||  ch > '7') */
	    } /* end else if (ch == '\\') */
	    else
	    {
		*(ptr++) = ch;
	    }
	    
	    count ++;

	    if (count > 500)
		warning("Very long string found.  Missing comma?");
	} /* end while */

	*ptr = '\0';

	return(ch);
}

X/*
 * Panic mode error recovery - skip everything until a "ch" is found.
 */
panic_mode(ch)
char ch;
{
	int c;

	for (;;) {
		c = next_char();
		if (c == ch)
			return;
		if (c == EOF);
			return;
	}
}
//go.sysin dd *
echo 'x - =src/compiler.h'
sed 's/^X//' <<'//go.sysin dd *' >=src/compiler.h
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	compiler.h - Global variables and structures for the terminfo
 *			compiler.
 *
 *  $Header:   RCS/compiler.v  Revision 2.1  82/10/25  14:46:04  pavel  Exp$
 *
 *  $Log:	RCS/compiler.v $
Revision 2.1  82/10/25  14:46:04  pavel
Added Copyright Notice

Revision 2.0  82/10/24  15:17:20  pavel
Beta-one Test Release

Revision 1.3  82/08/23  22:30:09  pavel
The REAL Alpha-one Release Version

Revision 1.2  82/08/19  19:10:10  pavel
Alpha Test Release One

Revision 1.1  82/08/12  18:38:11  pavel
Initial revision

 *
 */

#include <stdio.h>

#ifndef TRUE
#define TRUE	1
#define FALSE	0
#endif

#define SINGLE			/* only one terminal (actually none) */

char	*destination;		/* destination directory for object files */

long	start_time;		/* time at start of compilation */
long	time();

int	curr_line;		/* current line # in input */
long	curr_file_pos;		/* file offset of current line */

int	debug_level;		/* level of debugging output */

#define DEBUG(level, fmt, a1) \
		if (debug_level >= level)\
		    fprintf(stderr, fmt, a1);

	/*
	 *	These are the types of tokens returned by the scanner.
	 *	The first three are also used in the hash table of capability
	 *	names.  The scanner returns one of these values after loading
	 *	the specifics into the global structure curr_token.
	 *
	 */

#define BOOLEAN 0		/* Boolean capability */
#define NUMBER 1		/* Numeric capability */
#define STRING 2		/* String-valued capability */
#define CANCEL 3		/* Capability to be cancelled in following tc's */
#define NAMES  4		/* The names for a terminal type */

	/*
	 *	The global structure in which the specific parts of a
	 *	scanned token are returned.
	 *
	 */

struct token
{
	char	*tk_name;		/* name of capability */
	int	tk_valnumber;	/* value of capability (if a number) */
	char	*tk_valstring;	/* value of capability (if a string) */
};

struct token	curr_token;

	/*
	 *	The file comp_captab.c contains an array of these structures,
	 *	one per possible capability.  These are then made into a hash
	 *	table array of the same structures for use by the parser.
	 *
	 */

struct name_table_entry
{
	struct name_table_entry *nte_link;
	char	*nte_name;	/* name to hash on */
	int	nte_type;	/* BOOLEAN, NUMBER or STRING */
	short	nte_index;	/* index of associated variable in its array */
};

extern struct name_table_entry	cap_table[];
extern struct name_table_entry	*cap_hash_table[];

extern int	Captabsize;
extern int	Hashtabsize;

#define NOTFOUND	((struct name_table_entry *) 0)
	/*
	 *	Function types
	 *
	 */

struct name_table_entry	*find_entry();	/* look up entry in hash table */

char	next_char();
char	trans_string();
//go.sysin dd *
exit

sources@genrad.UUCP (12/18/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit".  This code is completely public domain, originally written by Pavel
Curtis of Cornell University.  This version has some small improvements and
bug fixes.

This unit contains:
	The Makefile, the rest of the header files, and awk scripts for
	when the Caps file is modified.

Part 6 will be
	the Caps file, dump.c, and the first installation of the library
	modules.

----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =src
then
    echo 'Making directory "=src"'
    mkdir =src
fi
echo 'x - =src/MKcaptab.awk'
sed 's/^X//' <<'//go.sysin dd *' >=src/MKcaptab.awk
#*********************************************************************
#                         COPYRIGHT NOTICE                           *
#*********************************************************************
#        This software is copyright (C) 1982 by Pavel Curtis         *
#                                                                    *
#        Permission is granted to reproduce and distribute           *
#        this file by any means so long as no fee is charged         *
#        above a nominal handling fee and so long as this            *
#        notice is always included in the copies.                    *
#                                                                    *
#        Other rights are reserved except as explicitly granted      *
#        by written permission of the author.                        *
#                Pavel Curtis                                        *
#                Computer Science Dept.                              *
#                405 Upson Hall                                      *
#                Cornell University                                  *
#                Ithaca, NY 14853                                    *
#                                                                    *
#                Ph- (607) 256-4934                                  *
#                                                                    *
#                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
#                decvax!cornell!pavel       (UUCPnet)                *
#********************************************************************/

#
#  $Header:   RCS/MKcaptab.v  Revision 2.1  82/10/25  14:45:02  pavel  Exp$
#


BEGIN	{
	    print  "/*"
	    print  " *	comp_captab.c -- The names of the capabilities in a form ready for"
	    print  " *		         the making of a hash table for the compiler."
	    print  " *"
	    print  " */"
	    print  ""
	    print  ""
	    print  "#include \"compiler.h\""
	    print  "#include \"term.h\""
	    print  ""
	    print  ""
	    print  "struct name_table_entry	cap_table[] ="
	    print  "{"
	}


$3 == "bool"	{
		    printf "\t0,%15s,\tBOOLEAN,\t%3d,\n", $2, BoolCount++
		}


$3 == "number"	{
		    printf "\t0,%15s,\tNUMBER,\t\t%3d,\n", $2, NumCount++
		}


$3 == "str"	{
		    printf "\t0,%15s,\tSTRING,\t\t%3d,\n", $2, StrCount++
		}


END	{
	    print  "};"
	    print  ""
	    printf "struct name_table_entry *cap_hash_table[%d];\n",\
					(BoolCount + NumCount + StrCount) * 2
	    print  ""
	    printf "int	Hashtabsize = %d;\n",\
					(BoolCount + NumCount + StrCount) * 2
	    printf "int	Captabsize = %d;\n", BoolCount + NumCount + StrCount
	    print  ""
	    print  ""
	    printf "#if (BOOLCOUNT!=%d)||(NUMCOUNT!=%d)||(STRCOUNT!=%d)\n",\
						BoolCount, NumCount, StrCount
	    print  "	--> term.h and comp_captab.c disagree about the <--"
	    print  "	--> numbers of booleans, numbers and/or strings <--"
	    print  "#endif"
	}
//go.sysin dd *
echo 'x - =src/MKnames.awk'
sed 's/^X//' <<'//go.sysin dd *' >=src/MKnames.awk
#*********************************************************************
#                         COPYRIGHT NOTICE                           *
#*********************************************************************
#        This software is copyright (C) 1982 by Pavel Curtis         *
#                                                                    *
#        Permission is granted to reproduce and distribute           *
#        this file by any means so long as no fee is charged         *
#        above a nominal handling fee and so long as this            *
#        notice is always included in the copies.                    *
#                                                                    *
#        Other rights are reserved except as explicitly granted      *
#        by written permission of the author.                        *
#                Pavel Curtis                                        *
#                Computer Science Dept.                              *
#                405 Upson Hall                                      *
#                Cornell University                                  *
#                Ithaca, NY 14853                                    *
#                                                                    *
#                Ph- (607) 256-4934                                  *
#                                                                    *
#                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
#                decvax!cornell!pavel       (UUCPnet)                *
#********************************************************************/

#
#  $Header:   RCS/MKnames.v  Revision 2.1  82/10/25  14:45:06  pavel  Exp$
#

BEGIN		{
			print  "/*" > "boolnames"
			print  " *	dump_names.c - Arrays of capability names for use by the" > "boolnames"
			print  " *			dump program." > "boolnames"
			print  " *" > "boolnames"
			print  " */" > "boolnames"
			print  "" > "boolnames"
			print  "" > "boolnames"
			print  "char	*BoolNames[] = {" > "boolnames"
			print  "char	*NumNames[] = {" > "numnames"
			print  "char	*StrNames[] = {" > "strnames"
		}

$3 == "bool"	{
			printf "\t\t%s,\n", $2 > "boolnames"
		}

$3 == "number"	{
			printf "\t\t%s,\n", $2 > "numnames"
		}

$3 == "str"	{
			printf "\t\t%s,\n", $2 > "strnames"
		}

END		{
			print  "};" > "boolnames"
			print  "" > "boolnames"
			print  "};" > "numnames"
			print  "" > "numnames"
			print  "};" > "strnames"
		}
//go.sysin dd *
echo 'x - =src/MKterm.h.awk'
sed 's/^X//' <<'//go.sysin dd *' >=src/MKterm.h.awk
#*********************************************************************
#                         COPYRIGHT NOTICE                           *
#*********************************************************************
#        This software is copyright (C) 1982 by Pavel Curtis         *
#                                                                    *
#        Permission is granted to reproduce and distribute           *
#        this file by any means so long as no fee is charged         *
#        above a nominal handling fee and so long as this            *
#        notice is always included in the copies.                    *
#                                                                    *
#        Other rights are reserved except as explicitly granted      *
#        by written permission of the author.                        *
#                Pavel Curtis                                        *
#                Computer Science Dept.                              *
#                405 Upson Hall                                      *
#                Cornell University                                  *
#                Ithaca, NY 14853                                    *
#                                                                    *
#                Ph- (607) 256-4934                                  *
#                                                                    *
#                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
#                decvax!cornell!pavel       (UUCPnet)                *
#********************************************************************/

#
# $Header:   RCS/MKterm.h.v  Revision 2.1  82/10/25  14:45:11  pavel  Exp$
#

BEGIN		{
		    print "/*"
		    print "**	term.h -- Definition of struct term"
		    print "*/"
		    print ""
		    print "#ifndef SGTTY"
		    print "#    include \"curses.h\""
		    print "#endif"
		    print ""
		    print "#ifdef SINGLE"
		    print "#	define CUR _first_term."
		    print "#else"
		    print "#	define CUR cur_term->"
		    print "#endif"
		    print ""
		    print ""
		}


$3 == "bool"	{
		    printf "#define %-30s CUR Booleans[%d]\n", $1, BoolCount++
		}

$3 == "number"	{
		    printf "#define %-30s CUR Numbers[%d]\n", $1, NumberCount++
		}

$3 == "str"	{
		    printf "#define %-30s CUR Strings[%d]\n", $1, StringCount++
		}


END		{
			print  ""
			print  ""
			print  "struct term"
			print  "{"
			print  "   char	 *term_names;	/* offset in str_table of terminal names */"
			print  "   char	 *str_table;	/* pointer to string table */"
			print  "   short Filedes;	/* file description being written to */"
			print  "   SGTTY Ottyb,		/* original state of the terminal */"
			print  "	 Nttyb;		/* current state of the terminal */"
			print  ""
			printf "   char		 Booleans[%d];\n", BoolCount
			printf "   short	 Numbers[%d];\n", NumberCount
			printf "   char		 *Strings[%d];\n", StringCount
			print  "};"
			print  ""
			print  "struct term	_first_term;"
			print  "struct term	*cur_term;"
			print  ""
			printf "#define BOOLCOUNT %d\n", BoolCount
			printf "#define NUMCOUNT  %d\n", NumberCount
			printf "#define STRCOUNT  %d\n", StringCount
		}
//go.sysin dd *
echo 'x - =src/Makefile'
sed 's/^X//' <<'//go.sysin dd *' >=src/Makefile
#*********************************************************************
#                         COPYRIGHT NOTICE                           *
#*********************************************************************
#        This software is copyright (C) 1982 by Pavel Curtis         *
#                                                                    *
#        Permission is granted to reproduce and distribute           *
#        this file by any means so long as no fee is charged         *
#        above a nominal handling fee and so long as this            *
#        notice is always included in the copies.                    *
#                                                                    *
#        Other rights are reserved except as explicitly granted      *
#        by written permission of the author.                        *
#                Pavel Curtis                                        *
#                Computer Science Dept.                              *
#                405 Upson Hall                                      *
#                Cornell University                                  *
#                Ithaca, NY 14853                                    *
#                                                                    *
#                Ph- (607) 256-4934                                  *
#                                                                    *
#                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
#                decvax!cornell!pavel       (UUCPnet)                *
#********************************************************************/

# RCSid: $Header:   RCS/Makefile.v  Revision 2.2  82/10/25  15:28:23  pavel  Exp$

SRCDIR= /etc/term
CFLAGS= -O -DSRCDIR='"$(SRCDIR)"'
DFLAGS= -g -DTRACE -DSRCDIR='"$(SRCDIR)"'

SRCS=	comp_main.c comp_hash.c comp_captab.c comp_scan.c comp_error.c \
	comp_parse.c read_entry.c \
	dump.c dump_names.c  \
	lib_setup.c lib_fixterm.c lib_tparm.c lib_tputs.c \
	lib_unctrl.c lib_raw.c lib_vidattr.c lib_trace.c lib_data.c \
	lib_beep.c lib_doupdate.c lib_refresh.c lib_initscr.c lib_newwin.c \
	lib_addch.c lib_addstr.c lib_scroll.c lib_clreol.c lib_touchwin.c \
	lib_mvcur.c lib_delwin.c lib_endwin.c lib_clrbot.c lib_move.c \
	lib_printw.c lib_scanw.c lib_erase.c lib_getch.c lib_options.c \
	lib_box.c lib_clear.c lib_delch.c lib_deleteln.c lib_insch.c \
	lib_insertln.c lib_getstr.c lib_mvwin.c lib_longname.c lib_tstp.c \
	lib_newterm.c lib_set_term.c lib_overlay.c lib_scrreg.c

#
# Normal, optimised object files
#
LIBOBJS= lib_setup.o lib_fixterm.o lib_tparm.o read_entry.o lib_tputs.o \
	lib_unctrl.o lib_raw.o lib_vidattr.o lib_trace.o lib_data.o lib_beep.o \
	lib_doupdate.o lib_refresh.o lib_initscr.o lib_newwin.o lib_addch.o \
	lib_addstr.o lib_scroll.o lib_clreol.o lib_touchwin.o lib_mvcur.o \
	lib_delwin.o lib_endwin.o lib_clrbot.o lib_move.o lib_printw.o \
	lib_scanw.o lib_erase.o lib_getch.o lib_options.o \
	lib_box.o lib_clear.o lib_delch.o lib_deleteln.o lib_insch.o \
	lib_insertln.o lib_getstr.o lib_mvwin.o lib_longname.o lib_tstp.o \
	lib_newterm.o lib_set_term.o lib_overlay.o lib_scrreg.o

#
# Debugging (tracing) object files
#
DLIBOBJS= lib_setup.d lib_fixterm.d lib_tparm.d read_entry.d lib_tputs.d \
	lib_unctrl.d lib_raw.d lib_vidattr.d lib_trace.d lib_data.d lib_beep.d \
	lib_doupdate.d lib_refresh.d lib_initscr.d lib_newwin.d lib_addch.d \
	lib_addstr.d lib_scroll.d lib_clreol.d lib_touchwin.d lib_mvcur.d \
	lib_delwin.d lib_endwin.d lib_clrbot.d lib_move.d lib_printw.d \
	lib_scanw.d lib_erase.d lib_getch.d lib_options.d \
	lib_box.d lib_clear.d lib_delch.d lib_deleteln.d lib_insch.d \
	lib_insertln.d lib_getstr.d lib_mvwin.d lib_longname.d lib_tstp.d \
	lib_newterm.d lib_set_term.d lib_overlay.d lib_scrreg.d

#
# Profiled Optimised object files
#
PLIBOBJS= lib_setup.p lib_fixterm.p lib_tparm.p read_entry.p lib_tputs.p \
	lib_unctrl.p lib_raw.p lib_vidattr.p lib_trace.p lib_data.p lib_beep.p \
	lib_doupdate.p lib_refresh.p lib_initscr.p lib_newwin.p lib_addch.p \
	lib_addstr.p lib_scroll.p lib_clreol.p lib_touchwin.p lib_mvcur.p \
	lib_delwin.p lib_endwin.p lib_clrbot.p lib_move.p lib_printw.p \
	lib_scanw.p lib_erase.p lib_getch.p lib_options.p \
	lib_box.p lib_clear.p lib_delch.p lib_deleteln.p lib_insch.p \
	lib_insertln.p lib_getstr.p lib_mvwin.p lib_longname.p lib_tstp.p \
	lib_newterm.p lib_set_term.p lib_overlay.p lib_scrreg.p

COMPOBJS= comp_main.o comp_hash.o comp_captab.o comp_scan.o comp_error.o \
	comp_parse.o read_entry.o

X.SUFFIXES: .d .p

X.c.d:
	-mv $*.o $*.O
	cc -c $(DFLAGS) $*.c
	mv $*.o $*.d
	-mv $*.O $*.o

X.c.p:
	-mv $*.o $*.O
	cc -pg -c $(CFLAGS) $*.c
	mv $*.o $*.p
	-mv $*.O $*.o

all:	compile dump lib dlib

install: all
	sed -e 's/clude *"curses.h" *$$/clude <ncurses.h>/' term.h > /usr/include/term.h
	sed -e 's/^#include *"terminfo.h" *$$/#include <terminfo.h>/' curses.h > /usr/include/ncurses.h
	cp terminfo.h /usr/include/terminfo.h
	cp unctrl.h /usr/include/unctrl.h
	cp compile $(SRCDIR)/compile
	cp dump $(SRCDIR)/dump
	cp libcurses.a /usr/lib/libncurses.a
	cp libdcurses.a /usr/lib/libdcurses.a
	ranlib /usr/lib/libncurses.a
	ranlib /usr/lib/libdcurses.a

lib:	libcurses.a	
libcurses.a:	${LIBOBJS}
	ar rv libcurses.a ${LIBOBJS}
	ranlib libcurses.a

dlib:	libdcurses.a	
libdcurses.a:	${DLIBOBJS}
	ar rv libdcurses.a ${DLIBOBJS}
	ranlib libdcurses.a

plib:	libpcurses.a	
libpcurses.a:	${PLIBOBJS}
	ar rv libpcurses.a ${PLIBOBJS}
	ranlib libpcurses.a

compile: ${COMPOBJS}
	cc -o compile ${COMPOBJS}

dump: dump.o dump_names.o read_entry.o
	cc -o dump dump.o dump_names.o read_entry.o

lint: ${SRCS}
	lint ${DFLAGS} ${SRCS} > lint.out

term.h: Caps MKterm.h.awk
	awk -f MKterm.h.awk Caps > term.h

comp_captab.c: Caps MKcaptab.awk
	awk -f MKcaptab.awk Caps > comp_captab.c

dump.o: dump.c term.h compiler.h

dump_names.c: Caps MKnames.awk
	awk -f MKnames.awk Caps
	cat boolnames numnames strnames > dump_names.c
	-rm -f boolnames numnames strnames

clean:
	-rm -f *.[od] term.h comp_captab.c tags dump_names.c

tags:	*.c *.h
	ctags *.c *.h

depend:	${SRCS}
	grep "^#include" ${SRCS} \
		| sed 's/\([^:]*\).c:[^"]*"\([^"]*\)".*/\1.o: \2/' \
		| sed '/#include/d' > makedep
	echo '/^# DO NOT DELETE THIS LINE/+2,$$d' > eddep
	echo '$$r makedep' >> eddep
	echo '/^# DO NOT DELETE THIS LINE/+2,$$s/\.o/.d/' >> eddep
	echo '$$r makedep' >> eddep
	echo 'w' >> eddep
	cp Makefile Makefile.bak
	ex - Makefile < eddep
	rm makedep eddep
	echo >> Makefile
	echo "# DEPENDENCIES MUST END AT END OF FILE" >> Makefile
	echo "# IF YOU PUT STUFF HERE, IT WILL GO AWAY" >> Makefile
	echo "# See make depend, above" >> Makefile

# DO NOT DELETE THIS LINE - make depend needs it

comp_main.d: compiler.h
comp_hash.d: compiler.h
comp_hash.d: term.h
comp_captab.d: compiler.h
comp_captab.d: term.h
comp_scan.d: compiler.h
comp_error.d: compiler.h
comp_parse.d: compiler.h
comp_parse.d: term.h
comp_parse.d: object.h
read_entry.d: term.h
read_entry.d: object.h
dump.d: compiler.h
dump.d: term.h
lib_setup.d: curses.h
lib_setup.d: curses.priv.h
lib_setup.d: term.h
lib_fixterm.d: curses.h
lib_fixterm.d: curses.priv.h
lib_fixterm.d: term.h
lib_tparm.d: curses.h
lib_tparm.d: curses.priv.h
lib_tparm.d: term.h
lib_tputs.d: curses.h
lib_tputs.d: curses.priv.h
lib_tputs.d: term.h
lib_raw.d: curses.h
lib_raw.d: curses.priv.h
lib_raw.d: term.h
lib_vidattr.d: curses.h
lib_vidattr.d: curses.priv.h
lib_vidattr.d: term.h
lib_trace.d: term.h
lib_trace.d: curses.h
lib_trace.d: curses.priv.h
lib_data.d: curses.priv.h
lib_data.d: curses.h
lib_data.d: term.h
lib_beep.d: curses.h
lib_beep.d: curses.priv.h
lib_beep.d: term.h
lib_doupdate.d: curses.h
lib_doupdate.d: curses.priv.h
lib_doupdate.d: term.h
lib_refresh.d: curses.h
lib_refresh.d: curses.priv.h
lib_initscr.d: curses.h
lib_initscr.d: curses.priv.h
lib_newwin.d: term.h
lib_newwin.d: curses.h
lib_newwin.d: curses.priv.h
lib_addch.d: curses.h
lib_addch.d: curses.priv.h
lib_addch.d: unctrl.h
lib_addstr.d: curses.h
lib_addstr.d: curses.priv.h
lib_scroll.d: curses.h
lib_scroll.d: curses.priv.h
lib_clreol.d: curses.h
lib_clreol.d: curses.priv.h
lib_touchwin.d: curses.h
lib_touchwin.d: curses.priv.h
lib_mvcur.d: term.h
lib_mvcur.d: curses.h
lib_mvcur.d: curses.priv.h
lib_delwin.d: curses.h
lib_delwin.d: curses.priv.h
lib_endwin.d: term.h
lib_endwin.d: curses.h
lib_endwin.d: curses.priv.h
lib_clrbot.d: curses.h
lib_clrbot.d: curses.priv.h
lib_move.d: curses.h
lib_move.d: curses.priv.h
lib_printw.d: curses.h
lib_printw.d: curses.priv.h
lib_scanw.d: curses.h
lib_scanw.d: curses.priv.h
lib_erase.d: curses.h
lib_erase.d: curses.priv.h
lib_getch.d: curses.h
lib_getch.d: curses.priv.h
lib_options.d: term.h
lib_options.d: curses.h
lib_options.d: curses.priv.h
lib_box.d: curses.h
lib_box.d: curses.priv.h
lib_clear.d: curses.h
lib_clear.d: curses.priv.h
lib_delch.d: curses.h
lib_delch.d: curses.priv.h
lib_delch.d: term.h
lib_deleteln.d: curses.h
lib_deleteln.d: curses.priv.h
lib_insch.d: curses.h
lib_insch.d: curses.priv.h
lib_insertln.d: curses.h
lib_insertln.d: curses.priv.h
lib_getstr.d: curses.h
lib_getstr.d: curses.priv.h
lib_getstr.d: unctrl.h
lib_mvwin.d: curses.h
lib_mvwin.d: curses.priv.h
lib_longname.d: curses.h
lib_longname.d: curses.priv.h
lib_tstp.d: term.h
lib_tstp.d: curses.h
lib_tstp.d: curses.priv.h
lib_newterm.d: curses.h
lib_newterm.d: term.h
lib_newterm.d: curses.priv.h
lib_set_term.d: curses.h
lib_set_term.d: curses.priv.h
lib_set_term.d: term.h
lib_overlay.d: curses.h
lib_overlay.d: curses.priv.h
lib_scrreg.d: curses.h
lib_scrreg.d: curses.priv.h
comp_main.o: compiler.h
comp_hash.o: compiler.h
comp_hash.o: term.h
comp_captab.o: compiler.h
comp_captab.o: term.h
comp_scan.o: compiler.h
comp_error.o: compiler.h
comp_parse.o: compiler.h
comp_parse.o: term.h
comp_parse.o: object.h
read_entry.o: term.h
read_entry.o: object.h
dump.o: compiler.h
dump.o: term.h
lib_setup.o: curses.h
lib_setup.o: curses.priv.h
lib_setup.o: term.h
lib_fixterm.o: curses.h
lib_fixterm.o: curses.priv.h
lib_fixterm.o: term.h
lib_tparm.o: curses.h
lib_tparm.o: curses.priv.h
lib_tparm.o: term.h
lib_tputs.o: curses.h
lib_tputs.o: curses.priv.h
lib_tputs.o: term.h
lib_raw.o: curses.h
lib_raw.o: curses.priv.h
lib_raw.o: term.h
lib_vidattr.o: curses.h
lib_vidattr.o: curses.priv.h
lib_vidattr.o: term.h
lib_trace.o: term.h
lib_trace.o: curses.h
lib_trace.o: curses.priv.h
lib_data.o: curses.priv.h
lib_data.o: curses.h
lib_data.o: term.h
lib_beep.o: curses.h
lib_beep.o: curses.priv.h
lib_beep.o: term.h
lib_doupdate.o: curses.h
lib_doupdate.o: curses.priv.h
lib_doupdate.o: term.h
lib_refresh.o: curses.h
lib_refresh.o: curses.priv.h
lib_initscr.o: curses.h
lib_initscr.o: curses.priv.h
lib_newwin.o: term.h
lib_newwin.o: curses.h
lib_newwin.o: curses.priv.h
lib_addch.o: curses.h
lib_addch.o: curses.priv.h
lib_addch.o: unctrl.h
lib_addstr.o: curses.h
lib_addstr.o: curses.priv.h
lib_scroll.o: curses.h
lib_scroll.o: curses.priv.h
lib_clreol.o: curses.h
lib_clreol.o: curses.priv.h
lib_touchwin.o: curses.h
lib_touchwin.o: curses.priv.h
lib_mvcur.o: term.h
lib_mvcur.o: curses.h
lib_mvcur.o: curses.priv.h
lib_delwin.o: curses.h
lib_delwin.o: curses.priv.h
lib_endwin.o: term.h
lib_endwin.o: curses.h
lib_endwin.o: curses.priv.h
lib_clrbot.o: curses.h
lib_clrbot.o: curses.priv.h
lib_move.o: curses.h
lib_move.o: curses.priv.h
lib_printw.o: curses.h
lib_printw.o: curses.priv.h
lib_scanw.o: curses.h
lib_scanw.o: curses.priv.h
lib_erase.o: curses.h
lib_erase.o: curses.priv.h
lib_getch.o: curses.h
lib_getch.o: curses.priv.h
lib_options.o: term.h
lib_options.o: curses.h
lib_options.o: curses.priv.h
lib_box.o: curses.h
lib_box.o: curses.priv.h
lib_clear.o: curses.h
lib_clear.o: curses.priv.h
lib_delch.o: curses.h
lib_delch.o: curses.priv.h
lib_delch.o: term.h
lib_deleteln.o: curses.h
lib_deleteln.o: curses.priv.h
lib_insch.o: curses.h
lib_insch.o: curses.priv.h
lib_insertln.o: curses.h
lib_insertln.o: curses.priv.h
lib_getstr.o: curses.h
lib_getstr.o: curses.priv.h
lib_getstr.o: unctrl.h
lib_mvwin.o: curses.h
lib_mvwin.o: curses.priv.h
lib_longname.o: curses.h
lib_longname.o: curses.priv.h
lib_tstp.o: term.h
lib_tstp.o: curses.h
lib_tstp.o: curses.priv.h
lib_newterm.o: curses.h
lib_newterm.o: term.h
lib_newterm.o: curses.priv.h
lib_set_term.o: curses.h
lib_set_term.o: curses.priv.h
lib_set_term.o: term.h
lib_overlay.o: curses.h
lib_overlay.o: curses.priv.h
lib_scrreg.o: curses.h
lib_scrreg.o: curses.priv.h

# DEPENDENCIES MUST END AT END OF FILE
# IF YOU PUT STUFF HERE, IT WILL GO AWAY
# See make depend, above
//go.sysin dd *
echo 'x - =src/curses.h'
sed 's/^X//' <<'//go.sysin dd *' >=src/curses.h
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *      curses.h - Main header file for the curses package
 *
 *  $Header:   RCS/curses.v  Revision 2.1  82/10/25  14:46:08  pavel  Exp$
 *
 *  $Log:	RCS/curses.v $
Revision 2.1  82/10/25  14:46:08  pavel
Added Copyright Notice

Revision 2.0  82/10/24  15:17:22  pavel
Beta-one Test Release

Revision 1.4  82/08/23  22:30:13  pavel
The REAL Alpha-one Release Version

Revision 1.3  82/08/20  16:52:46  pavel
XFixed <terminfo.h> bug

Revision 1.2  82/08/19  19:10:13  pavel
Alpha Test Release One

Revision 1.1  82/08/12  18:38:57  pavel
Initial revision

 *
 */

#ifndef WINDOW

#include "terminfo.h"


#define bool    char


#ifndef MINICURSES
    typedef unsigned short  chtype;
#else
    typedef unsigned char   chtype;
#endif  MINICURSES


#ifndef TRUE
#  define TRUE    (1)
#  define FALSE   (0)
#endif

#define ERR     (0)
#define OK      (1)

#define _SUBWIN         01
#define _ENDLINE        02
#define _FULLWIN        04
#define _SCROLLWIN      010

#define _NOCHANGE       -1

struct _win_st {
	short   _cury, _curx;
	short   _maxy, _maxx;
	short   _begy, _begx;
	short   _flags;
	chtype  _attrs;
	bool    _clear;
	bool    _leave;
	bool    _scroll;
	bool    _idlok;
	bool    _use_keypad;    /* 0=no, 1=yes, 2=yes/timeout */
	bool    _use_meta;      /* T=use the meta key */
	bool    _nodelay;       /* T=don't wait for tty input */
	chtype  **_line;
	short   *_firstchar;    /* First changed character in the line */
	short   *_lastchar;     /* Last changed character in the line */
	short   *_numchngd;     /* Number of changes made in the line */
	short	_regtop;	/* Top and bottom of scrolling region */
	short	_regbottom;
};

#define WINDOW  struct _win_st

WINDOW	*stdscr, *curscr;

int	LINES, COLS;

WINDOW  *initscr(), *newwin(), *subwin();
char    *longname();
struct  screen  *newterm(), *set_term();


X/*
 * psuedo functions
 */

#define getyx(win,y,x)   (y = (win)->_cury, x = (win)->_curx)

#define inch()           	winch(stdscr)
#define standout()      	wstandout(stdscr)
#define standend()      	wstandend(stdscr)
#define attron(at)      	wattron(stdscr,at)
#define attroff(at)     	wattroff(stdscr,at)
#define attrset(at)     	wattrset(stdscr,at)

#define winch(win)       	((win)->_line[(win)->_cury][(win)->_curx])
#define wstandout(win)          (wattrset(win,A_STANDOUT))
#define wstandend(win)          (wattrset(win,A_NORMAL))
#define wattron(win,at)         ((win)->_attrs |= (at))
#define wattroff(win,at)        ((win)->_attrs &= ~(at))
#define wattrset(win,at)        ((win)->_attrs = (at))


#ifndef MINICURSES
	/*
	 * psuedo functions for standard screen
	 */
#  define addch(ch)       waddch(stdscr, ch)
#  define getch()         wgetch(stdscr)
#  define addstr(str)     waddstr(stdscr, str)
#  define getstr(str)     wgetstr(stdscr, str)
#  define move(y, x)      wmove(stdscr, y, x)
#  define clear()         wclear(stdscr)
#  define erase()         werase(stdscr)
#  define clrtobot()      wclrtobot(stdscr)
#  define clrtoeol()      wclrtoeol(stdscr)
#  define insertln()      winsertln(stdscr)
#  define deleteln()      wdeleteln(stdscr)
#  define refresh()       wrefresh(stdscr)
#  define insch(c)        winsch(stdscr,c)
#  define delch()         wdelch(stdscr)
#  define setscrreg(t,b)  wsetscrreg(stdscr,t,b)

	    /*
	     * mv functions
	     */
#  define mvwaddch(win,y,x,ch)    (wmove(win,y,x) == ERR ? ERR : waddch(win,ch))
#  define mvwgetch(win,y,x)       (wmove(win,y,x) == ERR ? ERR : wgetch(win))
#  define mvwaddstr(win,y,x,str)  (wmove(win,y,x) == ERR ? ERR \
							 : waddstr(win,str))
#  define mvwgetstr(win,y,x)      (wmove(win,y,x) == ERR ? ERR : wgetstr(win))
#  define mvwinch(win,y,x)        (wmove(win,y,x) == ERR ? ERR : winch(win))
#  define mvwdelch(win,y,x)       (wmove(win,y,x) == ERR ? ERR : wdelch(win))
#  define mvwinsch(win,y,x,c)     (wmove(win,y,x) == ERR ? ERR : winsch(win,c))
#  define mvaddch(y,x,ch)         mvwaddch(stdscr,y,x,ch)
#  define mvgetch(y,x)            mvwgetch(stdscr,y,x)
#  define mvaddstr(y,x,str)       mvwaddstr(stdscr,y,x,str)
#  define mvgetstr(y,x)           mvwgetstr(stdscr,y,x)
#  define mvinch(y,x)             mvwinch(stdscr,y,x)
#  define mvdelch(y,x)            mvwdelch(stdscr,y,x)
#  define mvinsch(y,x,c)          mvwinsch(stdscr,y,x,c)
  
#else MINICURSES

#  define addch			  m_addch
#  define addstr                  m_addstr
#  define erase                   m_erase
#  define clear                   m_clear
#  define refresh                 m_refresh
#  define initscr                 m_initscr
#  define newterm                 m_newterm
#  define mvaddch(y,x,ch)         (move(y,x) == ERR ? ERR : addch(ch))
#  define mvaddstr(y,x,str)       (move(y,x) == ERR ? ERR : addstr(str))

X/*
 * These functions don't exist in minicurses, so we define them
 * to nonexistent functions to help the user catch the error.
 */
#  define box             no_box
#  define clrtobot        no_clrtobot
#  define clrtoeol        no_clrtoeol
#  define delch           no_delch
#  define deleteln        no_deleteln
#  define delwin          no_delwin
#  define getch           no_getch
#  define getstr          no_getstr
#  define insch           no_insch
#  define insertln        no_insertln
#  define longname        no_longname
#  define mvprintw        no_mvprintw
#  define mvscanw         no_mvscanw
#  define mvwin           no_mvwin
#  define mvwprintw       no_mvwprintw
#  define mvwscanw        no_mvwscanw
#  define newwin          no_newwin
#  define overlay         no_overlay
#  define overwrite       no_overwrite
#  define printw          no_printw
#  define putp            no_putp
#  define scanw           no_scanw
#  define scroll          no_scroll
#  define setscrreg       no_setscrreg
#  define subwin          no_subwin
#  define touchwin        no_touchwin
#  define tstp            no_tstp
#  define vidattr         no_vidattr
#  define waddch          no_waddch
#  define waddstr         no_waddstr
#  define wclear          no_wclear
#  define wclrtobot       no_wclrtobot
#  define wclrtoeol       no_wclrtoeol
#  define wdelch          no_wdelch
#  define wdeleteln       no_wdeleteln
#  define werase          no_werase
#  define wgetch          no_wgetch
#  define wgetstr         no_wgetstr
#  define winsch          no_winsch
#  define winsertln       no_winsertln
#  define wmove           no_wmove
#  define wprintw         no_wprintw
#  define wrefresh        no_wrefresh
#  define wscanw          no_wscanw
#  define wsetscrreg      no_wsetscrreg

X/* mv functions that aren't valid */
#  define mvdelch         no_mvwdelch
#  define mvgetch         no_mvwgetch
#  define mvgetstr        no_mvwgetstr
#  define mvinch          no_mvwinch
#  define mvinsch         no_mvwinsch
#  define mvwaddch        no_mvwaddch
#  define mvwaddstr       no_mvaddstr
#  define mvwdelch        no_mvwdelch
#  define mvwgetch        no_mvwgetch
#  define mvwgetstr       no_mvwgetstr
#  define mvwinch         no_mvwinch
#  define mvwinsch        no_mvwinsch

#endif MINICURSES


#ifndef MINICURSES
X/* Funny "characters" enabled for various special function keys for input */
#define KEY_BREAK       0401            /* break key (unreliable) */
#define KEY_DOWN        0402            /* The four arrow keys ... */
#define KEY_UP          0403
#define KEY_LEFT        0404
#define KEY_RIGHT       0405            /* ... */
#define KEY_HOME        0406            /* Home key (upward+left arrow) */
#define KEY_BACKSPACE   0407            /* backspace (unreliable) */
#define KEY_F0          0410            /* Function keys.  Space for 64 */
#define KEY_F(n)        (KEY_F0+(n))    /* keys is reserved. */
#define KEY_DL          0510            /* Delete line */
#define KEY_IL          0511            /* Insert line */
#define KEY_DC          0512            /* Delete character */
#define KEY_IC          0513            /* Insert char or enter insert mode */
#define KEY_EIC         0514            /* Exit insert char mode */
#define KEY_CLEAR       0515            /* Clear screen */
#define KEY_EOS         0516            /* Clear to end of screen */
#define KEY_EOL         0517            /* Clear to end of line */
#define KEY_SF          0520            /* Scroll 1 line forward */
#define KEY_SR          0521            /* Scroll 1 line backwards (reverse) */
#define KEY_NPAGE       0522            /* Next page */
#define KEY_PPAGE       0523            /* Previous page */
#define KEY_STAB        0524            /* Set tab */
#define KEY_CTAB        0525            /* Clear tab */
#define KEY_CATAB       0526            /* Clear all tabs */
#define KEY_ENTER       0527            /* Enter or send (unreliable) */
#define KEY_SRESET      0530            /* soft (partial) reset (unreliable) */
#define KEY_RESET       0531            /* reset or hard reset (unreliable) */
#define KEY_PRINT       0532            /* print or copy */
#define KEY_LL          0533            /* home down or bottom (lower left) */

#endif MINICURSES

#endif WINDOW
//go.sysin dd *
echo 'x - =src/curses.priv.h'
sed 's/^X//' <<'//go.sysin dd *' >=src/curses.priv.h
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	curses.priv.h
 *
 *	Header file for curses library objects which are private to
 *	the library.
 *
 *  $Log:	RCS/curses.priv.v $
Revision 2.1  82/10/25  14:46:17  pavel
Added Copyright Notice

Revision 2.0  82/10/25  13:50:25  pavel
Beta-one Test Release

 *
 */


#include <stdio.h>
#include "curses.h"

#define min(a,b)	((a) > (b)  ?  (b)  :  (a))
#define max(a,b)	((a) < (b)  ?  (b)  :  (a))

#define CHANGED     -1

WINDOW	*newscr;

extern int  _tracing;


struct try
{
        struct try      *child;     /* ptr to child.  NULL if none          */
        struct try      *sibling;   /* ptr to sibling.  NULL if none        */
        char            ch;         /* character at this node               */
        short           value;      /* code of string so far.  NULL if none */
};


struct screen
{
    	FILE		*_ifp;	    /* input file ptr for this terminal     */
    	FILE		*_ofp;	    /* output file ptr for this terminal    */
	struct term	*_term;	    /* used by terminfo stuff               */
	WINDOW		*_curscr;   /* windows specific to a given terminal */
	WINDOW		*_newscr;
        struct try      *_keytry;   /* "Try" for use with keypad mode       */
	char            _backbuf[10]; /* Buffer for pushed back characters  */
	int             _backcnt;   /* How many characters in _backbuf?     */
        int             _cursrow;   /* Row and column of physical cursor    */
        int             _curscol;
	bool		_nl;	    /* True if terminal has CRMOD bit on    */
	bool		_raw;	    /* True if in raw mode                  */
	bool		_cbreak;    /* True if in cbreak mode               */
	bool		_echo;	    /* True if echo on                      */
	bool		_nlmapping; /* True if terminal is really doing     */
				    /* NL mapping (fn of raw and nl)	    */
	int		_costs[9];  /* costs of cursor movements for mvcur  */
	int		_costinit;  /* set if _costs[] is initialized       */
};

struct screen	*SP;

#define MAXCOLUMNS    135
#define MAXLINES      66
#define UNINITIALISED ((struct try * ) -1)
//go.sysin dd *
echo 'x - =src/object.h'
sed 's/^X//' <<'//go.sysin dd *' >=src/object.h
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
** $Header:   RCS/object.v  Revision 2.1  82/10/25  14:49:50  pavel  Exp$
**
**	object.h - Format of compiled terminfo files
**
**		Header (12 bytes), containing information given below
**		Names Section, containing the names of the terminal
**		Boolean Section, containing the values of all of the
**				boolean capabilities
**				A null byte may be inserted here to make
**				sure that the Number Section begins on an
**				even word boundary.
**		Number Section, containing the values of all of the numeric
**				capabilities, each as a short integer
**		String Section, containing short integer offsets into the
**				String Table, one per string capability
**		String Table, containing the actual characters of the string
**				capabilities.
**
**	NOTE that all short integers in the file are stored using VAX/PDP-style
**	byte-swapping, i.e., least-significant byte first.  The code in
**	read_entry() automatically fixes this up on machines which don't use
**	this system (I hope).
**
**  $Log:	RCS/object.v $
Revision 2.1  82/10/25  14:49:50  pavel
Added Copyright Notice

Revision 2.0  82/10/24  15:18:19  pavel
Beta-one Test Release

Revision 1.3  82/08/23  22:31:12  pavel
The REAL Alpha-one Release Version

Revision 1.2  82/08/19  19:10:18  pavel
Alpha Test Release One

Revision 1.1  82/08/12  18:48:55  pavel
Initial revision

**
*/


#define MAGIC	0432

struct header
{
	short	magic;		/* Magic Number (0432)			*/
	short	name_size;	/* Size of names section		*/
	short	bool_count;	/* Number of booleans			*/
	short	num_count;	/* Number of numbers			*/
	short	str_count;	/* Number of strings			*/
	short	str_size;	/* Size of string table			*/
};
//go.sysin dd *
echo 'x - =src/term.h'
sed 's/^X//' <<'//go.sysin dd *' >=src/term.h
X/*
**	term.h -- Definition of struct term
*/

#ifndef SGTTY
#    include "curses.h"
#endif

#ifdef SINGLE
#	define CUR _first_term.
#else
#	define CUR cur_term->
#endif


#define auto_left_margin               CUR Booleans[0]
#define auto_right_margin              CUR Booleans[1]
#define beehive_glitch                 CUR Booleans[2]
#define ceol_standout_glitch           CUR Booleans[3]
#define eat_newline_glitch             CUR Booleans[4]
#define erase_overstrike               CUR Booleans[5]
#define generic_type                   CUR Booleans[6]
#define hard_copy                      CUR Booleans[7]
#define has_meta_key                   CUR Booleans[8]
#define has_status_line                CUR Booleans[9]
#define insert_null_glitch             CUR Booleans[10]
#define memory_above                   CUR Booleans[11]
#define memory_below                   CUR Booleans[12]
#define move_insert_mode               CUR Booleans[13]
#define move_standout_mode             CUR Booleans[14]
#define over_strike                    CUR Booleans[15]
#define status_line_esc_ok             CUR Booleans[16]
#define teleray_glitch                 CUR Booleans[17]
#define tilde_glitch                   CUR Booleans[18]
#define transparent_underline          CUR Booleans[19]
#define xon_xoff                       CUR Booleans[20]
#define columns                        CUR Numbers[0]
#define init_tabs                      CUR Numbers[1]
#define lines                          CUR Numbers[2]
#define lines_of_memory                CUR Numbers[3]
#define magic_cookie_glitch            CUR Numbers[4]
#define padding_baud_rate              CUR Numbers[5]
#define virtual_terminal               CUR Numbers[6]
#define width_status_line              CUR Numbers[7]
#define num_labels                     CUR Numbers[8]
#define label_height                   CUR Numbers[9]
#define label_width                    CUR Numbers[10]
#define back_tab                       CUR Strings[0]
#define bell                           CUR Strings[1]
#define carriage_return                CUR Strings[2]
#define change_scroll_region           CUR Strings[3]
#define clear_all_tabs                 CUR Strings[4]
#define clear_screen                   CUR Strings[5]
#define clr_eol                        CUR Strings[6]
#define clr_eos                        CUR Strings[7]
#define column_address                 CUR Strings[8]
#define command_character              CUR Strings[9]
#define cursor_address                 CUR Strings[10]
#define cursor_down                    CUR Strings[11]
#define cursor_home                    CUR Strings[12]
#define cursor_invisible               CUR Strings[13]
#define cursor_left                    CUR Strings[14]
#define cursor_mem_address             CUR Strings[15]
#define cursor_normal                  CUR Strings[16]
#define cursor_right                   CUR Strings[17]
#define cursor_to_ll                   CUR Strings[18]
#define cursor_up                      CUR Strings[19]
#define cursor_visible                 CUR Strings[20]
#define delete_character               CUR Strings[21]
#define delete_line                    CUR Strings[22]
#define dis_status_line                CUR Strings[23]
#define down_half_line                 CUR Strings[24]
#define enter_alt_charset_mode         CUR Strings[25]
#define enter_blink_mode               CUR Strings[26]
#define enter_bold_mode                CUR Strings[27]
#define enter_ca_mode                  CUR Strings[28]
#define enter_delete_mode              CUR Strings[29]
#define enter_dim_mode                 CUR Strings[30]
#define enter_insert_mode              CUR Strings[31]
#define enter_secure_mode              CUR Strings[32]
#define enter_protected_mode           CUR Strings[33]
#define enter_reverse_mode             CUR Strings[34]
#define enter_standout_mode            CUR Strings[35]
#define enter_underline_mode           CUR Strings[36]
#define erase_chars                    CUR Strings[37]
#define exit_alt_charset_mode          CUR Strings[38]
#define exit_attribute_mode            CUR Strings[39]
#define exit_ca_mode                   CUR Strings[40]
#define exit_delete_mode               CUR Strings[41]
#define exit_insert_mode               CUR Strings[42]
#define exit_standout_mode             CUR Strings[43]
#define exit_underline_mode            CUR Strings[44]
#define flash_screen                   CUR Strings[45]
#define form_feed                      CUR Strings[46]
#define from_status_line               CUR Strings[47]
#define init_1string                   CUR Strings[48]
#define init_2string                   CUR Strings[49]
#define init_3string                   CUR Strings[50]
#define init_file                      CUR Strings[51]
#define insert_character               CUR Strings[52]
#define insert_line                    CUR Strings[53]
#define insert_padding                 CUR Strings[54]
#define key_backspace                  CUR Strings[55]
#define key_catab                      CUR Strings[56]
#define key_clear                      CUR Strings[57]
#define key_ctab                       CUR Strings[58]
#define key_dc                         CUR Strings[59]
#define key_dl                         CUR Strings[60]
#define key_down                       CUR Strings[61]
#define key_eic                        CUR Strings[62]
#define key_eol                        CUR Strings[63]
#define key_eos                        CUR Strings[64]
#define key_f0                         CUR Strings[65]
#define key_f1                         CUR Strings[66]
#define key_f10                        CUR Strings[67]
#define key_f2                         CUR Strings[68]
#define key_f3                         CUR Strings[69]
#define key_f4                         CUR Strings[70]
#define key_f5                         CUR Strings[71]
#define key_f6                         CUR Strings[72]
#define key_f7                         CUR Strings[73]
#define key_f8                         CUR Strings[74]
#define key_f9                         CUR Strings[75]
#define key_home                       CUR Strings[76]
#define key_ic                         CUR Strings[77]
#define key_il                         CUR Strings[78]
#define key_left                       CUR Strings[79]
#define key_ll                         CUR Strings[80]
#define key_npage                      CUR Strings[81]
#define key_ppage                      CUR Strings[82]
#define key_right                      CUR Strings[83]
#define key_sf                         CUR Strings[84]
#define key_sr                         CUR Strings[85]
#define key_stab                       CUR Strings[86]
#define key_up                         CUR Strings[87]
#define keypad_local                   CUR Strings[88]
#define keypad_xmit                    CUR Strings[89]
#define lab_f0                         CUR Strings[90]
#define lab_f1                         CUR Strings[91]
#define lab_f10                        CUR Strings[92]
#define lab_f2                         CUR Strings[93]
#define lab_f3                         CUR Strings[94]
#define lab_f4                         CUR Strings[95]
#define lab_f5                         CUR Strings[96]
#define lab_f6                         CUR Strings[97]
#define lab_f7                         CUR Strings[98]
#define lab_f8                         CUR Strings[99]
#define lab_f9                         CUR Strings[100]
#define meta_off                       CUR Strings[101]
#define meta_on                        CUR Strings[102]
#define newline                        CUR Strings[103]
#define pad_char                       CUR Strings[104]
#define parm_dch                       CUR Strings[105]
#define parm_delete_line               CUR Strings[106]
#define parm_down_cursor               CUR Strings[107]
#define parm_ich                       CUR Strings[108]
#define parm_index                     CUR Strings[109]
#define parm_insert_line               CUR Strings[110]
#define parm_left_cursor               CUR Strings[111]
#define parm_right_cursor              CUR Strings[112]
#define parm_rindex                    CUR Strings[113]
#define parm_up_cursor                 CUR Strings[114]
#define pkey_key                       CUR Strings[115]
#define pkey_local                     CUR Strings[116]
#define pkey_xmit                      CUR Strings[117]
#define print_screen                   CUR Strings[118]
#define prtr_off                       CUR Strings[119]
#define prtr_on                        CUR Strings[120]
#define repeat_char                    CUR Strings[121]
#define reset_1string                  CUR Strings[122]
#define reset_2string                  CUR Strings[123]
#define reset_3string                  CUR Strings[124]
#define reset_file                     CUR Strings[125]
#define restore_cursor                 CUR Strings[126]
#define row_address                    CUR Strings[127]
#define save_cursor                    CUR Strings[128]
#define scroll_forward                 CUR Strings[129]
#define scroll_reverse                 CUR Strings[130]
#define set_attributes                 CUR Strings[131]
#define set_tab                        CUR Strings[132]
#define set_window                     CUR Strings[133]
#define tab                            CUR Strings[134]
#define to_status_line                 CUR Strings[135]
#define underline_char                 CUR Strings[136]
#define up_half_line                   CUR Strings[137]
#define init_prog                      CUR Strings[138]
#define key_a1                         CUR Strings[139]
#define key_a3                         CUR Strings[140]
#define key_b2                         CUR Strings[141]
#define key_c1                         CUR Strings[142]
#define key_c3                         CUR Strings[143]
#define prtr_non                       CUR Strings[144]
#define char_padding                   CUR Strings[145]
#define acs_chars                      CUR Strings[146]
#define plab_norm                      CUR Strings[147]


struct term
{
   char	 *term_names;	/* offset in str_table of terminal names */
   char	 *str_table;	/* pointer to string table */
   short Filedes;	/* file description being written to */
   SGTTY Ottyb,		/* original state of the terminal */
	 Nttyb;		/* current state of the terminal */

   char		 Booleans[21];
   short	 Numbers[11];
   char		 *Strings[148];
};

struct term	_first_term;
struct term	*cur_term;

#define BOOLCOUNT 21
#define NUMCOUNT  11
#define STRCOUNT  148
//go.sysin dd *
echo 'x - =src/terminfo.h'
sed 's/^X//' <<'//go.sysin dd *' >=src/terminfo.h
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *  $Header:   RCS/terminfo.v  Revision 2.1  82/10/25  14:49:59  pavel  Exp$
 *
 *	terminfo.h - those things needed for programs runnning at the
 *			terminfo level.
 *
 *  $Log:	RCS/terminfo.v $
Revision 2.1  82/10/25  14:49:59  pavel
Added Copyright Notice

Revision 2.0  82/10/24  15:18:26  pavel
Beta-one Test Release

Revision 1.4  82/08/23  22:31:21  pavel
The REAL Alpha-one Release Version

Revision 1.3  82/08/19  19:24:11  pavel
Alpha Test Release One

Revision 1.2  82/08/19  19:10:56  pavel
Alpha Test Release One

Revision 1.1  82/08/15  16:42:20  pavel
Initial revision

 *
 */

#ifndef A_STANDOUT

#include <stdio.h>
#include <sgtty.h>

#define SGTTY	struct sgttyb

    /* Video attributes */
#define A_NORMAL	0000000
#define A_ATTRIBUTES	0377600
#define A_CHARTEXT	0000177

#define A_STANDOUT	0000200
#define A_UNDERLINE	0000400

#ifndef MINICURSES
#  define A_REVERSE	0001000
#  define A_BLINK	0002000
#  define A_DIM		0004000
#  define A_BOLD	0010000
#  define A_INVIS	0020000
#  define A_PROTECT	0040000
#  define A_ALTCHARSET	0100000
#endif MINICURSES

extern char	ttytype[];
#define NAMESIZE	256
#endif
//go.sysin dd *
echo 'x - =src/unctrl.h'
sed 's/^X//' <<'//go.sysin dd *' >=src/unctrl.h
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 * unctrl.h
 *
 * $Header:   RCS/unctrl.v  Revision 2.1  82/10/25  14:50:04  pavel  Exp$
 *
 * $Log:	RCS/unctrl.v $
Revision 2.1  82/10/25  14:50:04  pavel
Added Copyright Notice

Revision 2.0  82/10/24  15:18:28  pavel
Beta-one Test Release

Revision 1.3  82/08/23  22:31:24  pavel
The REAL Alpha-one Release Version

Revision 1.2  82/08/19  19:10:59  pavel
Alpha Test Release One

Revision 1.1  82/08/19  19:04:26  pavel
Initial revision

 */

extern char	*_unctrl[];

# define	unctrl(ch)	(_unctrl[(unsigned) ch])
//go.sysin dd *
exit

sources@genrad.UUCP (12/19/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit".  This code is completely public domain, originally written by Pavel
Curtis of Cornell University.  This version has some small improvements and
bug fixes.

This unit contains:
	The Caps file (the capability database master file)
	dump.c
	the first installation of the lib files.

Parts 7, 8 and 9 will be the rest of the library sources.

----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =src
then
    echo 'Making directory "=src"'
    mkdir =src
fi
echo 'x - =src/Caps'
sed 's/^X//' <<'//go.sysin dd *' >=src/Caps
#*********************************************************************
#                         COPYRIGHT NOTICE                           *
#*********************************************************************
#        This software is copyright (C) 1982 by Pavel Curtis         *
#                                                                    *
#        Permission is granted to reproduce and distribute           *
#        this file by any means so long as no fee is charged         *
#        above a nominal handling fee and so long as this            *
#        notice is always included in the copies.                    *
#                                                                    *
#        Other rights are reserved except as explicitly granted      *
#        by written permission of the author.                        *
#                Pavel Curtis                                        *
#                Computer Science Dept.                              *
#                405 Upson Hall                                      *
#                Cornell University                                  *
#                Ithaca, NY 14853                                    *
#                                                                    *
#                Ph- (607) 256-4934                                  *
#                                                                    *
#                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
#                decvax!cornell!pavel       (UUCPnet)                *
#********************************************************************/

# $Header:   RCS/Caps.v  Revision 2.1  82/10/25  14:45:23  pavel  Exp$
#
#       Format for the Caps file:
#               variable_name    "capname"   type   Comment
#
#       where variable_name is the name of the variable used by a
#       programmer capname is the name used inside the /etc/terminfo
#       file type is one of bool, number or str and Comment is the text
#       of the comment which will go in term.h.
#
#       All blank lines and lines beginning with '#' are ignored.
#
#       >>   NOTE!!!  New capabilities \must/ be placed at the end of
#       >>>> the appropriate list (e.g. bools, numbers, strings).
#       >>>> This allows previous versions of programs to still function
#	>>   \without/ recompilation.
#

auto_left_margin        "bw"     bool   cub1 wraps from column 0 to last column
auto_right_margin       "am"     bool   Terminal has automatic margins
beehive_glitch          "xsb"    bool   Beehive (f1=escape, f2=ctrl C)
ceol_standout_glitch    "xhp"    bool   Standout not erased by overwriting (hp)
eat_newline_glitch      "xenl"   bool   newline ignored after 80 cols (Concept)
erase_overstrike        "eo"     bool   Can erase overstrikes with a blank
generic_type            "gn"     bool   Generic line type (e.g. dialup, switch).
hard_copy               "hc"     bool   Hardcopy terminal
has_meta_key            "km"     bool   Has a meta key (shift, sets parity bit)
has_status_line         "hs"     bool   Has extra "status line"
insert_null_glitch      "in"     bool   Insert mode distinguishes nulls
memory_above            "da"     bool   Display may be retained above the screen
memory_below            "db"     bool   Display may be retained below the screen
move_insert_mode        "mir"    bool   Safe to move while in insert mode
move_standout_mode      "msgr"   bool   Safe to move in standout modes
over_strike             "os"     bool   Terminal overstrikes
status_line_esc_ok      "eslok"  bool   Escape can be used on the status line
teleray_glitch          "xt"     bool   Tabs destructive, magic so char (Teleray 1061)
tilde_glitch            "hz"     bool   Hazeltine; can't print ~'s
transparent_underline   "ul"     bool   underline character overstrikes
xon_xoff                "xon"    bool   Terminal uses xon/xoff handshaking

columns              "cols"   number  Number of columns in a line
init_tabs	     "it"     number  Tabs initially every # spaces
lines                "lines"  number  Number of lines on screen or page
lines_of_memory      "lm"     number  Lines of memory if > lines. 0 means varies
magic_cookie_glitch  "xmc"    number  Number of blank chars left by smso or rmso
padding_baud_rate    "pb"     number  Lowest baud rate where cr/nl padding needed
virtual_terminal     "vt"     number  Virtual terminal number (CB/Unix)
width_status_line    "wsl"    number  No. columns in status line
num_labels           "nlab"   number  No. of labels on screen (start at 1)
label_height         "lh"     number  No. rows in each label
label_width          "lw"     number  No. cols in each label

back_tab                "cbt"    str    Back tab (P)
bell                    "bel"    str    Audible signal (bell) (P)
carriage_return         "cr"     str    Carriage return (P*)
change_scroll_region    "csr"    str    change to lines #1 through #2 (vt100) (PG)
clear_all_tabs          "tbc"    str    Clear all tab stops. (P)
clear_screen            "clear"  str    Clear screen (P*)
clr_eol                 "el"     str    Clear to end of line (P)
clr_eos                 "ed"     str    Clear to end of display (P*)
column_address          "hpa"    str    Set cursor column (PG)
command_character       "CC"     str    Term. settable cmd char in prototype
cursor_address          "cup"    str    Cursor motion to row #1 col #2 (PG)
cursor_down             "cud1"   str    Down one line
cursor_home             "home"   str    Home cursor (if no cup)
cursor_invisible        "civis"  str    Make cursor invisible
cursor_left             "cub1"   str    Move cursor left one space.
cursor_mem_address      "mrcup"  str    Memory relative cursor addressing.
cursor_normal           "cnorm"  str    Make cursor appear normal (undo vs/vi)
cursor_right            "cuf1"   str    Non-destructive space (cursor right)
cursor_to_ll            "ll"     str    Last line, first column (if no cup)
cursor_up               "cuu1"   str    Upline (cursor up)
cursor_visible          "cvvis"  str    Make cursor very visible
delete_character        "dch1"   str    Delete character (P*)
delete_line             "dl1"    str    Delete line (P*)
dis_status_line         "dsl"    str    Disable status line
down_half_line          "hd"     str    Half-line down (forward 1/2 linefeed)
enter_alt_charset_mode  "smacs"  str    Start alternate character set (P)
enter_blink_mode        "blink"  str    Turn on blinking
enter_bold_mode         "bold"   str    Turn on bold (extra bright) mode
enter_ca_mode           "smcup"  str    String to end programs that use cup
enter_delete_mode       "smdc"   str    Delete mode (enter)
enter_dim_mode          "dim"    str    Turn on half-bright mode
enter_insert_mode       "smir"   str    Insert mode (enter);
enter_secure_mode       "invis"  str    Turn on blank mode (chars invisible)
enter_protected_mode    "prot"   str    Turn on protected mode
enter_reverse_mode      "rev"    str    Turn on reverse video mode
enter_standout_mode     "smso"   str    Begin stand out mode
enter_underline_mode    "smul"   str    Start underscore mode
erase_chars             "ech"    str    Erase #1 characters (PG)
exit_alt_charset_mode   "rmacs"  str    End alternate character set (P)
exit_attribute_mode     "sgr0"   str    Turn off all attributes
exit_ca_mode            "rmcup"  str    String to begin programs that use cup
exit_delete_mode        "rmdc"   str    End delete mode
exit_insert_mode        "rmir"   str    End insert mode;
exit_standout_mode      "rmso"   str    End stand out mode
exit_underline_mode     "rmul"   str    End underscore mode
flash_screen            "flash"  str    Visible bell (may not move cursor)
form_feed               "ff"     str    Hardcopy terminal page eject (P*)
from_status_line        "fsl"    str    Return from status line
init_1string            "is1"    str    Terminal initialization string
init_2string            "is2"    str    Terminal initialization string
init_3string            "is3"    str    Terminal initialization string
init_file               "if"     str    Name of file containing is
insert_character        "ich1"   str    Insert character (P)
insert_line             "il1"    str    Add new blank line (P*)
insert_padding          "ip"     str    Insert pad after character inserted (P*)
key_backspace           "kbs"    str    Sent by backspace key
key_catab               "ktbc"   str    Sent by clear-all-tabs key.
key_clear               "kclr"   str    Sent by clear screen or erase key.
key_ctab                "kctab"  str    Sent by clear-tab key
key_dc                  "kdch1"  str    Sent by delete character key.
key_dl                  "kdl1"   str    Sent by delete line key.
key_down                "kcud1"  str    Sent by terminal down arrow key
key_eic                 "krmir"  str    Sent by rmir or smir in insert mode.
key_eol                 "kel"    str    Sent by clear-to-end-of-line key.
key_eos                 "ked"    str    Sent by clear-to-end-of-screen key.
key_f0                  "kf0"    str    Sent by function key f0.
key_f1                  "kf1"    str    Sent by function key f1.
key_f10                 "kf10"   str    Sent by function key f10.
key_f2                  "kf2"    str    Sent by function key f2.
key_f3                  "kf3"    str    Sent by function key f3.
key_f4                  "kf4"    str    Sent by function key f4.
key_f5                  "kf5"    str    Sent by function key f5.
key_f6                  "kf6"    str    Sent by function key f6.
key_f7                  "kf7"    str    Sent by function key f7.
key_f8                  "kf8"    str    Sent by function key f8.
key_f9                  "kf9"    str    Sent by function key f9.
key_home                "khome"  str    Sent by home key.
key_ic                  "kich1"  str    Sent by ins char/enter ins mode key.
key_il                  "kil1"   str    Sent by insert line.
key_left                "kcub1"  str    Sent by terminal left arrow key
key_ll			"kll"	 str	Sent by "home down" key (lower left)
key_npage               "knp"    str    Sent by next-page key
key_ppage               "kpp"    str    Sent by previous-page key
key_right               "kcuf1"  str    Sent by terminal right arrow key
key_sf                  "kind"   str    Sent by scroll-forward/down key
key_sr                  "kri"    str    Sent by scroll-backward/up key
key_stab                "khts"   str    Sent by set-tab key
key_up                  "kcuu1"  str    Sent by terminal up arrow key
keypad_local            "rmkx"   str    Out of "keypad transmit" mode
keypad_xmit             "smkx"   str    Put terminal in "keypad transmit" mode
lab_f0                  "lf0"    str    Labels on function key f0 if not f0
lab_f1                  "lf1"    str    Labels on function key f1 if not f1
lab_f10                 "lf10"   str    Labels on function key f10 if not f10
lab_f2                  "lf2"    str    Labels on function key f2 if not f2
lab_f3                  "lf3"    str    Labels on function key f3 if not f3
lab_f4                  "lf4"    str    Labels on function key f4 if not f4
lab_f5                  "lf5"    str    Labels on function key f5 if not f5
lab_f6                  "lf6"    str    Labels on function key f6 if not f6
lab_f7                  "lf7"    str    Labels on function key f7 if not f7
lab_f8                  "lf8"    str    Labels on function key f8 if not f8
lab_f9                  "lf9"    str    Labels on function key f9 if not f9
meta_off                "rmm"    str    Turn off "meta mode"
meta_on                 "smm"    str    Turn on "meta mode" (8th bit)
newline                 "nel"    str    Newline (behaves like cr followed by lf)
pad_char                "pad"    str    Pad character (rather than null)
parm_dch                "dch"    str    Delete #1 chars (PG*)
parm_delete_line        "dl"     str    Delete #1 lines (PG*)
parm_down_cursor        "cud"    str    Move cursor down #1 lines. (PG*)
parm_ich                "ich"    str    Insert #1 blank chars (PG*)
parm_index		"indn"	 str	Scroll forward #1 lines (PG)
parm_insert_line        "il"     str    Add #1 new blank lines (PG*)
parm_left_cursor        "cub"    str    Move cursor left #1 spaces (PG)
parm_right_cursor       "cuf"    str    Move cursor right #1 spaces. (PG*)
parm_rindex		"rin"	 str	Scroll backward #1 lines (PG)
parm_up_cursor          "cuu"    str    Move cursor up #1 lines. (PG*)
pkey_key                "pfkey"  str    Prog funct key #1 to type string #2
pkey_local              "pfloc"  str    Prog funct key #1 to execute string #2
pkey_xmit               "pfx"    str    Prog funct key #1 to xmit string #2
print_screen            "mc0"    str    Print contents of the screen
prtr_off                "mc4"    str    Turn off the printer
prtr_on                 "mc5"    str    Turn on the printer
repeat_char             "rep"    str    Repeat char #1 #2 times.  (PG*)
reset_1string           "rs1"    str    Reset terminal completely to sane modes.
reset_2string           "rs2"    str    Reset terminal completely to sane modes.
reset_3string           "rs3"    str    Reset terminal completely to sane modes.
reset_file              "rf"     str    Name of file containing reset string.
restore_cursor          "rc"     str    Restore cursor to position of last sc.
row_address             "vpa"    str    Like hpa but sets row. (PG)
save_cursor             "sc"     str    Save cursor position. (P)
scroll_forward          "ind"    str    Scroll text up (P)
scroll_reverse          "ri"     str    Scroll text down (P)
set_attributes          "sgr"    str    Define the video attributes (PG9)
set_tab                 "hts"    str    Set a tab in all rows, current column.
set_window              "wind"   str    Current window is lines #1-#2 cols #3-#4
tab                     "ht"     str    Tab to next 8 space hardware tab stop.
to_status_line          "tsl"    str    Go to status line
underline_char          "uc"     str    Underscore one char and move past it
up_half_line            "hu"     str    Half-line up (reverse 1/2 linefeed)
init_prog               "iprog"  str    Path name of program for init
key_a1                  "ka1"    str    Upper left of keypad
key_a3                  "ka3"    str    Upper right of keypad
key_b2                  "kb2"    str    Center of keypad
key_c1                  "kc1"    str    Lower left of keypad
key_c3                  "kc3"    str    Lower right of keypad
prtr_non                "mc5p"   str    Turn on the printer for #1 bytes.
char_padding            "rmp"    str    Like ip but when in replace mode
acs_chars               "acsc"   str    Graphics char set pairs aAbBcC - defn=vt100
plab_norm               "pln"    str    Prog label #1 to show string #2
//go.sysin dd *
echo 'x - =src/dump.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/dump.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	dump.c - dump the contents of a compiled terminfo file in a
 *		 human-readable format.
 *
 *  $Log:	RCS/dump.v $
 * Revision 2.1  82/10/25  14:46:20  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:17:29  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:30:18  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:12:50  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:39:19  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/dump.v  Revision 2.1  82/10/25  14:46:20  pavel  Exp$";

#include "compiler.h"
#include "term.h"

char	*BoolNames[], *NumNames[], *StrNames[];


main(argc, argv)
int	argc;
char	*argv[];
{
	int	i, j;
	int	cur_column;
	char	buffer[1024];

	for (j=1; j < argc; j++)
	{
	    if (read_entry(argv[j], &_first_term) < 0)
	    {
		fprintf(stderr, "read_entry bombed on %s\n", argv[j]);
		abort();
	    }

	    printf("%s,\n", _first_term.term_names);
	    putchar('\t');
	    cur_column = 9;

	    for (i=0; i < BOOLCOUNT; i++)
	    {
		if (_first_term.Booleans[i] == TRUE)
		{
		    if (cur_column > 9
				&&  cur_column + strlen(BoolNames[i]) + 2 > 79)
		    {
			printf("\n\t");
			cur_column = 9;
		    }
		    printf("%s, ", BoolNames[i]);
		    cur_column += strlen(BoolNames[i]) + 2;
		}
	    }

	    for (i=0; i < NUMCOUNT; i++)
	    {
		if (_first_term.Numbers[i] != -1)
		{
		    if (cur_column > 9
				&&  cur_column + strlen(NumNames[i]) + 5 > 79)
		    {
			printf("\n\t");
			cur_column = 9;
		    }
		    printf("%s#%d, ", NumNames[i], _first_term.Numbers[i]);
		    cur_column += strlen(NumNames[i]) + 5;
		}
	    }

	    for (i=0; i < STRCOUNT; i++)
	    {
		if (_first_term.Strings[i])
		{
		    sprintf(buffer, "%s=%s, ", StrNames[i],
							_first_term.Strings[i]);
		    expand(buffer);
		    if (cur_column > 9  &&  cur_column + strlen(buffer) > 79)
		    {
			printf("\n\t");
			cur_column = 9;
		    }
		    printf("%s", buffer);
		    cur_column += strlen(buffer);
		}
	    }

	    putchar('\n');
	}
}


typedef unsigned char	uchar;

expand(str)
uchar	*str;
{
    	char	buffer[1024];
	int	bufp;
	uchar	*ptr;

	bufp = 0;
	ptr = str;
	while (*str)
	{
	    if (*str < ' ')
	    {
		buffer[bufp++] = '^';
		buffer[bufp++] = *str + '@';
	    }
	    else if (*str < '\177')
		buffer[bufp++] = *str;
	    else
	    {
		sprintf(&buffer[bufp], "\\%03o", *str);
		bufp += 4;
	    }

	    str++;
	}

	buffer[bufp] = '\0';
	strcpy(ptr, buffer);
}
//go.sysin dd *
echo 'x - =src/lib_addch.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_addch.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_addch.c
**
**	The routine waddch().
**
** $Log:	RCS/lib_addch.v $
 * Revision 2.1  82/10/25  14:46:23  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:19:46  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_addch.v  Revision 2.1  82/10/25  14:46:23  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"
#include "unctrl.h"


waddch(win, c)
WINDOW	*win;
char	c;
{
	int	x, y;
	int	newx;
	chtype	ch = c;

#ifdef UNDEFINED
	if (_tracing)
	    _tracef("waddch(%o,%c) called", win, ch);
#endif

	x = win->_curx;
	y = win->_cury;

	if (y > win->_maxy  ||  x > win->_maxx  ||  y < 0  ||  x < 0)
	    return(ERR);

	switch (ch)
	{
	    case '\t':
		for (newx = x + (8 - (x & 07)); x < newx; x++)
		    if (waddch(win, ' ') == ERR)
			return(ERR);
		return(OK);

	    case '\n':
		wclrtoeol(win);
		if (SP->_nl)
		    x = 0;
		goto newline;

	    case '\r':
		x = 0;
		break;

	    case '\b':
		if (--x < 0)
		    x = 0;
		break;

	    default:
		if (ch < ' ')
		    return(waddstr(win, unctrl(ch)));

		ch |= win->_attrs;

		if (win->_line[y][x] != ch)
		{
		    if (win->_firstchar[y] == _NOCHANGE)
			win->_firstchar[y] = win->_lastchar[y] = x;
		    else if (x < win->_firstchar[y])
			win->_firstchar[y] = x;
		    else if (x > win->_lastchar[y])
			win->_lastchar[y] = x;

		    win->_numchngd[y]++;
		}

		win->_line[y][x++] = ch;
		if (x > win->_maxx)
		{
		    x = 0;
newline:
		    y++;
		    if (y > win->_regbottom)
		    {
			y--;
			if (win->_scroll)
			    scroll(win);
			else
			    return ERR;
		    }
		}
		break;
	}

	win->_curx = x;
	win->_cury = y;

	return(OK);
}
//go.sysin dd *
echo 'x - =src/lib_addstr.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_addstr.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_addstr.c
*
**	The routine waddstr().
**
** $Log:	RCS/lib_addstr.v $
 * Revision 2.1  82/10/25  14:46:26  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:19:59  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_addstr.v  Revision 2.1  82/10/25  14:46:26  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


waddstr(win, str)
WINDOW	*win; 
char	*str;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("waddstr(%o,%o) called", win, str);
#endif

	while (*str)
	{
	    if (waddch(win, *str++) == ERR)
		return(ERR);
	}

	return(OK);
}
//go.sysin dd *
echo 'x - =src/lib_beep.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_beep.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	beep.c
 *
 *	Routines beep() and flash()
 *
 *  $Log:	RCS/lib_beep.v $
 * Revision 2.1  82/10/25  14:46:29  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:17:31  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:30:22  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:11:02  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:40:14  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/lib_beep.v  Revision 2.1  82/10/25  14:46:29  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"
#include "term.h"

static
outc(ch)
char    ch;
{
        putc(ch, SP->_ofp);
}



X/*
 *	beep()
 *
 *	Sound the current terminal's audible bell if it has one.   If not,
 *	flash the screen if possible.
 *
 */

beep()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("beep() called");
#endif
	if (bell)
	    tputs(bell, 1, outc);
	else if (flash_screen)
	    tputs(flash_screen, 1, outc);
}



X/*
 *	flash()
 *
 *	Flash the current terminal's screen if possible.   If not,
 *	sound the audible bell if one exists.
 *
 */

flash()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("flash() called");
#endif
	if (flash_screen)
	    tputs(flash_screen, 1, outc);
	else if (bell)
	    tputs(bell, 1, outc);
}
//go.sysin dd *
echo 'x - =src/lib_box.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_box.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_box.c
**
**	The routine box().
**
** $Log:	RCS/lib_box.v $
 * Revision 2.1  82/10/25  14:46:31  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:20:07  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_box.v  Revision 2.1  82/10/25  14:46:31  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"



box(win, vert, hor)
WINDOW	*win;
char	vert, hor;
{
	int	i;
	int	endy, endx;
	chtype	*fp, *lp;

#ifdef TRACE
	if (_tracing)
	    _tracef("box(%o,%c,%c) called", win, vert, hor);
#endif

	endx = win->_maxx;
	endy = win->_maxy;

	fp = win->_line[0];
	lp = win->_line[endy];

	for (i = 0; i <= endx; i++)
	    fp[i] = lp[i] = hor;

	for (i = 0; i <= endy; i++)
	{
	    win->_line[i][0] = (win->_line[i][endx] = vert);
	    win->_firstchar[i] = 0;
	    win->_lastchar[i] = endx;
	    win->_numchngd[i] += 2;
	}

	win->_numchngd[0] = win->_numchngd[endy] = endx;

	if (! win->_scroll  &&  (win->_flags & _SCROLLWIN))
	    fp[0] = fp[endx] = lp[0] = lp[endx] = ' ';
}
//go.sysin dd *
echo 'x - =src/lib_clear.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_clear.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_clear.c
**
**	The routine wclear().
**
** $Log:	RCS/lib_clear.v $
 * Revision 2.1  82/10/25  14:46:34  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:20:17  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_clear.v  Revision 2.1  82/10/25  14:46:34  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"



wclear(win)
WINDOW	*win;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("wclear(%o) called", win);
#endif

	werase(win);

	win->_clear = TRUE;

	return;
}
//go.sysin dd *
echo 'x - =src/lib_clrbot.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_clrbot.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_clrbot.c
**
**	The routine wclrtobot().
**
** $Log:	RCS/lib_clrbot.v $
 * Revision 2.1  82/10/25  14:46:37  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:20:24  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_clrbot.v  Revision 2.1  82/10/25  14:46:37  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


wclrtobot(win)
WINDOW	*win;
{
	chtype	*ptr, *end, *maxx;
	int	y, startx, minx;
	chtype	blank = ' ' | win->_attrs;

#ifdef TRACE
	if (_tracing)
	    _tracef("wclrtobot(%o) called", win);
#endif

	startx = win->_curx;

	for (y = win->_cury; y <= win->_regbottom; y++)
	{
	    minx = _NOCHANGE;
	    end = &win->_line[y][win->_maxx];

	    for (ptr = &win->_line[y][startx]; ptr <= end; ptr++)
	    {
		if (*ptr != blank)
		{
		    maxx = ptr;
		    if (minx == _NOCHANGE)
			minx = ptr - win->_line[y];
		    *ptr = blank;
		}
	    }

	    if (minx != _NOCHANGE)
	    {
		if (win->_firstchar[y] > minx
					||  win->_firstchar[y] == _NOCHANGE)
		    win->_firstchar[y] = minx;

		if (win->_lastchar[y] < maxx - win->_line[y])
		    win->_lastchar[y] = maxx - win->_line[y];
	    }

	    startx = 0;
	}
}
//go.sysin dd *
echo 'x - =src/lib_clreol.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_clreol.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_clreol.c
**
**	The routine wclrtoeol().
**
** $Log:	RCS/lib_clreol.v $
 * Revision 2.1  82/10/25  14:46:42  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:20:38  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_clreol.v  Revision 2.1  82/10/25  14:46:42  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


wclrtoeol(win)
WINDOW	*win;
{
	chtype	*maxx, *ptr, *end;
	int	y, x, minx;
	chtype	blank = ' ' | win->_attrs;

#ifdef TRACE
	if (_tracing)
	    _tracef("wclrtoeol(%o) called", win);
#endif

	y = win->_cury;
	x = win->_curx;

	end = &win->_line[y][win->_maxx];
	minx = _NOCHANGE;
	maxx = &win->_line[y][x];

	for (ptr = maxx; ptr < end; ptr++)
	{
	    if (*ptr != blank)
	    {
		maxx = ptr;
		if (minx == _NOCHANGE)
		    minx = ptr - win->_line[y];
		*ptr = blank;
		win->_numchngd[y] += 1;
	    }
	}

	if (minx != _NOCHANGE)
	{
	    if (win->_firstchar[y] > minx || win->_firstchar[y] == _NOCHANGE)
		win->_firstchar[y] = minx;

	    if (win->_lastchar[y] < maxx - win->_line[y])
		win->_lastchar[y] = maxx - win->_line[y];
	}
}
//go.sysin dd *
echo 'x - =src/lib_data.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_data.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	lib_data.c - Global data definitions and initialisations
 *
 */


#include "curses.priv.h"
#include "curses.h"
#include "term.h"


char	ttytype[NAMESIZE];

#ifdef TRACE
	int	_tracing = 1;
#else
	int	_tracing = 0;
#endif


struct screen *SP = 0;
//go.sysin dd *
echo 'x - =src/lib_delch.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_delch.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_delch.c
**
**	The routine wdelch().
**
** $Log:	RCS/lib_delch.v $
 * Revision 2.1  82/10/25  14:46:52  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:20:47  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_delch.v  Revision 2.1  82/10/25  14:46:52  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"
#include "term.h"

wdelch(win)
WINDOW	*win;
{
	chtype	*temp1, *temp2;
	chtype	*end;

#ifdef TRACE
	if (_tracing)
	    _tracef("wdelch(%o) called", win);
#endif

	end = &win->_line[win->_cury][win->_maxx];
	temp2 = &win->_line[win->_cury][win->_curx + 1];
	temp1 = temp2 - 1;

	while (temp1 < end)
	    *temp1++ = *temp2++;

	*temp1 = ' ' | win->_attrs;

	win->_lastchar[win->_cury] = win->_maxx;

	if (win->_firstchar[win->_cury] == _NOCHANGE
				   || win->_firstchar[win->_cury] > win->_curx)
	    win->_firstchar[win->_cury] = win->_curx;

	if (delete_character)
	    win->_numchngd += 1;
	else
	    win->_numchngd += win->_maxx - win->_curx + 1;
}
//go.sysin dd *
echo 'x - =src/lib_deleteln.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_deleteln.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_deleteln.c
**
**	The routine wdeleteln().
**
** $Log:	RCS/lib_deleteln.v $
 * Revision 2.1  82/10/25  14:46:55  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:44:03  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_deleteln.v  Revision 2.1  82/10/25  14:46:55  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


wdeleteln(win)
WINDOW	*win;
{
	chtype	*end, *temp;
	int	y;

#ifdef TRACE
	if (_tracing)
	    _tracef("wdeleteln(%o) called", win);
#endif

	temp = win->_line[win->_cury];

	for (y = win->_cury; y < win->_regbottom; y++)
	{
	    win->_line[y] = win->_line[y+1];

	    win->_firstchar[y] = 0;
	    win->_lastchar[y] = win->_maxx;
	    win->_numchngd[y] = win->_maxx;
	}

	win->_line[win->_regbottom] = temp;

	for (end = &(temp[win->_maxx]); temp <= end; )
	    *temp++ = ' ' | win->_attrs;
}
//go.sysin dd *
echo 'x - =src/lib_delwin.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_delwin.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_delwin.c
**
**	The routine delwin().
**
** $Log:	RCS/lib_delwin.v $
 * Revision 2.1  82/10/25  14:47:01  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:44:21  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_delwin.v  Revision 2.1  82/10/25  14:47:01  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


delwin(win)
WINDOW	*win;
{
	int	i;

#ifdef TRACE
	if (_tracing)
	    _tracef("delwin(%o) called", win);
#endif

	if (! (win->_flags & _SUBWIN))
	{
	    for (i = 0; i <= win->_maxy  &&  win->_line[i]; i++)
		cfree(win->_line[i]);
	}

	cfree(win->_numchngd);
	cfree(win->_firstchar);
	cfree(win->_lastchar);
	cfree(win->_line);
	cfree(win);
}
//go.sysin dd *
echo 'x - =src/lib_endwin.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_endwin.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_endwin.c
**
**	The routine endwin().
**
** $Log:	RCS/lib_endwin.v $
 * Revision 2.1  82/10/25  14:47:13  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:45:05  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_endwin.v  Revision 2.1  82/10/25  14:47:13  pavel  Exp$";

#include "term.h"
#include "curses.h"
#include "curses.priv.h"


static
outc(ch)
char	ch;
{
    	putc(ch, SP->_ofp);
}


endwin()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("endwin() called");
#endif

	resetterm();

	mvcur(-1, -1, LINES - 1, 0);

	if (exit_ca_mode)
	    tputs(exit_ca_mode, 1, outc);

	if (curscr  &&  (curscr->_attrs != A_NORMAL))
	{
	    vidputs(A_NORMAL, outc);

	    curscr->_attrs = A_NORMAL;
	}

	fflush(SP->_ofp);
}
//go.sysin dd *
echo 'x - =src/lib_erase.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_erase.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_erase.c
**
**	The routine werase().
**
** $Log:	RCS/lib_erase.v $
 * Revision 2.2  82/11/03  12:27:41  pavel
 * Fixed off-by-one error...  If only I had used an invariant...
 * 
 * Revision 2.1  82/10/25  14:47:17  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:45:12  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_erase.v  Revision 2.2  82/11/03  12:27:41  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"



werase(win)
WINDOW	*win;
{
	int	y;
	chtype	*sp, *end, *start, *maxx;
	int	minx;
	chtype	blank = ' ' | win->_attrs;

#ifdef TRACE
	if (_tracing)
	    _tracef("werase(%o) called", win);
#endif

	for (y = win->_regtop; y <= win->_regbottom; y++)
	{
	    minx = _NOCHANGE;
	    start = win->_line[y];
	    end = &start[win->_maxx];

	    for (sp = start; sp <= end; sp++)
	    {
		if (*sp != blank)
		{
		    maxx = sp;
		    if (minx == _NOCHANGE)
			minx = sp - start;

		    *sp = blank;

		    win->_numchngd[y] += 1;
		}
	    }

	    if (minx != _NOCHANGE)
	    {
		if (win->_firstchar[y] > minx
					    ||  win->_firstchar[y] == _NOCHANGE)
		    win->_firstchar[y] = minx;

		if (win->_lastchar[y] < maxx - win->_line[y])
		    win->_lastchar[y] = maxx - win->_line[y];
	    }
	}

	win->_curx = win->_cury = 0;
}
//go.sysin dd *
echo 'x - =src/lib_fixterm.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_fixterm.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	fixterm.c
 *
 *	Routines:
 *		fixterm()
 *		resetterm()
 *		saveterm()
 *		gettmode()
 *		setterm()
 *		baudrate()
 *		erasechar()
 *		killchar()
 *		flushinp()
 *		savetty()
 *		resetty()
 *
 *  $Log:	RCS/lib_fixterm.v $
 * Revision 2.1  82/10/25  14:47:22  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:17:36  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:30:27  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:11:21  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:40:30  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/lib_fixterm.v  Revision 2.1  82/10/25  14:47:22  pavel  Exp$";

#include <sys/ioctl.h>
#include "curses.h"
#include "curses.priv.h"
#include "term.h"


X/*
 *	fixterm()
 *	resetterm()
 *
 *	fixterm() establishes the tty modes contained in cur_term->Nttyb.
 *	resetterm() establishes those in cur_term->Ottyb.
 *
 */


fixterm()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("fixterm() called");
#endif
        stty(cur_term->Filedes, &cur_term->Nttyb);
}


resetterm()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("resetterm() called");
#endif
        stty(cur_term->Filedes, &cur_term->Ottyb);
}



saveterm()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("saveterm() called");
#endif
	gtty(cur_term->Filedes, &cur_term->Nttyb);
}



X/*
 *	gettmode()
 *	setterm(type)
 *
 *	These are kept around for backward compatibilty.  gettmode() does
 *	nothing.  setterm() results in a proper call to setupterm()
 *
 */

gettmode()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("gettmode() called");
#endif
}


setterm(type)
char	*type;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("setterm() called");
#endif
    	setupterm(type, 1, 0);
}




X/*
 *	erasechar()
 *
 *	Return erase character as given in cur_term->Ottyb.
 *
 */

char
erasechar()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("erasechar() called");
#endif
    return(cur_term->Ottyb.sg_erase);
}



X/*
 *	killchar()
 *
 *	Return kill character as given in cur_term->Ottyb.
 *
 */

char
killchar()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("killchar() called");
#endif
    return(cur_term->Ottyb.sg_kill);
}



X/*
 *	flushinp()
 *
 *	Flush any input on cur_term->Filedes
 *
 */

flushinp()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("flushinp() called");
#endif
        ioctl(cur_term->Filedes, TIOCFLUSH, 0);
    
        if (SP)
	    SP->_backcnt = 0;
}



X/*
 *	int
 *	baudrate()
 *
 *	Returns the current terminal's baud rate.
 *
 */

static int speeds[] =
{
	0, 50, 75, 110, 134, 150, 200, 300, 600,
	1200, 1800, 2400, 4800, 9600, 19200, 38400
};

int
baudrate()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("baudrate() called");
#endif
	return(speeds[cur_term->Nttyb.sg_ospeed]);
}


X/*
**	savetty()  and  resetty()
**
**	Kept around for compatibility.
**	
*/

static struct sgttyb	sgbuf;

savetty()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("savetty() called");
#endif

    gtty(cur_term->Filedes, &sgbuf);
}

resetty()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("resetty() called");
#endif

    stty(cur_term->Filedes, &sgbuf);
}
//go.sysin dd *
exit

sources@genrad.UUCP (12/20/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit".  This code is completely public domain, originally written by Pavel
Curtis of Cornell University.  This version has some small improvements and
bug fixes.

This unit contains:
	more source units of the library.

Part 8 will be
	more source units of the library.

----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =src
then
    echo 'Making directory "=src"'
    mkdir =src
fi
echo 'x - =src/lib_getch.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_getch.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_getch.c
**
**	The routine getch().
**
** $Log:	RCS/lib_getch.v $
 * Revision 2.1  82/10/25  14:47:29  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:45:19  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_getch.v  Revision 2.1  82/10/25  14:47:29  pavel  Exp$";

#include <signal.h>
#include "curses.h"
#include "curses.priv.h"

#define nextc()       (SP->_backcnt > 0  ?  SP->_backbuf[--SP->_backcnt] \
                                         :  getc(SP->_ifp))
				       
#define putback(ch)   SP->_backbuf[SP->_backcnt++] = ch


wgetch(win)
WINDOW	*win;
{
	bool	setHere = FALSE;	/* cbreak mode was set here         */
	short	ch;                     /* 'short' because of keypad codes  */
        short   kgetch();

#ifdef TRACE
	if (_tracing)
	    _tracef("wgetch(%o) called", win);
#endif

	if (! win->_scroll  &&  (win->_flags & _FULLWIN)
						&&  win->_curx == win->_maxx
						&&  win->_cury == win->_maxy)
	    return(ERR);

#ifdef FIONREAD
	if (win->_nodelay)
	{
	    long	count;

	    ioctl(fileno(SP->_ifp), FIONREAD, &count);

	    if (! count)
		return(-1);
	}
#endif

	if (SP->_echo  &&  ! (SP->_raw  ||  SP->_cbreak))
	{
		cbreak();
		setHere = TRUE;
	}

        if (win->_use_keypad)
            ch = kgetch();
        else
	    ch = nextc();

	if (SP->_echo  &&  ch < 0400)    /* ch < 0400 => not a keypad key */
	{
	    mvwaddch(curscr, win->_begy + win->_cury,
                             win->_begx + win->_curx, ch | win->_attrs);
	    waddch(win, ch | win->_attrs);
	}

	if (setHere)
	    nocbreak();

	return(ch);
}



X/*
**      short
**      kgetch()
**
**      Get an input character, but take care of keypad sequences, returning
**      an appropriate code when one matches the input.  After each character
**      is received, set a one-second alarm call.  If no more of the sequence
**      is received by the time the alarm goes off, pass through the sequence
**      gotten so far.
**
*/

static  bool    alarmed;

static
short
kgetch()
{
        struct try  *ptr;
	char        ch;
	char        buffer[10];     /* Assume no sequences longer than 10 */
	char        *bufp = buffer;
	int         (*oldsig)();
	int         sigalrm();

	ptr = SP->_keytry;
	
	oldsig = signal(SIGALRM, sigalrm);
	alarmed = FALSE;
	
	do
	{
	    ch = nextc();
	    if (ch != EOF)              /* getc() returns EOF on error, too */
	        *(bufp++) = ch;
	    if (alarmed)
	        break;
	    
	    while (ptr != NULL  &&  ptr->ch != ch)
	        ptr = ptr->sibling;
	    
	    if (ptr != NULL)
	    {
	        if (ptr->value != NULL)
		{
		    alarm(0);
		    signal(SIGALRM, oldsig);
		    return(ptr->value);
		}
		else
		{
		    ptr = ptr->child;
		    alarm(1);
	        }
	    }
	    
	} while (ptr != NULL);
	
	alarm(0);
	signal(SIGALRM, oldsig);
	
	while (--bufp > buffer)
	    putback(*bufp);
	    
	return(*bufp);
}


static
sigalrm()
{
        alarmed = TRUE;
	signal(SIGALRM, sigalrm);
}
//go.sysin dd *
echo 'x - =src/lib_getstr.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_getstr.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_getstr.c
**
**	The routine wgetstr().
**
** $Log:	RCS/lib_getstr.v $
 * Revision 2.1  82/10/25  14:47:33  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:45:39  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_getstr.v  Revision 2.1  82/10/25  14:47:33  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"
#include "unctrl.h"

#define backspace() {							\
		    mvwaddstr(curscr, win->_begy + win->_cury,		\
				      win->_begx + win->_curx, "\b \b");\
		    waddstr(win, "\b \b");				\
		    fputs("\b \b", SP->_ofp);				\
		    fflush(SP->_ofp);					\
		    }


wgetstr(win,str)
WINDOW	*win; 
char	*str;
{
	bool	oldnl, oldecho, oldraw, oldcbreak;
	char	erasec;
	char	killc;
	char	*oldstr;

#ifdef TRACE
	if (_tracing)
	    _tracef("wgetstr(%o,%o) called", win, str);
#endif

	oldnl = SP->_nl;
	oldecho = SP->_echo;
	oldraw = SP->_raw;
	oldcbreak = SP->_cbreak;
	nl();
	noecho();
	noraw();
	cbreak();

	erasec = erasechar();
	killc = killchar();

	oldstr = str;

	while ((*str = getc(SP->_ifp)) != ERR  &&  *str != '\n')
	{
	    if (*str == erasec)
	    {
		if (str > oldstr)
		{
		    str--;
		    backspace();
		    if (*str < ' ' ||  *str == '\177')
			backspace();
		}
	    }
	    else if (*str == killc)
	    {
		while (str > oldstr)
		{
		    str--;
		    backspace();
		    if (*str < ' ' ||  *str == '\177')
			backspace();
		}
	    }
	    else
	    {
		mvwaddstr(curscr, win->_begy + win->_cury,
				  win->_begx + win->_curx, unctrl(*str));
		waddstr(win, unctrl(*str));
		fputs(unctrl(*str), SP->_ofp);
		fflush(SP->_ofp);
		str++;
	    }
	}

	if (! oldnl)
	    nonl();

	if (oldecho)
	    echo();

	if (oldraw)
	    raw();

	if (! oldcbreak)
	    nocbreak();

	if (*str == ERR)
        {
	    *str = '\0';
	    return(ERR);
	}

	*str = '\0';

#ifdef TRACE
	if (_tracing)
	    _tracef("\twgetstr returns %s", oldstr);
#endif

	return(OK);
}
//go.sysin dd *
echo 'x - =src/lib_initscr.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_initscr.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_initscr.c
**
**	The routine initscr().
**
** $Log:	RCS/lib_initscr.v $
 * Revision 2.1  82/10/25  14:47:36  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:45:54  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_initscr.v  Revision 2.1  82/10/25  14:47:36  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


WINDOW *
initscr()
{
#ifdef TRACE
	_init_trace();

	if (_tracing)
	    _tracef("initscr() called");
#endif

    	if (newterm(getenv("TERM"), stdout) == ERR)
	    return(ERR);
	else
	    return(stdscr);
}
//go.sysin dd *
echo 'x - =src/lib_insch.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_insch.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_insch.c
**
**	The routine winsch().
**
** $Log:	RCS/lib_insch.v $
 * Revision 2.1  82/10/25  14:47:39  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:46:02  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_insch.v  Revision 2.1  82/10/25  14:47:39  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


winsch(win, c)
WINDOW	*win;
char	c;
{
	chtype	*temp1, *temp2;
	chtype	*end;

#ifdef TRACE
	if (_tracing)
	    _tracef("winsch(%o,'%c') called", win, c);
#endif

	end = &win->_line[win->_cury][win->_curx];
	temp1 = &win->_line[win->_cury][win->_maxx];
	temp2 = temp1 - 1;

	while (temp1 > end)
	    *temp1-- = *temp2--;

	*temp1 = c | win->_attrs;

	win->_lastchar[win->_cury] = win->_maxx;
	if (win->_firstchar[win->_cury] == _NOCHANGE
	    			||  win->_firstchar[win->_cury] > win->_curx)
	    win->_firstchar[win->_cury] = win->_curx;
}
//go.sysin dd *
echo 'x - =src/lib_insertln.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_insertln.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_insertln.c
**
**	The routine winsertln().
**
** $Log:	RCS/lib_insertln.v $
 * Revision 2.1  82/10/25  14:47:44  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:46:12  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_insertln.v  Revision 2.1  82/10/25  14:47:44  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


winsertln(win)
WINDOW	*win;
{
	chtype	*temp, *end;
	int	y;

#ifdef TRACE
	if (_tracing)
	    _tracef("winsertln(%o) called", win);
#endif

	temp = win->_line[win->_regbottom];

	win->_firstchar[win->_cury] = 0;
	win->_lastchar[win->_cury] = win->_maxx;

	for (y = win->_regbottom;  y > win->_cury;  y--)
	{
	    win->_line[y] = win->_line[y-1];

	    win->_firstchar[y] = 0;
	    win->_lastchar[y] = win->_maxx;
	}

	win->_line[win->_cury] = temp;

	for (end = &temp[win->_maxx];  temp <= end;  temp++)
	    *temp = ' ' | win->_attrs;
}
//go.sysin dd *
echo 'x - =src/lib_longname.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_longname.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_longname.c
**
**	The routine longname().
**
** $Log:	RCS/lib_longname.v $
 * Revision 2.1  82/10/25  14:47:49  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:46:21  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_longname.v  Revision 2.1  82/10/25  14:47:49  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


char *
longname()
{
    	char	*ptr;

#ifdef TRACE
	if (_tracing)
	    _tracef("longname() called");
#endif

	for (ptr = ttytype + strlen(ttytype); ptr > ttytype; ptr--)
	    if (*ptr == '|')
		return(ptr + 1);

        return(ttytype);
}
//go.sysin dd *
echo 'x - =src/lib_move.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_move.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_move.c
**
**	The routine wmove().
**
** $Log:	RCS/lib_move.v $
 * Revision 2.1  82/10/25  14:47:51  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:46:31  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_move.v  Revision 2.1  82/10/25  14:47:51  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


wmove(win, y, x)
WINDOW	*win;
int	y, x;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("wmove(%o,%d,%d) called", win, y, x);
#endif

	if (0 <= x  &&  x <= win->_maxx  &&
		win->_regtop <= y  &&  y <= win->_regbottom)
	{
	    win->_curx = x;
	    win->_cury = y;

	    return(OK);
	}
	else
	    return(ERR);
}
//go.sysin dd *
echo 'x - =src/lib_mvcur.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_mvcur.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**
**	lib_mvcur.c
**
**	mvcur() and its subroutines
**
** $Log:	RCS/lib_mvcur.v $
 * Revision 2.1  82/10/25  14:47:54  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:46:40  pavel
 * Beta-one Test Release
 * 
**
**	Revisions needed:
**		implement c_save instead of multiple tputs() calls
**		routine revisions
*/

static char RCSid[] =
	"$Header:   RCS/lib_mvcur.v  Revision 2.1  82/10/25  14:47:54  pavel  Exp$";

#include "term.h"
#include "curses.h"
#include "curses.priv.h"


#define BUFSIZE	128			/* size of strategy buffer */

struct Sequence
{
	int	vec[BUFSIZE],	/* vector of operations */
		*end,		/* end of vector */
		cost;		/* cost of vector */
};

X/*
**	#define
**	Make_seq_best(s1, s2)
**	
**	Make_seq_best() swaps the values
**  of the pointers if s1->cost > s2->cost.
*/

#define Make_seq_best(s1, s2)		\
	if (s1->cost > s2->cost)	\
	{				\
	    struct Sequence	*temp;	\
					\
	    temp = s1;			\
	    s1 = s2;			\
	    s2 = temp;			\
	}				


XFILE	*out_file;				/* pointer to output file */

static int	c_count;		/* used for counting tputs output */

X/*rev c_save not yet used
static char	*c_save;		/* used for saving tputs output */

#define	INFINITY	1000		/* biggest, impossible sequence cost */


#define NUM_OPS		16		/* num. term. control sequences */
#define NUM_NPARM	9		/* num. ops wo/ parameters */

	/* operator indexes into op_info */

#define	CARRIAGE_RETURN	0		/* watch out for nl mapping */
#define	CURS_DOWN	1
#define	CURS_HOME	2
#define	CURS_LEFT	3
#define	CURS_RIGHT	4
#define	CURS_TO_LL	5
#define	CURS_UP		6
#define	TAB		7
#define	BACK_TAB	8
#define	ROW_ADDR	9
#define	COL_ADDR	10
#define	P_DOWN_CURS	11
#define	P_LEFT_CURS	12
#define	P_RIGHT_CURS	13
#define	P_UP_CURS	14
#define	CURS_ADDR	15

static bool	loc_init = FALSE;	/* set if op_info is init'ed */

static bool	rel_ok;			/* set if we really know where we are */


X/*
 *	op_info[NUM_OPS]
 *
 *	op_info[] contains for operations with no parameters
 *  the cost of the operation.  These ops should be first in the array.
 *	For operations with parameters, op_info[] contains
 *  the negative of the number of parameters.
 */

static int	op_info[NUM_OPS] =
{
	0,		/* carriage_return */
	0,		/* cursor_down */
	0,		/* cursor_home */
	0,		/* cursor_left */
	0,		/* cursor_right */
	0,		/* cursor_to_ll */
	0,		/* cursor_up */
	0,		/* tab */
	0,		/* back_tab */
	-1,		/* row_address */
	-1,		/* column_address */
	-1,		/* parm_down_cursor */
	-1,		/* parm_left_cursor */
	-1,		/* parm_right_cursor */
	-1,		/* parm_up_cursor */
	-2		/* cursor_address */
};


X/*
**
**	mvcur(oldrow, oldcol, newrow, newcol)
**
**	mvcur() optimally moves the cursor from the position
**  specified by (oldrow, oldcol) to (newrow, newcol).  If
**  (oldrow, oldcol) == (-1, -1), mvcur() does not use relative
**  cursor motions.  If the coordinates are otherwise
**  out of bounds, it mods them into range.
**
**	Revisions needed:
**		eat_newline_glitch, auto_right_margin
*/

mvcur(oldrow, oldcol, newrow, newcol)
int	oldrow, oldcol,
	newrow, newcol;
{
	struct Sequence	seqA, seqB,	/* allocate work structures */
			col0seq,	/* sequence to get from col0 to nc */
			*best,		/* best sequence so far */
			*try;		/* next try */

#ifdef TRACE
	if (_tracing)
	    _tracef("mvcur(%d,%d,%d,%d) called",
						oldrow, oldcol, newrow, newcol);
#endif

	update_ops();			/* make sure op_info[] is current */

	if (oldrow < 0  ||  oldcol < 0)
	    rel_ok = FALSE;		/* relative ops ok? */
	else
	{
	    rel_ok = TRUE;

	    oldrow %= lines;		/* mod values into range */
	    oldcol %= columns;
	}
	newrow %= lines;
	newcol %= columns;

	best = &seqA;
	try = &seqB;

		/* try out direct cursor addressing */

	zero_seq(best);
	add_op(best, CURS_ADDR, newrow, newcol);

		/* try out independent row/column addressing */

	if (rel_ok)
	{
	    zero_seq(try);
	    row(try, oldrow, newrow);
	    column(try, oldcol, newcol);
	    Make_seq_best(best, try);
	}

	zero_seq(&col0seq);		/* store seq. to get from c0 to nc */
	column(&col0seq, 0, newcol);

	if(col0seq.cost < INFINITY)	/* can get from col0 to newcol */
	{
		    /* try out homing and then row/column */

	    if (! rel_ok  ||  newcol < oldcol  ||  newrow < oldrow)
	    {
		zero_seq(try);
		add_op(try, CURS_HOME, 1);
		row(try, 0, newrow);
		add_seq(try, &col0seq);
		Make_seq_best(best, try);
	    }

		    /* try out homing to last line  and then row/column */

	    if (! rel_ok  ||  newcol < oldcol  ||  newrow > oldrow)
	    {
		zero_seq(try);
		add_op(try, CURS_TO_LL, 1);
		row(try, lines - 1, newrow);
		add_seq(try, &col0seq);
		Make_seq_best(best, try);
	    }
	}

#ifdef TRACE
	if (_tracing)
	    _tracef("\tmvcur: result follows");
#endif

	out_seq(best);

#ifdef TRACE
	if (_tracing)
	    _tracef("\tmvcur: end of result");
#endif
}


X/*
**	row(outseq, oldrow, newrow)
**
**	row() adds the best sequence for moving
**  the cursor from oldrow to newrow to seq.
**	row() considers row_address, parm_up/down_cursor
**  and cursor_up/down.
*/

static
row(outseq, orow, nrow)
int		orow, nrow;		/* old, new cursor locations */
struct Sequence	*outseq;		/* where to put the output */
{
	struct Sequence	seqA, seqB,
			*best,		/* best sequence so far */
			*try;		/* next try */
	int	parm_cursor, one_step;

	best = &seqA;
	try = &seqB;

	if (nrow == orow)
	    return;

	if (nrow < orow)
	{
	    parm_cursor = P_UP_CURS;
	    one_step = CURS_UP;
	}
	else
	{
	    parm_cursor = P_DOWN_CURS;
	    one_step = CURS_DOWN;
	}

		/* try out direct row addressing */

	zero_seq(best);
	add_op(best, ROW_ADDR, nrow);

		/* try out paramaterized up or down motion */

	if (rel_ok)
	{
	    zero_seq(try);
	    add_op(try, parm_cursor, abs(orow - nrow));
	    Make_seq_best(best, try);
	}
		/* try getting there one step at a time... */

	if (rel_ok)
	{
	    zero_seq(try);
	    add_op(try, one_step, abs(orow-nrow));
	    Make_seq_best(best, try);
	}

	add_seq(outseq, best);
}


X/*
**	column(outseq, oldcol, newcol)
**
**	column() adds the best sequence for moving
**  the cursor from oldcol to newcol to outseq.
**	column() considers column_address, parm_left/right_cursor,
**  simp_col(), and carriage_return followed by simp_col().
*/

static
column(outseq, ocol, ncol)
struct Sequence	*outseq;			/* where to put the output */
int		ocol, ncol;			/* old, new cursor  column */
{
	struct Sequence	seqA, seqB,
			*best, *try;
	int		parm_cursor;	/* set to either parm_up/down_cursor */

	best = &seqA;
	try = &seqB;

	if (ncol == ocol)
	    return;

	if (ncol < ocol)
	    parm_cursor = P_LEFT_CURS;
	else
	    parm_cursor = P_RIGHT_CURS;

		/* try out direct column addressing */

	zero_seq(best);
	add_op(best, COL_ADDR, ncol);

		/* try carriage_return then simp_col() */

	if (! rel_ok  ||  (ncol < ocol))
	{
	    zero_seq(try);
	    add_op(try, CARRIAGE_RETURN, 1);
	    simp_col(try, 0, ncol);
	    Make_seq_best(best, try);
	}
	if (rel_ok)
	{
		/* try out paramaterized left or right motion */

	    zero_seq(try);
	    add_op(try, parm_cursor, abs(ocol - ncol));
	    Make_seq_best(best, try);

		/* try getting there with simp_col() */

	    zero_seq(try);
	    simp_col(try, ocol, ncol);
	    Make_seq_best(best, try);
	}

	add_seq(outseq, best);
}


X/*
** 	simp_col(outseq, oldcol, newcol)
**
**	simp_col() adds the best simple sequence for getting
**  from oldcol to newcol to outseq.
**	simp_col() considers (back_)tab and cursor_left/right.
**
**  Revisions needed:
**	Simp_col asssumes that the cost of a (back_)tab
**  is less then the cost of one-stepping to get to the same column.
**	Should sometimes use overprinting instead of cursor_right.
*/

static
simp_col(outseq, oc, nc)
struct Sequence	*outseq;		/* place to put sequence */
int		oc, nc;			/* old column, new column */
{
	struct Sequence	seqA, seqB, tabseq,
			*best, *try;
	int		mytab, tabs, onepast,
			one_step, opp_step; 

	if (! rel_ok)
	{
	    outseq->cost = INFINITY;
	    return;
	}

	if (oc == nc)
	    return;

	best = &seqA;
	try  = &seqB;

	if (oc < nc)
	{
	    mytab = TAB;
	    if (init_tabs > 0  &&  op_info[TAB] < INFINITY)
	    {
		tabs = nc / init_tabs - oc / init_tabs;
		onepast = ((nc / init_tabs) + 1) * init_tabs;
		if (tabs)
		    oc = onepast - init_tabs;	/* consider it done */
	    }
	    else
		tabs = 0;

	    one_step = CURS_RIGHT;
	    opp_step = CURS_LEFT;
	}
	else
	{
	    mytab = BACK_TAB;
	    if (init_tabs > 0  &&  op_info[BACK_TAB] < INFINITY)
	    {
		tabs = oc / init_tabs - nc / init_tabs;
		onepast = ((nc - 1) / init_tabs) * init_tabs;
		if (tabs)
		    oc = onepast + init_tabs;	/* consider it done */
	    }
	    else
		tabs = 0;

	    one_step = CURS_LEFT;
	    opp_step = CURS_RIGHT;
	}

		/* tab as close as possible to nc */

	zero_seq(&tabseq);
	add_op(&tabseq, mytab, tabs);

		/* try extra tab and backing up */

	zero_seq(best);

	if (onepast >= 0  &&  onepast < columns)
	{
	    add_op(best, mytab, 1);
	    add_op(best, opp_step, abs(onepast - nc));
	}
	else
	    best->cost = INFINITY;	/* make sure of next swap */

		/* try stepping to nc */

	zero_seq(try);
	add_op(try, one_step, abs(nc - oc));
	Make_seq_best(best, try);
	
	if (tabseq.cost < INFINITY)
	    add_seq(outseq, &tabseq);
	add_seq(outseq, best);
}


X/*
**	zero_seq(seq)
**	add_seq(seq1, seq2)
**	out_seq(seq)
**
**	zero_seq() empties seq.
**	add_seq() adds seq1 to seq2.
**	out_seq() outputs a sequence.
*/

static
zero_seq(seq)
struct Sequence	*seq;
{
	seq->end = seq->vec;
	seq->cost = 0;
}

static
add_seq(seq1, seq2)
struct Sequence	*seq1, *seq2;
{
	int	*vptr;

	if(seq1->cost >= INFINITY  ||  seq2->cost >= INFINITY)
	    seq1->cost = INFINITY;
	else
	{
	    vptr = seq2->vec;
	    while (vptr != seq2->end)
		*(seq1->end++) = *(vptr++);
	    seq1->cost += seq2->cost;
	}
}


static
out_seq(seq)
struct Sequence	*seq;
{
	int	*opptr, prm[9], ps, p, op, outc();
	int	count;
	char	*sequence();

	if (seq->cost >= INFINITY)
	    return;

	for (opptr = seq->vec;  opptr < seq->end;  opptr++)
	{
	    op = *opptr;			/* grab operator */
	    ps = -op_info[op];
	    if(ps > 0)				/* parameterized */
	    {
		for (p = 0;  p < ps;  p++)	/* fill in needed parms */
		    prm[p] = *(++opptr);

		tputs(tparm(sequence(op),
			        prm[0], prm[1], prm[2], prm[3], prm[4],
				prm[5], prm[6], prm[7], prm[8]), 1, outc);
	    }
	    else
	    {
		count = *(++opptr);
		    /*rev should save tputs output instead of mult calls */
		while (count--)			/* do count times */
		    tputs(sequence(op), 1, outc);
	    }
	}
}


X/*
**	update_ops()
**
**	update_ops() makes sure that
** the op_info[] array is updated and initializes
** the cost array for SP if needed.
*/

static
update_ops()
{
	if (SP)				/* SP structure exists */
	{
	    int	op; 

	    out_file = SP->_ofp;	/* set output file pointer */

	    if (! SP->_costinit)	/* this term not yet assigned costs */
	    {
		loc_init = FALSE;	/* if !SP in the future, new term */
		init_costs(SP->_costs);	/* fill term costs */
		SP->_costinit = TRUE;
	    }

	    for (op = 0;  op < NUM_NPARM;  op++)
		op_info[op] = SP->_costs[op];	/* set up op_info */
	    
		/* check for newline that might be mapped... */
	    if (SP->_nlmapping  &&  index(sequence(CURS_DOWN), '\n'))
		op_info[CURS_DOWN] = INFINITY;
	}
	else
	{
	    out_file = stdout;

	    if (! loc_init)			/* using local costs */
	    {
		loc_init = TRUE;
		init_costs(op_info);		/* set up op_info */
	    }
		/* check for newline that might be mapped... */
	    if (index(sequence(CURS_DOWN), '\n'))
		op_info[CURS_DOWN] = INFINITY;
	}
}


X/*
**	init_costs(costs)
**
**	init_costs() fills the array costs[NUM_NPARM]
** with costs calculated by doing tputs() calls.
*/

static
init_costs(costs)
int	costs[];
{
	int	i, countc();

	for (i = 0;  i < NUM_NPARM;  i++)
	    if(sequence(i) != (char *) 0)
	    {
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("\tinit_costs: pricing %d: '%s'", i, sequence(i));
#endif

		c_count = 0;
		tputs(sequence(i), 1, countc);
		costs[i] = c_count;
	    }
	    else
		costs[i] = INFINITY;
}


X/*
**	countc()
**	outc(c)
**	savec(c)
**	
**	countc() increments global var c_count.
**	outc() outputs a single character.
**	savec() saves c in *c_save and increments c_save and c_count.
*/

static
countc()
{
	c_count++;
}

static
outc(c)
char c;
{
	fputc(c, out_file);
}

X/*rev not yet needed 
static
savec(c)
char c;
{
	*(c_save++) = c;
	c_count++;
}
*/


X/*
**	add_op(seq, op, p0, p1, ... , p8)
**
**	add_op() adds the operator op and the appropriate
**  number of paramaters to seq.  It also increases the 
**  cost appropriately.
**	if op has no parameters, p0 is taken to be a count.
*/

static
add_op(seq, op, p0, p1, p2, p3, p4, p5, p6, p7, p8)
struct Sequence	*seq;
int		op, p0, p1, p2, p3, p4, p5, p6, p7, p8;
{
	int	num_ps, p;

#ifdef UNDEFINED
	if (_tracing)
	    _tracef("\tadd_op(%o,%d,%d,%d) called", seq, op, p0, p1);
#endif

	num_ps = - op_info[op];		/* get parms or -cost */
	*(seq->end++) = op;

	if (num_ps == (- INFINITY)  ||  sequence(op) == (char *) 0)
	    seq->cost = INFINITY;
	else
	    if (num_ps <= 0)		/* no parms, -cost */
	{
	    seq->cost -= p0 * num_ps;	/* ADD count * cost */
	    *(seq->end++) = p0;
	}
	else
	{
	    int	pms[9];

	    pms[0] = p0;  pms[1] = p1;  pms[2] = p2;
	    pms[3] = p3;  pms[4] = p4;  pms[5] = p5;
	    pms[6] = p6;  pms[7] = p7;  pms[8] = p8;  
	    for(p = 0;  p < num_ps;  p++)
		*(seq->end++) = pms[p];
	    c_count = 0;
	    tputs(tparm(sequence(op), p0, p1, p2, p3, p4, p5, p6, p7, p8),
								 1, countc);
	    seq->cost += c_count;
	}
}


X/*
**	char	*
**	sequence(op)
**
**	sequence() returns a pointer to the op's
**  terminal control sequence.
*/

static char	*
sequence(op)
int	op;
{
	
	switch(op)
	{
	    case CARRIAGE_RETURN:
		return (carriage_return);
	    case CURS_DOWN:
		return (cursor_down);
	    case CURS_HOME:
		return (cursor_home);
	    case CURS_LEFT:
		return (cursor_left);
	    case CURS_RIGHT:
		return (cursor_right);
	    case CURS_TO_LL:
		return (cursor_to_ll);
	    case CURS_UP:
		return (cursor_up);
	    case TAB:
		return (tab);
	    case BACK_TAB:
		return (back_tab);
	    case ROW_ADDR:
		return (row_address);
	    case COL_ADDR:
		return (column_address);
	    case P_DOWN_CURS:
		return (parm_down_cursor);
	    case P_LEFT_CURS:
		return (parm_left_cursor);
	    case P_RIGHT_CURS:
		return (parm_right_cursor);
	    case P_UP_CURS:
		return (parm_up_cursor);
	    case CURS_ADDR:
		return (cursor_address);
	    default:
		return ((char *) 0);
	}
}

//go.sysin dd *
echo 'x - =src/lib_mvwin.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_mvwin.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_mvwin.c
**
**	The routine mvwin().
**
** $Log:	RCS/lib_mvwin.v $
 * Revision 2.1  82/10/25  14:48:10  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:47:03  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_mvwin.v  Revision 2.1  82/10/25  14:48:10  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


mvwin(win, by, bx)
WINDOW	*win;
int	by, bx;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("mvwin(%o,%d,%d) called", win, by, bx);
#endif

	if (by + win->_maxy > LINES -1  ||  bx + win->_maxx > COLS - 1)
	    return(ERR);

	win->_begy = by;
	win->_begx = bx;

	touchwin(win);

	return(OK);
}
//go.sysin dd *
echo 'x - =src/lib_newterm.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_newterm.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_newterm.c
**
** 	The newterm() function.
**
** $Log:	RCS/lib_newterm.v $
 * Revision 2.1  82/10/25  14:48:14  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:47:11  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_newterm.v  Revision 2.1  82/10/25  14:48:14  pavel  Exp$";

#include <signal.h>
#include <stdio.h>
#include "curses.h"
#include "term.h"
#include "curses.priv.h"



struct screen *
newterm(term, fp)
char	*term;
XFILE	*fp;
{
	int	errret;
	int	tstp();

#ifdef TRACE
	_init_trace();

	if (_tracing)
	    _tracef("newterm(%s,%o) called", term, fp);
#endif

	if (setupterm(term, fileno(fp), &errret) != 1)
	    return(ERR);

	if ((SP = (struct screen *) malloc(sizeof *SP)) == NULL)
	    return(ERR);

	if (fp == stdout)
	{
	    SP->_ofp       = stdout;
	    SP->_ifp       = stdin;
	}
	else
	{
	    SP->_ofp       = fp;
	    SP->_ifp       = fp;
	}
	SP->_term      = cur_term;
	SP->_cursrow   = -1;
	SP->_curscol   = -1;
        SP->_keytry    = UNINITIALISED;
	SP->_nl        = TRUE;
	SP->_raw       = FALSE;
	SP->_cbreak    = FALSE;
	SP->_echo      = TRUE;
	SP->_nlmapping = TRUE;
	SP->_costinit  = FALSE;

	LINES = lines;
	COLS = columns;

	if (enter_ca_mode)
	    putp(enter_ca_mode);

	if ((newscr = newwin(lines, columns, 0, 0)) == ERR)
	    return(ERR);

	if ((curscr = newwin(lines, columns, 0, 0)) == ERR)
	    return(ERR);

	SP->_newscr = newscr;
	SP->_curscr = curscr;

	newscr->_clear = TRUE;
	curscr->_clear = FALSE;

	signal(SIGTSTP, tstp);

	if (stdscr == NULL)
	    if ((stdscr = newwin(lines, columns, 0, 0)) == ERR)
		return(ERR);

#ifdef TRACE
	if (_tracing)
	    _tracef("\tnewterm returns %o", SP);
#endif

	return(SP);
}
//go.sysin dd *
echo 'x - =src/lib_newwin.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_newwin.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_newwin.c
**
**	The routines newwin(), subwin() and their dependent
**
** $Log:	RCS/lib_newwin.v $
 * Revision 2.1  82/10/25  14:48:18  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:47:18  pavel
 * Beta-one Test Release
 * 
**
*/

#include "term.h"
#include "curses.h"
#include "curses.priv.h"

short	*calloc();
WINDOW	*malloc();

static WINDOW	*makenew();


WINDOW *
newwin(num_lines, num_columns, begy, begx)
int	num_lines, num_columns, begy, begx;
{
	WINDOW	*win;
	chtype	*ptr;
	int	i, j;

#ifdef TRACE
	if (_tracing)
	    _tracef("newwin(%d,%d,%d,%d) called", num_lines, num_columns, begy, begx);
#endif

	if (num_lines == 0)
	    num_lines = lines - begy;

	if (num_columns == 0)
	    num_columns = columns - begx;

	if ((win = makenew(num_lines, num_columns, begy, begx)) == ERR)
	    return(ERR);

	for (i = 0; i < num_lines; i++)
	{
	    if ((win->_line[i] = (chtype *) calloc(num_columns, sizeof(chtype)))
								      == NULL)
	    {
		for (j = 0; j < i; j++)
		    cfree(win->_line[j]);

		cfree(win->_firstchar);
		cfree(win->_lastchar);
		cfree(win->_line);
		cfree(win);

		return(ERR);
	    }
	    else
		for (ptr = win->_line[i]; ptr < win->_line[i] + num_columns; )
		    *ptr++ = ' ';
	}

#ifdef TRACE
	if (_tracing)
	    _tracef("\tnewwin: returned window is %o", win);
#endif

	return(win);
}



WINDOW *
subwin(orig, num_lines, num_columns, begy, begx)
WINDOW	*orig;
int	num_lines, num_columns, begy, begx;
{
	WINDOW	*win;
	int	i, j, k;

#ifdef TRACE
	if (_tracing)
	    _tracef("subwin(%d,%d,%d,%d) called", num_lines, num_columns, begy, begx);
#endif

	/*
	** make sure window fits inside the original one
	*/

	if (begy < orig->_begy || begx < orig->_begx
			|| begy + num_lines > orig->_maxy
			|| begx + num_columns > orig->_maxx)
	    return(ERR);

	if (num_lines == 0)
	    num_lines = orig->_maxy - orig->_begy - begy;

	if (num_columns == 0)
	    num_columns = orig->_maxx - orig->_begx - begx;

	if ((win = makenew(num_lines, num_columns, begy, begx)) == ERR)
	    return(ERR);

	j = orig->_begy + begy;
	k = orig->_begx + begx;

	for (i = 0; i < num_lines; i++)
	    win->_line[i] = &orig->_line[j++][k];

	win->_flags = _SUBWIN;

#ifdef TRACE
	if (_tracing)
	    _tracef("\tsubwin: returned window is %o", win);
#endif

	return(win);
}



static WINDOW *
makenew(num_lines, num_columns, begy, begx)
int	num_lines, num_columns, begy, begx;
{
	int	i;
	WINDOW	*win;

	if ((win = (WINDOW *) malloc(sizeof(WINDOW))) == NULL)
		return ERR;

	if ((win->_line = (chtype **) calloc(num_lines, sizeof (chtype *)))
								       == NULL)
	{
		cfree(win);

		return(ERR);
	}

	if ((win->_firstchar = calloc(num_lines, sizeof(short))) == NULL)
	{
		cfree(win);
		cfree(win->_line);

		return(ERR);
	}

	if ((win->_lastchar = calloc(num_lines, sizeof(short))) == NULL)
	{
		cfree(win);
		cfree(win->_line);
		cfree(win->_firstchar);

		return(ERR);
	}

	if ((win->_numchngd = calloc(num_lines, sizeof(short))) == NULL)
	{
		cfree(win);
		cfree(win->_line);
		cfree(win->_firstchar);
		cfree(win->_lastchar);

		return(ERR);
	}

	win->_curx       = 0;
	win->_cury       = 0;
	win->_maxy       = num_lines - 1;
	win->_maxx       = num_columns - 1;
	win->_begy       = begy;
	win->_begx       = begx;

	win->_flags      = 0;
	win->_attrs      = A_NORMAL;

	win->_clear      = (num_lines == lines  &&  num_columns == columns);
	win->_scroll     = FALSE;
	win->_leave      = FALSE;
	win->_use_keypad = FALSE;
	win->_use_meta   = FALSE;
	win->_nodelay    = FALSE;

	win->_regtop     = 0;
	win->_regbottom  = num_lines - 1;

	for (i = 0; i < num_lines; i++)
	{
	    win->_firstchar[i] = win->_lastchar[i] = _NOCHANGE;
	    win->_numchngd[i] = 0;
	}

	if (begx + num_columns == columns)
	{
		win->_flags |= _ENDLINE;

		if (begx == 0  &&  num_lines == lines  &&  begy == 0)
			win->_flags |= _FULLWIN;

		if (begy + num_lines == lines)
			win->_flags |= _SCROLLWIN;
	}

	return(win);
}
//go.sysin dd *
echo 'x - =src/lib_options.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_options.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_options.c
**
**	The routines to handle option setting.
**
** $Log:	RCS/lib_options.v $
 * Revision 2.1  82/10/25  14:48:24  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:47:45  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_options.v  Revision 2.1  82/10/25  14:48:24  pavel  Exp$";

#include "term.h"
#include "curses.h"
#include "curses.priv.h"


static
outc(ch)
char	ch;
{
    	putc(ch, SP->_ofp);
}


idlok(win, flag)
WINDOW	*win;
int	flag;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("idlok(%o,%d) called", win, flag);
#endif

    	if ((insert_line  &&  delete_line)
#ifdef UNIMPLEMENTED
	     ||  (change_scroll_region)
#endif
	   )
	    curscr->_idlok = flag;
}


clearok(win, flag)
WINDOW	*win;
int	flag;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("clearok(%o,%d) called", win, flag);
#endif

    	if (win == curscr)
	    newscr->_clear = flag;
	else
	    win->_clear = flag;
}


leaveok(win, flag)
WINDOW	*win;
int	flag;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("leaveok(%o,%d) called", win, flag);
#endif

    	win->_leave = flag;
}


scrollok(win, flag)
WINDOW	*win;
int	flag;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("scrollok(%o,%d) called", win, flag);
#endif

    	win->_scroll = flag;
}


nodelay(win, flag)
WINDOW	*win;
int	flag;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("nodelay(%o,%d) called", win, flag);
#endif

    	win->_nodelay = flag;
}


keypad(win, flag)
WINDOW	*win;
int	flag;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("keypad(%o,%d) called", win, flag);
#endif

    	win->_use_keypad = flag;

	if (flag  &&  keypad_xmit)
	    tputs(keypad_xmit, 1, outc);
	else if (! flag  &&  keypad_local)
	    tputs(keypad_local, 1, outc);
	    
        if (SP->_keytry == UNINITIALISED)
	    init_keytry();
}



meta(win, flag)
WINDOW	*win;
int	flag;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("meta(%o,%d) called", win, flag);
#endif

	win->_use_meta = flag;

	if (flag  &&  meta_on)
	    tputs(meta_on, 1, outc);
	else if (! flag  &&  meta_off)
	    tputs(meta_off, 1, outc);
}



X/*
**      init_keytry()
**
**      Construct the try for the current terminal's keypad keys.
**
*/


static struct  try *newtry;

static
init_keytry()
{
        newtry = NULL;
	
        add_to_try(key_backspace, KEY_BACKSPACE);
        add_to_try(key_catab, KEY_CATAB);
        add_to_try(key_clear, KEY_CLEAR);
        add_to_try(key_ctab, KEY_CTAB);
        add_to_try(key_dc, KEY_DC);
        add_to_try(key_dl, KEY_DL);
        add_to_try(key_down, KEY_DOWN);
        add_to_try(key_eic, KEY_EIC);
        add_to_try(key_eol, KEY_EOL);
        add_to_try(key_eos, KEY_EOS);
        add_to_try(key_f0, KEY_F(0));
        add_to_try(key_f1, KEY_F(1));
        add_to_try(key_f2, KEY_F(2));
        add_to_try(key_f3, KEY_F(3));
        add_to_try(key_f4, KEY_F(4));
        add_to_try(key_f5, KEY_F(5));
        add_to_try(key_f6, KEY_F(6));
        add_to_try(key_f7, KEY_F(7));
        add_to_try(key_f8, KEY_F(8));
        add_to_try(key_f9, KEY_F(9));
        add_to_try(key_f10, KEY_F(10));
        add_to_try(key_home, KEY_HOME);
        add_to_try(key_ic, KEY_IC);
        add_to_try(key_il, KEY_IL);
        add_to_try(key_left, KEY_LEFT);
        add_to_try(key_npage, KEY_NPAGE);
        add_to_try(key_ppage, KEY_PPAGE);
        add_to_try(key_right, KEY_RIGHT);
        add_to_try(key_sf, KEY_SF);
        add_to_try(key_sr, KEY_SR);
        add_to_try(key_stab, KEY_STAB);
        add_to_try(key_up, KEY_UP);
	
	SP->_keytry = newtry;
}


add_to_try(str, code)
char    *str;
short   code;
{
        static bool     out_of_memory = FALSE;
        struct try      *ptr, *savedptr;
	struct try      *malloc();

	if (! str  ||  out_of_memory)
	    return;
	
	if (newtry != NULL)    
	{
	    ptr = newtry;
	    
       	    for (;;)
	    {
	        while (ptr->ch != *str  &&  ptr->sibling != NULL)
	            ptr = ptr->sibling;
	    
	        if (ptr->ch == *str)
		{
		    if (*(++str))
		    {
	                if (ptr->child != NULL)
		            ptr = ptr->child;
                        else
		            break;
		    }
		    else
		    {
		        ptr->value = code;
			return;
		    }
		}
		else
	        {
		    if ((ptr->sibling = malloc(sizeof *ptr)) == NULL)
		    {
		        out_of_memory = TRUE;
			return;
		    }
		    
		    savedptr = ptr = ptr->sibling;
		    ptr->child = ptr->sibling = NULL;
		    ptr->ch = *str++;
		    ptr->value = NULL;
		    
                    break;
	        }
	    } /* end for (;;) */  
	}
	else    /* newtry == NULL :: First sequence to be added */
	{
	    savedptr = ptr = newtry = malloc(sizeof *ptr);
	    
	    if (ptr == NULL)
	    {
	        out_of_memory = TRUE;
		return;
	    }
	    
	    ptr->child = ptr->sibling = NULL;
	    ptr->ch = *(str++);
	    ptr->value = NULL;
	}
	
	    /* at this point, we are adding to the try.  ptr->child == NULL */
	    
	while (*str)
	{
	    ptr->child = malloc(sizeof *ptr);
	    
	    ptr = ptr->child;
	    
	    if (ptr == NULL)
	    {
	        out_of_memory = TRUE;
		
		ptr = savedptr;
		while (ptr != NULL) 
		{
		    savedptr = ptr->child;
		    free(ptr);
		    ptr = savedptr;
		}
		
		return;
	    }
	    
	    ptr->child = ptr->sibling = NULL;
	    ptr->ch = *(str++);
	    ptr->value = NULL;
	}
	
	ptr->value = code;
	return;
}
//go.sysin dd *
exit

sources@genrad.UUCP (12/20/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit".  This code is completely public domain, originally written by Pavel
Curtis of Cornell University.  This version has some small improvements and
bug fixes.

This unit contains:
	more library modules

Part 9 will be
	the last of the library, and the start of the terminal data files.

----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =src
then
    echo 'Making directory "=src"'
    mkdir =src
fi
echo 'x - =src/lib_doupdate.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_doupdate.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	lib_doupdate.c
 *
 *	The routine doupdate() and its dependents
 *
 *  $Log:	lib_doupdate.c,v $
 * Revision 3.1  84/12/13  11:20:28  john
 * Revisions by Mark Horton
 * 
 * Revision 2.1  82/10/25  14:47:05  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:44:33  pavel
 * Beta-one Test Release
 * 
 *
 */

static char RCSid[] =
	"$Header: lib_doupdate.c,v 3.1 84/12/13 11:20:28 john Exp $";

#include <signal.h>
#include "curses.h"
#include "curses.priv.h"
#include "term.h"

#define GoTo(row,col)		mvcur(SP->_cursrow, SP->_curscol, row, col);  \
				SP->_cursrow = row;                           \
				SP->_curscol = col;

#define PutAttrChar(ch)		if (curscr->_attrs != (ch & A_ATTRIBUTES))    \
				{                                             \
				    curscr->_attrs = ch & A_ATTRIBUTES;       \
				    vidputs(curscr->_attrs, outc);            \
				}                                             \
				putc(ch & A_CHARTEXT, SP->_ofp);

#define PutChar(ch)		if (!auto_right_margin  ||                    \
						SP->_cursrow != lines - 1  || \
						SP->_curscol != columns - 1)  \
				{                                             \
				    PutAttrChar(ch);                          \
				    SP->_curscol++;                           \
				    if (SP->_curscol >= columns)              \
					if (auto_right_margin)                \
					{                                     \
					    SP->_curscol = 0;                 \
					    SP->_cursrow++;                   \
					}                                     \
					else                                  \
					    SP->_curscol--;                   \
				}



outc(ch)
char	ch;
{
    	putc(ch, SP->_ofp);
}



doupdate()
{
	int	i;
	int	(*oldsig)();

#ifdef TRACE
	if (_tracing)
	    _tracef("doupdate() called");
#endif

	oldsig = signal(SIGTSTP, SIG_IGN);

	if (curscr->_clear)
	{
	    ClrUpdate(curscr);
	    curscr->_clear = FALSE;

	    GoTo(curscr->_cury, curscr->_curx);
	}
	else
	{
	    if (newscr->_clear)
	    {
		ClrUpdate(newscr);
		newscr->_clear = FALSE;
	    }
	    else if (curscr->_idlok)
		IdlUpdate();
	    else
		NoIdlUpdate();

	    for (i = 0; i < lines; i++)
	    {
		newscr->_firstchar[i] = _NOCHANGE;
		newscr->_lastchar[i] = _NOCHANGE;
		newscr->_numchngd[i] = 0;
	    }

	    curscr->_curx = newscr->_curx;
	    curscr->_cury = newscr->_cury;

	    GoTo(curscr->_cury, curscr->_curx);
	}


	fflush(SP->_ofp);

	signal(SIGTSTP, oldsig);
}



X/*
**	ClrUpdate(scr)
**
**	Update by clearing and redrawing the entire screen.
**
*/

static
ClrUpdate(scr)
WINDOW	*scr;
{
    	int	i, j;
	int	lastNonBlank;

	ClearScreen();

	for (i=0; i < lines; i++)
	{
	    lastNonBlank = columns - 1;
	    while (scr->_line[i][lastNonBlank] == ' ')
		lastNonBlank--;

	    if (i == lines  &&  lastNonBlank == columns - 1)
		lastNonBlank--;

	    for (j=0; j <= lastNonBlank; j++)
	    {
		PutAttrChar(scr->_line[i][j]);
	    }

	    if (! auto_right_margin  ||  lastNonBlank < columns - 1)
	    {
		SP->_cursrow = i;
		SP->_curscol = lastNonBlank < 0  ?  0  :  lastNonBlank;

		GoTo(i + 1, 0);
	    }
	}

	if (scr != curscr)
	{
	    for (i=0; i < LINES; i++)
		for (j=0; j < COLS; j++)
		    curscr->_line[i][j] = scr->_line[i][j];
	}
}



X/*
**	NoIdlUpdate()
**
**	Update screen without using Insert/Delete Line capabilities
**
*/

static
NoIdlUpdate()
{
	int	i;

#ifdef TRACE
	if (_tracing)
	    _tracef("NoIdlUpdate() called");
#endif

	for (i=0; i < lines; i++)
	    if (newscr->_numchngd[i])
		TransformLine(i);
}



X/*
**	IdlUpdate()
**
**	Update screen using Insert/Delete Line capabilities
**
*/

#define UNCHANGED(n)	(newscr->_numchngd[n] <= columns/10		\
				||  newscr->_lastchar[n]		\
					  - newscr->_firstchar[n] <= columns/10)

static
IdlUpdate()
{
	int	firstLine, lastLine, thisLine;

#ifdef TRACE
	if (_tracing)
	    _tracef("IdlUpdate() called");
#endif

	firstLine = -1;

	for (thisLine = 0; thisLine < lines; thisLine++)
	{
	    if (UNCHANGED(thisLine))
	    {
		if (firstLine != -1)
		{
		    lastLine = thisLine - 1;
		    Gosling(firstLine, lastLine);
		    firstLine = -1;
		}
		
		if (newscr->_firstchar[thisLine] != _NOCHANGE)
		    TransformLine(thisLine);
	    }
	    else if (firstLine == -1)
		firstLine = thisLine;
	}

	if (firstLine != -1)
	    Gosling(firstLine, lines - 1);
}



X/*
**	TransformLine(lineno)
**
**	Call either IDcTransformLine or NoIDcTransformLine to do the
**	update, depending upon availability of insert/delete character.
*/

static
TransformLine(lineno)
int	lineno;
{
    	if ( (insert_character  ||  (enter_insert_mode  &&  exit_insert_mode))
		 &&  delete_character)
	    IDcTransformLine(lineno);
	else
	    NoIDcTransformLine(lineno);
}



X/*
**	NoIDcTransformLine(lineno)
**
**	Transform the given line in curscr to the one in newscr, without
**	using Insert/Delete Character.
**
**		firstChar = position of first different character in line
**		lastChar = position of last different character in line
**
**		overwrite all characters between firstChar and lastChar.
**
*/

static
NoIDcTransformLine(lineno)
int	lineno;
{
	register int	firstChar, lastChar;
	register chtype	*newLine = newscr->_line[lineno];
	register chtype	*oldLine = curscr->_line[lineno];
        register int     k;

#ifdef TRACE
	if (_tracing)
	    _tracef("NoIDcTransformLine(%d) called", lineno);
#endif

	firstChar = 0;
	while (firstChar < columns
			 &&  newLine[firstChar] == oldLine[firstChar])
	    firstChar++;

	if (firstChar >= columns)
	    return;

	lastChar = columns - 1;
	while (lastChar > firstChar  &&  newLine[lastChar] == oldLine[lastChar])
	    lastChar--;
    	
	GoTo(lineno, firstChar);

	for (k=firstChar; k <= lastChar; k++)
	{
	    PutChar(newLine[k]);
	    oldLine[k] = newLine[k];
	}
}



X/*
**	IDcTransformLine(lineno)
**
**	Transform the given line in curscr to the one in newscr, using
**	Insert/Delete Character.
**
**		firstChar = position of first different character in line
**		oLastChar = position of last different character in old line
**		nLastChar = position of last different character in new line
**
**		move to firstChar
**		overwrite chars up to min(oLastChar, nLastChar)
**		if oLastChar < nLastChar
**			insert newLine[oLastChar+1..nLastChar]
**		else
**			delete oLastChar - nLastChar spaces
*/

static
IDcTransformLine(lineno)
int	lineno;
{
	int	firstChar, oLastChar, nLastChar;
	chtype	*newLine = newscr->_line[lineno];
	chtype	*oldLine = curscr->_line[lineno];
        int     k, n;

#ifdef TRACE
	if (_tracing)
	    _tracef("IDcTransformLine(%d) called", lineno);
#endif

	firstChar = 0;
	while (firstChar < columns  &&  newLine[firstChar] == oldLine[firstChar])
	    firstChar++;

	if (firstChar >= columns)
	    return;

	oLastChar = columns - 1;
	while (oLastChar > firstChar  &&  oldLine[oLastChar] == ' ')
	    oLastChar--;

	nLastChar = columns - 1;
	while (nLastChar > firstChar  &&  newLine[nLastChar] == ' ')
	    nLastChar--;

	while (newLine[nLastChar] == oldLine[oLastChar])
	{
	    nLastChar--;
	    oLastChar--;
	}

	n = min(oLastChar, nLastChar);
	GoTo(lineno, firstChar);

	for (k=firstChar; k <= n; k++)
	    PutChar(newLine[k]);

	if (oLastChar < nLastChar)
	    InsStr(&newLine[k], nLastChar - oLastChar);
	else if (oLastChar > nLastChar)
	    DelChar(oLastChar - nLastChar);

	for (k=firstChar; k < columns; k++)
	    oldLine[k] = newLine[k];
}



X/*
**	Gosling(firstLine, lastLine)
**
**	Change the given range of lines on curscr into the same lines
**	on newscr, using Gosling's Algorithm.
*/

static short lineCost[MAXLINES][MAXLINES];
static short lineOps[MAXLINES][MAXLINES];
static short lineDels[MAXLINES];
static short lineIRs[MAXLINES];

#define INSERT	1
#define DELETE	2
#define REPLACE 3

static
Gosling(firstLine, lastLine)
int	firstLine, lastLine;
{
	int	i, count;

#ifdef TRACE
	if (_tracing)
	    _tracef("Gosling(%d,%d) called", firstLine, lastLine);
#endif

	Goscost(firstLine, lastLine - firstLine + 1);

	for (i=0; i <= lastLine - firstLine + 1; i++)
	    lineDels[i] = lineIRs[i] = 0;

	Gosdraw(lastLine - firstLine + 1, lastLine - firstLine + 1);

	count = 0;
	for (i = lastLine - firstLine + 1; i > 0; i--)
	{
	    if (lineDels[i] == DELETE)
		count++;
	    else if (count)
	    {	
		DelLine(count, firstLine + i, lastLine);
		count = 0;
	    }
	}

	if (count)
	    DelLine(count, firstLine, lastLine);


	for (i = 1; i <= lastLine - firstLine + 1; i++)
	{
	    switch (lineIRs[i])
	    {
		case REPLACE:
		    TransformLine(firstLine + i - 1);
		    break;

		case INSERT:
		    InsLine(firstLine + i - 1, lastLine);
		    break;

		default:
		    /* do nothing */
		    break;
	    }
	}
}



#define RPLCOST(old,new)	(oHash[old] == nHash[new]  ?  0  :  columns)

static
Goscost(lineno, length)
int	lineno, length;
{	
	int	i, j, cost;
	int	ILcost, DLcost;
	long	nHash[MAXLINES], oHash[MAXLINES];
        long    HashFn();

#ifdef TRACE
	if (_tracing)
	    _tracef("Goscost(lineno=%d,length=%d) called", lineno, length);
#endif

	ILcost = (insert_line ? strlen(insert_line) : 9999) + columns;
	DLcost = (delete_line ? strlen(delete_line) : 9999);

	for (i=1; i <= length; i++)
	{
	    nHash[i] = HashFn(newscr->_line[lineno + i - 1]);
	    oHash[i] = HashFn(curscr->_line[lineno + i - 1]);
	}

	lineCost[0][0] = 0;

	for (i=1; i <= length; i++)
	{
	    lineCost[i][0] = lineCost[i-1][0] + DLcost;
	    lineOps[i][0] = DELETE;

	    lineCost[0][i] = lineCost[0][i-1] + ILcost;
	    lineOps[0][i] = INSERT;
	}

	for (i=1; i <= length; i++)
	{
	    for (j=1; j <= length; j++)
	    {
		lineCost[i][j] = lineCost[i-1][j-1] + RPLCOST(i, j);
		lineOps[i][j] = REPLACE;

		cost = lineCost[i][j-1] + ILcost;
		if (cost < lineCost[i][j])
		{
		    lineCost[i][j] = cost;
		    lineOps[i][j] = INSERT;
		}

		cost = lineCost[i-1][j] + DLcost;
		if (cost < lineCost[i][j])
		{
		    lineCost[i][j] = cost;
		    lineOps[i][j] = DELETE;
		}
	    }
	}

	return(lineCost[columns][columns]);
}



X/*
**	_PrintCosts(length)
**
**	Print out the cost matrix.  Called only from sdb.
**
**
**	_DumpNewscr(first, last)
**
**	Print the specified range of lines from newscr.  Called only from sdb.
**
**
**	_DumpCurscr(first, last)
**
**	Print the specified range of lines from curscr.  Called only from sdb.
**
*/


_PrintCosts(length)
int	length;
{
    	int	i, j;

	for (i=0; i <= length; i++)
	{
	    for (j=0; j <= length; j++)
	    {
		printf("%5d/%d", lineCost[i][j], lineOps[i][j]);
	    }

	    putchar('\n');
	}

	fflush(stdout);
}


_DumpNewscr(first, last)
int	first, last;
{
    	int	i, j;

	for (i=first; i <= last; i++)
	{
	    for (j=0; j < columns; j++)
		putchar(newscr->_line[i][j]);
	    
	    putchar('\n');
	}
}


_DumpCurscr(first, last)
int	first, last;
{
    	int	i, j;

	for (i=first; i <= last; i++)
	{
	    for (j=0; j < columns; j++)
		putchar(curscr->_line[i][j]);
	    
	    putchar('\n');
	}
}



long
HashFn(line)
chtype	*line;
{
    	int	i = 0;
	long	hash = 0;

	while(i < columns  &&  (line[i] | A_CHARTEXT) == ' ')
	    i++;

	for (; i+1 < columns; i += 2)
	    hash += (line[i] << 8) + line[i+1];

	return (hash);
}





static
Gosdraw(i, j)
int	i, j;
{
    	if (i == 0  &&  j == 0)
	    return;
	
	switch (lineOps[i][j])
	{
	    case INSERT:
		Gosdraw(i, j-1);
		lineIRs[j] = INSERT;
		break;

	    case DELETE:
		lineDels[i] = DELETE;
		Gosdraw(i-1, j);
		break;

	    case REPLACE:
		Gosdraw(i-1, j-1);
		lineIRs[j] = REPLACE;
		break;
	}
}



X/*
**	ClearScreen()
**
**	Clear the physical screen and put cursor at home
**
*/

static
ClearScreen()
{
	if (clear_screen)
	{
	    tputs(clear_screen, 1, outc);
	    SP->_cursrow = SP->_curscol = 0;
	}
	else if (clr_eos)
	{
	    SP->_cursrow = SP->_curscol = -1;
	    GoTo(0,0);

	    tputs(clr_eos, 1, outc);
	}
	else if (clr_eol)
	{
	    SP->_cursrow = SP->_curscol = -1;

	    while (SP->_cursrow < lines)
	    {
		GoTo(SP->_cursrow, 0);
		tputs(clr_eol, 1, outc);
	    }

	    GoTo(0,0);
	}
}



X/*
**	InsStr(line, count)
**
**	Insert the count characters pointed to by line.
**
*/

InsStr(line, count)
chtype	*line;
int	count;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("InsStr(%o,%d) called", line, count);
#endif

    	if (enter_insert_mode  &&  exit_insert_mode)
	{
	    tputs(enter_insert_mode, 1, outc);
	    while (count)
	    {
		PutChar(*line);
		line++;
		count--;
	    }
	    tputs(exit_insert_mode, 1, outc);
	}
	else if (parm_ich)
	{
	    tputs(tparm(parm_ich, count), 1, outc);
	    while (count)
	    {
		PutChar(*line);
		line++;
		count--;
	    }
	}
	else
	{
	    while (count)
	    {
		tputs(insert_character, 1, outc);
		PutChar(*line);
		line++;
		count--;
	    }
	}
}



X/*
**	DelChar(count)
**
**	Delete count characters at current position
**
*/

DelChar(count)
int	count;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("DelChar(%d) called", count);
#endif

    	if (parm_dch)
	{
	    tputs(tparm(parm_dch, count), 1, outc);
	}
	else
	{
	    while (count--)
		tputs(delete_character, 1, outc);
	}
}



X/*
**	InsLine(lineno, lastLine)
**
**	Insert line number lineno, affecting up to lastLine
**
*/

InsLine(lineno, lastLine)
int	lineno, lastLine;
{
	int	i, j, k;
	chtype	*temp;
	chtype	*line = newscr->_line[lineno];

#ifdef TRACE
	if (_tracing)
	    _tracef("InsLine(%d,%d) called", lineno, lastLine);
#endif
	
	GoTo(lineno, 0);

    	tputs(insert_line, 1, outc);

	for (i=0; i < columns; i++)
	    PutChar(line[i]);

	temp = curscr->_line[lastLine];
	for (k = lastLine; k > lineno; k--)
	    curscr->_line[k] = curscr->_line[k - 1];

	curscr->_line[k] = temp;

	for (j=0; j < columns; j++)
	    curscr->_line[k][j] = newscr->_line[k][j];
}



X/*
**	DelLine(count, lineno, lastLine)
**
**	Delete count lines at lineno, affecting up to lastLine
**
*/

DelLine(count, lineno, lastLine)
int	count, lineno, lastLine;
{
	int	j, k;
	chtype	*temp;

#ifdef TRACE
	if (_tracing)
	    _tracef("DelLine(%d,%d,%d) called", count, lineno, lastLine);
#endif

	GoTo(lineno, 0);

    	if (parm_delete_line)
	{
	    tputs(tparm(parm_delete_line, count), 1, outc);
	}
	else
	{
	    while (count--)
		tputs(delete_line, 1, outc);
	}

	for (k = lineno; k + count <= lastLine; k++)
	{
	    temp = curscr->_line[k];
	    curscr->_line[k] = curscr->_line[k + count];
	    curscr->_line[k + count] = temp;
	}

	for (; k <= lastLine; k++)
	    for (j=0; j < columns; j++)
		curscr->_line[k][j] = ' ';
}
//go.sysin dd *
echo 'x - =src/lib_overlay.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_overlay.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_overlay.c
**
**	The routines overlay() and overwrite().
**
** $Log:	RCS/lib_overlay.v $
 * Revision 2.2  82/10/28  18:10:11  pavel
 * Fixed confusion about which direction the copy was supposed to go and
 * also added updates to win2->_{first,last}char.
 * 
 * Revision 2.1  82/10/25  14:48:35  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:48:09  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_overlay.v  Revision 2.2  82/10/28  18:10:11  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


X/*
**
**	overlay(win1, win2)
**
**
**	overlay() writes win1 on win2 non-destructively.
**
**/

overlay(win1, win2)
WINDOW	*win1, *win2;
{
	int	col, line, last_line, last_col;
	short   *firstchar, *lastchar;
	chtype	*w1ptr, *w2ptr, attrs;

#ifdef TRACE
	if (_tracing)
	    _tracef("overlay(%o, %o) called", win1, win2);
#endif
	
	last_col = min(win1->_maxx, win2->_maxx);
	last_line = min(win1->_maxy, win2->_maxy);
	attrs = win2->_attrs;
	firstchar = win2->_firstchar;
	lastchar = win2->_lastchar;

	for(line = 0;  line <= last_line;  line++)
	{
	    short   fc, lc;
	    
	    w1ptr = win1->_line[line];
	    w2ptr = win2->_line[line];
	    fc = _NOCHANGE;

	    for(col = 0;  col <= last_col;  col++)
	    {
		if ((*w1ptr & A_CHARTEXT) != ' ')
		{
		    *w2ptr = (*w1ptr & A_CHARTEXT) | attrs;
		    if (fc == _NOCHANGE)
		        fc = col;
		    lc = col;
		}

		w1ptr++;
		w2ptr++;
	    }
	    
	    if (*firstchar == _NOCHANGE)
	    {
	        *firstchar = fc;
		*lastchar = lc;
	    }
	    else if (fc != _NOCHANGE)
	    {
	        if (fc < *firstchar)
		    *firstchar = fc;

	        if (lc > *lastchar)
		    *lastchar = lc;
            }

	    firstchar++;
	    lastchar++;
	}
}


X/*
**
**	overwrite(win1, win2)
**
**
**	overwrite() writes win1 on win2 destructively.
**
**/

overwrite(win1, win2)
WINDOW	*win1, *win2;
{
	int	col, line, last_line, last_col;
	short   *firstchar, *lastchar;
	chtype	*w1ptr, *w2ptr, attrs;

#ifdef TRACE
	if (_tracing)
	    _tracef("overwrite(%o, %o) called", win1, win2);
#endif
	
	last_col = min(win1->_maxx, win2->_maxx);
	last_line = min(win1->_maxy, win2->_maxy);
	attrs = win2->_attrs;
	firstchar = win2->_firstchar;
	lastchar = win2->_lastchar;

	for(line = 0;  line <= last_line;  line++)
	{
	    short   fc, lc;
	    
	    w1ptr = win1->_line[line];
	    w2ptr = win2->_line[line];
	    fc = _NOCHANGE;

	    for(col = 0;  col <= last_col;  col++)
	    {
		if ((*w1ptr & A_CHARTEXT) != (*w2ptr & A_CHARTEXT))
		{
		    *w2ptr = (*w1ptr & A_CHARTEXT) | attrs;
		    if (fc == _NOCHANGE)
		        fc = col;
		    lc = col;
		}

		w1ptr++;
		w2ptr++;
	    }

	    if (*firstchar == _NOCHANGE)
	    {
	        *firstchar = fc;
		*lastchar = lc;
	    }
	    else if (fc != _NOCHANGE)
	    {
	        if (fc < *firstchar)
		    *firstchar = fc;

	        if (lc > *lastchar)
		    *lastchar = lc;
            }
	    
	    firstchar++;
	    lastchar++;
	}
}
//go.sysin dd *
echo 'x - =src/lib_printw.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_printw.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_printw.c
**
**	The routines printw(), wprintw() and friend.
**
** $Log:	RCS/lib_printw.v $
 * Revision 2.1  82/10/25  14:48:38  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:48:22  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_printw.v  Revision 2.1  82/10/25  14:48:38  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


printw(fmt, args)
char	*fmt;
int	args;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("printw(%s,...) called", fmt);
#endif

	return(sprintw(stdscr, fmt, &args));
}



wprintw(win, fmt, args)
WINDOW	*win;
char	*fmt;
int	args;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("wprintw(%o,%s,...) called", win, fmt);
#endif

	return(sprintw(win, fmt, &args));
}



mvprintw(y, x, fmt, args)
int		y, x;
char		*fmt;
int		args;
{
	return(move(y, x) == OK ? sprintw(stdscr, fmt, &args) : ERR);
}



mvwprintw(win, y, x, fmt, args)
WINDOW	*win;
int	y, x;
char	*fmt;
int	args;
{
	return(wmove(win, y, x) == OK ? sprintw(win, fmt, &args) : ERR);
}



X/*
**	This routine actually executes the printf and adds it to the window
**
**	This is really a modified version of "sprintf".  As such,
** it assumes that sprintf interfaces with the other printf functions
** in a certain way.  If this is not how your system works, you
** will have to modify this routine to use the interface that your
** "sprintf" uses.
*/

static
sprintw(win, fmt, args)
WINDOW	*win;
char	*fmt;
int	*args;
{
	FILE	junk;
	char	buf[512];

	junk._flag = _IOWRT + _IOSTRG;
	junk._ptr = buf;
	junk._cnt = 32767;

	_doprnt(fmt, args, &junk);
	putc('\0', &junk);

	return(waddstr(win, buf));
}
//go.sysin dd *
echo 'x - =src/lib_raw.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_raw.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	raw.c
 *
 *	Routines:
 *		raw()
 *		echo()
 *		nl()
 *		cbreak()
 *		crmode()
 *		noraw()
 *		noecho()
 *		nonl()
 *		nocbreak()
 *		nocrmode()
 *
 *	cbreak() == crmode()
 *	nocbreak() == crmode()
 *
 *  $Log:	RCS/lib_raw.v $
 * Revision 2.1  82/10/25  14:48:42  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:17:40  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:30:32  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:11:25  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:43:18  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/lib_raw.v  Revision 2.1  82/10/25  14:48:42  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"
#include "term.h"




raw()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("raw() called");
#endif

    cur_term->Nttyb.sg_flags |= RAW;
    stty(cur_term->Filedes, &cur_term->Nttyb);

    SP->_raw = TRUE;
    SP->_nlmapping = TRUE;
}


cbreak()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("cbreak() called");
#endif

    cur_term->Nttyb.sg_flags |= CBREAK;
    stty(cur_term->Filedes, &cur_term->Nttyb);

    SP->_cbreak = TRUE;
}

crmode()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("crmode() called");
#endif

    cbreak();
}


echo()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("echo() called");
#endif

    cur_term->Nttyb.sg_flags |= ECHO;
    stty(cur_term->Filedes, &cur_term->Nttyb);

    SP->_echo = TRUE;
}


nl()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("nl() called");
#endif

    cur_term->Nttyb.sg_flags |= CRMOD;
    stty(cur_term->Filedes, &cur_term->Nttyb);

    SP->_nl = TRUE;
    SP->_nlmapping = ! SP->_raw;
}


noraw()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("noraw() called");
#endif

    cur_term->Nttyb.sg_flags &= ~RAW;
    stty(cur_term->Filedes, &cur_term->Nttyb);

    SP->_raw = FALSE;
    SP->_nlmapping = SP->_nl;
}


nocbreak()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("nocbreak() called");
#endif

    cur_term->Nttyb.sg_flags &= ~CBREAK;
    stty(cur_term->Filedes, &cur_term->Nttyb);

    SP->_cbreak = FALSE;
}

nocrmode()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("nocrmode() called");
#endif

    nocbreak();
}


noecho()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("noecho() called");
#endif

    cur_term->Nttyb.sg_flags &= ~ECHO;
    stty(cur_term->Filedes, &cur_term->Nttyb);

    SP->_echo = FALSE;
}


nonl()
{
#ifdef UNDEFINED
	if (_tracing)
	    _tracef("nonl() called");
#endif

    cur_term->Nttyb.sg_flags &= ~CRMOD;
    stty(cur_term->Filedes, &cur_term->Nttyb);

    SP->_nl = FALSE;
    SP->_nlmapping = FALSE;
}
//go.sysin dd *
echo 'x - =src/lib_refresh.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_refresh.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	lib_refresh.c
 *
 *	The routines wrefresh() and wnoutrefresh().
 *
 *  $Log:	lib_refresh.c,v $
 * Revision 3.1  84/12/13  11:20:51  john
 * Revisions by Mark Horton
 * 
 * Revision 2.1  82/10/25  14:48:45  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:48:47  pavel
 * Beta-one Test Release
 * 
 *
 */

static char RCSid[] =
	"$Header: lib_refresh.c,v 3.1 84/12/13 11:20:51 john Exp $";


#include "curses.h"
#include "curses.priv.h"


wrefresh(win)
WINDOW	*win;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("wrefresh(%o) called", win);
#endif

	if (win == curscr)
	{
	    curscr->_clear = TRUE;
	    doupdate();
	}
	else
	{
	    wnoutrefresh(win);
	    doupdate();
	}
}



wnoutrefresh(win)
WINDOW	*win;
{
	int	i, j;
	int	begx = win->_begx;
	int	begy = win->_begy;
	int	m, n;

#ifdef TRACE
	if (_tracing)
	    _tracef("wnoutrefresh(%o) called", win);
#endif

	for (i=0, m=begy; i <= win->_maxy; i++, m++)
	{
#ifdef TRACE
	    if (_tracing)
	    {
		_tracef("win->_firstchar[%d]= %d\t_lastchar= %d\t_numchngd= %d",
			    i, win->_firstchar[i],
			       win->_lastchar[i],
			       win->_numchngd[i]);
	    }
#endif

	    if (win->_numchngd[i])
	    {
		j = win->_firstchar[i];
		n = j + begx;
		for (; j <= win->_lastchar[i]; j++, n++)
		{
		    if (win->_line[i][j] != newscr->_line[m][n])
		    {
			newscr->_line[m][n] = win->_line[i][j];
			newscr->_numchngd[m] += 1;

			if (newscr->_firstchar[m] == _NOCHANGE)
			    newscr->_firstchar[m] = newscr->_lastchar[m] = n;
			else if (n < newscr->_firstchar[m])
			    newscr->_firstchar[m] = n;
			else if (n > newscr->_lastchar[m])
			    newscr->_lastchar[m] = n;
		    }
		}
	    }

	    win->_numchngd[i] = 0;
	    win->_firstchar[i] = win->_lastchar[i] = _NOCHANGE;
	}

	if (win->_clear)
	{
	    win->_clear = FALSE;
	    newscr->_clear = TRUE;
	}

	if (! win->_leave)
	{
	    newscr->_cury = win->_cury + win->_begy;
	    newscr->_curx = win->_curx + win->_begx;
	}
}
//go.sysin dd *
echo 'x - =src/lib_scanw.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_scanw.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_scanw.c
**
**	The routines scanw(), wscanw() and friend.
**
** $Log:	RCS/lib_scanw.v $
 * Revision 2.1  82/10/25  14:48:51  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:49:07  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_scanw.v  Revision 2.1  82/10/25  14:48:51  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


scanw(fmt, args)
char	*fmt;
int	args;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("scanw(%s,...) called", fmt);
#endif

	return(sscans(stdscr, fmt, &args));
}



wscanw(win, fmt, args)
WINDOW	*win;
char	*fmt;
int	args;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("wscanw(%o,%s,...) called", win, fmt);
#endif

	return(sscans(win, fmt, &args));
}



mvscanw(y, x, fmt, args)
int	y, x;
char	*fmt;
int	args;
{
	return(move(y, x) == OK ? sscanw(stdscr, fmt, &args) : ERR);
}



mvwscanw(win, y, x, fmt, args)
WINDOW	*win;
int	y, x;
char	*fmt;
int	args;
{
	return(wmove(win, y, x) == OK ? sscanw(win, fmt, &args) : ERR);
}



X/*
**	This routine actually executes the scanf from the window.
**
**	This is really a modified version of "sscanf".  As such,
** it assumes that sscanf interfaces with the other scanf functions
** in a certain way.  If this is not how your system works, you
** will have to modify this routine to use the interface that your
** "sscanf" uses.
*/

static
sscans(win, fmt, args)
WINDOW	*win;
char	*fmt;
int	*args;
{
	char	buf[100];
	FILE	junk;

	junk._flag = _IOREAD|_IOSTRG;
	junk._base = junk._ptr = buf;

	if (wgetstr(win, buf) == ERR)
	    return(ERR);

	junk._cnt = strlen(buf);

	return(_doscan(&junk, fmt, args));
}
//go.sysin dd *
echo 'x - =src/lib_scroll.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_scroll.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_scroll.c
**
**	The routine scroll().
**
** $Log:	RCS/lib_scroll.v $
 * Revision 2.1  82/10/25  14:48:54  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:49:22  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_scroll.v  Revision 2.1  82/10/25  14:48:54  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


scroll(win)
WINDOW	*win;
{
	int	i;
	chtype	*ptr, *temp;
	chtype	blank = ' ' | win->_attrs;

#ifdef TRACE
	if (_tracing)
	    _tracef("scroll(%o) called", win);
#endif

	if (! win->_scroll)
	    return;

	temp = win->_line[0];
	for (i = 0; i < win->_regbottom; i++)
	    win->_line[i] = win->_line[i+1];

	for (ptr = temp; ptr - temp <= win->_maxx; ptr++)
	    *ptr = blank;

	win->_line[win->_regbottom] = temp;

	win->_cury--;
}
//go.sysin dd *
echo 'x - =src/lib_scrreg.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_scrreg.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_scrreg.c
**
**	The routine wsetscrreg().
**
** $Log:	RCS/lib_scrreg.v $
 * Revision 2.1  82/10/25  14:49:00  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:49:29  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_scrreg.v  Revision 2.1  82/10/25  14:49:00  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


wsetscrreg(win, top, bottom)
WINDOW	*win;
int	top, bottom;
{
#ifdef TRACE
	if (_tracing)
	    _tracef("wsetscrreg(%o,%d,%d) called", win, top, bottom);
#endif

    	if (0 <= top  &&  top <= win->_cury  &&
		win->_cury <= bottom  &&  bottom <= win->_maxy)
	{
	    win->_regtop = top;
	    win->_regbottom = bottom;

	    return(OK);
	}
	else
	    return(ERR);
}
//go.sysin dd *
echo 'x - =src/lib_set_term.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_set_term.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_set_term.c
**
**	The routine set_term().
**
** $Log:	RCS/lib_set_term.v $
 * Revision 2.1  82/10/25  14:49:06  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:49:42  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_set_term.v  Revision 2.1  82/10/25  14:49:06  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"
#include "term.h"


struct screen *
set_term(screen)
struct screen *screen;
{
    	struct screen	*oldSP;

#ifdef TRACE
	if (_tracing)
	    _tracef("set_term(%o) called", screen);
#endif

	oldSP = SP;
	SP = screen;

	cur_term = SP->_term;
	curscr   = SP->_curscr;
	newscr   = SP->_newscr;

	return(oldSP);
}
//go.sysin dd *
echo 'x - =src/lib_setup.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_setup.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	setupterm(termname, filedes, errret)
 *
 *	Find and read the appropriate object file for the terminal
 *	Make cur_term point to the structure.
 *	Turn off the XTABS bit in the tty structure if it was on
 *	If XTABS was on, remove the tab and backtab capabilities.
 *
 *  $Log:	RCS/lib_setup.v $
 * Revision 2.1  82/10/25  14:49:09  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:17:46  pavel
 * Beta-one Test Release
 * 
 * Revision 1.5  82/08/23  22:30:35  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.4  82/08/20  15:12:24  pavel
 * Fixed use of un-initialised cur_term.
 * 
 * Revision 1.3  82/08/19  19:22:09  pavel
 * Alpha Test Release One
 * 
 * Revision 1.2  82/08/19  19:11:28  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:45:07  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/lib_setup.v  Revision 2.1  82/10/25  14:49:09  pavel  Exp$";

#include <stdio.h>
#include "curses.h"
#include "curses.priv.h"
#include "term.h"

#define ret_error(code, fmt, arg)	if (errret)\
					{\
					    *errret = code;\
					    return(code);\
					}\
					else\
					{\
					    fprintf(stderr, fmt, arg);\
					    exit(1);\
					}


setupterm(termname, filedes, errret)
char	*termname;
int	filedes;
int	*errret;
{
	char		filename1[1024];
	char		filename2[1024];
	char		*directory = SRCDIR;
	char		*malloc(), *getenv();
	char		*terminfo;
	struct term	*term_ptr;

#ifdef TRACE
	_init_trace();
	if (_tracing)
	    _tracef("setupterm(%s,%d,%o) called", termname, filedes, errret);
#endif

	if (termname == NULL)
	{
	    termname = getenv("TERM");
	    if (termname == NULL)
		ret_error(-1, "TERM environment variable not set.\n", "");
	}

	if (cur_term == 0)
	    term_ptr = &_first_term;
	else
	{
	    term_ptr = (struct term *) malloc(sizeof(struct term));

	    if (term_ptr == NULL)
		ret_error(-1, "Not enough memory to create terminal structure.\n", "");
	}

	if ((terminfo = getenv("TERMINFO")) != NULL)
	    directory = terminfo;

	sprintf(filename1, "%s/%c/%s", directory, termname[0], termname);
	sprintf(filename2, "%s/%c/%s", SRCDIR, termname[0], termname);

	if (read_entry(filename1, term_ptr) < 0
				    &&  read_entry(filename2, term_ptr) < 0)
	    ret_error(0, "'%s': Unknown terminal type.\n", termname);

	if (command_character  &&  getenv("CC"))
	    do_prototype();

	cur_term = term_ptr;
	strncpy(ttytype, cur_term->term_names, NAMESIZE - 1);
	ttytype[NAMESIZE - 1] = '\0';
	cur_term->Filedes = filedes;
	gtty(filedes, &cur_term->Ottyb);
	if (cur_term->Ottyb.sg_flags & XTABS)
	    tab = back_tab = NULL;

	cur_term->Nttyb = cur_term->Ottyb;
	cur_term->Nttyb.sg_flags &= ~XTABS;

	fixterm();

	if (errret)
	    *errret = 1;
	
	return(1);
}



X/*
**	do_prototype()
**
**	Take the real command character out of the CC environment variable
**	and substitute it in for the prototype given in 'command_character'.
**
*/

static
do_prototype()
{
    	int	i, j;
	char	CC;
	char	proto;

	CC = *getenv("CC");
	proto = *command_character;

	for (i=0; i < STRCOUNT; i++)
	{
	    j = 0;
	    while (cur_term->Strings[i][j])
	    {
		if (cur_term->Strings[i][j] == proto)
		    cur_term->Strings[i][j] = CC;
		j++;
	    }
	}
}
//go.sysin dd *
echo 'x - =src/lib_touchwin.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_touchwin.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_touchwin.c
**
**	The routine touchwin().
**
** $Log:	RCS/lib_touchwin.v $
 * Revision 2.1  82/10/25  14:49:13  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:49:52  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_touchwin.v  Revision 2.1  82/10/25  14:49:13  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"


touchwin(win)
WINDOW	*win;
{
	int	y, maxy, maxx;

#ifdef TRACE
	if (_tracing)
	    _tracef("touchwin(%o) called", win);
#endif

	maxy = win->_maxy;
	maxx = win->_maxx;

	for (y = 0; y <= maxy; y++)
	{
	    win->_firstchar[y] = 0;
	    win->_lastchar[y] = maxx;
	    win->_numchngd[y] = maxx;
	}
}
//go.sysin dd *
echo 'x - =src/lib_tparm.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_tparm.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	tparm.c
 *
 *  $Log:	RCS/lib_tparm.v $
 * Revision 2.1  82/10/25  14:49:19  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:17:53  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:30:38  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:11:33  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:45:33  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/lib_tparm.v  Revision 2.1  82/10/25  14:49:19  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"
#include "term.h"



X/*
 *	char *
 *	tparm(string, parms)
 *
 *	Substitute the given parameters into the given string by the following
 *	rules (taken from terminfo(5)):
 *
 *	     Cursor addressing and other strings  requiring  parame-
 *	ters in the terminal are described by a parameterized string
 *	capability, with like escapes %x in  it.   For  example,  to
 *	address  the  cursor, the cup capability is given, using two
 *	parameters: the row and column to  address  to.   (Rows  and
 *	columns  are  numbered  from  zero and refer to the physical
 *	screen visible to the user, not to any  unseen  memory.)  If
 *	the terminal has memory relative cursor addressing, that can
 *	be indicated by
 *	
 *	     The parameter mechanism uses  a  stack  and  special  %
 *	codes  to manipulate it.  Typically a sequence will push one
 *	of the parameters onto the stack and then print it  in  some
 *	format.  Often more complex operations are necessary.
 *	
 *	     The % encodings have the following meanings:
 *	
 *	     %%        outputs `%'
 *	     %d        print pop() like %d in printf()
 *	     %2d       print pop() like %2d in printf()
 *	     %02d      print pop() like %02d in printf()
 *	     %3d       print pop() like %3d in printf()
 *	     %03d      print pop() like %03d in printf()
 *	     %c        print pop() like %c in printf()
 *	     %s        print pop() like %s in printf()
 *	
 *	     %p[1-9]   push ith parm
 *	     %P[a-z]   set variable [a-z] to pop()
 *	     %g[a-z]   get variable [a-z] and push it
 *	     %'c'      push char constant c
 *	     %{nn}     push integer constant nn
 *	
 *	     %+ %- %* %/ %m
 *	               arithmetic (%m is mod): push(pop() op pop())
 *	     %& %| %^  bit operations: push(pop() op pop())
 *	     %= %> %<  logical operations: push(pop() op pop())
 *	     %! %~     unary operations push(op pop())
 *	     %i        add 1 to first two parms (for ANSI terminals)
 *	
 *	     %? expr %t thenpart %e elsepart %;
 *	               if-then-else, %e elsepart is optional.
 *	               else-if's are possible ala Algol 68:
 *	               %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e b5 %;
 *	
 *	For those of the above operators which are binary and not commutative,
 *	the stack works in the usual way, with
 *			%gx %gy %m
 *	resulting in x mod y, not the reverse.
 */

#define STACKSIZE	20

#define npush(x)    if (stack_ptr < STACKSIZE) {stack[stack_ptr].num = x;\
                                                stack_ptr++;\
                                               }
#define npop()	   (stack_ptr > 0  ?  stack[--stack_ptr].num  :  0)
#define spop()	   (stack_ptr > 0  ?  stack[--stack_ptr].str  :  (char *) 0)

typedef union
{
	unsigned int	num;
	char		*str;
}		stack_frame;

stack_frame	stack[STACKSIZE];
static	int	stack_ptr;
static	char	buffer[256];
static	int	*param;
static	char	*bufptr;
static	int	variable[26];

static	char	*do_tparm();

char *
tparm(string, parms)
char	*string;
int	parms;
{
	char	len;
	int	number;
	int	level;
	int	x, y;

	param = &parms;

#ifdef UNDEFINED
	if (_tracing)
	    _tracef("tparm(%s,%d,%d,%d,%d,%d,%d,%d,%d,%d) called",
			string, param[0], param[1], param[2], param[3],
			param[4], param[5], param[6], param[7], param[8]);
#endif

	stack_ptr = 0;
	bufptr = buffer;

	while (*string)
	{
	    if (*string != '%')
		*(bufptr++) = *string;
	    else
	    {
		string++;
		switch (*string)
		{
		    default:
			break;

		    case '%':
			*(bufptr++) = '%';
			break;

		    case 'd':
			sprintf(bufptr, "%d", npop());
			bufptr += strlen(bufptr);
			break;

		    case '0':
			string++;
			len = *string;
			if ((len == '2'  ||  len == '3')  &&  *++string == 'd')
			{
			    if (len == '2')
				sprintf(bufptr, "%02d", npop());
			    else
				sprintf(bufptr, "%03d", npop());
			    
			    bufptr += strlen(bufptr);
			}
			break;

		    case '2':
			string++;
			if (*string == 'd')
			{
			    sprintf(bufptr, "%2d", npop());
			    bufptr += strlen(bufptr);
			}
			break;

		    case '3':
			string++;
			if (*string == 'd')
			{
			    sprintf(bufptr, "%3d", npop());
			    bufptr += strlen(bufptr);
			}
			break;

		    case 'c':
			*(bufptr++) = (char) npop();
			break;

		    case 's':
			strcpy(bufptr, spop());
			bufptr += strlen(bufptr);
			break;

		    case 'p':
			string++;
			if (*string >= '1'  &&  *string <= '9')
			    npush(param[*string - '1']);
			break;

		    case 'P':
			string++;
			if (*string >= 'a'  &&  *string <= 'z')
			    variable[*string - 'a'] = npop();
			break;

		    case 'g':
			string++;
			if (*string >= 'a'  &&  *string <= 'z')
			    npush(variable[*string - 'a']);
			break;

		    case '\'':
			string++;
			npush(*string);
			string++;
			break;

		    case '{':
			number = 0;
			string++;
			while (*string >= '0'  &&  *string <= '9')
			{
			    number = number * 10 + *string - '0';
			    string++;
			}
			npush(number);
			break;

		    case '+':
			npush(npop() + npop());
			break;

		    case '-':
			y = npop();
			x = npop();
			npush(x - y);
			break;

		    case '*':
			npush(npop() * npop());
			break;

		    case '/':
			y = npop();
			x = npop();
			npush(x / y);
			break;

		    case 'm':
			y = npop();
			x = npop();
			npush(x % y);
			break;

		    case '&':
			npush(npop() & npop());
			break;

		    case '|':
			npush(npop() | npop());
			break;

		    case '^':
			npush(npop() ^ npop());
			break;

		    case '=':
			y = npop();
			x = npop();
			npush(x == y);
			break;

		    case '<':
			y = npop();
			x = npop();
			npush(x < y);
			break;

		    case '>':
			y = npop();
			x = npop();
			npush(x > y);
			break;

		    case '!':
			npush(! npop());
			break;

		    case '~':
			npush(~ npop());
			break;

		    case 'i':
			param[0]++;
			param[1]++;
			break;

		    case '?':
			break;

		    case 't':
			x = npop();
			if (x)
			{
			    /* do nothing; keep executing */
			}
			else
			{
			    /* scan forward for %e or %; at level zero */
				string++;
				level = 0;
				while (*string)
				{
				    if (*string == '%')
				    {
					string++;
					if (*string == '?')
					    level++;
					else if (*string == ';')
					{
					    if (level > 0)
						level--;
					    else
						break;
					}
					else if (*string == 'e'  && level == 0)
					    break;
				    }

				    if (*string)
					string++;
				}
			}
			break;

		    case 'e':
			/* scan forward for a %; at level zero */
			    string++;
			    level = 0;
			    while (*string)
			    {
				if (*string == '%')
				{
				    string++;
				    if (*string == '?')
					level++;
				    else if (*string == ';')
				    {
					if (level > 0)
					    level--;
					else
					    break;
				    }
				}

				if (*string)
				    string++;
			    }
			break;

		    case ';':
			break;

		} /* endswitch (*string) */
	    } /* endelse (*string == '%') */

	    if (*string == '\0')
		break;
	    
	    string++;
	} /* endwhile (*string) */

	*bufptr = '\0';
	return(buffer);
}



X/*
 *	char *
 *	tgoto(string, x, y)
 *
 *	Retained solely for upward compatibility.  Note the intentional
 *	reversing of the last two arguments.
 *
 */

char *
tgoto(string, x, y)
char	*string;
int	x, y;
{
	return(tparm(string, y, x));
}
//go.sysin dd *
exit

sources@genrad.UUCP (12/21/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit".  This code is completely public domain, originally written by Pavel
Curtis of Cornell University.  This version has some small improvements and
bug fixes.

This unit contains:
	The last of the library, and the start of the terminal data.

Part 10 will be
	The end of the terminfo terminal data base.

----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =src
then
    echo 'Making directory "=src"'
    mkdir =src
fi
echo 'x - =src/lib_tputs.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_tputs.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	tputs.c
 *
 *  $Log:	lib_tputs.c,v $
 * Revision 3.1  84/12/13  11:21:03  john
 * Revisions by Mark Horton
 * 
 * Revision 2.1  82/10/25  14:49:31  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:18:06  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:30:52  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:11:38  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:46:00  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header: lib_tputs.c,v 3.1 84/12/13 11:21:03 john Exp $";

#include <ctype.h>
#include <stdio.h>
#include "curses.h"
#include "curses.priv.h"
#include "term.h"


tputs(string, affcnt, outc)
char	*string;
int	affcnt;
int	(*outc)();
{
	float	number;
	int	baud = baudrate();
	char	null = '\0';
	int	i;

#ifdef TRACE
	if (_tracing)
	    _tracef("tputs(%s,%d,%o) called", string, affcnt, outc);
#endif

	if (pad_char)
	    null = pad_char[0];

	while (*string)
	{
	    if (*string != '$')
		(*outc)(*string);
	    else
	    {
		string++;
		if (*string != '<')
		{
		    (*outc)('$');
		    (*outc)(*string);
		}
		else
		{

		    number = 0;
		    string++;

		    if (!isdigit(*string) && *string != '.' || !index(string, '>')) {
			(*outc)('$');
			(*outc)('<');
			continue;
		    }
		    while (isdigit(*string))
		    {
			number = number * 10 + *string - '0';
			string++;
		    }

		    if (*string == '.')
		    {
			string++;
			if (isdigit(*string))
			{
			    number += (float) (*string - '0') / 10.;
			    string++;
			}
		    }

		    if (*string == '*')
		    {
			number *= affcnt;
			string++;
		    }

		    if (padding_baud_rate  &&  baud >= padding_baud_rate && !xon_xoff)
		    {
			number = ((baud / 10.) * number) / 1000.;
			
			for (i=0; i < number; i++)
			    (*outc)(null);
		    }

		} /* endelse (*string == '<') */
	    } /* endelse (*string == '$') */

	    if (*string == '\0')
		break;

	    string++;
	}
}


void
_outc(ch)
{
    putchar(ch);
}


putp(string)
{
#ifdef TRACE
	if (_tracing)
	    _tracef("putp(%s) called", string);
#endif
	tputs(string, 1, _outc);
}
//go.sysin dd *
echo 'x - =src/lib_trace.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_trace.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	lib_trace.c - Tracing/Debugging routines
 *
 *  $Log:	RCS/lib_trace.v $
 * Revision 2.1  82/10/25  14:49:35  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:18:09  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:30:57  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:11:41  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/15  17:59:45  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
    "$Header:   RCS/lib_trace.v  Revision 2.1  82/10/25  14:49:35  pavel  Exp$";

#include "term.h"
#include "curses.h"
#include "curses.priv.h"


static int	tracefd;

_init_trace()
{
    	static int	been_here = 0;
	extern int	errno;
	extern char	*sys_errlist[];

	if (! been_here)
	{
	    been_here = 1;

	    if ((tracefd = creat("trace", 0644)) < 0)
	    {
		write(2, "curses: Can't open 'trace' file: ", 33);
		write(2, sys_errlist[errno], strlen(sys_errlist[errno]));
		write(2, "\n", 1);
		exit(1);
	    }
	}
}


traceon()
{
	_tracef("traceon() called");

    	_tracing = 1;
}


traceoff()
{
	_tracef("traceoff() called");

    	_tracing = 0;
}


_tracef(fmt, args)
char	*fmt;
int	args;
{
    	int	*parm = &args;
	char	buffer[256];
	char	*bufp = buffer;

	while (*fmt)
	{
	    if (*fmt == '%')
	    {
		fmt++;
		switch (*fmt)
		{
		    case 'd':
			addnum(&bufp, *(parm++), 10);
			break;

		    case 'o':
			addnum(&bufp, *(parm++), 8);
			break;

		    case 'c':
			*(bufp++) = *(parm++);
			break;

		    case 's':
			if (*parm)
			{
			    *(bufp++) = '"';
			    strcpy(bufp, *parm);
			    bufp += strlen(*parm);
			    *(bufp++) = '"';
			}
			else
			{
			    strcpy(bufp, "NULL");
			    bufp += 4;
			}
			parm++;
			break;
		}
	    }
	    else
		*(bufp++) = *fmt;

	    fmt++;
	}

	*(bufp++) = '\n';
	*bufp = '\0';
	write(tracefd, buffer, strlen(buffer));
}


static addnum(bufp, num, base)
char	**bufp;
int	num, base;
{
	int	a;

    	if (num < 0)
	{
	    num = -num;
	    *((*bufp)++) = '-';
	}

	if ((a = num / base) != 0)
	    addnum(bufp, a, base);
	*((*bufp)++) = '0' + (num % base);
}
//go.sysin dd *
echo 'x - =src/lib_tstp.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_tstp.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
**	lib_tstp.c
**
**	The routine tstp().
**
** $Log:	RCS/lib_tstp.v $
 * Revision 2.1  82/10/25  14:49:39  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/25  13:50:01  pavel
 * Beta-one Test Release
 * 
**
*/

static char RCSid[] =
	"$Header:   RCS/lib_tstp.v  Revision 2.1  82/10/25  14:49:39  pavel  Exp$";

#include "term.h"
#include "curses.h"
#include "curses.priv.h"
#include <signal.h>


static
outc(ch)
char	ch;
{
    	putc(ch, SP->_ofp);
}


tstp()
{
#ifdef TRACE
	if (_tracing)
	    _tracef("tstp() called");
#endif

	endwin();

	kill(0, SIGTSTP);
	signal(SIGTSTP, tstp);

	fixterm();
	flushinp();
	tputs(enter_ca_mode, 1, outc);
	wrefresh(curscr);
}
//go.sysin dd *
echo 'x - =src/lib_unctrl.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_unctrl.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 * define unctrl codes for each character
 *
 *  $Log:	RCS/lib_unctrl.v $
 * Revision 2.1  82/10/25  14:49:42  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:18:12  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:31:04  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:11:43  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:46:42  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/lib_unctrl.v  Revision 2.1  82/10/25  14:49:42  pavel  Exp$";

X/* LINTLIBRARY */
char	*_unctrl[]	= {	/* unctrl codes for ttys		*/
	"^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "^I", "^J", "^K",
	"^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W",
	"^X", "^Y", "^Z", "^[", "^\\", "^]", "^~", "^_",
	" ", "!", "\"", "#", "$",  "%", "&", "'", "(", ")", "*", "+", ",", "-",
	".", "/", "0",  "1", "2",  "3", "4", "5", "6", "7", "8", "9", ":", ";",
	"<", "=", ">",  "?", "@",  "A", "B", "C", "D", "E", "F", "G", "H", "I",
	"J", "K", "L",  "M", "N",  "O", "P", "Q", "R", "S", "T", "U", "V", "W",
	"X", "Y", "Z",  "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e",
	"f", "g", "h",  "i", "j",  "k", "l", "m", "n", "o", "p", "q", "r", "s",
	"t", "u", "v",  "w", "x",  "y", "z", "{", "|", "}", "~", "^?"
};
//go.sysin dd *
echo 'x - =src/lib_vidattr.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/lib_vidattr.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	vidputs(newmode, outc)
 *
 *	newmode is taken to be the logical 'or' of the symbols in curses.h
 *	representing graphic renditions.  The teminal is set to be in all of
 *	the given modes, if possible.
 *
 *	if set-attributes exists
 *		use it to set exactly what you want
 *	else
 *		if exit-attribute-mode exists
 *			turn off everything
 *		else
 *			turn off those which can be turned off and aren't in
 *			newmode.
 *		turn on each mode which should be on and isn't, one by one
 *
 *	NOTE that this algorithm won't achieve the desired mix of attributes
 *	in some cases, but those are probably just those cases in which it is
 *	actually impossible, anyway, so...
 *
 *  $Log:	RCS/lib_vidattr.v $
 * Revision 2.1  82/10/25  14:49:45  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:18:15  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:31:08  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:11:46  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  18:48:23  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header:   RCS/lib_vidattr.v  Revision 2.1  82/10/25  14:49:45  pavel  Exp$";

#include "curses.h"
#include "curses.priv.h"
#include "term.h"


vidputs(newmode, outc)
unsigned newmode;
int	 (*outc)();
{
	static unsigned		previous_attr = 0;
	       unsigned		turn_off, turn_on;

#ifdef TRACE
	if (_tracing)
	    _tracef("vidputs(%o,%o) called", newmode, outc);
#endif

	if (set_attributes)
	{
	    tputs(tparm(set_attributes,
			(newmode & A_STANDOUT) != 0,
			(newmode & A_UNDERLINE) != 0,
			(newmode & A_REVERSE) != 0,
			(newmode & A_BLINK) != 0,
			(newmode & A_DIM) != 0,
			(newmode & A_BOLD) != 0,
			(newmode & A_INVIS) != 0,
			(newmode & A_PROTECT) != 0,
			(newmode & A_ALTCHARSET) != 0), 1, outc);
	}
	else
	{
	    if (exit_attribute_mode)
		tputs(exit_attribute_mode, 1, outc);
	    else
	    {
		turn_off = ~newmode & previous_attr;

		if ((turn_off & A_UNDERLINE)  &&  exit_underline_mode)
		    tputs(exit_underline_mode, 1, outc);

		if ((turn_off & A_STANDOUT)  &&  exit_standout_mode)
		    tputs(exit_standout_mode, 1, outc);

		if ((turn_off & A_ALTCHARSET)  &&  exit_alt_charset_mode)
		    tputs(exit_alt_charset_mode, 1, outc);
	    }

	    turn_on = newmode & ~previous_attr;

	    if ((turn_on & A_ALTCHARSET)  &&  enter_alt_charset_mode)
		tputs(enter_alt_charset_mode, 1, outc);

	    if ((turn_on & A_BLINK)  &&  enter_blink_mode)
		tputs(enter_blink_mode, 1, outc);

	    if ((turn_on & A_BOLD)  &&  enter_bold_mode)
		tputs(enter_bold_mode, 1, outc);

	    if ((turn_on & A_INVIS)  &&  enter_secure_mode)
		tputs(enter_secure_mode, 1, outc);

	    if ((turn_on & A_DIM)  &&  enter_dim_mode)
		tputs(enter_dim_mode, 1, outc);

	    if ((turn_on & A_PROTECT)  &&  enter_protected_mode)
		tputs(enter_protected_mode, 1, outc);

	    if ((turn_on & A_REVERSE)  &&  enter_reverse_mode)
		tputs(enter_reverse_mode, 1, outc);

	    if ((turn_on & A_STANDOUT)  &&  enter_standout_mode)
		tputs(enter_standout_mode, 1, outc);

	    if ((turn_on & A_UNDERLINE)  &&  enter_underline_mode)
		tputs(enter_underline_mode, 1, outc);
	}

	previous_attr = newmode;
}



vidattr(newmode)
unsigned	newmode;
{
    void	_outc();

#ifdef TRACE
	if (_tracing)
	    _tracef("vidattr(%o) called", newmode);
#endif

    vidputs(newmode, _outc);
}
//go.sysin dd *
echo 'x - =src/read_entry.c'
sed 's/^X//' <<'//go.sysin dd *' >=src/read_entry.c
X/*********************************************************************
*                         COPYRIGHT NOTICE                           *
**********************************************************************
*        This software is copyright (C) 1982 by Pavel Curtis         *
*                                                                    *
*        Permission is granted to reproduce and distribute           *
*        this file by any means so long as no fee is charged         *
*        above a nominal handling fee and so long as this            *
*        notice is always included in the copies.                    *
*                                                                    *
*        Other rights are reserved except as explicitly granted      *
*        by written permission of the author.                        *
*                Pavel Curtis                                        *
*                Computer Science Dept.                              *
*                405 Upson Hall                                      *
*                Cornell University                                  *
*                Ithaca, NY 14853                                    *
*                                                                    *
*                Ph- (607) 256-4934                                  *
*                                                                    *
*                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
*                decvax!cornell!pavel       (UUCPnet)                *
*********************************************************************/

X/*
 *	read_entry.c -- Routine for reading in a compiled terminfo file
 *
 *  $Log:	read_entry.c,v $
 * Revision 3.1  84/12/13  11:21:14  john
 * Revisions by Mark Horton
 * 
 * Revision 2.1  82/10/25  14:49:55  pavel
 * Added Copyright Notice
 * 
 * Revision 2.0  82/10/24  15:18:22  pavel
 * Beta-one Test Release
 * 
 * Revision 1.3  82/08/23  22:31:15  pavel
 * The REAL Alpha-one Release Version
 * 
 * Revision 1.2  82/08/19  19:11:49  pavel
 * Alpha Test Release One
 * 
 * Revision 1.1  82/08/12  22:25:13  pavel
 * Initial revision
 * 
 *
 */

static char RCSid[] =
	"$Header: read_entry.c,v 3.1 84/12/13 11:21:14 john Exp $";

#include <sys/types.h>
#include <sys/stat.h>
#include "term.h"
#include "object.h"

#define OFFSET_BUFSIZE	100

#define min(a, b)	((a) > (b)  ?  (b)  :  (a))

X/*
 *	int
 *	read_entry(filename, ptr)
 *
 *	Read the compiled terminfo entry in the given file into the
 *	structure pointed to by ptr, allocating space for the string
 *	table and placing its address in ptr->str_table.
 *
 */

#define swap(x)		(((x >> 8) & 0377) + 256 * (x & 0377))

static char	TermNames[128];	/* Buffer for terminal names for first term */
static char	StringTable[1024];	/* String table for first terminal  */

int
read_entry(filename, ptr)
char		*filename;
struct term	*ptr;
{
	struct stat	statbuf;
	int		fd;
	int		numread;
	int		num_strings;
	int		cur_string;
	char		*malloc();
	int		i;
	struct header	header;
	unsigned char	bytebuf[2];
	char		ch;
	union
	{
	    unsigned char    byte[2];
	    short            number;
	}		offset_buf[OFFSET_BUFSIZE];

	fd = open(filename, 0);

	if (fd < 0)
	    return(-1);

	read(fd, &header, sizeof(header));

	if (must_swap())
	{
	    header.magic = swap(header.magic);
	    header.name_size = swap(header.name_size);
	    header.bool_count = swap(header.bool_count);
	    header.num_count = swap(header.num_count);
	    header.str_count = swap(header.str_count);
	    header.str_size = swap(header.str_size);
	}

	if (header.magic != MAGIC)
	{
	    close(fd);
	    return(-1);
	}

	read(fd, TermNames, min(127, header.name_size));
	TermNames[127] = '\0';
	ptr->term_names = TermNames;
	if (header.name_size > 127)
	    lseek(fd, (long) (header.name_size - 127), 1);

	read(fd, ptr->Booleans, min(BOOLCOUNT, header.bool_count));
	if (header.bool_count > BOOLCOUNT)
	    lseek(fd, (long) (header.bool_count - BOOLCOUNT), 1);
	else
	    for (i=header.bool_count; i < BOOLCOUNT; i++)
		ptr->Booleans[i] = 0;

	if ((header.name_size + header.bool_count) % 2 != 0)
	    read(fd, &ch, 1);

	if (must_swap())
	    read(fd, ptr->Numbers, min(NUMCOUNT, header.num_count * 2));
	else
	{
	    for (i=0; i < min(header.num_count, NUMCOUNT); i++)
	    {
		read(fd, bytebuf, 2);
		if (bytebuf[0] == 0377  &&  bytebuf[1] == 0377)
		    ptr->Numbers[i] = -1;
		else
		    ptr->Numbers[i] = bytebuf[0] + 256 * bytebuf[1];
	    }
	}

	if (header.num_count > NUMCOUNT)
	    lseek(fd, (long) (2 * (header.num_count - NUMCOUNT)), 1);
	else
	    for (i=header.num_count; i < NUMCOUNT; i++)
		ptr->Numbers[i] = -1;

	if (cur_term)	/* cur_term is non-zero only if we've been called */
	{
	    ptr->str_table = malloc(header.str_size);
	    if (ptr->str_table == NULL)
	    {
		close(fd);
		return (-1);
	    }
	}
	else
	    ptr->str_table = StringTable;

	num_strings = min(STRCOUNT, header.str_count);
	cur_string = 0;

	while (num_strings > 0)
	{
	    numread = read(fd, offset_buf, 2*min(num_strings, OFFSET_BUFSIZE));
	    if (numread <= 0)
	    {
		close(fd);
		return(-1);
	    }

	    if (must_swap())
	    {
		for (i = 0; i < numread / 2; i++)
		{
		    ptr->Strings[i + cur_string] =
			(offset_buf[i].byte[0] == 0377
					    &&  offset_buf[i].byte[1] == 0377)
			? 0
			: ((offset_buf[i].byte[0] + 256*offset_buf[i].byte[1])
							      + ptr->str_table);
		}
	    }
	    else
	    {
		for (i = 0; i < numread / 2; i++)
		{
		    ptr->Strings[i + cur_string] =
			(offset_buf[i].number == -1)
			?
			    0
			:
			    offset_buf[i].number + ptr->str_table;
		}
	    }

	    cur_string += numread / 2;
	    num_strings -= numread / 2;
	}

	if (header.str_count > STRCOUNT)
	    lseek(fd, (long) (2 * (header.str_count - STRCOUNT)), 1);
	else
	    for (i=header.str_count; i < STRCOUNT; i++)
		ptr->Strings[i] = 0;

	numread = read(fd, ptr->str_table, header.str_size);
	close(fd);
	if (numread != header.str_size)
	    return(-1);

	return(0);
}



X/*
 *	int
 *	must_swap()
 *
 *	Test whether this machine will need byte-swapping
 *
 */

int
must_swap()
{
	union
	{
	    short num;
	    char  byte[2];
	}		test;

	test.num = 1;
	return(test.byte[1]);
}
//go.sysin dd *
echo 'x - =src/xx.ti'
sed 's/^X//' <<'//go.sysin dd *' >=src/xx.ti
xaa-a|foobar a,
	cud1=ctrlK, cub1=ctrlH, cuf1=esc[C, cuu1=esc[A,
	use=ansi+local,
	clear=esc[Hesc[J$<156>, el=esc[K$<5>, ed=esc[J,
xaa-b,
	is1=esc[7mesc7esc[Hesc9esc8,
xaa-c|foobar c,
	is2=\r\nesc[Aesc7esc[60;1;0;30pesc8, lines#29,
	use=xaa-a,
xaa-d|foobar d,
	use=xaa-b, use=xaa-c,
xaa-e|foobar e,
	smcup=esc[30;1Hesc[Kesc[30;1;0;30p,
	use=xaa-d,
xaa-f,
	cup=esc[%i%p1%d;%p2%dH, home=esc[H, bold=esc[1m,
//go.sysin dd *
if test ! -d =data
then
    echo 'Making directory "=data"'
    mkdir =data
fi
echo 'x - =data/misc'
sed 's/^X//' <<'//go.sysin dd *' >=data/misc
# # --------------------------------
#	@(#)misc	1.8	5/20/82
#
# misc: MISCELLANEOUS TERMINALS
#
# ----------------------------------------------------------------
#
# BB&N BitGraph
# The function keys kf0-kf9 are the codes generated by the keypad keys 0-9
# NOTE that this means that PF1-PF4 are not represented here at all.
bg|bitg|bitgraph|BBN BitGraph,
	msgr, xon, cols#85, lines#64,
	bel=^G, cr=^M, tbc=\E[g, clear=\E[H\E[J, el=\E[K, ed=\E[J,
	cup=\E[%i%p1%d;%p2%dH, home=\E[H,
	cub=\E[%p1%dD, cub1=\E[D, cuf=\E[%p1%dC, cuf1=\E[C,
	cud=\E[%p1%dB, cud1=\E[B, cuu=\E[%p1%dA, cuu1=\E[A,
	dl=\E[%p1%dM, dl1=\E[M, il=\E[%p1%dL, il1=\E[L,
#	dch=\E[%p1%dP, dch1=\E[P, ich=\E[%p1%d@, ich1=\E[@,
	smso=\E[4m, rmso=\E[m, smul=\E[4m, rmul=\E[m,
	bold=\E[m, rev=\E[7m, sgr0=\E[m,
	sgr=\E[%?%p1%t7;%;%?%p2%t4;%;%?%p3%t7;%;%?%p4%t5;%;%?%p6%t1;%;m,
	is2=\E:e\E[m\E(B^O\E[1;64r\E[H\E[J\E[20l\E[?1;6l\E[?5;7;50;52h\E=,
	kbs=^H, kcud1=\E[B, kcub1=\E[D, kcuf1=\E[C, kcuu1=\E[A,
	kf0=\EOp, kf1=\EOq, kf2=\EOr, kf3=\EOs, kf4=\EOt,
	kf5=\EOu, kf6=\EOv, kf7=\EOw, kf8=\EOx, kf9=\EOy,
	sc=\E7, rc=\E8, ind=\ED, ri=\EM, nel=\EE,
	hts=\EH, ht=^I,
#
# Vanilla ANSI terminal.  This is assumed to implement all the normal
# ANSI stuff with no extensions.  It assumes insert/delete line/char
# is there, so it won't work with vt100 clones.  It assumes video
# attributes for bold, blink, underline, and reverse, which won't
# matter much if the terminal can't do some of those.  Padding is
# assumed to be zero, which shouldn't hurt since xon/xoff is assumed.
# This entry is based on the Ann Arbor Ambassador.
ansi|generic ansi standard terminal,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=\E[L, am, cub1=^H, ed=\E[J,
	el=\E[K, clear=\E[H\E[J, cup=\E[%i%p1%d;%p2%dH, cols#80, lines#24,
	dch1=\E[P, dl1=\E[M, home=\E[H,
	ich=\E[%p1%d@, ich1=\E[@, smir=\E6, rmir=\E6,
	bold=\E[1m, rev=\E[7m, blink=\E[5m, invis=\E[8m, sgr0=\E[0m,
	sgr=\E[%?%p1%t7;%;%?%p2%t4;%;%?%p3%t7;%;%?%p4%t5;%;%?%p6%t1;%;m,
	kcuu1=\E[A, kcud1=\E[B, kcub1=\E[D, kcuf1=\E[C, khome=\E[H, kbs=^H,
	cuf1=\E[C, ht=^I, cuu1=\E[A, xon, rep=%p1%c\E[%p2%{1}%-%db,
	rmul=\E[m, smul=\E[4m, rmso=\E[m, smso=\E[7m,
# The tab 132 uses xon/xoff, so no padding needed.
# smkx/rmkx have nothing to do with arrow keys.
# is2 sets 80 col mode, normal video, autowrap on (for am).
# Seems to be no way to get rid of status line.
tab132|tab|tab 132/15,
	is2=\E[?7h\E[?3l\E[?5l, smkx@, rmkx@, cr=^M, cud1=^J, ind=^J,
	bel=^G, lm#96, da, db, il1=\E[L, dl1=\E[M, dch1=\E[P,
	rmir=\E[4l, smir=\E[4h, cup=\E[%i%p1%d;%p2%dH,
	kcuu1=\E[A, kcud1=\E[B, kcub1=\E[D, use=vt100,
tab132w,
	cols#132, is2=\E[?7h\E[?3h\E[?5l, use=tab132,
tab132rv,
	is2=\E[?7h\E[?3l\E[?5h, use=tab132,
tab132wrv,
	is2=\E[?7h\E[?3h\E[?5h, use=tab132w,
# This used to say "de#001202" which presumably refers to the stty bits
# that need to be set for some version of Unix.  We need the real delay
# requirements here.
mw2|Multiwriter 2,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#132, hc, os,
trs80|trs-80|Radio Shack TRS-80 model I,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	am, cub1=^H, cols#64, lines#16,
# I think the direct is supposed to be vt100 compatible, so all this
# should probably be replaced by a use=vt100, but I can't test it.
d800|direct|direct800|Direct 800/A,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#80, lines#24, am,
	clear=\E[1;1H\E[2J, cub1=^H, cup=\E[%i%p1%d;%p2%dH,
	cuf1=\E[C, cuu1=\E[A, el=\E[K, ed=\E[J, smso=\E[7m, rmso=\E[0m,
	smul=\E[4m, rmul=\E[0m, xhp, cvvis=\E[>12l, cnorm=\E[>12h,
	ind=\ED, ri=\EM, da, db, rmacs=\E[1m, smacs=\E[0m, msgr, ht=^I, 
	kcub1=\E[D, kcuf1=\E[C, kcuu1=\E[A, kcud1=\E[B,
	kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS,
	kf5=\EOT, kf6=\EOU, kf7=\EOV, kf8=\EOW,
vc404|volker-craig 404,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H, ed=^W$<40>, el=^V$<20>,
	clear=^X$<40>, cup=^P%p1%' '%+%c%p2%' '%+%c, cols#80, home=^Y$<40>,
	kcud1=^J, kcub1=^H, kcuf1=^U, kcuu1=^Z, lines#24, cuf1=^U, cuu1=^Z,
vc404s|volker-craig 404 w/standout mode,
	cr=^M, cud1=^J, ind=^J, bel=^G, rmso=^O, smso=^N, use=vc404,
vc404na|volker-craig 404 w/no arrow keys,
	kcuf1@, kcuu1@, use=vc404,
vc404sna|volker-craig 404 w/standout mode and no arrow keys,
	rmso=^O, smso=^N, use=vc404na,
# missing in vc303a and vc303 descriptions:  they scroll 2 lines at a time
# every other linefeed.
vc303a|vc403a|volker-craig 303a,
	cr=^M, cud1=^J, bel=^G, am, cub1=^H, el=^V$<20>, clear=^X$<40>,
	cols#80, home=^Y$<40>, kcud1=^J, kcub1=^H, kcuf1=^U,
	kcuu1=^Z, lines#24, ll=^P^@W, cuf1=^U, cuu1=^Z,
vc303|vc103|vc203|volker-craig 303,
	cr=^M, cud1=^J, bel=^G, am, cub1=^H, clear=^L$<40>, cols#80,
	home=^K$<40>, kcud1=^J, kcub1=^H, kcuf1=^I, kcuu1=^N, lines#24,
	ll=^O$<1>W, cuf1=^I, cuu1=^N,
# From cbosg!ucbvax!SRC:george Fri Sep 11 22:38:32 1981
ampex|d80|dialogue|dialogue80|ampex dialogue 80,
	tbc=\E3, hts=\E1, cr=^M, cud1=^J, ind=^J, bel=^G,
	is2=\EA, smul=\El, rmul=\Em,
	am, cub1=^H, ht=^I, clear=\E*$<75>, cup=\E=%p1%' '%+%c%p2%' '%+%c,
	il1=\EE$<5*>, cbt=\EI, ich1=\EQ, dl1=\ER$<5*>, dch1=\EW,
	el=\Et, ed=\Ey, smso=\Ej, rmso=\Ek, lines#24, cols#80, cuf1=^L, cuu1=^K,
d132|datagraphix|datagraphix 132a,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	cols#80, lines#30, clear=^l, home=\Et, da, db, ind=\Ev, ri=\Ew,
	cuu1=\Ek, cuf1=\El, cvvis=\Ex, cnorm=\Em\En,
	il1=\E3, ich1=\E5, dch1=\E6, in, ich1=\E5,
soroc|Soroc 120,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	ed=\EY, el=\ET, clear=\E*$<2>,
	kcub1=^H, kcuu1=^K, kcuf1=^L, kcud1=^J, use=adm3a,
# tec is2 untested, and taken from CB/Unix virtual terminal driver.
# Upper case terminal, uses lower case for control sequences!!!
# The driver shows the C ~ operator used on CM coordinates.
tec400|tec scope,
	cr=^M, cud1=^J, ind=^J, bel=^G, cup=l%p2%~%c%p1%~%c,
	cuu1=x, cud1=h, cuf1=g, cub1=w, home=i, smso={, rmso=|,
	xmc#1, clear=f, il1=e, dl1=u, ich1=d, dch1=t, el=c, ed=s,
# From ucbvax!geoff Mon Sep 21 21:15:45 1981 
# This entry has been tested.
tec500|tec 500,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H,
	cup=\E=%p1%' '%+%c%p2%' '%+%c, clear=^Z$<20>,
	cols#80, home=^^, lines#24, cuf1=^L, cuu1=^K, smso=^], rmso=^\,
# I would appreciate more information on this terminal, such as the
# manufacturer and the model number.  There are too many 'tecs' in here.
tec,
	lines#24, cols#80, clear=^l, cuu1=^k, cuf1=\037, am,
	cub1=^H, home=\036, cr=^M, cud1=^J, ind=^J, bel=^G,
teletec|Teletec Datascreen,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	am, cub1=^H, cols#80, clear=^l, home=^^, lines#24, cuf1=^_, cuu1=^k,
aed512|aed|AED 512,
	if=/usr/lib/tabset/aed,
	cr=^M, cud1=^J, bel=^G,
	cols#64, lines#40, clear=^L,
	cub1=^H, cuf1=\Ei0800\001,
	cnorm=\E\072004=000200??\001,
	flash=\EK0001??0000K0001202080\001,
	smso=\E\07200>8000140[80C00\001, rmso=\E[00C80\001,
	smul=\E\07200>8000140\001, rmul=\E\07200>8000100\001,
	uc=\Ei???>l0800i0102\001,
	smcup=\E\07200>8000140{<04<0??00001010L<0\072004=0002??00\001,
	rmcup=\E\07200>8000100{804<0??00001000L80\072004=000200??\001,
	ind=\E;1100\072004=000200??;1300\047\200\001\n\E\072004=0002??00;1200\001\n,
	cuu1=^K, .cup=\E;1300%p1%c%p2%c\001,
digilog|333|digilog 333,
	cub1=^H, cols#80, el=\030, home=^n, lines#16, cuf1=^i, cuu1=^o,
	cr=^M, cud1=^J, ind=^J, bel=^G,
ep48|ep4080|execuport 4080,
	am, cub1=^H, os, cols#80, hu=\036, hd=\034,
	cr=^M, cud1=^J, ind=^J, bel=^G,
ep40|ep4000|execuport 4000,
	am, cub1=^H, os, cols#136, hu=\036, hd=\034,
	cr=^M, cud1=^J, ind=^J, bel=^G,
terminet1200|terminet300|tn1200|tn300|terminet|ge terminet 1200,
	cols#120, hc, os,
	cr=^M, cud1=^J, ind=^J, bel=^G,
datapoint|dp3|dp3360|datapoint 3360,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H,
	ed=^_, el=^^, clear=^]^_, cols#82, home=^], lines#25, cuf1=^x, cuu1=^z,
dg|dg6053|data general 6053,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	am, cub1=^H, cup=^P%p2%c%p1%c, clear=^L, home=^H, cuf1=^S,
	cuu1=^W, el=^K, cols#80, lines#24,
cdi|cdi1203,
	am, cub1=^H, hc, os, cols#80,
	cr=^M$<200>, cud1=^J, ind=^J, bel=^G,
# ^S is an arrow key!  Boy is this guy in for a surprise on v7!
sol,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H, cup=\E^1%p1%c\E^2%p2%c,
	clear=^K, home=^N, cols#64, lines#16, cuf1=^S, cuu1=^W,
	kcub1=^A, kcuf1=^S, kcuu1=^W, kcud1=^Z,
xl83|cybernex XL-83,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H, ed=^P$<62>, el=^O$<3>,
	clear=^L$<62>, cup=^W%p1%' '%+%c%p2%' '%+%c, cols#80, home=^K,
	kcud1=^J, kcub1=^H, kcuu1=^N, lines#24, cuu1=^N, cuf1=^I,
omron|Omron 8025AG,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EL, am, cub1=^H, ed=\ER,
	cols#80, el=\EK, clear=\EJ, da, db, dch1=\EP, dl1=\EM, home=\EH,
	lines#24, cuf1=\EC, rmso=\E4, ind=\ES, smso=\Ef, ri=\ET,
	cuu1=\EA, cnorm=, cvvis=\EN,
plasma|plasma panel,
	am, cub1=^H, clear=^L, cols#85, home=^^, lines#45, cuf1=\030, cuu1=\026,
	cr=^M, cud1=^J, ind=^J, bel=^G,
swtp|ct82|Southwest Technical Products CT82,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H, il1=^\^y,
	ed=^v, el=^F, clear=^L, cup=^k%p2%c%p1%c, cols#82, lines#20, dl1=^z,
	cuf1=^s, cuu1=^a, smso=^^^v, rmso=^^^F, dch1=^\^h, ich1=^\^x, home=^p,
	ind=^n, ri=^o, ll=^c,
	is2=^\^r^^^s^^^d^]^w^i^s^^^]^^^o^]^w^r^i,
terak|Terak emulating Datamedia 1520,
	use=dm1520,
remote|virtual remote terminal,
	cols#79, am@, use=virtual,
virtual|CB-UNIX virtual terminal,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#80, lines#24, am, clear=\E\112,
	cub1=^H, cup=\E\107%p2%c%p1%c, cuf1=\E\103, cuu1=\E\101, el=\E\113,
	ed=\E\114, il1=\E\120, dl1=\E\116, ich1=\E\117, lm#0, da, db,
	kcub1=\E\104, kcuf1=\E\103, kcuu1=\E\101, kcud1=\E\102, khome=\E\105,
	smso=\E\141\004, rmso=\E\142\004, smul=\E\141\001, rmul=\E\142\001,
# This is untested.  The cup sequence is hairy enough that it probably
# needs work.  The idea is ctrl(O), dd(row), dd(col), where dd(x)
# is x - 2*(x%16) + '9'
delta|dd5000|delta data 5000,
	cud1=^J, ind=^J, bel=^G, am, cub1=^H, clear=^NR,
	cup=^O%p1%p1%{16}%m%{2}%*%-%'9'%+%c%p2%p2%{16}%m%{2}%*%-%'9'%+%c,
	cols#80, lines#27, home=^NQ, cuf1=^Y, cuu1=^Z, el=^NU, dch1=^NV,
mdl110|cybernex mdl-110,
	cup=^P%p1%' '%+%c%p2%' '%+%c, cols#80, lines#24, am, clear=^X$<70>,
	cub1=^H, cr=^M, cud1=^J, ind=^J, bel=^G, cuf1=^U, cuu1=^Z, home=^Y,
	el=^N@^V$<145>, ed=^NA^W$<145>, il1=^NA^N^]$<65>, dl1=^NA^N^^$<40>,
	ich1=^NA^]$<3.5>, smdc=, rmdc=, dch1=^NA^^$<3.5>, smso=^NF, rmso=^NG,
	ht=\t$<43>, ed=^N@^V$<6>,
zen30|z30|zentec 30,
	cr=^M, cud1=^J, ind=^J, bel=^G, mir, cols#80, lines#24,
	ul, il1=\EE$<1.5*>, cub1=^H, el=\ET$<1.0*>,
	cup=\E=%p1%' '%+%c%p2%' '%+%c, clear=\E*, home=^^, cuf1=^L,
	rmso=\EG0, smso=\EG6, cuu1=^K, smir=\Eq, rmir=\Er,
	am, dch1=\EW, dl1=\ER$<1.5*>, ed=\EY,
# Test version for Falco ts-1. See "arpavax.hickman@ucb" for info
falco|ts1|ts-1|falco ts-1,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#80, lines#24, ht=^I,
	is2=\Eu\E3, il1=\EE, am, el=\ET\EG0^H, cup=\E=%p1%' '%+%c%p2%' '%+%c,
	clear=\E*, ed=\EY, dch1=\EW, cub1=^H, dl1=\ER, rmir=\Er, smir=\Eq,
	home=^^, kf0=^A0\r, kcud1=^J, kcub1=^H, kcuf1=^L, kcuu1=^K, cuf1=^L,
	rmso=\Eg0, smso=\Eg1, cuu1=^K, smul=\Eg1, rmul=\Eg0,
//go.sysin dd *
echo 'x - =data/perkinelmer'
sed 's/^X//' <<'//go.sysin dd *' >=data/perkinelmer
# # --------------------------------
#	@(#)perkinelmer	1.4	5/19/82
#
# perkinelmer: PERKIN ELMER
#
bantam|pe550|perkin elmer 550,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, cols#80, el=\EI$<20>,
	clear=\EK$<20>, cup=\EX%p1%' '%+%c\EY%p2%' '%+%c, home=\EH,
	lines#24, ll=\EH\EA, cuf1=\EC, cuu1=\EA, ed=^N@^V$<6>,
fox|perkin elmer 1100,
	tbc=\E3, hts=\E1, cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H,
	ed=\EJ$<5.5*>, el=\EI, clear=\EH\EJ$<132>, cols#80, home=\EH, lines#24,
	ll=\EH\EA, cuf1=\EC, cup=\EX%p1%' '%+%c\EY%p2%' '%+%c,
	cuu1=\EA, flash=^P^B^P^C,
owl|perkin elmer 1200,
	tbc=\E3, hts=\E1, cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EL$<5.5*>,
	am, cub1=^H, ed=\EJ$<5.5*>, el=\EI$<5.5>, clear=\EH\EJ$<132>, home=\EH,
	ll=\EH\EA, cup=\EX%p1%' '%+%c\EY%p2%' '%+%c, cols#80, dch1=\EO$<5.5*>,
	dl1=\EM$<5.5*>, ich1=\EN, ip=$<5.5*>, kbs=^h, in, lines#24,
	cuf1=\EC, cuu1=\EA, rmso=\E!\200, smso=\E!^H, flash=^P^B^P^C,
	kf1=\ERA, kf2=\ERB, kf3=\ERC, kf4=\ERD, kf5=\ERE, kf6=\ERF,
	kf7=\ERG, kf8=\ERH, kf9=\ERI, kf0=\ERJ,
//go.sysin dd *
echo 'x - =data/print'
sed 's/^X//' <<'//go.sysin dd *' >=data/print
# # --------------------------------
#	@(#)print	1.1 print 5/19/82
#
# print: PRINTERS
#
# Generic line printer.  We assume it can backspace, since even those
# line printers that can't have this hidden by UNIX lpr driver.
lpr|lp|printer|print|printing|line printer,
	cr=^M, cud1=^J, ff=^L, bel=^G, cub1=^H, cols#132, hc, os,
citoh|ci8510|8510|c.itoh 8510a,
	cols#80, ri=\Er, bold=\E!, smul=\EX, rmul=\EY, sgr0=\E"\EY, 
	is2=\E(009\054017\054025\054033\054041\054049\054057\054065\054073.,
	rep=\ER%p2%3d%p1%c, use=lpr,
//go.sysin dd *
echo 'x - =data/special'
sed 's/^X//' <<'//go.sysin dd *' >=data/special
# # --------------------------------
#	@(#)special	1.5	5/19/82
#
# special: SPECIALS
#
# Generic "terminals".  These are used to label tty lines when you don't
# know what kind of terminal is on it.  The characteristics of an unknown
# terminal are the lowest common denominator - they look about like a ti 700.
arpanet|network,
	use=unknown,
bussiplexer,
	use=unknown,
dialup,
	use=unknown,
ethernet|network,
	use=unknown,
plugboard|patch|patchboard,
	use=unknown,
dumb,
	am, bel=^G, cols#80, cr=^M, cud1=^J, ind=^J,
unknown,
	gn, use=dumb,
switch|intelligent switch,
	use=unknown,
//go.sysin dd *
echo 'x - =data/tektronix'
sed 's/^X//' <<'//go.sysin dd *' >=data/tektronix
# # --------------------------------
#	@(#)tektronix	1.5	5/20/82
#
# tektronix: TEKTRONIX
#
tek|tek4012|4012|tektronix 4012,
	cr=^M, cud1=^J, bel=^G, ff=^L$<1000>,
	is2=\E^O, cub1=^H, clear=\E^L$<1000>, cols#75, lines#35, os,
tek4013|4013|tektronix 4013,
	rmacs=\E^N, smacs=\E^O, use=4012,
tek4014|4014|tektronix 4014,
	is2=\E^O\E9, cols#81, lines#38, use=tek4012,
tek4015|4015|tektronix 4015,
	rmacs=\E^N, smacs=\E^O, use=4014,
tek4014-sm|4014-sm|tektronix 4014 in small font,
	is2=\E^O\E\072, cols#121, lines#58, use=tek4014,
tek4015-sm|4015-sm|tektronix 4015 in small font,
	rmacs=\E^N, smacs=\E^O, use=4014-sm,
tek4023|4023|tex|tektronix 4023,
	cr=^M, cud1=^J, ind=^J, bel=^G, smso=^_P, rmso=^_@,
	cup=\034%p2%' '%+%c%p1%' '%+%c, cuf1=\t, cub1=^H,
	clear=\E^L$<4>, cols#80, lines#24, am, vt#4,
# Can't use cursor motion because it's memory relative, and because
# it only works in the workspace, not the monitor.  Same for home.
# Likewise, standout only works in the workspace.
# el was commented out since vi and rogue seem to work better simulating
# it with lots of spaces!
4025|4027|4024|tek4025|tek4027|tek4024|4025cu|4027cu|tektronix 4024/4025/4027,
	cr=^M, ind=^F^J, cud1=^F^J, bel=^G, am, da, db, ht=^I, 
	cub1=^H, lm#0, lines#34, cols#80, clear=^_era\r\n\n,
	is2=\41com 31\r\n^_sto 9 17 25 33 41 49 57 65 73\r,
	smkx=^_lea p4 /h/\r^_lea p8 /k/\r^_lea p6 / /\r^_lea p2 /j/\r^_lea f5 /H/\r,
	rmkx=^_lea p2\r^_lea p4\r^_lea p6\r^_lea p8\r^_lea f5\r,
	cuu1=^K, cuf1=^_rig\r, il1=^_up\r^_ili\r$<145>, dl1=^_dli\r^F,
	dch1=^_dch\r, smir=^_ich\r, rmir=^F^_dow\r^K,
	.el=^_dch 80\r, ed=^_dli 50\r, CC=^_,
	il=^_up\r^_ili %p1%d\r$<145>, dl1=^_dli %p1%d\r^F,
	cuu=^_up %p1%d\r, cud=^_dow %p1%d\r, cub=^_lef %p1%d\r, cuf=^_rig %p1%d\r,
4025-17|4027-17|tek 4025 17 line window,
	lines#17, use=4025,
4025-17ws|4027-17ws|tek 4025 17 line window in workspace,
	is2=\41com 31\r\n^_sto 9 17 25 33 41 49 57 65 73\r^_wor 17\r^_mon 17\r,
	smcup=^_wor h\r, rmcup=^_mon h\r, smso=^_att e\r, rmso=^_att s\r, use=4025-17,
4025ex|4027ex|tek 4025 w/!,
	smcup=\41com 31\r, rmcup=^_com 33\r,
	is2=^_com 33\r\n\41sto 9 17 25 33 41 49 57 65 73\r, use=4025,
# The 4110 series may be a wonderful graphics series, but they make the 4025
# look good for screen editing.  In the dialog area, you can't move the cursor
# off the bottom line.  Out of the dialog area, ^K moves it up, but there
# is no way to scroll.  Note that there is a floppy for free from Tek that
# makes the 4112 emulate the vt52 (use the vt52 termcap).  There is also
# an expected enhancement that will use ANSI standard sequences.
4112|4113|4114|tek4112|tektronix 4110 series,
	cub1=^H, cr=^M, cud1=^J, bel=^G, am,
	clear=\ELZ, lines#34, cols#80,
# 4112 in non-dialog area pretending to scroll.  It really wraps but vi is
# said to work (more or less) in this mode.
4112-fs,
	ind=^J, ri=^K,
4112-nd|4112 not in dialog area,
	cuu1=^K, use=4112,
4112-5|4112 in 5 line dialog area,
	lines#5, use=4112,
//go.sysin dd *
echo 'x - =data/teleray'
sed 's/^X//' <<'//go.sysin dd *' >=data/teleray
# # --------------------------------
#	@(#)teleray	1.4	5/19/82
#
# teleray: TELERAY
#
# Note two things called "teleray".  Reorder should move the common one
# to the front if you have either.  A dumb teleray with the cursor stuck
# on the bottom and no obvious model number is probably a 3700.
t3700|teleray|dumb teleray 3700,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, clear=^L, cols#80, lines#24,
t3800|teleray 3800 series,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, ed=\EJ, el=\EK, clear=^L,
	cup=\EY%p1%' '%+%c%p2%' '%+%c, cols#80,  
	cud1=\n, home=\EH, lines#24, ll=\EY7 , cuf1=\EC, ht=^I, cuu1=^K,
t1061|t10|teleray 1061,
	tbc=\EG, hts=\EF, cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EL$<2*>,
	am, cub1=^H, ed=\EJ$<1>, el=\EK, clear=^L$<1>,
	cup=\EY%p1%' '%+%c%p2%' '%+%c, cols#80,
	dch1=\EQ, dl1=\EM$<2*>, home=\EH, ich1=\EP, ip=$<0.4*>,
	kf1=^Z1, kf2=^Z2, kf3=^Z3, kf4=^Z4, kf5=^Z5, kf6=^Z6, kf7=^Z7, kf8=^Z8,
	lines#24, cuf1=\EC, ht=^I, rmso=\ER@, smso= \ERD, km,
	is2=\Ee\EU01^Z1\EV\EU02^Z2\EV\EU03^Z3\EV\EU04^Z4\EV\EU05^Z5\EV\EU06^Z6\EV\EU07^Z7\EV\EU08^Z8\EV\Ef,
	cuu1=\EA, smul=\ERH, rmul=\ER@, xhp, xt, xmc#1,
t1061f|teleray 1061 with fast PROMs,
	il1=\EL, ip@, dl1=\EM, use=t1061,
//go.sysin dd *
echo 'x - =data/teletype'
sed 's/^X//' <<'//go.sysin dd *' >=data/teletype
# # --------------------------------
#	@(#)teletype	1.7	5/19/82
#
# teletype: TELETYPE
#
# This works on the default blit, except that output is by exclusive or,
# and insert line leaves 1/2 line at the bottom of the screen.
blit|jerq,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#88, lines#72, ht=^I,
	am, ul, eo, mir, il=\Ef%p1%' '%+%c, dl=\Ee%p1%' '%+%c,
	dl1=\EE, rmir=\ER, smir=\EQ, dch1=\EO, cub1=\ED, da, db,
	il1=\EF, ed=\EJ, el=\EK, clear=^L, cup=\EY%p2%' '%+%c%p1%' '%+%c,
	cuf1=\EC, cuu1=\EA, kcuu1=\EA, kcud1=\EB, kcuf1=\EC, kcub1=\ED,
	flash=\E^G, smso=\EU!, rmso=\EV!, smul=\EU", rmul=\EV",
blitlayer|layer|vitty,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#80, lines#24, ht=^I,
	am, clear=^L, cup=\EY%p2%' '%+%c%p1%' '%+%c, el=\EK, il=\EI, dl=\ED,
33|tty33|tty|model 33 teletype,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#72, hc, os,
# The Dataspeed 40's have lots of braindamage, such as xmc (?) and printing
# a visible newline indicator after each newline.  The 40-1 is a half duplex
# terminal and is hopeless.  The 40-2 is braindamaged but has hope and is
# described here.  The 40-4 is a 3270 lookalike and beyond hope.
# The terminal has blinking standout.  It also has visible bell but I don't
# know it - it's null here to prevent it from showing the BL character.
# I am not sure if the 40 has xmc or not, it looked like it didn't.
# Note also that the control characters have been randomly rearranged,
# for example, to get escape you type control-P!
40|tty40|ds40|ds40-2|dataspeed40|teletype dataspeed 40/2,
	clear=\ER$<160>, ed=\EJ$<160>, il1=\EL$<160>, dl1=\EM$<160>,
	dch1=\EP$<50>, ich1=\E\^$<50>, cuf1=\EC, cuu1=\E7, cub1=^H, cr=\EG,
	ind=^J, cud1=\EB, cols#80, lines#24, flash=, smso=\E3, rmso=\E4,
43|tty43|model 43 teletype,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	kbs=^h, am, cub1=^H, hc, os, cols#132,
37|tty37|model 37 teletype,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	cub1=^H, hc, hu=\E8, hd=\E9, cuu1=\E7, os,
# From jwb Wed Mar 31 13:25:09 1982 remote from ihuxp
# This description seems to avoid line 1 - I don't know why.
# It looks a lot like a vt100 with ins/del line/char.
# But the insert char is not ANSI standard!
4424|tty4424|teletype 4424m,
	il1=\EL, da, db, ip=$<2>, ich1=\E^, dch1=\EP, dl1=\EM,
	cols#80, lines#23, am, clear=\E[2;H\E[J, cub1=^H,
	cup=\E[%i%p1%2d;%p2%2dH\E[B,
	cuf1=\E[C, cuu1=\E[A, mir, ri=\ET,
	el=\E[K, smso=\E[7m, rmso=\E[m, smul=\E[4m, rmul=\E[m,
	is2=\E[m\E[2;24r,
	kcud1=\E[B, kcub1=\E[D, kcuu1=\E[A, kcuf1=\E[C,
	khome=\E[H, kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS,
//go.sysin dd *
echo 'x - =data/televideo'
sed 's/^X//' <<'//go.sysin dd *' >=data/televideo
# # --------------------------------
#	@(#)televideo	1.4	5/19/82
#
# televideo: TELEVIDEO
#
# There are some tvi's that require incredible amounts of padding and
# some that don't.  I'm assuming 912 and 920 are the old slow ones,
# and 912b, 912c, 920b, 920c are the new ones that don't need padding.
tvi912|912|920|tvi920|old televideo,
	tbc=\E3, hts=\E1, cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EE$<33*>, am,
	cub1=^H, el=\ET, cup=\E=%p1%' '%+%c%p2%' '%+%c, clear=^Z,
	cols#80, dch1=\EW, dl1=\ER$<33*>,
	kbs=^h, kcuu1=^K, kcud1=^J, kcub1=^H, kcuf1=^L,
	kf0=^A@\r, kf1=^AA\r, kf2=^AB\r, kf3=^AC\r, kf4=^AD\r,
	kf5=^AE\r, kf6=^AF\r, kf7=^AG\r, kf8=^AH\r, kf9=^AI\r,
	home=^^, ich1=\EQ, lines#24, cuf1=^L, ht=^I, 
	rmso=\Ek, smso=\Ej, cuu1=^K, smul=\El, rmul=\Em, xmc#1,
# the 912 has a <funct> key that's like shift: <funct>8 xmits "^A8\r".
# The 920 has this plus real function keys that xmit different things.
# Terminfo makes you use the funct key on the 912 but the real keys on the 920.
912b|912c|tvi912b|tvi912c|tvi|new televideo 912,
	il1=\EE$<5*>, dl1=\ER$<5*>, use=tvi912,
920b|920c|tvi920b|tvi920c|new televideo 920,
	kf0=^A@\r, kf1=^AA\r, kf2=^AB\r, kf3=^AC\r, kf4=^AD\r, kf5=^AE\r,
	kf6=^AF\r, kf7=^AG\r, kf8=^AH\r, kf9=^AI\r, use=tvi912b,
# Two page TVI 912/920.
# set to page 1 when entering ex (\E-17 )
# reset to page 0 when exiting ex (\E-07 )
tvi912-2p|tvi920-2p|912-2p|920-2p|tvi-2p|televideo w/2 pages,
	smcup=\E-17 , rmcup=\E-07 , use=tvi912,
tvi950-ap|tvi 950 w/alt pages,
	is2=\E\\1, smcup=\E-06 , rmcup=\E-16 , use=tvi950,
tvi950-b|bare tvi950 no is2,
	is2@, smkx=\El, rmkx=\Ek, use=tvi950,
tvi950-ns|tvi950 w/no standout,
	smso@, rmso@, smul@, rmul@, use=tvi950,
# The following tvi descriptions from B:pjphar
# Now that we have is1, is2, and is3, these should be factored.
#
# is2 for all 950's.  It sets the following attributes:
# full duplex (\EDF)		write protect off (\E()
# conversation mode (\EC)	graphics mode off (\E%)
# white on black (\Ed)		auto page flip off (\Ew)
# turn off status line (\Eg)	clear status line (\Ef\r)
# normal video (\E0)		monitor mode off (\EX or \Eu)
# edit mode (\Er)		load blank char to space (\Ee\040)
# line edit mode (\EO)		enable buffer control (^O)
# protect mode off (\E\047)	local edit keys (\Ek)
# program unshifted send key to send line all (\E016)
# program shifted send key to send line unprotected (\E004)
# set the following to nulls:
#	field delimiter (\Ex0\0\0)
#	line delimiter (\Ex1\0\0)
#	start-protected field delimiter (\Ex2\0\0)
#	end-protected field delimiter (\Ex3\0\0)
# set end of text delimiter to carriage return/null (\Ex4\r\0)
#
# tvi950 sets duplex (send) edit keys (\El) when entering vi
#        sets local (no send) edit keys (\Ek) when exiting vi
#
tvi950|950|televideo950,
	tbc=\E3, hts=\E1, cr=^M, cud1=^J, ind=^J, bel=^G,
	is2=\EDF\EC\Ed\EG0\Eg\Er\EO\E\047\E(\E%\Ew\EX\Ee ^O
	\Ek\E016\E004\Ex0\0\0\Ex1\0\0\Ex2\0\0
	\Ex3\0\0\Ex4\r\0\Ef\r\El,
	il1=\EE, am, cub1=^H, cbt=\EI, ed=\Ey, el=\Et, clear=\E*,
	cup=\E=%p1%' '%+%c%p2%' '%+%c, cols#80, dch1=\EW, dl1=\ER,
	cud1=^V, rmir=\Er, home=^^, smir=\Eq, kf0=^A0\r,
	kf1=^A@\r, kf2=^AA\r, kf3=^AB\r, kf4=^AC\r, kf5=^AD\r, kf6=^AE\r,
	kf7=^AF\r, kf8=^AG\r, kf9=^AH\r, kbs=^H, kcud1=^V, khome=^^, kcub1=^H,
	kcuf1=^L, kcuu1=^K, lines#24, mir, msgr, cuf1=^L,
	ht=^I, rmso=\EG0, xmc#1, smso=\EG4, ri=\Ej,
	rmul=\EG0, cuu1=^K, smul=\EG8,
	flash=\Eb$<20>\Ed, cnorm=\Ek, cvvis=\El, xenl,
	hs, tsl=\Eg\Ef, fsl=\r,
#
# is2 for 950 with two pages adds the following:
#	set 48 line page (\E\\2)
#	place cursor at page 0, line 24, column 1 (\E-07 )
#
# two page 950 adds the following:
#	when entering ex, set 24 line page (\E\\1)
#	when exiting ex, reset 48 line page (\E\\2)
#			 place cursor at 0,24,1 (\E-07 )
#
tvi950-2p|950-2p|televideo950 w/2 pages,
	is2=\EDF\EC\Ed\EG0\Eg\Er\EO\E\047\E(\E%\Ew\EX\Ee ^O
	\Ek\E016\E004\Ex0\0\0\Ex1\0\0\Ex2\0\0
	\Ex3\0\0\Ex4\r\0\E\\2\E-07 
	rmcup=\E\\2\E-07 , smcup=\E\\1\E-07 , use=tvi950,
#
# is2 for 950 with four pages adds the following:
#	set 96 line page (\E\\3)
#	place cursor at page 0, line 24, column 1 (\E-07 )
#
# four page 950 adds the following:
#	when entering ex, set 24 line page (\E\\1)
#	when exiting ex, reset 96 line page (\E\\3)
#			 place cursor at 0,24,1 (\E-07 )
#
tvi950-4p|950-4p|televideo950 w/4 pages,
	is2=\EDF\EC\Ed\EG0\Eg\Er\EO\E\047\E(\E%\Ew\EX\Ee ^O
	\Ek\E016\E004\Ex0\0\0\Ex1\0\0\Ex2\0\0
	\Ex3\0\0\Ex4\r\0\E\\3\E-07 
	rmcup=\E\\3\E-07 , smcup=\E\\1\E-07 , use=tvi950,
#
# is2 for reverse video 950 changes the following:
#	set reverse video (\Ed)
#
# set flash accordingly (\Eb ...nulls... \Ed)
#
tvi950-rv|950-rv|televideo950 rev video,
	tbc=\E3, hts=\E1,
	is2=\EDF\EC\Eb\EG0\Eg\Er\EO\E\047\E(\E%\Ew\EX\Ee ^O
	\Ek\E016\E004\Ex0\0\0\Ex1\0\0\Ex2\0\0
	\Ex3\0\0\Ex4\r\0, flash=\Ed$<20>\Eb, use=tvi950,
#
# uses the appropriate entries from 9502p and 950rv
#
tvi950-rv2p|950-rv2p|televideo950 rev video w/2 pages,
	is2=\EDF\EC\Eb\EG0\Eg\Er\EO\E\047\E(\E%\Ew\EX\Ee ^O
	\Ek\E016\E004\Ex0\0\0\Ex1\0\0\Ex2\0\0
	\Ex3\0\0\Ex4\r\0\E\\2\E-07 
	rmcup=\E\\2\E-07 , smcup=\E\\1\E-07 , use=tvi950rv,
#
# uses the appropriate entries from 9504p and 950rv
#
tvi950-rv4p|950-rv4p|televideo950 rev video w/4 pages,
	is2=\EDF\EC\Eb\EG0\Er\EO\E\047\E(\E%\Ew\EX\Ee ^O
	\Ek\E016\E004\Ex0\0\0\Ex1\0\0\Ex2\0\0
	\Ex3\0\0\Ex4\r\0\E\\3\E-07 
	rmcup=\E\\3\E-07 , smcup=\E\\1\E-07 , use=tvi950rv,
//go.sysin dd *
echo 'x - =data/ti'
sed 's/^X//' <<'//go.sysin dd *' >=data/ti
# # --------------------------------
#	@(#)ti	1.4	5/20/82
#
# ti: TEXAS INSTRUMENTS
#
ti700|ti733|735|ti735|ti silent 700,
	cr=^M$<162>, use=ti745,
ti|ti745|745|743|ti silent 745,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, cols#80, hc, os,
ti800|ti omni 800,
	cols#132, use=ti745,
//go.sysin dd *
echo 'x - =data/trailer'
sed 's/^X//' <<'//go.sysin dd *' >=data/trailer
# # ------------------------
#
# The following have been included for upward compatibility with previous
# names.  They are considered obsolete and the new name (which typically
# contains an extra dash) should be used instead.  These names will go
# away eventually (read: "soon") so you should start converting!
#
aaa20, use=aaa-20,
aaa20rev, use=aaa-20-rv,
aaa30, use=aaa-30,
aaa30rev, use=aaa-30-rv,
aaa40, use=aaa-40,
aaa40rev, use=aaa-40-rv,
aaa48, use=aaa-48,
aaa48rev, use=aaa-48-rv,
aaarev, use=aaa-48-rv,
aaa60, use=aaa-60,
aaa60rev, use=aaa-60-rv,
vt100-np, use=vt100,
aaa-29-np, use=aaa-29,
hp2621nl|2621nl, use=2621-nl,
hp2621nt|2621nt, use=2621-nt,
hp2621wl|2621wl, use=2621-wl,
9122p, use=912-2p,
9202p, use=920-2p,
9502p, use=950-2p,
9504p, use=950-4p,
950rv, use=950-rv,
950rv2p, use=950-rv2p,
950rv4p, use=950-rv4p,
aaadb, use=aaa-db,
c1004p, use=c100-4p,
c100rv, use=c100-rv,
c100rv4p, use=c100-rv4p,
c100rv4pna, use=c100-rv4pna,
c100rv4ppp, use=c100-rv4ppp,
c100rvna, use=c100-rvna,
c100rvpp, use=c100-rvpp,
c100rvs, use=c100-rvs,
c100s, use=c100-s,
c108-4, use=c108-4p,
c108-8, use=c108-8p,
c100-s|concept-s|concept100-s, use=c100,
c100-rvs|concept-rvs|concept100-rvs, use=c100-rv,
h19a|h19A, use=h19-a,
h19b, use=h19-b,
h19bs, use=h19-bs,
h19u, use=h19-u,
mime2as, use=mime2a-s,
mime2av, use=mime2a-v,
mimefb, use=mime-fb,
mimehb, use=mime-hb,
tvi2p, use=tvi-2p,
tvi9122p, use=tvi912-2p,
tvi9202p, use=tvi920-2p,
tvi9502p, use=tvi950-2p,
tvi9504p, use=tvi950-4p,
tvi950b, use=tvi950-b,
tvi950ns, use=tvi950-ns,
tvi950rv, use=tvi950-rv,
tvi950rv2p, use=tvi950-rv2p,
tvi950rv4p, use=tvi950-rv4p,
vt100am, use=vt100-am,
vt100nam, use=vt100-nam,
vt100s, use=vt100-s,
vt100w, use=vt100-w,
#
# END OF TERMINFO
#  ------------------------
//go.sysin dd *
echo 'x - =data/visual'
sed 's/^X//' <<'//go.sysin dd *' >=data/visual
# # --------------------------------
#	@(#)visual	1.4	5/20/82
#
# visual: VISUAL
#
# The Visual 200 beeps when you type a character in insert mode.
# This is a horribly obnoxious misfeature, and some of the entries
# below try to get around the problem by ignoring the feature or
# turning it off when inputting a character.  They are said not to
# work well at 300 baud.  (You could always cut the wire to the bell!)
vi200|visual 200 with function keys,
	cr=^M, cud1=^J, ind=^J, bel=^G, lines#24, cols#80,
	il1=\EL, am, cub1=^H, ed=\Ey, el=\Ex$<4*>, clear=\Ev,
	cup=\EY%p1%' '%+%c%p2%' '%+%c, dch1=\EO$<4*>, dl1=\EM$<4*>,
	home=\EH, ich1=\Ei \b\Ej, is2=\E3\Eb\Ej\E\\\El\EG\Ed\Ek,
	kf0=\EP, kf1=\EQ, kf2=\ER, kf3=\E , kf4=\E!, kf5=\E", kf6=\E#,
	kf7=\E$, kf8=\E%, kf9=\E&,
	kcub1=\ED, kcuf1=\EC, kcuu1=\EA, kcud1=\EB, khome=\EH,
	cuf1=\EC, ht=^I, ri=\EI, cuu1=\EA, cvvis=\Ed, cnorm=\Ec,
vi200-rv-ic|visual 200 reverse video using insert char,
	rmir=\Ej, smir=\Ei, ich1@, use=vi200-rv,
# The older Visuals didn't come with function keys. This entry uses
# smkx and rmkx so that the keypad keys can be used as function keys.
# If your version of vi doesn't support function keys you may want
# to use vi200-f.
vi200-f|visual|visual 200 no function keys,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#80, lines#24,
	il1=\EL, am, cub1=^H, ed=\Ey, el=\Ex$<4*>, clear=\Ev,
	cup=\EY%p1%' '%+%c%p2%' '%+%c, dch1=\EO$<4*>, dl1=\EM$<4*>,
	home=\EH, ich1=\Ei \b\Ej, is2=\E3\Eb\Ej\E\\\El\EG\Ed\Ek,
	smkx=\E=, rmkx=\E>,
	kf0=\E?p, kf1=\E?q, kf2=\E?r, kf3=\E?s, kf4=\E?t, kf5=\E?u, kf6=\E?v,
	kf7=\E?w, kf8=\E?x, kf9=\E?y,
	kcub1=\ED, kcuf1=\EC, kcuu1=\EA, kcud1=\EB, khome=\EH,
	cuf1=\EC, ht=^I, ri=\EI, cuu1=\EA, cvvis=\Ed, cnorm=\Ec,
vi200-rv|visual 200 reverse video,
	smso=\E4, rmso=\E3, ri@, cvvis@, cnorm@, use=vi200,
vi200-ic|visual 200 using insert char,
	rmir=\Ej, smir=\Ei, ich1@, use=vi200,
//go.sysin dd *
exit

sources@genrad.UUCP (12/21/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit".  This code is completely public domain, originally written by Pavel
Curtis of Cornell University.  This version has some small improvements and
bug fixes.

This unit contains:
	the last of the terminal data files

Part 11 will be
	a demo program that uses the new curses

----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
if test ! -d =data
then
    echo 'Making directory "=data"'
    mkdir =data
fi
echo 'x - =data/Makefile'
sed 's/^X//' <<'//go.sysin dd *' >=data/Makefile
PARTS= header adds annarbor beehive cdc concept datamedia dec diablo general \
	hazeltine heath homebrew hp ibm lsi microterm misc perkinelmer \
	print special tektronix teleray teletype televideo ti visual trailer

compiled: source
	time compile source

source: ${PARTS}
	cat ${PARTS} > source
	-rm -f /etc/terminfo
	ln source /etc/terminfo

clean:
	rm -r ? source

changes:
	vi ${PARTS}
//go.sysin dd *
echo 'x - =data/adds'
sed 's/^X//' <<'//go.sysin dd *' >=data/adds
# # --------------------------------
#	@(#)adds	1.3	3/22/82
#
# adds: ADDS
#
# Regent: lowest common denominator, works on all regents.
regent|adds regent series,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H, clear=^L,
	cup=^K%p1%' '%+%c^P%p1%{10}%/%{16}%*%p1%{10}%m%+%c,
	cols#80, home=^A, lines#24, ll=^A^Z, cuf1=^F, cuu1=^Z,
# Regent 100 has a bug where if computer sends escape when user is holding
# down shift key it gets confused, so we avoid escape.
regent100|adds regent 100,
	cup=^K%p1%' '%+%c^P%p1%{10}%/%{16}%*%p1%{10}%m%+%c,
	kf1=^B1\r, kf2=^B2\r, kf3=^B3\r, kf4=^B4\r,
	kf5=^B5\r, kf6=^B6\r, kf7=^B7\r, kf8=^B8\r,
	khome=^A, kcub1=^U, kcuf1=^F, kcuu1=^Z, kcud1=^J, use=regent,
# Regent 20, untested
regent20|adds regent 20,
	ed=\Ek, el=\EK, cup=\EY%p1%' '%+%c%p2%' '%+%c, use=regent,
regent25|adds regent 25,
	kf0=^B0\r, kf1=^B1\r, kf2=^B2\r, kf3=^B3\r, kf4=^B4\r,
	kf5=^B5\r, kf6=^B6\r, kf7=^B7\r, kf8=^B8\r, kf9=^B9\r,
	khome=^A, kcub1=^U, kcuf1=^F, kcuu1=^Z, kcud1=^J, use=regent20,
# Regent 40: untested
regent40|adds regent 40,
	il1=\EM, dl1=\El, is2=\EB, rmso=\E0@, smso=\E0P,
	rmul=\E0@, smul=\E0`, flash=\ED\Ed, use=regent25,
# If you have standout problem with regent 200, try smso=\ER\EOP,rmso=\E0@\EV,
regent60|regent200|adds Regent 60,
	dch1=\EE, rmir=\EF, smir=\EF, is2=\EV\EB, use=regent40,
regent60na|regent 60 w/no arrow keys,
	kcub1@, kcuf1@, kcuu1@, kcud1@, use=regent60,
# Note: if return acts weird on a980, check internal switch #2
# on the top chip on the CONTROL pad board.
a980|adds consul 980,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=\E^N$<13>, am, cub1=^H,
	clear=^L$<1>^K@, cup=^K%p1%'@'%+%c\E^E%p1%2d, cols#80, dl1=\E^O$<13>,
	kf0=\E0, kf1=\E1, kf2=\E2, kf3=\E3, kf4=\E4,
	kf5=\E5, kf6=\E6, kf7=\E7, kf8=\E8, kf9=\E9,
	lines#24, cuf1=\E^E01, smso=^Y^^^N, rmso=^O, cuu1=$<9>,
# From Onyx:edward  Thu Jul  9 09:27:33 1981
viewpoint|addsviewpoint|adds viewpoint,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H, lines#24, cols#80,
	cup=\EY%p1%' '%+%c%p2%' '%+%c, ed=\Ek, el=\EK, cuf1=^F,
	cuu1=^Z, clear=^L, ll=^A, kcub1=^U, kcuf1=^F, kcud1=^J, kcuu1=^Z, khome=^A,
	smso=^N, rmso=^O, smul=^N, rmul=^O, is2=^O\E0`, cvvis=^O\E0P, cnorm=^O\E0`,
//go.sysin dd *
echo 'x - =data/annarbor'
sed 's/^X//' <<'//go.sysin dd *' >=data/annarbor
# # --------------------------------
#	@(#)annarbor	1.8	5/19/82
#
# annarbor: ANN ARBOR
#
aa|annarbor|4080|ann arbor 4080,
	cr=^M, cud1=^J, ind=^J, bel=^G, tbc=^\^P^P, hts=^]^P1,
	cup=^O%p2%{10}%/%{16}%*%p2%{10}%m%+%c%p1%?%p1%{19}%>%t%{12}%+%;%'@'%+%c,
	cols#80, lines#40, cub1=^H, clear=^L$<2>, cuu1=^N, cuf1=^_,
	home=^K, am, kbs=^^, kcud1=^J, kcuu1=^N, kcub1=^H, kcuf1=^_, khome=^K,
# From cbosg!chico!randvax!day Aug 1981
# alias aaa 'setenv TERM aaa-\!^; tset -e^H -Q; alias clr echo "^[\[2J^[\[H"'
# Be sure to change ^[ to escape in above alias.  Needs function keys added.
# The ann arbor ambassador entries are merged from Mike O'Brien@Rand
# and Howard Katseff at Bell Labs, and are not thoroughly tested.
# Highly modified 6/22 by Mike O'Brien.
# split out into several for the various screen sizes by dave-yost@rand
# Many changes by Mark Horton 3/82
aaa-unk|ann arbor ambassador (internal - don't use this directly),
	am, km, mir, xon, cols#80, it#8,
	cr=^M, ht=^I, cbt=\E[Z, bel=^G, ind=^J, ri=\EM,
	cuu1=\E[A, cuf1=\E[C, cud1=^J, cub1=^H,
	cuu=\E[%p1%dA, cuf=\E[%p1%dC, cud=\E[%p1%dB, cub=\E[%p1%dD,
	ed=\E[J, el=\E[K$<5>, clear=\E[H\E[J$<156>,
	home=\E[H, cup=\E[%i%p1%d;%p2%dH,
	hpa=\E[%p1%{1}%+%d`, vpa=\E[%p1%{1}%+%dd,
	dl=\E[%p1%dM,  dl1=\E[M,  il=\E[%p1%dL$<3*>,  il1=\E[L$<3>,
	dch=\E[%p1%dP, dch1=\E[P, .ich=\E[%p1%d@$<4*>, .ich1=\E[@$<4>,
	smir=\E[>4h, rmir=\E[>4l,
	smul=\E[4m, rmul=\E[m, smso=\E[1m, rmso=\E[m,
	bold=\E[1m, rev=\E[7m, blink=\E[5m, invis=\E[8m, sgr0=\E[0m,
	sgr=\E[%?%p1%t1;%;%?%p2%t4;%;%?%p3%t7;%;%?%p4%t5;%;%?%p6%t1;%;%?%p7%t8;%;m,
	kcuu1=\E[A, kcud1=\E[B, kcub1=\E[D, kcuf1=\E[C, khome=\E[H, kbs=^H,
	kich1=\E[@, krmir=\E6,  kil1=\E[L,  kclr=\E[J,  kdch1=\E[P, kdl1=\E[M,
	kf1=\EOA, kf2=\EOB, kf3=\EOC, kf4=\EOD, kf5=\EOE,
	kf6=\EOF, kf7=\EOG, kf8=\EOH, kf9=\EOI, kf10=\EOJ,
	rep=%p1%c\E[%p2%{1}%-%db,  sc=\E7, rc=\E8,
	flash=\E7\E[H\E[4m\E9$<20>\E[m\E9\E8,
	is1=\E[m\E7\E[H\E9\E8, is3=\E[1Q\E[>20;30l,
	smm=\E[>52h, rmm=\E[>52l,
	.mc0=\E[0i, .mc5=\E[v, .mc4=^C,
aaa-unk-stat|Ann Arbor Ambassadors with status lines,
	tsl=\E[>51h\E[1;%p1%dH\E[2K, fsl=\E[>51l, hs, eslok,
	.dsl=\E7\E[60;0;0;30p\E[60;1H\E[K\E[H\E8,
aaa-unk-rv|Ann Arbor Ambassadors in reverse-video mode,
	bold=\E[1;7m, rev=\E[m, blink=\E[5;7m, invis=\E[7;8m, sgr0=\E[7m,
	rmul=\E[7m, smul=\E[4;7m, rmso=\E[7m, smso=\E[m, rs1=\E[H\E[7m\E[J,
	sgr=\E[%?%p1%!%t7;%;%?%p2%t4;%;%?%p3%t7;%;%?%p4%t5;%;%?%p6%t1;%;%?%p7%t8;%;m,
	flash=\E7\E[H\E[7;4m\E9$<20>\E[7m\E9\E8,
	is1=\E[7m\E7\E[H\E9\E8,
aaa-18|ann arbor ambassador/18 lines,
	smcup=\E[18;0;0;18p, rmcup=\E[60;0;0;18p\E[60;1H\E[K,
	is2=\E7\E[60;0;0;18p\E8, lines#18, use=aaa-unk,
aaa-18-rv|ann arbor ambassador/18 lines+reverse video,
	 use=aaa-unk-rv, use=aaa-18,
aaa-20|ann arbor ambassador/20 lines,
	smcup=\E[20;0;0;20p, rmcup=\E[60;0;0;20p\E[60;1H\E[K,
	is2=\E7\E[60;0;0;20p\E8, lines#20, use=aaa-unk,
aaa-20-rv|ann arbor ambassador/20 lines+reverse video,
	use=aaa-unk-rv, use=aaa-20,
aaa-22|ann arbor ambassador/22 lines,
	smcup=\E[22;0;0;22p, rmcup=\E[60;0;0;22p\E[60;1H\E[K,
	is2=\E7\E[60;0;0;22p\E8, lines#22, use=aaa-unk,
aaa-22-rv|ann arbor ambassador/22 lines+reverse video,
	use=aaa-unk-rv, use=aaa-22,
aaa-24|ann arbor ambassador/24 lines,
	smcup=\E[24;0;0;24p, rmcup=\E[60;0;0;24p\E[60;1H\E[K,
	is2=\E7\E[60;0;0;24p\E8, lines#24, use=aaa-unk,
aaa-24-rv|ann arbor ambassador/24 lines+reverse video,
	use=aaa-unk-rv, use=aaa-24,
aaa-26|ann arbor ambassador/26 lines,
	smcup=\E[26;0;0;26p, rmcup=\E[60;0;0;26p\E[60;1H\E[K,
	is2=\E7\E[60;0;0;26p\E8, lines#26, use=aaa-unk,
aaa-26-rv|ann arbor ambassador/26 lines+reverse video,
	use=aaa-unk-rv, use=aaa-26,
aaa-28|ann arbor ambassador/28 lines,
	smcup=\E[28;0;0;28p, rmcup=\E[60;0;0;28p\E[60;1H\E[K,
	is2=\E7\E[60;0;0;28p\E8, lines#28, use=aaa-unk,
aaa-28-rv|ann arbor ambassador/28 lines+reverse video,
	use=aaa-unk-rv, use=aaa-28,
aaa-29|ann arbor ambassador/29 lines plus status line,
	smcup=\E[30;1;0;30p,
	rmcup=\E[60;1;0;30p\E[60;1H\E[K,
	is2=\E7\E[H\E[K\E[60;1;0;30p\E8\E[>51h\E[H\E[>51l, lines#29,
	use=aaa-unk-stat, use=aaa-unk,
aaa-29-rv|ann arbor ambassador/29 lines+status line+reverse video,
	use=aaa-unk-rv, use=aaa-29,
aaa-30|ambassador|ann arbor ambassador/30 lines,
	smcup=\E[30;0;0;30p, rmcup=\E[60;0;0;30p\E[60;1H\E[K,
	is2=\E7\E[60;0;0;30p\E8, lines#30, use=aaa-unk,
aaa-30-rv|ann arbor ambassador/30 lines in reverse video,
	use=aaa-unk-rv, use=aaa-30,
aaa-36|ann arbor ambassador/36 lines,
	smcup=\E[36;0;0;36p, rmcup=\E[60;0;0;36p\E[60;1H\E[K,
	is2=\E7\E[60;0;0;36p\E8, lines#36, use=aaa-unk,
aaa-36-rv|ann arbor ambassador/36 lines+reverse video,
	use=aaa-unk-rv, use=aaa-36,
aaa-40|ann arbor ambassador/40 lines,
	smcup=\E[40;0;0;40p, rmcup=\E[60;0;0;40p\E[60;1H\E[K,
	is2=\E7\E[60;0;0;40p\E8, lines#40, use=aaa-unk,
aaa-40-rv|ann arbor ambassador/40 lines+reverse video,
	use=aaa-unk-rv, use=aaa-40,
aaa-47|ann arbor ambassador/48 lines+status line,
	smcup=\E[48;1;0;48p,
	rmcup=\E[60;1;0;48p\E[60;1H\E[K,
	is2=\E7\E[H\E[K\E[60;1;0;48p\E8\E[>51h\E[H\E[>51l, lines#47,
	use=aaa-unk-stat, use=aaa-unk,
aaa-47-rv|ann arbor ambassador/48 lines+status line+reverse video,
	use=aaa-unk-rv, use=aaa-47,
aaa|ambas|aaa-48|ann arbor ambassador/48 lines,
	smcup=\E[48;0;0;48p, rmcup=\E[60;0;0;48p\E[60;1H\E[K,
	is2=\E7\E[60;0;0;48p\E8, lines#48, use=aaa-unk,
aaa-rv|aaa-48-rv|ann arbor ambassador/48 lines+reverse video,
	use=aaa-unk-rv, use=aaa-48,
aaa-59|ann arbor ambassador/59 lines plus status line,
	is2=\E7\E[H\E[K\E[60;1;0;60p\E8\E[>51h\E[H\E[>51l, lines#59,
	use=aaa-unk-stat, use=aaa-unk,
aaa-59-rv|ann arbor ambassador/59 lines+status line+reverse video,
	use=aaa-unk-rv, use=aaa-59,
aaa-60|ann arbor ambassador/60 lines,
	is2=\E7\E[60;0;0;60p\E[1Q\E[m\E[>20;30l\E8, lines#60, use=aaa-unk,
aaa-60-rv|ann arbor ambassador/60 lines+reverse video,
	use=aaa-unk-rv, use=aaa-60,
aaa-db|aaa-30-db|ann arbor ambassador 30 lines/destructive backspace,
	cub1=\E[D, is3=\E[1Q\E[m\E[>20l\E[>30h, use=aaa-30,
//go.sysin dd *
echo 'x - =data/beehive'
sed 's/^X//' <<'//go.sysin dd *' >=data/beehive
# # --------------------------------
#	@(#)beehive	1.5	5/20/82
#
# beehive: BEEHIVE
#
# Reports are that most of these Beehive entries (except superbee) have not been
# tested and do not work right.  rmso is a trouble spot.  Be warned.
# set tab is ^F, clear (one) tab is ^V, no way to clear all tabs.
# Superbee - f1=escape, f2=^C.
# Note: there are at least 3 kinds of superbees in the world.  The sb1
# holds onto escapes and botches ^C's.  The sb2 is the best of the 3.
# The sb3 puts garbage on the bottom of the screen when you scroll with
# the switch in the back set to CRLF instead of AEP.  This description
# is tested on the sb2 but should work on all with either switch setting.
# The f1/f2 business is for the sb1 and the xsb can be taken out for
# the other two if you want to try to hit that tiny escape key.
# This description is tricky: being able to use cup depends on there being
# 2048 bytes of memory and the hairy ind string.
# Now that we have separate ind and cud1, I imagine this could be improved.
sb1|superbee|superb|beehive super bee,
	tbc=\E3, hts=\E1, is2=\EE, cud1=^J,
	cr=^M$<10>, ind=\n$<3>\n$<3>\EA\EK$<3>\ET\ET, bel=^G,
	am, cub1=^H, ed=\EJ$<3>, el=\EK$<3>,
	clear=\EH\EJ$<3>, cols#80, cup=\EF%p2%3d%p1%3d, cr=\r$<1000>,
	lm#25, da, db, xsb, dch1=\EP$<3>, dl1=\EM$<100>,
	smso=\E_1, rmso=\E_0, lines#25,
	cuf1=\EC, ht=^I, cuu1=\EA, home=\EH, cnorm=\n,
	kf1=\Ep, kf2=\Eq, kf3=\Er, kf4=\Es, kf5=\Et, kf6=\Eu, kf7=\Ev, kf8=\Ew,
	kcud1=\EB, khome=\EH, kcub1=\ED, kcuf1=\EC, kcuu1=\EA,
# This loses on lines > 80 chars long, use at your own risk
superbeeic|super bee with insert char,
	ich1=, smir=\EQ, rmir=\ER, use=superbee,
sb2|sb3|fixed superbee,
	xsb@, use=superbee,
# good grief - does this entry make xmc when it doesn't have to?
# look at those spaces in rmso/smso.  Seems strange to me.
# However, not having one to test changes on, I'll just leave it be...
bh3m|beehiveIIIm,
	if=/usr/lib/tabset/beehive,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	il1=^S$<160>, am, cub1=^H, ed=^R, el=^P, clear=^E^R,
	cols#80, dl1=^Q$<350>, home=^E, lines#20, ll=^E^K,
	cuf1=^L, ht=^I, rmso= ^_, smso=^] , cuu1=^K,
microb|microbee|micro bee series,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H,
	ed=\EJ, el=\EK, clear=\EE, cols#80, cup=\EF%p1%' '%+%c%p2%' '%+%c,
	kf1=\Ep, kf2=\Eq, kf3=\Er, kf4=\Es,
	kf5=\Et, kf6=\Eu, kf7=\Ev, kf8=\Ew, kf9=\Ex,
	kcud1=\EB, khome=\EH, kcub1=\ED, kcuf1=\EC, kcuu1=\EA,
	lines#24, cuf1=\EC, ht=^I, cuu1=\EA,
	rmso=\Ed@ , smso= \EdP, rmul=\Ed@, smul=\Ed`,
//go.sysin dd *
echo 'x - =data/cdc'
sed 's/^X//' <<'//go.sysin dd *' >=data/cdc
# # --------------------------------
#	@(#)cdc	1.3	3/22/82
#
# cdc: CONTROL DATA
#
cdc456|cdc,
	cr=^M, cud1=^J, ind=^J, bel=^G, lines#24, cols#80, clear=^Y^X,
	cuf1=^L, cuu1=^Z, cub1=^H, cup=\E1%p1%' '%+%c%p2%' '%+%c, home=^Y,
	il1=\E\114, dl1=\E\112, el=^V, ed=^X, am,
cdc456tst,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	lines#24, cols#80, clear=^y^x, cub1=^H, cup=\E1%p1%' '%+%c%p2%' '%+%c, am,
//go.sysin dd *
echo 'x - =data/concept'
sed 's/^X//' <<'//go.sysin dd *' >=data/concept
# # --------------------------------
#	@(#)concept	1.6	5/20/82
#
# concept: (HUMAN DESIGNED SYSTEMS)
#
# From vax135!hpk  Sat Jun 27 07:41:20 1981
# Extensive changes to c108 by arpavax:eric Feb 1982
#
# There seem to be a number of different versions of the C108 PROMS
# (with bug fixes in its Z-80 program).
# The first one that we had would lock out the keyboard of you
# sent lots of short lines (like /usr/dict/words) at 9600 baud.
# Try that on your C108 and see if it sends a ^S when you type it.
# If so, you have an old version of the PROMs.
# The old one also messed up running in with a 132-character line-length.
# You should configure the C108 to send ^S/^Q before running this.
# It is much faster (at 9600 baud) than the c100 because the delays
# are not fixed.
# Old cursor addressing that didn't understand > 95:
#	cup=\Ea%p1%' '%+%c%p2%' '%+%c,
c108|c108-8p|concept108-8p|concept 108 w/8 pages,
	rmcup=\Ev  ^B p\Ep\r\n, use=c108-4p, 
c108-4p|concept108-4p|concept 108 w/4 pages,
	cr=^M, cud1=^J, ind=^J, bel=^G, 
	is2=\EU\E F\Ef\E7\E5\E8\El\ENH\EK\E\200\Eo&\200\Eo\47\E\E!,
	smcup=\EU\Ev  8p\Ep\r, rmcup=\Ev  ^A p\Ep\r\n,
	il1=\E^R, cub1=^H, ed=\E^C, el=\E^S, clear=\E?\E^E, cols#80,
	cup=\Ea%p1%?%p1%{95}%>%t^A%c%{96}%-%;%' '%+%c%p2%?%p2%{95}%>%t^A%c%{96}%-%;%' '%+%c,
	dch1=\E^A, dl1=\E^B, rmir=\E\200, eo, smir=\E^P, lines#24, mir,
	cuf1=\E=, kbs=^h, ul, cuu1=\E;, db, smul=\EG, rmul=\Eg,
	cvvis=\EW, cnorm=\Ew, in, am, xenl, flash=\Ek$<50>\EK,
	smkx=\EX, rmkx=\Ex, kcuu1=\E;,
	kcud1=\E<, kcub1=\E>, kcuf1=\E=, khome=\E?,
	kf1=\E5, kf2=\E6, kf3=\E7, kf4=\E8, kf5=\E9, kf6=\E:,
	smso=\ED, rmso=\Ed, dim=\EE, bold=\ED, rev=\ED, sgr0=\Ee\Ed\Eg\Ec,
c108-rv-8p|concept 108 w/8 pages in reverse video,
	smcup=\EU\Ev  8p\Ep\r, rmcup=\Ev  ^B p\Ep\r\n, use=c108-rv-4p, 
c108-rv-4p|concept 108 w/4 pages in reverse video,
	flash=\EK\200\200\200\200\200\200\200\200\200\200\200\200\200\200\Ek,
	is2=\EU\E F\Ef\E7\E5\E8\El\ENH\Ek\E\200\Eo&\200\Eo\47\E\E!,
	use=c108-4p, 
c108-na|c108-na-8p|concept 108 w/8 pages no arrows,
	smkx@, rmkx@, kf7=\E;, kf8=\E<, kf9=\E=, use=c108-8p,
c108-rv-na|c108-rv-na-8p|concept 108 w/8 pages no arrows in rev video,
	smkx@, rmkx@, kf7=\E;, kf8=\E<, kf9=\E=, use=c108-rv-8p,
# this needs new frotz in the cup capability for 2-char addrs when > 95....
c108-w|c108-w-8p|concept 108 w/8 pages in wide mode,
	is2=\EU\E F\Ef\E7\E5\E8\El\ENH\EK\E\200\Eo&\200\Eo\47\E\E",
	smcup=\EU\Ev  8^AD\Ep\r, rmcup=\Ev  ^A0^AD\Ep\r\n,
	cup=\Ea%p1%?%p1%{95}%>%t^A%c%{96}%-%;%' '%+%c%p2%?%p2%{95}%>%t^A%c%{96}%-%;%' '%+%c,
	cols#132, use=c108-8p,
# Concepts have only window relative cursor addressing, not screen relative.
# To get it to work right here, smcup/rmcup (which were invented for the
# concept) lock you into a one page window for screen style programs.
# To get out of the one page window, we use a clever trick:
# we set the window size to zero ("\Ev    " in rmcup) which the terminal
# recognizes as an error and resets the window to all of memory.
# This trick works on c100 but does not on c108, sigh.
#
# Some tty drivers use cr3 for concept, others use nl3, hence the delays on
# cr and ind below.  This padding is only needed at 9600 baud.
# One or the other is commented out depending on local conventions.
# 2 nulls padding on rmcup isn't always enough.  6 works fine.  Maybe less
# than 6 but more than 2 will work.
concept100|c100|concept|c104|c100-4p|concept 100,
	is2=\EU\Ef\E7\E5\E8\El\ENH\EK\E\200\Eo&\200\Eo\47\E,
	cr=$<9>^M, ind=^J,
#	cr=^M, ind=^J$<9>,
	bel=^G, cud1=^J, smcup=\EU\Ev  8p\Ep\r, rmcup=\Ev    $<6>\Ep\r\n,
	il1=\E^R$<3*>, am, cub1=^H, ed=\E^C$<16*>, el=\E^U$<16>, clear=^L$<2*>,
	cup=\Ea%p1%' '%+%c%p2%' '%+%c, cols#80, dch1=\E^A$<16*>, dl1=\E^B$<3*>,
	rmir=\E\200, eo, smir=\E^P, in, ip=$<16*>, lines#24, mir, cuf1=\E=,
	ht=\t$<8>, kbs=^h, ul, cuu1=\E;, db, smul=\EG, rmul=\Eg,
	xenl, cvvis=\EW, cnorm=\Ew, flash=\Ek$<20>\EK,
	pb#9600, vt#8,
	smul=\EG, rmul=\Eg, smso=\EE\ED, rmso=\Ed\Ee,
	dim=\EE, rev=\ED, blink=\EC, prot=\EI, invis=\EH, sgr0=\EN\200,
	rep=\Er%p1%c%p2%' '%+%c$<.2*>, smkx=\EX, rmkx=\Ex,
	kcuu1=\E;, kcud1=\E<, kcub1=\E>, kcuf1=\E=, khome=\E?,
	kf1=\E5, kf2=\E6, kf3=\E7,
c100-rvpp|c100-rv4ppp|c100 with printer port,
	is2=\EU\Ef\E7\E5\E8\El\ENH\Ek\E\200\Eo&\200\Eo!\200\EQ"\EY(^W\Eo\47\E,
	use=c100-rv,
c100-rvna|c100-rv4pna|c100 with no arrows,
	smkx@, rmkx@, use=c100-rv,
c100-rv|c100-rv4p|concept100-rv|c100 rev video,
	is2=\EU\Ef\E7\E5\E8\El\ENH\Ek\E\200\Eo&\200\Eo\47\E,
	flash=\EK$<20>\Ek, cvvis@, cnorm@, smso=\EE, rmso=\Ee, use=c100,
//go.sysin dd *
echo 'x - =data/datamedia'
sed 's/^X//' <<'//go.sysin dd *' >=data/datamedia
# # --------------------------------
#	@(#)datamedia	1.4	5/19/82
#
# datamedia: DATAMEDIA
#
dm1520|dm1521|1521|1520|datamedia 1520,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H, ed=^K, el=^], clear=^L,
	cup=^^%p2%' '%+%c%p1%' '%+%c, cols#80, home=^Y,
	kcuu1=^_, kcud1=^J, kcub1=^H, kcuf1=^\, khome=^Y,
	lines#24, cuf1=^\, cuu1=^_, xenl, ht=^I, 
dm2500|datamedia2500|2500|datamedia 2500,
	cud1=^J, ind=^J, bel=^G, il1=^P\n^X^]^X^]$<15>, cub1=^H, el=^W,
	clear=^^^^\177, cup=^L%p2%'`'%^%c%p1%'`'%^%c, cols#80,
	dch1=^P\b^X^]$<10*>,
	dl1=^P^Z^X^]$<10*>, smdc=^P, rmdc=^X^], rmir=\377\377^X^]$<10>, home=^B,
	ich1=^P^\^X^]$<10*>, smir=^P, lines#24, cuf1=^\,
	pad=\377, smso=^N, rmso=^X^], cuu1=^Z,
dm3025|datamedia 3025a,
	is2=\EQ\EU\EV, cr=^M, cud1=^J, ind=^J, bel=^G,
	il1=\EP\n\EQ$<130>, cub1=^H, ed=\EJ$<2>, el=\EK, clear=\EM$<2>,
	cup=\EY%p2%' '%+%c%p1%' '%+%c, cols#80, dch1=\b$<6>,
	dl1=\EP\EA\EQ$<130>, smdc=\EP, rmdc=\EQ, rmir=\EQ, home=\EH,
	smir=\EP, ip=, lines#24, cuf1=\EC, ht=^I, 
	smso=\EOA, rmso=\EO@, cuu1=\EA,
3045|dm3045|datamedia 3045a,
	is2=\EU\EV, cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H,
	ed=\EJ$<2>, el=\EK, clear=\EM$<2>, cup=\EY%p2%' '%+%c%p1%' '%+%c,
	cols#80, dch1=\EB$<6>, smdc=, rmdc=, rmir=\EP, home=\EH,
	ich1=, smir=\EP, ip=$<6>,
	kf0=\Ey\r, kf1=\Ep\r, kf2=\Eq\r, kf3=\Er\r, kf4=\Es\r,
	kf5=\Et\r, kf6=\Eu\r, kf7=\Ev\r, kf8=\Ew\r, kf9=\Ex\r,
	khome=\EH, kcuu1=\EA, kcuf1=\EC, lines#24, cuf1=\EC, pad=\177, ht=^I,
	eo, ul, cuu1=\EA, xenl,
# dt80/1 is2 a vt100 lookalike, but it doesn't seem to need any padding.
dt80|dmdt80|dm80|datamedia dt80/1,
	cr=^M, cud1=^J, ind=^J, bel=^G, ed=\E[J, el=\E[K, clear=\E[2J\E[H,
	cup=\E[%i%p1%d;%p2%dH, home=\E[H, cuf1=\E[C, ri=\EM,
	smso=\E[7m, rmso=\E[m, cuu1=\E[A, smul=\E[4m, rmul=\E[m, use=vt100,
# except in 132 column mode, where it needs a little padding.
# This is2 still less padding than the vt100, and you can always turn on
# the ^S/^Q handshaking, smso you can use vt100 flavors for things like
# reverse video.
dt80-w|dmdt80-w|dm80-w|datamedia dt80/1 in 132 char mode,
	cr=^M, cud1=^J, ind=^J, bel=^G, ed=\E[0J$<20>, cols#132, el=\E[0K$<20>,
	cup=\E[%i%p1%d;%p2%dH$<5>, clear=\E[H\E[2J$<50>, cuu1=\E[A$<5>, use=dmdt80,
//go.sysin dd *
echo 'x - =data/dec'
sed 's/^X//' <<'//go.sysin dd *' >=data/dec
# # --------------------------------
#	@(#)dec	1.7	5/20/82
#
# dec: DEC (DIGITAL EQUIPMENT CORPORATION)
#
# Note that xenl glitch in vt100 is not quite the same as concept,
# since the cursor is left in a different position while in the
# weird state (concept at beginning of next line, vt100 at end
# of this line) so all versions of vi before 3.7 don't handle
# xenl right on vt100.
# I assume you have smooth scroll off or are at a slow enough baud
# rate that it doesn't matter (1200? or less).  Also this assumes
# that you set auto-nl to "on", if you set it off use vt100-nam below.
#
# Since there are two things here called vt100, the installer can make
# a local decision to make either one standard "vt100" by including
# it in the list of terminals in reorder, since the first vt100 in
# /etc/terminfo is the one that it will find.  The choice is between
# nam (no automatic margins) and am (automatic margins), as determined
# by the wrapline switch (group 3 #2).  I presonally recommend turning
# on the bit and using vt100-am, since having stuff hammer on the right
# margin is sort of hard to read.  However, the xenl glitch does not occur
# if you turn the bit off.
#
# I am unsure about the padding requirements listed here.  I have heard
# a claim that the vt100 needs no padding.  It's possible that it needs
# padding only if the xon/xoff switch is off.  For UNIX, this switch
# should probably be on.
#
# The vt100 uses rs2 and rf rather than is2/tbc/hts because the tab settings
# are in non-volatile memory and don't need to be reset upon login.
# Also setting the number of columns glitches the screen annoyingly.
# You can type "reset" to get them set.
vt100-mc|vt100 without advanced video option,
	sgr@, smso=\E[7m , rmso=\E[m , xmc#1,
	smul@, rmul@, bold@, rev@, blink@, sgr0@, use=vt100,
vt100|vt100-am|dec vt100,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#80, lines#24,
	clear=\E[;H\E[2J$<50>, cub1=^H, am, cup=\E[%i%p1%d;%p2%dH$<5>,
	cuf1=\E[C$<2>, cuu1=\E[A$<2>, el=\E[K$<3>, ed=\E[J$<50>,
	smso=\E[7m$<2>, rmso=\E[m$<2>, smul=\E[4m$<2>, rmul=\E[m$<2>,
	bold=\E[1m$<2>, rev=\E[7m$<2>, blink=\E[5m$<2>, sgr0=\E[m$<2>,
	sgr=\E[%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p6%t;1%;m,
	rs2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h, smkx=\E[?1h\E=, rmkx=\E[?1l\E>,
	rf=/usr/lib/tabset/vt100, home=\E[H,
	kcuu1=\EOA, kcud1=\EOB, kcuf1=\EOC, kcub1=\EOD, kbs=^H,
	kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS, ht=^I, ri=\EM$<5>,
	vt#3, xenl, xon, sc=\E7, rc=\E8, csr=\E[%i%p1%d;%p2%dr,
vt100-nam|vt100 w/no am,
	am@, xenl@, use=vt100-am,
vt100-23|vt100 for use with sysline,
	lines#23, is2=\E[1;23r\E[23;1H,
	hs, eslok, tsl=\E7\E[24;%p1%dH\E[1K, fsl=\E8, use=vt100-am,
gt42|dec gt42,
	cr=^M, cud1=^J, bel=^G,
	cub1=^H, cols#72, lines#40, os,
vt132|vt132,
	il1=\E[L$<99>, dl1=\E[M$<99>, ip=$<7>, dch1=\E[P$<7>, rmir=\E[4l,
	smir=\E[4h, xenl, ind=^J$<30>, use=vt100,
gt40|dec gt40,
	cr=^M, cud1=^J, bel=^G,
	cub1=^H, cols#72, lines#30, os,
vt50|dec vt50,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, ed=\EJ, el=\EK, clear=\EH\EJ,
	cols#80, lines#12, cuf1=\EC, ht=^I, cuu1=\EA,
dw1|decwriter I,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	cub1=^H, cols#72, hc, os,
vt50h|dec vt50h,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, ed=\EJ, el=\EK,
	clear=\EH\EJ, cup=\EY%p1%' '%+%c%p2%' '%+%c, cols#80, lines#12,
	cuf1=\EC, ht=^I, ri=\EI, cuu1=\EA,
vt100-s|dec vt100 132 cols 14 lines (w/o advanced video option),
	lines#14, use=vt100-w,
vt100-w|vt100-w-am|dec vt100 132 cols (w/advanced video),
	cols#132, lines#24, rs2=\E>\E[?3h\E[?4l\E[?5l\E[?8h, use=vt100-am,
vt100-w-nam|dec vt100 132 cols (w/advanced video),
	cols#132, lines#24, rs2=\E>\E[?3h\E[?4l\E[?5l\E[?8h, vt@, use=vt100-nam,
vt52|dec vt52,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, ed=\EJ, el=\EK,
	clear=\EH\EJ, cup=\EY%p1%' '%+%c%p2%' '%+%c, cols#80, lines#24,
	cuf1=\EC, ht=^I, ri=\EI, cuu1=\EA,
	kcuu1=\EA, kcud1=\EB, kcuf1=\EC, kcub1=\ED, kbs=^H,
# The dw3 (and dw4?) supposedly have some fancy stuff, like settable tabs
# and column addressing.  But I don't know the details, and nobody seems
# to use them except for consoles so it has never really mattered.
dw2|dw3|decwriter|dw|decwriter II,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	kbs=^h, cub1=^H, cols#132, hc, os,
# From cbosg!ucbvax!G:tut Thu Sep 24 22:10:46 1981
dw4|decwriter IV,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, cols#132, hc, os, am,
	ht=^I, is2=\Ec, kf0=\EOP, kf1=\EOQ, kf2=\EOR, kf3=\EOS, kbs=^H,
//go.sysin dd *
echo 'x - =data/diablo'
sed 's/^X//' <<'//go.sysin dd *' >=data/diablo
# # --------------------------------
#	@(#)diablo	1.4	5/19/82
#
# diablo: DAISY WHEEL PRINTERS
#
# The A manufacturer represents Diablo, DTC, Xerox, Qume, and other Daisy
# wheel terminals until such time as terminfo distinguishes between them
# enough to justify separate codes.
1620|1640|450|diablo 1620,
	cr=^M, cud1=^J, ind=^J, bel=^G, tbc=\E2, hts=\E1, hpa=\E\t%i%p1%c, kbs=^H,
	cub1=^H, cols#132, ff=^L, hc, hu=\EU, hd=\ED, os, ht=^I, cuu1=\E\n,
1620-m8|1640-m8|diablo 1620 w/8 column left margin,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#124, is2=\r        \E9, use=1620,
# DTC 382 with VDU.  Has no ed so we fake it with el.  Standout works but
# won't go away without dynamite.  The terminal has tabs, but I'm getting
# tired of fighting the braindamage.  If no tab is set or the terminal's
# in a bad mood, it glitches the screen around all of memory.  Note that
# return puts a blank ("a return character") in the space the cursor was
# at, so we use ^P return (and thus ^P newline for newline).  Note also
# that if you turn off tabs and let Unix expand tabs, curses won't work
# (current version) because it doesn't turn off this bit, and cursor
# addressing sends a tab for row/column 9.  What a losing terminal!  I
# have been unable to get tabs set in all 96 lines - it always leaves at
# least one line with no tabs in it, and once you tab through that line,
# it completely weirds out.
dtc|mc0|dtc382|382,
	.if=/usr/lib/tabset/dtcvdu,
	bel=^G, cud1=^J, ind=^J, il1=^P^Z, am, cub1=^H,
	cols#80, el=^P^U, clear=^P^]$<20>, cup=^P^Q%p2%c%p1%c, dch1=^X,
	dl1=^P^S, rmir=^Pi, home=^P^R, smir=^PI, cnorm=^Pb, cvvis=^PB, pad=\177,
	rmcup=^P^]$<20>, lines#24, cuf1=^PR, .rmso=^P \200, .smso=^P \002^PF,
	smul=^P \020, rmul=^P \200, cuu1=^P^L, xhp, lm#96,
	da, db, cr=^P^M, ed=^P^U^P^S^P^S,
dtc300s|300|300s|dtc 300s,
	tbc=\E3, hts=\E1, cr=^M, cud1=^J, ind=^J, bel=^G,
	kbs=^h, cub1=^H, cols#132, ff=^L, hc, hu=\EH, hd=\Eh, os, ht=^I, cuu1=^Z,
gsi,
	cub1=^H, cols#132, hc, hd=\Eh, hu=\EH, os, ht=^I, cuu1=^Z,
	cr=^M, cud1=^J, ind=^J, bel=^G,
aj830|aj832|aj|anderson jacobson,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	cub1=^H, hc, hd=\E9, hu=\E8, os, cuu1=\E7,
# From cbosg!ucbvax!pur-ee!cincy!chris Thu Aug 20 09:09:18 1981
# This is incomplete, but it's a start.
5520|nec|spinwriter|nec 5520|,
	tbc=\E3, hts=\E1, cr=^M, cud1=^J, ind=^J, bel=^G,
	kbs=^h, cub1=^H, cols#132, ff=^L, hc, hu=\E]s\E9\E]W, hd=\E]s\n\E]W,
	os, ht=^I, cuu1=\E9,
qume5|qume|Qume Sprint 5,
	tbc=\E3, hts=\E1, cr=^M, cud1=^J, ind=^J, bel=^G,
	kbs=^h, cub1=^H, cols#80, ff=^L, hc, hu=\EH, hd=\Eh, os, ht=^I, cuu1=^Z,
# I suspect the xerox1720 is the same as the diablo 1620.
x1720|x1700|1700|x1750|xerox 1720,
	cols#132, cub1=^H, ff=^L, hc, os, ht=^I, 
	cr=^M, cud1=^J, ind=^J, bel=^G,
	tbc=\E2, hts=\E1,
//go.sysin dd *
echo 'x - =data/general'
sed 's/^X//' <<'//go.sysin dd *' >=data/general
# # --------------------------------
#	@(#)general	1.4	5/19/82
#
# general: GENERAL TERMINAL (formerly INFOTON)
#
# Infoton is now called General Terminal Corp.
# gt100 sounds like something DEC would come out with.  Lets hope they don't.
i100|gt100|gt100a|General Terminal 100A (formerly Infoton 100),
	cr=^M, cud1=^J, ind=^J, bel=^G, clear=^L, ed=\EJ, el=\EK,
	lines#24, cols#80, il1=\EL, dl1=\EM, cuu1=\EA, cuf1=\EC,
	home=\EH, cup=\Ef%p2%' '%+%c%p1%' '%+%c,
	flash=\Eb\Ea, am, cub1=^H, smso=\Eb, rmso=\Ea,
# Looks like an ANSI terminal, but what a kludge for dch1!  I bet smdc/rmdc
# could be used even if the terminal is really that braindamaged.
# But you would think being ANSI they would do \E[P right.  Hmm.
i400|400|infoton 400,
	cr=^M, cud1=^J, ind=^J, bel=^G, if=/usr/lib/tabset/infoton_tabs,
	il1=\E[L, am, cub1=^H, el=\E[N, clear=\E[2J, cup=\E[%i%p1%3d;%p2%3dH,
	cols#80, dl1=\E[M, lines#25, cuf1=\E[C, cuu1=\E[A,
	smir=\E[4h\E[2Q, rmir=\E[4l\E[0Q, dch1=\E[4h\E[2Q\E[P\E[4l\E[0Q,
addrinfo,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	lines#24, cols#80, clear=^L, home=^H, cuf1=^Y, ed=^K,
	cuu1=^\, am, cub1=^Z, cup=\037%i%p1%{1}%-%c%p2%{1}%-%c, ll=^H^\,
# No, I don't know what this is.  But KAS happens to be Kurt Shoens initials.
infotonKAS,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^Z,
	ed=^K, clear=^L, cols#80, lines#24, cuf1=^Y, cuu1=^\, ll=^H^\,
//go.sysin dd *
echo 'x - =data/hazeltine'
sed 's/^X//' <<'//go.sysin dd *' >=data/hazeltine
# # --------------------------------
#	@(#)hazeltine	1.4	5/19/82
#
# hazeltine: HAZELTINE
#
# Since cuf1 is blank, when you want to erase something you
# are out of luck.  You will have to do ^L's a lot to
# redraw the screen.  h1000 is untested.  It doesn't work in
# vi - this terminal is too dumb for even vi.  (The code is
# there but it isn't debugged for this case.)
h1000|hazeltine 1000,
	cub1=^H, home=^K, clear=^L, cuf1= , cols#80, lines#12, cr=^M, cud1=^J, ind=^J, bel=^G,
# Note: the h1552 appears to be the first Hazeltine terminal which
# is not braindamaged.  It has tildes and backprimes and everything!
# Be sure the auto lf/cr switch is set to cr.
h1552|hazeltine 1552,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EE, dl1=\EO,
	kf1=\EP, lf1=blue, kf2=\EQ, lf2=red, kf3=\ER, lf3=green, use=vt52,
h1552rv|hazeltine 1552 reverse video,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	smso=\ES, rmso=\ET, use=h1552,
# From cbosg!ucbvax!pur-ee!cincy!chris Thu Aug 20 09:09:18 1981
h1420|hazeltine 1420,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, am, lines#24, cols#80,
	il1=\E^Z, dl1=\E^S, ed=\E^X, clear=\E\034, cuu1=\E^L,
	cuf1=^P, el=\E^O, ht=^N, cup=\E^Q%p2%c%p1%' '%+%c, smso=\E\037, rmso=\E^Y,
h1500|hazeltine 1500,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=~^Z$<40>, am,
	cub1=^H, ed=~^X$<10>, el=~^O, clear=~^\, cup=~^Q%p2%c%p1%c, cols#80,
	dl1=~^S$<40>, cud1=~^K, lines#24, cuf1=^P, .rmso=~^_, .smso=~^Y, cuu1=~^L,
# h1510 assumed to be in sane escape mode.  Else use h1500.
h1510|hazeltine 1510,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	il1=\E^Z, am, cub1=^H, ed=\E^X, el=\E^O, clear=\E^\, cup=\E^Q%p2%c%p1%c, cols#80,
	dl1=\E^S, cud1=\E^K, lines#24, cuf1=^P, .rmso=\E^_, .smso=\E^Y, cuu1=\E^L,
h1520|hazeltine 1520,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=~^Z, am, cub1=^H,
	ed=~^X, el=~^O, clear=~\034, cup=~^Q%p2%c%p1%c$<1>, cols#80,
	dl1=~^S, cud1=~^K, hz, lines#24, cuf1=^P, rmso=~^Y, smso=~\037, cuu1=~^L, home=~^R,
# Note: h2000 won't work well because of a clash between upper case and ~'s.
h2000|hazeltine 2000,
	cud1=^J, ind=^J, bel=^G,
	il1=~^z$<6>, am, cub1=^H, clear=~^\$<6>, cup=~^q%p2%c%p1%c, cols#74,
	dl1=~^s$<6>, home=~^r, lines#27, pad=\177,
//go.sysin dd *
echo 'x - =data/header'
sed 's/^X//' <<'//go.sysin dd *' >=data/header
# ------------------------
#
#	Terminfo source file %W% (CBOSGD) %G%
#	Mark Horton, U.C. Berkeley, Bell Telephone Laboratories
#
# This file describes capabilities of various terminals, as needed by
# software such as screen editors.  It does not attempt to describe
# printing terminals very well, nor graphics terminals.  Someday.
# See terminfo(5) in the Unix Programmers Manual for documentation.
#
# Conventions: First entry is two chars, first char is manufacturer,
# second char is canonical name for model or mode.
# Third entry is the one the editor will print with "set" command.
# Last entry is verbose description.
# Others are mnemonic synonyms for the terminal.
#
# Terminal naming conventions:
# Terminal names look like <manufacturer> <model> - <modes/options>
# Certain abbreviations (e.g. c100 for concept100) are also allowed
# for upward compatibility.  The part to the left of the dash, if a
# dash is present, describes the particular hardware of the terminal.
# The part to the right can be used for flags indicating special ROM's,
# extra memory, particular terminal modes, or user preferences.
# All names are always in lower case, for consistency in typing.
# Because of file naming restrictions, terminal names should not contain
# period or slash, in fact, entirely alphanumeric characters plus dash are
# highly recommended.  These restrictions do not apply to the verbose name.
#
# The following are conventionally used flags:
#	rv	Terminal in reverse video mode (black on white)
#	2p	Has two pages of memory.  Likewise 4p, 8p, etc.
#	w	Wide - in 132 column mode.
#	pp	Has a printer port which is used.
#	na	No arrow keys - terminfo ignores arrow keys which are
#		actually there on the terminal, so the user can use
#		the arrow keys locally.
#  
# There are some cases where the same name is used for two different
# terminals, e.g. "teleray" or "2621" or "vt100".  In these cases,
# if a site has one of these, they should choose a local default and
# bring that terminal to the front in the reorder script.  This works
# because tgetent picks the first match in /etc/terminfo.
# The list of names intentionally duplicated is:
# 2621, c108, dtc, hp2621, teleray, tvi, vt100.
#
# If you absolutely MUST check for a specific terminal (this is discouraged)
# check for the 2nd entry (the canonical form) since all other codes are
# subject to change.  The two letter codes are there for version 6 and are
# EXTREMELY subject to change, or even to go away if version 6 becomes for
# all practical purposes obsolete.  We would much rather put in special
# capabilities to describe your terminal rather than having you key on the
# name.
#
#  Special manufacturer codes:
#	A: hardcopy daisy wheel terminals
#	M: Misc. (with only a few terminals)
#  	q: Homemade
#  	s: special (dialup, etc.)
#  
# Comments in this file begin with # - they cannot appear in the middle
# of a terminfo entry.  Individual entries are commented out by
# placing a period between the colon and the capability name.
#
#  This file is to be installed with an editor script (reorder)
#  that moves the most common terminals to the front of the file.
#  If the source is not available, it can be constructed by sorting
#  the above entries by the 2 char initial code.
//go.sysin dd *
echo 'x - =data/heath'
sed 's/^X//' <<'//go.sysin dd *' >=data/heath
# # --------------------------------
#	@(#)heath	1.4	5/19/82
#
# heath: HEATHKIT (ZENITH)
#
h19-a|heath-ansi|heathkit-a|heathkit h19 ansi mode,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=\E[1L$<1*>, am, cub1=^H, ed=\E[J,
	el=\E[K, clear=\E[2J, cup=\E[%i%p1%2d;%p2%2dH, cols#80,
	dch1=\E[1P, dl1=\E[1M$<1*>, cud1=\E[1B,
	rmir=\E[4l, home=\E[H, smir=\E[4h, lines#24, mir,
	cuf1=\E[1C, rmacs=\E[10m, smacs=\E[11m, msgr, ht=^I, 
	rmso=\E[0m, smso=\E[7m, cuu1=\E[1A, cvvis=\E[>4h, cnorm=\E[>4l,
	kbs=^h, kcuu1=\E[1A, kcud1=\E[1B, kcub1=\E[1D, kcuf1=\E[1C,
	khome=\E[H,
	kf1=\EOS, kf2=\EOT, kf3=\EOU, kf4=\EOV, kf5=\EOW, lf6=blue,
	lf7=red, lf8=white, kf6=\EOP, kf7=\EOQ, kf8=\EOR,
	ri=\EM, is2=\E<\E[>1;2;3;4;5;6;7;8;9l\E[0m\E[11m\E[?7h,
h19-bs|heathkit w/keypad shifted,
	smkx=\Et, rmkx=\Eu, use=h19-b,
h19-smul|heathkit w/keypad shifted/underscore cursor,
	smkx=\Et, rmkx=\Eu, use=h19-u,
h19|heath|h19-b|heathkit|heath-19|z19|zenith|heathkit h19,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EL$<1*>, am, cub1=^H,
	ed=\EJ, el=\EK, clear=\EE, cup=\EY%p1%' '%+%c%p2%' '%+%c, cols#80,
	dch1=\EN, dl1=\EM$<1*>, cud1=\EB, rmir=\EO, home=\EH, smir=\E@,
	lines#24, mir, cuf1=\EC, rmacs=\EF, smacs=\EG, msgr, ht=^I, 
	ri=\EI, rmso=\Eq, smso=\Ep, cuu1=\EA, cvvis=\Ex4, cnorm=\Ey4,
	kbs=^h, kcuu1=\EA, kcud1=\EB, kcub1=\ED, kcuf1=\EC, khome=\EH,
	kf1=\ES, kf2=\ET, kf3=\EU, kf4=\EV, kf5=\EW,
	lf6=blue, lf7=red, lf8=white, kf6=\EP, kf7=\EQ, kf8=\ER,
	hs, eslok, tsl=\Ej\Ex5\EY8%p1%' '%+%c\Eo\Eo, fsl=\Ek\Ey5,
h19-u|heathkit with underscore cursor,
	cvvis@, cnorm@, use=h19-b,
# This still doesn't work right - something funny is going on with return
# and linefeed in the reach program.
reach|h89|h89 running reach,
	cr@, cud1=\EB, is2=\Ey3\Ev, use=h19-b,
//go.sysin dd *
echo 'x - =data/homebrew'
sed 's/^X//' <<'//go.sysin dd *' >=data/homebrew
# # --------------------------------
#	@(#)homebrew	1.4	5/19/82
#
# homebrew: HOME MADE TERMINALS
#
bc|bill croft homebrew,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H,
	cup=\E=%p1%' '%+%c%p2%' '%+%c, clear=^Z, cols#96, home=^^, lines#72,
	cuf1=^L, cuu1=^K, flash=,
nucterm|rayterm|nuc|NUC homebrew,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H, clear=^L$<1>,
	lines#24, cols#80, cuf1=^C, cuu1=^N, home=^B, ll=^K, el=^A, ed=^E,
carlock|klc,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=^E, am, el=^U, clear=^Z$<100>,
	cup=\E=%p1%' '%+%c%p2%' '%+%c, cols#80, dch1=\177, dl1=^D, ed=,
	rmir=^T, home=^^, smir=^T, lines#24, cuf1=^L, rmso=^V, smso=^V,
	cuu1=^K, flash=\EV\EV,
ex3000,
	cr=^M, cud1=^J, ind=^J, bel=^G, lines#24, cols#80, home=^Q,
exidy|exidy2500|exidy sorcerer rmacs dm2500,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=^P^J^X, am, cub1=^H,
	el=^W, clear=^^, cup=^L%p2%'`'%^%c%p1%'`'%^%c, cols#64,
	dch1=\b, dl1=^P^Z^X, smdc=^P, ed=^X, rmir=^X, home=^B, ich1=^\,
	smir=^P, lines#30, cuf1=^\, ht=^I, smso=^N, rmso=^X, cuu1=^Z,
# This came from the comp ctr who got it from some user.  Smart indeed!
sexidy|exidy smart,
	cr=^M, cud1=^J, ind=^J, bel=^G, lines#24, cols#64, clear=^L, home=^Q,
	cuf1=^S, cuu1=^W, cub1=^H, cub1=^A, kcud1=^S,
# netx and xitex are almost identical, except for the padding
# on clear screen.  Hmm.
netx|netronics,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, ed=^F^E$<2000>, el=^E$<1600>,
	clear=^L$<466>, cup=\E=%p1%'@'%+%c%p2%'@'%+%c, cols#64, home=^D,
	lines#16, cuf1=\E+@A, pad=\200, ri=\E=@@^K, cuu1=^K,
xitex|xitex sct-100,
	cr=^M, cud1=^J, ind=^J, bel=^G, cub1=^H, ed=^F^E$<2000>, el=^E$<1600>,
	clear=^L$<400>, cup=\E=%p1%'@'%+%c%p2%'@'%+%c, cols#64, home=^D,
	lines#16, cuf1=\E+@A, pad=\200, ri=\E=@@^K, cuu1=^K,
ubell|ubellchar,
	if=/usr/lib/tabset/ubell,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H, ht=^I, el=\Ed,
	clear=^Z, cup=\E=%p1%' '%+%c%p2%' '%+%c, cols#80, lines#24, cuf1=^L,
	cuu1=^K, home=^^,
ttywilliams,
	cr=^M, cud1=^J, ind=^J, bel=^G, cols#80, lines#12,
	cub1=^Y, cud1=^K, cuu1=^Z, clear=^^, el=^_, am, home=^], cuf1=^X,
//go.sysin dd *
echo 'x - =data/hp'
sed 's/^X//' <<'//go.sysin dd *' >=data/hp
# # --------------------------------
#	@(#)hp	1.7	5/20/82
#
# hp: HEWLETT PACKARD
#
# Note: no "home" on HP's since that homes to top of memory, not screen.
# Due to severe 2621 braindamage, the only way to get the arrow keys to
# transmit anything at all is to turn on the function key labels
# (f1-f8) with smkx, and even then the poor user has to hold down shift!
# The default 2621 turns off the labels except when it has to to enable
# the function keys.  If your installation prefers labels on all the time,
# or off all the time (at the "expense" of the function keys) move the
# 2621-nl or 2621-wl labels to the front using reorder.
# Note: there are newer ROM's for 2621's that allow you to set strap A
# so the regular arrow keys xmit \EA, etc, as with the 2645.  However,
# even with this strap set, the terminal stops xmitting if you reset it,
# until you unset and reset the strap!  Since there is no way to set/unset
# the strap with an escape sequence, we don't use it in the default.
# If you like, you can use 2621-ba (braindamaged arrow keys).
hp2621-ba|2621-ba|2621 w/new rom and strap A set,
	smkx@, rmkx@,
	kcuu1=\EA, kcud1=\EB, kcub1=\ED, kcuf1=\EC, khome=\Eh, use=hp2621,
# 2621 with labels on all the time - normal outside vi, function inside vi.
hp2621-wl|2621-wl|hp 2621 w/labels,
	is2=\E&jA\r, rmkx=\E&jA, use=hp2621-fl,
# 2621 with function labels.  Most of the time they are off,
# but inside vi, the function key labels appear.  You have to
# hold down shift to get them to xmit.
hp2621-fl|2621|hp2621|hp2621a|hp2621p|2621a|2621p|2621-fl|2621A|2621P|hp 2621,
	is2=\E&j@\r, cbt=\Ei, cup=\E&a%p2%dc%p1%dY,
	dch1=\EP$<2>, ip=$<2>, pb#19200,
	smso=\E&dD, rmso=\E&d@, smul=\E&dD, rmul=\E&d@, sgr0=\E&d@, xhp@,
	khome=\Ep\r, kcuu1=\Et\r, kcub1=\Eu\r, kcuf1=\Ev\r, kcud1=\Ew\r,
	kf1=\Ep\r, kf2=\Eq\r, kf3=\Er\r, kf4=\Es\r, kf5=\Et\r, kf6=\Eu\r,
	kf7=\Ev\r, kf8=\Ew\r, smkx=\E&jB, rmkx=\E&j@, ht=^I$<2>, xon, use=hp,
# 2621k45: untested
2621k45|hp2621k45|k45|hp 2621 with 45 keyboard,
	kbs=^H, kcuu1=\EA, kcud1=\EB, kcub1=\ED, kcuf1=\EC, khome=\Eh,
	smkx=\E&s1A, rmkx=\E&s0A, use=2621,
# This terminal should be used at 4800 baud or less.  It needs padding for
# plain characters at 9600, I guessed at an appropriate cr delay.
# It really wants ^E/^F handshaking, but that doesn't work well even if
# you write software to support it.
2645|hp2645|hp45|hp 264x series,
	dim=\E&dH, rev=\E&dB, smul=\E&dD, blink=\E&dA, sgr0=\E&d@,
	sgr=\E&d%'@'%?%p1%t%'B'%|%;%?%p2%t%'D'%|%;%?%p3%t%'B'%|%;%?%p4%t%'A'%|%;%?%p5%t%'H'%|%;%?%p6%t%'B'%|%;%c,
	kcuu1=\EA, kcud1=\EB, kcub1=\ED, kcuf1=\EC, khome=\Eh,
	smkx=\E&s1A, rmkx=\E&s0A, knp=\EU, kpp=\EV, kri=\ET, kind=\ES,
	kil1=\EL, kdl1=\EM, kich1=\EQ, kdch1=\EP,
	kel=\EK, ked=\EJ, krmir=\ER, pb#9600, cr=^M$<20>, use=hp,
hp|hewlett-packard,
	tbc=\E3, hts=\E1, cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EL, am, cub1=^H,
	ed=\EJ, el=\EK, hpa=\E&a%p1%dC, clear=\EH\EJ,
	cup=\E&a%p2%dc%p1%dY$<6>, cols#80, vpa=\E&a%p1%dY, lm#0, da, db,
	dch1=\EP, dl1=\EM, rmir=\ER, smir=\EQ, kbs=^H, lines#24, mir,
	cuf1=\EC, ht=^I, rmso=\E&d@, smso=\E&dJ,
	smul=\E&dD, rmul=\E&d@, cuu1=\EA, xhp, vt#6,
hp-0|hewlett-packard for testing of curses and the like,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cuf1=\EC,
	cub1=^H, clear=\EH\EJ, home=\E&a0c0Y, cols#80, lines#24,
hp-1,
	ht=^I, cuu1=\EA, use=hp-0,
hp-2,
	cup=\E&a%p2%dc%p1%dY$<6>, use=hp-1,
hp-3,
	ed=\EJ, el=\EK, use=hp-2,
# This entry does not use any of the fancy windowing stuff of the 2626.
# Indeed, terminfo does not yet handle such stuff.  Since changing any window
# clears memory, it is probably not possible to use this for screen opt.
# ed is incredibly slow most of the time - I am guessing at the exact padding.
# Since the terminal uses xoff/xon this is intended only for cost computation,
# so that the terminal will prefer el or even dl1 which is probably faster!
hp2626|hp2626a|hp2626p|2626|2626a|2626p|2626A|2626P|hp 2626,
	dch1=\EP$<2>, ip=$<2>, rmso=\E&d@, smso=\E&dB, ed=\EJ$<500>,
	rev=\E&dB, smul=\E&dD, blink=\E&dA, invis=\E&dS, sgr0=\E&d@,
	rmul=\E&d@,
	sgr=\E&d%'@'%?%p1%t%'B'%|%;%?%p2%t%'D'%|%;%?%p3%t%'B'%|%;%?%p4%t%'A'%|%;%c,
	khome=\Eh, kcuu1=\EA, kcub1=\ED, kcuf1=\EC, kcud1=\EB,
	smkx=\E&s1A, rmkx=\E&s0A, knp=\EU, kpp=\EV, kri=\ET,
	kind=\ES, kil1=\EL, kdl1=\EM, kich1=\EQ, kdch1=\EP,
	kel=\EK, ked=\EJ, krmir=\ER,
	ind=\ES, ht=^I$<2>, xhp, use=2621,
# This entry is for sysline.  It allocates a 23 line window with a 115 line
# workspace for regular use, and a 1 line window for the status line.
# This assumes port 2 is being used.
# Turn off horizontal line, Create ws #1 with 115 lines,
# Create ws #2 with 1 line, Create window #1 lines 1-23,
# Create window #2 lines 24-24, Attach cursor to workspace #1.
# Note that this clears the tabs so it must be done by tset before
# it sets the tabs.
2626-23|hp 2626 using only 23 lines,
	tsl=\E&w7f2p2I\E&w4f2I\r\EK\E&a%p1%dC,
	fsl=\E&d@\E&w7f2p1I\E&w4f1I, eslok, hs,
	is1=\E&q3t0{0H \E&w0f115n1I \E&w0f1n2I
	\E&w2f1i0d0u22l0S \E&w2f2i0d23u23l0S \E&w7f2p1I \r,
	lines#23, use=2626,
# Force terminal back to 24 lines after being 23.
2626-24|hp 2626 using all 24 lines,
	is1=\E&q3t0{0H \E&w0f118n1I \E&w0f1n2I
	\E&w2f1i0d0u23l0S \E&w3f2I \E&w7f2p1I \r,
	use=2626,
# Various entries useful for small windows on 2626.
2626-12,
	lines#12, use=2626,
2626-12x40,
	cols#40, lines#12, use=2626,
2626-x40,
	cols#40, use=2626,
2626-11,
	lines#11, use=2626-23,
# cD is a pain - but it only screws up at 9600 baud.
# You should use this terminal at 4800 baud or less.
hp2648|hp2648a|2648a|2648A|2648|HP 2648a graphics terminal,
	clear=\EH\EJ$<50>, cup=\E&a%p2%dc%p1%dY$<20>,
	dch1=\EP$<7>, ip=$<5>, use=2645,
# 2640a doesn't have the Y cursor addressing feature, and C is memory relative
# instead of screen relative, as we need.
2640|hp2640a|2640a|hp 2640a,
	cup@, smkx@, rmkx@, use=2645,
2640b|hp2640b|2644a|hp2644a|hp 264x series,
	smkx@, rmkx@, use=2645,
# 2621 using all 48 lines of memory, only 24 visible at any time.  Untested.
2621-48|48 line 2621,
	lines#48, home=\EH, cup=\E&a%p2%dc%p1%dR, use=2621,
# 2621 with no labels ever.  Also prevents vi delays on escape.
hp2621-nl|2621-nl|hp 2621 with no labels,
	smkx@, rmkx@, khome@, kcuu1@, kcub1@, kcuf1@, kcud1@, use=hp2621-fl,
# Needed for UCB ARPAVAX console, since lsi-11 expands tabs (wrong).
hp2621-nt|2621-nt|hp 2621 w/no tabs,
	ht@, use=hp2621,
//go.sysin dd *
echo 'x - =data/ibm'
sed 's/^X//' <<'//go.sysin dd *' >=data/ibm
# # --------------------------------
#	@(#)ibm	1.4	5/19/82
#
# ibm: IBM, INTERACTIVE SYSTEMS, and INTECOLOR
#
# Some of these should go in the misc category, IBM, ISC, and intecolor can't
# all have I.  I will wait to see who comes out with more terminals.
# These compucolors appear similar, but they at least have different
# sized screens.  I don't know what's going on here.
# There is further confusion since intecolor seems to call themselves isc too.
8001|isc8001|compucolor|intecolor,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EU, am, cub1=^Z,
	clear=^L$<3*>, cup=^C%p2%c%p1%c, cols#80, rmdc=\EQ, smdc=\EQ, ed=\EF,
	dch1=\177, dl1=\EV, rmir=\EF, smir=\EQ, lines#40, cuf1=^Y$<1>,
	ht=\t$<8>, cuu1=^\, home=^H$<1>,
compucolor2|compucolorii,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	ht=^I, am, cup=^C%p2%c%p1%c, cub1=^Z, lines#32, cols#64,
	clear=^L, home=^H, cuf1=^Y, cuu1=^\,
# From cithep!eric  Wed Sep 16 08:06:44 1981
intext|Interactive Systems Corporation modified owl 1200,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=\020$<5.5*>, am, cub1=^_,
	cub1=^H, cbt=^Y, ed=\026J$<5.5*>, el=^K\160^R,
	clear=\014$<132>, cup=\017%p1%' '%+%c%p2%' '%+%c, cols#80,
	dch1=\022$<5.5*>, dl1=\021$<5.5*>, rmir=\026\074,
	smir=\026\073, ip=$<5.5*>, lines#24, cuf1=\036, ht=^I, 
	cuu1=\034, rmso=^V# , xmc#1, smso=^V$\054,
	kcub1=^_, kcud1=^J, kcuf1=^^, kcuu1=\034, kbs=^H, khome=^Z,
	kf1=^VA\r, kf2=^VB\r, kf3=^VC\r, kf4=^VD\r, kf5=^VE\r,
	kf6=^VF\r, kf7=^VG\r, kf8=^VH\r, kf9=^VI\r, kf0=^VJ\r,
ibm|ibm3101|3101|i3101|IBM 3101-10,
	.if=/usr/lib/tabset/3101,
	cr=^M, cud1=^J, ind=^J, bel=^G, tbc=\EH, hts=\E0, am, cub1=^H,
	clear=\EK, lines#24, cols#80, cuf1=\EC, cuu1=\EA, ed=\EJ, el=\EI,
	kcud1=\EB, kcub1=\ED, kcuf1=\EC, kcuu1=\EA,
	home=\EH, cup=\EY%p1%' '%+%c%p2%' '%+%c, ht=^I, 
//go.sysin dd *
echo 'x - =data/lsi'
sed 's/^X//' <<'//go.sysin dd *' >=data/lsi
# # --------------------------------
#	@(#)lsi	1.4	5/19/82
#
# lsi: LEAR SIEGLER (ADM)
#
# If the adm31 gives you trouble with standout mode, check the DIP switch
# in position 6, bank @c11, 25% from back end of pad.  Should be OFF.
# If there is no such switch, you have an old adm31 and must use oadm31
adm31|31|lsi adm31,
	is2=\Eu\E0, cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EE, am, cub1=^H,
	el=\ET, cup=\E=%p1%' '%+%c%p2%' '%+%c, clear=\E*, ed=\EY, cols#80,
	dch1=\EW, dl1=\ER, rmir=\Er, home=^^, smir=\Eq,
	kf0=^A0\r, kf1=^A1\r, kf2=^A2\r, kf3=^A3\r, kf4=^A4\r,
	kf5=^A5\r, kf6=^A6\r, kf7=^A7\r, kf8=^A8\r, kf9=^A9\r,
	kcud1=^J, kcub1=^H, kcuf1=^L, kcuu1=^K,
	lines#24, mir, cuf1=^L,
	rmso=\EG0, smso=\EG1, cuu1=^K, smul=\EG1, rmul=\EG0,
adm2|lsi adm2,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EE, am, cub1=^H, ed=\EY, el=\ET,
	clear=\E;, cup=\E=%p1%' '%+%c%p2%' '%+%c, cols#80, dch1=\EW, dl1=\ER,
	home=^^, ich1=\EQ, kcud1=^J, khome=^^, kcub1=^H, kcuf1=^L, kcuu1=^K,
	lines#24, cuf1=^L, cuu1=^K,
adm3|lsi adm3,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	am, cub1=^H, clear=^Z, lines#24, cols#80,
adm42|42|lsi adm42,
	cvvis=\EC\E3 \E3(, cr=^M, cud1=^J, ind=^J, bel=^G, il1=\EE$<270>,
	am, cub1=^H, ed=\EY, el=\ET, clear=\E;, cup=\E=%p1%' '%+%c%p2%' '%+%c,
	cols#80, dch1=\EW, dl1=\ER, rmir=\Er, smir=\Eq, ip=$<6*>, lines#24,
	cbt=\EI, cuf1=^L, rmso=\EG0, smso=\EG4, ht=\t, cuu1=^k,
	pad=\177,
adm5|lsi adm5,
	cr=^M, cud1=^J, ind=^J, bel=^G,
	ed=\EY, el=\ET, cud1=^J, kbs=^H, khome=^^,
	rmso=\EG, xmc#1, smso=\EG, use=adm3aplus,
adm3a|3a|lsi adm3a,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H,
	cup=\E=%p1%' '%+%c%p2%' '%+%c, clear=^Z$<1>,
	cols#80, home=^^, lines#24, cuf1=^L, cuu1=^K,
adm3a+|3a+|adm3aplus|lsi adm3a+,
	kcub1=^H, kcud1=^J, kcuu1=^K, kcuf1=^L, use=adm3a,
oadm31|o31|old adm31,
	smso=\EG4, smul@, rmul@, use=adm31,
//go.sysin dd *
echo 'x - =data/microterm'
sed 's/^X//' <<'//go.sysin dd *' >=data/microterm
# # --------------------------------
#	@(#)microterm	1.4	5/19/82
#
# microterm: MICROTERM
#
microterm|act4|microterm act iv,
	cr=^M, cud1=^J, ind=^J, bel=^G, am, cub1=^H, ed=^_, el=^^, clear=^L,
	cup=^T%p1%c%p2%c, cols#80, lines#24, cuf1=^X, cuu1=^Z, home=^],
# The padding on cuf1 for act5 and mime is a guess and not final.
# The act5 has hardware tabs, but in cols 8, 16, 24, 32, 41 (!), 49, ...
microterm5|act5|microterm act v,
	uc=\EA, ri=\EH$<3>, kcuu1=^Z, kcud1=^K, kcub1=^H, kcuf1=^X, use=act4,
# Act V in split screen mode.  act5s is not tested and said not to work.
# Could have been because of the funny tabs - it might work now.
act5s|skinny act5,
	smcup=\EP, rmcup=\EQ, lines#48, cols#39, use=act5,
# These mime1 entries refer to the Microterm Mime I or Mime II.
# The default mime is assumed to be in enhanced act iv mode.
# There is a ^Q in is2 to unwedge any lines that wedge on ^S.
mime|mime1|mime2|mimei|mimeii|microterm mime1,
	cup=^T%p1%{24}%+%c%p2%?%p2%{32}%>%t%{48}%+%;%{80}%+%c, cols#80,
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=^A$<80>, am, cub1=^H,
	ed=^_, el=^^, clear=\035^C, dl1=^W$<80>, ht=^I, lines#24,
	cuf1=^X, uc=^U, cuu1=^z, home=\035, cud1=^K, is2=\E^S^Q,
	kcuu1=^Z, kcud1=^K, kcub1=^H, kcuf1=^X, ri=^R$<3>, vt#9,
mime-3a|mime-adm3a|mime1 emulating adm3a,
	am@, kcuu1=^Z, kcud1=^K, kcub1=^H, kcuf1=^X, use=adm3a,
mime-3ax|mime-adm3ax|mime1 emulating enhanced adm3a,
	il1=^A$<80>, dl1=^W$<80>, ht=^I$<3>, el=^X, ed=^_, use=mime-3a,
# Mimes using brightness for standout.  Half bright is very dim unless
# you turn up the brightness so far that lines show up on the screen.
mime-fb|full bright mime1,
	smso=^Y, rmso=^S, is2=^S\E^Q, use=mime,
mime-hb|half bright mime1,
	smso=^S, rmso=^Y, is2=^Y\E, use=mime,
# These entries (for mime 2a) put the terminal in low intensity mode
# since high intensity mode is so obnoxious.
# This is the preferred mode (but ^X can't be used as a kill character (?))
mime2a|mime2a-v|microterm mime2a (emulating an enhanced vt52),
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=^A$<20*>, cub1=^H, ed=\EQ$<20*>,
	cols#80, el=\EP, clear=\EL, cup=\EY%p1%' '%+%c%p2%' '%+%c, is2=^Y,
	dch1=^N, dl1=^W$<20*>, ip=$<2>, rmir=^Z, home=\EH, smir=^O, cuu1=\EA,
	ri=\EA, kcud1=\EB, kcub1=\ED, kcuf1=\EC, kcuu1=\EA, lines#24,
	cuf1=\EC, ht=^I, rmso=\E9, smso=\E8, smul=\E4, rmul=\E5,
mime2a-s|microterm mime2a (emulating an enhanced soroc iq120),
	cr=^M, cud1=^J, ind=^J, bel=^G, il1=^A$<20*>, am, cub1=^H, ed=\EJ$<20*>,
	el=\EK, clear=\EL, cup=\E=%p1%' '%+%c%p2%' '%+%c, cols#80, dch1=\ED,
	dl1=^W$<20*>, kcub1=^H, kcuf1=^L, kcuu1=^K, kcud1=^J, home=^^, is2=\E),
	ri=\EI, smir=\EE, rmir=^Z, ip=$<2>, lines#24, cuf1=^L, cuu1=\EI,
	smso=\E:, rmso=\E;, smul=\E6, rmul=\E7,
//go.sysin dd *
exit

sources@genrad.UUCP (12/22/84)

This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit".  This code is completely public domain, originally written by Pavel
Curtis of Cornell University.  This version has some small improvements and
bug fixes.

This unit contains:
	The demo program "mille".

----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
echo 'Making directory "=test"'
mkdir =test
echo 'Making directory "=test/=mille"'
mkdir =test/=mille
echo 'x - =test/=mille/Makefile'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/Makefile
HEADERS=mille.h
CFILES=	comp.c end.c extern.c init.c mille.c misc.c move.c print.c \
	roll.c save.c types.c varpush.c
OBJS=	comp.o end.o extern.o init.o mille.o misc.o move.o print.o \
	roll.o save.o types.o varpush.o
POBJS=	comp.po end.po extern.po init.po mille.po misc.po move.po \
	roll.po print.po save.po types.po varpush.po
LIBS=	../../=src/libpcurses.a
CFLAGS=	-O -DSTANDOUT -I../../=src
X.SUFFIXES: .po .i

X.c.po:
	rm -f x.c ; ln $*.c x.c
	${CC} ${CFLAGS} -pg -c x.c
	mv x.o $*.po

X.c.i:
	${CC} ${CFLAGS} -P $*.c

mille: ${OBJS} 
	${CC} ${CFLAGS} -n -o mille ${OBJS} ${LIBS}

install: mille
	cp mille /usr/games

pmb: ${POBJS}
	${CC} ${CFLAGS} -n -pg -o pmb ${POBJS} $(LIBS)

mille.po: mille.c
	rm -f x.c ; ln mille.c x.c
	${CC} ${CFLAGS} -DPROF -p -c x.c
	mv x.o mille.po

table: table.o extern.o
	${CC} ${CFLAGS} -i -o table table.o extern.o

readdump: readdump.o extern.o varpush.o
	${CC} ${CFLAGS} -i -o readdump readdump.o extern.o varpush.o

ctags:
	ctags ${HEADERS} ${CFILES}
	ed - tags < :ctfix
	sort tags -o tags

lint:
	lint -hxb ${CFILES} > lint.out

mille.ar:
	ar ruv mille.ar Makefile tags ${HEADERS} ${CFILES}

tar:
	tar crvf mille.tar Makefile tags :ctfix ${HEADERS} ${CFILES}

lpr:
	pr Makefile ${HEADERS} ${CFILES} tags | lpr ; lpq
//go.sysin dd *
echo 'x - =test/=mille/comp.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/comp.c
# include	"mille.h"

# define	V_VALUABLE	40

calcmove() {

	reg CARD	card;
	reg int		*value;
	reg PLAY	*pp, *op;
	reg bool	foundend, cango, canstop, foundlow;
	reg unsgn int	i, count200, badcount, nummin, nummax, diff;
	reg int		curmin, curmax;
	reg CARD	safe, oppos;
	int		valbuf[HAND_SZ], count[NUM_CARDS];
	bool		playit[HAND_SZ];

	wmove(Score, ERR_Y, ERR_X);	/* get rid of error messages	*/
	wclrtoeol(Score);
	pp = &Player[COMP];
	op = &Player[PLAYER];
	safe = 0;
	cango = 0;
	canstop = FALSE;
	foundend = FALSE;
	for (i = 0; i < NUM_CARDS; i++)
		count[i] = 0;
	for (i = 0; i < HAND_SZ; i++) {
		card = pp->hand[i];
		switch (card) {
		  case C_STOP:	case C_CRASH:
		  case C_FLAT:	case C_EMPTY:
			if (playit[i] = canplay(pp, op, card))
				canstop = TRUE;
			goto norm;
		  case C_LIMIT:
			if ((playit[i] = canplay(pp, op, card))
			    && Numseen[C_25] == Numcards[C_25]
			    && Numseen[C_50] == Numcards[C_50])
				canstop = TRUE;
			goto norm;
		  case C_25:	case C_50:	case C_75:
		  case C_100:	case C_200:
			if ((playit[i] = canplay(pp, op, card))
			    && pp->mileage + Value[card] == End)
				foundend = TRUE;
			goto norm;
		  default:
			playit[i] = canplay(pp, op, card);
norm:
			if (playit[i])
				++cango;
			break;
		  case C_GAS_SAFE:	case C_DRIVE_SAFE:
		  case C_SPARE_SAFE:	case C_RIGHT_WAY:
			if (pp->battle == opposite(card)
			   || (pp->speed == C_LIMIT && card == C_RIGHT_WAY)) {
				Movetype = M_PLAY;
				Card_no = i;
				return;
			}
			++safe;
			playit[i] = TRUE;
			break;
		}
		++count[card];
	}
	if (pp->hand[0] == C_INIT && Topcard > Deck) {
		Movetype = M_DRAW;
		return;
	}
	if (Debug)
		fprintf(outf, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n", cango, canstop, safe);
	if (foundend)
		foundend = !check_ext(TRUE);
	for (i = 0; safe && i < HAND_SZ; i++) {
		if (issafety(pp->hand[i])) {
			if (onecard(op) || (foundend && cango && !canstop)) {
				if (Debug)
					fprintf(outf, "CALCMOVE: onecard(op) = %d, foundend = %d\n", onecard(op), foundend);
playsafe:
				Movetype = M_PLAY;
				Card_no = i;
				return;
			}
			oppos = opposite(pp->hand[i]);
			if (Numseen[oppos] == Numcards[oppos])
				goto playsafe;
			else if (!cango
			    && (op->can_go || !pp->can_go || Topcard < Deck)) {
				card = (Topcard - Deck) - roll(1, 10);
				if ((!pp->mileage) != (!op->mileage))
					card -= 7;
				if (Debug)
					fprintf(outf, "CALCMOVE: card = %d, DECK_SZ / 4 = %d\n", card, DECK_SZ / 4);
				if (card < DECK_SZ / 4)
					goto playsafe;
			}
			safe--;
			playit[i] = cango;
		}
	}
	if (!pp->can_go && !isrepair(pp->battle))
		Numneed[opposite(pp->battle)]++;
redoit:
	foundlow = (cango || count[C_END_LIMIT] != 0
			  || Numseen[C_LIMIT] == Numcards[C_LIMIT]
			  || pp->safety[S_RIGHT_WAY] != S_UNKNOWN);
	foundend = FALSE;
	count200 = pp->nummiles[C_200];
	badcount = 0;
	curmax = -1;
	curmin = 101;
	nummin = -1;
	nummax = -1;
	value = valbuf;
	for (i = 0; i < HAND_SZ; i++) {
		card = pp->hand[i];
		if (issafety(card) || playit[i] == (cango != 0)) {
			if (Debug)
				fprintf(outf, "CALCMOVE: switch(\"%s\")\n", C_name[card]);
			switch (card) {
			  case C_25:	case C_50:
				diff = End - pp->mileage;
				/* avoid getting too close */
				if (Topcard > Deck && cango && diff <= 100
				    && diff / Value[card] > count[card]
				    && (card == C_25 || diff % 50 == 0)) {
					if (card == C_50 && diff - 50 == 25
					    && count[C_25] > 0)
						goto okay;
					*value = 0;
					if (--cango <= 0)
						goto redoit;
					break;
				}
okay:
				*value = (Value[card] >> 3);
				if (pp->speed == C_LIMIT)
					++*value;
				else
					--*value;
				if (!foundlow
				   && (card == C_50 || count[C_50] == 0)) {
					*value = (pp->mileage ? 10 : 20);
					foundlow = TRUE;
				}
				goto miles;
			  case C_200:
				if (++count200 > 2) {
					*value = 0;
					break;
				}
			  case C_75:	case C_100:
				*value = (Value[card] >> 3);
				if (pp->speed == C_LIMIT)
					--*value;
				else
					++*value;
miles:
				if (pp->mileage + Value[card] > End)
					*value = (End == 700 ? card : 0);
				else if (pp->mileage + Value[card] == End) {
					*value = (foundend ? card : V_VALUABLE);
					foundend = TRUE;
				}
				break;
			  case C_END_LIMIT:
				if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
					*value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 1);
				else if (pp->speed == C_LIMIT && End - pp->mileage <= 50)
					*value = 1;
				else if (pp->speed == C_LIMIT
				    || Numseen[C_LIMIT] != Numcards[C_LIMIT]) {
					safe = S_RIGHT_WAY;
					oppos = C_LIMIT;
					goto repair;
				}
				else {
					*value = 0;
					--count[C_END_LIMIT];
				}
				break;
			  case C_REPAIRS:	case C_SPARE:	case C_GAS:
				safe = safety(card) - S_CONV;
				oppos = opposite(card);
				if (pp->safety[safe] != S_UNKNOWN)
					*value = (pp->safety[safe] == S_PLAYED ? -1 : 1);
				else if (pp->battle != oppos
				    && (Numseen[oppos] == Numcards[oppos] || Numseen[oppos] + count[card] > Numcards[oppos])) {
					*value = 0;
					--count[card];
				}
				else {
repair:
					*value = Numcards[oppos] * 6;
					*value += (Numseen[card] - Numseen[oppos]);
					if (!cango)
					    *value /= (count[card]*count[card]);
					count[card]--;
				}
				break;
			  case C_GO:
				if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
					*value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 2);
				else if (pp->can_go
				 && Numgos + count[C_GO] == Numneed[C_GO]) {
					*value = 0;
					--count[C_GO];
				}
				else {
					*value = Numneed[C_GO] * 3;
					*value += (Numseen[C_GO] - Numgos);
					*value /= (count[C_GO] * count[C_GO]);
					count[C_GO]--;
				}
				break;
			  case C_LIMIT:
				if (op->mileage + 50 >= End) {
					*value = (End == 700 && !cango);
					break;
				}
				if (canstop || (cango && !op->can_go))
					*value = 1;
				else {
					*value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 2 : 3);
					safe = S_RIGHT_WAY;
					oppos = C_END_LIMIT;
					goto normbad;
				}
				break;
			  case C_CRASH:	case C_EMPTY:	case C_FLAT:
				safe = safety(card) - S_CONV;
				oppos = opposite(card);
				*value = (pp->safety[safe]!=S_UNKNOWN ? 3 : 4);
normbad:
				if (op->safety[safe] == S_PLAYED)
					*value = -1;
				else {
				    *value *= (Numneed[oppos] + Numseen[oppos] + 2);
				    if (!pp->mileage || foundend || onecard(op))
					*value += 5;
				    if (op->mileage == 0 || onecard(op))
					*value += 5;
				    if (op->speed == C_LIMIT)
					*value -= 3;
				    if (cango && pp->safety[safe] != S_UNKNOWN)
					*value += 3;
				    if (!cango)
					*value /= ++badcount;
				}
				break;
			  case C_STOP:
				if (op->safety[S_RIGHT_WAY] == S_PLAYED)
					*value = -1;
				else {
				    *value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 3 : 4);
				    *value *= (Numcards[C_STOP] + Numseen[C_GO]);
				    if (!pp->mileage || foundend || onecard(op))
					*value += 5;
				    if (!cango)
					*value /= ++badcount;
				    if (op->mileage == 0)
					*value += 5;
				    if ((card == C_LIMIT
				      && op->speed == C_LIMIT) || (!op->can_go))
					*value -= 5;
				    if (cango && pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
					*value += 5;
				}
				break;
			  case C_GAS_SAFE:	case C_DRIVE_SAFE:
			  case C_SPARE_SAFE:	case C_RIGHT_WAY:
				*value = cango ? 0 : 101;
				break;
			  case C_INIT:
				*value = 0;
			}
		}
		else
			*value = cango ? 0 : 101;
		if (card != C_INIT) {
			if (*value >= curmax) {
				nummax = i;
				curmax = *value;
			}
			if (*value <= curmin) {
				nummin = i;
				curmin = *value;
			}
		}
		if (Debug)
			mvprintw(i+6,2,"%3d %-14s",*value,C_name[pp->hand[i]]);
		value++;
	}
	if (!pp->can_go && !isrepair(pp->battle))
		Numneed[opposite(pp->battle)]++;
	if (cango) {
		mvaddstr(MOVE_Y + 1, MOVE_X, "PLAY\n");
		if (Debug)
			getmove();
		if (!Debug || Movetype == M_DRAW) {
			Movetype = M_PLAY;
			Card_no = nummax;
		}
	}
	else {
		mvaddstr(MOVE_Y + 1, MOVE_X, "DISCARD\n");
		if (Debug)
			getmove();
		if (!Debug || Movetype == M_DRAW) {
			Movetype = M_DISCARD;
			Card_no = nummin;
		}
	}
	mvprintw(MOVE_Y + 2, MOVE_X, "%16s", C_name[pp->hand[Card_no]]);
}

onecard(pp)
reg PLAY	*pp; {

	reg CARD	bat, spd, card;

	bat = pp->battle;
	spd = pp->speed;
	card = -1;
	if (pp->can_go || ((isrepair(bat) || bat == C_STOP
	    || spd == C_LIMIT) && Numseen[S_RIGHT_WAY] != 0)
	    || Numseen[safety(bat)] != 0)
		switch (End - pp->mileage) {
		  case 200:
			if (pp->nummiles[C_200] == 2)
				return FALSE;
			card = C_200;
		  case 100:
		  case 75:
			if (card == -1)
				card = (End - pp->mileage == 75 ? C_75 : C_100);
			if (spd == C_LIMIT)
				return Numseen[S_RIGHT_WAY] == 0;
		  case 50:
		  case 25:
			if (card == -1)
				card = (End - pp->mileage == 25 ? C_25 : C_50);
			return Numseen[card] != Numcards[card];
		}
	return FALSE;
}

canplay(pp, op, card)
reg PLAY	*pp, *op;
reg CARD	card; {

	switch (card) {
	  case C_200:
		if (pp->nummiles[C_200] == 2)
			break;
	  case C_75:	case C_100:
		if (pp->speed == C_LIMIT)
			break;
	  case C_50:
		if (pp->mileage + Value[card] > End)
			break;
	  case C_25:
		if (pp->can_go)
			return TRUE;
		break;
	  case C_EMPTY:	case C_FLAT:	case C_CRASH:
	  case C_STOP:
		if (op->can_go && op->safety[safety(card) - S_CONV] != S_PLAYED)
			return TRUE;
		break;
	  case C_LIMIT:
		if (op->speed != C_LIMIT && op->safety[S_RIGHT_WAY] != S_PLAYED
		    && op->mileage + 50 < End)
			return TRUE;
		break;
	  case C_GAS:	case C_SPARE:	case C_REPAIRS:
		if (pp->battle == opposite(card))
			return TRUE;
		break;
	  case C_GO:
		if (!pp->can_go
		    && (isrepair(pp->battle) || pp->battle == C_STOP))
			return TRUE;
		break;
	  case C_END_LIMIT:
		if (pp->speed == C_LIMIT)
			return TRUE;
	}
	return FALSE;
}
//go.sysin dd *
echo 'x - =test/=mille/end.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/end.c
# include	"mille.h"

X/*
 *	print out the score as if it was final, and add the totals for
 * the end-of-games points to the user who deserves it (if any).
 */
finalscore(pp)
reg PLAY	*pp; {

	reg int		temp, tot, num;

	num = pp - Player;
	temp = num * 6 + 21 + 3;
	for (tot = 5; tot <= 9; tot++)
		mvaddch(tot, temp, '0');
	if (pp->mileage == End) {
		temp -= 2;
		mvaddstr(5, temp, "40");
		tot = SC_TRIP;
		if (pp->nummiles[C_200] == 0) {
			mvaddstr(6, temp, "30");
			tot = SC_TRIP + SC_SAFE;
		}
		if (Topcard <= Deck) {
			mvaddstr(7, temp, "30");
			tot += SC_DELAY;
		}
		if (End == 1000) {
			mvaddstr(8, temp, "20");
			tot += SC_EXTENSION;
		}
		if (Player[other(num)].mileage == 0) {
			mvaddstr(9, temp, "50");
			tot += SC_SHUT_OUT;
		}
		pp->total += tot;
		pp->hand_tot += tot;
	}
}

# ifdef EXTRAP
static int	Last_tot[2];	/* last tot used for extrapolate	*/

X/*
 *	print out the score as if it was final, and add the totals for
 * the end-of-games points to the user who deserves it (if any).
 */
extrapolate(pp)
reg PLAY	*pp; {

	reg int		x, num, tot, count;

	num = pp - Player;
	tot += SC_TRIP + SC_DELAY + SC_EXT;
	x = num * 6 + 21 + 3;
	for (tot = 5; tot <= 9; tot++)
		mvaddch(tot, x, '0');
	x -= 2;
	pp = &Player[other(num)];
	for (count = 0, tot = 0; tot < NUM_SAFE; tot++)
		if (pp->safety[tot] != S_PLAYED)
			count += SC_SAFE;
	mvprintw(3, x, "%3d", count);
	tot += count;
	if (count == 400) {
		mvaddstr(4, x, "30");
		tot += SC_ALL_SAFE;
	}
	pp = &Player[num];
	for (count = 0, tot = 0; tot < NUM_SAFE; tot++)
		if (pp->safety[tot] != S_PLAYED)
			count += SC_COUP / 10;
	mvprintw(4, x - 1, "%3d", count);
	tot += count;
	tot += 1000 - pp->mileage;
	mvaddstr(5, x, "40");
	mvaddstr(7, x, "30");
	mvaddstr(8, x, "20");
	if (pp->nummiles[C_200] == 0) {
		mvaddstr(6, x, "30");
		tot = SC_TRIP + SC_SAFE;
	}
	if (Player[other(num)].mileage == 0) {
		mvaddstr(9, x, "50");
		tot += SC_SHUT_OUT;
	}
	pp->total += tot;
	pp->hand_tot += tot;
	Last_tot[num] = tot;
}

undoex() {

	reg PLAY	*pp;
	reg int		i;

	i = 0;
	for (pp = Player; pp < &Player[2]; pp++) {
		pp->total -= Last_tot[i];
		pp->hand_tot -= Last_tot[i++];
	}
}
# endif
//go.sysin dd *
echo 'x - =test/=mille/extern.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/extern.c
# include	"mille.h"

bool	Debug,			/* set if debugging code on		*/
	Finished,		/* set if current hand is finished	*/
	Next,			/* set if changing players		*/
	On_exit,		/* set if game saved on exiting		*/
	Order,			/* set if hand should be sorted		*/
	Saved;			/* set if game just saved		*/

char	*C_fmt = "%-18.18s",	/* format for printing cards		*/
	*Fromfile = NULL,	/* startup file for game		*/
	Initstr[100],		/* initial string for error field	*/
	*_cn[NUM_CARDS] = {	/* Card name buffer			*/
		"",
		"25",
		"50",
		"75",
		"100",
		"200",
		"Out of Gas",
		"Flat Tire",
		"Accident",
		"Stop",
		"Speed Limit", 
		"Gasoline",
		"Spare Tire",
		"Repairs",
		"Go",
		"End of Limit",
		"Extra Tank",
		"Puncture Proof",
		"Driving Ace",
		"Right of Way"
	},
	**C_name = &_cn[1];	/* Card names				*/

int	Card_no,		/* Card number for current move		*/
	End,			/* End value for current hand		*/
	Handstart = COMP,	/* Player who starts hand		*/
	Movetype,		/* Current move type			*/
	Play,			/* Current player			*/
	Numgos,			/* Number of Go cards used by computer	*/
	Window = W_SMALL,	/* Current window wanted		*/
	Numseen[NUM_CARDS],	/* Number of cards seen in current hand	*/
	Value[NUM_MILES] = {	/* Value of mileage cards		*/
		25, 50, 75, 100, 200
	},
	Numcards[NUM_CARDS] = {	/* Number of cards in deck		*/
		10,	/* C_25 */
		10,	/* C_50 */
		10,	/* C_75 */
		12,	/* C_100 */
		4,	/* C_200 */
		2,	/* C_EMPTY */
		2,	/* C_FLAT */
		2,	/* C_CRASH */
		4,	/* C_STOP */
		3,	/* C_LIMIT */
		6,	/* C_GAS */
		6,	/* C_SPARE */
		6,	/* C_REPAIRS */
		14,	/* C_GO */
		6,	/* C_END_LIMIT */
		1,	/* C_GAS_SAFE */
		1,	/* C_SPARE_SAFE */
		1,	/* C_DRIVE_SAFE */
		1,	/* C_RIGHT_WAY */
		0	/* C_INIT */
	};
	Numneed[NUM_CARDS] = {	/* number of cards needed per hand	*/
		0,	/* C_25 */
		0,	/* C_50 */
		0,	/* C_75 */
		0,	/* C_100 */
		0,	/* C_200 */
		2,	/* C_EMPTY */
		2,	/* C_FLAT */
		2,	/* C_CRASH */
		4,	/* C_STOP */
		3,	/* C_LIMIT */
		2,	/* C_GAS */
		2,	/* C_SPARE */
		2,	/* C_REPAIRS */
		10,	/* C_GO */
		3,	/* C_END_LIMIT */
		1,	/* C_GAS_SAFE */
		1,	/* C_SPARE_SAFE */
		1,	/* C_DRIVE_SAFE */
		1,	/* C_RIGHT_WAY */
		0	/* C_INIT */
	};

CARD	Discard,		/* Top of discard pile			*/
	*Topcard,		/* Pointer to next card to be picked	*/
	Opposite[NUM_CARDS] = {	/* Opposites of each card		*/
		C_25, C_50, C_75, C_100, C_200, C_GAS, C_SPARE,
		C_REPAIRS, C_GO, C_END_LIMIT, C_EMPTY, C_FLAT, C_CRASH,
		C_STOP, C_LIMIT, C_EMPTY, C_FLAT, C_CRASH, C_STOP, C_INIT
	},
	Deck[DECK_SZ] = {	/* Current deck				*/
		C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25,
		C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50,
		C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75,
		C_100, C_100, C_100, C_100, C_100, C_100, C_100, C_100, C_100,
		C_100, C_100, C_100,
		C_200, C_200, C_200, C_200,
		C_EMPTY, C_EMPTY,
		C_FLAT, C_FLAT,
		C_CRASH, C_CRASH,
		C_STOP, C_STOP, C_STOP, C_STOP,
		C_LIMIT, C_LIMIT, C_LIMIT,
		C_GAS, C_GAS, C_GAS, C_GAS, C_GAS, C_GAS,
		C_SPARE, C_SPARE, C_SPARE, C_SPARE, C_SPARE, C_SPARE,
		C_REPAIRS, C_REPAIRS, C_REPAIRS, C_REPAIRS, C_REPAIRS,
			C_REPAIRS,
		C_END_LIMIT, C_END_LIMIT, C_END_LIMIT, C_END_LIMIT, C_END_LIMIT,
			C_END_LIMIT,
		C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO,
			C_GO, C_GO, C_GO, C_GO,
		C_GAS_SAFE, C_SPARE_SAFE, C_DRIVE_SAFE, C_RIGHT_WAY
	};

XFILE	*outf;

PLAY	Player[2];		/* Player descriptions			*/

WINDOW	*Board,			/* Playing field screen			*/
	*Miles,			/* Mileage screen			*/
	*Score;			/* Score screen				*/
//go.sysin dd *
echo 'x - =test/=mille/init.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/init.c
# include	"mille.h"

init() {

	reg PLAY	*pp;
	reg int		i, j;
	reg CARD	card;

	for (j = 0; j < C_RIGHT_WAY; j++)
		Numseen[j] = 0;
	Numgos = 0;

	for (i = 0; i < 2; i++) {
		pp = &Player[i];
		pp->hand[0] = C_INIT;
		for (j = 0; j < NUM_SAFE; j++) {
			pp->safety[j] = S_UNKNOWN;
			pp->coups[j] = FALSE;
		}
		for (j = 1; j < HAND_SZ; j++) {
			pp->hand[j] = *--Topcard;
			if (i == COMP) {
				account(card = *Topcard);
				if (issafety(card))
					pp->safety[card - S_CONV] = S_IN_HAND;
			}
		}
		pp->mileage = 0;
		pp->hand_tot = 0;
		pp->safescore = 0;
		pp->coupscore = 0;
		pp->can_go = FALSE;
		pp->speed = C_INIT;
		pp->battle = C_INIT;
		pp->new_speed = FALSE;
		pp->new_battle = FALSE;
		for (j = 0; j < NUM_MILES; j++)
			pp->nummiles[j] = 0;
	}
	if (Order)
		sort(Player[PLAYER].hand);
	Discard = C_INIT;
	Finished = FALSE;
	End = 700;
}

shuffle() {

	reg int		i, r;
	reg CARD	temp;

	for (i = 0; i < DECK_SZ; i++) {
		r = roll(1, DECK_SZ) - 1;
		if (r < 0 || r > DECK_SZ - 1) {
			fprintf(stderr, "shuffle: card no. error: %d\n", r);
			die();
		}
		temp = Deck[r];
		Deck[r] = Deck[i];
		Deck[i] = temp;
	}
	Topcard = &Deck[DECK_SZ];
}

newboard() {

	werase(Board);
	werase(Score);
	mvaddstr(5, 0, "--HAND--");
	mvaddch(6, 0, 'P');
	mvaddch(7, 0, '1');
	mvaddch(8, 0, '2');
	mvaddch(9, 0, '3');
	mvaddch(10, 0, '4');
	mvaddch(11, 0, '5');
	mvaddch(12, 0, '6');
	mvaddstr(13, 0, "--BATTLE--");
	mvaddstr(15, 0, "--SPEED--");
	mvaddstr(5, 20, "--DECK--");
	mvaddstr(7, 20, "--DISCARD--");
	mvaddstr(13, 20, "--BATTLE--");
	mvaddstr(15, 20, "--SPEED--");
	wmove(Miles, 0, 0);
	if (winch(Miles) != '-') {
		werase(Miles);
		mvwaddstr(Miles, 0, 0, "--MILEAGE--");
		mvwaddstr(Miles, 0, 41, "--MILEAGE--");
	}
	else {
		wmove(Miles, 1, 0);
		wclrtobot(Miles);
	}
	newscore();
	stdscr = Board;
}

newscore() {

	reg int	i;

	stdscr = Score;
	move(0, 22);
	if (inch() != 'Y') {
		erase();
		mvaddstr(0, 22,  "You   Comp   Value");
		mvaddstr(1, 2, "Milestones Played");
		mvaddstr(2, 8, "Each Safety");
		mvaddstr(3, 5, "All 4 Safeties");
		mvaddstr(4, 3, "Each Coup Fourre");
		mvaddstr(2, 37, "100");
		mvaddstr(3, 37, "300");
		mvaddstr(4, 37, "300");
	}
	else {
		move(5, 1);
		clrtobot();
	}
	for (i = 0; i < SCORE_Y; i++)
		mvaddch(i, 0, '|');
	move(SCORE_Y - 1, 1);
	while (addch('_') != ERR)
		continue;
	if (Window == W_FULL || Finished) {
		mvaddstr(5, 5, "Trip Completed");
		mvaddstr(6, 10, "Safe Trip");
		mvaddstr(7, 5, "Delayed Action");
		mvaddstr(8, 10, "Extension");
		mvaddstr(9, 11, "Shut-Out");
		mvaddstr(10, 21, "----   ----   -----");
		mvaddstr(11, 9, "Hand Total");
		mvaddstr(12, 20, "-----  -----");
		mvaddstr(13, 6, "Overall Total");
		mvaddstr(14, 15, "Games");
		mvaddstr(5, 37, "400");
		mvaddstr(6, 37, "300");
		mvaddstr(7, 37, "300");
		mvaddstr(8, 37, "200");
		mvaddstr(9, 37, "500");
	}
	else {
		mvaddstr(5, 21, "----   ----   -----");
		mvaddstr(6, 9, "Hand Total");
		mvaddstr(7, 20, "-----  -----");
		mvaddstr(8, 6, "Overall Total");
		mvaddstr(9, 15, "Games");
		mvaddstr(11, 2, "p: pick");
		mvaddstr(12, 2, "u: use #");
		mvaddstr(13, 2, "d: discard #");
		mvaddstr(14, 2, "w: toggle window");
		mvaddstr(11, 21, "q: quit");
		mvaddstr(12, 21, "o: order hand");
		mvaddstr(13, 21, "s: save");
		mvaddstr(14, 21, "r: reprint");
	}
	stdscr = Board;
}
//go.sysin dd *
echo 'x - =test/=mille/mille.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/mille.c
# include	"mille.h"
# include	<signal.h>
# include       <term.h>

int	rub();

char	_sobuf[BUFSIZ];

main(ac, av)
reg int		ac;
reg char	*av[]; {

	reg bool	restore;

# if 0
	if (getuid() == GURP) {
		printf("%s: Permission denied\n", av[0]);
		exit(1);
	}
# endif
	if (strcmp(av[0], "a.out") == 0) {
		outf = fopen("q", "w");
		setbuf(outf, 0);
		Debug = TRUE;
	}
	restore = FALSE;
# ifdef pdp11
	if (geteuid() != ARNOLD)
		maxusers(MAXUSERS, NULL);
# endif
	switch (ac) {
	  case 2:
		rest_f(av[1]);
		restore = TRUE;
	  case 1:
		break;
	  default:
		printf("usage: milles [ restore_file ]\n");
		exit(-1);
		/* NOTREACHED */
	}
	setbuf(stdout, _sobuf);
	Play = PLAYER;
	initscr();
	if (! cursor_address) {
		printf("Sorry.  Need cursor addressing to play mille\n");
		exit(-1);
	}
	delwin(stdscr);
	stdscr = Board = newwin(BOARD_Y, BOARD_X, 0, 0);
	Score = newwin(SCORE_Y, SCORE_X, 0, 40);
	Miles = newwin(MILES_Y, MILES_X, 17, 0);
	leaveok(Score, TRUE);
	leaveok(Miles, TRUE);
	clearok(curscr, TRUE);
# ifndef PROF
	srand(getpid());
# else
	srand(0);
# endif
	crmode();
	noecho();
	nonl();
	signal(SIGINT, rub);
	for (;;) {
		if (!restore || (Player[PLAYER].total >= 5000
		    || Player[COMP].total >= 5000)) {
			if (Player[COMP].total < Player[PLAYER].total)
				Player[PLAYER].games++;
			else if (Player[COMP].total > Player[PLAYER].total)
				Player[COMP].games++;
			Player[COMP].total = 0;
			Player[PLAYER].total = 0;
		}
		do {
			if (!restore)
				Handstart = Play = other(Handstart);
			if (!restore || On_exit) {
				shuffle();
				init();
			}
			newboard();
			if (restore)
				mvwaddstr(Score, ERR_Y, ERR_X, Initstr);
			prboard();
			do {
				domove();
				if (Finished)
					newscore();
				prboard();
			} while (!Finished);
			check_more();
			restore = On_exit = FALSE;
		} while (Player[COMP].total < 5000
		    && Player[PLAYER].total < 5000);
	}
}

X/*
 *	Routine to trap rubouts, and make sure they really want to
 * quit.
 */
rub() {

	signal(SIGINT, 1);
	if (getyn("Really? "))
		die();
	signal(SIGINT, rub);
}

X/*
 *	Time to go beddy-by
 */
die() {

	signal(SIGINT, 1);
	if (outf)
		fflush(outf);
	mvcur(0, COLS - 1, LINES - 1, 0);
	endwin();
	exit(1);
}
//go.sysin dd *
echo 'x - =test/=mille/mille.h'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/mille.h
# include	<ctype.h>
# include	<curses.h>

X/*
 * Miscellaneous constants
 */

# define	unsgn		unsigned
# define        reg             register
# define	CARD		short

# ifdef  vax
#	define	ARNOLD		78	/* my uid			*/
# else
#	define	ARNOLD		24601	/* my uid			*/
# endif

# define	GURP		28672	/* bad uid			*/
# define	MAXUSERS	35	/* max # of users for startup	*/
# define	HAND_SZ		7	/* number of cards in a hand	*/
# define	DECK_SZ		101	/* number of cards in decks	*/
# define	NUM_SAFE	4	/* number of saftey cards	*/
# define	NUM_MILES	5	/* number of milestones types	*/
# define	NUM_CARDS	20	/* number of types of cards	*/
# define	BOARD_Y		17	/* size of board screen		*/
# define	BOARD_X		40
# define	MILES_Y		7	/* size of mileage screen	*/
# define	MILES_X		80
# define	SCORE_Y		17	/* size of score screen		*/
# define	SCORE_X		40
# define	MOVE_Y		10	/* Where to print move prompt	*/
# define	MOVE_X		20
# define	ERR_Y		15	/* Where to print errors	*/
# define	ERR_X		5
# define	EXT_Y		4	/* Where to put Extension	*/
# define	EXT_X		9

# define	PLAYER		0
# define	COMP		1

# define	W_SMALL		0	/* Small (initial) window	*/
# define	W_FULL		1	/* Full (final) window		*/

X/*
 * Move types
 */

# define	M_DISCARD	0
# define	M_DRAW		1
# define	M_PLAY		2
# define	M_ORDER		3

X/*
 * Scores
 */

# define	SC_SAFETY	100
# define	SC_ALL_SAFE	300
# define	SC_COUP		300
# define	SC_TRIP		400
# define	SC_SAFE		300
# define	SC_DELAY	300
# define	SC_EXTENSION	200
# define	SC_SHUT_OUT	500

X/*
 * safety descriptions
 */

# define	S_UNKNOWN	0	/* location of safety unknown	*/
# define	S_IN_HAND	1	/* safety in player's hand	*/
# define	S_PLAYED	2	/* safety has been played	*/
# define	S_GAS_SAFE	0	/* Gas safety card index	*/
# define	S_SPARE_SAFE	1	/* Tire safety card index	*/
# define	S_DRIVE_SAFE	2	/* Driveing safety card index	*/
# define	S_RIGHT_WAY	3	/* Right-of-Way card index	*/
# define	S_CONV		15	/* conversion from C_ to S_	*/

X/*
 * card numbers
 */

# define	C_INIT		-1
# define	C_25		0
# define	C_50		1
# define	C_75		2
# define	C_100		3
# define	C_200		4
# define	C_EMPTY		5
# define	C_FLAT		6	
# define	C_CRASH		7
# define	C_STOP		8
# define	C_LIMIT		9
# define	C_GAS		10
# define	C_SPARE		11
# define	C_REPAIRS	12
# define	C_GO		13
# define	C_END_LIMIT	14
# define	C_GAS_SAFE	15
# define	C_SPARE_SAFE	16
# define	C_DRIVE_SAFE	17
# define	C_RIGHT_WAY	18

typedef struct {
	bool	coups[NUM_SAFE];
	bool	can_go;
	bool	new_battle;
	bool	new_speed;
	short	safety[NUM_SAFE];
	short	nummiles[NUM_MILES];
	CARD	hand[HAND_SZ];
	CARD	battle;
	CARD	speed;
	int	mileage;
	int	hand_tot;
	int	safescore;
	int	coupscore;
	int	total;
	int	games;
} PLAY;

X/*
 * macros
 */

# define	other(x)	(1 - x)
# define	nextplay()	(Play = other(Play))
# define	nextwin(x)	(1 - x)
# define	opposite(x)	(Opposite[x])
# define	issafety(x)	(x >= C_GAS_SAFE)

X/*
 * externals
 */

extern bool	Debug, Finished, Next, On_exit, Order, Saved;

extern char	*C_fmt, **C_name, *Fromfile, Initstr[];

extern int	Card_no, End, Handstart, Movetype, Numcards[], Numgos,
		Numneed[], Numseen[NUM_CARDS], Play, Value[], Window;

extern CARD	Deck[DECK_SZ], Discard, Opposite[NUM_CARDS], *Topcard;

extern FILE	*outf;

extern PLAY	Player[2];

extern WINDOW	*Board, *Miles, *Score;

X/*
 * functions
 */

CARD	getcard();
//go.sysin dd *
echo 'x - =test/=mille/misc.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/misc.c
#include	"mille.h"
#include	"unctrl.h"
#define	NUMSAFE	4

X/* VARARGS1 */
error(str, arg)
char	*str;
{
	stdscr = Score;
	mvprintw(ERR_Y, ERR_X, str, arg);
	clrtoeol();
	putchar('');
	refresh();
	stdscr = Board;
	return FALSE;
}

CARD
getcard()
{
	reg char	c, c1;

	for (;;) {
		while ((c = getch()) == '\n' || c == '\r' || c == ' ')
			continue;
		if (islower(c))
			c = toupper(c);
		if (c == killchar() || c == erasechar())
			return -1;
		addstr(unctrl(c));
		clrtoeol();
		switch (c) {
		  case '1':	case '2':	case '3':
		  case '4':	case '5':	case '6':
			c -= '0';
			break;
		  case '0':	case 'P':	case 'p':
			c = 0;
			break;
		  default:
			putchar('');
			addch('\b');
			if (!isprint(c))
				addch('\b');
			c = -1;
			break;
		}
		refresh();
		if (c >= 0) {
			while ((c1=getch()) != '\r' && c1 != '\n' && c1 != ' ')
				if (c1 == killchar())
					return -1;
				else if (c1 == erasechar()) {
					addch('\b');
					clrtoeol();
					refresh();
					goto cont;
				}
				else
					write(0, "", 1);
			return c;
		}
cont:		;
	}
}

check_ext(forcomp)
reg bool	forcomp; {


	if (End == 700)
		if (Play == PLAYER) {
			if (getyn("Extension? ")) {
extend:
				if (!forcomp)
					End = 1000;
				return TRUE;
			}
			else {
done:
				if (!forcomp)
					Finished = TRUE;
				return FALSE;
			}
		}
		else {
			reg PLAY	*pp, *op;
			reg int		i, safe, miles;

			pp = &Player[COMP];
			op = &Player[PLAYER];
			for (safe = 0, i = 0; i < NUMSAFE; i++)
				if (pp->safety[i] != S_UNKNOWN)
					safe++;
			if (safe < 2)
				goto done;
			if (op->mileage == 0 || onecard(op)
			    || (op->can_go && op->mileage >= 500))
				goto done;
			for (miles = 0, i = 0; i < NUMSAFE; i++)
				if (op->safety[i] != S_PLAYED
				    && pp->safety[i] == S_UNKNOWN)
					miles++;
			if (miles + safe == NUMSAFE)
				goto extend;
			for (miles = 0, i = 0; i < HAND_SZ; i++)
				if ((safe = pp->hand[i]) <= C_200)
					miles += Value[safe]; 
			if (miles + (Topcard - Deck) * 3 > 1000)
				goto extend;
			goto done;
		}
	else
		goto done;
}

X/*
 *	Get a yes or no answer to the given question.  Saves are
 * also allowed.  Return TRUE if the answer was yes, FALSE if no.
 */
getyn(prompt)
reg char	*prompt; {

	reg char	c;

	Saved = FALSE;
	for (;;) {
		leaveok(Board, FALSE);
		mvaddstr(MOVE_Y, MOVE_X, prompt);
		clrtoeol();
		refresh();
		switch (c = getch()) {
		  case 'n':	case 'N':
			addch('N');
			refresh();
			leaveok(Board, TRUE);
			return FALSE;
		  case 'y':	case 'Y':
			addch('Y');
			refresh();
			leaveok(Board, TRUE);
			return TRUE;
		  case 's':	case 'S':
			addch('S');
			refresh();
			Saved = save();
			continue;
		  default:
			addstr(unctrl(c));
			refresh();
			putchar('');
			break;
		}
	}
}

X/*
 *	Check to see if more games are desired.  If not, and game
 * came from a saved file, make sure that they don't want to restore
 * it.  Exit appropriately.
 */
check_more() {

	raw();	/* Flush input */
	noraw();

	On_exit = TRUE;
	if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000)
		if (getyn("Another game? "))
			return;
		else {
			/*
			 * must do accounting normally done in main()
			 */
			if (Player[PLAYER].total > Player[COMP].total)
				Player[PLAYER].games++;
			else if (Player[PLAYER].total < Player[COMP].total)
				Player[COMP].games++;
			Player[COMP].total = 0;
			Player[PLAYER].total = 0;
		}
	else
		if (getyn("Another hand? "))
			return;
	if (!Saved && getyn("Save game? "))
		if (!save())
			return;
	die();
}
//go.sysin dd *
echo 'x - =test/=mille/move.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/move.c
#include	"mille.h"
#include	"unctrl.h"

#define	CTRL(c)		(c - 'A' + 1)

char	*Movenames[] = {
		"M_DISCARD", "M_DRAW", "M_PLAY", "M_ORDER"
	};

domove()
{
	reg PLAY	*pp;
	reg int		i, j;
	reg bool	goodplay;

	pp = &Player[Play];
	if (Play == PLAYER)
		getmove();
	else
		calcmove();
	Next = FALSE;
	goodplay = TRUE;
	switch (Movetype) {
	  case M_DISCARD:
		if (haspicked(pp)) {
			if (pp->hand[Card_no] == C_INIT)
				if (Card_no == 6)
					Finished = TRUE;
				else
					error("no card there");
			else {
				Discard = pp->hand[Card_no];
				pp->hand[Card_no] = C_INIT;
				Next = TRUE;
				if (Play == PLAYER)
					account(Discard);
			}
		}
		else
			error("must pick first");
		break;
	  case M_PLAY:
		goodplay = playcard(pp);
		break;
	  case M_DRAW:
		Card_no = 0;
		if (Topcard <= Deck)
			error("no more cards");
		else if (haspicked(pp))
			error("already picked");
		else {
			pp->hand[0] = *--Topcard;
			if (Debug)
				fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
acc:
			if (Play == COMP) {
				account(*Topcard);
				if (issafety(*Topcard))
					pp->safety[*Topcard-S_CONV] = S_IN_HAND;
			}
			if (pp->hand[1] == C_INIT && Topcard > Deck) {
				Card_no = 1;
				pp->hand[1] = *--Topcard;
				if (Debug)
					fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
				goto acc;
			}
			pp->new_battle = FALSE;
			pp->new_speed = FALSE;
		}
		break;

	  case M_ORDER:
		break;
	}
	/*
	 * move blank card to top by one of two methods.  If the
	 * computer's hand was sorted, the randomness for picking
	 * between equally valued cards would be lost
	 */
	if (Order && Movetype != M_DRAW && goodplay && pp == &Player[PLAYER])
		sort(pp->hand);
	else
		for (i = 1; i < HAND_SZ; i++)
			if (pp->hand[i] == C_INIT) {
				for (j = 0; pp->hand[j] == C_INIT; j++)
					if (j >= HAND_SZ) {
						j = 0;
						break;
					}
				pp->hand[i] = pp->hand[j];
				pp->hand[j] = C_INIT;
			}
	if (Topcard <= Deck)
		check_go();
	if (Next)
		nextplay();
}

X/*
 *	Check and see if either side can go.  If they cannot,
 * the game is over
 */
check_go() {

	reg CARD	card;
	reg PLAY	*pp, *op;
	reg int		i;

	for (pp = Player; pp < &Player[2]; pp++) {
		op = (pp == &Player[COMP] ? &Player[PLAYER] : &Player[COMP]);
		for (i = 0; i < HAND_SZ; i++) {
			card = pp->hand[i];
			if (issafety(card) || canplay(pp, op, card)) {
				if (Debug) {
					fprintf(outf, "CHECK_GO: can play %s (%d), ", C_name[card], card);
					fprintf(outf, "issafety(card) = %d, ", issafety(card));
					fprintf(outf, "canplay(pp, op, card) = %d\n", canplay(pp, op, card));
				}
				return;
			}
			else if (Debug)
				fprintf(outf, "CHECK_GO: cannot play %s\n",
				    C_name[card]);
		}
	}
	Finished = TRUE;
}

playcard(pp)
reg PLAY	*pp;
{
	reg int		v;
	reg CARD	card;

	/*
	 * check and see if player has picked
	 */
	switch (pp->hand[Card_no]) {
	  default:
		if (!haspicked(pp))
mustpick:
			return error("must pick first");
	  case C_GAS_SAFE:	case C_SPARE_SAFE:
	  case C_DRIVE_SAFE:	case C_RIGHT_WAY:
		break;
	}

	card = pp->hand[Card_no];
	if (Debug)
		fprintf(outf, "PLAYCARD: Card = %s\n", C_name[card]);
	Next = FALSE;
	switch (card) {
	  case C_200:
		if (pp->nummiles[C_200] == 2)
			return error("only two 200's per hand");
	  case C_100:	case C_75:
		if (pp->speed == C_LIMIT)
			return error("limit of 50");
	  case C_50:
		if (pp->mileage + Value[card] > End)
			return error("puts you over %d", End);
	  case C_25:
		if (!pp->can_go)
			return error("cannot move now");
		pp->nummiles[card]++;
		v = Value[card];
		pp->total += v;
		pp->hand_tot += v;
		if ((pp->mileage += v) == End)
			check_ext(FALSE);
		break;

	  case C_GAS:	case C_SPARE:	case C_REPAIRS:
		if (pp->battle != opposite(card))
			return error("can't play \"%s\"", C_name[card]);
		pp->battle = card;
		if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
			pp->can_go = TRUE;
		break;

	  case C_GO:
		if (pp->battle != C_INIT && pp->battle != C_STOP
		    && !isrepair(pp->battle))
			return error("cannot play \"Go\" on a \"%s\"",
			    C_name[pp->battle]);
		pp->battle = C_GO;
		pp->can_go = TRUE;
		break;

	  case C_END_LIMIT:
		if (pp->speed != C_LIMIT)
			return error("not limited");
		pp->speed = C_END_LIMIT;
		break;

	  case C_EMPTY:	case C_FLAT:	case C_CRASH:
	  case C_STOP:
		pp = &Player[other(Play)];
		if (!pp->can_go)
			return error("opponent cannot go");
		else if (pp->safety[safety(card) - S_CONV] == S_PLAYED)
protected:
			return error("opponent is protected");
		pp->battle = card;
		pp->new_battle = TRUE;
		pp->can_go = FALSE;
		pp = &Player[Play];
		break;

	  case C_LIMIT:
		pp = &Player[other(Play)];
		if (pp->speed == C_LIMIT)
			return error("opponent has limit");
		if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
			goto protected;
		pp->speed = C_LIMIT;
		pp->new_speed = TRUE;
		pp = &Player[Play];
		break;

	  case C_GAS_SAFE:	case C_SPARE_SAFE:
	  case C_DRIVE_SAFE:	case C_RIGHT_WAY:
		if (pp->battle == opposite(card)
		    || (card == C_RIGHT_WAY && pp->speed == C_LIMIT)) {
			if (!(card == C_RIGHT_WAY && !isrepair(pp->battle))) {
				pp->battle = C_GO;
				pp->can_go = TRUE;
			}
			if (card == C_RIGHT_WAY && pp->speed == C_LIMIT)
				pp->speed = C_INIT;
			if (pp->new_battle
			    || (pp->new_speed && card == C_RIGHT_WAY)) {
				pp->coups[card - S_CONV] = TRUE;
				pp->total += SC_COUP;
				pp->hand_tot += SC_COUP;
				pp->coupscore += SC_COUP;
			}
		}
		/*
		 * if not coup, must pick first
		 */
		else if (pp->hand[0] == C_INIT && Topcard > Deck)
			goto mustpick;
		pp->safety[card - S_CONV] = S_PLAYED;
		pp->total += SC_SAFETY;
		pp->hand_tot += SC_SAFETY;
		if ((pp->safescore += SC_SAFETY) == NUM_SAFE * SC_SAFETY) {
			pp->total += SC_ALL_SAFE;
			pp->hand_tot += SC_ALL_SAFE;
		}
		if (card == C_RIGHT_WAY) {
			if (pp->speed == C_LIMIT)
				pp->speed = C_INIT;
			if (pp->battle == C_STOP || pp->battle == C_INIT) {
				pp->can_go = TRUE;
				pp->battle = C_INIT;
			}
			if (!pp->can_go && isrepair(pp->battle))
				pp->can_go = TRUE;
		}
		Next = -1;
		break;

	  case C_INIT:
		error("no card there");
		Next = -1;
		break;
	}
	if (pp == &Player[PLAYER])
		account(card);
	pp->hand[Card_no] = C_INIT;
	Next = (Next == -1 ? FALSE : TRUE);
	return TRUE;
}

getmove()
{
	reg char	c, *sp;
	static char	moveprompt[] = ">>:Move:";
#ifdef EXTRAP
	static bool	last_ex = FALSE;	/* set if last command was E */

	if (last_ex) {
		undoex();
		prboard();
		last_ex = FALSE;
	}
#endif
	for (;;) {
		stand(MOVE_Y, MOVE_X, moveprompt);
		clrtoeol();
		move(MOVE_Y, MOVE_X + sizeof moveprompt);
		leaveok(Board, FALSE);
		refresh();
		while ((c = getch()) == killchar() || c == erasechar())
			continue;
		if (islower(c))
			c = toupper(c);
		if (isprint(c) && !isspace(c)) {
			addch(c);
			refresh();
		}
		switch (c)
		{
		  case 'P':		/* Pick */
			Movetype = M_DRAW;
			goto ret;
		  case 'U':		/* Use Card */
		  case 'D':		/* Discard Card */
			if ((Card_no = getcard()) < 0)
				break;
			Movetype = (c == 'U' ? M_PLAY : M_DISCARD);
			goto ret;
		  case 'O':		/* Order */
			Order = !Order;
			Movetype = M_ORDER;
			goto ret;
		  case 'Q':		/* Quit */
			rub();		/* Same as a rubout */
			break;
		  case 'W':		/* Window toggle */
			Window = nextwin(Window);
			newscore();
			prscore(TRUE);
			wrefresh(Score);
			break;
		  case 'R':		/* Redraw screen */
		  case CTRL('L'):
			clearok(curscr, TRUE);
			newboard();
			prboard();
			break;
		  case 'S':		/* Save game */
			On_exit = FALSE;
			save();
			break;
		  case 'E':		/* Extrapolate */
#ifdef EXTRAP
			if (last_ex)
				break;
			Finished = TRUE;
			if (Window != W_FULL)
				newscore();
			prscore(FALSE);
			wrefresh(Score);
			last_ex = TRUE;
			Finished = FALSE;
#else
			error("%c: command not implemented", c);
#endif
			break;
		  case '\r':		/* Ignore RETURNs and	*/
		  case '\n':		/* Line Feeds		*/
		  case ' ':		/* and Spaces		*/
			break;
		  case 'Z':		/* Debug code */
			if (geteuid() == ARNOLD) {
				if (!Debug && outf == NULL) {
					char	buf[40];
over:
					mvaddstr(MOVE_Y, MOVE_X, "file: ");
					clrtoeol();
					leaveok(Board, FALSE);
					refresh();
					sp = buf;
					while ((*sp = getch()) != '\n') {
						if (*sp == killchar())
							goto over;
						else if (*sp == erasechar()) {
							if (--sp < buf)
								sp = buf;
							else {
								addch('\b');
								if (*sp < ' ')
								    addch('\b');
								clrtoeol();
							}
						}
						else
							addstr(unctrl(*sp++));
						refresh();
					}
					*sp = '\0';
					leaveok(Board, TRUE);
					if ((outf = fopen(buf, "w")) == NULL)
						perror(buf);
					setbuf(outf, 0);
				}
				Debug = !Debug;
				break;
			}
			/* FALLTHROUGH */
		  default:
			error("unknown command: %s", unctrl(c));
			break;
		}
	}
ret:
	leaveok(Board, TRUE);
}
X/*
 * return whether or not the player has picked
 */
haspicked(pp)
reg PLAY	*pp; {

	reg int	card;

	if (Topcard <= Deck)
		return TRUE;
	switch (pp->hand[Card_no]) {
	  case C_GAS_SAFE:	case C_SPARE_SAFE:
	  case C_DRIVE_SAFE:	case C_RIGHT_WAY:
		card = 1;
		break;
	  default:
		card = 0;
		break;
	}
	return (pp->hand[card] != C_INIT);
}

account(card)
reg CARD	card; {

	reg CARD	oppos;

	if (card == C_INIT)
		return;
	++Numseen[card];
	if (Play == COMP)
		switch (card) {
		  case C_GAS_SAFE:
		  case C_SPARE_SAFE:
		  case C_DRIVE_SAFE:
			oppos = opposite(card);
			Numgos += Numcards[oppos] - Numseen[oppos];
			break;
		  case C_CRASH:
		  case C_FLAT:
		  case C_EMPTY:
		  case C_STOP:
			Numgos++;
			break;
		}
}

sort(hand)
reg CARD	*hand;
{
	reg CARD	*cp, *tp;
	reg int		j;
	reg CARD	temp;

	cp = hand;
	hand += HAND_SZ;
	for ( ; cp < &hand[-1]; cp++)
		for (tp = cp + 1; tp < hand; tp++)
			if (*cp > *tp) {
				temp = *cp;
				*cp = *tp;
				*tp = temp;
			}
}
//go.sysin dd *
echo 'x - =test/=mille/print.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/print.c
# include	"mille.h"

# define	COMP_STRT	20
# define	CARD_STRT	2

prboard() {

	reg PLAY	*pp;
	reg int		i, j, k, temp;

	for (k = 0; k < 2; k++) {
		pp = &Player[k];
		temp = k * COMP_STRT + CARD_STRT;
		for (i = 0; i < NUM_SAFE; i++)
			if (pp->safety[i] == S_PLAYED) {
				mvaddstr(i, temp, C_name[i + S_CONV]);
				if (pp->coups[i])
					mvaddch(i, temp - CARD_STRT, '*');
			}
		mvprintw(14, temp, C_fmt, C_name[pp->battle]);
		mvprintw(16, temp, C_fmt, C_name[pp->speed]);
		for (i = C_25; i <= C_200; ) {
			reg char	*name;
			reg int		end;

			name = C_name[i];
			temp = k * 40;
			end = pp->nummiles[i++];
			for (j = 0; j < end; j++)
				mvwaddstr(Miles, i, (j << 2) + temp, name);
		}
	}
	prscore(TRUE);
	temp = CARD_STRT;
	pp = &Player[PLAYER];
	for (i = 0; i < HAND_SZ; i++)
		mvprintw(i + 6, temp, C_fmt, C_name[pp->hand[i]]);
	mvprintw(6, COMP_STRT + CARD_STRT, "%2d", Topcard - Deck);
	mvprintw(8, COMP_STRT + CARD_STRT, C_fmt, C_name[Discard]);
	if (End == 1000) {
		static char	ext[] = "Extension";

		stand(EXT_Y, EXT_X, ext);
	}
	wrefresh(Board);
	wrefresh(Miles);
	wrefresh(Score);
}

X/*
 *	Put str at (y,x) in standout mode
 */
stand(y, x, str)
reg int		y, x;
reg char	*str; {

	standout();
	mvaddstr(y, x, str);
	standend();
	return TRUE;
}

prscore(for_real)
reg bool	for_real; {

	reg PLAY	*pp;
	reg int		x;
	reg char	*Score_fmt = "%4d";

	stdscr = Score;
	for (pp = Player; pp < &Player[2]; pp++) {
		x = (pp - Player) * 6 + 21;
		mvprintw(1, x, Score_fmt, pp->mileage);
		mvprintw(2, x, Score_fmt, pp->safescore);
		if (pp->safescore == 400)
			mvaddstr(3, x + 1, "300");
		else
			mvaddch(3, x + 3, '0');
		mvprintw(4, x, Score_fmt, pp->coupscore);
		if (Window == W_FULL || Finished) {
#ifdef EXTRAP
			if (for_real)
				finalscore(pp);
			else
				extrapolate(pp);
#else
			finalscore(pp);
#endif
			mvprintw(11, x, Score_fmt, pp->hand_tot);
			mvprintw(13, x, Score_fmt, pp->total);
			mvprintw(14, x, Score_fmt, pp->games);
		}
		else {
			mvprintw(6, x, Score_fmt, pp->hand_tot);
			mvprintw(8, x, Score_fmt, pp->total);
			mvprintw(9, x, Score_fmt, pp->games);
		}
	}
	stdscr = Board;
}
//go.sysin dd *
echo 'x - =test/=mille/roll.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/roll.c
X/*
 *	This routine rolls ndie nside-sided dice.
 */

# define	reg	register

# ifndef vax
# define	MAXRAND	32767L

roll(ndie, nsides)
int	ndie, nsides; {

	reg long	tot;
	reg unsigned	n, r;

	tot = 0;
	n = ndie;
	while (n--)
		tot += rand();
	return (int) ((tot * (long) nsides) / ((long) MAXRAND + 1)) + ndie;
}

# else

roll(ndie, nsides)
reg int	ndie, nsides; {

	reg int		tot, r;
	reg double	num_sides;

	num_sides = nsides;
	tot = 0;
	while (ndie--)
		tot += (r = rand()) * (num_sides / 017777777777) + 1;
	return tot;
}
# endif
//go.sysin dd *
echo 'x - =test/=mille/save.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/save.c
#include	"mille.h"
#include	"unctrl.h"
#include	<sys/types.h>
#include	<sys/stat.h>
#include	<time.h>

typedef	struct stat	STAT;
typedef	struct tm	TIME;

char	*ctime();

int	read(), write();

X/*
 *	This routine saves the current game for use at a later date
 */
extern int	errno;
extern char	*sys_errlist[];

save() {

	reg char	*sp;
	reg int		outf;
	reg TIME	*tp;
	char		buf[80];
	TIME		tme;
	STAT		junk;

	tp = &tme;
	if (Fromfile && getyn("Same file? "))
		strcpy(buf, Fromfile);
	else {
over:
		mvaddstr(MOVE_Y, MOVE_X, "file: ");
		clrtoeol();
		leaveok(Board, FALSE);
		refresh();
#ifdef UNDEFINED
		sp = buf;
		while ((*sp = getch()) != '\n') {
			if (*sp == killchar())
				goto over;
			else if (*sp == erasechar()) {
				if (--sp < buf)
					sp = buf;
				else {
					addch('\b');
					/*
					 * if the previous char was a control
					 * char, cover up two characters.
					 */
					if (*sp < ' ')
						addch('\b');
					clrtoeol();
				}
			}
			else
				addstr(unctrl(*sp++));
			refresh();
		}
		*sp = '\0';
#else
		getstr(buf);
#endif
		leaveok(Board, TRUE);
	}

	/*
	 * check for existing files, and confirm overwrite if needed
	 */

	if (sp == buf || (!Fromfile && stat(buf, &junk) > -1
	    && getyn("Overwrite File? ") == FALSE))
		return FALSE;

	if ((outf = creat(buf, 0644)) < 0) {
		error(sys_errlist[errno]);
		return FALSE;
	}
	mvwaddstr(Score, ERR_Y, ERR_X, buf);
	wrefresh(Score);
	time(tp);			/* get current time		*/
	strcpy(buf, ctime(tp));
	for (sp = buf; *sp != '\n'; sp++)
		continue;
	*sp = '\0';
	varpush(outf, write);
	close(outf);
	wprintw(Score, " [%s]", buf);
	wclrtoeol(Score);
	wrefresh(Score);
	return TRUE;
}

X/*
 *	This does the actual restoring.  It returns TRUE if the
 * backup was made on exiting, in which case certain things must
 * be cleaned up before the game starts.
 */
rest_f(file)
reg char	*file; {

	reg char	*sp;
	reg int		inf;
	char		buf[80];
	STAT		sbuf;

	if ((inf = open(file, 0)) < 0) {
		perror(file);
		exit(1);
	}
	if (fstat(inf, &sbuf) < 0) {		/* get file stats	*/
		perror(file);
		exit(1);
	}
	varpush(inf, read);
	close(inf);
	strcpy(buf, ctime(&sbuf.st_mtime));
	for (sp = buf; *sp != '\n'; sp++)
		continue;
	*sp = '\0';
	/*
	 * initialize some necessary values
	 */
	sprintf(Initstr, "%s [%s]\n", file, buf);
	Fromfile = file;
	return !On_exit;
}
//go.sysin dd *
echo 'x - =test/=mille/table.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/table.c
# define	DEBUG
# include	"mille.h"

main() {

	reg int	i, j, count;

	printf("   %16s -> %5s %5s %4s %s\n", "Card", "cards", "count", "need", "opposite");
	for (i = 0; i < NUM_CARDS - 1; i++) {
		for (j = 0, count = 0; j < DECK_SZ; j++)
			if (Deck[j] == i)
				count++;
		printf("%2d %16s -> %5d %5d %4d %s\n", i, C_name[i], Numcards[i], count, Numneed[i], C_name[opposite(i)]);
	}
}
//go.sysin dd *
echo 'x - =test/=mille/types.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/types.c
# include	"mille.h"

isrepair(card)
reg CARD	card; {

	return card == C_GAS || card == C_SPARE || card == C_REPAIRS || card == C_INIT;
}

safety(card)
reg CARD	card; {

	switch (card) {
	  case C_EMPTY:
	  case C_GAS:
	  case C_GAS_SAFE:
		return C_GAS_SAFE;
	  case C_FLAT:
	  case C_SPARE:
	  case C_SPARE_SAFE:
		return C_SPARE_SAFE;
	  case C_CRASH:
	  case C_REPAIRS:
	  case C_DRIVE_SAFE:
		return C_DRIVE_SAFE;
	  case C_GO:
	  case C_STOP:
	  case C_RIGHT_WAY:
	  case C_LIMIT:
	  case C_END_LIMIT:
		return C_RIGHT_WAY;
	}
	/* NOTREACHED */
}
//go.sysin dd *
echo 'x - =test/=mille/unctrl.h'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/unctrl.h
# include	<stdio.h>
# define	unctrl(ch)	(_unctrl[ch])

extern char	*_unctrl[];
//go.sysin dd *
echo 'x - =test/=mille/varpush.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/varpush.c
# include	"mille.h"

int	read(), write();

X/*
 *	push variables around via the routine func() on the file
 * channel file.  func() is either read or write.
 */
varpush(file, func)
reg int	file;
reg int	(*func)(); {

	int	temp;

	(*func)(file, &Debug, sizeof Debug);
	(*func)(file, &Finished, sizeof Finished);
	(*func)(file, &Order, sizeof Order);
	(*func)(file, &End, sizeof End);
	(*func)(file, &On_exit, sizeof On_exit);
	(*func)(file, &Handstart, sizeof Handstart);
	(*func)(file, &Numgos, sizeof Numgos);
	(*func)(file,  Numseen, sizeof Numseen);
	(*func)(file, &Play, sizeof Play);
	(*func)(file, &Window, sizeof Window);
	(*func)(file,  Deck, sizeof Deck);
	(*func)(file, &Discard, sizeof Discard);
	(*func)(file,  Player, sizeof Player);
	if (func == read) {
		read(file, &temp, sizeof temp);
		Topcard = &Deck[temp];
		if (Debug) {
			char	buf[80];
over:
			printf("Debug file:");
			gets(buf);
			if ((outf = fopen(buf, "w")) == NULL) {
				perror(buf);
				goto over;
			}
			if (strcmp(buf, "/dev/null") != 0)
				setbuf(outf, 0);
		}
	}
	else {
		temp = Topcard - Deck;
		write(file, &temp, sizeof temp);
	}
}
//go.sysin dd *
exit