1: # include   "curses.ext"
   2: 
   3: # define    HARDTABS    8
   4: 
   5: extern char *tgoto();
   6: int     plodput();
   7: 
   8: /*
   9:  * Terminal driving and line formatting routines.
  10:  * Basic motion optimizations are done here as well
  11:  * as formatting of lines (printing of control characters,
  12:  * line numbering and the like).
  13:  *
  14:  * 3/27/83 (Berkeley) @(#)cr_put.c	1.4
  15:  */
  16: 
  17: /*
  18:  * Sync the position of the output cursor.
  19:  * Most work here is rounding for terminal boundaries getting the
  20:  * column position implied by wraparound or the lack thereof and
  21:  * rolling up the screen to get destline on the screen.
  22:  */
  23: 
  24: static int  outcol, outline, destcol, destline;
  25: 
  26: WINDOW      *_win;
  27: 
  28: mvcur(ly, lx, y, x)
  29: int ly, lx, y, x; {
  30: 
  31: #ifdef DEBUG
  32:     fprintf(outf, "MVCUR: moving cursor from (%d,%d) to (%d,%d)\n", ly, lx, y, x);
  33: #endif
  34:     destcol = x;
  35:     destline = y;
  36:     outcol = lx;
  37:     outline = ly;
  38:     fgoto();
  39: }
  40: 
  41: char
  42: _putchar(c)
  43: reg char    c; {
  44: 
  45:     putchar(c);
  46: #ifdef DEBUG
  47:     fprintf(outf, "_PUTCHAR(%s)\n", unctrl(c));
  48: #endif
  49: }
  50: 
  51: fgoto()
  52: {
  53:     reg char    *cgp;
  54:     reg int     l, c;
  55: 
  56:     if (destcol > COLS - 1) {
  57:         destline += destcol / COLS;
  58:         destcol %= COLS;
  59:     }
  60:     if (outcol > COLS - 1) {
  61:         l = (outcol + 1) / COLS;
  62:         outline += l;
  63:         outcol %= COLS;
  64:         if (AM == 0) {
  65:             while (l > 0) {
  66:                 if (_pfast)
  67:                     if (CR)
  68:                         tputs(CR, 0, _putchar);
  69:                     else
  70:                         _putchar('\r');
  71:                 if (NL)
  72:                     tputs(NL, 0, _putchar);
  73:                 else
  74:                     _putchar('\n');
  75:                 l--;
  76:             }
  77:             outcol = 0;
  78:         }
  79:         if (outline > LINES - 1) {
  80:             destline -= outline - (LINES - 1);
  81:             outline = LINES - 1;
  82:         }
  83:     }
  84:     if (destline > LINES - 1) {
  85:         l = destline;
  86:         destline = LINES - 1;
  87:         if (outline < LINES - 1) {
  88:             c = destcol;
  89:             if (_pfast == 0 && !CA)
  90:                 destcol = 0;
  91:             fgoto();
  92:             destcol = c;
  93:         }
  94:         while (l > LINES - 1) {
  95:             /*
  96: 			 * The following linefeed (or simulation thereof)
  97: 			 * is supposed to scroll up the screen, since we
  98: 			 * are on the bottom line.  We make the assumption
  99: 			 * that linefeed will scroll.  If ns is in the
 100: 			 * capability list this won't work.  We should
 101: 			 * probably have an sc capability but sf will
 102: 			 * generally take the place if it works.
 103: 			 *
 104: 			 * Superbee glitch:  in the middle of the screen we
 105: 			 * have to use esc B (down) because linefeed screws up
 106: 			 * in "Efficient Paging" (what a joke) mode (which is
 107: 			 * essential in some SB's because CRLF mode puts garbage
 108: 			 * in at end of memory), but you must use linefeed to
 109: 			 * scroll since down arrow won't go past memory end.
 110: 			 * I turned this off after recieving Paul Eggert's
 111: 			 * Superbee description which wins better.
 112: 			 */
 113:             if (NL /* && !XB */ && _pfast)
 114:                 tputs(NL, 0, _putchar);
 115:             else
 116:                 _putchar('\n');
 117:             l--;
 118:             if (_pfast == 0)
 119:                 outcol = 0;
 120:         }
 121:     }
 122:     if (destline < outline && !(CA || UP))
 123:         destline = outline;
 124:     if (CA)
 125:     {
 126:         cgp = tgoto(CM, destcol, destline);
 127:         if (plod(strlen(cgp)) > 0)
 128:             plod(0);
 129:         else
 130:             tputs(cgp, 0, _putchar);
 131:     }
 132:     else
 133:         plod(0);
 134:     outline = destline;
 135:     outcol = destcol;
 136: }
 137: 
 138: /*
 139:  * Move (slowly) to destination.
 140:  * Hard thing here is using home cursor on really deficient terminals.
 141:  * Otherwise just use cursor motions, hacking use of tabs and overtabbing
 142:  * and backspace.
 143:  */
 144: 
 145: static int plodcnt, plodflg;
 146: 
 147: plodput(c)
 148: {
 149:     if (plodflg)
 150:         plodcnt--;
 151:     else
 152:         _putchar(c);
 153: }
 154: 
 155: plod(cnt)
 156: {
 157:     register int i, j, k;
 158:     register int soutcol, soutline;
 159: 
 160:     plodcnt = plodflg = cnt;
 161:     soutcol = outcol;
 162:     soutline = outline;
 163:     /*
 164: 	 * Consider homing and moving down/right from there, vs moving
 165: 	 * directly with local motions to the right spot.
 166: 	 */
 167:     if (HO) {
 168:         /*
 169: 		 * i is the cost to home and tab/space to the right to
 170: 		 * get to the proper column.  This assumes ND space costs
 171: 		 * 1 char.  So i+destcol is cost of motion with home.
 172: 		 */
 173:         if (GT)
 174:             i = (destcol / HARDTABS) + (destcol % HARDTABS);
 175:         else
 176:             i = destcol;
 177:         /*
 178: 		 * j is cost to move locally without homing
 179: 		 */
 180:         if (destcol >= outcol) {    /* if motion is to the right */
 181:             j = destcol / HARDTABS - outcol / HARDTABS;
 182:             if (GT && j)
 183:                 j += destcol % HARDTABS;
 184:             else
 185:                 j = destcol - outcol;
 186:         }
 187:         else
 188:             /* leftward motion only works if we can backspace. */
 189:             if (outcol - destcol <= i && (BS || BC))
 190:                 i = j = outcol - destcol; /* cheaper to backspace */
 191:             else
 192:                 j = i + 1; /* impossibly expensive */
 193: 
 194:         /* k is the absolute value of vertical distance */
 195:         k = outline - destline;
 196:         if (k < 0)
 197:             k = -k;
 198:         j += k;
 199: 
 200:         /*
 201: 		 * Decision.  We may not have a choice if no UP.
 202: 		 */
 203:         if (i + destline < j || (!UP && destline < outline)) {
 204:             /*
 205: 			 * Cheaper to home.  Do it now and pretend it's a
 206: 			 * regular local motion.
 207: 			 */
 208:             tputs(HO, 0, plodput);
 209:             outcol = outline = 0;
 210:         }
 211:         else if (LL) {
 212:             /*
 213: 			 * Quickly consider homing down and moving from there.
 214: 			 * Assume cost of LL is 2.
 215: 			 */
 216:             k = (LINES - 1) - destline;
 217:             if (i + k + 2 < j && (k<=0 || UP)) {
 218:                 tputs(LL, 0, plodput);
 219:                 outcol = 0;
 220:                 outline = LINES - 1;
 221:             }
 222:         }
 223:     }
 224:     else
 225:     /*
 226: 	 * No home and no up means it's impossible.
 227: 	 */
 228:         if (!UP && destline < outline)
 229:             return -1;
 230:     if (GT)
 231:         i = destcol % HARDTABS + destcol / HARDTABS;
 232:     else
 233:         i = destcol;
 234: /*
 235: 	if (BT && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) {
 236: 		j *= (k = strlen(BT));
 237: 		if ((k += (destcol&7)) > 4)
 238: 			j += 8 - (destcol&7);
 239: 		else
 240: 			j += k;
 241: 	}
 242: 	else
 243: */
 244:         j = outcol - destcol;
 245:     /*
 246: 	 * If we will later need a \n which will turn into a \r\n by
 247: 	 * the system or the terminal, then don't bother to try to \r.
 248: 	 */
 249:     if ((NONL || !_pfast) && outline < destline)
 250:         goto dontcr;
 251:     /*
 252: 	 * If the terminal will do a \r\n and there isn't room for it,
 253: 	 * then we can't afford a \r.
 254: 	 */
 255:     if (NC && outline >= destline)
 256:         goto dontcr;
 257:     /*
 258: 	 * If it will be cheaper, or if we can't back up, then send
 259: 	 * a return preliminarily.
 260: 	 */
 261:     if (j > i + 1 || outcol > destcol && !BS && !BC) {
 262:         /*
 263: 		 * BUG: this doesn't take the (possibly long) length
 264: 		 * of CR into account.
 265: 		 */
 266:         if (CR)
 267:             tputs(CR, 0, plodput);
 268:         else
 269:             plodput('\r');
 270:         if (NC) {
 271:             if (NL)
 272:                 tputs(NL, 0, plodput);
 273:             else
 274:                 plodput('\n');
 275:             outline++;
 276:         }
 277:         outcol = 0;
 278:     }
 279: dontcr:
 280:     while (outline < destline) {
 281:         outline++;
 282:         if (NL && _pfast)
 283:             tputs(NL, 0, plodput);
 284:         else
 285:             plodput('\n');
 286:         if (plodcnt < 0)
 287:             goto out;
 288:         if (NONL || _pfast == 0)
 289:             outcol = 0;
 290:     }
 291:     if (BT)
 292:         k = strlen(BT);
 293:     while (outcol > destcol) {
 294:         if (plodcnt < 0)
 295:             goto out;
 296: /*
 297: 		if (BT && outcol - destcol > k + 4) {
 298: 			tputs(BT, 0, plodput);
 299: 			outcol--;
 300: 			outcol &= ~7;
 301: 			continue;
 302: 		}
 303: */
 304:         outcol--;
 305:         if (BC)
 306:             tputs(BC, 0, plodput);
 307:         else
 308:             plodput('\b');
 309:     }
 310:     while (outline > destline) {
 311:         outline--;
 312:         tputs(UP, 0, plodput);
 313:         if (plodcnt < 0)
 314:             goto out;
 315:     }
 316:     if (GT && destcol - outcol > 1) {
 317:         for (;;) {
 318:             i = tabcol(outcol, HARDTABS);
 319:             if (i > destcol)
 320:                 break;
 321:             if (TA)
 322:                 tputs(TA, 0, plodput);
 323:             else
 324:                 plodput('\t');
 325:             outcol = i;
 326:         }
 327:         if (destcol - outcol > 4 && i < COLS && (BC || BS)) {
 328:             if (TA)
 329:                 tputs(TA, 0, plodput);
 330:             else
 331:                 plodput('\t');
 332:             outcol = i;
 333:             while (outcol > destcol) {
 334:                 outcol--;
 335:                 if (BC)
 336:                     tputs(BC, 0, plodput);
 337:                 else
 338:                     plodput('\b');
 339:             }
 340:         }
 341:     }
 342:     while (outcol < destcol) {
 343:         /*
 344: 		 * move one char to the right.  We don't use ND space
 345: 		 * because it's better to just print the char we are
 346: 		 * moving over.
 347: 		 */
 348:         if (_win != NULL)
 349:             if (plodflg)    /* avoid a complex calculation */
 350:                 plodcnt--;
 351:             else {
 352:                 i = curscr->_y[outline][outcol];
 353:                 if ((i&_STANDOUT) == (curscr->_flags&_STANDOUT))
 354:                     putchar(i);
 355:                 else
 356:                     goto nondes;
 357:             }
 358:         else
 359: nondes:
 360:              if (ND)
 361:             tputs(ND, 0, plodput);
 362:         else
 363:             plodput(' ');
 364:         outcol++;
 365:         if (plodcnt < 0)
 366:             goto out;
 367:     }
 368: out:
 369:     if (plodflg) {
 370:         outcol = soutcol;
 371:         outline = soutline;
 372:     }
 373:     return(plodcnt);
 374: }
 375: 
 376: /*
 377:  * Return the column number that results from being in column col and
 378:  * hitting a tab, where tabs are set every ts columns.  Work right for
 379:  * the case where col > COLS, even if ts does not divide COLS.
 380:  */
 381: tabcol(col, ts)
 382: int col, ts;
 383: {
 384:     int offset, result;
 385: 
 386:     if (col >= COLS) {
 387:         offset = COLS * (col / COLS);
 388:         col -= offset;
 389:     }
 390:     else
 391:         offset = 0;
 392:     return col + ts - (col % ts) + offset;
 393: }

Defined functions

_putchar defined in line 41; used 8 times
fgoto defined in line 51; used 2 times
mvcur defined in line 28; used 2 times
plod defined in line 155; used 3 times
plodput defined in line 147; used 20 times

Defined variables

destcol defined in line 24; used 29 times
destline defined in line 24; used 19 times
outcol defined in line 24; used 32 times
outline defined in line 24; used 24 times
plodcnt defined in line 145; used 8 times
plodflg defined in line 145; used 4 times

Defined macros

HARDTABS defined in line 3; used 8 times
Last modified: 1983-05-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1047
Valid CSS Valid XHTML 1.0 Strict