|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)win.c 3.14 4/24/85"; ! 3: #endif ! 4: ! 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: ! 11: #include "defs.h" ! 12: #include "char.h" ! 13: ! 14: /* ! 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: * ! 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. ! 25: * Deletewin() deletes a window. Front() moves a window to the front ! 26: * of its group. Wwopen(), wwadd(), and wwdelete() should never be called ! 27: * directly. ! 28: */ ! 29: ! 30: /* ! 31: * Open a user window. ! 32: */ ! 33: struct ww * ! 34: openwin(id, row, col, nrow, ncol, nline, label, haspty, hasframe, shf, sh) ! 35: char *label; ! 36: char haspty, hasframe; ! 37: char *shf, **sh; ! 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: } ! 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()); ! 51: return 0; ! 52: } ! 53: w->ww_id = id; ! 54: window[id] = w; ! 55: w->ww_hasframe = hasframe; ! 56: w->ww_alt = w->ww_w; ! 57: if (label != 0 && setlabel(w, label) < 0) ! 58: error("No memory for label."); ! 59: wwcursor(w, 1); ! 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); ! 66: addwin(w, 0); ! 67: setselwin(w); ! 68: wwupdate(); ! 69: wwflush(); ! 70: if (wwspawn(w, shf, sh) < 0) { ! 71: error("Can't execute %s: %s.", shf, wwerror()); ! 72: c_close(w); ! 73: return 0; ! 74: } ! 75: return w; ! 76: } ! 77: ! 78: findid() ! 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. ! 93: * May leave selwin == 0. ! 94: */ ! 95: closewin(w) ! 96: register 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); ! 106: deletewin(w); ! 107: wwclose(w); ! 108: } ! 109: ! 110: /* ! 111: * Open an information (display) window. ! 112: */ ! 113: struct ww * ! 114: openiwin(nrow, label) ! 115: char *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; ! 123: w->ww_nointr = 1; ! 124: w->ww_noupdate = 1; ! 125: w->ww_unctrl = 1; ! 126: w->ww_id = -1; ! 127: w->ww_center = 1; ! 128: (void) setlabel(w, label); ! 129: addwin(w, 1); ! 130: reframe(); ! 131: wwupdate(); ! 132: return w; ! 133: } ! 134: ! 135: /* ! 136: * Close an information window. ! 137: */ ! 138: closeiwin(w) ! 139: struct ww *w; ! 140: { ! 141: closewin(w); ! 142: reframe(); ! 143: } ! 144: ! 145: /* ! 146: * Move the window to the top of its group. ! 147: * Don't do it if already fully visible. ! 148: * Wwvisible() doesn't work for tinted windows. ! 149: * But anything to make it faster. ! 150: * Always reframe() if doreframe is true. ! 151: */ ! 152: front(w, doreframe) ! 153: register struct ww *w; ! 154: char doreframe; ! 155: { ! 156: if (w->ww_back != (isfg(w) ? framewin : fgwin) && !wwvisible(w)) { ! 157: deletewin(w); ! 158: addwin(w, isfg(w)); ! 159: doreframe = 1; ! 160: } ! 161: if (doreframe) ! 162: reframe(); ! 163: } ! 164: ! 165: /* ! 166: * Add a window at the top of normal windows or foreground windows. ! 167: * For normal windows, we put it behind the current window. ! 168: */ ! 169: addwin(w, fg) ! 170: register struct ww *w; ! 171: char fg; ! 172: { ! 173: if (fg) { ! 174: wwadd(w, framewin); ! 175: if (fgwin == framewin) ! 176: fgwin = w; ! 177: } else ! 178: wwadd(w, selwin != 0 && selwin != w && !isfg(selwin) ! 179: ? selwin : fgwin); ! 180: } ! 181: ! 182: /* ! 183: * Delete a window. ! 184: */ ! 185: deletewin(w) ! 186: register struct ww *w; ! 187: { ! 188: if (fgwin == w) ! 189: fgwin = w->ww_back; ! 190: wwdelete(w); ! 191: } ! 192: ! 193: reframe() ! 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: ! 205: labelwin(w) ! 206: register 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: ! 231: stopwin(w) ! 232: register struct ww *w; ! 233: { ! 234: w->ww_stopped = 1; ! 235: if (w->ww_pty >= 0 && w->ww_ispty) ! 236: (void) ioctl(w->ww_pty, (int)TIOCSTOP, (char *)0); ! 237: } ! 238: ! 239: startwin(w) ! 240: register struct ww *w; ! 241: { ! 242: w->ww_stopped = 0; ! 243: if (w->ww_pty >= 0 && w->ww_ispty) ! 244: (void) ioctl(w->ww_pty, (int)TIOCSTART, (char *)0); ! 245: } ! 246: ! 247: sizewin(w, nrow, ncol) ! 248: register 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(); ! 259: } ! 260: ! 261: waitnl(w) ! 262: struct ww *w; ! 263: { ! 264: (void) waitnl1(w, "[Type any key to continue]"); ! 265: } ! 266: ! 267: more(w, always) ! 268: register struct ww *w; ! 269: char always; ! 270: { ! 271: int c; ! 272: char uc = w->ww_unctrl; ! 273: ! 274: if (!always && w->ww_cur.r < w->ww_w.b - 2) ! 275: return 0; ! 276: c = waitnl1(w, "[Type escape to abort, any other key to continue]"); ! 277: w->ww_unctrl = 0; ! 278: wwputs("\033E", w); ! 279: w->ww_unctrl = uc; ! 280: return c == ctrl([) ? 2 : 1; ! 281: } ! 282: ! 283: waitnl1(w, prompt) ! 284: register struct ww *w; ! 285: char *prompt; ! 286: { ! 287: char uc = w->ww_unctrl; ! 288: ! 289: w->ww_unctrl = 0; ! 290: front(w, 0); ! 291: wwprintf(w, "\033Y%c%c\033p%s\033q ", ! 292: w->ww_w.nr - 1 + ' ', ' ', prompt); /* print on last line */ ! 293: wwcurtowin(w); ! 294: while (wwpeekc() < 0) ! 295: wwiomux(); ! 296: w->ww_unctrl = uc; ! 297: return wwgetc(); ! 298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.