xref: /csrg-svn/usr.bin/window/README (revision 62451)
142954Sbostic/*-
262450Sbostic * Copyright (c) 1990, 1993
362450Sbostic *	The Regents of the University of California.  All rights reserved.
433514Sbostic *
542954Sbostic * This code is derived from software contributed to Berkeley by
642954Sbostic *  Edward Wang at The University of California, Berkeley.
733514Sbostic *
842954Sbostic * %sccs.include.redist.c%
942954Sbostic *
10*62451Sbostic *	@(#)README	8.1 (Berkeley) 06/06/93
1118742Sedward */
1218742Sedward
1316284SedwardCompilation notes:
1415556Sedward
1556709Sedward     Compiler options:
1616284Sedward
1736258Sedward	BYTE_ORDER (used only in ww.h)
1836258Sedward		It should already be defined in machine/endian.h.
1936258Sedward		The code knows about BIG_ENDIAN, LITTLE_ENDIAN, and PDP_ENDIAN.
2036258Sedward		It only cares about byte order in words, so PDP_ENDIAN
2136258Sedward		is the same as LITTLE_ENDIAN.
2256709Sedward	OLD_TTY
2356709Sedward		If you don't have Posix termios, then define this.
2456709Sedward	VMIN_BUG
2556709Sedward		Even if you have Posix termios, define this if the MIN and TIME
2656709Sedward		feature in noncanonical mode doesn't work correctly.
2715556Sedward
2832343Sedward     Ok, there's another one, STR_DEBUG.  It turns on consistency checks
2932343Sedward     in the string allocator.  It's been left on since performace doesn't
3032343Sedward     seem to suffer.  There's an abort() somewhere when an inconsistency
3132343Sedward     is found.  It hasn't happened in years.
3232343Sedward
3316398Sedward     The file local.h contains locally tunable constants.
3415556Sedward
3532343Sedward     The makefile used to be updated with mkmf; it has been changed
3632343Sedwardat various times to use cpp -M and, currently, mkdep.  The only library
3732343Sedwardit needs is termcap.
3815556Sedward
3956709Sedward     Window, as is, only runs on 4.3 (or later) machines.
4015556Sedward
4129718Sedward     On 4.2 machines, at least these modifications must be done:
4215556Sedward
4329718Sedward	delete uses of window size ioctls: TIOCGWINSZ, TIOCSWINSZ,
4429718Sedward		struct winsize
4529718Sedward	add to ww.h
4629718Sedward		typedef int fd_set;
4729718Sedward		#define FD_ZERO(s) (*(s) = 0)
4829718Sedward		#define FD_SET(b, s) (*(s) |= 1 << (b))
4929718Sedward		#define FD_ISSET(b, s) (*(s) & 1 << (b))
5029718Sedward	add to ww.h
5129718Sedward		#define sigmask(s) (1 << (s) - 1)
5229718Sedward
5329718Sedward
5416284SedwardA few notes about the internals:
5516284Sedward
5616284Sedward     The window package.  Windows are opened by calling wwopen().
5716284SedwardWwwrite() is the primitive for writing to windows.  Wwputc(), wwputs(),
5816284Sedwardand wwprintf() are also supported.  Some of the outputs to windows are
5916284Sedwarddelayed.  Wwupdate() updates the terminal to match the internal screen
6016284Sedwardbuffer.  Wwspawn() spawns a child process on the other end of a window,
6132343Sedwardwith its environment tailored to the window.  Visible windows are
6216284Sedwarddoubly linked in the order of their overlap.  Wwadd() inserts a window
6316535Sedwardinto the list at a given place.  Wwdelete() deletes it.  Windows not in
6432343Sedwardthe list are not visible, though wwwrite() still works.  Window was
6532343Sedwardwritten before the days of X and Sunview, so some of the terminology
6632343Sedwardis not standard.
6716284Sedward
6816284Sedward     Most functions return -1 on error.  Wwopen() returns the null
6916535Sedwardpointer.  An error number is saved in wwerrno.  Wwerror() returns an
7016535Sedwarderror string based on wwerrno suitable for printing.
7116284Sedward
7216284Sedward     The terminal drivers perform all output to the physical terminal,
7316284Sedwardincluding special functions like character and line insertion and
7416284Sedwarddeletion.  The window package keeps a list of known terminals.  At
7516284Sedwardinitialization time, the terminal type is matched against the list to
7616284Sedwardfind the right terminal driver to use.  The last driver, the generic
7716284Sedwarddriver, matches all terminals and uses the termcap database.  The
7816284Sedwardinterface between the window package the terminal driver is the `tt'
7916284Sedwardstructure.  It contains pointers to functions to perform special
8016284Sedwardfunctions and terminal output, as well as flags about the
8132343Sedwardcharacteristics of the terminal.  Most of these ideas are borrowed
8232343Sedwardfrom the Maryland window package, which in turn is based on Goslin's
8332343SedwardEmacs.
8416284Sedward
8516535Sedward     The IO system is semi-synchronous.  Terminal input is signal
8616535Sedwarddriven, and everything else is done synchronously with a single
8732343Sedwardselect().  It is roughly event-driven, though not in a clean way.
8816284Sedward
8916535Sedward     Normally, in both conversation mode and command mode, window
9016535Sedwardsleeps in a select() in wwiomux() waiting for data from the
9116535Sedwardpseudo-terminals.  At the same time, terminal input causes SIGIO which
9216535Sedwardis caught by wwrint().  The select() returns when at least one of the
9316535Sedwardpseudo-terminals becomes ready for reading.
9416284Sedward
9516535Sedward     Wwrint() is the interrupt handler for tty input.  It reads input
9616535Sedwardinto a linear buffer accessed through four pointers:
9716284Sedward
9816284Sedward	+-------+--------------+----------------+
9916284Sedward	| empty |    data      |   empty	|
10016284Sedward	+-------+--------------+----------------+
10116284Sedward	^	^		^		 ^
10216284Sedward	|	|		|		 |
10316284Sedward       wwib    wwibp	       wwibq		wwibe
10416284Sedward
10532343SedwardWwrint() appends characters at the end and increments wwibq (*wwibq++
10632343Sedward= c), and characters are taken off the buffer at wwibp using the
10732343Sedwardwwgetc() and wwpeekc() macros.  As is the convention in C, wwibq
10832343Sedwardand wwibe point to one position beyond the end.  In addition,
10932343Sedwardwwrint() will do a longjmp(wwjmpbuf) if wwsetjmp is true.  This is
11032343Sedwardused by wwiomux() to interrupt the select() which would otherwise
11132343Sedwardresume after the interrupt.  (Actually, I hear this is not true,
11232343Sedwardbut the longjmp feature is used to avoid a race condition as well.
11332343SedwardAnyway, it means I didn't have to depend on a feature in a
11432343Sedwarddaily-changing kernel, but that's another story.) The macro
11532343Sedwardwwinterrupt() returns true if the input buffer is non-empty.
11632343SedwardWwupdate(), wwwrite(), and wwiomux() check this condition and will
11732343Sedwardreturn at the first convenient opportunity when it becomes true.
11832343SedwardIn the case of wwwrite(), the flag ww_nointr in the window structure
11932343Sedwardoverrides this.  This feature allows the user to interrupt lengthy
12032343Sedwardoutputs safely.  The structure of the input buffer is designed to
12132343Sedwardavoid race conditions without blocking interrupts.
12216284Sedward
12332343Sedward     Actually, wwsetjmp and wwinterrupt() are part of a software
12432343Sedwardinterrupt scheme used by the two interrupt catchers wwrint() and
12532343Sedwardwwchild().  Asserting the interrupt lets the synchronous parts of
12632343Sedwardthe program know that there's an interesting asynchronous condition
12732343Sedward(i.e., got a keyboard character, or a child process died) that they
12832343Sedwardmight want to process before anything else.  The synchronous routines
12932343Sedwardcan check for this condition with wwinterrupt() or by arranging
13032343Sedwardthat a longjmp() be done.
13132343Sedward
13232343Sedward     Wwiomux() copies pseudo-terminal output into their corresponding
13316284Sedwardwindows.  Without anything to do, it blocks in a select(), waiting for
13416284Sedwardread ready on pseudo-terminals.  Reads are done into per-window buffers
13516284Sedwardin the window structures.  When there is at least one buffer non-empty,
13616284Sedwardwwiomux() finds the top most of these windows and writes it using
13716535Sedwardwwwrite().  Then the process is repeated.  A non-blocking select() is
13816535Sedwarddone after a wwwrite() to pick up any output that may have come in
13916535Sedwardduring the write, which may take a long time.  Specifically, we use
14016535Sedwardthis to stop output or flush buffer when a pseudo-terminal tells us to
14116535Sedward(we use pty packet mode).  The select() blocks only when all of the
14216535Sedwardwindows' buffers are empty.  A wwupdate() is done prior to this, which
14316535Sedwardis the only time the screen is guaranteed to be completely up to date.
14416535SedwardWwiomux() loops until wwinterrupt() becomes true.
14516284Sedward
14616535Sedward     The top level routine for all this is mloop().  In conversation
14716535Sedwardmode, it simply calls wwiomux(), which only returns when input is
14816535Sedwardavailable.  The input buffer is then written to the pseudo-terminal of
14916535Sedwardthe current window.  If the escape character is found in the input,
15016535Sedwardcommand mode is entered.  Otherwise, the process is repeated.  In
15116535Sedwardcommand mode, control is transferred to docmd() which returns only when
15216535Sedwardconversation mode is reentered.  Docmd() and other command processing
15316535Sedwardroutines typically wait for input in a loop:
15416284Sedward
15516535Sedward	while (wwpeekc() < 0)
15616284Sedward		wwiomux();
15716284Sedward
15816535SedwardWhen the loop terminates, wwgetc() is used to read the input buffer.
15916284Sedward
16016284Sedward     Output to the physical terminal is handled by the lowest level
16116284Sedwardroutines of the window package, in the files ttoutput.c and tt.h.  The
16216535Sedwardstandard IO package is not used, to get better control over buffering
16316535Sedwardand to use non-blocking reads in wwrint().  The buffer size is set to
16416284Sedwardapproximately one second of output time, based on the baudrate.
16516284Sedward
16616284Sedward     The result of all this complexity is faster response time,
16716284Sedwardespecially in output stopping and flushing.  Wwwrite() checks
16816284Sedwardwwinterrupt() after every line.  It also calls wwupdate() for each line
16916284Sedwardit writes.  The output buffer is limited to one second of output time.
17016284SedwardThus, there is usually only a delay of one to two lines plus one second
17116284Sedwardafter a ^C or ^S.  Also, commands that produce lengthy output can be
17216284Sedwardaborted without actually showing all of it on the terminal.  (Try the
17316535Sedward'?' command followed by escape immediately.)
174