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

Defined functions

CalcWind defined in line 179; used 1 times
CentWind defined in line 168; used 4 times
DelCurWindow defined in line 161; used 2 times
FLine defined in line 23; used 3 times
GrowWindow defined in line 355; used 2 times
NextWindow defined in line 282; used 4 times
OneWindow defined in line 248; used 2 times
PageNWind defined in line 293; used 2 times
PrevWindow defined in line 127; used 4 times
SetTop defined in line 389; used 10 times
ShrWindow defined in line 360; used 2 times
SplitWind defined in line 435; used 2 times
WNumLines defined in line 408; used 2 times
WVisSpace defined in line 414; used 2 times
WindFind defined in line 205; used 2 times
WindSize defined in line 368; used 5 times
del_wind defined in line 44; used 3 times
div_wind defined in line 73; used 5 times
w_nam_typ defined in line 302; used 1 times
windbp defined in line 254; used 5 times
windlook defined in line 273; used 2 times
winit defined in line 113; used 1 times

Defined variables

ScrollStep defined in line 174; used 7 times
curwind defined in line 18; used 75 times
fwind defined in line 19; used 34 times
onlyone defined in line 15; used 5 times
Last modified: 1986-04-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1768
Valid CSS Valid XHTML 1.0 Strict