--- rxvt-unicode/src/screen.C 2008/11/04 14:34:13 1.314 +++ rxvt-unicode/src/screen.C 2008/11/05 12:28:15 1.325 @@ -145,7 +145,7 @@ rend_t rend = l.r[col] & ~RS_baseattrMask; rend = SET_FONT (rend, FONTSET (rend)->find_font (' ')); - // found begin, nuke + // found start, nuke do { l.t[col] = ' '; l.r[col] = rend; @@ -160,11 +160,6 @@ void rxvt_term::scr_reset () { -#if ENABLE_OVERLAY - scr_overlay_off (); -#endif - - rvideo_mode = false; view_start = 0; num_scr = 0; @@ -177,9 +172,6 @@ if (ncol == prev_ncol && nrow == prev_nrow) return; - if (current_screen != PRIMARY) - scr_swap_screen (); - // we need at least two lines for wrapping to work correctly while (nrow + saveLines < 2) { @@ -288,6 +280,7 @@ { // Re-wrap lines. This is rather ugly, possibly because I am too dumb // to come up with a lean and mean algorithm. + // TODO: maybe optimise when width didn't change row_col_t ocur = screen.cur; ocur.row = MOD (term_start + ocur.row, prev_total_rows); @@ -401,8 +394,6 @@ clamp_it (screen.cur.row, 0, nrow - 1); clamp_it (screen.cur.col, 0, ncol - 1); - - free (tabs); } CLEAR_ALL_SELECTION (); @@ -410,14 +401,6 @@ prev_nrow = nrow; prev_ncol = ncol; - tabs = (char *)rxvt_malloc (ncol); - - for (int col = ncol; --col; ) - tabs [col] = col % TABSIZE == 0; - - if (current_screen != PRIMARY) - scr_swap_screen (); - tt_winch (); HOOK_INVOKE ((this, HOOK_RESET, DT_END)); @@ -438,27 +421,52 @@ free (row_buf); free (swap_buf); free (drawn_buf); - free (tabs); + row_buf = 0; // signal that we freed all the arrays above - row_buf = 0; // signal that we freed all the arrays + free (tabs); + tabs = 0; } } /* ------------------------------------------------------------------------- */ /* - * Hard reset + * Hard/Soft reset */ void rxvt_term::scr_poweron () { scr_release (); prev_nrow = prev_ncol = 0; + rvideo_mode = false; + scr_soft_reset (); scr_reset (); scr_clear (true); scr_refresh (); } +void +rxvt_term::scr_soft_reset () +{ + /* only affects modes, nothing drastic such as clearing the screen */ +#if ENABLE_OVERLAY + scr_overlay_off (); +#endif + + if (current_screen != PRIMARY) + scr_swap_screen (); + + free (tabs); + tabs = (char *)rxvt_malloc (ncol); + + for (int col = ncol; --col; ) + tabs [col] = col % TABSIZE == 0; + + scr_scroll_region (0, MAX_ROWS - 1); + scr_rendition (0, ~RS_None); + scr_insert_mode (0); +} + /* ------------------------------------------------------------------------- * * PROCESS SCREEN COMMANDS * * ------------------------------------------------------------------------- */ @@ -908,8 +916,8 @@ // if the character doesn't fit into the remaining columns... if (expect_false (screen.cur.col > ncol - width && ncol >= width)) { - // ...output spaces - c = ' '; + // ... artificially enlargen the previous one + c = NOCHAR; // and try the same character next loop iteration --str; } @@ -1335,36 +1343,43 @@ min_it (num, nrow - row); - /*TODO: the xlceararea/xfillrectangle below don't take scroll offste into account, ask mikachu for details */ + // TODO: the code below does not work when view_start != 0 + // the workaround is to disable the clear and use a normal refresh + // when view_start != 0. mysterious. if (rstyle & (RS_RVid | RS_Uline)) ren = (rend_t) ~RS_None; else if (GET_BASEBG (rstyle) == Color_bg) { ren = DEFAULT_RSTYLE; - if (mapped) + if (mapped && !view_start) XClearArea (dpy, vt, 0, - Row2Pixel (row), (unsigned int)width, + Row2Pixel (row - view_start), (unsigned int)width, (unsigned int)Height2Pixel (num), False); } else { ren = rstyle & (RS_fgMask | RS_bgMask); - gcvalue.foreground = pix_colors[bgcolor_of (rstyle)]; - XChangeGC (dpy, gc, GCForeground, &gcvalue); - XFillRectangle (dpy, vt, gc, - 0, Row2Pixel (row), - (unsigned int)width, - (unsigned int)Height2Pixel (num)); - gcvalue.foreground = pix_colors[Color_fg]; - XChangeGC (dpy, gc, GCForeground, &gcvalue); + if (mapped && !view_start) + { + gcvalue.foreground = pix_colors[bgcolor_of (rstyle)]; + XChangeGC (dpy, gc, GCForeground, &gcvalue); + XFillRectangle (dpy, vt, gc, + 0, Row2Pixel (row - view_start), + (unsigned int)width, + (unsigned int)Height2Pixel (num)); + gcvalue.foreground = pix_colors[Color_fg]; + XChangeGC (dpy, gc, GCForeground, &gcvalue); + } } for (; num--; row++) { scr_blank_screen_mem (ROW(row), rstyle); - scr_blank_line (drawn_buf [row], 0, ncol, ren); + + if (!view_start) + scr_blank_line (drawn_buf [row], 0, ncol, ren); } } @@ -1466,11 +1481,18 @@ line->touch (); line->is_longer (0); + // nuke wide spanning the start + if (line->t[screen.cur.col] == NOCHAR) + scr_kill_char (*line, screen.cur.col); + switch (insdel) { case INSERT: line->l = min (line->l + count, ncol); + if (line->t[screen.cur.col] == NOCHAR) + scr_kill_char (*line, screen.cur.col); + for (int col = ncol - 1; (col - count) >= screen.cur.col; col--) { line->t[col] = line->t[col - count]; @@ -1500,42 +1522,42 @@ selection_check (1); screen.cur.col -= count; + // nuke wide char after the end + if (screen.cur.col + count < ncol && line->t[screen.cur.col + count] == NOCHAR) + scr_kill_char (*line, screen.cur.col + count); + scr_blank_line (*line, screen.cur.col, count, rstyle); break; case DELETE: - { - line->l = max (line->l - count, 0); + line->l = max (line->l - count, 0); - rend_t tr = line->r[ncol - 1] & (RS_fgMask | RS_bgMask | RS_baseattrMask); + // nuke wide char spanning the end + if (screen.cur.col + count < ncol && line->t[screen.cur.col + count] == NOCHAR) + scr_kill_char (*line, screen.cur.col + count); - for (int col = screen.cur.col; (col + count) < ncol; col++) - { - line->t[col] = line->t[col + count]; - line->r[col] = line->r[col + count]; - } - - // nuke wide char at the end - if (line->t[screen.cur.col] == NOCHAR) - scr_kill_char (*line, screen.cur.col); + for (int col = screen.cur.col; (col + count) < ncol; col++) + { + line->t[col] = line->t[col + count]; + line->r[col] = line->r[col + count]; + } - scr_blank_line (*line, ncol - count, count, tr); + scr_blank_line (*line, ncol - count, count, rstyle); - if (selection.op && current_screen == selection.screen - && ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur)) - { - if (selection.end.row != screen.cur.row - || (screen.cur.col >= selection.beg.col - count) - || selection.end.col >= ncol) - CLEAR_SELECTION (); - else - { - /* shift selection */ - selection.beg.col -= count; - selection.mark.col -= count; /* XXX: yes? */ - selection.end.col -= count; - } - } + if (selection.op && current_screen == selection.screen + && ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur)) + { + if (selection.end.row != screen.cur.row + || (screen.cur.col >= selection.beg.col - count) + || selection.end.col >= ncol) + CLEAR_SELECTION (); + else + { + /* shift selection */ + selection.beg.col -= count; + selection.mark.col -= count; /* XXX: yes? */ + selection.end.col -= count; + } } break;