add IP type-of-service without gettos (at least for now)
[unix-history] / usr / src / usr.bin / window / win.c
CommitLineData
60de5df9 1/*
46e9ea25
KB
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
3dd3a9e5
KB
5 * This code is derived from software contributed to Berkeley by
6 * Edward Wang at The University of California, Berkeley.
7 *
87f529ec 8 * %sccs.include.redist.c%
60de5df9
EW
9 */
10
46e9ea25 11#ifndef lint
3dd3a9e5 12static char sccsid[] = "@(#)win.c 3.24 (Berkeley) %G%";
46e9ea25
KB
13#endif /* not lint */
14
b6b63f20 15#include "defs.h"
0e64e422 16#include "char.h"
bbbb7b14
EW
17#ifdef POSIX_TTY
18#include <sys/ioctl.h>
19#endif
b6b63f20
EW
20
21/*
e1dba5dd
EW
22 * Higher level routines for dealing with windows.
23 *
24 * There are two types of windows: user window, and information window.
25 * User windows are the ones with a pty and shell. Information windows
26 * are for displaying error messages, and other information.
27 *
d7c2cbb0
EW
28 * The windows are doubly linked in overlapping order and divided into
29 * two groups: foreground and normal. Information
30 * windows are always foreground. User windows can be either.
31 * Addwin() adds a window to the list at the top of one of the two groups.
e1dba5dd 32 * Deletewin() deletes a window. Front() moves a window to the front
d7c2cbb0 33 * of its group. Wwopen(), wwadd(), and wwdelete() should never be called
e1dba5dd 34 * directly.
b6b63f20
EW
35 */
36
37/*
38 * Open a user window.
39 */
40struct ww *
7ecf4dca 41openwin(id, row, col, nrow, ncol, nline, label, haspty, hasframe, shf, sh)
b6b63f20 42char *label;
7ecf4dca
EW
43char haspty, hasframe;
44char *shf, **sh;
b6b63f20
EW
45{
46 register struct ww *w;
47
48 if (id < 0 && (id = findid()) < 0)
49 return 0;
50 if (row + nrow <= 0 || row > wwnrow - 1
51 || col + ncol <= 0 || col > wwncol - 1) {
52 error("Illegal window position.");
53 return 0;
54 }
7ecf4dca
EW
55 w = wwopen(haspty ? WWO_PTY : WWO_SOCKET, nrow, ncol, row, col, nline);
56 if (w == 0) {
57 error("Can't open window: %s.", wwerror());
b6b63f20
EW
58 return 0;
59 }
60 w->ww_id = id;
61 window[id] = w;
7ecf4dca 62 w->ww_hasframe = hasframe;
b27a9cfb 63 w->ww_alt = w->ww_w;
b6b63f20
EW
64 if (label != 0 && setlabel(w, label) < 0)
65 error("No memory for label.");
66 wwcursor(w, 1);
945df92c
EW
67 /*
68 * We have to do this little maneuver to make sure
69 * addwin() puts w at the top, so we don't waste an
70 * insert and delete operation.
71 */
72 setselwin((struct ww *)0);
d7c2cbb0 73 addwin(w, 0);
945df92c 74 setselwin(w);
7ecf4dca
EW
75 if (wwspawn(w, shf, sh) < 0) {
76 error("Can't execute %s: %s.", shf, wwerror());
2422abab 77 closewin(w);
b6b63f20
EW
78 return 0;
79 }
80 return w;
81}
82
83findid()
84{
85 register i;
86
87 for (i = 0; i < NWINDOW && window[i] != 0; i++)
88 ;
89 if (i >= NWINDOW) {
90 error("Too many windows.");
91 return -1;
92 }
93 return i;
94}
95
2422abab
EW
96struct ww *
97findselwin()
98{
99 register struct ww *w, *s = 0;
100 register i;
101
102 for (i = 0; i < NWINDOW; i++)
103 if ((w = window[i]) != 0 && w != selwin &&
104 (s == 0 ||
105 !isfg(w) && (w->ww_order < s->ww_order || isfg(s))))
106 s = w;
107 return s;
108}
109
b6b63f20 110/*
2422abab 111 * Close a user window. Close all if w == 0.
b6b63f20
EW
112 */
113closewin(w)
114register struct ww *w;
115{
2422abab
EW
116 char didit = 0;
117 register i;
118
119 if (w != 0) {
120 closewin1(w);
121 didit++;
122 } else
123 for (i = 0; i < NWINDOW; i++) {
124 if ((w = window[i]) == 0)
125 continue;
126 closewin1(w);
127 didit++;
128 }
129 if (didit) {
130 if (selwin == 0)
131 if (lastselwin != 0) {
132 setselwin(lastselwin);
133 lastselwin = 0;
134 } else if (w = findselwin())
135 setselwin(w);
136 if (lastselwin == 0 && selwin)
137 if (w = findselwin())
138 lastselwin = w;
139 reframe();
140 }
b6b63f20
EW
141}
142
143/*
144 * Open an information (display) window.
145 */
146struct ww *
147openiwin(nrow, label)
148char *label;
149{
150 register struct ww *w;
151
152 if ((w = wwopen(0, nrow, wwncol, 2, 0, 0)) == 0)
153 return 0;
154 w->ww_mapnl = 1;
155 w->ww_hasframe = 1;
b1189050 156 w->ww_nointr = 1;
0e64e422
EW
157 w->ww_noupdate = 1;
158 w->ww_unctrl = 1;
b6b63f20
EW
159 w->ww_id = -1;
160 w->ww_center = 1;
161 (void) setlabel(w, label);
d7c2cbb0 162 addwin(w, 1);
b6b63f20
EW
163 reframe();
164 return w;
165}
166
167/*
168 * Close an information window.
169 */
170closeiwin(w)
171struct ww *w;
172{
2422abab 173 closewin1(w);
b6b63f20
EW
174 reframe();
175}
176
2422abab
EW
177closewin1(w)
178register struct ww *w;
179{
180 if (w == selwin)
181 selwin = 0;
182 if (w == lastselwin)
183 lastselwin = 0;
184 if (w->ww_id >= 0 && w->ww_id < NWINDOW)
185 window[w->ww_id] = 0;
186 if (w->ww_label)
187 str_free(w->ww_label);
188 deletewin(w);
189 wwclose(w);
190}
191
e1dba5dd
EW
192/*
193 * Move the window to the top of its group.
d7c2cbb0 194 * Don't do it if already fully visible.
e1dba5dd
EW
195 * Wwvisible() doesn't work for tinted windows.
196 * But anything to make it faster.
197 * Always reframe() if doreframe is true.
198 */
199front(w, doreframe)
200register struct ww *w;
201char doreframe;
202{
d7c2cbb0
EW
203 if (w->ww_back != (isfg(w) ? framewin : fgwin) && !wwvisible(w)) {
204 deletewin(w);
205 addwin(w, isfg(w));
206 doreframe = 1;
e1dba5dd
EW
207 }
208 if (doreframe)
209 reframe();
210}
211
212/*
d7c2cbb0 213 * Add a window at the top of normal windows or foreground windows.
945df92c 214 * For normal windows, we put it behind the current window.
e1dba5dd 215 */
d7c2cbb0 216addwin(w, fg)
e1dba5dd 217register struct ww *w;
d7c2cbb0 218char fg;
e1dba5dd 219{
d7c2cbb0 220 if (fg) {
e1dba5dd
EW
221 wwadd(w, framewin);
222 if (fgwin == framewin)
223 fgwin = w;
d7c2cbb0 224 } else
945df92c
EW
225 wwadd(w, selwin != 0 && selwin != w && !isfg(selwin)
226 ? selwin : fgwin);
e1dba5dd
EW
227}
228
229/*
230 * Delete a window.
231 */
232deletewin(w)
233register struct ww *w;
234{
d7c2cbb0
EW
235 if (fgwin == w)
236 fgwin = w->ww_back;
e1dba5dd
EW
237 wwdelete(w);
238}
239
240reframe()
241{
242 register struct ww *w;
243
244 wwunframe(framewin);
245 for (w = wwhead.ww_back; w != &wwhead; w = w->ww_back)
246 if (w->ww_hasframe) {
247 wwframe(w, framewin);
248 labelwin(w);
249 }
250}
251
252labelwin(w)
253register struct ww *w;
254{
255 int mode = w == selwin ? WWM_REV : 0;
256
257 if (!w->ww_hasframe)
258 return;
259 if (w->ww_id >= 0) {
260 char buf[2];
261
262 buf[0] = w->ww_id + '1';
263 buf[1] = 0;
264 wwlabel(w, framewin, 1, buf, mode);
265 }
266 if (w->ww_label) {
267 int col;
268
269 if (w->ww_center) {
270 col = (w->ww_w.nc - strlen(w->ww_label)) / 2;
271 col = MAX(3, col);
272 } else
273 col = 3;
274 wwlabel(w, framewin, col, w->ww_label, mode);
275 }
276}
277
3fdb475b
EW
278stopwin(w)
279 register struct ww *w;
280{
281 w->ww_stopped = 1;
282 if (w->ww_pty >= 0 && w->ww_ispty)
20029082 283 (void) ioctl(w->ww_pty, TIOCSTOP, (char *)0);
3fdb475b
EW
284}
285
286startwin(w)
287 register struct ww *w;
288{
289 w->ww_stopped = 0;
290 if (w->ww_pty >= 0 && w->ww_ispty)
20029082 291 (void) ioctl(w->ww_pty, TIOCSTART, (char *)0);
edc20be7
EW
292}
293
294sizewin(w, nrow, ncol)
295register struct ww *w;
296{
297 struct ww *back = w->ww_back;
298
299 w->ww_alt.nr = w->ww_w.nr;
300 w->ww_alt.nc = w->ww_w.nc;
301 wwdelete(w);
302 if (wwsize(w, nrow, ncol) < 0)
303 error("Can't resize window: %s.", wwerror());
304 wwadd(w, back);
305 reframe();
3fdb475b
EW
306}
307
b6b63f20
EW
308waitnl(w)
309struct ww *w;
310{
311 (void) waitnl1(w, "[Type any key to continue]");
312}
313
b1189050 314more(w, always)
b6b63f20 315register struct ww *w;
b1189050 316char always;
b6b63f20
EW
317{
318 int c;
0e64e422 319 char uc = w->ww_unctrl;
b6b63f20 320
b1189050 321 if (!always && w->ww_cur.r < w->ww_w.b - 2)
b6b63f20
EW
322 return 0;
323 c = waitnl1(w, "[Type escape to abort, any other key to continue]");
0e64e422 324 w->ww_unctrl = 0;
b1189050 325 wwputs("\033E", w);
0e64e422 326 w->ww_unctrl = uc;
95bc282c 327 return c == ctrl('[') ? 2 : 1;
b6b63f20
EW
328}
329
330waitnl1(w, prompt)
331register struct ww *w;
332char *prompt;
333{
0e64e422
EW
334 char uc = w->ww_unctrl;
335
336 w->ww_unctrl = 0;
b6b63f20 337 front(w, 0);
a5e3d905 338 wwprintf(w, "\033Y%c%c\033sA%s\033rA ",
b6b63f20
EW
339 w->ww_w.nr - 1 + ' ', ' ', prompt); /* print on last line */
340 wwcurtowin(w);
8fa6d94c
EW
341 while (wwpeekc() < 0)
342 wwiomux();
0e64e422 343 w->ww_unctrl = uc;
8fa6d94c 344 return wwgetc();
b6b63f20 345}