--- rxvt-unicode/src/screen.C 2004/02/24 23:58:13 1.37 +++ rxvt-unicode/src/screen.C 2004/03/03 02:59:53 1.43 @@ -3,6 +3,7 @@ *---------------------------------------------------------------------------* * * Copyright (c) 1997-2001 Geoff Wing + * Copyright (c) 2003-2004 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 @@ -18,8 +19,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *--------------------------------------------------------------------------*/ + /* - * We handle _all_ screen updates and selections + * This file handles _all_ screen updates and selections */ #include "../config.h" /* NECESSARY */ @@ -32,7 +34,7 @@ #include #include -#include "salloc.C" // HACK!! +#include "salloc.C" // HACK, should be a seperate compile! inline void fill_text (text_t *start, text_t value, int len) { @@ -889,24 +891,33 @@ // width -1 characters (e.g. combining chars) are ignored currently. if (width > 0) - do - { - stp[screen.cur.col] = c; - srp[screen.cur.col] = rend; + { + do + { + stp[screen.cur.col] = c; + srp[screen.cur.col] = rend; - if (screen.cur.col < last_col - 1) - screen.cur.col++; - else - { - screen.tlen[row] = last_col; - if (screen.flags & Screen_Autowrap) - screen.flags |= Screen_WrapNext; - break; - } + if (screen.cur.col < last_col - 1) + screen.cur.col++; + else + { + screen.tlen[row] = last_col; + if (screen.flags & Screen_Autowrap) + screen.flags |= Screen_WrapNext; + break; + } - c = NOCHAR; - } - while (--width > 0); + c = NOCHAR; + } + while (--width > 0); + + // pad with spaces when overwriting wide character with smaller one + for (int c = screen.cur.col; stp[c] == NOCHAR && c < last_col; c++) + { + stp[c] = ' '; + srp[c] = rend; + } + } else (void)0; /* handle combining character etc. here. */ } @@ -1098,6 +1109,10 @@ } MAX_IT (screen.cur.row, 0); MIN_IT (screen.cur.row, (int32_t)TermWin.nrow - 1); + + while (screen.cur.col > 0 + && screen.text[screen.cur.row + TermWin.saveLines][screen.cur.col] == NOCHAR) + screen.cur.col--; } /* ------------------------------------------------------------------------- */ @@ -2054,25 +2069,25 @@ for (col = 0; col < TermWin.ncol; col++) { /* compare new text with old - if exactly the same then continue */ - rend_t rend = srp[col]; /* screen rendition (target rendtion) */ - if (stp[col] == dtp[col] /* Must match characters to skip. */ - && (rend == drp[col] /* Either rendition the same or */ + && (srp[col] == drp[col] /* Either rendition the same or */ || (stp[col] == ' ' /* space w/ no background change */ - && GET_BGATTR (rend) == GET_BGATTR (drp[col])))) + && GET_BGATTR (srp[col]) == GET_BGATTR (drp[col])))) continue; + // redraw one or more characters + + // seek to the beginning if wide characters + while (stp[col] == NOCHAR && col > 0) + --col; + + rend_t rend = srp[col]; /* screen rendition (target rendtion) */ text_t *text = stp + col; int count = 1; - /* redraw one or more characters */ - dtp[col] = stp[col]; drp[col] = rend; - if (*text == NOCHAR) // never start redrawing at invisible characters. */ - continue; - int xpixel = Col2Pixel (col); // this loop looks very messy, it can probably be optimized @@ -2155,7 +2170,7 @@ } #ifdef TEXT_BLINK - if (rend & RS_Blink) + if (rend & RS_Blink && back == Color_bg) { if (!text_blink_ev.active) { @@ -2197,8 +2212,8 @@ if ((rend & RS_Uline) && (font->descent > 1)) XDrawLine (display->display, drawBuffer, TermWin.gc, - xpixel, ypixel + font->ascent + 1, - xpixel + Width2Pixel (count) - 1, ypixel + font->ascent + 1); + xpixel, ypixel + font->ascent + 1, + xpixel + Width2Pixel (count) - 1, ypixel + font->ascent + 1); } /* for (col....) */ } /* for (row....) */ @@ -2228,10 +2243,10 @@ cursorwidth++; XDrawRectangle (display->display, drawBuffer, TermWin.gc, - Col2Pixel (oldcursor.col), - Row2Pixel (oldcursor.row), - (unsigned int) (Width2Pixel (cursorwidth) - 1), - (unsigned int) (Height2Pixel (1) - TermWin.lineSpace - 1)); + Col2Pixel (oldcursor.col), + Row2Pixel (oldcursor.row), + (unsigned int) (Width2Pixel (cursorwidth) - 1), + (unsigned int) (Height2Pixel (1) - TermWin.lineSpace - 1)); } } @@ -2249,17 +2264,19 @@ * specially by XClearArea */ XClearArea (display->display, TermWin.vt, 0, 0, - (unsigned int)TermWin.int_bwidth, - (unsigned int)TermWin_TotalHeight (), False); + (unsigned int)TermWin.int_bwidth, + (unsigned int)TermWin_TotalHeight (), False); + if (clearlast && TermWin.int_bwidth) /* * clear the whole screen height, note that width == 0 is treated * specially by XClearArea */ XClearArea (display->display, TermWin.vt, - TermWin.width + TermWin.int_bwidth, 0, - (unsigned int)TermWin.int_bwidth, - (unsigned int)TermWin_TotalHeight (), False); + TermWin.width + TermWin.int_bwidth, 0, + (unsigned int)TermWin.int_bwidth, + (unsigned int)TermWin_TotalHeight (), False); + if (refresh_type & SMOOTH_REFRESH) XSync (display->display, False); @@ -2293,13 +2310,14 @@ /* ------------------------------------------------------------------------- */ void -rxvt_term::scr_clear () +rxvt_term::scr_clear (bool really) { if (!TermWin.mapped) return; num_scr_allow = 0; want_refresh = 1; + #ifdef TRANSPARENT if ((Options & Opt_transparent) && (am_pixmap_trans == 0)) { @@ -2316,21 +2334,21 @@ } #endif - XClearWindow (display->display, TermWin.vt); + if (really) + XClearWindow (display->display, TermWin.vt); } /* ------------------------------------------------------------------------- */ void rxvt_term::scr_reverse_selection () { - int i, col, row, end_row; - rend_t *srp; - if (selection.op && current_screen == selection.screen) { - end_row = TermWin.saveLines - TermWin.view_start; - i = selection.beg.row + TermWin.saveLines; - row = selection.end.row + TermWin.saveLines; + int end_row = TermWin.saveLines - TermWin.view_start; + int i = selection.beg.row + TermWin.saveLines; + int col, row = selection.end.row + TermWin.saveLines; + rend_t *srp; + if (i >= end_row) col = selection.beg.col; else @@ -2338,10 +2356,12 @@ col = 0; i = end_row; } + end_row += TermWin.nrow; for (; i < row && i < end_row; i++, col = 0) for (srp = screen.rend[i]; col < TermWin.ncol; col++) srp[col] ^= RS_RVid; + if (i == row && i < end_row) for (srp = screen.rend[i]; col < selection.end.col; col++) srp[col] ^= RS_RVid; @@ -2490,10 +2510,10 @@ for (;;) { if (XGetWindowProperty (display->display, win, prop, (long) (nread / 4), - (long) (PROP_SIZE / 4), delete_prop, - AnyPropertyType, &ct.encoding, &ct.format, - &ct.nitems, &bytes_after, - &ct.value) != Success) + (long) (PROP_SIZE / 4), delete_prop, + AnyPropertyType, &ct.encoding, &ct.format, + &ct.nitems, &bytes_after, + &ct.value) != Success) break; if (ct.encoding == 0) @@ -2511,7 +2531,8 @@ if (ct.nitems == 0) { D_SELECT ((stderr, "rxvt_selection_paste: property empty - also INCR end")); - if (selection_wait == Sel_normal && nread == 0) + if (selection_wait == Sel_normal && nread == 0 + && (win != display->root || prop != XA_CUT_BUFFER0)) // avoid recursion { /* * pass through again trying CUT_BUFFER0 if we've come from @@ -2712,13 +2733,10 @@ void rxvt_term::selection_make (Time tm) { - int i, col, end_col, row, end_row; - unsigned char *new_selection_text; - char *str; - text_t *t; -#ifdef ACS_ASCII - rend_t *re; -#endif + int i, col, end_col, row, end_row; + unsigned char *new_selection_text; + char *str; + text_t *t; D_SELECT ((stderr, "rxvt_selection_make (): selection.op=%d, selection.clicks=%d", selection.op, selection.clicks)); switch (selection.op) @@ -2734,13 +2752,14 @@ default: return; } + selection.op = SELECTION_DONE; if (selection.clicks == 4) return; /* nothing selected, go away */ i = (selection.end.row - selection.beg.row + 1) * (TermWin.ncol + 1) + 1; - str = (char *)rxvt_malloc (i * MB_CUR_MAX + 1); + str = (char *)rxvt_malloc ((i + 2) * MB_CUR_MAX + 1); new_selection_text = (unsigned char *)str; @@ -2748,6 +2767,7 @@ MAX_IT (col, 0); row = selection.beg.row + TermWin.saveLines; end_row = selection.end.row + TermWin.saveLines; + struct mbstate mbs; for (; row <= end_row; row++, col = 0) { @@ -2766,7 +2786,7 @@ t++; else { - int len = wctomb (str, *t++); + int len = wcrtomb (str, *t++, mbs); if (len > 0) str += len; } @@ -2794,7 +2814,7 @@ return; } - // due to MB_MAX_CUR, selection wastage is usually high, so realloc + // due to MB_CUR_MAX, selection wastage is usually high, so realloc if (str - (char *)new_selection_text > 1024) new_selection_text = (unsigned char *)rxvt_realloc (new_selection_text, i + 1); @@ -2818,12 +2838,12 @@ if (XmbTextListToTextProperty (display->display, &cl, 1, XStringStyle, &ct) >= 0) { XChangeProperty (display->display, display->root, XA_CUT_BUFFER0, XA_STRING, 8, - PropModeReplace, ct.value, ct.nitems); + PropModeReplace, ct.value, ct.nitems); XFree (ct.value); } else XChangeProperty (display->display, display->root, XA_CUT_BUFFER0, XA_STRING, 8, - PropModeReplace, selection.text, (int)selection.len); + PropModeReplace, selection.text, (int)selection.len); } selection_time = tm;