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

Defined functions

vback defined in line 300; used 4 times
vcontext defined in line 171; used 6 times
vcookit defined in line 424; used 3 times
vdepth defined in line 434; used 20 times
vdown defined in line 122; used 3 times
vfit defined in line 321; used 3 times
vmoveto defined in line 19; used 1 times
vreset defined in line 285; used 1 times
vroll defined in line 341; used 2 times
vrollR defined in line 382; used 1 times
vshow defined in line 232; used 7 times
vup defined in line 73; used 3 times
vupdown defined in line 52; used 2 times

Defined variables

sccsid defined in line 2; never used
Last modified: 1981-07-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1386
Valid CSS Valid XHTML 1.0 Strict