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