--- rxvt-unicode/src/screen.C 2004/04/04 14:35:00 1.68 +++ rxvt-unicode/src/screen.C 2004/08/17 01:29:12 1.104 @@ -1,5 +1,5 @@ /*--------------------------------*-C-*--------------------------------------* - * File: screen.c + * File: screen.C *---------------------------------------------------------------------------* * * Copyright (c) 1997-2001 Geoff Wing @@ -27,11 +27,10 @@ #include "../config.h" /* NECESSARY */ #define INTERN_SCREEN #include "rxvt.h" /* NECESSARY */ -#include "screen.intpro" /* PROTOS for internal routines */ #include /* get the typedef for CARD32 */ -#include +#include #include #include "salloc.C" // HACK, should be a seperate compile! @@ -50,41 +49,41 @@ * GENERAL SCREEN AND SELECTION UPDATE ROUTINES * * ------------------------------------------------------------------------- */ #define ZERO_SCROLLBACK() \ - if ((Options & Opt_scrollTtyOutput) == Opt_scrollTtyOutput) \ + if (options & Opt_scrollTtyOutput) \ TermWin.view_start = 0 #define CLEAR_SELECTION() \ - selection.beg.row = selection.beg.col \ + selection.beg.row = selection.beg.col \ = selection.end.row = selection.end.col = 0 #define CLEAR_ALL_SELECTION() \ - selection.beg.row = selection.beg.col \ - = selection.mark.row = selection.mark.col \ + selection.beg.row = selection.beg.col \ + = selection.mark.row = selection.mark.col \ = selection.end.row = selection.end.col = 0 -#define ROW_AND_COL_IS_AFTER(A, B, C, D) \ +#define ROW_AND_COL_IS_AFTER(A, B, C, D) \ (((A) > (C)) || (((A) == (C)) && ((B) > (D)))) -#define ROW_AND_COL_IS_BEFORE(A, B, C, D) \ +#define ROW_AND_COL_IS_BEFORE(A, B, C, D) \ (((A) < (C)) || (((A) == (C)) && ((B) < (D)))) -#define ROW_AND_COL_IN_ROW_AFTER(A, B, C, D) \ +#define ROW_AND_COL_IN_ROW_AFTER(A, B, C, D) \ (((A) == (C)) && ((B) > (D))) -#define ROW_AND_COL_IN_ROW_AT_OR_AFTER(A, B, C, D) \ +#define ROW_AND_COL_IN_ROW_AT_OR_AFTER(A, B, C, D) \ (((A) == (C)) && ((B) >= (D))) -#define ROW_AND_COL_IN_ROW_BEFORE(A, B, C, D) \ +#define ROW_AND_COL_IN_ROW_BEFORE(A, B, C, D) \ (((A) == (C)) && ((B) < (D))) -#define ROW_AND_COL_IN_ROW_AT_OR_BEFORE(A, B, C, D) \ +#define ROW_AND_COL_IN_ROW_AT_OR_BEFORE(A, B, C, D) \ (((A) == (C)) && ((B) <= (D))) /* these must be row_col_t */ -#define ROWCOL_IS_AFTER(X, Y) \ +#define ROWCOL_IS_AFTER(X, Y) \ ROW_AND_COL_IS_AFTER ((X).row, (X).col, (Y).row, (Y).col) -#define ROWCOL_IS_BEFORE(X, Y) \ +#define ROWCOL_IS_BEFORE(X, Y) \ ROW_AND_COL_IS_BEFORE ((X).row, (X).col, (Y).row, (Y).col) -#define ROWCOL_IN_ROW_AFTER(X, Y) \ +#define ROWCOL_IN_ROW_AFTER(X, Y) \ ROW_AND_COL_IN_ROW_AFTER ((X).row, (X).col, (Y).row, (Y).col) -#define ROWCOL_IN_ROW_BEFORE(X, Y) \ +#define ROWCOL_IN_ROW_BEFORE(X, Y) \ ROW_AND_COL_IN_ROW_BEFORE ((X).row, (X).col, (Y).row, (Y).col) -#define ROWCOL_IN_ROW_AT_OR_AFTER(X, Y) \ +#define ROWCOL_IN_ROW_AT_OR_AFTER(X, Y) \ ROW_AND_COL_IN_ROW_AT_OR_AFTER ((X).row, (X).col, (Y).row, (Y).col) -#define ROWCOL_IN_ROW_AT_OR_BEFORE(X, Y) \ +#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) /* @@ -94,22 +93,22 @@ */ #define drawBuffer TermWin.vt -#define CLEAR_ROWS(row, num) \ - if (TermWin.mapped) \ - XClearArea (display->display, drawBuffer, TermWin.int_bwidth, \ +#define CLEAR_ROWS(row, num) \ + if (TermWin.mapped) \ + XClearArea (display->display, drawBuffer, 0, \ Row2Pixel (row), (unsigned int)TermWin.width, \ (unsigned int)Height2Pixel (num), False) -#define CLEAR_CHARS(x, y, num) \ - if (TermWin.mapped) \ - XClearArea (display->display, drawBuffer, x, y, \ - (unsigned int)Width2Pixel (num), \ +#define CLEAR_CHARS(x, y, num) \ + if (TermWin.mapped) \ + XClearArea (display->display, drawBuffer, x, y, \ + (unsigned int)Width2Pixel (num), \ (unsigned int)Height2Pixel (1), False) -#define ERASE_ROWS(row, num) \ - XFillRectangle (display->display, drawBuffer, TermWin.gc, \ - TermWin.int_bwidth, Row2Pixel (row), \ - (unsigned int)TermWin.width, \ +#define ERASE_ROWS(row, num) \ + XFillRectangle (display->display, drawBuffer, TermWin.gc, \ + 0, Row2Pixel (row), \ + (unsigned int)TermWin.width, \ (unsigned int)Height2Pixel (num)) /* ------------------------------------------------------------------------- * @@ -120,7 +119,7 @@ rxvt_term::scr_blank_line (text_t *et, rend_t *er, unsigned int width, rend_t efs) { efs &= ~RS_baseattrMask; - efs = SET_FONT (efs, TermWin.fontset->find_font (' ')); + efs = SET_FONT (efs, TermWin.ascii_map [' ' - 0x20]); while (width--) { @@ -157,7 +156,9 @@ int k; rend_t setrstyle; - D_SCREEN ((stderr, "rxvt_scr_reset ()")); +#if ENABLE_OVERLAY + scr_overlay_off (); +#endif TermWin.view_start = 0; num_scr = 0; @@ -174,10 +175,18 @@ if (ncol == prev_ncol && nrow == prev_nrow) return; + // we need at least two lines for wrapping to work correctly + if (nrow + TermWin.saveLines < 2) + { + TermWin.saveLines++; + prev_nrow--; + TermWin.nscrolled++; + } + want_refresh = 1; - total_rows = nrow + TermWin.saveLines; prev_total_rows = prev_nrow + TermWin.saveLines; + total_rows = nrow + TermWin.saveLines; screen.tscroll = 0; screen.bscroll = nrow - 1; @@ -188,10 +197,10 @@ ralloc = new rxvt_salloc (ncol * sizeof (rend_t)); } - if (prev_nrow == 0) + if (!screen.text) { /* - * first time called so just malloc everything : don't rely on realloc + * 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 */ screen.text = (text_t **)rxvt_calloc (total_rows, sizeof (text_t *)); @@ -216,7 +225,7 @@ scr_blank_screen_mem (drawn_text, drawn_rend, p, DEFAULT_RSTYLE); } - MEMSET (charsets, 'B', sizeof (charsets)); + memset (charsets, 'B', sizeof (charsets)); TermWin.nscrolled = 0; /* no saved lines */ rstyle = DEFAULT_RSTYLE; screen.flags = Screen_DefaultFlags; @@ -258,6 +267,7 @@ for (p = nrow; p < prev_nrow; p++) { q = p + TermWin.saveLines; + if (screen.text[q]) { #ifdef DEBUG_STRICT @@ -266,6 +276,7 @@ talloc->free (screen.text[q]); ralloc->free (screen.rend[q]); } + if (swap.text[p]) { #ifdef DEBUG_STRICT @@ -274,6 +285,7 @@ talloc->free (swap.text[p]); ralloc->free (swap.rend[p]); } + #ifdef DEBUG_STRICT assert (drawn_text[p] && drawn_rend[p]); #endif @@ -313,7 +325,7 @@ swap.rend[p] = NULL; drawn_text[p] = NULL; drawn_rend[p] = NULL; - scr_blank_screen_mem (swap.text, swap.rend, p, setrstyle); + scr_blank_screen_mem (swap.text, swap.rend, p, setrstyle); scr_blank_screen_mem (drawn_text, drawn_rend, p, setrstyle); } @@ -338,7 +350,6 @@ /* resize columns */ if (ncol != prev_ncol) { - int common = min (prev_ncol, ncol); rxvt_salloc *ta = new rxvt_salloc (ncol * sizeof (text_t)); rxvt_salloc *ra = new rxvt_salloc (ncol * sizeof (rend_t)); @@ -346,39 +357,38 @@ { if (screen.text[p]) { - text_t *t = (text_t *)ta->alloc (); memcpy (t, screen.text[p], common * sizeof (text_t)); screen.text[p] = t; - rend_t *r = (rend_t *)ra->alloc (); memcpy (r, screen.rend[p], common * sizeof (rend_t)); screen.rend[p] = r; + screen.text[p] = (text_t *)ta->alloc (screen.text[p], prev_ncol * sizeof (text_t)); + screen.rend[p] = (rend_t *)ra->alloc (screen.rend[p], prev_ncol * sizeof (rend_t)); MIN_IT (screen.tlen[p], (int16_t)ncol); if (ncol > prev_ncol) - scr_blank_line (& (screen.text[p][prev_ncol]), - & (screen.rend[p][prev_ncol]), - ncol - prev_ncol, - setrstyle); + scr_blank_line (&screen.text[p][prev_ncol], + &screen.rend[p][prev_ncol], + ncol - prev_ncol, setrstyle); } } for (p = 0; p < nrow; p++) { - text_t *t = (text_t *)ta->alloc (); memcpy (t, drawn_text[p], common * sizeof (text_t)); drawn_text[p] = t; - rend_t *r = (rend_t *)ra->alloc (); memcpy (r, drawn_rend[p], common * sizeof (rend_t)); drawn_rend[p] = r; + drawn_text[p] = (text_t *)ta->alloc (drawn_text[p], prev_ncol * sizeof (text_t)); + drawn_rend[p] = (rend_t *)ra->alloc (drawn_rend[p], prev_ncol * sizeof (rend_t)); if (ncol > prev_ncol) - scr_blank_line (& (drawn_text[p][prev_ncol]), - & (drawn_rend[p][prev_ncol]), + scr_blank_line (&drawn_text[p][prev_ncol], + &drawn_rend[p][prev_ncol], ncol - prev_ncol, setrstyle); if (swap.text[p]) { - text_t *t = (text_t *)ta->alloc (); memcpy (t, swap.text[p], common * sizeof (text_t)); swap.text[p] = t; - rend_t *r = (rend_t *)ra->alloc (); memcpy (r, swap.rend[p], common * sizeof (rend_t)); swap.rend[p] = r; + swap.text[p] = (text_t *)ta->alloc (swap.text[p], prev_ncol * sizeof (text_t)); + swap.rend[p] = (rend_t *)ra->alloc (swap.rend[p], prev_ncol * sizeof (rend_t)); MIN_IT (swap.tlen[p], (int16_t)ncol); if (ncol > prev_ncol) - scr_blank_line (& (swap.text[p][prev_ncol]), - & (swap.rend[p][prev_ncol]), + scr_blank_line (&swap.text[p][prev_ncol], + &swap.rend[p][prev_ncol], ncol - prev_ncol, setrstyle); } @@ -472,13 +482,11 @@ void rxvt_term::scr_poweron () { - D_SCREEN ((stderr, "rxvt_scr_poweron ()")); - scr_release (); prev_nrow = prev_ncol = 0; scr_reset (); - scr_clear (); + scr_clear (true); scr_refresh (SLOW_REFRESH); } @@ -495,8 +503,6 @@ { screen_t *s; - D_SCREEN ((stderr, "rxvt_scr_cursor (%c)", mode)); - #if NSCREENS && !defined(NO_SECONDARY_SCREEN_CURSOR) if (current_screen == SECONDARY) s = &swap; @@ -513,6 +519,7 @@ s->s_charset = s->charset; s->s_charset_char = charsets[s->charset]; break; + case RESTORE: want_refresh = 1; s->cur.row = s->s_cur.row; @@ -553,8 +560,6 @@ want_refresh = 1; - D_SCREEN ((stderr, "rxvt_scr_change_screen (%d)", scrn)); - TermWin.view_start = 0; if (current_screen == scrn) @@ -564,7 +569,7 @@ SWAP_IT (current_screen, scrn, int); #if NSCREENS - if (Options & Opt_secondaryScreen) + if (options & Opt_secondaryScreen) { num_scr = 0; offset = TermWin.saveLines; @@ -592,12 +597,29 @@ } else #endif - if (Options & Opt_secondaryScroll) + if (options & Opt_secondaryScroll) //if (current_screen == PRIMARY) scr_scroll_text (0, (prev_nrow - 1), prev_nrow, 0); return scrn; } +// clear WrapNext indicator, solidifying position on next line +void +rxvt_term::scr_do_wrap () +{ + if (!(screen.flags & Screen_WrapNext)) + return; + + screen.flags &= ~Screen_WrapNext; + + screen.cur.col = 0; + + if (screen.cur.row == screen.bscroll) + scr_scroll_text (screen.tscroll, screen.bscroll, 1, 0); + else if (screen.cur.row < TermWin.nrow - 1) + screen.cur.row++; +} + /* ------------------------------------------------------------------------- */ /* * Change the colour for following text @@ -644,10 +666,9 @@ return 0; want_refresh = 1; - D_SCREEN ((stderr, "rxvt_scroll_text (%d,%d,%d,%d): %s", row1, row2, count, spec, (current_screen == PRIMARY) ? "Primary" : "Secondary")); if (row1 == 0 && count > 0 - && (current_screen == PRIMARY || Options & Opt_secondaryScroll)) + && (current_screen == PRIMARY || options & Opt_secondaryScroll)) { nscrolled = (long)TermWin.nscrolled + (long)count; @@ -656,7 +677,7 @@ else TermWin.nscrolled = (uint16_t)nscrolled; - if ((Options & Opt_scrollWithBuffer) + if ((options & Opt_scrollWithBuffer) && TermWin.view_start != 0 && TermWin.view_start != TermWin.saveLines) scr_page (UP, count); @@ -705,18 +726,15 @@ /* A: scroll up */ /* A1: Copy lines that will get clobbered by the rotation */ - for (i = 0, j = row1; i < count; i++, j++) - { - buf_text[i] = screen.text[j]; - buf_rend[i] = screen.rend[j]; - } + memcpy (buf_text, screen.text + row1, count * sizeof (text_t *)); + memcpy (buf_rend, screen.rend + row1, count * sizeof (rend_t *)); + /* A2: Rotate lines */ - for (j = row1, i = j + count; i <= row2; i++, j++) - { - screen.tlen[j] = screen.tlen[i]; - screen.text[j] = screen.text[i]; - screen.rend[j] = screen.rend[i]; - } + i = row2 - row1 - count + 1; + memmove (screen.tlen + row1, screen.tlen + row1 + count, i * sizeof (int16_t)); + memmove (screen.text + row1, screen.text + row1 + count, i * sizeof (text_t *)); + memmove (screen.rend + row1, screen.rend + row1 + count, i * sizeof (rend_t *)); + j = row2 - count + 1, i = count; } else /* if (j < 0) */ @@ -729,6 +747,7 @@ buf_text[i] = screen.text[j]; buf_rend[i] = screen.rend[j]; } + /* B2: Rotate lines */ for (j = row2, i = j - count; i >= row1; i--, j--) { @@ -736,21 +755,18 @@ screen.text[j] = screen.text[i]; screen.rend[j] = screen.rend[i]; } + j = row1, i = count; count = -count; } /* C: Resurrect lines */ - for (; i--; j++) - { - screen.tlen[j] = 0; - screen.text[j] = buf_text[i]; - screen.rend[j] = buf_rend[i]; - - if (!spec) /* line length may not equal TermWin.ncol */ - scr_blank_screen_mem (screen.text, screen.rend, - (unsigned int)j, rstyle); - } + memset (screen.tlen + j, 0, i * sizeof (int16_t)); + memcpy (screen.text + j, buf_text, i * sizeof (text_t *)); + memcpy (screen.rend + j, buf_rend, i * sizeof (text_t *)); + if (!spec) /* line length may not equal TermWin.ncol */ + for (; i--; j++) + scr_blank_screen_mem (screen.text, screen.rend, (unsigned int)j, rstyle); return count; } @@ -762,7 +778,7 @@ void rxvt_term::scr_add_lines (const unicode_t *str, int nlines, int len) { - unsigned char checksel, clearsel; + unsigned char checksel; unicode_t c; int i, row, last_col; text_t *stp; @@ -772,13 +788,12 @@ return; want_refresh = 1; + ZERO_SCROLLBACK (); last_col = TermWin.ncol; - D_SCREEN ((stderr, "rxvt_scr_add_lines (%d,%d)", nlines, len)); - ZERO_SCROLLBACK (); if (nlines > 0) { - nlines += (screen.cur.row - screen.bscroll); + nlines += screen.cur.row - screen.bscroll; if ((nlines > 0) && (screen.tscroll == 0) && (screen.bscroll == (TermWin.nrow - 1))) @@ -788,10 +803,11 @@ screen.cur.row -= nlines; } } + #ifdef DEBUG_STRICT assert (screen.cur.col < last_col); assert ((screen.cur.row < TermWin.nrow) - && (screen.cur.row >= - (int32_t)TermWin.nscrolled)); + && (screen.cur.row >= - (int32_t)TermWin.nscrolled)); #else /* drive with your eyes closed */ MIN_IT (screen.cur.col, last_col - 1); MIN_IT (screen.cur.row, (int32_t)TermWin.nrow - 1); @@ -800,7 +816,6 @@ row = screen.cur.row + TermWin.saveLines; checksel = selection.op && current_screen == selection.screen ? 1 : 0; - clearsel = 0; stp = screen.text[row]; srp = screen.rend[row]; @@ -812,11 +827,11 @@ if (c < 0x20) switch (c) { - case '\t': + case C0_HT: scr_tab (1); continue; - case '\n': + case C0_LF: if (screen.tlen[row] != -1) /* XXX: think about this */ MAX_IT (screen.tlen[row], screen.cur.col); @@ -831,7 +846,7 @@ srp = screen.rend[row]; /* _must_ refresh */ continue; - case '\r': + case C0_CR: if (screen.tlen[row] != -1) /* XXX: think about this */ MAX_IT (screen.tlen[row], screen.cur.col); @@ -845,21 +860,22 @@ && ROWCOL_IS_BEFORE (screen.cur, selection.end)) { checksel = 0; - clearsel = 1; + /* + * If we wrote anywhere in the selected area, kill the selection + * XXX: should we kill the mark too? Possibly, but maybe that + * should be a similar check. + */ + CLEAR_SELECTION (); } if (screen.flags & Screen_WrapNext) { screen.tlen[row] = -1; - if (screen.cur.row == screen.bscroll) - scr_scroll_text (screen.tscroll, screen.bscroll, 1, 0); - else if (screen.cur.row < (TermWin.nrow - 1)) - row = (++screen.cur.row) + TermWin.saveLines; + + scr_do_wrap (); row = screen.cur.row + TermWin.saveLines; stp = screen.text[row]; /* _must_ refresh */ srp = screen.rend[row]; /* _must_ refresh */ - screen.cur.col = 0; - screen.flags &= ~Screen_WrapNext; } if (screen.flags & Screen_Insert) @@ -868,7 +884,7 @@ // rely on wcwidth to tell us the character width, at least for non-latin1 // do wcwidth before further replacements, as wcwidth says that line-drawing // characters have width -1 (DOH!) on GNU/Linux sometimes. - int width = c < 256 ? 1 : wcwidth (c); + int width = c < 0x100 ? 1 : wcwidth (c); if (charsets[screen.charset] == '0') // DEC SPECIAL { @@ -887,14 +903,22 @@ } } - if (width > 0) + if (width != 0) { -#if !UNICODE_3 && ENABLE_COMBINING +#if !UNICODE_3 // trim characters we can't store directly :( if (c >= 0x10000) +# if ENABLE_COMBINING c = rxvt_composite.compose (c); // map to lower 16 bits +# else + c = 0xfffd; +# endif #endif - rend_t rend = SET_FONT (rstyle, TermWin.fontset->find_font (c)); + bool bold = (options & Opt_realBold) && ((rstyle & RS_Bold) != 0); + rend_t rend = SET_FONT (rstyle, + c > 0x7f || bold || c < 0x20 + ? TermWin.fontset->find_font (c, bold) + : TermWin.ascii_map [c - 0x20]); do { @@ -965,14 +989,6 @@ if (screen.tlen[row] != -1) /* XXX: think about this */ MAX_IT (screen.tlen[row], screen.cur.col); - /* - * If we wrote anywhere in the selected area, kill the selection - * XXX: should we kill the mark too? Possibly, but maybe that - * should be a similar check. - */ - if (clearsel) - CLEAR_SELECTION (); - #ifdef DEBUG_STRICT assert (screen.cur.row >= 0); #else /* drive with your eyes closed */ @@ -989,6 +1005,7 @@ rxvt_term::scr_backspace () { want_refresh = 1; + if (screen.cur.col == 0) { if (screen.cur.row > 0) @@ -998,11 +1015,11 @@ screen.cur.row--; return; #endif - } } - else if ((screen.flags & Screen_WrapNext) == 0) + else if (!(screen.flags & Screen_WrapNext)) scr_gotorc (0, -1, RELATIVE); + screen.flags &= ~Screen_WrapNext; } @@ -1017,7 +1034,6 @@ { int i, x; - D_SCREEN ((stderr, "rxvt_scr_tab (%d)", count)); want_refresh = 1; i = x = screen.cur.col; @@ -1061,7 +1077,7 @@ * Move cursor left in row. If we're at the left boundary, shift everything * in that row right. Clear left column. */ -#ifndef NO_FRILLS +#if ENABLE_FRILLS void rxvt_term::scr_backindex () { @@ -1071,6 +1087,7 @@ { if (screen.tlen[screen.cur.row + TermWin.saveLines] == 0) return; /* um, yeah? */ + scr_insdel_chars (1, INSERT); } } @@ -1082,7 +1099,7 @@ * Move cursor right in row. If we're at the right boundary, shift everything * in that row left. Clear right column. */ -#ifndef NO_FRILLS +#if ENABLE_FRILLS void rxvt_term::scr_forwardindex () { @@ -1093,10 +1110,12 @@ else { row = screen.cur.row + TermWin.saveLines; + if (screen.tlen[row] == 0) return; /* um, yeah? */ else if (screen.tlen[row] == -1) screen.tlen[row] = TermWin.ncol; + scr_gotorc (0, 0, R_RELATIVE); scr_insdel_chars (1, DELETE); scr_gotorc (0, TermWin.ncol - 1, R_RELATIVE); @@ -1114,14 +1133,12 @@ want_refresh = 1; ZERO_SCROLLBACK (); - D_SCREEN ((stderr, "rxvt_scr_gotorc (r:%s%d,c:%s%d): from (r:%d,c:%d)", (relative & R_RELATIVE ? "+" : ""), row, (relative & C_RELATIVE ? "+" : ""), col, screen.cur.row, screen.cur.col)); - - screen.cur.col = ((relative & C_RELATIVE) ? (screen.cur.col + col) - : col); + screen.cur.col = relative & C_RELATIVE ? screen.cur.col + col : col; MAX_IT (screen.cur.col, 0); MIN_IT (screen.cur.col, (int32_t)TermWin.ncol - 1); screen.flags &= ~Screen_WrapNext; + if (relative & R_RELATIVE) { if (row > 0) @@ -1151,35 +1168,33 @@ else screen.cur.row = row; } + 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--; } /* ------------------------------------------------------------------------- */ /* - * direction should be UP or DN + * direction should be UP or DN */ void rxvt_term::scr_index (enum page_dirn direction) { - int dirn; + int dirn; want_refresh = 1; - dirn = ((direction == UP) ? 1 : -1); - D_SCREEN ((stderr, "rxvt_scr_index (%d)", dirn)); - ZERO_SCROLLBACK (); + dirn = ((direction == UP) ? 1 : -1); + screen.flags &= ~Screen_WrapNext; + if ((screen.cur.row == screen.bscroll && direction == UP) || (screen.cur.row == screen.tscroll && direction == DN)) scr_scroll_text (screen.tscroll, screen.bscroll, dirn, 0); else screen.cur.row += dirn; + MAX_IT (screen.cur.row, 0); MIN_IT (screen.cur.row, (int32_t)TermWin.nrow - 1); selection_check (0); @@ -1198,13 +1213,10 @@ unsigned int row, col, num; want_refresh = 1; - D_SCREEN ((stderr, "rxvt_scr_erase_line (%d) at screen row: %d", mode, screen.cur.row)); ZERO_SCROLLBACK (); selection_check (1); - screen.flags &= ~Screen_WrapNext; - row = TermWin.saveLines + screen.cur.row; switch (mode) { @@ -1236,8 +1248,7 @@ } if (screen.text[row]) - scr_blank_line (& (screen.text[row][col]), - & (screen.rend[row][col]), num, rstyle); + scr_blank_line (&screen.text[row][col], &screen.rend[row][col], num, rstyle); else scr_blank_screen_mem (screen.text, screen.rend, row, rstyle); } @@ -1258,8 +1269,8 @@ XGCValues gcvalue; want_refresh = 1; - D_SCREEN ((stderr, "rxvt_scr_erase_screen (%d) at screen row: %d", mode, screen.cur.row)); ZERO_SCROLLBACK (); + row_offset = (int32_t)TermWin.saveLines; switch (mode) @@ -1285,8 +1296,6 @@ return; } - refresh_type |= REFRESH_BOUNDS; - if (selection.op && current_screen == selection.screen && ((selection.beg.row >= row && selection.beg.row <= row + num) || (selection.end.row >= row @@ -1308,10 +1317,10 @@ else { ren = (rstyle & (RS_fgMask | RS_bgMask)); - gcvalue.foreground = PixColors[GET_BGCOLOR (rstyle)]; + gcvalue.foreground = pix_colors[GET_BGCOLOR (rstyle)]; XChangeGC (display->display, TermWin.gc, GCForeground, &gcvalue); ERASE_ROWS (row, num); - gcvalue.foreground = PixColors[Color_fg]; + gcvalue.foreground = pix_colors[Color_fg]; XChangeGC (display->display, TermWin.gc, GCForeground, &gcvalue); } @@ -1337,8 +1346,9 @@ rend_t *r1, fs; want_refresh = 1; - num_scr_allow = 0; ZERO_SCROLLBACK (); + + num_scr_allow = 0; selection_check (3); fs = SET_FONT (rstyle, TermWin.fontset->find_font ('E')); @@ -1375,7 +1385,8 @@ else if (insdel == INSERT) count = end; } - screen.flags &= ~Screen_WrapNext; + + scr_do_wrap (); scr_scroll_text (screen.cur.row, screen.bscroll, insdel * count, 0); } @@ -1399,15 +1410,16 @@ if (count <= 0) return; + scr_do_wrap (); + selection_check (1); MIN_IT (count, (TermWin.ncol - screen.cur.col)); row = screen.cur.row + TermWin.saveLines; - screen.flags &= ~Screen_WrapNext; stp = screen.text[row]; srp = screen.rend[row]; - slp = & (screen.tlen[row]); + slp = &screen.tlen[row]; switch (insdel) { @@ -1519,6 +1531,7 @@ rxvt_term::scr_cursor_visible (int mode) { want_refresh = 1; + if (mode) screen.flags |= Screen_VisibleCursor; else @@ -1537,7 +1550,7 @@ if (mode) screen.flags |= Screen_Autowrap; else - screen.flags &= ~ (Screen_Autowrap | Screen_WrapNext); + screen.flags &= ~(Screen_Autowrap | Screen_WrapNext); } /* ------------------------------------------------------------------------- */ @@ -1586,7 +1599,7 @@ rxvt_term::scr_set_tab (int mode) { if (mode < 0) - MEMSET (tabs, 0, TermWin.ncol * sizeof (char)); + memset (tabs, 0, TermWin.ncol * sizeof (char)); else if (screen.cur.col < TermWin.ncol) tabs[screen.cur.col] = (mode ? 1 : 0); } @@ -1600,23 +1613,23 @@ void rxvt_term::scr_rvideo_mode (int mode) { - XGCValues gcvalue; + XGCValues gcvalue; if (rvideo != mode) { rvideo = mode; - SWAP_IT (PixColors[Color_fg], PixColors[Color_bg], rxvt_color); + SWAP_IT (pix_colors[Color_fg], pix_colors[Color_bg], rxvt_color); #if defined(XPM_BACKGROUND) if (bgPixmap.pixmap == None) #endif #if defined(TRANSPARENT) - if (! (Options & Opt_transparent) || am_transparent == 0) + if (! (options & Opt_transparent) || am_transparent == 0) #endif XSetWindowBackground (display->display, TermWin.vt, - PixColors[Color_bg]); + pix_colors[Color_bg]); - gcvalue.foreground = PixColors[Color_fg]; - gcvalue.background = PixColors[Color_bg]; + gcvalue.foreground = pix_colors[Color_fg]; + gcvalue.background = pix_colors[Color_bg]; XChangeGC (display->display, TermWin.gc, GCBackground | GCForeground, &gcvalue); scr_clear (); @@ -1742,10 +1755,18 @@ if (drawn_text == NULL) /* sanity check */ return; +#ifndef NO_SLOW_LINK_SUPPORT + if (refresh_type == FAST_REFRESH && !display->is_local) + { + y = 0; + height = TermWin.height; + } +#endif + #ifdef DEBUG_STRICT - x = max (x, (int)TermWin.int_bwidth); + x = max (x, 0); x = min (x, (int)TermWin.width); - y = max (y, (int)TermWin.int_bwidth); + y = max (y, 0); y = min (y, (int)TermWin.height); #endif @@ -1763,14 +1784,11 @@ MIN_IT (rc[i].row, TermWin.nrow - 1); } - D_SCREEN ((stderr, "rxvt_scr_expose (x:%d, y:%d, w:%d, h:%d) area (c:%d,r:%d)- (c:%d,r:%d)", x, y, width, height, rc[PART_BEG].col, rc[PART_BEG].row, rc[PART_END].col, rc[PART_END].row)); - for (i = rc[PART_BEG].row; i <= rc[PART_END].row; i++) - fill_text (& (drawn_text[i][rc[PART_BEG].col]), 0, - (rc[PART_END].col - rc[PART_BEG].col + 1)); + fill_text (&drawn_text[i][rc[PART_BEG].col], 0, rc[PART_END].col - rc[PART_BEG].col + 1); if (refresh) - scr_refresh (SLOW_REFRESH | REFRESH_BOUNDS); + scr_refresh (SLOW_REFRESH); } /* ------------------------------------------------------------------------- */ @@ -1795,14 +1813,15 @@ uint16_t oldviewstart; oldviewstart = TermWin.view_start; + if (y < len) { p = (TermWin.nrow + TermWin.nscrolled) * (len - y) / len; p -= (long) (TermWin.nrow - 1); p = max (p, 0); } + TermWin.view_start = (uint16_t)min (p, TermWin.nscrolled); - D_SCREEN ((stderr, "rxvt_scr_move_to (%d, %d) view_start:%d", y, len, TermWin.view_start)); return scr_changeview (oldviewstart); } @@ -1815,10 +1834,9 @@ int rxvt_term::scr_page (enum page_dirn direction, int nlines) { - int n; - uint16_t oldviewstart; + int n; + uint16_t oldviewstart; - D_SCREEN ((stderr, "rxvt_scr_page (%s, %d) view_start:%d", ((direction == UP) ? "UP" : "DN"), nlines, TermWin.view_start)); #ifdef DEBUG_STRICT assert ((nlines >= 0) && (nlines <= TermWin.nrow)); #endif @@ -1844,6 +1862,7 @@ want_refresh = 1; num_scr -= (TermWin.view_start - oldviewstart); } + return (int) (TermWin.view_start - oldviewstart); } @@ -1854,11 +1873,11 @@ #ifndef NO_BELL # ifndef NO_MAPALERT # ifdef MAPALERT_OPTION - if (Options & Opt_mapAlert) + if (options & Opt_mapAlert) # endif XMapWindow (display->display, TermWin.parent[0]); # endif - if (Options & Opt_visualBell) + if (options & Opt_visualBell) { scr_rvideo_mode (!rvideo); /* refresh also done */ scr_rvideo_mode (!rvideo); /* refresh also done */ @@ -1874,14 +1893,15 @@ rxvt_term::scr_printscreen (int fullhist) { #ifdef PRINTPIPE - int i, r1, nrows, row_offset; - text_t *t; - FILE *fd; + int i, r1, nrows, row_offset; + FILE *fd; if ((fd = popen_printer ()) == NULL) return; + nrows = TermWin.nrow; row_offset = TermWin.saveLines; + if (!fullhist) row_offset -= TermWin.view_start; else @@ -1890,14 +1910,34 @@ row_offset -= TermWin.nscrolled; } + wctomb (0, 0); + for (r1 = 0; r1 < nrows; r1++) { - t = screen.text[r1 + row_offset]; - for (i = TermWin.ncol - 1; i >= 0; i--) - if (!isspace (t[i])) - break; - fprintf (fd, "%.*s\n", (i + 1), t); + text_t *tp = screen.text[r1 + row_offset]; + int len = screen.tlen[r1 + row_offset]; + + for (i = len >= 0 ? len : TermWin.ncol - 1; i--; ) + { + char mb[MB_LEN_MAX]; + text_t t = *tp++; + if (t == NOCHAR) + continue; + + len = wctomb (mb, t); + + if (len <= 0) + { + mb[0] = ' '; + len = 1; + } + + fwrite (mb, 1, len, fd); + } + + fputc ('\n', fd); } + pclose_printer (fd); #endif } @@ -1921,9 +1961,7 @@ void rxvt_term::scr_refresh (unsigned char refresh_type) { - unsigned char clearfirst, /* first character writes before cell */ - clearlast, /* last character writes beyond cell */ - must_clear, /* use draw_string not draw_image_string */ + unsigned char must_clear, /* use draw_string not draw_image_string */ rvid, /* reverse video this position */ showcursor; /* show the cursor */ int16_t col, row, /* column/row we're processing */ @@ -1933,8 +1971,7 @@ #ifndef NO_CURSORCOLOR rend_t cc1; /* store colours at cursor position (s) */ #endif - rend_t *drp, *srp; /* drawn-rend-pointer, screen-rend-pointer */ - text_t *dtp, *stp; /* drawn-text-pointer, screen-text-pointer */ + rend_t *crp; // cursor rendition pointer if (refresh_type == NO_REFRESH || !TermWin.mapped) return; @@ -1942,23 +1979,16 @@ /* * A: set up vars */ - clearfirst = clearlast = must_clear = 0; - + must_clear = 0; refresh_count = 0; row_offset = TermWin.saveLines - TermWin.view_start; - if ((refresh_type & REFRESH_BOUNDS)) - { - clearfirst = clearlast = 1; - refresh_type &= ~REFRESH_BOUNDS; - } - #ifdef XPM_BACKGROUND must_clear |= (bgPixmap.pixmap != None); #endif #ifdef TRANSPARENT - must_clear |= ((Options & Opt_transparent) && am_transparent); + must_clear |= ((options & Opt_transparent) && am_transparent); #endif ocrow = oldcursor.row; /* is there an old outline cursor on screen? */ @@ -1966,6 +1996,9 @@ * B: reverse any characters which are selected */ scr_reverse_selection (); +#if ENABLE_OVERLAY + scr_swap_overlay (); +#endif /* * C: set the cursor character (s) @@ -1983,13 +2016,18 @@ if (showcursor) { - srp = &(screen.rend[screen.cur.row + TermWin.saveLines][screen.cur.col]); + int col = screen.cur.col; + + while (col && screen.text[screen.cur.row + TermWin.saveLines][col] == NOCHAR) + col--; + + crp = &screen.rend[screen.cur.row + TermWin.saveLines][col]; if (showcursor && TermWin.focus) { - *srp ^= RS_RVid; + *crp ^= RS_RVid; #ifndef NO_CURSORCOLOR - cc1 = *srp & (RS_fgMask | RS_bgMask); + cc1 = *crp & (RS_fgMask | RS_bgMask); if (ISSET_PIXCOLOR (Color_cursor)) ccol1 = Color_cursor; else @@ -2006,8 +2044,8 @@ #else ccol2 = Color_bg; #endif - *srp = SET_FGCOLOR (*srp, ccol1); - *srp = SET_BGCOLOR (*srp, ccol2); + *crp = SET_FGCOLOR (*crp, ccol1); + *crp = SET_BGCOLOR (*crp, ccol2); #endif } } @@ -2044,19 +2082,20 @@ } } + rend_t *drp, *srp; /* drawn-rend-pointer, screen-rend-pointer */ + text_t *dtp, *stp; /* drawn-text-pointer, screen-text-pointer */ #ifndef NO_SLOW_LINK_SUPPORT /* * D: CopyArea pass - very useful for slower links * This has been deliberately kept simple. */ i = num_scr; - if (refresh_type == FAST_REFRESH && num_scr_allow && i + if (!display->is_local + && refresh_type == FAST_REFRESH && num_scr_allow && i && abs (i) < TermWin.nrow && !must_clear) { int16_t nits; int j; - rend_t *drp2; - text_t *dtp2; int len, wlen; j = TermWin.nrow; @@ -2066,12 +2105,12 @@ { if (row + i >= 0 && row + i < TermWin.nrow && row + i != ocrow) { - stp = screen.text[row + row_offset]; - srp = screen.rend[row + row_offset]; - dtp = drawn_text[row]; - dtp2 = drawn_text[row + i]; - drp = drawn_rend[row]; - drp2 = drawn_rend[row + i]; + text_t *stp = screen.text[row + row_offset]; + rend_t *srp = screen.rend[row + row_offset]; + text_t *dtp = drawn_text[row]; + text_t *dtp2 = drawn_text[row + i]; + rend_t *drp = drawn_rend[row]; + rend_t *drp2 = drawn_rend[row + i]; for (nits = 0, col = TermWin.ncol; col--; ) if (stp[col] != dtp2[col] || srp[col] != drp2[col]) @@ -2101,7 +2140,6 @@ if (wlen < len) SWAP_IT (wlen, len, int); - D_SCREEN ((stderr, "rxvt_scr_refresh (): XCopyArea: %d -> %d (height: %d)", len + i, len, wlen - len + 1)); XCopyArea (display->display, TermWin.vt, TermWin.vt, TermWin.gc, 0, Row2Pixel (len + i), (unsigned int)TermWin_TotalWidth (), @@ -2118,10 +2156,10 @@ */ for (row = 0; row < TermWin.nrow; row++) { - stp = screen.text[row + row_offset]; - srp = screen.rend[row + row_offset]; - dtp = drawn_text[row]; - drp = drawn_rend[row]; + text_t *stp = screen.text[row + row_offset]; + rend_t *srp = screen.rend[row + row_offset]; + text_t *dtp = drawn_text[row]; + rend_t *drp = drawn_rend[row]; /* * E2: OK, now the real pass @@ -2161,9 +2199,7 @@ dtp[col] = stp[col]; drp[col] = rend; count++; - - if (i) // only possible skip if char unchanged - i++; + i++; continue; } @@ -2176,20 +2212,24 @@ if (stp[col] != dtp[col] || srp[col] != drp[col]) { - if (must_clear && (i++ > (count / 2))) + if (must_clear && (i++ > count / 2)) break; dtp[col] = stp[col]; drp[col] = rend; i = 0; } - else if (must_clear || (stp[col] != ' ' && ++i >= 32)) + else if (must_clear || (stp[col] != ' ' && ++i >= 16)) break; } col--; /* went one too far. move back */ count -= i; /* dump any matching trailing chars */ + // sometimes we optimize away the trailing NOCHAR's, add them back + while (i && text[count] == NOCHAR) + count++, i--; + /* * Determine the attributes for the string */ @@ -2202,7 +2242,7 @@ rvid = !!(rend & RS_RVid); #ifndef NO_BOLD_UNDERLINE_REVERSE - if (rend & RS_Bold && fore == Color_fg) + if (rend & RS_Bold && fore == Color_fg && !(options & Opt_realBold)) { if (ISSET_PIXCOLOR (Color_BD)) fore = Color_BD; @@ -2230,7 +2270,7 @@ } #ifdef TEXT_BLINK - if (rend & RS_Blink && back == Color_bg) + if (rend & RS_Blink && (back == Color_bg || fore == Color_bg)) { if (!text_blink_ev.active) { @@ -2270,7 +2310,7 @@ else font->draw (*TermWin.drawable, xpixel, ypixel, text, count, fore, back); - if ((rend & RS_Uline) && (font->descent > 1)) + if (rend & RS_Uline && font->descent > 1 && fore != back) XDrawLine (display->display, drawBuffer, TermWin.gc, xpixel, ypixel + font->ascent + 1, xpixel + Width2Pixel (count) - 1, ypixel + font->ascent + 1); @@ -2284,18 +2324,16 @@ { if (TermWin.focus) { - srp = & (screen.rend[screen.cur.row + TermWin.saveLines] - [screen.cur.col]); - *srp ^= RS_RVid; + *crp ^= RS_RVid; #ifndef NO_CURSORCOLOR - *srp = (*srp & ~ (RS_fgMask | RS_bgMask)) | cc1; + *crp = (*crp & ~ (RS_fgMask | RS_bgMask)) | cc1; #endif } else if (oldcursor.row >= 0) { #ifndef NO_CURSORCOLOR if (ISSET_PIXCOLOR (Color_cursor)) - XSetForeground (display->display, TermWin.gc, PixColors[Color_cursor]); + XSetForeground (display->display, TermWin.gc, pix_colors[Color_cursor]); #endif int cursorwidth = 1; while (oldcursor.col + cursorwidth < TermWin.ncol @@ -2313,32 +2351,13 @@ /* * H: cleanup selection */ +#if ENABLE_OVERLAY + scr_swap_overlay (); +#endif scr_reverse_selection (); - /* - * I: other general cleanup - */ - if (clearfirst && TermWin.int_bwidth) - /* - * clear the whole screen height, note that width == 0 is treated - * specially by XClearArea - */ - XClearArea (display->display, TermWin.vt, 0, 0, - (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); - if (refresh_type & SMOOTH_REFRESH) - XSync (display->display, False); + XFlush (display->display); num_scr = 0; num_scr_allow = 1; @@ -2379,11 +2398,11 @@ want_refresh = 1; #ifdef TRANSPARENT - if ((Options & Opt_transparent) && (am_pixmap_trans == 0)) + if ((options & Opt_transparent) && (am_pixmap_trans == 0)) { int i; - if (! (Options & Opt_transparent_all)) + if (! (options & Opt_transparent_all)) i = 0; else i = (int) (sizeof (TermWin.parent) / sizeof (Window)); @@ -2470,7 +2489,7 @@ void rxvt_term::selection_check (int check_more) { - row_col_t pos; + row_col_t pos; if (!selection.op) return; @@ -2507,20 +2526,15 @@ unsigned int i, j, n; unsigned char *ds = (unsigned char *)rxvt_malloc (PROP_SIZE); -#if 0 - /* a paste should act like the user is typing, so check scrollTtyKeypress */ - ZERO_SCROLLBACK (r); -#endif - /* convert normal newline chars into common keyboard Return key sequence */ for (i = 0; i < len; i += PROP_SIZE) { n = min (len - i, PROP_SIZE); - MEMCPY (ds, data + i, n); + memcpy (ds, data + i, n); for (j = 0; j < n; j++) - if (ds[j] == '\n') - ds[j] = '\r'; + if (ds[j] == C0_LF) + ds[j] = C0_CR; tt_write (ds, (int)n); } @@ -2540,8 +2554,6 @@ unsigned long bytes_after; XTextProperty ct; - D_SELECT ((stderr, "rxvt_selection_paste (%08lx, %lu, %d), wait=%2x", win, (unsigned long)prop, (int)delete_prop, selection_wait)); - if (prop == None) /* check for failed XConvertSelection */ { if ((selection_type & Sel_CompoundText)) @@ -2577,21 +2589,22 @@ break; if (ct.encoding == 0) + break; + + if (ct.encoding == xa[XA_INCR]) { - D_SELECT ((stderr, "rxvt_selection_paste: property didn't exist!")); + // INCR selection, start handshake + XDeleteProperty (display->display, win, prop); + selection_wait = Sel_incr; + incr_ev.start (NOW + 10); break; } if (ct.value == NULL) - { - D_SELECT ((stderr, "rxvt_selection_paste: property shooting blanks!")); - continue; - } + continue; if (ct.nitems == 0) { - D_SELECT ((stderr, "rxvt_selection_paste: property empty - also INCR end")); - if (selection_wait == Sel_normal && nread == 0 && (win != display->root || prop != XA_CUT_BUFFER0)) // avoid recursion { @@ -2599,7 +2612,6 @@ * pass through again trying CUT_BUFFER0 if we've come from * XConvertSelection () but nothing was presented */ - D_SELECT ((stderr, "rxvt_selection_request: pasting CUT_BUFFER0")); selection_paste (display->root, XA_CUT_BUFFER0, False); } @@ -2611,11 +2623,10 @@ char **cl; int cr; - if (XmbTextPropertyToTextList (display->display, &ct, &cl, - &cr) >= 0 && cl) + if (XmbTextPropertyToTextList (display->display, &ct, &cl, &cr) >= 0 && cl) { for (int i = 0; i < cr; i++) - paste ((unsigned char *)cl[i], STRLEN (cl[i])); + paste ((unsigned char *)cl[i], strlen (cl[i])); XFreeStringList (cl); } @@ -2634,7 +2645,6 @@ if (selection_wait == Sel_normal) selection_wait = Sel_none; - D_SELECT ((stderr, "rxvt_selection_paste: bytes written: %ld", nread)); return (int)nread; } @@ -2652,52 +2662,16 @@ void rxvt_term::selection_property (Window win, Atom prop) { - int reget_time = 0; - - if (prop == None) + if (prop == None || selection_wait != Sel_incr) return; - D_SELECT ((stderr, "rxvt_selection_property (%08lx, %lu)", win, (unsigned long)prop)); - if (selection_wait == Sel_normal) - { - int a, afmt; - Atom atype; - unsigned long bytes_after, nitems; - unsigned char *s = NULL; - - a = XGetWindowProperty (display->display, win, prop, 0L, 1L, False, - xa[XA_INCR], &atype, &afmt, &nitems, - &bytes_after, &s); - if (s) - XFree (s); - if (a != Success) - return; - -#ifndef __CYGWIN32__ - if (atype == xa[XA_INCR]) - { /* start an INCR transfer */ - D_SELECT ((stderr, "rxvt_selection_property: INCR: starting transfer")); - XDeleteProperty (display->display, win, prop); - XFlush (display->display); - reget_time = 1; - selection_wait = Sel_incr; - } -#endif - - } - else if (selection_wait == Sel_incr) + if (selection_paste (win, prop, 1) > 0) + incr_ev.start (NOW + 10); + else { - reget_time = 1; - - if (selection_paste (win, prop, True) == -1) - { - D_SELECT ((stderr, "rxvt_selection_property: INCR: clean end")); - selection_wait = Sel_none; - incr_ev.stop (); - } + selection_wait = Sel_none; + incr_ev.stop (); } - if (reget_time) /* received more data so reget time */ - incr_ev.start (NOW + 10); } /* ------------------------------------------------------------------------- */ @@ -2713,14 +2687,11 @@ void rxvt_term::selection_request (Time tm, int x, int y) { - D_SELECT ((stderr, "rxvt_selection_request (%lu, %d, %d)", tm, x, y)); - if (x < 0 || x >= TermWin.width || y < 0 || y >= TermWin.height) return; /* outside window */ if (selection.text) { /* internal selection */ - D_SELECT ((stderr, "rxvt_selection_request: pasting internal")); char *str = rxvt_wcstombs (selection.text, selection.len); paste ((unsigned char *)str, strlen (str)); free (str); @@ -2749,7 +2720,6 @@ } selection_wait = Sel_none; /* don't loop in rxvt_selection_paste () */ - D_SELECT ((stderr, "rxvt_selection_request: pasting CUT_BUFFER0")); selection_paste (display->root, XA_CUT_BUFFER0, False); } @@ -2772,7 +2742,6 @@ if (XGetSelectionOwner (display->display, sel) != None) { - D_SELECT ((stderr, "rxvt_selection_request_other: pasting %s", debug_xa_names[selnum])); XConvertSelection (display->display, sel, target, xa[XA_VT_SELECTION], TermWin.vt, selection_request_time); return 1; @@ -2789,8 +2758,6 @@ void rxvt_term::selection_clear () { - D_SELECT ((stderr, "rxvt_selection_clear ()")); - want_refresh = 1; free (selection.text); selection.text = NULL; @@ -2813,7 +2780,6 @@ wchar_t *new_selection_text; text_t *t; - D_SELECT ((stderr, "rxvt_selection_make (): selection.op=%d, selection.clicks=%d", selection.op, selection.clicks)); switch (selection.op) { case SELECTION_CONT: @@ -2845,7 +2811,7 @@ for (; row <= end_row; row++, col = 0) { - t = &(screen.text[row][col]); + t = &screen.text[row][col]; end_col = screen.tlen[row]; @@ -2881,11 +2847,11 @@ } if (screen.tlen[row] != -1 && row != end_row) - new_selection_text[ofs++] = L'\n'; + new_selection_text[ofs++] = C0_LF; } if (end_col != selection.end.col) - new_selection_text[ofs++] = L'\n'; + new_selection_text[ofs++] = C0_LF; new_selection_text[ofs] = 0; @@ -2919,7 +2885,6 @@ #endif selection_time = tm; - D_SELECT ((stderr, "rxvt_selection_make (): selection.len=%d", selection.len)); } /* ------------------------------------------------------------------------- */ @@ -2930,8 +2895,6 @@ void rxvt_term::selection_click (int clicks, int x, int y) { - D_SELECT ((stderr, "rxvt_selection_click (%d, %d, %d)", clicks, x, y)); - clicks = ((clicks - 1) % 3) + 1; selection.clicks = clicks; /* save clicks so extend will work */ @@ -2983,7 +2946,7 @@ /* what do we want: spaces/tabs are delimiters or cutchars or non-cutchars */ #define DELIMIT_TEXT(x) \ - (unicode::is_space (x) ? 2 : (x) <= 0xff && !!STRCHR (rs[Rs_cutchars], (x))) + (unicode::is_space (x) ? 2 : (x) <= 0xff && !!strchr (rs[Rs_cutchars], (x))) #define DELIMIT_REND(x) 1 void @@ -3011,10 +2974,10 @@ col = mark->col; MAX_IT (col, 0); /* find the edge of a word */ - stp = & (screen.text[row][col]); + stp = &screen.text[row][col]; w1 = DELIMIT_TEXT (*stp); - srp = (&screen.rend[row][col]); + srp = &screen.rend[row][col]; w2 = DELIMIT_REND (*srp); for (;;) @@ -3058,8 +3021,6 @@ } Old_Word_Selection_You_Die: - D_SELECT ((stderr, "rxvt_selection_delimit_word (%s,...) @ (r:%3d, c:%3d) has boundary (r:%3d, c:%3d)", (dirn == UP ? "up " : "down"), mark->row, mark->col, row - TermWin.saveLines, col)); - if (dirn == DN) col++; /* put us on one past the end */ @@ -3103,7 +3064,6 @@ selection.beg.col = selection.end.col = 0; selection.clicks = 4; want_refresh = 1; - D_SELECT ((stderr, "rxvt_selection_extend () selection.clicks = 4")); return; } @@ -3122,16 +3082,13 @@ void rxvt_term::selection_extend_colrow (int32_t col, int32_t row, int button3, int buttonpress, int clickchange) { - int16_t ncol = TermWin.ncol; - int end_col; - row_col_t pos; + int16_t ncol = TermWin.ncol; + int end_col; + row_col_t pos; enum { LEFT, RIGHT } closeto = RIGHT; - D_SELECT ((stderr, "rxvt_selection_extend_colrow (c:%d, r:%d, %d, %d) clicks:%d, op:%d", col, row, button3, buttonpress, selection.clicks, selection.op)); - D_SELECT ((stderr, "rxvt_selection_extend_colrow () ENT b: (r:%d,c:%d) m: (r:%d,c:%d), e: (r:%d,c:%d)", selection.beg.row, selection.beg.col, selection.mark.row, selection.mark.col, selection.end.row, selection.end.col)); - want_refresh = 1; switch (selection.op) { @@ -3162,7 +3119,6 @@ { selection.beg.col = selection.end.col = selection.mark.col; selection.beg.row = selection.end.row = selection.mark.row; - D_SELECT ((stderr, "rxvt_selection_extend_colrow () ENT2 b: (r:%d,c:%d) m: (r:%d,c:%d), e: (r:%d,c:%d)", selection.beg.row, selection.beg.col, selection.mark.row, selection.mark.col, selection.end.row, selection.end.col)); } pos.col = col; @@ -3265,8 +3221,8 @@ } else if (selection.clicks == 3) { -#ifndef NO_FRILLS - if ((Options & Opt_tripleclickwords)) +#if ENABLE_FRILLS + if ((options & Opt_tripleclickwords)) { int end_row; @@ -3301,8 +3257,7 @@ if (closeto == LEFT) { selection.mark.row = selection.end.row; - selection.mark.col = selection.end.col - - (selection.clicks == 2); + selection.mark.col = selection.end.col - (selection.clicks == 2); } else { @@ -3310,10 +3265,9 @@ selection.mark.col = selection.beg.col; } } - D_SELECT ((stderr, "rxvt_selection_extend_colrow () EXIT b: (r:%d,c:%d) m: (r:%d,c:%d), e: (r:%d,c:%d)", selection.beg.row, selection.beg.col, selection.mark.row, selection.mark.col, selection.end.row, selection.end.col)); } -#ifndef NO_FRILLS +#if ENABLE_FRILLS void rxvt_term::selection_remove_trailing_spaces () { @@ -3412,10 +3366,12 @@ target - target_list); ev.property = rq.property; } +#if TODO // TODO else if (rq.target == xa[XA_MULTIPLE]) { /* TODO: Handle MULTIPLE */ } +#endif else if (rq.target == xa[XA_TIMESTAMP] && selection.text) { XChangeProperty (display->display, rq.requestor, rq.property, XA_INTEGER, @@ -3506,61 +3462,137 @@ /* ------------------------------------------------------------------------- */ #ifdef USE_XIM void -rxvt_term::im_set_position (XPoint *pos) +rxvt_term::im_set_position (XPoint &pos) { XWindowAttributes xwa; XGetWindowAttributes (display->display, TermWin.vt, &xwa); - pos->x = Col2Pixel (screen.cur.col) + xwa.x; - pos->y = Height2Pixel ((screen.cur.row + 1)) + xwa.y - TermWin.lineSpace; -} + pos.x = xwa.x + Col2Pixel (screen.cur.col); + pos.y = xwa.y + Height2Pixel (screen.cur.row) + TermWin.fbase; +} #endif -/* ------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------- * - * DEBUG ROUTINES * - * ------------------------------------------------------------------------- */ -#if 0 + +#if ENABLE_OVERLAY void -rxvt_debug_colors (void) +rxvt_term::scr_overlay_new (int x, int y, int w, int h) { - int color; - const char *name[] = + if (TermWin.nrow < 3 || TermWin.ncol < 3) + return; + + want_refresh = 1; + + scr_overlay_off (); + + if (x < 0) x = TermWin.ncol - w; + if (y < 0) y = TermWin.nrow - h; + + // make space for border + w += 2; MIN_IT (w, TermWin.ncol); + h += 2; MIN_IT (h, TermWin.nrow); + + x -= 1; MAX_IT (x, 0); + y -= 1; MAX_IT (y, 0); + + MIN_IT (x, TermWin.ncol - w); + MIN_IT (y, TermWin.nrow - h); + + ov_x = x; ov_y = y; + ov_w = w; ov_h = h; + + ov_text = new text_t *[h]; + ov_rend = new rend_t *[h]; + + for (y = 0; y < h; y++) { - "fg", "bg", - "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white" - }; + text_t *tp = ov_text[y] = new text_t[w]; + rend_t *rp = ov_rend[y] = new rend_t[w]; + + text_t t0, t1, t2; + rend_t r = SET_BGCOLOR (SET_FGCOLOR (RS_None, Color_bg), Color_fg); + + if (y == 0) + t0 = 0x2554, t1 = 0x2550, t2 = 0x2557; + else if (y < h - 1) + t0 = 0x2551, t1 = 0x0020, t2 = 0x2551; + else + t0 = 0x255a, t1 = 0x2550, t2 = 0x255d; + + *tp++ = t0; + *rp++ = r; + + for (x = w - 2; x > 0; --x) + { + *tp++ = t1; + *rp++ = r; + } + + *tp = t2; + *rp = r; + } +} + +void +rxvt_term::scr_overlay_off () +{ + if (!ov_text) + return; - fprintf (stderr, "Color ( "); - if (rstyle & RS_RVid) - fprintf (stderr, "rvid "); - if (rstyle & RS_Bold) - fprintf (stderr, "bold "); - if (rstyle & RS_Blink) - fprintf (stderr, "blink "); - if (rstyle & RS_Uline) - fprintf (stderr, "uline "); - fprintf (stderr, "): "); + want_refresh = 1; - color = GET_FGCOLOR (rstyle); -#ifndef NO_BRIGHTCOLOR - if (color >= minBrightCOLOR && color <= maxBrightCOLOR) + for (int y = 0; y < ov_h; y++) { - color -= (minBrightCOLOR - minCOLOR); - fprintf (stderr, "bright "); + delete [] ov_text[y]; + delete [] ov_rend[y]; } -#endif - fprintf (stderr, "%s on ", name[color]); - color = GET_BGCOLOR (rstyle); -#ifndef NO_BRIGHTCOLOR - if (color >= minBrightCOLOR && color <= maxBrightCOLOR) + delete [] ov_text; ov_text = 0; + delete [] ov_rend; ov_rend = 0; +} + +void +rxvt_term::scr_overlay_set (int x, int y, text_t text, rend_t rend) +{ + if (!ov_text || x >= ov_w - 2 || y >= ov_h) + return; + + x++, y++; + + ov_text[y][x] = text; + ov_rend[y][x] = rend; +} + +void +rxvt_term::scr_overlay_set (int x, int y, const char *s) +{ + while (*s) + scr_overlay_set (x++, y, *s++); +} + +void +rxvt_term::scr_swap_overlay () +{ + if (!ov_text) + return; + + int row_offset = ov_y + TermWin.saveLines - TermWin.view_start; + + // swap screen mem with overlay + for (int y = ov_h; y--; ) { - color -= (minBrightCOLOR - minCOLOR); - fprintf (stderr, "bright "); + text_t *t1 = ov_text[y]; + rend_t *r1 = ov_rend[y]; + + text_t *t2 = screen.text[y + row_offset] + ov_x; + rend_t *r2 = screen.rend[y + row_offset] + ov_x; + + for (int x = ov_w; x--; ) + { + text_t t = *t1; *t1++ = *t2; *t2++ = t; + rend_t r = *r1; *r1++ = *r2; *r2++ = SET_FONT (r, TermWin.fontset->find_font (t, false)); + } } -#endif - fprintf (stderr, "%s\n", name[color]); } + #endif +/* ------------------------------------------------------------------------- */