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