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