/* * Scroll the screen up cnt lines physically. * If doclr is true, do a clear eol if the terminal * has standout (to prevent it from scrolling up) */ void vmoveitup(register int cnt, int doclr) { if (cnt == 0) return; #ifdef ADEBUG if (trace) tfixnl(), fprintf(trace, "vmoveitup(%d)\n", cnt); #endif if (doclr && (SO || SE)) vclrech(0); if (SF) { destline = WECHO; destcol = (NONL ? 0 : outcol % WCOLS); fgoto(); while (cnt > 0) vputp(SF, 0), cnt--; return; } destline = WECHO + cnt; destcol = (NONL ? 0 : outcol % WCOLS); fgoto(); if (state == ONEOPEN || state == HARDOPEN) { outline = destline = 0; vclrcell(vtube[0], WCOLS); } }
/* * Termchar routine for command mode. * Watch for possible switching to -nl mode. * Otherwise flush into next level of buffering when * small buffer fills or at a newline. */ int termchar(int c) { if (pfast == 0 && phadnl) pstart(); if (c == '\n') phadnl = 1; else if (linp >= &linb[63]) flush1(); #ifdef MB if (mb_cur_max > 1 && c & ~(wchar_t)0177) { char mb[MB_LEN_MAX]; int i, n; n = wctomb(mb, c&TRIM); for (i = 0; i < n; i++) *linp++ = mb[i]; } else #endif /* MB */ *linp++ = c; if (linp >= &linb[63]) { fgoto(); flush1(); } return c; }
/* * Try to start -nl mode. */ void pstart(void) { if (NONL) return; if (!value(OPTIMIZE)) return; if (ruptible == 0 || pfast) return; fgoto(); flusho(); pfast = 1; normtty++; tty = normf; tty.c_oflag &= ~(ONLCR #if defined (TAB3) | TAB3 #elif defined (XTABS) | XTABS #endif ); tty.c_lflag &= ~ECHO; sTTY(1); }
void flush2(void) { fgoto(); flusho(); pstop(); }
/* * Stop open, restoring tty modes. */ void ostop(struct termios f) { pfast = (f.c_oflag & ONLCR) == 0; termreset(), fgoto(), flusho(); normal(f); tostop(); }
/* * Termchar routine for command mode. * Watch for possible switching to -nl mode. * Otherwise flush into next level of buffering when * small buffer fills or at a newline. */ void termchar(int c) { if (pfast == 0 && phadnl) pstart(); if (c == '\n') phadnl = 1; else if (linp >= &linb[63]) flush1(); *linp++ = c; if (linp >= &linb[63]) { fgoto(); flush1(); } }
/* * Sync the position of the output cursor. * Most work here is rounding for terminal boundaries getting the * column position implied by wraparound or the lack thereof and * rolling up the screen to get destline on the screen. */ void fgoto(void) { register int l, c; if (destcol > TCOLUMNS - 1) { destline += destcol / TCOLUMNS; destcol %= TCOLUMNS; } if (outcol > TCOLUMNS - 1) { l = (outcol + 1) / TCOLUMNS; outline += l; outcol %= TCOLUMNS; if (AM == 0) { while (l > 0) { if (pfast && ospeed != B0) if (xCR) tputs(xCR, 0, putch); else putch('\r'); if (xNL) tputs(xNL, 0, putch); else putch('\n'); l--; } outcol = 0; } if (outline > TLINES - 1) { destline -= outline - (TLINES - 1); outline = TLINES - 1; } } if (destline > TLINES - 1) { l = destline; destline = TLINES - 1; if (outline < TLINES - 1) { c = destcol; if (pfast == 0 && (!CA || holdcm)) destcol = 0; fgoto(); destcol = c; } while (l > TLINES - 1) { /* * The following linefeed (or simulation thereof) * is supposed to scroll up the screen, since we * are on the bottom line. We make the assumption * that linefeed will scroll. If ns is in the * capability list this won't work. We should * probably have an sc capability but sf will * generally take the place if it works. * * Superbee glitch: in the middle of the screen we * have to use esc B (down) because linefeed screws up * in "Efficient Paging" (what a joke) mode (which is * essential in some SB's because CRLF mode puts garbage * in at end of memory), but you must use linefeed to * scroll since down arrow won't go past memory end. * I turned this off after recieving Paul Eggert's * Superbee description which wins better. */ if (xNL /* && !XB */ && pfast) tputs(xNL, 0, putch); else putch('\n'); l--; if (pfast == 0) outcol = 0; } } if (destline < outline && !(CA && !holdcm || UP != NOSTR)) destline = outline; if (CA && !holdcm) if (plod(costCM) > 0) plod(0); else tputs(tgoto(CM, destcol, destline), 0, putch); else plod(0); outline = destline; outcol = destcol; }
/* * Flush from small line buffer into output buffer. * Work here is destroying motion into positions, and then * letting fgoto do the optimized motion. */ void flush1(void) { register char *lp; int c, n; *linp = 0; lp = linb; while (*lp) { nextc(c, lp, n); lp += n; switch (c) { case '\r': destline += destcol / TCOLUMNS; destcol = 0; continue; case '\b': if (destcol) destcol--; continue; case ' ': destcol++; continue; case '\t': destcol += value(TABSTOP) - destcol % value(TABSTOP); continue; case '\n': destline += destcol / TCOLUMNS + 1; if (destcol != 0 && destcol % TCOLUMNS == 0) destline--; destcol = 0; continue; default: fgoto(); for (;;) { if (AM == 0 && outcol == TCOLUMNS) fgoto(); c &= TRIM; putch(c); if (c == '\b') { outcol--; destcol--; #ifndef BIT8 } else if ( c >= ' ' && c != DELETE) { #else } else if (printable(c)) { #endif #ifdef MB n = colsc(c); outcol += n; destcol += n; #else /* !MB */ outcol++; destcol++; #endif /* !MB */ if (XN && outcol % TCOLUMNS == 0) putch('\r'), putch('\n'); } nextc(c, lp, n); lp += n; #ifndef BIT8 if (c <= ' ') #else if (c == ' ' || !printable(c)) #endif break; } --lp; continue; } } linp = linb; }
/* * Flush from small line buffer into output buffer. * Work here is destroying motion into positions, and then * letting fgoto do the optimized motion. */ void flush1(void) { register char *lp; register short c; *linp = 0; lp = linb; while (*lp) switch (c = *lp++) { case '\r': destline += destcol / COLUMNS; destcol = 0; continue; case '\b': if (destcol) destcol--; continue; case ' ': destcol++; continue; case '\t': destcol += value(TABSTOP) - destcol % value(TABSTOP); continue; case '\n': destline += destcol / COLUMNS + 1; if (destcol != 0 && destcol % COLUMNS == 0) destline--; destcol = 0; continue; default: fgoto(); for (;;) { if (AM == 0 && outcol == COLUMNS) fgoto(); c &= TRIM; putch(c); if (c == '\b') { outcol--; destcol--; } else if (c >= ' ' && c != DELETE) { outcol++; destcol++; if (XN && outcol % COLUMNS == 0) putch('\r'), putch('\n'); } c = *lp++; if (c <= ' ') break; } --lp; continue; } linp = linb; }
/* * Move cursor to line y, column x, handling wraparound and scrolling. */ void vgoto(register int y, register int x) { register cell *tp; register int c; /* * Fold the possibly too large value of x. */ if (x >= WCOLS) { y += x / WCOLS; x %= WCOLS; } #ifdef MB if (y >= 0 && y <= WLINES && mb_cur_max > 1 && !insmode) { while (x > 0 && (vtube[y][x]&(MULTICOL|TRIM)) == MULTICOL && vtube[y][x-1] & MULTICOL && (vtube[y][x-1]&(MULTICOL|TRIM)) != MULTICOL) x--; } #endif /* MB */ if (y < 0) error(catgets(catd, 1, 238, "Internal error: vgoto")); if (outcol >= WCOLS) { if (AM) { outline += outcol / WCOLS; outcol %= WCOLS; } else outcol = WCOLS - 1; } /* * In a hardcopy or glass crt open, print the stuff * implied by a motion, or backspace. */ if (state == HARDOPEN || state == ONEOPEN) { if (y != outline) error(catgets(catd, 1, 239, "Line too long for open")); if (x + 1 < outcol - x || (outcol > x && !BS)) destcol = 0, fgoto(); tp = vtube[WBOT] + outcol; while (outcol != x) if (outcol < x) { if (*tp == 0) *tp = ' '; c = *tp++ & TRIM; vputc(c && (!OS || EO) ? c : ' '); outcol++; } else { if (BC) vputp(BC, 0); else vputc('\b'); outcol--; } destcol = outcol = x; destline = outline; return; } /* * If the destination position implies a scroll, do it. */ destline = y; if (destline > WBOT && (!splitw || destline > WECHO)) { endim(); vrollup(destline); } /* * If there really is a motion involved, do it. * The check here is an optimization based on profiling. */ destcol = x; if ((destline - outline) * WCOLS != destcol - outcol) { if (!MI) endim(); fgoto(); } }