|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.