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