|
|
1.1 ! root 1: /*************************************************************************** ! 2: * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * ! 3: * is provided to you without charge, and with no warranty. You may give * ! 4: * away copies of JOVE, including sources, provided that this notice is * ! 5: * included in all the files. * ! 6: ***************************************************************************/ ! 7: ! 8: /* This creates/deletes/divides/grows/shrinks windows. */ ! 9: ! 10: #include "jove.h" ! 11: #include "termcap.h" ! 12: #include "chars.h" ! 13: #include "disp.h" ! 14: ! 15: private 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: int ! 24: FLine(w) ! 25: register Window *w; ! 26: { ! 27: register Window *wp = fwind; ! 28: register int lineno = -1; ! 29: ! 30: do { ! 31: if (wp == w) ! 32: return lineno + 1; ! 33: lineno += wp->w_height; ! 34: wp = wp->w_next; ! 35: } while (wp != fwind); ! 36: complain("window?"); ! 37: /* NOTREACHED */ ! 38: } ! 39: ! 40: /* Delete `wp' from the screen. If it is the only window left ! 41: on the screen, then complain. It gives its body ! 42: to the next window if there is one, otherwise the previous ! 43: window gets the body. */ ! 44: ! 45: void ! 46: del_wind(wp) ! 47: register Window *wp; ! 48: { ! 49: register Window *prev = wp->w_prev; ! 50: ! 51: if (one_windp()) ! 52: complain(onlyone); ! 53: ! 54: prev->w_next = wp->w_next; ! 55: wp->w_next->w_prev = prev; ! 56: ! 57: if (fwind == wp) { ! 58: fwind = wp->w_next; ! 59: fwind->w_height += wp->w_height; ! 60: /* Here try to do something intelligent for redisplay() */ ! 61: SetTop(fwind, prev_line(fwind->w_top, wp->w_height)); ! 62: if (curwind == wp) ! 63: SetWind(fwind); ! 64: } else { ! 65: prev->w_height += wp->w_height; ! 66: if (curwind == wp) ! 67: SetWind(prev); ! 68: } ! 69: #ifdef MAC ! 70: RemoveScrollBar(wp); ! 71: Windchange++; ! 72: #endif ! 73: free((char *) wp); ! 74: } ! 75: ! 76: /* Divide the window WP N times, or at least once. Complains if WP is too ! 77: small to be split into that many pieces. It returns the new window. */ ! 78: ! 79: Window * ! 80: div_wind(wp, n) ! 81: register Window *wp; ! 82: int n; ! 83: { ! 84: register Window *new; ! 85: int amt; ! 86: ! 87: if (n < 1) ! 88: n = 1; ! 89: amt = wp->w_height / (n + 1); ! 90: if (amt < 2) ! 91: complain(toosmall); ! 92: ! 93: while (--n >= 0) { ! 94: new = (Window *) emalloc(sizeof (Window)); ! 95: new->w_flags = 0; ! 96: new->w_LRscroll = 0; ! 97: ! 98: new->w_height = amt; ! 99: wp->w_height -= amt; ! 100: ! 101: /* set the lines such that w_line is the center in ! 102: each Window */ ! 103: new->w_line = wp->w_line; ! 104: new->w_char = wp->w_char; ! 105: new->w_bufp = wp->w_bufp; ! 106: new->w_top = prev_line(new->w_line, HALF(new)); ! 107: ! 108: /* Link the new window into the list */ ! 109: new->w_prev = wp; ! 110: new->w_next = wp->w_next; ! 111: new->w_next->w_prev = new; ! 112: wp->w_next = new; ! 113: #ifdef MAC ! 114: new->w_control = 0; ! 115: #endif ! 116: } ! 117: #ifdef MAC ! 118: Windchange++; ! 119: #endif ! 120: return new; ! 121: } ! 122: ! 123: /* Initialze the first window setting the bounds to the size of the ! 124: screen. There is no buffer with this window. See parse for the ! 125: setting of this window. */ ! 126: ! 127: void ! 128: winit() ! 129: { ! 130: register Window *w; ! 131: ! 132: w = curwind = fwind = (Window *) emalloc(sizeof (Window)); ! 133: w->w_line = w->w_top = 0; ! 134: w->w_LRscroll = 0; ! 135: w->w_flags = 0; ! 136: w->w_char = 0; ! 137: w->w_next = w->w_prev = fwind; ! 138: w->w_height = ILI; ! 139: #ifdef MAC ! 140: w->w_control = 0; ! 141: Windchange++; ! 142: #endif ! 143: } ! 144: ! 145: /* Change to previous window. */ ! 146: ! 147: void ! 148: PrevWindow() ! 149: { ! 150: register Window *new = curwind->w_prev; ! 151: ! 152: if (Asking) ! 153: complain((char *) 0); ! 154: if (one_windp()) ! 155: complain(onlyone); ! 156: SetWind(new); ! 157: } ! 158: ! 159: /* Make NEW the current Window */ ! 160: ! 161: void ! 162: SetWind(new) ! 163: register Window *new; ! 164: { ! 165: if (!Asking && curbuf!=NULL) { /* can you say kludge? */ ! 166: curwind->w_line = curline; ! 167: curwind->w_char = curchar; ! 168: curwind->w_bufp = curbuf; ! 169: } ! 170: if (new == curwind) ! 171: return; ! 172: SetBuf(new->w_bufp); ! 173: if (!inlist(new->w_bufp->b_first, new->w_line)) { ! 174: new->w_line = curline; ! 175: new->w_char = curchar; ! 176: } ! 177: DotTo(new->w_line, new->w_char); ! 178: if (curchar > (int)strlen(linebuf)) ! 179: new->w_char = curchar = strlen(linebuf); ! 180: curwind = new; ! 181: } ! 182: ! 183: /* delete the current window if it isn't the only one left */ ! 184: ! 185: void ! 186: DelCurWindow() ! 187: { ! 188: SetABuf(curwind->w_bufp); ! 189: del_wind(curwind); ! 190: } ! 191: ! 192: /* put the current line of `w' in the middle of the window */ ! 193: ! 194: void ! 195: CentWind(w) ! 196: register Window *w; ! 197: { ! 198: SetTop(w, prev_line(w->w_line, HALF(w))); ! 199: } ! 200: ! 201: int ScrollStep = 0; /* full scrolling */ ! 202: ! 203: /* Calculate the new topline of the window. If ScrollStep == 0 ! 204: it means we should center the current line in the window. */ ! 205: ! 206: void ! 207: CalcWind(w) ! 208: register Window *w; ! 209: { ! 210: register int up; ! 211: int scr_step; ! 212: Line *newtop; ! 213: ! 214: if (ScrollStep == 0) /* Means just center it */ ! 215: CentWind(w); ! 216: else { ! 217: up = inorder(w->w_line, 0, w->w_top, 0); ! 218: if (up == -1) { ! 219: CentWind(w); ! 220: return; ! 221: } ! 222: scr_step = (ScrollStep < 0) ? SIZE(w) + ScrollStep : ! 223: ScrollStep - 1; ! 224: if (up) /* point is above the screen */ ! 225: newtop = prev_line(w->w_line, scr_step); ! 226: else ! 227: newtop = prev_line(w->w_line, (SIZE(w) - 1 - scr_step)); ! 228: if (LineDist(newtop, w->w_top) >= SIZE(w) - 1) ! 229: CentWind(w); ! 230: else ! 231: SetTop(w, newtop); ! 232: } ! 233: } ! 234: ! 235: /* This is bound to C-X 4 [BTF]. To make the screen stay the ! 236: same we have to remember various things, like the current ! 237: top line in the current window. It's sorta gross, but it's ! 238: necessary because of the way this is implemented (i.e., in ! 239: terms of do_find(), do_select() which manipulate the windows. */ ! 240: ! 241: void ! 242: WindFind() ! 243: { ! 244: register Buffer *obuf = curbuf, ! 245: *nbuf; ! 246: Line *ltop = curwind->w_top; ! 247: Bufpos odot, ! 248: ndot; ! 249: ! 250: DOTsave(&odot); ! 251: ! 252: switch (waitchar((int *) 0)) { ! 253: case 't': ! 254: case 'T': ! 255: ExecCmd((data_obj *) FindCmd(FindTag)); ! 256: break; ! 257: ! 258: case CTL('T'): ! 259: ExecCmd((data_obj *) FindCmd(FDotTag)); ! 260: break; ! 261: ! 262: case 'b': ! 263: case 'B': ! 264: ExecCmd((data_obj *) FindCmd(BufSelect)); ! 265: break; ! 266: ! 267: case 'f': ! 268: case 'F': ! 269: ExecCmd((data_obj *) FindCmd(FindFile)); ! 270: break; ! 271: ! 272: default: ! 273: complain("T: find-tag, ^T: find-tag-at-point, F: find-file, B: select-buffer."); ! 274: } ! 275: ! 276: nbuf = curbuf; ! 277: DOTsave(&ndot); ! 278: SetBuf(obuf); ! 279: SetDot(&odot); ! 280: SetTop(curwind, ltop); /* there! it's as if we did nothing */ ! 281: ! 282: if (one_windp()) ! 283: (void) div_wind(curwind, 1); ! 284: ! 285: tiewind(curwind->w_next, nbuf); ! 286: SetWind(curwind->w_next); ! 287: SetDot(&ndot); ! 288: } ! 289: ! 290: /* Go into one window mode by deleting all the other windows */ ! 291: ! 292: void ! 293: OneWindow() ! 294: { ! 295: while (curwind->w_next != curwind) ! 296: del_wind(curwind->w_next); ! 297: } ! 298: ! 299: Window * ! 300: windbp(bp) ! 301: register Buffer *bp; ! 302: { ! 303: ! 304: register Window *wp = fwind; ! 305: ! 306: if (bp == 0) ! 307: return 0; ! 308: do { ! 309: if (wp->w_bufp == bp) ! 310: return wp; ! 311: wp = wp->w_next; ! 312: } while (wp != fwind); ! 313: return 0; ! 314: } ! 315: ! 316: /* Change window into the next window. Curwind becomes the new window. */ ! 317: ! 318: void ! 319: NextWindow() ! 320: { ! 321: register Window *new = curwind->w_next; ! 322: ! 323: if (Asking) ! 324: complain((char *) 0); ! 325: if (one_windp()) ! 326: complain(onlyone); ! 327: SetWind(new); ! 328: } ! 329: ! 330: /* Scroll the next Window */ ! 331: ! 332: void ! 333: PageNWind() ! 334: { ! 335: if (one_windp()) ! 336: complain(onlyone); ! 337: NextWindow(); ! 338: NextPage(); ! 339: PrevWindow(); ! 340: } ! 341: ! 342: Window * ! 343: w_nam_typ(name, type) ! 344: register char *name; ! 345: int type; ! 346: { ! 347: register Window *w; ! 348: register Buffer *b; ! 349: ! 350: b = buf_exists(name); ! 351: w = fwind; ! 352: if (b) do { ! 353: if (w->w_bufp == b) ! 354: return w; ! 355: } while ((w = w->w_next) != fwind); ! 356: ! 357: w = fwind; ! 358: do { ! 359: if (w->w_bufp->b_type == type) ! 360: return w; ! 361: } while ((w = w->w_next) != fwind); ! 362: ! 363: return 0; ! 364: } ! 365: ! 366: /* Put a window with the buffer `name' in it. Erase the buffer if ! 367: `clobber' is non-zero. */ ! 368: ! 369: void ! 370: pop_wind(name, clobber, btype) ! 371: register char *name; ! 372: int clobber; ! 373: int btype; ! 374: { ! 375: register Window *wp; ! 376: register Buffer *newb; ! 377: ! 378: if ((newb = buf_exists(name)) != NIL) ! 379: btype = -1; /* if the buffer exists, don't change ! 380: it's type */ ! 381: if ((wp = w_nam_typ(name, btype)) == 0) { ! 382: if (one_windp()) ! 383: SetWind(div_wind(curwind, 1)); ! 384: else ! 385: PrevWindow(); ! 386: } else ! 387: SetWind(wp); ! 388: ! 389: newb = do_select((Window *) 0, name); ! 390: if (clobber) { ! 391: initlist(newb); ! 392: newb->b_modified = NO; ! 393: } ! 394: tiewind(curwind, newb); ! 395: if (btype != -1) ! 396: newb->b_type = btype; ! 397: SetBuf(newb); ! 398: } ! 399: ! 400: void ! 401: GrowWindow() ! 402: { ! 403: WindSize(curwind, abs(arg_value())); ! 404: } ! 405: ! 406: void ! 407: ShrWindow() ! 408: { ! 409: WindSize(curwind, -abs(arg_value())); ! 410: } ! 411: ! 412: /* Change the size of the window by inc. First arg is the window, ! 413: second is the increment. */ ! 414: ! 415: void ! 416: WindSize(w, inc) ! 417: register Window *w; ! 418: register int inc; ! 419: { ! 420: if (one_windp()) ! 421: complain(onlyone); ! 422: ! 423: if (inc == 0) ! 424: return; ! 425: else if (inc < 0) { /* Shrinking this Window. */ ! 426: if (w->w_height + inc < 2) ! 427: complain(toosmall); ! 428: w->w_height += inc; ! 429: w->w_prev->w_height -= inc; ! 430: } else { /* Growing the window. */ ! 431: /* Change made from original code so that growing a window ! 432: exactly offsets effect of shrinking a window, i.e. ! 433: doing either followed by the other restores original ! 434: sizes of all affected windows. */ ! 435: if (w->w_prev->w_height - inc < 2) ! 436: complain(toosmall); ! 437: w->w_height += inc; ! 438: w->w_prev->w_height -= inc; ! 439: } ! 440: #ifdef MAC ! 441: Windchange++; ! 442: #endif ! 443: } ! 444: ! 445: /* Set the topline of the window, calculating its number in the buffer. ! 446: This is for numbering the lines only. */ ! 447: ! 448: void ! 449: SetTop(w, line) ! 450: Window *w; ! 451: register Line *line; ! 452: { ! 453: register Line *lp = w->w_bufp->b_first; ! 454: register int num = 0; ! 455: ! 456: w->w_top = line; ! 457: if (w->w_flags & W_NUMLINES) { ! 458: while (lp) { ! 459: num += 1; ! 460: if (line == lp) ! 461: break; ! 462: lp = lp->l_next; ! 463: } ! 464: w->w_topnum = num; ! 465: } ! 466: } ! 467: ! 468: void ! 469: WNumLines() ! 470: { ! 471: curwind->w_flags ^= W_NUMLINES; ! 472: SetTop(curwind, curwind->w_top); ! 473: } ! 474: ! 475: void ! 476: WVisSpace() ! 477: { ! 478: curwind->w_flags ^= W_VISSPACE; ! 479: ClAndRedraw(); ! 480: } ! 481: ! 482: /* Return the line number that `line' occupies in `windes' */ ! 483: ! 484: int ! 485: in_window(windes, line) ! 486: register Window *windes; ! 487: register Line *line; ! 488: { ! 489: register int i; ! 490: register Line *top = windes->w_top; ! 491: ! 492: for (i = 0; top && i < windes->w_height - 1; i++, top = top->l_next) ! 493: if (top == line) ! 494: return FLine(windes) + i; ! 495: return -1; ! 496: } ! 497: ! 498: void ! 499: SplitWind() ! 500: { ! 501: SetWind(div_wind(curwind, is_an_arg() ? (arg_value() - 1) : 1)); ! 502: } ! 503: ! 504: /* Goto the window with the named buffer. If no such window ! 505: exists, pop one and attach the buffer to it. */ ! 506: void ! 507: GotoWind() ! 508: { ! 509: char *bname; ! 510: Window *w; ! 511: ! 512: bname = ask_buf(lastbuf); ! 513: w = curwind->w_next; ! 514: do { ! 515: if (w->w_bufp->b_name == bname) { ! 516: SetABuf(curbuf); ! 517: SetWind(w); ! 518: return; ! 519: } ! 520: w = w->w_next; ! 521: } while (w != curwind); ! 522: SetABuf(curbuf); ! 523: pop_wind(bname, NO, -1); ! 524: } ! 525: ! 526: void ! 527: ScrollRight() ! 528: { ! 529: int amt = (is_an_arg() ? arg_value() : 10); ! 530: ! 531: if (curwind->w_LRscroll - amt < 0) ! 532: curwind->w_LRscroll = 0; ! 533: else ! 534: curwind->w_LRscroll -= amt; ! 535: UpdModLine = YES; ! 536: } ! 537: ! 538: void ! 539: ScrollLeft() ! 540: { ! 541: int amt = (is_an_arg() ? arg_value() : 10); ! 542: ! 543: curwind->w_LRscroll += amt; ! 544: UpdModLine = YES; ! 545: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.