diff options
Diffstat (limited to 'contrib/ncurses/ncurses/tty/tty_update.c')
-rw-r--r-- | contrib/ncurses/ncurses/tty/tty_update.c | 261 |
1 files changed, 134 insertions, 127 deletions
diff --git a/contrib/ncurses/ncurses/tty/tty_update.c b/contrib/ncurses/ncurses/tty/tty_update.c index b8670cd15f1d..298c11ed0a21 100644 --- a/contrib/ncurses/ncurses/tty/tty_update.c +++ b/contrib/ncurses/ncurses/tty/tty_update.c @@ -70,7 +70,7 @@ #include <term.h> -MODULE_ID("$Id: tty_update.c,v 1.139 2000/06/24 23:45:17 tom Exp $") +MODULE_ID("$Id: tty_update.c,v 1.146 2000/10/07 01:11:44 tom Exp $") /* * This define controls the line-breakout optimization. Every once in a @@ -112,15 +112,24 @@ position_check(int expected_y, int expected_x, char *legend) /* check to see if the real cursor position matches the virtual */ { char buf[20]; + char *s; int y, x; if (!_nc_tracing || (expected_y < 0 && expected_x < 0)) return; + _nc_flush(); memset(buf, '\0', sizeof(buf)); putp("\033[6n"); /* only works on ANSI-compatibles */ _nc_flush(); - (void) read(0, buf, sizeof(buf) - 1); + *(s = buf) = 0; + do { + int ask = sizeof(buf) - 1 - (s - buf); + int got = read(0, s, ask); + if (got == 0) + break; + s += got; + } while (strchr(buf, 'R') == 0); _tracef("probe returned %s", _nc_visbuf(buf)); /* try to interpret as a position report */ @@ -133,8 +142,9 @@ position_check(int expected_y, int expected_x, char *legend) expected_y = y - 1; if (y - 1 != expected_y || x - 1 != expected_x) { beep(); + tputs(tparm("\033[%d;%dH", expected_y + 1, expected_x + 1), 1, _nc_outch); _tracef("position seen (%d, %d) doesn't match expected one (%d, %d) in %s", - y - 1, x - 1, expected_y, expected_x, legend); + y - 1, x - 1, expected_y, expected_x, legend); } else { _tracef("position matches OK in %s", legend); } @@ -156,7 +166,7 @@ GoTo(int const row, int const col) chtype oldattr = SP->_current_attr; TR(TRACE_MOVE, ("GoTo(%d, %d) from (%d, %d)", - row, col, SP->_cursrow, SP->_curscol)); + row, col, SP->_cursrow, SP->_curscol)); position_check(SP->_cursrow, SP->_curscol, "GoTo"); @@ -168,7 +178,7 @@ GoTo(int const row, int const col) if ((oldattr & A_ALTCHARSET) || (oldattr && !move_standout_mode)) { TR(TRACE_CHARPUT, ("turning off (%#lx) %s before move", - oldattr, _traceattr(oldattr))); + oldattr, _traceattr(oldattr))); vidattr(A_NORMAL); } @@ -187,8 +197,8 @@ PutAttrChar(chtype ch) ch = ('`' | AttrOf(ch)); TR(TRACE_CHARPUT, ("PutAttrChar(%s) at (%d, %d)", - _tracechtype(ch), - SP->_cursrow, SP->_curscol)); + _tracechtype(ch), + SP->_cursrow, SP->_curscol)); UpdateAttrs(ch); data = TextOf(ch); if (SP->_outch != 0) { @@ -295,7 +305,7 @@ PutCharLR(chtype const ch) TPUTS_TRACE("enter_am_mode"); putp(enter_am_mode); } else if ((enter_insert_mode && exit_insert_mode) - || insert_character || parm_ich) { + || insert_character || parm_ich) { GoTo(screen_lines - 1, screen_columns - 2); callPutChar(ch); GoTo(screen_lines - 1, screen_columns - 2); @@ -361,7 +371,7 @@ can_clear_with(chtype ch) if (!back_color_erase && SP->_coloron) { if (ch & A_COLOR) return FALSE; -#ifdef NCURSES_EXT_FUNCS +#if NCURSES_EXT_FUNCS if (!SP->_default_color) return FALSE; if (SP->_default_fg != C_MASK || SP->_default_bg != C_MASK) @@ -427,10 +437,11 @@ EmitRange(const chtype * ntext, int num) * don't bother moving cursor, since it can be the * last update on the line. */ - if (runcount < num) + if (runcount < num) { GoTo(SP->_cursrow, SP->_curscol + runcount); - else + } else { return 1; /* cursor stays in the middle */ + } } else if (repeat_char && runcount > SP->_rep_cost) { bool wrap_possible = (SP->_curscol + runcount >= screen_columns); int rep_count = runcount; @@ -469,15 +480,15 @@ EmitRange(const chtype * ntext, int num) */ static int PutRange( - const chtype * otext, - const chtype * ntext, - int row, - int first, int last) + const chtype * otext, + const chtype * ntext, + int row, + int first, int last) { int j, run; TR(TRACE_CHARPUT, ("PutRange(%p, %p, %d, %d, %d)", - otext, ntext, row, first, last)); + otext, ntext, row, first, last)); if (otext != ntext && (last - first + 1) > SP->_inline_cost) { @@ -597,8 +608,8 @@ doupdate(void) continue; } - T(("At (%d, %d): from %s...", i, j, _traceattr(rattr))); - T(("...to %s", _traceattr(turnon))); + TR(TRACE_ATTRS, ("At (%d, %d): from %s...", i, j, _traceattr(rattr))); + TR(TRACE_ATTRS, ("...to %s", _traceattr(turnon))); /* * If the attribute change location is a blank with a @@ -628,15 +639,17 @@ doupdate(void) for (; n < screen_columns; n++) { if (AttrOf(newscr->_line[m].text[n]) == rattr) { end_onscreen = TRUE; - T(("Range attributed with %s ends at (%d, %d)", - _traceattr(turnon), m, n)); + TR(TRACE_ATTRS, + ("Range attributed with %s ends at (%d, %d)", + _traceattr(turnon), m, n)); goto foundit; } } n = 0; } - T(("Range attributed with %s ends offscreen", - _traceattr(turnon))); + TR(TRACE_ATTRS, + ("Range attributed with %s ends offscreen", + _traceattr(turnon))); foundit:; if (end_onscreen) { @@ -649,8 +662,8 @@ doupdate(void) * of span. */ while (n >= 0 - && TextOf(lastline[n]) == ' ' - && SAFE(AttrOf(lastline[n]))) + && TextOf(lastline[n]) == ' ' + && SAFE(AttrOf(lastline[n]))) lastline[n--] &= ~turnon; /* check that there's enough room at end of span */ @@ -665,8 +678,9 @@ doupdate(void) if (failed) { int p, q = j; - T(("Clearing %s beginning at (%d, %d)", - _traceattr(turnon), i, j)); + TR(TRACE_ATTRS, + ("Clearing %s beginning at (%d, %d)", + _traceattr(turnon), i, j)); /* turn off new attributes over span */ for (p = i; p < screen_lines; p++) { @@ -679,8 +693,9 @@ doupdate(void) } foundend:; } else { - T(("Cookie space for %s found before (%d, %d)", - _traceattr(turnon), i, j)); + TR(TRACE_ATTRS, + ("Cookie space for %s found before (%d, %d)", + _traceattr(turnon), i, j)); /* * back up the start of range so there's room @@ -706,7 +721,7 @@ doupdate(void) nonempty = 0; if (curscr->_clear || newscr->_clear) { /* force refresh ? */ - T(("clearing and updating from scratch")); + TR(TRACE_UPDATE, ("clearing and updating from scratch")); ClrUpdate(); curscr->_clear = FALSE; /* reset flag */ newscr->_clear = FALSE; /* reset flag */ @@ -724,7 +739,7 @@ doupdate(void) nonempty = ClrBottom(nonempty); - T(("Transforming lines, nonempty %d", nonempty)); + TR(TRACE_UPDATE, ("Transforming lines, nonempty %d", nonempty)); for (i = 0; i < nonempty; i++) { /* * Here is our line-breakout optimization. @@ -785,10 +800,10 @@ doupdate(void) #if USE_TRACE_TIMES (void) times(&after); TR(TRACE_TIMES, - ("Update cost: %ld chars, %ld clocks system time, %ld clocks user time", - _nc_outchars, - after.tms_stime - before.tms_stime, - after.tms_utime - before.tms_utime)); + ("Update cost: %ld chars, %ld clocks system time, %ld clocks user time", + _nc_outchars, + after.tms_stime - before.tms_stime, + after.tms_utime - before.tms_utime)); #endif /* USE_TRACE_TIMES */ _nc_signal_handler(TRUE); @@ -832,11 +847,11 @@ ClrUpdate(void) chtype blank = ClrBlank(stdscr); int nonempty = min(screen_lines, newscr->_maxy + 1); - T(("ClrUpdate() called")); + TR(TRACE_UPDATE, ("ClrUpdate() called")); ClearScreen(blank); - T(("updating screen from scratch")); + TR(TRACE_UPDATE, ("updating screen from scratch")); nonempty = ClrBottom(nonempty); @@ -856,14 +871,15 @@ ClrToEOL(chtype blank, bool needclear) int j; if (curscr != 0 - && SP->_cursrow >= 0 - && SP->_curscol >= 0) { + && SP->_cursrow >= 0) { for (j = SP->_curscol; j < screen_columns; j++) { - chtype *cp = &(curscr->_line[SP->_cursrow].text[j]); + if (j >= 0) { + chtype *cp = &(curscr->_line[SP->_cursrow].text[j]); - if (*cp != blank) { - *cp = blank; - needclear = TRUE; + if (*cp != blank) { + *cp = blank; + needclear = TRUE; + } } } } else { @@ -897,11 +913,9 @@ ClrToEOS(chtype blank) row = SP->_cursrow; col = SP->_curscol; - { - UpdateAttrs(blank); - TPUTS_TRACE("clr_eos"); - tputs(clr_eos, screen_lines - row, _nc_outch); - } + UpdateAttrs(blank); + TPUTS_TRACE("clr_eos"); + tputs(clr_eos, screen_lines - row, _nc_outch); while (col < screen_columns) curscr->_line[row].text[col++] = blank; @@ -922,53 +936,40 @@ ClrToEOS(chtype blank) static int ClrBottom(int total) { - static chtype *tstLine; - static size_t lenLine; - int row; - size_t col; + int col; int top = total; int last = min(screen_columns, newscr->_maxx + 1); - size_t length = sizeof(chtype) * last; - chtype blank = newscr->_line[total - 1].text[last - 1]; /* lower right char */ - - if (!clr_eos || !can_clear_with(blank)) - return total; - - if ((tstLine == 0) || (last > (int) lenLine)) { - tstLine = typeRealloc(chtype, last, tstLine); - if (tstLine == 0) - return total; - lenLine = last; - tstLine[0] = ~blank; /* force the fill below */ - } - if (tstLine[0] != blank) { - for (col = 0; col < lenLine; col++) - tstLine[col] = blank; - } + chtype blank = ClrBlank(stdscr); + bool ok; - for (row = total - 1; row >= 0; row--) { - if (memcmp(tstLine, newscr->_line[row].text, length)) - break; - if (memcmp(tstLine, curscr->_line[row].text, length)) - top = row; - } + if (clr_eos && can_clear_with(blank)) { - /* don't use clr_eos for just one line if clr_eol available */ - if (top < total - 1 || (top < total && !clr_eol && !clr_bol)) { - GoTo(top, 0); - ClrToEOS(blank); - total = top; - if (SP->oldhash && SP->newhash) { - for (row = top; row < screen_lines; row++) - SP->oldhash[row] = SP->newhash[row]; + for (row = total - 1; row >= 0; row--) { + for (col = 0, ok = TRUE; ok && col < last; col++) { + ok = (newscr->_line[row].text[col] == blank); + } + if (!ok) + break; + + for (col = 0; ok && col < last; col++) { + ok = (curscr->_line[row].text[col] == blank); + } + if (!ok) + top = row; + } + + /* don't use clr_eos for just one line if clr_eol available */ + if (top < total - 1 || (top < total && !clr_eol && !clr_bol)) { + GoTo(top, 0); + ClrToEOS(blank); + total = top; + if (SP->oldhash && SP->newhash) { + for (row = top; row < screen_lines; row++) + SP->oldhash[row] = SP->newhash[row]; + } } } -#if NO_LEAKS - if (tstLine != 0) { - FreeAndNull(tstLine); - } -#endif return total; } @@ -999,7 +1000,7 @@ TransformLine(int const lineno) int n; bool attrchanged = FALSE; - T(("TransformLine(%d) called", lineno)); + TR(TRACE_UPDATE, ("TransformLine(%d) called", lineno)); /* copy new hash value to old one */ if (SP->oldhash && SP->newhash) @@ -1081,11 +1082,11 @@ TransformLine(int const lineno) */ if (TextOf(newLine[n]) == ' ' && ((n > 0 - && xmc_turn_on(newLine[n - 1], newLine[n])) + && xmc_turn_on(newLine[n - 1], newLine[n])) || (n == 0 && lineno > 0 && xmc_turn_on(NEW(lineno - 1, screen_columns - 1), - newLine[n])))) { + newLine[n])))) { n = m; } @@ -1097,7 +1098,7 @@ TransformLine(int const lineno) */ if (TextOf(newLine[n]) != ' ' && ((n + 1 < screen_columns - && xmc_turn_off(newLine[n], newLine[n + 1])) + && xmc_turn_off(newLine[n], newLine[n + 1])) || (n + 1 >= screen_columns && lineno + 1 < screen_lines && xmc_turn_off(newLine[n], NEW(lineno + 1, 0))))) { @@ -1112,7 +1113,7 @@ TransformLine(int const lineno) /* find the first differing character */ while (firstChar < screen_columns && - newLine[firstChar] == oldLine[firstChar]) + newLine[firstChar] == oldLine[firstChar]) firstChar++; /* if there wasn't one, we're done */ @@ -1158,15 +1159,15 @@ TransformLine(int const lineno) nLastChar = screen_columns - 1; while (nLastChar > firstChar - && newLine[nLastChar] == oldLine[nLastChar]) + && newLine[nLastChar] == oldLine[nLastChar]) nLastChar--; if (nLastChar >= firstChar) { GoTo(lineno, firstChar); PutRange(oldLine, newLine, lineno, firstChar, nLastChar); memcpy(oldLine + firstChar, - newLine + firstChar, - (nLastChar - firstChar + 1) * sizeof(chtype)); + newLine + firstChar, + (nLastChar - firstChar + 1) * sizeof(chtype)); } return; } @@ -1188,8 +1189,8 @@ TransformLine(int const lineno) PutChar(newLine[firstChar]); ClrToEOL(blank, FALSE); } else if ((nLastChar != oLastChar) - && (newLine[nLastChar] != oldLine[oLastChar] - || !(_nc_idcok && has_ic()))) { + && (newLine[nLastChar] != oldLine[oLastChar] + || !(_nc_idcok && has_ic()))) { GoTo(lineno, firstChar); if ((oLastChar - nLastChar) > SP->_el_cost) { if (PutRange(oldLine, newLine, lineno, firstChar, nLastChar)) @@ -1234,7 +1235,7 @@ TransformLine(int const lineno) if (DelCharCost(oLastChar - nLastChar) > SP->_el_cost + nLastNonblank - (n + 1)) { if (PutRange(oldLine, newLine, lineno, - n + 1, nLastNonblank)) + n + 1, nLastNonblank)) GoTo(lineno, nLastNonblank + 1); ClrToEOL(blank, FALSE); } else { @@ -1256,8 +1257,8 @@ TransformLine(int const lineno) /* update the code's internal representation */ if (screen_columns > firstChar) memcpy(oldLine + firstChar, - newLine + firstChar, - (screen_columns - firstChar) * sizeof(chtype)); + newLine + firstChar, + (screen_columns - firstChar) * sizeof(chtype)); } /* @@ -1273,9 +1274,9 @@ ClearScreen(chtype blank) int i, j; bool fast_clear = (clear_screen || clr_eos || clr_eol); - T(("ClearScreen() called")); + TR(TRACE_UPDATE, ("ClearScreen() called")); -#ifdef NCURSES_EXT_FUNCS +#if NCURSES_EXT_FUNCS if (SP->_coloron && !SP->_default_color) { _nc_do_color(COLOR_PAIR(SP->_current_attr), 0, FALSE, _nc_outch); @@ -1302,18 +1303,18 @@ ClearScreen(chtype blank) } else if (clr_eol) { SP->_cursrow = SP->_curscol = -1; + UpdateAttrs(blank); for (i = 0; i < screen_lines; i++) { GoTo(i, 0); - UpdateAttrs(blank); TPUTS_TRACE("clr_eol"); putp(clr_eol); } GoTo(0, 0); } } else { + UpdateAttrs(blank); for (i = 0; i < screen_lines; i++) { GoTo(i, 0); - UpdateAttrs(blank); for (j = 0; j < screen_columns; j++) PutChar(blank); } @@ -1325,7 +1326,7 @@ ClearScreen(chtype blank) curscr->_line[i].text[j] = blank; } - T(("screen cleared")); + TR(TRACE_UPDATE, ("screen cleared")); } /* @@ -1338,7 +1339,7 @@ ClearScreen(chtype blank) static void InsStr(chtype * line, int count) { - T(("InsStr(%p,%d) called", line, count)); + TR(TRACE_UPDATE, ("InsStr(%p,%d) called", line, count)); /* Prefer parm_ich as it has the smallest cost - no need to shift * the whole line on each character. */ @@ -1393,7 +1394,8 @@ DelChar(int count) { int n; - T(("DelChar(%d) called, position = (%d,%d)", count, newscr->_cury, newscr->_curx)); + TR(TRACE_UPDATE, ("DelChar(%d) called, position = (%d,%d)", count, + newscr->_cury, newscr->_curx)); if (parm_dch) { TPUTS_TRACE("parm_dch"); @@ -1494,7 +1496,7 @@ scroll_csr_forward(int n, int top, int bot, int miny, int maxy, chtype blank) } else return ERR; -#ifdef NCURSES_EXT_FUNCS +#if NCURSES_EXT_FUNCS if (FILL_BCE()) { for (i = 0; i < n; i++) { GoTo(bot - i, 0); @@ -1550,7 +1552,7 @@ scroll_csr_backward(int n, int top, int bot, int miny, int maxy, chtype blank) } else return ERR; -#ifdef NCURSES_EXT_FUNCS +#if NCURSES_EXT_FUNCS if (FILL_BCE()) { for (i = 0; i < n; i++) { GoTo(top + i, 0); @@ -1630,18 +1632,11 @@ _nc_scrolln(int n, int top, int bot, int maxy) * Explicitly clear if stuff pushed off top of region might * be saved by the terminal. */ - if (non_dest_scroll_region || (memory_above && top == 0)) { - for (i = 0; i < n; i++) { - GoTo(i, 0); - ClrToEOL(BLANK, FALSE); - } - } - res = scroll_csr_forward(n, top, bot, 0, maxy, blank); if (res == ERR && change_scroll_region) { if ((((n == 1 && scroll_forward) || parm_index) - && (SP->_cursrow == bot || SP->_cursrow == bot - 1)) + && (SP->_cursrow == bot || SP->_cursrow == bot - 1)) && save_cursor && restore_cursor) { cursor_saved = TRUE; TPUTS_TRACE("save_cursor"); @@ -1665,23 +1660,24 @@ _nc_scrolln(int n, int top, int bot, int maxy) if (res == ERR && _nc_idlok) res = scroll_idl(n, top, bot - n + 1, blank); - } else { /* (n < 0) - scroll down (backward) */ + /* - * Do explicit clear to end of region if it's possible that the - * terminal might hold on to stuff we push off the end. + * Clear the newly shifted-in text. */ - if (non_dest_scroll_region || (memory_below && bot == maxy)) { + if (res != ERR + && (non_dest_scroll_region || (memory_below && bot == maxy))) { if (bot == maxy && clr_eos) { - GoTo(maxy + n, 0); + GoTo(bot - n, 0); ClrToEOS(BLANK); - } else if (clr_eol) { - for (i = 0; i < -n; i++) { - GoTo(maxy + n + i, 0); + } else { + for (i = 0; i < n; i++) { + GoTo(bot - i, 0); ClrToEOL(BLANK, FALSE); } } } + } else { /* (n < 0) - scroll down (backward) */ res = scroll_csr_backward(-n, top, bot, 0, maxy, blank); if (res == ERR && change_scroll_region) { @@ -1709,6 +1705,17 @@ _nc_scrolln(int n, int top, int bot, int maxy) if (res == ERR && _nc_idlok) res = scroll_idl(-n, bot + n + 1, top, blank); + + /* + * Clear the newly shifted-in text. + */ + if (res != ERR + && (non_dest_scroll_region || (memory_above && top == 0))) { + for (i = 0; i < -n; i++) { + GoTo(i + top, 0); + ClrToEOL(BLANK, FALSE); + } + } } if (res == ERR) @@ -1759,7 +1766,7 @@ void _nc_screen_wrap(void) { UpdateAttrs(A_NORMAL); -#ifdef NCURSES_EXT_FUNCS +#if NCURSES_EXT_FUNCS if (SP->_coloron && !SP->_default_color) { SP->_default_color = TRUE; @@ -1786,7 +1793,7 @@ _nc_do_xmc_glitch(attr_t previous) SP->_curscol += magic_cookie_glitch; if (SP->_curscol >= SP->_columns) wrap_cursor(); - T(("bumped to %d,%d after cookie", SP->_cursrow, SP->_curscol)); + TR(TRACE_UPDATE, ("bumped to %d,%d after cookie", SP->_cursrow, SP->_curscol)); } chg >>= 1; } |