xref: /csrg-svn/usr.bin/window/README (revision 16284)
1*16284Sedward@(#)README	3.2 84/04/05
215556Sedward
3*16284SedwardCompilation notes:
415556Sedward
5*16284Sedward     The flags:
6*16284Sedward
715556Sedward	O_SUN		use 68000 byte ordering
815556Sedward	O_4_1C		4.1c
915556Sedward	O_4_1A		4.1a
1015556Sedward
11*16284Sedward     4.2bsd on a vax needs no flags.  Some systems will need the jobs library.
12*16284Sedward4.1a does not support the 't' command.
1315556Sedward
14*16284Sedward     The makefile should be updated with mkmf.  The only library it needs
15*16284Sedwardis termcap (and jobs for 4.1).
1615556Sedward
17*16284Sedward     Do not profile on 4.1.  A bug in the system causes profiling
18*16284Sedwardto stay on after an exec.
1915556Sedward
2015556Sedward
21*16284SedwardA few notes about the internals:
22*16284Sedward
23*16284Sedward     The window package.  Windows are opened by calling wwopen().
24*16284SedwardWwwrite() is the primitive for writing to windows.  Wwputc(), wwputs(),
25*16284Sedwardand wwprintf() are also supported.  Some of the outputs to windows are
26*16284Sedwarddelayed.  Wwupdate() updates the terminal to match the internal screen
27*16284Sedwardbuffer.  Wwspawn() spawns a child process on the other end of a window,
28*16284Sedwardwith it's environment tailored to the window.  Visible windows are
29*16284Sedwarddoubly linked in the order of their overlap.  Wwadd() inserts a window
30*16284Sedwardinto the list.  Wwdelete() deletes it.  Windows not in the list are not
31*16284Sedwardvisible, though wwwrite() still works.
32*16284Sedward
33*16284Sedward     Most functions return -1 on error.  Wwopen() returns the null
34*16284Sedwardpointer.  An error number is saved in wwerrno.  Wwerror() returns
35*16284Sedwardan error message based on wwerrno suitable for printing.
36*16284Sedward
37*16284Sedward     The terminal drivers perform all output to the physical terminal,
38*16284Sedwardincluding special functions like character and line insertion and
39*16284Sedwarddeletion.  The window package keeps a list of known terminals.  At
40*16284Sedwardinitialization time, the terminal type is matched against the list to
41*16284Sedwardfind the right terminal driver to use.  The last driver, the generic
42*16284Sedwarddriver, matches all terminals and uses the termcap database.  The
43*16284Sedwardinterface between the window package the terminal driver is the `tt'
44*16284Sedwardstructure.  It contains pointers to functions to perform special
45*16284Sedwardfunctions and terminal output, as well as flags about the
46*16284Sedwardcharacteristics of the terminal.
47*16284Sedward
48*16284Sedward     The IO system is semi-synchronous.  Terminal input is signal driven,
49*16284Sedwardand everything else is done synchronously with a single select().
50*16284Sedward
51*16284Sedward     Normally, in both conversation mode and command mode, window sleeps in
52*16284Sedwarda select() in wwiomux() waiting for data from the pseudo-terminals.  At the
53*16284Sedwardsame time, terminal input causes SIGIO which is caught by wwrint().  The
54*16284Sedwardselect() returns when at least one of the pseudo-terminals becomes ready
55*16284Sedwardfor reading.
56*16284Sedward
57*16284Sedward     Wwrint() is the interrupt handler for tty input.  It reads input into
58*16284Sedwarda linear buffer accessed through four pointers:
59*16284Sedward
60*16284Sedward	+-------+--------------+----------------+
61*16284Sedward	| empty |    data      |   empty	|
62*16284Sedward	+-------+--------------+----------------+
63*16284Sedward	^	^		^		 ^
64*16284Sedward	|	|		|		 |
65*16284Sedward       wwib    wwibp	       wwibq		wwibe
66*16284Sedward
67*16284SedwardWwrint() appends characters at the end and increments wwibq (*wwibq++ = c),
68*16284Sedwardand characters are taken from the buffer at wwibp using the wwgetc() and
69*16284Sedwardwwpeekc() macros.  As is the convention in C, wwibq and wwibe point to
70*16284Sedwardone position beyond the end.  In addition, wwrint() will do a
71*16284Sedwardlongjmp(wwjmpbuf) if wwsetjmp is true.  This is used by wwiomux() to
72*16284Sedwardinterrupt the select() which would otherwise resume after the
73*16284Sedwardinterrupt.  The macro wwinterrupt() returns true if the input buffer is
74*16284Sedwardnon-empty.  Wwupdate(), wwwrite(), and wwiomux() check this condition
75*16284Sedwardand will return at the first convenient opportunity when it becomes
76*16284Sedwardtrue.  In the case of wwwrite(), the flag ww_nointr in the window
77*16284Sedwardstructure overrides this.  This feature allows the user to interrupt
78*16284Sedwardlengthy outputs safely.  The structure of the input is carefully
79*16284Sedwarddesigned to avoid race conditions without blocking interrupts.
80*16284Sedward
81*16284Sedward     Wwiomux() copies pseudo-terminal outputs into their corresponding
82*16284Sedwardwindows.  Without anything to do, it blocks in a select(), waiting for
83*16284Sedwardread ready on pseudo-terminals.  Reads are done into per-window buffers
84*16284Sedwardin the window structures.  When there is at least one buffer non-empty,
85*16284Sedwardwwiomux() finds the top most of these windows and writes it using
86*16284Sedwardwwwrite().  Then the process is repeated.  The select() blocks only when
87*16284Sedwardall of the windows' buffers are empty.  The non-blocking select() is
88*16284Sedwarddone only to pick up any output that may have come in during the wwwrite(),
89*16284Sedwardwhich may take a long time.  A wwupdate() is done prior to calling
90*16284Sedwarda blocking select().  This is the only time the screen is guaranteed to
91*16284Sedwardbe completely up to date.  The pseudo-terminals run in packet mode to
92*16284Sedwardcontrol output flushing and stopping.  Wwiomux() loops until
93*16284Sedwardwwinterrupt() becomes true.
94*16284Sedward
95*16284Sedward     The top level routine for all this is mloop().  In conversation mode,
96*16284Sedwardit simply calls wwiomux(), which only returns when input is available.
97*16284SedwardThe input buffer is then written to the pseudo-terminal of the current
98*16284Sedwardwindow.  If the escape character is found in the input, command mode
99*16284Sedwardis entered.  Otherwise, the process is repeated.  In command mode,
100*16284Sedwardcontrol is transferred to docmd() which returns only when conversation
101*16284Sedwardmode is reentered.  Docmd() and other command processing routines
102*16284Sedwardtypically wait for input in a loop:
103*16284Sedward
104*16284Sedward	while (peekc() < 0)
105*16284Sedward		wwiomux();
106*16284Sedward
107*16284SedwardWhen the loop terminates, getc() is used to read the input buffer.
108*16284Sedward
109*16284Sedward     Output to the physical terminal is handled by the lowest level
110*16284Sedwardroutines of the window package, in the files ttoutput.c and tt.h.  The
111*16284Sedwardstandard IO package is not used, for better control over buffering and
112*16284Sedwardto use non-blocking reads in wwrint().  The buffer size is set to
113*16284Sedwardapproximately one second of output time, based on the baudrate.
114*16284Sedward
115*16284Sedward     The result of all this complexity is faster response time,
116*16284Sedwardespecially in output stopping and flushing.  Wwwrite() checks
117*16284Sedwardwwinterrupt() after every line.  It also calls wwupdate() for each line
118*16284Sedwardit writes.  The output buffer is limited to one second of output time.
119*16284SedwardThus, there is usually only a delay of one to two lines plus one second
120*16284Sedwardafter a ^C or ^S.  Also, commands that produce lengthy output can be
121*16284Sedwardaborted without actually showing all of it on the terminal.  (Try the
122*16284Sedward'h' command followed by escape immediately.)
123