1: /* Copyright (c) 1979 Regents of the University of California */
   2: #include "ex.h"
   3: #include "ex_tty.h"
   4: #include "ex_vis.h"
   5: 
   6: /*
   7:  * Routines to adjust the window, showing specified lines
   8:  * in certain positions on the screen, and scrolling in both
   9:  * directions.  Code here is very dependent on mode (open versus visual).
  10:  */
  11: 
  12: /*
  13:  * Move in a nonlocal way to line addr.
  14:  * If it isn't on screen put it in specified context.
  15:  * New position for cursor is curs.
  16:  * Like most routines here, we vsave().
  17:  */
  18: vmoveto(addr, curs, context)
  19:     register line *addr;
  20:     char *curs;
  21:     char context;
  22: {
  23: 
  24:     markit(addr);
  25:     vsave();
  26:     vjumpto(addr, curs, context);
  27: }
  28: 
  29: /*
  30:  * Vjumpto is like vmoveto, but doesn't mark previous
  31:  * context or save linebuf as current line.
  32:  */
  33: vjumpto(addr, curs, context)
  34:     register line *addr;
  35:     char *curs;
  36:     char context;
  37: {
  38: 
  39:     noteit(0);
  40:     if (context != 0)
  41:         vcontext(addr, context);
  42:     else
  43:         vshow(addr, NOLINE);
  44:     noteit(1);
  45:     vnline(curs);
  46: }
  47: 
  48: /*
  49:  * Go up or down cnt (negative is up) to new position curs.
  50:  */
  51: vupdown(cnt, curs)
  52:     register int cnt;
  53:     char *curs;
  54: {
  55: 
  56:     if (cnt > 0)
  57:         vdown(cnt, 0, 0);
  58:     else if (cnt < 0)
  59:         vup(-cnt, 0, 0);
  60:     if (vcnt == 0)
  61:         vrepaint(curs);
  62:     else
  63:         vnline(curs);
  64: }
  65: 
  66: /*
  67:  * Go up cnt lines, afterwards preferring to be ind
  68:  * logical lines from the top of the screen.
  69:  * If scroll, then we MUST use a scroll.
  70:  * Otherwise clear and redraw if motion is far.
  71:  */
  72: vup(cnt, ind, scroll)
  73:     register int cnt, ind;
  74:     bool scroll;
  75: {
  76:     register int i, tot;
  77: 
  78:     if (dot == one) {
  79:         beep();
  80:         return;
  81:     }
  82:     vsave();
  83:     i = lineDOT() - 1;
  84:     if (cnt > i) {
  85:         ind -= cnt - i;
  86:         if (ind < 0)
  87:             ind = 0;
  88:         cnt = i;
  89:     }
  90:     if (!scroll && cnt <= vcline) {
  91:         vshow(dot - cnt, NOLINE);
  92:         return;
  93:     }
  94:     cnt -= vcline, dot -= vcline, vcline = 0;
  95:     if (hold & HOLDWIG)
  96:         goto contxt;
  97:     if (
  98: #ifdef OPENCODE
  99:         state == VISUAL &&
 100: #endif
 101:         !AL && !SR &&
 102:         cnt <= WTOP - ZERO && vfit(dot - cnt, cnt) <= WTOP - ZERO)
 103:         goto okr;
 104:     tot = WECHO - ZERO;
 105:     if (
 106: #ifdef OPENCODE
 107:         state != VISUAL ||
 108: #endif
 109:         (!AL && !SR) || (!scroll && (cnt > tot || vfit(dot - cnt, cnt) > tot / 3 + 1))) {
 110:         if (ind > basWLINES / 2)
 111:             ind = basWLINES / 3;
 112: contxt:
 113:         vcontext(dot + ind - cnt, '.');
 114:         return;
 115:     }
 116: okr:
 117:     vrollR(cnt);
 118:     if (scroll) {
 119:         vcline += ind, dot += ind;
 120:         if (vcline >= vcnt)
 121:             dot -= vcline - vcnt + 1, vcline = vcnt - 1;
 122:         getDOT();
 123:     }
 124: }
 125: 
 126: /*
 127:  * Like vup, but scrolling down.
 128:  */
 129: vdown(cnt, ind, scroll)
 130:     register int cnt, ind;
 131:     bool scroll;
 132: {
 133:     register int i, tot;
 134: 
 135:     if (dot == dol) {
 136:         beep();
 137:         return;
 138:     }
 139:     vsave();
 140:     i = dol - dot;
 141:     if (cnt > i) {
 142:         ind -= cnt - i;
 143:         if (ind < 0)
 144:             ind = 0;
 145:         cnt = i;
 146:     }
 147:     i = vcnt - vcline - 1;
 148:     if (!scroll && cnt <= i) {
 149:         vshow(dot + cnt, NOLINE);
 150:         return;
 151:     }
 152:     cnt -= i, dot += i, vcline += i;
 153:     if (hold & HOLDWIG)
 154:         goto dcontxt;
 155:     if (!scroll) {
 156:         tot = WECHO - ZERO;
 157:         if (
 158: #ifdef OPENCODE
 159:             state != VISUAL ||
 160: #endif
 161:             cnt - tot > 0 || vfit(dot, cnt) > tot / 3 + 1) {
 162: dcontxt:
 163:             vcontext(dot + cnt, '.');
 164:             return;
 165:         }
 166:     }
 167:     if (cnt > 0)
 168:         vroll(cnt);
 169:     if (
 170: #ifdef OPENCODE
 171:         state == VISUAL &&
 172: #endif
 173:                            scroll) {
 174:         vcline -= ind, dot -= ind;
 175:         if (vcline < 0)
 176:             dot -= vcline, vcline = 0;
 177:         getDOT();
 178:     }
 179: }
 180: 
 181: /*
 182:  * Show line addr in context where on the screen.
 183:  * Work here is in determining new top line implied by
 184:  * this placement of line addr, since we always draw from the top.
 185:  */
 186: vcontext(addr, where)
 187:     register line *addr;
 188:     char where;
 189: {
 190:     register line *top;
 191: 
 192:     getline(*addr);
 193: #ifdef OPENCODE
 194:     if (state != VISUAL)
 195:         top = addr;
 196:     else
 197: #endif
 198:     switch (where) {
 199: 
 200:     case '^':
 201:         addr = vback(addr, basWLINES - vdepth());
 202:         getline(*addr);
 203:         /* fall into ... */
 204: 
 205:     case '-':
 206:         top = vback(addr, basWLINES - vdepth());
 207:         getline(*addr);
 208:         break;
 209: 
 210:     case '.':
 211:         top = vback(addr, basWLINES / 2 - vdepth());
 212:         getline(*addr);
 213:         break;
 214: 
 215:     default:
 216:         top = addr;
 217:         break;
 218:     }
 219: #ifdef OPENCODE
 220:     if (state == ONEOPEN && LINE(0) == WBOT)
 221:         vup1();
 222: #endif
 223:     vcnt = vcline = 0;
 224:     vclean();
 225: #ifdef OPENCODE
 226:     if (state == CRTOPEN)
 227:         vup1();
 228: #endif
 229:     vshow(addr, top);
 230: }
 231: 
 232: /*
 233:  * Get a clean line.  If we are in a hard open
 234:  * we may be able to reuse the line we are on
 235:  * if it is blank.  This is a real win.
 236:  */
 237: vclean()
 238: {
 239: 
 240: #ifdef OPENCODE
 241:     if (state != VISUAL && state != CRTOPEN) {
 242:         destcol = 0;
 243:         if (!ateopr())
 244:             vup1();
 245:         vcnt = 0;
 246:     }
 247: #endif
 248: }
 249: 
 250: /*
 251:  * Show line addr with the specified top line on the screen.
 252:  * Top may be 0; in this case have vcontext compute the top
 253:  * (and call us recursively).  Eventually, we clear the screen
 254:  * (or its open mode equivalent) and redraw.
 255:  */
 256: vshow(addr, top)
 257:     line *addr, *top;
 258: {
 259: #ifndef CBREAK
 260:     register bool fried = 0;
 261: #endif
 262:     register int cnt = addr - dot;
 263:     register int i = vcline + cnt;
 264:     short oldhold = hold;
 265: 
 266:     if (
 267: #ifdef OPENCODE
 268:         state != HARDOPEN && state != ONEOPEN &&
 269: #endif
 270:                                                  i >= 0 && i < vcnt) {
 271:         dot = addr;
 272:         getDOT();
 273:         vcline = i;
 274:         return;
 275:     }
 276: #ifdef OPENCODE
 277:     if (state != VISUAL) {
 278:         dot = addr;
 279:         vopen(dot, WBOT);
 280:         return;
 281:     }
 282: #endif
 283:     if (top == 0) {
 284:         vcontext(addr, '.');
 285:         return;
 286:     }
 287:     dot = top;
 288: #ifndef CBREAK
 289:     if (vcookit(2))
 290:         fried++, vcook();
 291: #endif
 292:     oldhold = hold;
 293:     hold |= HOLDAT;
 294:     vclear();
 295:     vreset(0);
 296:     vredraw(WTOP);
 297:     /* error if vcline >= vcnt ! */
 298:     vcline = addr - top;
 299:     dot = addr;
 300:     getDOT();
 301:     hold = oldhold;
 302:     vsync(LASTLINE);
 303: #ifndef CBREAK
 304:     if (fried)
 305:         flusho(), vraw();
 306: #endif
 307: }
 308: 
 309: /*
 310:  * reset the state.
 311:  * If inecho then leave us at the beginning of the echo
 312:  * area;  we are called this way in the middle of a :e escape
 313:  * from visual, e.g.
 314:  */
 315: vreset(inecho)
 316:     bool inecho;
 317: {
 318: 
 319:     vcnt = vcline = 0;
 320:     WTOP = basWTOP;
 321:     WLINES = basWLINES;
 322:     if (inecho)
 323:         splitw = 1, vgoto(WECHO, 0);
 324: }
 325: 
 326: /*
 327:  * Starting from which line preceding tp uses almost (but not more
 328:  * than) cnt physical lines?
 329:  */
 330: line *
 331: vback(tp, cnt)
 332:     register int cnt;
 333:     register line *tp;
 334: {
 335:     register int d;
 336: 
 337:     if (cnt > 0)
 338:         for (; tp > one; tp--) {
 339:             getline(tp[-1]);
 340:             d = vdepth();
 341:             if (d > cnt)
 342:                 break;
 343:             cnt -= d;
 344:         }
 345:     return (tp);
 346: }
 347: 
 348: /*
 349:  * How much scrolling will it take to roll cnt lines starting at tp?
 350:  */
 351: vfit(tp, cnt)
 352:     register line *tp;
 353:     int cnt;
 354: {
 355:     register int j;
 356: 
 357:     j = 0;
 358:     while (cnt > 0) {
 359:         cnt--;
 360:         getline(tp[cnt]);
 361:         j += vdepth();
 362:     }
 363:     if (tp > dot)
 364:         j -= WBOT - LASTLINE;
 365:     return (j);
 366: }
 367: 
 368: /*
 369:  * Roll cnt lines onto the screen.
 370:  */
 371: vroll(cnt)
 372:     register int cnt;
 373: {
 374: #ifndef CBREAK
 375:     register bool fried = 0;
 376: #endif
 377:     short oldhold = hold;
 378: 
 379: #ifdef ADEBUG
 380:     if (trace)
 381:         tfixnl(), fprintf(trace, "vroll(%d)\n", cnt);
 382: #endif
 383: #ifdef OPENCODE
 384:     if (state != VISUAL)
 385:         hold |= HOLDAT|HOLDROL;
 386: #endif
 387:     if (WBOT == WECHO) {
 388:         vcnt = 0;
 389: #ifdef OPENCODE
 390:         if (state == ONEOPEN)
 391:             vup1();
 392: #endif
 393:     }
 394: #ifndef CBREAK
 395:     if (vcookit(cnt))
 396:         fried++, vcook();
 397: #endif
 398:     for (; cnt > 0 && Peekkey != ATTN; cnt--) {
 399:         dot++, vcline++;
 400:         vopen(dot, LASTLINE);
 401:         vscrap();
 402:     }
 403:     hold = oldhold;
 404: #ifdef OPENCODE
 405:     if (state == HARDOPEN)
 406:         sethard();
 407: #endif
 408:     vsyncCL();
 409: #ifndef CBREAK
 410:     if (fried)
 411:         flusho(), vraw();
 412: #endif
 413: }
 414: 
 415: /*
 416:  * Roll backwards (scroll up).
 417:  */
 418: vrollR(cnt)
 419:     register int cnt;
 420: {
 421:     register bool fried = 0;
 422:     short oldhold = hold;
 423: 
 424: #ifdef ADEBUG
 425:     if (trace)
 426:         tfixnl(), fprintf(trace, "vrollR(%d), dot=%d\n", cnt, lineDOT());
 427: #endif
 428: #ifndef CBREAK
 429:     if (vcookit(cnt))
 430:         fried++, vcook();
 431: #endif
 432:     if (WBOT == WECHO)
 433:         vcnt = 0;
 434:     heldech = 0;
 435:     hold |= HOLDAT|HOLDECH;
 436:     for (; cnt > 0 && Peekkey != ATTN; cnt--) {
 437:         dot--;
 438:         vopen(dot, WTOP);
 439:         vscrap();
 440:     }
 441:     hold = oldhold;
 442:     if (heldech)
 443:         vclrech(0);
 444:     vsync(LINE(vcnt-1));
 445: #ifndef CBREAK
 446:     if (fried)
 447:         flusho(), vraw();
 448: #endif
 449: }
 450: 
 451: /*
 452:  * Go into cooked mode (allow interrupts) during
 453:  * a scroll if we are at less than 1200 baud and not
 454:  * a 'vi' command, of if we are in a 'vi' command and the
 455:  * scroll is more than 2 full screens.
 456:  *
 457:  * BUG:		An interrupt during a scroll in this way
 458:  *		dumps to command mode.
 459:  */
 460: vcookit(cnt)
 461:     register int cnt;
 462: {
 463: 
 464:     return (cnt > 1 && (ospeed < B1200 && !initev || cnt > LINES * 2));
 465: }
 466: 
 467: /*
 468:  * Determine displayed depth of current line.
 469:  */
 470: vdepth()
 471: {
 472:     register int d;
 473: 
 474:     d = (column(NOSTR) + WCOLS - 1 + (Putchar == listchar) + IN) / WCOLS;
 475: #ifdef ADEBUG
 476:     if (trace)
 477:         tfixnl(), fprintf(trace, "vdepth returns %d\n", d == 0 ? 1 : d);
 478: #endif
 479:     return (d == 0 ? 1 : d);
 480: }
 481: 
 482: /*
 483:  * Move onto a new line, with cursor at position curs.
 484:  */
 485: vnline(curs)
 486:     char *curs;
 487: {
 488: 
 489:     if (curs)
 490:         wcursor = curs;
 491:     else if (vmoving)
 492:         wcursor = vfindcol(vmovcol);
 493:     else
 494:         wcursor = vskipwh(linebuf);
 495:     cursor = linebuf;
 496:     vmove();
 497: }

Defined functions

vback defined in line 330; used 4 times
vcontext defined in line 186; used 6 times
vcookit defined in line 460; used 3 times
vdepth defined in line 470; used 20 times
vdown defined in line 129; used 2 times
vfit defined in line 351; used 3 times
vmoveto defined in line 18; used 1 times
vreset defined in line 315; used 1 times
vroll defined in line 371; used 2 times
vrollR defined in line 418; used 1 times
vshow defined in line 256; used 7 times
vup defined in line 72; used 2 times
vupdown defined in line 51; used 2 times
Last modified: 1980-09-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1388
Valid CSS Valid XHTML 1.0 Strict