|
|
1.1 ! root 1: /************************************************************************* ! 2: * This program is copyright (C) 1985, 1986 by Jonathan Payne. It is * ! 3: * provided to you without charge for use only on a licensed Unix * ! 4: * system. You may copy JOVE provided that this notice is included with * ! 5: * the copy. You may not sell copies of this program or versions * ! 6: * modified for use on microcomputer systems, unless the copies are * ! 7: * included with a Unix system distribution and the source is provided. * ! 8: *************************************************************************/ ! 9: ! 10: /* This creates/deletes/divides/grows/shrinks windows. */ ! 11: ! 12: #include "jove.h" ! 13: #include "termcap.h" ! 14: ! 15: static char onlyone[] = "You only have one window!", ! 16: toosmall[] = "Resulting window would be too small."; ! 17: ! 18: Window *curwind, ! 19: *fwind = 0; ! 20: ! 21: /* First line in a Window */ ! 22: ! 23: FLine(w) ! 24: register Window *w; ! 25: { ! 26: register Window *wp = fwind; ! 27: register int lineno = -1; ! 28: ! 29: do { ! 30: if (wp == w) ! 31: return lineno + 1; ! 32: lineno += wp->w_height; ! 33: wp = wp->w_next; ! 34: } while (wp != fwind); ! 35: complain("window?"); ! 36: /* NOTREACHED */ ! 37: } ! 38: ! 39: /* Delete `wp' from the screen. If it is the only window left ! 40: on the screen, then complain. It gives its body ! 41: to the next window if there is one, otherwise the previous ! 42: window gets the body. */ ! 43: ! 44: del_wind(wp) ! 45: register Window *wp; ! 46: { ! 47: register Window *prev = wp->w_prev; ! 48: ! 49: if (one_windp()) ! 50: complain(onlyone); ! 51: ! 52: wp->w_prev->w_next = wp->w_next; ! 53: wp->w_next->w_prev = wp->w_prev; ! 54: ! 55: if (fwind == wp) { ! 56: fwind = wp->w_next; ! 57: fwind->w_height += wp->w_height; ! 58: /* Here try to do something intelligent for redisplay() */ ! 59: SetTop(fwind, prev_line(fwind->w_top, wp->w_height)); ! 60: if (curwind == wp) ! 61: SetWind(fwind); ! 62: } else { ! 63: prev->w_height += wp->w_height; ! 64: if (curwind == wp) ! 65: SetWind(prev); ! 66: } ! 67: free((char *) wp); ! 68: } ! 69: ! 70: /* Divide the window WP N times, or at least once. Complains if WP is too ! 71: small to be split into that many pieces. It returns the new window. */ ! 72: ! 73: Window * ! 74: div_wind(wp, n) ! 75: register Window *wp; ! 76: { ! 77: register Window *new; ! 78: int amt; ! 79: ! 80: if (n < 1) ! 81: n = 1; ! 82: amt = wp->w_height / (n + 1); ! 83: if (amt < 2) ! 84: complain(toosmall); ! 85: ! 86: while (--n >= 0) { ! 87: new = (Window *) emalloc(sizeof (Window)); ! 88: new->w_visspace = new->w_numlines = 0; ! 89: ! 90: new->w_height = amt; ! 91: wp->w_height -= amt; ! 92: ! 93: /* set the lines such that w_line is the center in ! 94: each Window */ ! 95: new->w_line = wp->w_line; ! 96: new->w_char = wp->w_char; ! 97: new->w_bufp = wp->w_bufp; ! 98: new->w_top = prev_line(new->w_line, HALF(new)); ! 99: ! 100: /* Link the new window into the list */ ! 101: new->w_prev = wp; ! 102: new->w_next = wp->w_next; ! 103: new->w_next->w_prev = new; ! 104: wp->w_next = new; ! 105: } ! 106: return new; ! 107: } ! 108: ! 109: /* Initialze the first window setting the bounds to the size of the ! 110: screen. There is no buffer with this window. See parse for the ! 111: setting of this window. */ ! 112: ! 113: winit() ! 114: { ! 115: register Window *w; ! 116: ! 117: w = curwind = fwind = (Window *) emalloc(sizeof (Window)); ! 118: w->w_line = w->w_top = 0; ! 119: w->w_visspace = w->w_numlines = 0; ! 120: w->w_char = 0; ! 121: w->w_next = w->w_prev = fwind; ! 122: w->w_height = ILI; ! 123: } ! 124: ! 125: /* Change to previous window. */ ! 126: ! 127: PrevWindow() ! 128: { ! 129: register Window *new = curwind->w_prev; ! 130: ! 131: if (one_windp()) ! 132: complain(onlyone); ! 133: SetWind(new); ! 134: } ! 135: ! 136: /* Make NEW the current Window */ ! 137: ! 138: SetWind(new) ! 139: register Window *new; ! 140: { ! 141: if (!Asking){ /* can you say kludge? */ ! 142: curwind->w_line = curline; ! 143: curwind->w_char = curchar; ! 144: curwind->w_bufp = curbuf; ! 145: } ! 146: if (new == curwind) ! 147: return; ! 148: SetBuf(new->w_bufp); ! 149: if (!inlist(new->w_bufp->b_first, new->w_line)) { ! 150: new->w_line = curline; ! 151: new->w_char = curchar; ! 152: } ! 153: DotTo(new->w_line, new->w_char); ! 154: if (curchar > strlen(linebuf)) ! 155: new->w_char = curchar = strlen(linebuf); ! 156: curwind = new; ! 157: } ! 158: ! 159: /* Delete the current window if it isn't the only one left */ ! 160: ! 161: DelCurWindow() ! 162: { ! 163: del_wind(curwind); ! 164: } ! 165: ! 166: /* Put the current line of `w' in the middle of the window */ ! 167: ! 168: CentWind(w) ! 169: register Window *w; ! 170: { ! 171: SetTop(w, prev_line(w->w_line, HALF(w))); ! 172: } ! 173: ! 174: int ScrollStep = 0; /* Full scrolling */ ! 175: ! 176: /* Calculate the new topline of the screen. If ScrollStep == 0 ! 177: it means we should center the current line in the window. */ ! 178: ! 179: CalcWind(w) ! 180: register Window *w; ! 181: { ! 182: register int up; ! 183: Line *newtop; ! 184: ! 185: if (ScrollStep == 0) /* Means just center it */ ! 186: CentWind(w); ! 187: else { ! 188: up = inorder(w->w_line, 0, w->w_top, 0); ! 189: if (up == -1) { ! 190: CentWind(w); ! 191: return; ! 192: } ! 193: if (up) /* Dot is above the screen */ ! 194: newtop = prev_line(w->w_line, min(ScrollStep - 1, HALF(w))); ! 195: else ! 196: newtop = prev_line(w->w_line, (SIZE(w) - 1) - ! 197: min(ScrollStep - 1, HALF(w))); ! 198: if (LineDist(newtop, w->w_top) >= SIZE(w) - 1) ! 199: CentWind(w); ! 200: else ! 201: SetTop(w, newtop); ! 202: } ! 203: } ! 204: ! 205: WindFind() ! 206: { ! 207: register Buffer *savebuf = curbuf; ! 208: Bufpos savedot; ! 209: extern int ! 210: FindTag(), ! 211: BufSelect(), ! 212: FindFile(); ! 213: ! 214: DOTsave(&savedot); ! 215: ! 216: switch (waitchar()) { ! 217: case 't': ! 218: case 'T': ! 219: ExecCmd((data_obj *) FindCmd(FindTag)); ! 220: break; ! 221: ! 222: case 'b': ! 223: case 'B': ! 224: ExecCmd((data_obj *) FindCmd(BufSelect)); ! 225: break; ! 226: ! 227: case 'f': ! 228: case 'F': ! 229: ExecCmd((data_obj *) FindCmd(FindFile)); ! 230: break; ! 231: ! 232: default: ! 233: complain("T: find-tag, F: find-file, B: select-buffer."); ! 234: } ! 235: ! 236: if (one_windp()) ! 237: (void) div_wind(curwind, 1); ! 238: ! 239: tiewind(curwind->w_next, curbuf); ! 240: SetBuf(savebuf); /* Back to original buffer */ ! 241: SetDot(&savedot); /* in original position */ ! 242: tiewind(curwind, curbuf); ! 243: SetWind(curwind->w_next); ! 244: } ! 245: ! 246: /* Go into one window mode by deleting all the other windows */ ! 247: ! 248: OneWindow() ! 249: { ! 250: while (curwind->w_next != curwind) ! 251: del_wind(curwind->w_next); ! 252: } ! 253: ! 254: Window * ! 255: windbp(bp) ! 256: register Buffer *bp; ! 257: { ! 258: ! 259: register Window *wp = fwind; ! 260: ! 261: if (bp == 0) ! 262: return 0; ! 263: do { ! 264: if (wp->w_bufp == bp) ! 265: return wp; ! 266: wp = wp->w_next; ! 267: } while (wp != fwind); ! 268: return 0; ! 269: } ! 270: ! 271: /* Look for a window containing a buffer whose name is `name' */ ! 272: ! 273: Window * ! 274: windlook(name) ! 275: register char *name; ! 276: { ! 277: return windbp(buf_exists(name)); ! 278: } ! 279: ! 280: /* Change window into the next window. Curwind becomes the new window. */ ! 281: ! 282: NextWindow() ! 283: { ! 284: register Window *new = curwind->w_next; ! 285: ! 286: if (one_windp()) ! 287: complain(onlyone); ! 288: SetWind(new); ! 289: } ! 290: ! 291: /* Scroll the next Window */ ! 292: ! 293: PageNWind() ! 294: { ! 295: if (one_windp()) ! 296: complain(onlyone); ! 297: NextWindow(); ! 298: NextPage(); ! 299: PrevWindow(); ! 300: } ! 301: ! 302: Window * ! 303: w_nam_typ(name, type) ! 304: register char *name; ! 305: { ! 306: register Window *w; ! 307: register Buffer *b; ! 308: ! 309: b = buf_exists(name); ! 310: w = fwind; ! 311: if (b) do { ! 312: if (w->w_bufp == b) ! 313: return w; ! 314: } while ((w = w->w_next) != fwind); ! 315: ! 316: w = fwind; ! 317: do { ! 318: if (w->w_bufp->b_type == type) ! 319: return w; ! 320: } while ((w = w->w_next) != fwind); ! 321: ! 322: return 0; ! 323: } ! 324: ! 325: /* Put a window with the buffer `name' in it. Erase the buffer if ! 326: `clobber' is non-zero. */ ! 327: ! 328: pop_wind(name, clobber, btype) ! 329: register char *name; ! 330: { ! 331: register Window *wp; ! 332: register Buffer *newb; ! 333: ! 334: if ((wp = w_nam_typ(name, btype)) == 0) { ! 335: if (one_windp()) ! 336: SetWind(div_wind(curwind, 1)); ! 337: else ! 338: PrevWindow(); ! 339: } else ! 340: SetWind(wp); ! 341: ! 342: newb = do_select((Window *) 0, name); ! 343: if (clobber) ! 344: initlist(newb); ! 345: tiewind(curwind, newb); ! 346: #ifdef IPROCS ! 347: if (newb->b_type != B_IPROCESS && btype != -1) ! 348: #else ! 349: if (btype != -1) ! 350: #endif ! 351: newb->b_type = btype; ! 352: SetBuf(newb); ! 353: } ! 354: ! 355: GrowWindow() ! 356: { ! 357: WindSize(curwind, abs(exp)); ! 358: } ! 359: ! 360: ShrWindow() ! 361: { ! 362: WindSize(curwind, -abs(exp)); ! 363: } ! 364: ! 365: /* Change the size of the window by inc. First arg is the window, ! 366: second is the increment. */ ! 367: ! 368: WindSize(w, inc) ! 369: register Window *w; ! 370: register int inc; ! 371: { ! 372: if (one_windp()) ! 373: complain(onlyone); ! 374: ! 375: if (inc == 0) ! 376: return; ! 377: else if (inc < 0) { /* Shrinking this Window. */ ! 378: if (w->w_height + inc < 2) ! 379: complain(toosmall); ! 380: w->w_height += inc; ! 381: w->w_prev->w_height -= inc; ! 382: } else /* Growing the window. */ ! 383: WindSize(w->w_next, -inc); ! 384: } ! 385: ! 386: /* Set the topline of the window, calculating its number in the buffer. ! 387: This is for numbering the lines only. */ ! 388: ! 389: SetTop(w, line) ! 390: Window *w; ! 391: register Line *line; ! 392: { ! 393: register Line *lp = w->w_bufp->b_first; ! 394: register int num = 0; ! 395: ! 396: w->w_top = line; ! 397: if (w->w_numlines) { ! 398: while (lp) { ! 399: num++; ! 400: if (line == lp) ! 401: break; ! 402: lp = lp->l_next; ! 403: } ! 404: w->w_topnum = num; ! 405: } ! 406: } ! 407: ! 408: WNumLines() ! 409: { ! 410: curwind->w_numlines = !curwind->w_numlines; ! 411: SetTop(curwind, curwind->w_top); ! 412: } ! 413: ! 414: WVisSpace() ! 415: { ! 416: curwind->w_visspace = !curwind->w_visspace; ! 417: ClAndRedraw(); ! 418: } ! 419: ! 420: /* Return the line number that `line' occupies in `windes' */ ! 421: ! 422: in_window(windes, line) ! 423: register Window *windes; ! 424: register Line *line; ! 425: { ! 426: register int i; ! 427: register Line *top = windes->w_top; ! 428: ! 429: for (i = 0; top && i < windes->w_height - 1; i++, top = top->l_next) ! 430: if (top == line) ! 431: return FLine(windes) + i; ! 432: return -1; ! 433: } ! 434: ! 435: SplitWind() ! 436: { ! 437: SetWind(div_wind(curwind, exp_p ? (exp - 1) : 1)); ! 438: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.