|
|
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.