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

Defined functions

fgoto defined in line 49; used 2 times
plod defined in line 152; used 3 times
plodput defined in line 144; used 20 times
tabcol defined in line 378; used 1 times

Defined variables

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

Defined macros

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