--- rxvt-unicode/src/screen.C 2006/01/06 01:16:58 1.211 +++ rxvt-unicode/src/screen.C 2006/01/15 05:14:12 1.227 @@ -3,7 +3,7 @@ *---------------------------------------------------------------------------* * * Copyright (c) 1997-2001 Geoff Wing - * Copyright (c) 2003-2004 Marc Lehmann + * Copyright (c) 2003-2006 Marc Lehmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -147,6 +147,9 @@ rxvt_term::scr_blank_screen_mem (line_t &l, rend_t efs) { scr_blank_line (l, 0, ncol, efs); + + l.l = 0; + l.f = 0; } /* ------------------------------------------------------------------------- * @@ -193,7 +196,6 @@ { /* * first time called so just malloc everything: don't rely on realloc - * Note: this is still needed so that all the scrollback lines are NULL */ nsaved = 0; /* no saved lines */ term_start = 0; @@ -201,10 +203,9 @@ talloc = new rxvt_salloc (ncol * sizeof (text_t)); ralloc = new rxvt_salloc (ncol * sizeof (rend_t)); - row_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t)); - temp_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t)); - drawn_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t)); - swap_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t)); + row_buf = (line_t *)rxvt_calloc (total_rows + nrow, sizeof (line_t)); + drawn_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t)); + swap_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t)); for (int row = nrow; row--; ) { @@ -259,7 +260,6 @@ #endif drawn_buf = (line_t *)rxvt_realloc (drawn_buf, nrow * sizeof (line_t)); - temp_buf = (line_t *)rxvt_realloc (temp_buf , nrow * sizeof (line_t)); swap_buf = (line_t *)rxvt_realloc (swap_buf , nrow * sizeof (line_t)); for (int row = min (nrow, prev_nrow); row--; ) @@ -274,7 +274,8 @@ drawn_buf[row].clear (); scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE); } - line_t *old_buf = row_buf; row_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t)); + line_t *old_buf = row_buf; + row_buf = (line_t *)rxvt_calloc (total_rows + nrow, sizeof (line_t)); int p = MOD (term_start + prev_nrow, prev_total_rows); // previous row int pend = MOD (term_start - nsaved , prev_total_rows); @@ -432,7 +433,6 @@ free (row_buf); free (swap_buf); free (drawn_buf); - free (temp_buf); free (tabs); row_buf = 0; // signal that we freed all the arrays @@ -574,7 +574,7 @@ void rxvt_term::scr_color (unsigned int color, int fgbg) { - if (color > maxTermCOLOR) + if (!IN_RANGE_INC (color, minCOLOR, maxTermCOLOR)) color = fgbg; if (fgbg == Color_fg) @@ -615,15 +615,48 @@ if (count > 0 && row1 == 0 - && row2 == nrow - 1 && (current_screen == PRIMARY || OPTION (Opt_secondaryScroll))) { nsaved = min (nsaved + count, saveLines); HOOK_INVOKE ((this, HOOK_SCROLL_BACK, DT_INT, count, DT_INT, nsaved, DT_END)); + // scroll everything up 'count' lines term_start = (term_start + count) % total_rows; + { + // severe bottommost scrolled line + line_t &l = ROW(row2 - count); + l.touch (); + l.is_longer (0); + } + + // erase newly scorlled-in lines + for (int i = count; i; --i ) + { + // basically this is a slightly optimized scr_blank_screen_mem + // it is worth the effort on slower machines + line_t &l = ROW(nrow - i); + + scr_blank_line (l, 0, l.l, rstyle); + + l.l = 0; + l.f = 0; + } + + // now copy lines below the scroll region bottom to the + // bottom of the screen again, so they look as if they + // hadn't moved. + for (int i = nrow; --i > row2; ) + { + line_t &l1 = ROW(i - count); + line_t &l2 = ROW(i); + + ::swap (l1, l2); + l2.touch (); + } + + // move and/or clear selection, if any if (selection.op && current_screen == selection.screen) { selection.beg.row -= count; @@ -639,12 +672,7 @@ } } - for (int i = count; i--; ) - { - ROW(row2 - i).l = 0; - scr_blank_screen_mem (ROW(row2 - i), rstyle); - } - + // finally move the view window, if desired if (OPTION (Opt_scrollWithBuffer) && view_start != 0 && view_start != saveLines) @@ -682,6 +710,8 @@ min_it (count, rows); + line_t *temp_buf = row_buf + total_rows; + for (int row = 0; row < rows; row++) { temp_buf [row] = ROW(row1 + (row + count + rows) % rows); @@ -702,7 +732,7 @@ * Add text given in of length to screen struct */ void -rxvt_term::scr_add_lines (const unicode_t *str, int nlines, int len) +rxvt_term::scr_add_lines (const wchar_t *str, int len, int minlines) { if (len <= 0) /* sanity */ return; @@ -710,22 +740,22 @@ unsigned char checksel; unicode_t c; int ncol = this->ncol; - const unicode_t *strend = str + len; + const wchar_t *strend = str + len; want_refresh = 1; ZERO_SCROLLBACK (); - if (nlines > 0) + if (minlines > 0) { - nlines += screen.cur.row - screen.bscroll; + minlines += screen.cur.row - screen.bscroll; - if (nlines > 0 + if (minlines > 0 && screen.tscroll == 0 && screen.bscroll == nrow - 1) { /* _at least_ this many lines need to be scrolled */ - scr_scroll_text (screen.tscroll, screen.bscroll, nlines); - screen.cur.row -= nlines; + scr_scroll_text (screen.tscroll, screen.bscroll, minlines); + screen.cur.row -= minlines; } } @@ -742,7 +772,7 @@ while (str < strend) { - c = *str++; + c = (unicode_t)*str++; // convert to rxvt-unicodes representation if (c < 0x20) if (c == C0_LF) @@ -1305,10 +1335,7 @@ for (; num--; row++) { - line_t &l = ROW(row); - l.l = 0; - l.is_longer (0); - scr_blank_screen_mem (l, rstyle); + scr_blank_screen_mem (ROW(row), rstyle); scr_blank_line (drawn_buf [row], 0, ncol, ren); } } @@ -1860,6 +1887,7 @@ if (OPTION (Opt_visualBell)) { scr_rvideo_mode (!rvideo); /* refresh also done */ + display->flush (); rxvt_usleep (VISUAL_BELL_DURATION); scr_rvideo_mode (!rvideo); /* refresh also done */ } @@ -2377,9 +2405,6 @@ */ scr_reverse_selection (); - if (refresh_type & SMOOTH_REFRESH) - XFlush (display->display); - num_scr = 0; num_scr_allow = 1; } @@ -2390,7 +2415,7 @@ if (!l.t) return; - l.touch (); // maybe a bit of an overkill, but its not performance-relevant + l.touch (); // maybe a bit of an overkill, but it's not performance-relevant for (int i = ncol; i--; ) l.r[i] = SET_FONT (l.r[i], FONTSET (l.r[i])->find_font (l.t[i])); @@ -2453,6 +2478,54 @@ XClearWindow (display->display, vt); } +void +rxvt_term::scr_xor_rect (int beg_row, int beg_col, int end_row, int end_col, rend_t rstyle1, rend_t rstyle2) +{ + int view_end = -view_start + nrow; + int row, col; + + for (row = max (beg_row, -view_start); row <= min (end_row, view_end); row++) + { + text_t *stp = ROW(row).t; + rend_t *srp = ROW(row).r; + + for (col = beg_col; col < end_col; col++) + srp[col] ^= rstyle1; + + while (col-- > beg_col && (stp[col] == NOCHAR || unicode::is_space (stp[col]))) + srp[col] ^= rstyle2; + + if (++col < end_col) + srp[col] ^= rstyle2; + } +} + +void +rxvt_term::scr_xor_span (int beg_row, int beg_col, int end_row, int end_col, rend_t rstyle) +{ + int view_end = -view_start + nrow; + int row, col; + + if (beg_row >= -view_start) + { + col = beg_col; + row = beg_row; + } + else + { + col = 0; + row = -view_start; + } + + for (; row < min (end_row, view_end); row++, col = 0) + for (rend_t *srp = ROW(row).r; col < ncol; col++) + srp[col] ^= rstyle; + + if (row == end_row) + for (rend_t *srp = ROW(row).r; col < end_col; col++) + srp[col] ^= rstyle; +} + /* ------------------------------------------------------------------------- */ void rxvt_term::scr_reverse_selection () @@ -2461,49 +2534,16 @@ && current_screen == selection.screen && selection.end.row >= -view_start) { - int view_end = -view_start + nrow; - int row, col; - #if ENABLE_FRILLS if (selection.rect) - { - for (row = max (selection.beg.row, -view_start); row <= min (selection.end.row, view_end); row++) - { - text_t *stp = ROW(row).t; - rend_t *srp = ROW(row).r; - - for (col = selection.beg.col; col < selection.end.col; col++) - srp[col] ^= RS_RVid; - - while (col-- > selection.beg.col && (stp[col] == NOCHAR || unicode::is_space (stp[col]))) - srp[col] ^= RS_RVid | RS_Uline; - - if (++col < selection.end.col) - srp[col] ^= RS_RVid | RS_Uline; - } - } + scr_xor_rect (selection.beg.row, selection.beg.col, + selection.end.row, selection.end.col, + RS_RVid, RS_RVid | RS_Uline); else #endif - { - if (selection.beg.row >= -view_start) - { - col = selection.beg.col; - row = selection.beg.row; - } - else - { - col = 0; - row = -view_start; - } - - for (; row < min (selection.end.row, view_end); row++, col = 0) - for (rend_t *srp = ROW(row).r; col < ncol; col++) - srp[col] ^= RS_RVid; - - if (row == selection.end.row) - for (rend_t *srp = ROW(row).r; col < selection.end.col; col++) - srp[col] ^= RS_RVid; - } + scr_xor_span (selection.beg.row, selection.beg.col, + selection.end.row, selection.end.col, + RS_RVid); } } @@ -3005,7 +3045,10 @@ return true; } else - return false; + { + selection_clear (); + return false; + } #if 0 XTextProperty ct; @@ -3029,6 +3072,15 @@ clicks = ((clicks - 1) % 3) + 1; selection.clicks = clicks; /* save clicks so extend will work */ + if (clicks == 2 && !selection.rect + && HOOK_INVOKE ((this, HOOK_SEL_EXTEND, DT_END))) + { + MEvent.clicks = 1; // what a mess + selection.screen = current_screen; + selection.op = SELECTION_CONT; + return; + } + selection_start_colrow (Pixel2Col (x), Pixel2Row (y)); if (clicks == 2 || clicks == 3) @@ -3333,11 +3385,8 @@ if (ROWCOL_IS_AFTER (selection.end, selection.beg)) selection.end.col--; - if (!HOOK_INVOKE ((this, HOOK_SEL_EXTEND, DT_END))) - { - selection_delimit_word (UP, &selection.beg, &selection.beg); - selection_delimit_word (DN, &selection.end, &selection.end); - } + selection_delimit_word (UP, &selection.beg, &selection.beg); + selection_delimit_word (DN, &selection.end, &selection.end); } else if (selection.clicks == 3) {