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, 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, 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: }