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

Defined functions

vback defined in line 308; used 4 times
vcontext defined in line 179; used 6 times
vcookit defined in line 432; used 3 times
vdepth defined in line 442; used 20 times
vdown defined in line 130; used 3 times
vfit defined in line 329; used 3 times
vjumpto defined in line 42; used 9 times
vmoveto defined in line 27; used 1 times
vreset defined in line 293; used 1 times
vroll defined in line 349; used 2 times
vrollR defined in line 390; used 1 times
vshow defined in line 240; used 7 times
vup defined in line 81; used 3 times
vupdown defined in line 60; used 2 times

Defined variables

sccsid defined in line 8; never used
Last modified: 1985-06-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1736
Valid CSS Valid XHTML 1.0 Strict