xref: /csrg-svn/usr.bin/window/README (revision 16398)
1*16398Sedward@(#)README	3.3 84/04/16
215556Sedward
316284SedwardCompilation notes:
415556Sedward
5*16398Sedward     There is only one compiler option:
616284Sedward
715556Sedward	O_SUN		use 68000 byte ordering
815556Sedward
9*16398Sedward     The file local.h contains locally tunable constants.
1015556Sedward
1116284Sedward     The makefile should be updated with mkmf.  The only library it needs
1216284Sedwardis termcap (and jobs for 4.1).
1315556Sedward
14*16398Sedward     Window only runs on 4.2 machines.
1515556Sedward
1615556Sedward
1716284SedwardA few notes about the internals:
1816284Sedward
1916284Sedward     The window package.  Windows are opened by calling wwopen().
2016284SedwardWwwrite() is the primitive for writing to windows.  Wwputc(), wwputs(),
2116284Sedwardand wwprintf() are also supported.  Some of the outputs to windows are
2216284Sedwarddelayed.  Wwupdate() updates the terminal to match the internal screen
2316284Sedwardbuffer.  Wwspawn() spawns a child process on the other end of a window,
2416284Sedwardwith it's environment tailored to the window.  Visible windows are
2516284Sedwarddoubly linked in the order of their overlap.  Wwadd() inserts a window
2616284Sedwardinto the list.  Wwdelete() deletes it.  Windows not in the list are not
2716284Sedwardvisible, though wwwrite() still works.
2816284Sedward
2916284Sedward     Most functions return -1 on error.  Wwopen() returns the null
3016284Sedwardpointer.  An error number is saved in wwerrno.  Wwerror() returns
3116284Sedwardan error message based on wwerrno suitable for printing.
3216284Sedward
3316284Sedward     The terminal drivers perform all output to the physical terminal,
3416284Sedwardincluding special functions like character and line insertion and
3516284Sedwarddeletion.  The window package keeps a list of known terminals.  At
3616284Sedwardinitialization time, the terminal type is matched against the list to
3716284Sedwardfind the right terminal driver to use.  The last driver, the generic
3816284Sedwarddriver, matches all terminals and uses the termcap database.  The
3916284Sedwardinterface between the window package the terminal driver is the `tt'
4016284Sedwardstructure.  It contains pointers to functions to perform special
4116284Sedwardfunctions and terminal output, as well as flags about the
4216284Sedwardcharacteristics of the terminal.
4316284Sedward
4416284Sedward     The IO system is semi-synchronous.  Terminal input is signal driven,
4516284Sedwardand everything else is done synchronously with a single select().
4616284Sedward
4716284Sedward     Normally, in both conversation mode and command mode, window sleeps in
4816284Sedwarda select() in wwiomux() waiting for data from the pseudo-terminals.  At the
4916284Sedwardsame time, terminal input causes SIGIO which is caught by wwrint().  The
5016284Sedwardselect() returns when at least one of the pseudo-terminals becomes ready
5116284Sedwardfor reading.
5216284Sedward
5316284Sedward     Wwrint() is the interrupt handler for tty input.  It reads input into
5416284Sedwarda linear buffer accessed through four pointers:
5516284Sedward
5616284Sedward	+-------+--------------+----------------+
5716284Sedward	| empty |    data      |   empty	|
5816284Sedward	+-------+--------------+----------------+
5916284Sedward	^	^		^		 ^
6016284Sedward	|	|		|		 |
6116284Sedward       wwib    wwibp	       wwibq		wwibe
6216284Sedward
6316284SedwardWwrint() appends characters at the end and increments wwibq (*wwibq++ = c),
6416284Sedwardand characters are taken from the buffer at wwibp using the wwgetc() and
6516284Sedwardwwpeekc() macros.  As is the convention in C, wwibq and wwibe point to
6616284Sedwardone position beyond the end.  In addition, wwrint() will do a
6716284Sedwardlongjmp(wwjmpbuf) if wwsetjmp is true.  This is used by wwiomux() to
6816284Sedwardinterrupt the select() which would otherwise resume after the
6916284Sedwardinterrupt.  The macro wwinterrupt() returns true if the input buffer is
7016284Sedwardnon-empty.  Wwupdate(), wwwrite(), and wwiomux() check this condition
7116284Sedwardand will return at the first convenient opportunity when it becomes
7216284Sedwardtrue.  In the case of wwwrite(), the flag ww_nointr in the window
7316284Sedwardstructure overrides this.  This feature allows the user to interrupt
7416284Sedwardlengthy outputs safely.  The structure of the input is carefully
7516284Sedwarddesigned to avoid race conditions without blocking interrupts.
7616284Sedward
7716284Sedward     Wwiomux() copies pseudo-terminal outputs into their corresponding
7816284Sedwardwindows.  Without anything to do, it blocks in a select(), waiting for
7916284Sedwardread ready on pseudo-terminals.  Reads are done into per-window buffers
8016284Sedwardin the window structures.  When there is at least one buffer non-empty,
8116284Sedwardwwiomux() finds the top most of these windows and writes it using
8216284Sedwardwwwrite().  Then the process is repeated.  The select() blocks only when
8316284Sedwardall of the windows' buffers are empty.  The non-blocking select() is
8416284Sedwarddone only to pick up any output that may have come in during the wwwrite(),
8516284Sedwardwhich may take a long time.  A wwupdate() is done prior to calling
8616284Sedwarda blocking select().  This is the only time the screen is guaranteed to
8716284Sedwardbe completely up to date.  The pseudo-terminals run in packet mode to
8816284Sedwardcontrol output flushing and stopping.  Wwiomux() loops until
8916284Sedwardwwinterrupt() becomes true.
9016284Sedward
9116284Sedward     The top level routine for all this is mloop().  In conversation mode,
9216284Sedwardit simply calls wwiomux(), which only returns when input is available.
9316284SedwardThe input buffer is then written to the pseudo-terminal of the current
9416284Sedwardwindow.  If the escape character is found in the input, command mode
9516284Sedwardis entered.  Otherwise, the process is repeated.  In command mode,
9616284Sedwardcontrol is transferred to docmd() which returns only when conversation
9716284Sedwardmode is reentered.  Docmd() and other command processing routines
9816284Sedwardtypically wait for input in a loop:
9916284Sedward
10016284Sedward	while (peekc() < 0)
10116284Sedward		wwiomux();
10216284Sedward
10316284SedwardWhen the loop terminates, getc() is used to read the input buffer.
10416284Sedward
10516284Sedward     Output to the physical terminal is handled by the lowest level
10616284Sedwardroutines of the window package, in the files ttoutput.c and tt.h.  The
10716284Sedwardstandard IO package is not used, for better control over buffering and
10816284Sedwardto use non-blocking reads in wwrint().  The buffer size is set to
10916284Sedwardapproximately one second of output time, based on the baudrate.
11016284Sedward
11116284Sedward     The result of all this complexity is faster response time,
11216284Sedwardespecially in output stopping and flushing.  Wwwrite() checks
11316284Sedwardwwinterrupt() after every line.  It also calls wwupdate() for each line
11416284Sedwardit writes.  The output buffer is limited to one second of output time.
11516284SedwardThus, there is usually only a delay of one to two lines plus one second
11616284Sedwardafter a ^C or ^S.  Also, commands that produce lengthy output can be
11716284Sedwardaborted without actually showing all of it on the terminal.  (Try the
11816284Sedward'h' command followed by escape immediately.)
119