# include "curses.ext" # define HARDTABS 8 int plodput(); char *tgoto(); /* * Terminal driving and line formatting routines. * Basic motion optimizations are done here as well * as formatting of lines (printing of control characters, * line numbering and the like). */ static int outcol, outline, destcol, destline, plodcnt; WINDOW *_win = NULL; mvcur(ly, lx, y, x) int ly, lx, y, x; { #ifdef DEBUG fprintf(outf, "MVCUR: moving cursor from (%d,%d) to (%d,%d)\n", ly, lx, y, x); #endif destcol = x; destline = y; outcol = lx; outline = ly; fgoto(); } fgoto() { reg char *cgp; reg int l, c; if(outcol < 0 || outcol >= COLS || outline < 0 || outline >= 0) { /* * wost. poloveniq */ if(destcol < 0 || destcol >= COLS || destline< 0 || destline>= COLS) destcol = destline = 0; if(CA) { cgp = tgoto(CM, destcol, destline); _puts(cgp); return; } if(HO) { _puts(HO); outcol = outline = 0; goto o1; } if(LL) { _puts(LL); outcol = 0; outline = LINES - 1; } o1:; } if(destcol < 0 || destcol >= COLS) destcol = outcol; if(destline< 0 || destline>= COLS) destline= outline; if (CA) { /* estx prqmaq adresaciq */ if (plod(strlen(cgp)) > 0) /* imeet smysl ee neispolxzowatx */ plod(0); /* a sdwigom */ else _puts(cgp); /* ina~e ispolxzuem */ } else plod(0); /* esli prqmoj adresacii net, to tolxko sdwig */ outline = destline; /* pome~aem, ~to priehali */ outcol = destcol; } extern bool plodflg; extern int plodcnt; /* * esli CNT == 0, to wypolnqet fakti~eskoe dvivenie, * w protiwnom slu~ae wozwra}aet 0, esli sgen. im prosled. * dlinnee CNT, ina~e ~islo simwolow, na kotoroe ego posled. koro~e * CNT */ plod(cnt) int cnt; { reg int i, j, k; reg int soutcol, soutline; reg char c; plodcnt = plodflg = cnt; soutcol = outcol; soutline = outline; if(destline < outline && UP == NULL) if(HO) goto dohome; else return(0); /* ne movem wypolnitx !!! */ if (HO) { /* estx HOME */ if (GT) i = (destcol / HARDTABS) + (destcol % HARDTABS); else i = destcol; /* I - ~erez na~alo */ if (destcol >= outcol) { j = destcol / HARDTABS - outcol / HARDTABS; if (GT && j) j += destcol % HARDTABS; else j = destcol - outcol; /* J - bez perem w na~alo */ } else if (outcol - destcol <= i && (BS || BC)) i = j = outcol - destcol; else j = i + 1; k = outline - destline; if (k < 0) k = -k; j += k; if (i + destline < j) { dohome: plodps(HO); outcol = outline = 0; } else if (LL) { k = (LINES - 1) - destline; if (i + k + 2 < j) { plodps(LL); outcol = 0; outline = LINES - 1; } } } if (GT) i = destcol % HARDTABS + destcol / HARDTABS; else i = destcol; /* if (BT && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) { j *= (k = strlen(BT)); if ((k += (destcol&7)) > 4) j += 8 - (destcol&7); else j += k; } else */ j = outcol - destcol; /* * If we will later need a \n which will turn into a \r\n by * the system or the terminal, then don't bother to try to \r. */ if (NONL && outline < destline) goto dontcr; /* * If the terminal will do a \r\n and there isn't room for it, * then we can't afford a \r. */ if (NC && outline >= destline) goto dontcr; /* * If it will be cheaper, or if we can't back up, then send * a return preliminarily. */ if (j > i + 1 || (outcol > destcol && !BS && !BC)) { plodput('\r'); if (NC) { plodput('\n'); outline++; } outcol = 0; } dontcr: while (outline < destline) { outline++; plodput('\n'); if (plodcnt < 0) goto out; if (NONL) outcol = 0; } while (outcol > destcol) { if (plodcnt < 0) goto out; /* if (BT) k = strlen(BT); if (BT && outcol - destcol > 4+k) { plodps(BT); outcol--; outcol &= ~7; continue; } */ outcol--; if (BC) plodps(BC); else plodput('\b'); } while (outline > destline) { outline--; plodps(UP); if (plodcnt < 0) goto out; } if (GT && destcol - outcol > 4) { for (;;) { i = (outcol / HARDTABS + 1) * HARDTABS; if (i > destcol) break; if (TA) plodps(TA); else plodput('\t'); outcol = i; } if (destcol - outcol > 4 && i < COLS && (BC || BS)) { if (TA) plodps(TA); else plodput('\t'); outcol = i; while (outcol > destcol) { outcol--; if (BC) plodps(BC); else plodput('\b'); } } } while (outcol < destcol) { if (_win != NULL) if (plodflg) /* avoid a complex calculation */ plodcnt--; else { c = _win->_y[outline-_win->_begy][outcol-_win->_begx]; if ((c&_STANDOUT) == (curscr->_flags&_STANDOUT)) _putchar(c); else goto nondes; } else nondes: if (ND) plodps(ND); else plodput(' '); outcol++; if (plodcnt < 0) goto out; } out: if (plodflg) { outcol = soutcol; outline = soutline; } return(plodcnt); } /* * Move (slowly) to destination. * Hard thing here is using home cursor on really deficient terminals. * Otherwise just use cursor motions, hacking use of tabs and overtabbing * and backspace. */ static bool plodflg; plodput(c) reg char c; { if (plodflg) plodcnt--; else { _putchar(c); #ifdef DEBUG fprintf(outf, "PLODPUT(%s)\n", unctrl(c)); #endif } } plodps(s) register char *s; { while(*s) plodput(*s++); }