--- rxvt-unicode/src/screen.C 2005/12/20 19:30:59 1.175 +++ rxvt-unicode/src/screen.C 2005/12/21 10:34:24 1.180 @@ -85,9 +85,6 @@ #define ROWCOL_IN_ROW_AT_OR_BEFORE(X, Y) \ ROW_AND_COL_IN_ROW_AT_OR_BEFORE ((X).row, (X).col, (Y).row, (Y).col) -#define LINENO(n) (((n) + term_start + total_rows) % total_rows) -#define ROW(n) (save [LINENO (n)]) - /* * CLEAR_ROWS : clear rows starting from row * CLEAR_CHARS: clear chars starting from pixel position @@ -253,7 +250,7 @@ /* delete rows */ k = min (nsaved, prev_nrow - nrow); // k = max (0, - ( (nrow - 1) - r->screen.cur.row)); // mmc's http://maruska.dyndns.org/wiki/scrolling-bug //make configurable? //D TODO - scr_scroll_text (0, (int)prev_nrow - 1, k, 1); + scr_scroll_text (0, (int)prev_nrow - 1, k); for (p = nrow; p < prev_nrow; p++) { @@ -291,7 +288,7 @@ if (k > 0) { - scr_scroll_text (0, (int)nrow - 1, -k, 1); + scr_scroll_text (0, (int)nrow - 1, -k); screen.cur.row += k; screen.s_cur.row += k; nsaved -= k; @@ -540,13 +537,7 @@ int rxvt_term::scr_change_screen (int scrn) { - int i; -#if NSCREENS - int offset; -#endif - want_refresh = 1; - view_start = 0; if (current_screen == scrn) @@ -554,33 +545,31 @@ selection_check (2); /* check for boundary cross */ - i = current_screen; current_screen = scrn; scrn = i; + int i = current_screen; current_screen = scrn; scrn = i; - SWAP_IT (screen.cur.row, swap.cur.row, int16_t); - SWAP_IT (screen.cur.col, swap.cur.col, int16_t); - MAX_IT (screen.cur.row, 0); - MIN_IT (screen.cur.row, (int32_t)prev_nrow - 1); - MAX_IT (screen.cur.col, 0); - MIN_IT (screen.cur.col, (int32_t)prev_ncol - 1); + ::swap (screen.cur.row, swap.cur.row); + ::swap (screen.cur.col, swap.cur.col); + + screen.cur.row = clamp (screen.cur.row, 0, prev_nrow - 1); + screen.cur.col = clamp (screen.cur.col, 0, prev_ncol - 1); #if NSCREENS if (options & Opt_secondaryScreen) { num_scr = 0; - offset = saveLines; - for (i = prev_nrow; i--;) - SWAP_IT (ROW(i), swap_save[i], line_t); + for (int i = nrow; i--; ) + ::swap (ROW(i), swap_save[i]); - SWAP_IT (screen.charset, swap.charset, int16_t); - SWAP_IT (screen.flags, swap.flags, int); + ::swap (screen.charset, swap.charset); + ::swap (screen.flags, swap.flags); screen.flags |= Screen_VisibleCursor; swap.flags |= Screen_VisibleCursor; } else #endif if (options & Opt_secondaryScroll) - scr_scroll_text (0, prev_nrow - 1, prev_nrow, 0); + scr_scroll_text (0, prev_nrow - 1, prev_nrow); return scrn; } @@ -597,7 +586,7 @@ screen.cur.col = 0; if (screen.cur.row == screen.bscroll) - scr_scroll_text (screen.tscroll, screen.bscroll, 1, 0); + scr_scroll_text (screen.tscroll, screen.bscroll, 1); else if (screen.cur.row < nrow - 1) screen.cur.row++; } @@ -638,19 +627,19 @@ * Scroll text between and inclusive, by lines * count positive ==> scroll up * count negative ==> scroll down - * spec == 0 for normal routines */ int -rxvt_term::scr_scroll_text (int row1, int row2, int count, int spec) +rxvt_term::scr_scroll_text (int row1, int row2, int count) { - int i, j; - if (count == 0 || (row1 > row2)) return 0; want_refresh = 1; + num_scr += count; - if (row1 == 0 && count > 0 + if (count > 0 + && row1 == 0 + && row2 == nrow - 1 && (current_screen == PRIMARY || options & Opt_secondaryScroll)) { nsaved = min (nsaved + count, saveLines); @@ -661,6 +650,8 @@ selection.beg.row -= count; selection.end.row -= count; selection.mark.row -= count; + + selection_check (0); } for (int i = count; i--; ) @@ -673,15 +664,10 @@ } else { - if (!spec) - row1 += saveLines; - - row2 += saveLines; - if (selection.op && current_screen == selection.screen) { - i = selection.beg.row + saveLines; - j = selection.end.row + saveLines; + int i = selection.beg.row; + int j = selection.end.row; if ((i < row1 && j > row1) || (i < row2 && j > row2) @@ -699,55 +685,26 @@ selection.beg.row -= count; selection.end.row -= count; selection.mark.row -= count; + + selection_check (0); } } - selection_check (0); /* _after_ nsaved update */ - - num_scr += count; - j = count; - - if (count < 0) - count = -count; + // use a simple and robust scrolling algorithm, this + // part of scr_scroll_text is not time-critical. - i = row2 - row1 + 1; - MIN_IT (count, i); + int rows = row2 - row1 + 1; - if (j > 0) + for (int row = 0; row < rows; row++) { - /* scroll up */ + buf [row] = ROW(row1 + (row + count + rows) % rows); - /* Copy lines that will get clobbered by the rotation */ - memcpy (buf, save + row1, count * sizeof (line_t)); - - /* Rotate lines */ - i = row2 - row1 - count + 1; - memmove (save + row1, save + row1 + count, i * sizeof (line_t)); - - j = row2 - count + 1, i = count; - } - else /* if (j < 0) */ - { - /* scroll down */ - - /* Copy lines that will get clobbered by the rotation */ - for (i = 0, j = row2; i < count; i++, j--) - buf[i] = save[j]; - - /* Rotate lines */ - for (j = row2, i = j - count; i >= row1; i--, j--) - save[j] = save[i]; - - j = row1, i = count; - count = -count; + if (!IN_RANGE_EXC (row + count, 0, rows)) + scr_blank_screen_mem (buf [row], rstyle); } - /* Resurrect lines */ - memcpy (save + j, buf, i * sizeof (line_t)); - - if (!spec) /* line length may not equal ncol */ - for (; i--; j++) - scr_blank_screen_mem (save[j], rstyle); + for (int row = 0; row < rows; row++) + ROW(row1 + row) = buf [row]; } return count; @@ -780,7 +737,7 @@ && (screen.bscroll == (nrow - 1))) { /* _at least_ this many lines need to be scrolled */ - scr_scroll_text (screen.tscroll, screen.bscroll, nlines, 0); + scr_scroll_text (screen.tscroll, screen.bscroll, nlines); screen.cur.row -= nlines; } } @@ -813,7 +770,7 @@ screen.flags &= ~Screen_WrapNext; if (screen.cur.row == screen.bscroll) - scr_scroll_text (screen.tscroll, screen.bscroll, 1, 0); + scr_scroll_text (screen.tscroll, screen.bscroll, 1); else if (screen.cur.row < (nrow - 1)) row = ++screen.cur.row; @@ -1236,7 +1193,7 @@ if ((screen.cur.row == screen.bscroll && direction == UP) || (screen.cur.row == screen.tscroll && direction == DN)) - scr_scroll_text (screen.tscroll, screen.bscroll, dirn, 0); + scr_scroll_text (screen.tscroll, screen.bscroll, dirn); else screen.cur.row += dirn; @@ -1307,15 +1264,13 @@ rxvt_term::scr_erase_screen (int mode) { int num; - int32_t row, row_offset; + int32_t row; rend_t ren; XGCValues gcvalue; want_refresh = 1; ZERO_SCROLLBACK (); - row_offset = (int32_t)saveLines; - switch (mode) { case 0: /* erase to end of screen */ @@ -1369,8 +1324,8 @@ for (; num--; row++) { - scr_blank_screen_mem (save[row + row_offset], rstyle); - save[row + row_offset].l = 0; + scr_blank_screen_mem (ROW (row), rstyle); + ROW (row).l = 0; scr_blank_line (drawn[row], 0, ncol, ren); } } @@ -1394,8 +1349,7 @@ void rxvt_term::scr_E () { - int i, j, k; - rend_t *r1, fs; + rend_t fs; want_refresh = 1; ZERO_SCROLLBACK (); @@ -1404,13 +1358,14 @@ selection_check (3); fs = SET_FONT (rstyle, FONTSET (rstyle)->find_font ('E')); - for (k = saveLines, i = nrow; i--; k++) + for (int row = nrow; row--; ) { - line_t &line = save[k]; + line_t &line = ROW(row); fill_text (line.t, 'E', ncol); + rend_t *r1 = line.r; - for (r1 = line.r, j = ncol; j--; ) + for (int j = ncol; j--; ) *r1++ = fs; line.l = ncol; /* make the `E's selectable */ @@ -1444,7 +1399,7 @@ scr_do_wrap (); - scr_scroll_text (screen.cur.row, screen.bscroll, insdel * count, 0); + scr_scroll_text (screen.cur.row, screen.bscroll, insdel * count); } /* ------------------------------------------------------------------------- */ @@ -1468,9 +1423,9 @@ selection_check (1); MIN_IT (count, (ncol - screen.cur.col)); - row = screen.cur.row + saveLines; + row = screen.cur.row; - line_t *line = save + row; + line_t *line = &ROW(row); switch (insdel) { @@ -1501,14 +1456,14 @@ } } - scr_blank_line (save[row], screen.cur.col, count, rstyle); + scr_blank_line (*line, screen.cur.col, count, rstyle); break; case ERASE: screen.cur.col += count; /* don't worry if > ncol */ selection_check (1); screen.cur.col -= count; - scr_blank_line (save[row], screen.cur.col, count, rstyle); + scr_blank_line (*line, screen.cur.col, count, rstyle); break; case DELETE: @@ -1525,8 +1480,7 @@ if (line->is_longer ()) /* break line continuation */ line->l = ncol; - line->l -= count; - MAX_IT (line->l, 0); + line->l = max (line->l - count, 0); if (selection.op && current_screen == selection.screen && ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur)) @@ -1943,31 +1897,31 @@ rxvt_term::scr_printscreen (int fullhist) { #ifdef PRINTPIPE - int i, r1, nrows, row_offset; + int nrows, row_start; FILE *fd; if ((fd = popen_printer ()) == NULL) return; - nrows = nrow; - row_offset = saveLines; - - if (!fullhist) - row_offset -= view_start; + if (fullhist) + { + nrows = nrow + nsaved; + row_start = -nsaved; + } else { - nrows += nsaved; - row_offset -= nsaved; + nrows = nrow; + row_start = -view_start; } wctomb (0, 0); - for (r1 = 0; r1 < nrows; r1++) + for (int r1 = 0; r1 < nrows; r1++) { - text_t *tp = save[r1 + row_offset].t; - int len = save[r1 + row_offset].l; + text_t *tp = ROW(r1).t; + int len = ROW(r1).l; - for (i = len >= 0 ? len : ncol - 1; i--; ) //TODO//FIXME//LEN + for (int i = len >= 0 ? len : ncol - 1; i--; ) //TODO//FIXME//LEN { char mb[MB_LEN_MAX]; text_t t = *tp++; @@ -2005,8 +1959,7 @@ showcursor; /* show the cursor */ int16_t col, row, /* column/row we're processing */ ocrow; /* old cursor row */ - int i, /* tmp */ - row_offset; /* basic offset in screen structure */ + int i; /* tmp */ #ifndef NO_CURSORCOLOR rend_t cc1; /* store colours at cursor position (s) */ #endif @@ -2023,8 +1976,6 @@ must_clear = 0; refresh_count = 0; - row_offset = term_start - view_start; - #if XPM_BACKGROUND must_clear |= bgPixmap.pixmap != None; #endif @@ -2137,8 +2088,8 @@ */ i = num_scr; if (!display->is_local - && refresh_type == FAST_REFRESH && num_scr_allow && i - && abs (i) < nrow && !must_clear) + && refresh_type == FAST_REFRESH && num_scr_allow && num_scr + && abs (num_scr) < nrow && !must_clear) { int16_t nits; int j; @@ -2151,7 +2102,7 @@ { if (row + i >= 0 && row + i < nrow && row + i != ocrow) { - line_t s = save[(row + row_offset) % nlines]; + line_t s = ROW(row - view_start); line_t d = drawn[row]; line_t d2 = drawn[row + i]; @@ -2199,8 +2150,8 @@ */ for (row = 0; row < nrow; row++) { - text_t *stp = save[(row + row_offset) % total_rows].t; - rend_t *srp = save[(row + row_offset) % total_rows].r; + text_t *stp = ROW(row - view_start).t; + rend_t *srp = ROW(row - view_start).r; text_t *dtp = drawn[row].t; rend_t *drp = drawn[row].r; @@ -3075,8 +3026,8 @@ selection.mark.row = row - view_start; selection.mark.col = col; - selection.mark.row = min (max (selection.mark.row, -nsaved), nrow - 1); - selection.mark.col = min (max (selection.mark.col, 0), ncol - 1); + selection.mark.row = clamp (selection.mark.row, -nsaved, nrow - 1); + selection.mark.col = clamp (selection.mark.col, 0, ncol - 1); while (selection.mark.col > 0 && ROW(selection.mark.row).t[selection.mark.col] == NOCHAR) @@ -3191,8 +3142,8 @@ void rxvt_term::selection_extend (int x, int y, int flag) { - int col = min (max (Pixel2Col (x), 0), nrow - 1); - int row = min (max (Pixel2Row (y), 0), ncol); + int col = clamp (Pixel2Col (x), 0, ncol); + int row = clamp (Pixel2Row (y), 0, nrow - 1); /* * If we're selecting characters (single click) then we must check first @@ -3373,7 +3324,7 @@ if (!ROW(end_row).is_longer ()) { selection.end.row = end_row; - selection.end.col = save[end_row + saveLines].l; + selection.end.col = ROW(end_row).l; selection_remove_trailing_spaces (); break; }