xref: /csrg-svn/usr.bin/window/README (revision 16535)
1*16535Sedward@(#)README	3.4 84/05/23
215556Sedward
316284SedwardCompilation notes:
415556Sedward
516398Sedward     There is only one compiler option:
616284Sedward
7*16535Sedward	mc68000		use 68000 byte ordering
8*16535Sedward			It should already be defined in the preprocessor.
915556Sedward
1016398Sedward     The file local.h contains locally tunable constants.
1115556Sedward
1216284Sedward     The makefile should be updated with mkmf.  The only library it needs
1316284Sedwardis termcap (and jobs for 4.1).
1415556Sedward
1516398Sedward     Window only runs on 4.2 machines.
1615556Sedward
1715556Sedward
1816284SedwardA few notes about the internals:
1916284Sedward
2016284Sedward     The window package.  Windows are opened by calling wwopen().
2116284SedwardWwwrite() is the primitive for writing to windows.  Wwputc(), wwputs(),
2216284Sedwardand wwprintf() are also supported.  Some of the outputs to windows are
2316284Sedwarddelayed.  Wwupdate() updates the terminal to match the internal screen
2416284Sedwardbuffer.  Wwspawn() spawns a child process on the other end of a window,
2516284Sedwardwith it's environment tailored to the window.  Visible windows are
2616284Sedwarddoubly linked in the order of their overlap.  Wwadd() inserts a window
27*16535Sedwardinto the list at a given place.  Wwdelete() deletes it.  Windows not in
28*16535Sedwardthe list are not visible, though wwwrite() still works.
2916284Sedward
3016284Sedward     Most functions return -1 on error.  Wwopen() returns the null
31*16535Sedwardpointer.  An error number is saved in wwerrno.  Wwerror() returns an
32*16535Sedwarderror string based on wwerrno suitable for printing.
3316284Sedward
3416284Sedward     The terminal drivers perform all output to the physical terminal,
3516284Sedwardincluding special functions like character and line insertion and
3616284Sedwarddeletion.  The window package keeps a list of known terminals.  At
3716284Sedwardinitialization time, the terminal type is matched against the list to
3816284Sedwardfind the right terminal driver to use.  The last driver, the generic
3916284Sedwarddriver, matches all terminals and uses the termcap database.  The
4016284Sedwardinterface between the window package the terminal driver is the `tt'
4116284Sedwardstructure.  It contains pointers to functions to perform special
4216284Sedwardfunctions and terminal output, as well as flags about the
4316284Sedwardcharacteristics of the terminal.
4416284Sedward
45*16535Sedward     The IO system is semi-synchronous.  Terminal input is signal
46*16535Sedwarddriven, and everything else is done synchronously with a single
47*16535Sedwardselect().
4816284Sedward
49*16535Sedward     Normally, in both conversation mode and command mode, window
50*16535Sedwardsleeps in a select() in wwiomux() waiting for data from the
51*16535Sedwardpseudo-terminals.  At the same time, terminal input causes SIGIO which
52*16535Sedwardis caught by wwrint().  The select() returns when at least one of the
53*16535Sedwardpseudo-terminals becomes ready for reading.
5416284Sedward
55*16535Sedward     Wwrint() is the interrupt handler for tty input.  It reads input
56*16535Sedwardinto a linear buffer accessed through four pointers:
5716284Sedward
5816284Sedward	+-------+--------------+----------------+
5916284Sedward	| empty |    data      |   empty	|
6016284Sedward	+-------+--------------+----------------+
6116284Sedward	^	^		^		 ^
6216284Sedward	|	|		|		 |
6316284Sedward       wwib    wwibp	       wwibq		wwibe
6416284Sedward
65*16535SedwardWwrint() appends characters at the end and increments wwibq (*wwibq++ =
66*16535Sedwardc), and characters are taken from the buffer at wwibp using the
67*16535Sedwardwwgetc() and wwpeekc() macros.  As is the convention in C, wwibq and
68*16535Sedwardwwibe point to one position beyond the end.  In addition, wwrint() will
69*16535Sedwarddo a longjmp(wwjmpbuf) if wwsetjmp is true.  This is used by wwiomux()
70*16535Sedwardto interrupt the select() which would otherwise resume after the
7116284Sedwardinterrupt.  The macro wwinterrupt() returns true if the input buffer is
7216284Sedwardnon-empty.  Wwupdate(), wwwrite(), and wwiomux() check this condition
7316284Sedwardand will return at the first convenient opportunity when it becomes
7416284Sedwardtrue.  In the case of wwwrite(), the flag ww_nointr in the window
7516284Sedwardstructure overrides this.  This feature allows the user to interrupt
76*16535Sedwardlengthy outputs safely.  The structure of the input buffer is designed
77*16535Sedwardto avoid race conditions without blocking interrupts.
7816284Sedward
7916284Sedward     Wwiomux() copies pseudo-terminal outputs into their corresponding
8016284Sedwardwindows.  Without anything to do, it blocks in a select(), waiting for
8116284Sedwardread ready on pseudo-terminals.  Reads are done into per-window buffers
8216284Sedwardin the window structures.  When there is at least one buffer non-empty,
8316284Sedwardwwiomux() finds the top most of these windows and writes it using
84*16535Sedwardwwwrite().  Then the process is repeated.  A non-blocking select() is
85*16535Sedwarddone after a wwwrite() to pick up any output that may have come in
86*16535Sedwardduring the write, which may take a long time.  Specifically, we use
87*16535Sedwardthis to stop output or flush buffer when a pseudo-terminal tells us to
88*16535Sedward(we use pty packet mode).  The select() blocks only when all of the
89*16535Sedwardwindows' buffers are empty.  A wwupdate() is done prior to this, which
90*16535Sedwardis the only time the screen is guaranteed to be completely up to date.
91*16535SedwardWwiomux() loops until wwinterrupt() becomes true.
9216284Sedward
93*16535Sedward     The top level routine for all this is mloop().  In conversation
94*16535Sedwardmode, it simply calls wwiomux(), which only returns when input is
95*16535Sedwardavailable.  The input buffer is then written to the pseudo-terminal of
96*16535Sedwardthe current window.  If the escape character is found in the input,
97*16535Sedwardcommand mode is entered.  Otherwise, the process is repeated.  In
98*16535Sedwardcommand mode, control is transferred to docmd() which returns only when
99*16535Sedwardconversation mode is reentered.  Docmd() and other command processing
100*16535Sedwardroutines typically wait for input in a loop:
10116284Sedward
102*16535Sedward	while (wwpeekc() < 0)
10316284Sedward		wwiomux();
10416284Sedward
105*16535SedwardWhen the loop terminates, wwgetc() is used to read the input buffer.
10616284Sedward
10716284Sedward     Output to the physical terminal is handled by the lowest level
10816284Sedwardroutines of the window package, in the files ttoutput.c and tt.h.  The
109*16535Sedwardstandard IO package is not used, to get better control over buffering
110*16535Sedwardand to use non-blocking reads in wwrint().  The buffer size is set to
11116284Sedwardapproximately one second of output time, based on the baudrate.
11216284Sedward
11316284Sedward     The result of all this complexity is faster response time,
11416284Sedwardespecially in output stopping and flushing.  Wwwrite() checks
11516284Sedwardwwinterrupt() after every line.  It also calls wwupdate() for each line
11616284Sedwardit writes.  The output buffer is limited to one second of output time.
11716284SedwardThus, there is usually only a delay of one to two lines plus one second
11816284Sedwardafter a ^C or ^S.  Also, commands that produce lengthy output can be
11916284Sedwardaborted without actually showing all of it on the terminal.  (Try the
120*16535Sedward'?' command followed by escape immediately.)
121