ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/screen.C
(Generate patch)

Comparing rxvt-unicode/src/screen.C (file contents):
Revision 1.11 by pcg, Thu Dec 18 13:33:03 2003 UTC vs.
Revision 1.20 by pcg, Fri Jan 30 15:58:07 2004 UTC

1/*--------------------------------*-C-*--------------------------------------* 1/*--------------------------------*-C-*--------------------------------------*
2 * File: screen.c 2 * File: screen.c
3 *---------------------------------------------------------------------------* 3 *---------------------------------------------------------------------------*
4 * $Id: screen.C,v 1.11 2003/12/18 13:33:03 pcg Exp $
5 * 4 *
6 * Copyright (c) 1997-2001 Geoff Wing <gcw@pobox.com> 5 * Copyright (c) 1997-2001 Geoff Wing <gcw@pobox.com>
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
289 else if (nrow > prev_nrow) 288 else if (nrow > prev_nrow)
290 { 289 {
291 /* add rows */ 290 /* add rows */
292 scr_reset_realloc (); /* realloc _first_ */ 291 scr_reset_realloc (); /* realloc _first_ */
293 292
294 TermWin.ncol = prev_ncol; // save b/c scr_blank_screen_mem uses this 293 TermWin.ncol = prev_ncol; // save b/c scr_blank_screen_mem uses this
295 294
296 k = min (TermWin.nscrolled, nrow - prev_nrow); 295 k = min (TermWin.nscrolled, nrow - prev_nrow);
297 296
298 for (p = prev_total_rows; p < total_rows; p++) 297 for (p = prev_total_rows; p < total_rows; p++)
299 { 298 {
447 /* then so is screen.rend[i] */ 446 /* then so is screen.rend[i] */
448 assert(screen.rend[i]); 447 assert(screen.rend[i]);
449 } 448 }
450#endif 449#endif
451 450
452 delete talloc; 451 delete talloc; talloc = 0;
453 delete ralloc; 452 delete ralloc; ralloc = 0;
454 453
455 free (screen.text); 454 free (screen.text);
456 free (screen.tlen); 455 free (screen.tlen);
457 free (screen.rend); 456 free (screen.rend);
458 free (drawn_text); 457 free (drawn_text);
899 case 'z': c = 0x2265; break; case '{': c = 0x03c0; break; case '|': c = 0x2260; break; 898 case 'z': c = 0x2265; break; case '{': c = 0x03c0; break; case '|': c = 0x2260; break;
900 case '}': c = 0x00a3; break; case '~': c = 0x00b7; break; 899 case '}': c = 0x00a3; break; case '~': c = 0x00b7; break;
901 } 900 }
902 901
903 rend_t rend = SET_FONT (R->rstyle, R->TermWin.fontset->find_font (c)); 902 rend_t rend = SET_FONT (R->rstyle, R->TermWin.fontset->find_font (c));
904
905 stp[R->screen.cur.col] = c;
906 srp[R->screen.cur.col] = rend;
907
908 if (c > 255)
909 {
910 // rely on wcwidth to tell us the character width, at least for non iso-8859-1 903 // rely on wcwidth to tell us the character width, at least for non-ascii
911 int width = wcwidth (c); 904 int width = c <= 128 ? 1 : wcwidth (c);
905
906 // width -1 characters (e.g. combining chars) are ignored currently.
907 if (width > 0)
908 do
912 909 {
913 if (width > 1) 910 stp[R->screen.cur.col] = c;
914 {
915 while (--width > 0 && R->screen.cur.col < last_col - 1)
916 {
917
918 srp[R->screen.cur.col] |= RS_wide; 911 srp[R->screen.cur.col] = rend;
919 912
913 if (R->screen.cur.col < last_col - 1)
920 R->screen.cur.col++; 914 R->screen.cur.col++;
921 stp[R->screen.cur.col] = NOCHAR; 915 else
922 srp[R->screen.cur.col] = rend;
923 } 916 {
924 }
925 }
926
927 if (R->screen.cur.col < last_col - 1)
928 R->screen.cur.col++;
929 else {
930 R->screen.tlen[row] = last_col; 917 R->screen.tlen[row] = last_col;
931 if (R->screen.flags & Screen_Autowrap) 918 if (R->screen.flags & Screen_Autowrap)
932 R->screen.flags |= Screen_WrapNext; 919 R->screen.flags |= Screen_WrapNext;
920 break;
921 }
922
923 c = NOCHAR;
933 } 924 }
925 while (--width > 0);
926 else
927 1; /* handle combining character etc. here. */
934 } 928 }
929
935 if (R->screen.tlen[row] != -1) /* XXX: think about this */ 930 if (R->screen.tlen[row] != -1) /* XXX: think about this */
936 MAX_IT(R->screen.tlen[row], R->screen.cur.col); 931 MAX_IT(R->screen.tlen[row], R->screen.cur.col);
937 932
938/* 933/*
939 * If we wrote anywhere in the selected area, kill the selection 934 * If we wrote anywhere in the selected area, kill the selection
940 * XXX: should we kill the mark too? Possibly, but maybe that 935 * XXX: should we kill the mark too? Possibly, but maybe that
941 * should be a similar check. 936 * should be a similar check.
1650 rxvt_set_font_style(aR); 1645 rxvt_set_font_style(aR);
1651} 1646}
1652 1647
1653 1648
1654/* ------------------------------------------------------------------------- * 1649/* ------------------------------------------------------------------------- *
1655 * GRAPHICS COLOURS *
1656 * ------------------------------------------------------------------------- */
1657
1658#ifdef RXVT_GRAPHICS
1659/* EXTPROTO */
1660int
1661rxvt_scr_get_fgcolor(pR)
1662{
1663 return GET_FGCOLOR(R->rstyle);
1664}
1665
1666/* ------------------------------------------------------------------------- */
1667/* EXTPROTO */
1668int
1669rxvt_scr_get_bgcolor(pR)
1670{
1671 return GET_BGCOLOR(R->rstyle);
1672}
1673#endif
1674
1675/* ------------------------------------------------------------------------- *
1676 * MAJOR SCREEN MANIPULATION * 1650 * MAJOR SCREEN MANIPULATION *
1677 * ------------------------------------------------------------------------- */ 1651 * ------------------------------------------------------------------------- */
1652
1653/*
1654 * refresh matching text.
1655 */
1656bool
1657rxvt_term::scr_refresh_rend (rend_t mask, rend_t value)
1658{
1659 bool found = false;
1660
1661 for (int i = 0; i < TermWin.nrow; i++)
1662 {
1663 int col = 0;
1664 rend_t *drp = drawn_rend [i];
1665
1666 for (; col < TermWin.ncol; col++, drp++)
1667 if ((*drp & mask) == value)
1668 {
1669 found = true;
1670 *drp = ~value;
1671 }
1672 }
1673
1674 return found;
1675}
1678 1676
1679/* 1677/*
1680 * Refresh an area 1678 * Refresh an area
1681 */ 1679 */
1682enum { 1680enum {
1859 * Refresh the screen 1857 * Refresh the screen
1860 * R->drawn_text/R->drawn_rend contain the screen information before the update. 1858 * R->drawn_text/R->drawn_rend contain the screen information before the update.
1861 * R->screen.text/R->screen.rend contain what the screen will change to. 1859 * R->screen.text/R->screen.rend contain what the screen will change to.
1862 */ 1860 */
1863 1861
1864#if defined (NO_BRIGHTCOLOR) || defined (VERYBOLD)
1865# define MONO_BOLD(x) ((x) & (RS_Bold|RS_Blink))
1866# define MONO_BOLD_FG(x, fg) MONO_BOLD(x)
1867#else
1868# define MONO_BOLD(x) \
1869 (((x) & (RS_Bold | RS_fgMask)) == (RS_Bold | Color_fg))
1870# define MONO_BOLD_FG(x, fg) (((x) & RS_Bold) && (fg) == Color_fg)
1871#endif
1872
1873#define FONT_WIDTH(X, Y) \ 1862#define FONT_WIDTH(X, Y) \
1874 (X)->per_char[(Y) - (X)->min_char_or_byte2].width 1863 (X)->per_char[(Y) - (X)->min_char_or_byte2].width
1875#define FONT_RBEAR(X, Y) \ 1864#define FONT_RBEAR(X, Y) \
1876 (X)->per_char[(Y) - (X)->min_char_or_byte2].rbearing 1865 (X)->per_char[(Y) - (X)->min_char_or_byte2].rbearing
1877#define FONT_LBEAR(X, Y) \ 1866#define FONT_LBEAR(X, Y) \
1883rxvt_term::scr_refresh (unsigned char refresh_type) 1872rxvt_term::scr_refresh (unsigned char refresh_type)
1884{ 1873{
1885 unsigned char clearfirst, /* first character writes before cell */ 1874 unsigned char clearfirst, /* first character writes before cell */
1886 clearlast, /* last character writes beyond cell */ 1875 clearlast, /* last character writes beyond cell */
1887 must_clear, /* use draw_string not draw_image_string */ 1876 must_clear, /* use draw_string not draw_image_string */
1888#ifndef NO_BOLDFONT
1889 bfont, /* we've changed font to bold font */
1890#endif
1891 rvid, /* reverse video this position */ 1877 rvid, /* reverse video this position */
1892 wbyte, /* we're in multibyte */
1893 showcursor; /* show the cursor */ 1878 showcursor; /* show the cursor */
1894 int fore, back; /* desired foreground/background */
1895 int16_t col, row, /* column/row we're processing */ 1879 int16_t col, row, /* column/row we're processing */
1896 ocrow; /* old cursor row */ 1880 ocrow; /* old cursor row */
1897 int cursorwidth; 1881 int cursorwidth;
1898 int i, /* tmp */ 1882 int i, /* tmp */
1899 row_offset; /* basic offset in screen structure */ 1883 row_offset; /* basic offset in screen structure */
1901 rend_t cc1; /* store colours at cursor position(s) */ 1885 rend_t cc1; /* store colours at cursor position(s) */
1902 rend_t cc2; /* store colours at cursor position(s) */ 1886 rend_t cc2; /* store colours at cursor position(s) */
1903#endif 1887#endif
1904 rend_t *drp, *srp; /* drawn-rend-pointer, screen-rend-pointer */ 1888 rend_t *drp, *srp; /* drawn-rend-pointer, screen-rend-pointer */
1905 text_t *dtp, *stp; /* drawn-text-pointer, screen-text-pointer */ 1889 text_t *dtp, *stp; /* drawn-text-pointer, screen-text-pointer */
1906 char *buffer; /* local copy of buffer */
1907 1890
1908 if (refresh_type == NO_REFRESH || !TermWin.mapped) 1891 if (refresh_type == NO_REFRESH || !TermWin.mapped)
1909 return; 1892 return;
1910 1893
1911 /* 1894 /*
1912 * A: set up vars 1895 * A: set up vars
1913 */ 1896 */
1914 clearfirst = clearlast = must_clear = wbyte = 0; 1897 clearfirst = clearlast = must_clear = 0;
1915#ifndef NO_BOLDFONT
1916 bfont = 0;
1917#endif
1918 1898
1919 if (currmaxcol < TermWin.ncol)
1920 {
1921 currmaxcol = TermWin.ncol;
1922 buffer = (char *)rxvt_realloc (buffer,
1923 sizeof(char) * (currmaxcol + 1) * MB_CUR_MAX);
1924 }
1925
1926 buffer = buffer;
1927 refresh_count = 0; 1899 refresh_count = 0;
1928 1900
1929 row_offset = TermWin.saveLines - TermWin.view_start; 1901 row_offset = TermWin.saveLines - TermWin.view_start;
1930 1902
1931 if ((refresh_type & REFRESH_BOUNDS)) 1903 if ((refresh_type & REFRESH_BOUNDS))
1940#if defined(TRANSPARENT) 1912#if defined(TRANSPARENT)
1941 must_clear |= ((Options & Opt_transparent) && am_transparent); 1913 must_clear |= ((Options & Opt_transparent) && am_transparent);
1942#endif 1914#endif
1943 ocrow = oldcursor.row; /* is there an old outline cursor on screen? */ 1915 ocrow = oldcursor.row; /* is there an old outline cursor on screen? */
1944 1916
1945/* 1917 /*
1946 * B: reverse any characters which are selected 1918 * B: reverse any characters which are selected
1947 */ 1919 */
1948 rxvt_scr_reverse_selection (this); 1920 rxvt_scr_reverse_selection (this);
1949 1921
1950/* 1922 /*
1951 * C: set the cursor character(s) 1923 * C: set the cursor character(s)
1952 */ 1924 */
1953 { 1925 {
1954 unsigned char setoldcursor; 1926 unsigned char setoldcursor;
1955 rend_t ccol1, /* Cursor colour */ 1927 rend_t ccol1, /* Cursor colour */
1956 ccol2; /* Cursor colour2 */ 1928 ccol2; /* Cursor colour2 */
1957 1929
1974 if (showcursor && TermWin.focus) 1946 if (showcursor && TermWin.focus)
1975 { 1947 {
1976 *srp ^= RS_RVid; 1948 *srp ^= RS_RVid;
1977#ifndef NO_CURSORCOLOR 1949#ifndef NO_CURSORCOLOR
1978 cc1 = *srp & (RS_fgMask | RS_bgMask); 1950 cc1 = *srp & (RS_fgMask | RS_bgMask);
1979 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_cursor)) 1951 if (ISSET_PIXCOLOR (this, Color_cursor))
1980 ccol1 = Color_cursor; 1952 ccol1 = Color_cursor;
1981 else 1953 else
1982#ifdef CURSOR_COLOR_IS_RENDITION_COLOR 1954#ifdef CURSOR_COLOR_IS_RENDITION_COLOR
1983 ccol1 = GET_FGCOLOR(rstyle); 1955 ccol1 = GET_FGCOLOR(rstyle);
1984#else 1956#else
1985 ccol1 = Color_fg; 1957 ccol1 = Color_fg;
1986#endif 1958#endif
1987 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_cursor2)) 1959 if (ISSET_PIXCOLOR (this, Color_cursor2))
1988 ccol2 = Color_cursor2; 1960 ccol2 = Color_cursor2;
1989 else 1961 else
1990#ifdef CURSOR_COLOR_IS_RENDITION_COLOR 1962#ifdef CURSOR_COLOR_IS_RENDITION_COLOR
1991 ccol2 = GET_BGCOLOR(rstyle); 1963 ccol2 = GET_BGCOLOR(rstyle);
1992#else 1964#else
1994#endif 1966#endif
1995 *srp = SET_FGCOLOR(*srp, ccol1); 1967 *srp = SET_FGCOLOR(*srp, ccol1);
1996 *srp = SET_BGCOLOR(*srp, ccol2); 1968 *srp = SET_BGCOLOR(*srp, ccol2);
1997#endif 1969#endif
1998 } 1970 }
1999
2000 while (IS_WIDE (*srp))
2001 cursorwidth++, srp++;
2002 } 1971 }
2003 1972
2004 /* make sure no outline cursor is left around */ 1973 /* make sure no outline cursor is left around */
2005 setoldcursor = 0; 1974 setoldcursor = 0;
2006 if (ocrow != -1) { 1975 if (ocrow != -1) {
2026 } 1995 }
2027 } 1996 }
2028 } 1997 }
2029 1998
2030#ifndef NO_SLOW_LINK_SUPPORT 1999#ifndef NO_SLOW_LINK_SUPPORT
2031/* 2000 /*
2032 * D: CopyArea pass - very useful for slower links 2001 * D: CopyArea pass - very useful for slower links
2033 * This has been deliberately kept simple. 2002 * This has been deliberately kept simple.
2034 */ 2003 */
2035 i = num_scr; 2004 i = num_scr;
2036 if (refresh_type == FAST_REFRESH && num_scr_allow && i 2005 if (refresh_type == FAST_REFRESH && num_scr_allow && i
2037 && abs(i) < TermWin.nrow && !must_clear) 2006 && abs(i) < TermWin.nrow && !must_clear)
2038 { 2007 {
2039 int16_t nits; 2008 int16_t nits;
2094 } 2063 }
2095 } 2064 }
2096 } 2065 }
2097#endif 2066#endif
2098 2067
2099/* 2068 /*
2100 * E: main pass across every character 2069 * E: main pass across every character
2101 */ 2070 */
2102 for (row = 0; row < TermWin.nrow; row++) 2071 for (row = 0; row < TermWin.nrow; row++)
2103 { 2072 {
2104 stp = screen.text[row + row_offset]; 2073 stp = screen.text[row + row_offset];
2105 srp = screen.rend[row + row_offset]; 2074 srp = screen.rend[row + row_offset];
2106 dtp = drawn_text[row]; 2075 dtp = drawn_text[row];
2107 drp = drawn_rend[row]; 2076 drp = drawn_rend[row];
2108 2077
2109/* 2078 /*
2110 * E2: OK, now the real pass 2079 * E2: OK, now the real pass
2111 */ 2080 */
2112 int ypixel = (int)Row2Pixel(row); 2081 int ypixel = (int)Row2Pixel(row);
2113 2082
2114 for (col = 0; col < TermWin.ncol; col++) 2083 for (col = 0; col < TermWin.ncol; col++)
2115 { 2084 {
2116 /* compare new text with old - if exactly the same then continue */ 2085 /* compare new text with old - if exactly the same then continue */
2149 i++; 2118 i++;
2150 2119
2151 continue; 2120 continue;
2152 } 2121 }
2153 2122
2154 if (((rend ^ srp[col]) & ~RS_wide) != 0) 2123 if (rend != srp[col])
2155 break; 2124 break;
2156 2125
2157 count++; 2126 count++;
2158 2127
2159 if (stp[col] != dtp[col] 2128 if (stp[col] != dtp[col]
2171 } 2140 }
2172 2141
2173 col--; /* went one too far. move back */ 2142 col--; /* went one too far. move back */
2174 count -= i; /* dump any matching trailing chars */ 2143 count -= i; /* dump any matching trailing chars */
2175 2144
2176/* 2145 /*
2177 * Determine the attributes for the string 2146 * Determine the attributes for the string
2178 */ 2147 */
2179 int fid = GET_FONT(rend); 2148 int fid = GET_FONT (rend);
2180 fore = GET_FGCOLOR(rend); 2149 int fore = GET_FGCOLOR (rend); // desired foreground
2181 back = GET_BGCOLOR(rend); 2150 int back = GET_BGCOLOR (rend); // desired background
2151
2182 rend = GET_ATTR(rend); 2152 rend = GET_ATTR (rend);
2183 2153
2184 rvid = (rend & RS_RVid) ? 1 : 0; 2154 rvid = !!(rend & RS_RVid);
2185#ifdef OPTION_HC 2155#ifdef TEXT_BLINK
2186 if (!rvid && (rend & RS_Blink)) 2156 if (rend & RS_Blink)
2187 { 2157 {
2188 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_HC)) 2158 if (!text_blink_ev.active)
2189 back = Color_HC;
2190 else 2159 {
2191 rvid = !rvid; /* fall back */ 2160 text_blink_ev.start (NOW + TEXT_BLINK_INTERVAL);
2161 hidden_text = 0;
2162 }
2163 else if (hidden_text)
2164 fore = back;
2192 } 2165 }
2193#endif 2166#endif
2194 if (rvid) 2167 if (rvid)
2195 { 2168 {
2196 SWAP_IT(fore, back, int); 2169 SWAP_IT(fore, back, int);
2197 2170
2198#ifndef NO_BOLD_UNDERLINE_REVERSE 2171#ifndef NO_BOLD_UNDERLINE_REVERSE
2199 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_RV) 2172 if (ISSET_PIXCOLOR (this, Color_RV)
2200# ifndef NO_CURSORCOLOR 2173# ifndef NO_CURSORCOLOR
2201 && !ISSET_PIXCOLOR (this, Color_cursor) 2174 && !ISSET_PIXCOLOR (this, Color_cursor)
2202# endif 2175# endif
2203 ) 2176 )
2204 back = Color_RV; 2177 back = Color_RV;
2205#endif 2178#endif
2206 } 2179 }
2207#ifndef NO_BOLD_UNDERLINE_REVERSE 2180#ifndef NO_BOLD_UNDERLINE_REVERSE
2208 else if (rend & RS_Bold) 2181 else if (rend & RS_Bold)
2209 { 2182 {
2210 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_BD)) 2183 if (ISSET_PIXCOLOR (this, Color_BD))
2211 {
2212 fore = Color_BD; 2184 fore = Color_BD;
2213# ifndef VERYBOLD 2185 else if (fore == Color_fg)
2214 rend &= ~RS_Bold; /* we've taken care of it */ 2186 fore = Color_White;
2215# endif
2216 }
2217 } 2187 }
2218 else if (rend & RS_Uline) 2188 else if (rend & RS_Uline)
2219 { 2189 {
2220 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_UL)) 2190 if (ISSET_PIXCOLOR (this, Color_UL))
2221 {
2222 fore = Color_UL; 2191 fore = Color_UL;
2223 rend &= ~RS_Uline; /* we've taken care of it */
2224 }
2225 } 2192 }
2226#endif 2193#endif
2227 2194
2228/* 2195 /*
2229 * Actually do the drawing of the string here 2196 * Actually do the drawing of the string here
2230 */ 2197 */
2231 rxvt_font *font = (*TermWin.fontset)[fid]; 2198 rxvt_font *font = (*TermWin.fontset)[fid];
2232 2199
2233 if (back == Color_bg) 2200 if (back == Color_bg)
2234 { 2201 {
2235 if (must_clear) 2202 if (must_clear)
2255 xpixel, ypixel + font->ascent + 1, 2222 xpixel, ypixel + font->ascent + 1,
2256 xpixel + Width2Pixel(count) - 1, ypixel + font->ascent + 1); 2223 xpixel + Width2Pixel(count) - 1, ypixel + font->ascent + 1);
2257 } /* for (col....) */ 2224 } /* for (col....) */
2258 } /* for (row....) */ 2225 } /* for (row....) */
2259 2226
2260/* 2227 /*
2261 * G: cleanup cursor and display outline cursor if necessary 2228 * G: cleanup cursor and display outline cursor if necessary
2262 */ 2229 */
2263 if (showcursor) { 2230 if (showcursor) {
2264 if (TermWin.focus) { 2231 if (TermWin.focus) {
2265 srp = &(screen.rend[screen.cur.row + TermWin.saveLines] 2232 srp = &(screen.rend[screen.cur.row + TermWin.saveLines]
2266 [screen.cur.col]); 2233 [screen.cur.col]);
2267 *srp ^= RS_RVid; 2234 *srp ^= RS_RVid;
2270#endif 2237#endif
2271 } else if (oldcursor.row >= 0) { 2238 } else if (oldcursor.row >= 0) {
2272#ifndef NO_CURSORCOLOR 2239#ifndef NO_CURSORCOLOR
2273 unsigned long gcmask; /* Graphics Context mask */ 2240 unsigned long gcmask; /* Graphics Context mask */
2274 2241
2275 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_cursor)) 2242 if (ISSET_PIXCOLOR (this, Color_cursor))
2276 XSetForeground (Xdisplay, TermWin.gc, PixColors[Color_cursor]); 2243 XSetForeground (Xdisplay, TermWin.gc, PixColors[Color_cursor]);
2277#endif 2244#endif
2278 XDrawRectangle(Xdisplay, drawBuffer, TermWin.gc, 2245 XDrawRectangle(Xdisplay, drawBuffer, TermWin.gc,
2279 Col2Pixel(oldcursor.col), 2246 Col2Pixel(oldcursor.col),
2280 Row2Pixel(oldcursor.row), 2247 Row2Pixel(oldcursor.row),
2281 (unsigned int)(Width2Pixel(cursorwidth) - 1), 2248 (unsigned int)(Width2Pixel(cursorwidth) - 1),
2282 (unsigned int)(Height2Pixel(1) - TermWin.lineSpace - 1)); 2249 (unsigned int)(Height2Pixel(1) - TermWin.lineSpace - 1));
2283 } 2250 }
2284 } 2251 }
2285/* 2252
2253 /*
2286 * H: cleanup selection 2254 * H: cleanup selection
2287 */ 2255 */
2288 rxvt_scr_reverse_selection (this); 2256 rxvt_scr_reverse_selection (this);
2289 2257
2290/* 2258 /*
2291 * I: other general cleanup 2259 * I: other general cleanup
2292 */ 2260 */
2293 if (clearfirst && TermWin.int_bwidth) 2261 if (clearfirst && TermWin.int_bwidth)
2294 /* 2262 /*
2295 * clear the whole screen height, note that width == 0 is treated 2263 * clear the whole screen height, note that width == 0 is treated
2296 * specially by XClearArea 2264 * specially by XClearArea
2297 */ 2265 */
2362 i = end_row; 2330 i = end_row;
2363 } 2331 }
2364 end_row += R->TermWin.nrow; 2332 end_row += R->TermWin.nrow;
2365 for (; i < row && i < end_row; i++, col = 0) 2333 for (; i < row && i < end_row; i++, col = 0)
2366 for (srp = R->screen.rend[i]; col < R->TermWin.ncol; col++) 2334 for (srp = R->screen.rend[i]; col < R->TermWin.ncol; col++)
2367#ifndef OPTION_HC
2368 srp[col] ^= RS_RVid; 2335 srp[col] ^= RS_RVid;
2369#else
2370 srp[col] ^= RS_Blink;
2371#endif
2372 if (i == row && i < end_row) 2336 if (i == row && i < end_row)
2373 for (srp = R->screen.rend[i]; col < R->selection.end.col; col++) 2337 for (srp = R->screen.rend[i]; col < R->selection.end.col; col++)
2374#ifndef OPTION_HC
2375 srp[col] ^= RS_RVid; 2338 srp[col] ^= RS_RVid;
2376#else
2377 srp[col] ^= RS_Blink;
2378#endif
2379 } 2339 }
2380} 2340}
2381 2341
2382/* ------------------------------------------------------------------------- */ 2342/* ------------------------------------------------------------------------- */
2383/* 2343/*
2489rxvt_selection_paste(pR_ Window win, Atom prop, Bool delete_prop) 2449rxvt_selection_paste(pR_ Window win, Atom prop, Bool delete_prop)
2490{ 2450{
2491 long nread = 0; 2451 long nread = 0;
2492 unsigned long bytes_after; 2452 unsigned long bytes_after;
2493 XTextProperty ct; 2453 XTextProperty ct;
2494 int dummy_count;
2495 char **cl;
2496 2454
2497 D_SELECT((stderr, "rxvt_selection_paste(%08lx, %lu, %d), wait=%2x", win, (unsigned long)prop, (int)delete_prop, R->selection_wait)); 2455 D_SELECT((stderr, "rxvt_selection_paste(%08lx, %lu, %d), wait=%2x", win, (unsigned long)prop, (int)delete_prop, R->selection_wait));
2498 2456
2499 if (prop == None) /* check for failed XConvertSelection */ 2457 if (prop == None) /* check for failed XConvertSelection */
2500 { 2458 {
2503 int selnum = R->selection_type & Sel_whereMask; 2461 int selnum = R->selection_type & Sel_whereMask;
2504 2462
2505 R->selection_type = 0; 2463 R->selection_type = 0;
2506 if (selnum != Sel_direct) 2464 if (selnum != Sel_direct)
2507 rxvt_selection_request_other(aR_ XA_STRING, selnum); 2465 rxvt_selection_request_other(aR_ XA_STRING, selnum);
2466 }
2467
2468 if ((R->selection_type & Sel_UTF8String))
2469 {
2470 int selnum = R->selection_type & Sel_whereMask;
2471
2472 R->selection_type = Sel_CompoundText;
2473 if (selnum != Sel_direct)
2474 rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], selnum);
2475 else
2476 R->selection_type = 0;
2508 } 2477 }
2509 2478
2510 return 0; 2479 return 0;
2511 } 2480 }
2512 2481
2547 nread = -1; /* discount any previous stuff */ 2516 nread = -1; /* discount any previous stuff */
2548 break; 2517 break;
2549 } 2518 }
2550 2519
2551 nread += ct.nitems; 2520 nread += ct.nitems;
2521
2522 char **cl;
2523 int cr;
2552 if (XmbTextPropertyToTextList (R->Xdisplay, &ct, &cl, 2524 if (XmbTextPropertyToTextList (R->Xdisplay, &ct, &cl,
2553 &dummy_count) == Success && cl) 2525 &cr) >= 0 && cl)
2554 { 2526 {
2527 for (int i = 0; i < cr; i++)
2555 R->paste ((unsigned char *)cl[0], STRLEN (cl[0])); 2528 R->paste ((unsigned char *)cl[i], STRLEN (cl[i]));
2529
2556 XFreeStringList (cl); 2530 XFreeStringList (cl);
2557 } 2531 }
2558 else 2532 else
2559 R->paste (ct.value, ct.nitems); 2533 R->paste (ct.value, ct.nitems);
2560 2534
2575} 2549}
2576 2550
2577void 2551void
2578rxvt_term::incr_cb (time_watcher &w) 2552rxvt_term::incr_cb (time_watcher &w)
2579{ 2553{
2580 w.stop ();
2581 selection_wait = Sel_none; 2554 selection_wait = Sel_none;
2582 2555
2583 rxvt_print_error("data loss: timeout on INCR selection paste"); 2556 rxvt_print_error ("data loss: timeout on INCR selection paste");
2584} 2557}
2585 2558
2586/* 2559/*
2587 * INCR support originally provided by Paul Sheer <psheer@obsidian.co.za> 2560 * INCR support originally provided by Paul Sheer <psheer@obsidian.co.za>
2588 */ 2561 */
2654 int i; 2627 int i;
2655 2628
2656 R->selection_request_time = tm; 2629 R->selection_request_time = tm;
2657 R->selection_wait = Sel_normal; 2630 R->selection_wait = Sel_normal;
2658 for (i = Sel_Primary; i <= Sel_Clipboard; i++) { 2631 for (i = Sel_Primary; i <= Sel_Clipboard; i++) {
2632#if X_HAVE_UTF8_STRING
2633 R->selection_type = Sel_UTF8String;
2634 if (rxvt_selection_request_other(aR_ R->xa[XA_UTF8_STRING], i))
2635 return;
2636#else
2659 R->selection_type = Sel_CompoundText; 2637 R->selection_type = Sel_CompoundText;
2660 if (rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], i)) 2638 if (rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], i))
2661 return; 2639 return;
2640#endif
2662 } 2641 }
2663 } 2642 }
2664 R->selection_wait = Sel_none; /* don't loop in rxvt_selection_paste() */ 2643 R->selection_wait = Sel_none; /* don't loop in rxvt_selection_paste() */
2665 D_SELECT((stderr, "rxvt_selection_request: pasting CUT_BUFFER0")); 2644 D_SELECT((stderr, "rxvt_selection_request: pasting CUT_BUFFER0"));
2666 rxvt_selection_paste(aR_ Xroot, XA_CUT_BUFFER0, False); 2645 rxvt_selection_paste(aR_ Xroot, XA_CUT_BUFFER0, False);
2798 { 2777 {
2799 free (new_selection_text); 2778 free (new_selection_text);
2800 return; 2779 return;
2801 } 2780 }
2802 2781
2803 // due to MB_MAX_CUR, selection wastage is usually high 2782 // due to MB_MAX_CUR, selection wastage is usually high, so realloc
2804 if (str - (char *)new_selection_text > 1024) 2783 if (str - (char *)new_selection_text > 1024)
2805 new_selection_text = (unsigned char *)rxvt_realloc (new_selection_text, i + 1); 2784 new_selection_text = (unsigned char *)rxvt_realloc (new_selection_text, i + 1);
2806 2785
2807 R->selection.len = i; 2786 R->selection.len = i;
2787
2808 if (R->selection.text) 2788 if (R->selection.text)
2809 free (R->selection.text); 2789 free (R->selection.text);
2810 2790
2811 R->selection.text = new_selection_text; 2791 R->selection.text = new_selection_text;
2812 2792
2813 XSetSelectionOwner(R->Xdisplay, XA_PRIMARY, R->TermWin.vt, tm); 2793 XSetSelectionOwner(R->Xdisplay, XA_PRIMARY, R->TermWin.vt, tm);
2814 if (XGetSelectionOwner(R->Xdisplay, XA_PRIMARY) != R->TermWin.vt) 2794 if (XGetSelectionOwner(R->Xdisplay, XA_PRIMARY) != R->TermWin.vt)
2815 rxvt_print_error("can't get primary selection"); 2795 rxvt_print_error("can't get primary selection");
2796
2797
2798 {
2799 XTextProperty ct;
2800 char *cl = (char *)R->selection.text;
2801
2802 if (XmbTextListToTextProperty(R->Xdisplay, &cl, 1, XStringStyle, &ct) >= 0)
2803 {
2804 XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8,
2805 PropModeReplace, ct.value, ct.nitems);
2806 XFree (ct.value);
2807 }
2808 else
2816 XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8, 2809 XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8,
2817 PropModeReplace, R->selection.text, (int)R->selection.len); 2810 PropModeReplace, R->selection.text, (int)R->selection.len);
2811 }
2812
2818 R->selection_time = tm; 2813 R->selection_time = tm;
2819 D_SELECT((stderr, "rxvt_selection_make(): R->selection.len=%d", R->selection.len)); 2814 D_SELECT((stderr, "rxvt_selection_make(): R->selection.len=%d", R->selection.len));
2820} 2815}
2821 2816
2822/* ------------------------------------------------------------------------- */ 2817/* ------------------------------------------------------------------------- */
3274/* 3269/*
3275 * On some systems, the Atom typedef is 64 bits wide. We need to have a type 3270 * On some systems, the Atom typedef is 64 bits wide. We need to have a type
3276 * that is exactly 32 bits wide, because a format of 64 is not allowed by 3271 * that is exactly 32 bits wide, because a format of 64 is not allowed by
3277 * the X11 protocol. 3272 * the X11 protocol.
3278 */ 3273 */
3279typedef CARD32 Atom32; 3274typedef CARD32 Atom32;
3280 3275
3281/* ------------------------------------------------------------------------- */ 3276/* ------------------------------------------------------------------------- */
3282/* 3277/*
3283 * Respond to a request for our current selection 3278 * Respond to a request for our current selection
3284 * EXT: SelectionRequest 3279 * EXT: SelectionRequest
3286/* EXTPROTO */ 3281/* EXTPROTO */
3287void 3282void
3288rxvt_selection_send(pR_ const XSelectionRequestEvent *rq) 3283rxvt_selection_send(pR_ const XSelectionRequestEvent *rq)
3289{ 3284{
3290 XSelectionEvent ev; 3285 XSelectionEvent ev;
3291#ifdef USE_XIM
3292 Atom32 target_list[4];
3293#else
3294 Atom32 target_list[3];
3295#endif
3296 Atom target;
3297 XTextProperty ct; 3286 XTextProperty ct;
3298 XICCEncodingStyle style; 3287 XICCEncodingStyle style;
3299 char *cl[2], dummy[1]; 3288 Atom target;
3300 3289
3301 ev.type = SelectionNotify; 3290 ev.type = SelectionNotify;
3302 ev.property = None; 3291 ev.property = None;
3303 ev.display = rq->display; 3292 ev.display = rq->display;
3304 ev.requestor = rq->requestor; 3293 ev.requestor = rq->requestor;
3305 ev.selection = rq->selection; 3294 ev.selection = rq->selection;
3306 ev.target = rq->target; 3295 ev.target = rq->target;
3307 ev.time = rq->time; 3296 ev.time = rq->time;
3308 3297
3309 if (rq->target == R->xa[XA_TARGETS]) { 3298 if (rq->target == R->xa[XA_TARGETS]) {
3299 Atom32 target_list[5];
3300 Atom32 *target = target_list;
3301
3310 target_list[0] = (Atom32) R->xa[XA_TARGETS]; 3302 *target++ = (Atom32) R->xa[XA_TARGETS];
3311 target_list[1] = (Atom32) XA_STRING; 3303 *target++ = (Atom32) XA_STRING;
3312 target_list[2] = (Atom32) R->xa[XA_TEXT]; 3304 *target++ = (Atom32) R->xa[XA_TEXT];
3313#ifdef USE_XIM
3314 target_list[3] = (Atom32) R->xa[XA_COMPOUND_TEXT]; 3305 *target++ = (Atom32) R->xa[XA_COMPOUND_TEXT];
3306#if X_HAVE_UTF8_STRING
3307 *target++ = (Atom32) R->xa[XA_UTF8_STRING];
3315#endif 3308#endif
3316 XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_ATOM, 3309 XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_ATOM,
3317 (8 * sizeof(target_list[0])), PropModeReplace, 3310 (8 * sizeof(target_list[0])), PropModeReplace,
3318 (unsigned char *)target_list, 3311 (unsigned char *)target_list,
3319 (sizeof(target_list) / sizeof(target_list[0]))); 3312 target - target_list);
3320 ev.property = rq->property; 3313 ev.property = rq->property;
3321 } else if (rq->target == R->xa[XA_MULTIPLE]) { 3314 } else if (rq->target == R->xa[XA_MULTIPLE]) {
3322 /* TODO: Handle MULTIPLE */ 3315 /* TODO: Handle MULTIPLE */
3323 } else if (rq->target == R->xa[XA_TIMESTAMP] && R->selection.text) { 3316 } else if (rq->target == R->xa[XA_TIMESTAMP] && R->selection.text) {
3324 XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_INTEGER, 3317 XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_INTEGER,
3325 (8 * sizeof(Time)), PropModeReplace, 3318 (8 * sizeof(Time)), PropModeReplace,
3326 (unsigned char *)&R->selection_time, 1); 3319 (unsigned char *)&R->selection_time, 1);
3327 ev.property = rq->property; 3320 ev.property = rq->property;
3328 } else if (rq->target == XA_STRING 3321 } else if (rq->target == XA_STRING
3322 || rq->target == R->xa[XA_TEXT]
3329 || rq->target == R->xa[XA_COMPOUND_TEXT] 3323 || rq->target == R->xa[XA_COMPOUND_TEXT]
3330 || rq->target == R->xa[XA_TEXT]) { 3324 || rq->target == R->xa[XA_UTF8_STRING]
3331#ifdef USE_XIM 3325 ) {
3332 short freect = 0; 3326 short freect = 0;
3333#endif
3334 int selectlen; 3327 int selectlen;
3328 char *cl;
3335 3329
3336#ifdef USE_XIM 3330 target = rq->target;
3331
3337 if (rq->target != XA_STRING) { 3332 if (target == XA_STRING)
3333 // we actually don't do XA_STRING, but who cares, as i18n clients
3334 // will ask for another format anyways.
3335 style = XStringStyle;
3336 else if (target == R->xa[XA_TEXT])
3337 style = XTextStyle;
3338 else if (target == R->xa[XA_COMPOUND_TEXT])
3339 style = XCompoundTextStyle;
3340#if X_HAVE_UTF8_STRING
3341 else if (target == R->xa[XA_UTF8_STRING])
3342 style = XUTF8StringStyle;
3343#endif
3344 else
3345 {
3338 target = R->xa[XA_COMPOUND_TEXT]; 3346 target = R->xa[XA_COMPOUND_TEXT];
3339 style = (rq->target == R->xa[XA_COMPOUND_TEXT])
3340 ? XCompoundTextStyle : XStdICCTextStyle;
3341 } else
3342#endif
3343 {
3344 target = XA_STRING;
3345 style = XStringStyle; 3347 style = XCompoundTextStyle;
3346 } 3348 }
3349
3347 if (R->selection.text) { 3350 if (R->selection.text) {
3348 cl[0] = (char *)R->selection.text; 3351 cl = (char *)R->selection.text;
3349 selectlen = R->selection.len; 3352 selectlen = R->selection.len;
3350 } else { 3353 } else {
3351 cl[0] = dummy; 3354 cl = "";
3352 *dummy = '\0';
3353 selectlen = 0; 3355 selectlen = 0;
3354 } 3356 }
3355#ifdef USE_XIM 3357
3356 if (XmbTextListToTextProperty(R->Xdisplay, cl, 1, style, &ct) 3358 if (XmbTextListToTextProperty(R->Xdisplay, &cl, 1, style, &ct) >= 0)
3357 == Success) /* if we failed to convert then send it raw */
3358 freect = 1; 3359 freect = 1;
3359 else 3360 else
3360#endif
3361 { 3361 {
3362 /* if we failed to convert then send it raw */
3362 ct.value = (unsigned char *)cl[0]; 3363 ct.value = (unsigned char *)cl;
3363 ct.nitems = selectlen; 3364 ct.nitems = selectlen;
3364 } 3365 }
3366
3365 XChangeProperty(R->Xdisplay, rq->requestor, rq->property, 3367 XChangeProperty(R->Xdisplay, rq->requestor, rq->property,
3366 target, 8, PropModeReplace, 3368 target, 8, PropModeReplace,
3367 ct.value, (int)ct.nitems); 3369 ct.value, (int)ct.nitems);
3368 ev.property = rq->property; 3370 ev.property = rq->property;
3369#ifdef USE_XIM 3371
3370 if (freect) 3372 if (freect)
3371 XFree(ct.value); 3373 XFree (ct.value);
3372#endif
3373 } 3374 }
3374 XSendEvent(R->Xdisplay, rq->requestor, False, 0L, (XEvent *)&ev); 3375 XSendEvent(R->Xdisplay, rq->requestor, False, 0L, (XEvent *)&ev);
3375} 3376}
3376 3377
3377/* ------------------------------------------------------------------------- * 3378/* ------------------------------------------------------------------------- *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines