xref: /csrg-svn/usr.bin/window/README (revision 29718)
1*29718Sedward@(#)README	3.7 08/04/86
215556Sedward
318742Sedward/*
418742Sedward * Copyright (c) 1983 Regents of the University of California,
518742Sedward * All rights reserved.  Redistribution permitted subject to
618742Sedward * the terms of the Berkeley Software License Agreement.
718742Sedward */
818742Sedward
916284SedwardCompilation notes:
1015556Sedward
1116398Sedward     There is only one compiler option:
1216284Sedward
1316535Sedward	mc68000		use 68000 byte ordering
1416535Sedward			It should already be defined in the preprocessor.
1515556Sedward
1616398Sedward     The file local.h contains locally tunable constants.
1715556Sedward
1816284Sedward     The makefile should be updated with mkmf.  The only library it needs
19*29718Sedwardis termcap.
2015556Sedward
21*29718Sedward     Window, as is, only runs on 4.3 machines.
2215556Sedward
23*29718Sedward     On 4.2 machines, at least these modifications must be done:
2415556Sedward
25*29718Sedward	delete uses of window size ioctls: TIOCGWINSZ, TIOCSWINSZ,
26*29718Sedward		struct winsize
27*29718Sedward	add to ww.h
28*29718Sedward		typedef int fd_set;
29*29718Sedward		#define FD_ZERO(s) (*(s) = 0)
30*29718Sedward		#define FD_SET(b, s) (*(s) |= 1 << (b))
31*29718Sedward		#define FD_ISSET(b, s) (*(s) & 1 << (b))
32*29718Sedward	add to ww.h
33*29718Sedward		#define sigmask(s) (1 << (s) - 1)
34*29718Sedward
35*29718Sedward
3616284SedwardA few notes about the internals:
3716284Sedward
3816284Sedward     The window package.  Windows are opened by calling wwopen().
3916284SedwardWwwrite() is the primitive for writing to windows.  Wwputc(), wwputs(),
4016284Sedwardand wwprintf() are also supported.  Some of the outputs to windows are
4116284Sedwarddelayed.  Wwupdate() updates the terminal to match the internal screen
4216284Sedwardbuffer.  Wwspawn() spawns a child process on the other end of a window,
4316284Sedwardwith it's environment tailored to the window.  Visible windows are
4416284Sedwarddoubly linked in the order of their overlap.  Wwadd() inserts a window
4516535Sedwardinto the list at a given place.  Wwdelete() deletes it.  Windows not in
4616535Sedwardthe list are not visible, though wwwrite() still works.
4716284Sedward
4816284Sedward     Most functions return -1 on error.  Wwopen() returns the null
4916535Sedwardpointer.  An error number is saved in wwerrno.  Wwerror() returns an
5016535Sedwarderror string based on wwerrno suitable for printing.
5116284Sedward
5216284Sedward     The terminal drivers perform all output to the physical terminal,
5316284Sedwardincluding special functions like character and line insertion and
5416284Sedwarddeletion.  The window package keeps a list of known terminals.  At
5516284Sedwardinitialization time, the terminal type is matched against the list to
5616284Sedwardfind the right terminal driver to use.  The last driver, the generic
5716284Sedwarddriver, matches all terminals and uses the termcap database.  The
5816284Sedwardinterface between the window package the terminal driver is the `tt'
5916284Sedwardstructure.  It contains pointers to functions to perform special
6016284Sedwardfunctions and terminal output, as well as flags about the
6116284Sedwardcharacteristics of the terminal.
6216284Sedward
6316535Sedward     The IO system is semi-synchronous.  Terminal input is signal
6416535Sedwarddriven, and everything else is done synchronously with a single
6516535Sedwardselect().
6616284Sedward
6716535Sedward     Normally, in both conversation mode and command mode, window
6816535Sedwardsleeps in a select() in wwiomux() waiting for data from the
6916535Sedwardpseudo-terminals.  At the same time, terminal input causes SIGIO which
7016535Sedwardis caught by wwrint().  The select() returns when at least one of the
7116535Sedwardpseudo-terminals becomes ready for reading.
7216284Sedward
7316535Sedward     Wwrint() is the interrupt handler for tty input.  It reads input
7416535Sedwardinto a linear buffer accessed through four pointers:
7516284Sedward
7616284Sedward	+-------+--------------+----------------+
7716284Sedward	| empty |    data      |   empty	|
7816284Sedward	+-------+--------------+----------------+
7916284Sedward	^	^		^		 ^
8016284Sedward	|	|		|		 |
8116284Sedward       wwib    wwibp	       wwibq		wwibe
8216284Sedward
8316535SedwardWwrint() appends characters at the end and increments wwibq (*wwibq++ =
8416535Sedwardc), and characters are taken from the buffer at wwibp using the
8516535Sedwardwwgetc() and wwpeekc() macros.  As is the convention in C, wwibq and
8616535Sedwardwwibe point to one position beyond the end.  In addition, wwrint() will
8716535Sedwarddo a longjmp(wwjmpbuf) if wwsetjmp is true.  This is used by wwiomux()
8816535Sedwardto interrupt the select() which would otherwise resume after the
8916284Sedwardinterrupt.  The macro wwinterrupt() returns true if the input buffer is
9016284Sedwardnon-empty.  Wwupdate(), wwwrite(), and wwiomux() check this condition
9116284Sedwardand will return at the first convenient opportunity when it becomes
9216284Sedwardtrue.  In the case of wwwrite(), the flag ww_nointr in the window
9316284Sedwardstructure overrides this.  This feature allows the user to interrupt
9416535Sedwardlengthy outputs safely.  The structure of the input buffer is designed
9516535Sedwardto avoid race conditions without blocking interrupts.
9616284Sedward
9716284Sedward     Wwiomux() copies pseudo-terminal outputs into their corresponding
9816284Sedwardwindows.  Without anything to do, it blocks in a select(), waiting for
9916284Sedwardread ready on pseudo-terminals.  Reads are done into per-window buffers
10016284Sedwardin the window structures.  When there is at least one buffer non-empty,
10116284Sedwardwwiomux() finds the top most of these windows and writes it using
10216535Sedwardwwwrite().  Then the process is repeated.  A non-blocking select() is
10316535Sedwarddone after a wwwrite() to pick up any output that may have come in
10416535Sedwardduring the write, which may take a long time.  Specifically, we use
10516535Sedwardthis to stop output or flush buffer when a pseudo-terminal tells us to
10616535Sedward(we use pty packet mode).  The select() blocks only when all of the
10716535Sedwardwindows' buffers are empty.  A wwupdate() is done prior to this, which
10816535Sedwardis the only time the screen is guaranteed to be completely up to date.
10916535SedwardWwiomux() loops until wwinterrupt() becomes true.
11016284Sedward
11116535Sedward     The top level routine for all this is mloop().  In conversation
11216535Sedwardmode, it simply calls wwiomux(), which only returns when input is
11316535Sedwardavailable.  The input buffer is then written to the pseudo-terminal of
11416535Sedwardthe current window.  If the escape character is found in the input,
11516535Sedwardcommand mode is entered.  Otherwise, the process is repeated.  In
11616535Sedwardcommand mode, control is transferred to docmd() which returns only when
11716535Sedwardconversation mode is reentered.  Docmd() and other command processing
11816535Sedwardroutines typically wait for input in a loop:
11916284Sedward
12016535Sedward	while (wwpeekc() < 0)
12116284Sedward		wwiomux();
12216284Sedward
12316535SedwardWhen the loop terminates, wwgetc() is used to read the input buffer.
12416284Sedward
12516284Sedward     Output to the physical terminal is handled by the lowest level
12616284Sedwardroutines of the window package, in the files ttoutput.c and tt.h.  The
12716535Sedwardstandard IO package is not used, to get better control over buffering
12816535Sedwardand to use non-blocking reads in wwrint().  The buffer size is set to
12916284Sedwardapproximately one second of output time, based on the baudrate.
13016284Sedward
13116284Sedward     The result of all this complexity is faster response time,
13216284Sedwardespecially in output stopping and flushing.  Wwwrite() checks
13316284Sedwardwwinterrupt() after every line.  It also calls wwupdate() for each line
13416284Sedwardit writes.  The output buffer is limited to one second of output time.
13516284SedwardThus, there is usually only a delay of one to two lines plus one second
13616284Sedwardafter a ^C or ^S.  Also, commands that produce lengthy output can be
13716284Sedwardaborted without actually showing all of it on the terminal.  (Try the
13816535Sedward'?' command followed by escape immediately.)
139