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