--- rxvt-unicode/src/screen.C 2004/08/25 03:52:09 1.129 +++ rxvt-unicode/src/screen.C 2004/12/12 15:13:37 1.147 @@ -568,28 +568,32 @@ selection_check (2); /* check for boundary cross */ SWAP_IT (current_screen, scrn, int); + + SWAP_IT (screen.cur.row, swap.cur.row, int16_t); + SWAP_IT (screen.cur.col, swap.cur.col, int16_t); +# ifdef DEBUG_STRICT + assert (screen.cur.row >= 0 && screen.cur.row < prev_nrow); + assert (screen.cur.col >= 0 && screen.cur.col < prev_ncol); +# else /* drive with your eyes closed */ + 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); +# endif + #if NSCREENS if (options & Opt_secondaryScreen) { num_scr = 0; offset = TermWin.saveLines; + for (i = prev_nrow; i--;) { SWAP_IT (screen.text[i + offset], swap.text[i], text_t *); SWAP_IT (screen.tlen[i + offset], swap.tlen[i], int16_t); SWAP_IT (screen.rend[i + offset], swap.rend[i], rend_t *); } - SWAP_IT (screen.cur.row, swap.cur.row, int16_t); - SWAP_IT (screen.cur.col, swap.cur.col, int16_t); -# ifdef DEBUG_STRICT - assert ((screen.cur.row >= 0) && (screen.cur.row < prev_nrow)); - assert ((screen.cur.col >= 0) && (screen.cur.col < prev_ncol)); -# else /* drive with your eyes closed */ - 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); -# endif + SWAP_IT (screen.charset, swap.charset, int16_t); SWAP_IT (screen.flags, swap.flags, int); screen.flags |= Screen_VisibleCursor; @@ -599,7 +603,8 @@ #endif if (options & Opt_secondaryScroll) //if (current_screen == PRIMARY) - scr_scroll_text (0, (prev_nrow - 1), prev_nrow, 0); + scr_scroll_text (0, prev_nrow - 1, prev_nrow, 0); + return scrn; } @@ -880,9 +885,6 @@ srp = screen.rend[row]; /* _must_ refresh */ } - if (screen.flags & Screen_Insert) - scr_insdel_chars (1, INSERT); - // 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. @@ -893,7 +895,7 @@ // vt100 special graphics and line drawing // 5f-7e standard vt100 // 40-5e rxvt extension for extra curses acs chars - static uint16_t vt100_0[63] = { // 5f .. 7e + static uint16_t vt100_0[63] = { // 40 .. 7e 0x0000, 0x2191, 0x2193, 0x2192, 0x2190, 0x2588, 0x259a, 0x2603, // 40-47 hi mr. snowman! 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 48-4f 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 50-57 @@ -911,6 +913,9 @@ } } + if (screen.flags & Screen_Insert) + scr_insdel_chars (width, INSERT); + if (width != 0) { // some utf-8 decoders decode surrogate characters. @@ -970,11 +975,12 @@ while (--width > 0); // pad with spaces when overwriting wide character with smaller one - for (int c = screen.cur.col; c < last_col && stp[c] == NOCHAR; c++) - { - stp[c] = ' '; - srp[c] = rend; - } + if (!width) + for (int c = screen.cur.col; c < last_col && stp[c] == NOCHAR; c++) + { + stp[c] = ' '; + srp[c] = rend; + } } else if (width == 0) { @@ -991,25 +997,24 @@ { tp = stp + screen.cur.col - 1; rp = srp + screen.cur.col - 1; + + while (*tp == NOCHAR && tp > stp) + tp--, rp--; } else if (screen.cur.row > 0 && screen.tlen [screen.cur.row - 1 + TermWin.saveLines] == -1) { - tp = screen.text[screen.cur.row - 1 + TermWin.saveLines] + last_col - 1; - rp = screen.rend[screen.cur.row - 1 + TermWin.saveLines] + last_col - 1; + int line = screen.cur.row - 1 + TermWin.saveLines; + + tp = screen.text[line] + last_col - 1; + rp = screen.rend[line] + last_col - 1; + + while (*tp == NOCHAR && tp > screen.text[line]) + tp--, rp--; } else continue; - // handle double-width-chars by making them look extremely ugly - if (*tp == NOCHAR) - { - // hack //D //TODO //--tp, --rp; - *tp = ' '; - *rp &= ~RS_baseattrMask; - *rp = SET_FONT (*rp, FONTSET (*rp)->find_font (*tp)); - } - // first try to find a precomposed character unicode_t n = rxvt_compose (*tp, c); if (n == NOCHAR) @@ -1098,7 +1103,7 @@ // store horizontal tab commands as characters inside the text // buffer so they can be selected and pasted. - if (ht) + if (ht && options & Opt_pastableTabs) { base_rend = SET_FONT (base_rend, 0); @@ -1381,7 +1386,7 @@ } else { - ren = (rstyle & (RS_fgMask | RS_bgMask)); + ren = rstyle & (RS_fgMask | RS_bgMask); gcvalue.foreground = pix_colors[GET_BGCOLOR (rstyle)]; XChangeGC (display->display, TermWin.gc, GCForeground, &gcvalue); ERASE_ROWS (row, num); @@ -1391,11 +1396,9 @@ for (; num--; row++) { - scr_blank_screen_mem (screen.text, screen.rend, - (unsigned int) (row + row_offset), rstyle); + scr_blank_screen_mem (screen.text, screen.rend, (unsigned int) (row + row_offset), rstyle); screen.tlen[row + row_offset] = 0; - scr_blank_line (drawn_text[row], drawn_rend[row], - (unsigned int)TermWin.ncol, ren); + scr_blank_line (drawn_text[row], drawn_rend[row], (unsigned int)TermWin.ncol, ren); } } @@ -1489,8 +1492,7 @@ switch (insdel) { case INSERT: - for (col = TermWin.ncol - 1; (col - count) >= screen.cur.col; - col--) + for (col = TermWin.ncol - 1; (col - count) >= screen.cur.col; col--) { stp[col] = stp[col - count]; srp[col] = srp[col - count]; @@ -1510,13 +1512,13 @@ CLEAR_SELECTION (); else { /* shift selection */ - selection.beg.col += count; + selection.beg.col += count; selection.mark.col += count; /* XXX: yes? */ - selection.end.col += count; + selection.end.col += count; } } - scr_blank_line (& (stp[screen.cur.col]), & (srp[screen.cur.col]), + scr_blank_line (&stp[screen.cur.col], &srp[screen.cur.col], (unsigned int)count, rstyle); break; @@ -1524,7 +1526,7 @@ screen.cur.col += count; /* don't worry if > TermWin.ncol */ selection_check (1); screen.cur.col -= count; - scr_blank_line (& (stp[screen.cur.col]), & (srp[screen.cur.col]), + scr_blank_line (&stp[screen.cur.col], &srp[screen.cur.col], (unsigned int)count, rstyle); break; @@ -1537,8 +1539,7 @@ srp[col] = srp[col + count]; } - scr_blank_line (& (stp[TermWin.ncol - count]), - & (srp[TermWin.ncol - count]), + scr_blank_line (&stp[TermWin.ncol - count], &srp[TermWin.ncol - count], (unsigned int)count, tr); if (*slp == -1) /* break line continuation */ @@ -1557,9 +1558,9 @@ else { /* shift selection */ - selection.beg.col -= count; + selection.beg.col -= count; selection.mark.col -= count; /* XXX: yes? */ - selection.end.col -= count; + selection.end.col -= count; } } @@ -1753,10 +1754,10 @@ */ void rxvt_term::scr_charset_choose (int set) - { - screen.charset = set; - set_font_style (); - } +{ + screen.charset = set; + set_font_style (); +} /* ------------------------------------------------------------------------- */ /* @@ -1769,10 +1770,10 @@ */ void rxvt_term::scr_charset_set (int set, unsigned int ch) - { - charsets[set] = (unsigned char)ch; - set_font_style (); - } +{ + charsets[set] = (unsigned char)ch; + set_font_style (); +} /* ------------------------------------------------------------------------- * @@ -2038,6 +2039,8 @@ #endif rend_t *crp; // cursor rendition pointer + want_refresh = 0; /* screen is current */ + if (refresh_type == NO_REFRESH || !TermWin.mapped) return; @@ -2244,7 +2247,7 @@ // redraw one or more characters - // seek to the beginning if wide characters + // seek to the beginning of wide characters while (stp[col] == NOCHAR && col > 0) --col; @@ -2398,9 +2401,12 @@ font->draw (*TermWin.drawable, xpixel, ypixel, text, count, fore, back); 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); + { + XSetForeground (display->display, TermWin.gc, pix_colors[fore]); + XDrawLine (display->display, drawBuffer, TermWin.gc, + xpixel, ypixel + font->ascent + 1, + xpixel + Width2Pixel (count) - 1, ypixel + font->ascent + 1); + } } /* for (col....) */ } /* for (row....) */ @@ -2449,7 +2455,6 @@ num_scr = 0; num_scr_allow = 1; - want_refresh = 0; /* screen is current */ } void @@ -2546,22 +2551,36 @@ int col, row = selection.end.row + TermWin.saveLines; rend_t *srp; - if (i >= end_row) - col = selection.beg.col; - else +#if ENABLE_FRILLS + if (selection.rect) { - col = 0; - i = end_row; + end_row += TermWin.nrow; + + for (; i <= row && i <= end_row; i++) + for (srp = screen.rend[i], col = selection.beg.col; col < selection.end.col; col++) + srp[col] ^= RS_RVid; } + else +#endif + { + if (i >= end_row) + col = selection.beg.col; + else + { + 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; + 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; + } } } @@ -2741,6 +2760,23 @@ char **cl; int cr; + +#if ENABLE_FRILLS + // xlib is horribly broken with respect to UTF8_STRING, and nobody cares to fix it + // so recode it manually + if (ct.encoding == xa[XA_UTF8_STRING]) + { + wchar_t *w = rxvt_utf8towcs ((const char *)ct.value, ct.nitems); + char *s = rxvt_wcstombs (w); + + // TODO: strlen == only the first element will be converted. well... + paste ((unsigned char *)s, strlen (s)); + + free (s); + free (w); + } + else +#endif if (XmbTextPropertyToTextList (display->display, &ct, &cl, &cr) >= 0 && cl) { for (int i = 0; i < cr; i++) @@ -2833,7 +2869,6 @@ if (selection_request_other (xa[XA_COMPOUND_TEXT], i)) return; #endif - } } @@ -2921,7 +2956,6 @@ new_selection_text = (wchar_t *)rxvt_malloc ((i + 4) * sizeof (wchar_t)); col = selection.beg.col; - MAX_IT (col, 0); row = selection.beg.row + TermWin.saveLines; end_row = selection.end.row + TermWin.saveLines; int ofs = 0; @@ -2929,16 +2963,25 @@ for (; row <= end_row; row++, col = 0) { - t = &screen.text[row][col]; - end_col = screen.tlen[row]; +#if ENABLE_FRILLS + if (selection.rect) + { + col = selection.beg.col; + end_col = TermWin.ncol + 1; + } +#endif + + MAX_IT (col, 0); + if (end_col == -1) end_col = TermWin.ncol; - if (row == end_row) + if (row == end_row || selection.rect) MIN_IT (end_col, selection.end.col); + t = &screen.text[row][col]; for (; col < end_col; col++) { if (*t == NOCHAR) @@ -2996,8 +3039,7 @@ if (XwcTextListToTextProperty (display->display, &selection.text, 1, XStringStyle, &ct) >= 0) { - XChangeProperty (display->display, display->root, XA_CUT_BUFFER0, XA_STRING, 8, - PropModeReplace, ct.value, ct.nitems); + set_string_property (XA_CUT_BUFFER0, ct.value, ct.nitems); XFree (ct.value); } #endif @@ -3208,6 +3250,7 @@ } closeto = RIGHT; want_refresh = 1; + switch (selection.op) { case SELECTION_INIT: @@ -3230,6 +3273,7 @@ default: return; } + if (selection.beg.col == selection.end.col && selection.beg.col != selection.mark.col && selection.beg.row == selection.end.row @@ -3289,9 +3333,10 @@ { /* button1 drag or button3 drag */ if (ROWCOL_IS_AFTER (selection.mark, pos)) { - if ((selection.mark.row == selection.end.row) - && (selection.mark.col == selection.end.col) - && clickchange && selection.clicks == 2) + if (selection.mark.row == selection.end.row + && selection.mark.col == selection.end.col + && clickchange + && selection.clicks == 2) selection.mark.col--; selection.beg.row = pos.row; @@ -3312,21 +3357,23 @@ { end_col = screen.tlen[selection.beg.row + TermWin.saveLines]; - if (end_col != -1 && selection.beg.col > end_col) - { -#if 1 - selection.beg.col = ncol; -#else - if (selection.beg.row != selection.end.row) - selection.beg.col = ncol; - else - selection.beg.col = selection.mark.col; + if (selection.beg.col > end_col + && end_col != -1 +#if ENABLE_FRILLS + && !selection.rect #endif - } + ) + selection.beg.col = ncol; end_col = screen.tlen[selection.end.row + TermWin.saveLines]; - if (end_col != -1 && selection.end.col > end_col) + if ( + selection.end.col > end_col + && end_col != -1 +#if ENABLE_FRILLS + && !selection.rect +#endif + ) selection.end.col = ncol; } else if (selection.clicks == 2) @@ -3334,8 +3381,8 @@ if (ROWCOL_IS_AFTER (selection.end, selection.beg)) selection.end.col--; - 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) { @@ -3344,7 +3391,7 @@ { int end_row; - selection_delimit_word (UP, & (selection.beg), & (selection.beg)); + selection_delimit_word (UP, &selection.beg, &selection.beg); end_row = screen.tlen[selection.mark.row + TermWin.saveLines]; for (end_row = selection.mark.row; end_row < TermWin.nrow; end_row++) @@ -3365,6 +3412,7 @@ { if (ROWCOL_IS_AFTER (selection.mark, selection.beg)) selection.mark.col++; + selection.beg.col = 0; selection.end.col = ncol; } @@ -3383,25 +3431,35 @@ selection.mark.col = selection.beg.col; } } + +#if ENABLE_FRILLS + if (selection.rect && selection.beg.col > selection.end.col) + SWAP_IT (selection.beg.col, selection.end.col, int); +#endif } #if ENABLE_FRILLS void rxvt_term::selection_remove_trailing_spaces () { - int32_t end_col, end_row; - text_t *stp; + int32_t end_col, end_row; + text_t *stp; end_col = selection.end.col; end_row = selection.end.row; + for ( ; end_row >= selection.beg.row; ) { stp = screen.text[end_row + TermWin.saveLines]; + while (--end_col >= 0) { - if (stp[end_col] != ' ' && stp[end_col] != '\t') + if (stp[end_col] != ' ' + && stp[end_col] != '\t' + && stp[end_col] != NOCHAR) break; } + if (end_col >= 0 || screen.tlen[end_row - 1 + TermWin.saveLines] != -1) { @@ -3409,9 +3467,11 @@ selection.end.row = end_row; break; } + end_row--; end_col = TermWin.ncol; } + if (selection.mark.row > selection.end.row) { selection.mark.row = selection.end.row; @@ -3437,14 +3497,6 @@ /* ------------------------------------------------------------------------- */ /* - * On some systems, the Atom typedef is 64 bits wide. We need to have a type - * that is exactly 32 bits wide, because a format of 64 is not allowed by - * the X11 protocol. - */ -typedef CARD32 Atom32; - -/* ------------------------------------------------------------------------- */ -/* * Respond to a request for our current selection * EXT: SelectionRequest */ @@ -3452,9 +3504,6 @@ rxvt_term::selection_send (const XSelectionRequestEvent &rq) { XSelectionEvent ev; - XTextProperty ct; - XICCEncodingStyle style; - Atom target; ev.type = SelectionNotify; ev.property = None; @@ -3466,22 +3515,21 @@ if (rq.target == xa[XA_TARGETS]) { - Atom32 target_list[6]; - Atom32 *target = target_list; + Atom target_list[6]; + Atom *target = target_list; - *target++ = (Atom32) xa[XA_TARGETS]; - *target++ = (Atom32) xa[XA_TIMESTAMP]; - *target++ = (Atom32) XA_STRING; - *target++ = (Atom32) xa[XA_TEXT]; - *target++ = (Atom32) xa[XA_COMPOUND_TEXT]; + *target++ = xa[XA_TARGETS]; + *target++ = xa[XA_TIMESTAMP]; + *target++ = XA_STRING; + *target++ = xa[XA_TEXT]; + *target++ = xa[XA_COMPOUND_TEXT]; #if X_HAVE_UTF8_STRING - *target++ = (Atom32) xa[XA_UTF8_STRING]; + *target++ = xa[XA_UTF8_STRING]; #endif XChangeProperty (display->display, rq.requestor, rq.property, XA_ATOM, - (8 * sizeof (target_list[0])), PropModeReplace, - (unsigned char *)target_list, - target - target_list); + 32, PropModeReplace, + (unsigned char *)target_list, target - target_list); ev.property = rq.property; } #if TODO // TODO @@ -3492,9 +3540,8 @@ #endif else if (rq.target == xa[XA_TIMESTAMP] && selection.text) { - XChangeProperty (display->display, rq.requestor, rq.property, XA_INTEGER, - (8 * sizeof (Time)), PropModeReplace, - (unsigned char *)&selection_time, 1); + XChangeProperty (display->display, rq.requestor, rq.property, rq.target, + 32, PropModeReplace, (unsigned char *)&selection_time, 1); ev.property = rq.property; } else if (rq.target == XA_STRING @@ -3503,28 +3550,38 @@ || rq.target == xa[XA_UTF8_STRING] ) { + XTextProperty ct; + Atom target = rq.target; short freect = 0; int selectlen; wchar_t *cl; - - target = rq.target; + enum { + enc_string = XStringStyle, + enc_text = XStdICCTextStyle, + enc_compound_text = XCompoundTextStyle, +#ifdef X_HAVE_UTF8_STRING + enc_utf8 = XUTF8StringStyle, +#else + enc_utf8 = -1, +#endif + } style; if (target == XA_STRING) // we actually don't do XA_STRING, but who cares, as i18n clients // will ask for another format anyways. - style = XStringStyle; + style = enc_string; else if (target == xa[XA_TEXT]) - style = XStdICCTextStyle; + style = enc_text; else if (target == xa[XA_COMPOUND_TEXT]) - style = XCompoundTextStyle; -#if X_HAVE_UTF8_STRING + style = enc_compound_text; +#if ENABLE_FRILLS else if (target == xa[XA_UTF8_STRING]) - style = XUTF8StringStyle; + style = enc_utf8; #endif else { target = xa[XA_COMPOUND_TEXT]; - style = XCompoundTextStyle; + style = enc_compound_text; } if (selection.text) @@ -3538,19 +3595,31 @@ selectlen = 0; } - // Xwc doesn't handle iso-10646 in wchar_t gracefully, so maybe recode it - // manually for XUTF8StringStyle. - if (XwcTextListToTextProperty (display->display, &cl, 1, style, &ct) >= 0) +#if ENABLE_FRILLS + // xlib is horribly broken with respect to UTF8_STRING, and nobody cares to fix it + // so recode it manually + if (style == enc_utf8) + { + freect = 1; + ct.encoding = target; + ct.format = 8; + ct.value = (unsigned char *)rxvt_wcstoutf8 (cl, selectlen); + ct.nitems = strlen ((char *)ct.value); + } + else +#endif + if (XwcTextListToTextProperty (display->display, &cl, 1, (XICCEncodingStyle) style, &ct) >= 0) freect = 1; else { /* if we failed to convert then send it raw */ ct.value = (unsigned char *)cl; ct.nitems = selectlen; + ct.encoding = target; } XChangeProperty (display->display, rq.requestor, rq.property, - target, 8, PropModeReplace, + ct.encoding, 8, PropModeReplace, ct.value, (int)ct.nitems); ev.property = rq.property;