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