O_SUN changed to mc68000
[unix-history] / usr / src / usr.bin / window / README
CommitLineData
b6b0f513 1@(#)README 3.4 84/05/16
84a5ea18 2
533eb3f8
EW
3Compilation notes:
4
7c38ad4d 5 There is only one compiler option:
84a5ea18
EW
6
7 O_SUN use 68000 byte ordering
84a5ea18 8
7c38ad4d 9 The file local.h contains locally tunable constants.
84a5ea18 10
533eb3f8
EW
11 The makefile should be updated with mkmf. The only library it needs
12is termcap (and jobs for 4.1).
84a5ea18 13
7c38ad4d 14 Window only runs on 4.2 machines.
84a5ea18 15
84a5ea18 16
533eb3f8
EW
17A few notes about the internals:
18
19 The window package. Windows are opened by calling wwopen().
20Wwwrite() is the primitive for writing to windows. Wwputc(), wwputs(),
21and wwprintf() are also supported. Some of the outputs to windows are
22delayed. Wwupdate() updates the terminal to match the internal screen
23buffer. Wwspawn() spawns a child process on the other end of a window,
24with it's environment tailored to the window. Visible windows are
25doubly linked in the order of their overlap. Wwadd() inserts a window
26into the list. Wwdelete() deletes it. Windows not in the list are not
27visible, though wwwrite() still works.
28
29 Most functions return -1 on error. Wwopen() returns the null
30pointer. An error number is saved in wwerrno. Wwerror() returns
31an error message based on wwerrno suitable for printing.
32
33 The terminal drivers perform all output to the physical terminal,
34including special functions like character and line insertion and
35deletion. The window package keeps a list of known terminals. At
36initialization time, the terminal type is matched against the list to
37find the right terminal driver to use. The last driver, the generic
38driver, matches all terminals and uses the termcap database. The
39interface between the window package the terminal driver is the `tt'
40structure. It contains pointers to functions to perform special
41functions and terminal output, as well as flags about the
42characteristics of the terminal.
43
44 The IO system is semi-synchronous. Terminal input is signal driven,
45and everything else is done synchronously with a single select().
46
47 Normally, in both conversation mode and command mode, window sleeps in
48a select() in wwiomux() waiting for data from the pseudo-terminals. At the
49same time, terminal input causes SIGIO which is caught by wwrint(). The
50select() returns when at least one of the pseudo-terminals becomes ready
51for reading.
52
53 Wwrint() is the interrupt handler for tty input. It reads input into
54a linear buffer accessed through four pointers:
55
56 +-------+--------------+----------------+
57 | empty | data | empty |
58 +-------+--------------+----------------+
59 ^ ^ ^ ^
60 | | | |
61 wwib wwibp wwibq wwibe
62
63Wwrint() appends characters at the end and increments wwibq (*wwibq++ = c),
64and characters are taken from the buffer at wwibp using the wwgetc() and
65wwpeekc() macros. As is the convention in C, wwibq and wwibe point to
66one position beyond the end. In addition, wwrint() will do a
67longjmp(wwjmpbuf) if wwsetjmp is true. This is used by wwiomux() to
68interrupt the select() which would otherwise resume after the
69interrupt. The macro wwinterrupt() returns true if the input buffer is
70non-empty. Wwupdate(), wwwrite(), and wwiomux() check this condition
71and will return at the first convenient opportunity when it becomes
72true. In the case of wwwrite(), the flag ww_nointr in the window
73structure overrides this. This feature allows the user to interrupt
74lengthy outputs safely. The structure of the input is carefully
75designed to avoid race conditions without blocking interrupts.
76
77 Wwiomux() copies pseudo-terminal outputs into their corresponding
78windows. Without anything to do, it blocks in a select(), waiting for
79read ready on pseudo-terminals. Reads are done into per-window buffers
80in the window structures. When there is at least one buffer non-empty,
81wwiomux() finds the top most of these windows and writes it using
82wwwrite(). Then the process is repeated. The select() blocks only when
83all of the windows' buffers are empty. The non-blocking select() is
84done only to pick up any output that may have come in during the wwwrite(),
85which may take a long time. A wwupdate() is done prior to calling
86a blocking select(). This is the only time the screen is guaranteed to
87be completely up to date. The pseudo-terminals run in packet mode to
88control output flushing and stopping. Wwiomux() loops until
89wwinterrupt() becomes true.
90
91 The top level routine for all this is mloop(). In conversation mode,
92it simply calls wwiomux(), which only returns when input is available.
93The input buffer is then written to the pseudo-terminal of the current
94window. If the escape character is found in the input, command mode
95is entered. Otherwise, the process is repeated. In command mode,
96control is transferred to docmd() which returns only when conversation
97mode is reentered. Docmd() and other command processing routines
98typically wait for input in a loop:
99
100 while (peekc() < 0)
101 wwiomux();
102
103When the loop terminates, getc() is used to read the input buffer.
104
105 Output to the physical terminal is handled by the lowest level
106routines of the window package, in the files ttoutput.c and tt.h. The
107standard IO package is not used, for better control over buffering and
108to use non-blocking reads in wwrint(). The buffer size is set to
109approximately one second of output time, based on the baudrate.
110
111 The result of all this complexity is faster response time,
112especially in output stopping and flushing. Wwwrite() checks
113wwinterrupt() after every line. It also calls wwupdate() for each line
114it writes. The output buffer is limited to one second of output time.
115Thus, there is usually only a delay of one to two lines plus one second
116after a ^C or ^S. Also, commands that produce lengthy output can be
117aborted without actually showing all of it on the terminal. (Try the
118'h' command followed by escape immediately.)