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.12 by pcg, Thu Dec 18 14:11:47 2003 UTC vs.
Revision 1.19 by pcg, Thu Jan 29 23:26:01 2004 UTC

1/*--------------------------------*-C-*--------------------------------------* 1/*--------------------------------*-C-*--------------------------------------*
2 * File: screen.c 2 * File: screen.c
3 *---------------------------------------------------------------------------* 3 *---------------------------------------------------------------------------*
4 * $Id: screen.C,v 1.12 2003/12/18 14:11:47 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 */
1908 return; 1892 return;
1909 1893
1910 /* 1894 /*
1911 * A: set up vars 1895 * A: set up vars
1912 */ 1896 */
1913 clearfirst = clearlast = must_clear = wbyte = 0; 1897 clearfirst = clearlast = must_clear = 0;
1914#ifndef NO_BOLDFONT
1915 bfont = 0;
1916#endif
1917 1898
1918 if (currmaxcol < TermWin.ncol) 1899 if (currmaxcol < TermWin.ncol)
1919 { 1900 {
1920 currmaxcol = TermWin.ncol; 1901 currmaxcol = TermWin.ncol;
1921 buffer = (char *)rxvt_realloc (buffer, 1902 buffer = (char *)rxvt_realloc (buffer,
1992#endif 1973#endif
1993 *srp = SET_FGCOLOR(*srp, ccol1); 1974 *srp = SET_FGCOLOR(*srp, ccol1);
1994 *srp = SET_BGCOLOR(*srp, ccol2); 1975 *srp = SET_BGCOLOR(*srp, ccol2);
1995#endif 1976#endif
1996 } 1977 }
1997
1998 while (IS_WIDE (*srp))
1999 cursorwidth++, srp++;
2000 } 1978 }
2001 1979
2002 /* make sure no outline cursor is left around */ 1980 /* make sure no outline cursor is left around */
2003 setoldcursor = 0; 1981 setoldcursor = 0;
2004 if (ocrow != -1) { 1982 if (ocrow != -1) {
2147 i++; 2125 i++;
2148 2126
2149 continue; 2127 continue;
2150 } 2128 }
2151 2129
2152 if (((rend ^ srp[col]) & ~RS_wide) != 0) 2130 if (rend != srp[col])
2153 break; 2131 break;
2154 2132
2155 count++; 2133 count++;
2156 2134
2157 if (stp[col] != dtp[col] 2135 if (stp[col] != dtp[col]
2172 count -= i; /* dump any matching trailing chars */ 2150 count -= i; /* dump any matching trailing chars */
2173 2151
2174 /* 2152 /*
2175 * Determine the attributes for the string 2153 * Determine the attributes for the string
2176 */ 2154 */
2177 int fid = GET_FONT(rend); 2155 int fid = GET_FONT (rend);
2178 fore = GET_FGCOLOR(rend); 2156 int fore = GET_FGCOLOR (rend); // desired foreground
2179 back = GET_BGCOLOR(rend); 2157 int back = GET_BGCOLOR (rend); // desired background
2158
2180 rend = GET_ATTR(rend); 2159 rend = GET_ATTR (rend);
2181 2160
2182 rvid = (rend & RS_RVid) ? 1 : 0; 2161 rvid = !!(rend & RS_RVid);
2162#ifdef TEXT_BLINK
2163 if (rend & RS_Blink)
2164 {
2165 if (!text_blink_ev.active)
2166 {
2167 text_blink_ev.start (NOW + TEXT_BLINK_INTERVAL);
2168 hidden_text = 0;
2169 }
2170 else if (hidden_text)
2171 fore = back;
2172 }
2183#ifdef OPTION_HC 2173#elif OPTION_HC
2184 if (!rvid && (rend & RS_Blink)) 2174 if (!rvid && (rend & RS_Blink))
2185 { 2175 {
2186 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_HC)) 2176 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_HC))
2187 back = Color_HC; 2177 back = Color_HC;
2188 else 2178 else
2203#endif 2193#endif
2204 } 2194 }
2205#ifndef NO_BOLD_UNDERLINE_REVERSE 2195#ifndef NO_BOLD_UNDERLINE_REVERSE
2206 else if (rend & RS_Bold) 2196 else if (rend & RS_Bold)
2207 { 2197 {
2198 if (Xdepth > 2)
2208 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_BD)) 2199 if (ISSET_PIXCOLOR (this, Color_BD))
2209 {
2210 fore = Color_BD; 2200 fore = Color_BD;
2211# ifndef VERYBOLD
2212 rend &= ~RS_Bold; /* we've taken care of it */
2213# endif
2214 } 2201 else
2202 fore = Color_White;
2215 } 2203 }
2216 else if (rend & RS_Uline) 2204 else if (rend & RS_Uline)
2217 { 2205 {
2218 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_UL)) 2206 if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_UL))
2219 {
2220 fore = Color_UL; 2207 fore = Color_UL;
2221 rend &= ~RS_Uline; /* we've taken care of it */
2222 }
2223 } 2208 }
2224#endif 2209#endif
2225 2210
2226 /* 2211 /*
2227 * Actually do the drawing of the string here 2212 * Actually do the drawing of the string here
2488rxvt_selection_paste(pR_ Window win, Atom prop, Bool delete_prop) 2473rxvt_selection_paste(pR_ Window win, Atom prop, Bool delete_prop)
2489{ 2474{
2490 long nread = 0; 2475 long nread = 0;
2491 unsigned long bytes_after; 2476 unsigned long bytes_after;
2492 XTextProperty ct; 2477 XTextProperty ct;
2493 int dummy_count;
2494 char **cl;
2495 2478
2496 D_SELECT((stderr, "rxvt_selection_paste(%08lx, %lu, %d), wait=%2x", win, (unsigned long)prop, (int)delete_prop, R->selection_wait)); 2479 D_SELECT((stderr, "rxvt_selection_paste(%08lx, %lu, %d), wait=%2x", win, (unsigned long)prop, (int)delete_prop, R->selection_wait));
2497 2480
2498 if (prop == None) /* check for failed XConvertSelection */ 2481 if (prop == None) /* check for failed XConvertSelection */
2499 { 2482 {
2502 int selnum = R->selection_type & Sel_whereMask; 2485 int selnum = R->selection_type & Sel_whereMask;
2503 2486
2504 R->selection_type = 0; 2487 R->selection_type = 0;
2505 if (selnum != Sel_direct) 2488 if (selnum != Sel_direct)
2506 rxvt_selection_request_other(aR_ XA_STRING, selnum); 2489 rxvt_selection_request_other(aR_ XA_STRING, selnum);
2490 }
2491
2492 if ((R->selection_type & Sel_UTF8String))
2493 {
2494 int selnum = R->selection_type & Sel_whereMask;
2495
2496 R->selection_type = Sel_CompoundText;
2497 if (selnum != Sel_direct)
2498 rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], selnum);
2499 else
2500 R->selection_type = 0;
2507 } 2501 }
2508 2502
2509 return 0; 2503 return 0;
2510 } 2504 }
2511 2505
2546 nread = -1; /* discount any previous stuff */ 2540 nread = -1; /* discount any previous stuff */
2547 break; 2541 break;
2548 } 2542 }
2549 2543
2550 nread += ct.nitems; 2544 nread += ct.nitems;
2545
2546 char **cl;
2547 int cr;
2551 if (XmbTextPropertyToTextList (R->Xdisplay, &ct, &cl, 2548 if (XmbTextPropertyToTextList (R->Xdisplay, &ct, &cl,
2552 &dummy_count) == Success && cl) 2549 &cr) >= 0 && cl)
2553 { 2550 {
2551 for (int i = 0; i < cr; i++)
2554 R->paste ((unsigned char *)cl[0], STRLEN (cl[0])); 2552 R->paste ((unsigned char *)cl[i], STRLEN (cl[i]));
2553
2555 XFreeStringList (cl); 2554 XFreeStringList (cl);
2556 } 2555 }
2557 else 2556 else
2558 R->paste (ct.value, ct.nitems); 2557 R->paste (ct.value, ct.nitems);
2559 2558
2574} 2573}
2575 2574
2576void 2575void
2577rxvt_term::incr_cb (time_watcher &w) 2576rxvt_term::incr_cb (time_watcher &w)
2578{ 2577{
2579 w.stop ();
2580 selection_wait = Sel_none; 2578 selection_wait = Sel_none;
2581 2579
2582 rxvt_print_error("data loss: timeout on INCR selection paste"); 2580 rxvt_print_error ("data loss: timeout on INCR selection paste");
2583} 2581}
2584 2582
2585/* 2583/*
2586 * INCR support originally provided by Paul Sheer <psheer@obsidian.co.za> 2584 * INCR support originally provided by Paul Sheer <psheer@obsidian.co.za>
2587 */ 2585 */
2653 int i; 2651 int i;
2654 2652
2655 R->selection_request_time = tm; 2653 R->selection_request_time = tm;
2656 R->selection_wait = Sel_normal; 2654 R->selection_wait = Sel_normal;
2657 for (i = Sel_Primary; i <= Sel_Clipboard; i++) { 2655 for (i = Sel_Primary; i <= Sel_Clipboard; i++) {
2656#if X_HAVE_UTF8_STRING
2657 R->selection_type = Sel_UTF8String;
2658 if (rxvt_selection_request_other(aR_ R->xa[XA_UTF8_STRING], i))
2659 return;
2660#else
2658 R->selection_type = Sel_CompoundText; 2661 R->selection_type = Sel_CompoundText;
2659 if (rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], i)) 2662 if (rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], i))
2660 return; 2663 return;
2664#endif
2661 } 2665 }
2662 } 2666 }
2663 R->selection_wait = Sel_none; /* don't loop in rxvt_selection_paste() */ 2667 R->selection_wait = Sel_none; /* don't loop in rxvt_selection_paste() */
2664 D_SELECT((stderr, "rxvt_selection_request: pasting CUT_BUFFER0")); 2668 D_SELECT((stderr, "rxvt_selection_request: pasting CUT_BUFFER0"));
2665 rxvt_selection_paste(aR_ Xroot, XA_CUT_BUFFER0, False); 2669 rxvt_selection_paste(aR_ Xroot, XA_CUT_BUFFER0, False);
2797 { 2801 {
2798 free (new_selection_text); 2802 free (new_selection_text);
2799 return; 2803 return;
2800 } 2804 }
2801 2805
2802 // due to MB_MAX_CUR, selection wastage is usually high 2806 // due to MB_MAX_CUR, selection wastage is usually high, so realloc
2803 if (str - (char *)new_selection_text > 1024) 2807 if (str - (char *)new_selection_text > 1024)
2804 new_selection_text = (unsigned char *)rxvt_realloc (new_selection_text, i + 1); 2808 new_selection_text = (unsigned char *)rxvt_realloc (new_selection_text, i + 1);
2805 2809
2806 R->selection.len = i; 2810 R->selection.len = i;
2811
2807 if (R->selection.text) 2812 if (R->selection.text)
2808 free (R->selection.text); 2813 free (R->selection.text);
2809 2814
2810 R->selection.text = new_selection_text; 2815 R->selection.text = new_selection_text;
2811 2816
2812 XSetSelectionOwner(R->Xdisplay, XA_PRIMARY, R->TermWin.vt, tm); 2817 XSetSelectionOwner(R->Xdisplay, XA_PRIMARY, R->TermWin.vt, tm);
2813 if (XGetSelectionOwner(R->Xdisplay, XA_PRIMARY) != R->TermWin.vt) 2818 if (XGetSelectionOwner(R->Xdisplay, XA_PRIMARY) != R->TermWin.vt)
2814 rxvt_print_error("can't get primary selection"); 2819 rxvt_print_error("can't get primary selection");
2820
2821
2822 {
2823 XTextProperty ct;
2824 char *cl = (char *)R->selection.text;
2825
2826 if (XmbTextListToTextProperty(R->Xdisplay, &cl, 1, XStringStyle, &ct) >= 0)
2827 {
2828 XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8,
2829 PropModeReplace, ct.value, ct.nitems);
2830 XFree (ct.value);
2831 }
2832 else
2815 XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8, 2833 XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8,
2816 PropModeReplace, R->selection.text, (int)R->selection.len); 2834 PropModeReplace, R->selection.text, (int)R->selection.len);
2835 }
2836
2817 R->selection_time = tm; 2837 R->selection_time = tm;
2818 D_SELECT((stderr, "rxvt_selection_make(): R->selection.len=%d", R->selection.len)); 2838 D_SELECT((stderr, "rxvt_selection_make(): R->selection.len=%d", R->selection.len));
2819} 2839}
2820 2840
2821/* ------------------------------------------------------------------------- */ 2841/* ------------------------------------------------------------------------- */
3273/* 3293/*
3274 * On some systems, the Atom typedef is 64 bits wide. We need to have a type 3294 * On some systems, the Atom typedef is 64 bits wide. We need to have a type
3275 * that is exactly 32 bits wide, because a format of 64 is not allowed by 3295 * that is exactly 32 bits wide, because a format of 64 is not allowed by
3276 * the X11 protocol. 3296 * the X11 protocol.
3277 */ 3297 */
3278typedef CARD32 Atom32; 3298typedef CARD32 Atom32;
3279 3299
3280/* ------------------------------------------------------------------------- */ 3300/* ------------------------------------------------------------------------- */
3281/* 3301/*
3282 * Respond to a request for our current selection 3302 * Respond to a request for our current selection
3283 * EXT: SelectionRequest 3303 * EXT: SelectionRequest
3285/* EXTPROTO */ 3305/* EXTPROTO */
3286void 3306void
3287rxvt_selection_send(pR_ const XSelectionRequestEvent *rq) 3307rxvt_selection_send(pR_ const XSelectionRequestEvent *rq)
3288{ 3308{
3289 XSelectionEvent ev; 3309 XSelectionEvent ev;
3290#ifdef USE_XIM
3291 Atom32 target_list[4];
3292#else
3293 Atom32 target_list[3];
3294#endif
3295 Atom target;
3296 XTextProperty ct; 3310 XTextProperty ct;
3297 XICCEncodingStyle style; 3311 XICCEncodingStyle style;
3298 char *cl[2], dummy[1]; 3312 Atom target;
3299 3313
3300 ev.type = SelectionNotify; 3314 ev.type = SelectionNotify;
3301 ev.property = None; 3315 ev.property = None;
3302 ev.display = rq->display; 3316 ev.display = rq->display;
3303 ev.requestor = rq->requestor; 3317 ev.requestor = rq->requestor;
3304 ev.selection = rq->selection; 3318 ev.selection = rq->selection;
3305 ev.target = rq->target; 3319 ev.target = rq->target;
3306 ev.time = rq->time; 3320 ev.time = rq->time;
3307 3321
3308 if (rq->target == R->xa[XA_TARGETS]) { 3322 if (rq->target == R->xa[XA_TARGETS]) {
3323 Atom32 target_list[5];
3324 Atom32 *target = target_list;
3325
3309 target_list[0] = (Atom32) R->xa[XA_TARGETS]; 3326 *target++ = (Atom32) R->xa[XA_TARGETS];
3310 target_list[1] = (Atom32) XA_STRING; 3327 *target++ = (Atom32) XA_STRING;
3311 target_list[2] = (Atom32) R->xa[XA_TEXT]; 3328 *target++ = (Atom32) R->xa[XA_TEXT];
3312#ifdef USE_XIM
3313 target_list[3] = (Atom32) R->xa[XA_COMPOUND_TEXT]; 3329 *target++ = (Atom32) R->xa[XA_COMPOUND_TEXT];
3330#if X_HAVE_UTF8_STRING
3331 *target++ = (Atom32) R->xa[XA_UTF8_STRING];
3314#endif 3332#endif
3315 XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_ATOM, 3333 XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_ATOM,
3316 (8 * sizeof(target_list[0])), PropModeReplace, 3334 (8 * sizeof(target_list[0])), PropModeReplace,
3317 (unsigned char *)target_list, 3335 (unsigned char *)target_list,
3318 (sizeof(target_list) / sizeof(target_list[0]))); 3336 target - target_list);
3319 ev.property = rq->property; 3337 ev.property = rq->property;
3320 } else if (rq->target == R->xa[XA_MULTIPLE]) { 3338 } else if (rq->target == R->xa[XA_MULTIPLE]) {
3321 /* TODO: Handle MULTIPLE */ 3339 /* TODO: Handle MULTIPLE */
3322 } else if (rq->target == R->xa[XA_TIMESTAMP] && R->selection.text) { 3340 } else if (rq->target == R->xa[XA_TIMESTAMP] && R->selection.text) {
3323 XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_INTEGER, 3341 XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_INTEGER,
3324 (8 * sizeof(Time)), PropModeReplace, 3342 (8 * sizeof(Time)), PropModeReplace,
3325 (unsigned char *)&R->selection_time, 1); 3343 (unsigned char *)&R->selection_time, 1);
3326 ev.property = rq->property; 3344 ev.property = rq->property;
3327 } else if (rq->target == XA_STRING 3345 } else if (rq->target == XA_STRING
3346 || rq->target == R->xa[XA_TEXT]
3328 || rq->target == R->xa[XA_COMPOUND_TEXT] 3347 || rq->target == R->xa[XA_COMPOUND_TEXT]
3329 || rq->target == R->xa[XA_TEXT]) { 3348 || rq->target == R->xa[XA_UTF8_STRING]
3330#ifdef USE_XIM 3349 ) {
3331 short freect = 0; 3350 short freect = 0;
3332#endif
3333 int selectlen; 3351 int selectlen;
3352 char *cl;
3334 3353
3335#ifdef USE_XIM 3354 target = rq->target;
3355
3336 if (rq->target != XA_STRING) { 3356 if (target == XA_STRING)
3357 // we actually don't do XA_STRING, but who cares, as i18n clients
3358 // will ask for another format anyways.
3359 style = XStringStyle;
3360 else if (target == R->xa[XA_TEXT])
3361 style = XTextStyle;
3362 else if (target == R->xa[XA_COMPOUND_TEXT])
3363 style = XCompoundTextStyle;
3364#if X_HAVE_UTF8_STRING
3365 else if (target == R->xa[XA_UTF8_STRING])
3366 style = XUTF8StringStyle;
3367#endif
3368 else
3369 {
3337 target = R->xa[XA_COMPOUND_TEXT]; 3370 target = R->xa[XA_COMPOUND_TEXT];
3338 style = (rq->target == R->xa[XA_COMPOUND_TEXT])
3339 ? XCompoundTextStyle : XStdICCTextStyle;
3340 } else
3341#endif
3342 {
3343 target = XA_STRING;
3344 style = XStringStyle; 3371 style = XCompoundTextStyle;
3345 } 3372 }
3373
3346 if (R->selection.text) { 3374 if (R->selection.text) {
3347 cl[0] = (char *)R->selection.text; 3375 cl = (char *)R->selection.text;
3348 selectlen = R->selection.len; 3376 selectlen = R->selection.len;
3349 } else { 3377 } else {
3350 cl[0] = dummy; 3378 cl = "";
3351 *dummy = '\0';
3352 selectlen = 0; 3379 selectlen = 0;
3353 } 3380 }
3354#ifdef USE_XIM 3381
3355 if (XmbTextListToTextProperty(R->Xdisplay, cl, 1, style, &ct) 3382 if (XmbTextListToTextProperty(R->Xdisplay, &cl, 1, style, &ct) >= 0)
3356 == Success) /* if we failed to convert then send it raw */
3357 freect = 1; 3383 freect = 1;
3358 else 3384 else
3359#endif
3360 { 3385 {
3386 /* if we failed to convert then send it raw */
3361 ct.value = (unsigned char *)cl[0]; 3387 ct.value = (unsigned char *)cl;
3362 ct.nitems = selectlen; 3388 ct.nitems = selectlen;
3363 } 3389 }
3390
3364 XChangeProperty(R->Xdisplay, rq->requestor, rq->property, 3391 XChangeProperty(R->Xdisplay, rq->requestor, rq->property,
3365 target, 8, PropModeReplace, 3392 target, 8, PropModeReplace,
3366 ct.value, (int)ct.nitems); 3393 ct.value, (int)ct.nitems);
3367 ev.property = rq->property; 3394 ev.property = rq->property;
3368#ifdef USE_XIM 3395
3369 if (freect) 3396 if (freect)
3370 XFree(ct.value); 3397 XFree (ct.value);
3371#endif
3372 } 3398 }
3373 XSendEvent(R->Xdisplay, rq->requestor, False, 0L, (XEvent *)&ev); 3399 XSendEvent(R->Xdisplay, rq->requestor, False, 0L, (XEvent *)&ev);
3374} 3400}
3375 3401
3376/* ------------------------------------------------------------------------- * 3402/* ------------------------------------------------------------------------- *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines