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