1 | /*--------------------------------*-C-*--------------------------------------* |
1 | /*--------------------------------*-C-*--------------------------------------* |
2 | * File: screen.c |
2 | * File: screen.c |
3 | *---------------------------------------------------------------------------* |
3 | *---------------------------------------------------------------------------* |
4 | * $Id: screen.C,v 1.16 2004/01/16 22:11:09 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 |
… | |
… | |
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 | // rely on wcwidth to tell us the character width, at least for non-ascii |
903 | // rely on wcwidth to tell us the character width, at least for non-ascii |
905 | int width = c <= 128 ? 1 : wcwidth (c); |
904 | int width = c <= 128 ? 1 : wcwidth (c); |
906 | |
905 | |
907 | // width 0 characters (e.g. combining chars) are ignored. your problem, really |
906 | // width -1 characters (e.g. combining chars) are ignored currently. |
908 | while (width-- > 0) |
907 | if (width > 0) |
|
|
908 | do |
909 | { |
909 | { |
910 | stp[R->screen.cur.col] = c; |
910 | stp[R->screen.cur.col] = c; |
911 | srp[R->screen.cur.col] = rend; |
911 | srp[R->screen.cur.col] = rend; |
912 | |
912 | |
913 | if (R->screen.cur.col < last_col - 1) |
913 | if (R->screen.cur.col < last_col - 1) |
914 | R->screen.cur.col++; |
914 | R->screen.cur.col++; |
915 | else |
915 | else |
916 | { |
916 | { |
917 | R->screen.tlen[row] = last_col; |
917 | R->screen.tlen[row] = last_col; |
918 | if (R->screen.flags & Screen_Autowrap) |
918 | if (R->screen.flags & Screen_Autowrap) |
919 | R->screen.flags |= Screen_WrapNext; |
919 | R->screen.flags |= Screen_WrapNext; |
920 | break; |
920 | break; |
921 | } |
921 | } |
922 | |
922 | |
923 | c = NOCHAR; |
923 | c = NOCHAR; |
924 | } |
924 | } |
|
|
925 | while (--width > 0); |
|
|
926 | else |
|
|
927 | 1; /* handle combining character etc. here. */ |
925 | } |
928 | } |
|
|
929 | |
926 | if (R->screen.tlen[row] != -1) /* XXX: think about this */ |
930 | if (R->screen.tlen[row] != -1) /* XXX: think about this */ |
927 | MAX_IT(R->screen.tlen[row], R->screen.cur.col); |
931 | MAX_IT(R->screen.tlen[row], R->screen.cur.col); |
928 | |
932 | |
929 | /* |
933 | /* |
930 | * If we wrote anywhere in the selected area, kill the selection |
934 | * If we wrote anywhere in the selected area, kill the selection |
931 | * XXX: should we kill the mark too? Possibly, but maybe that |
935 | * XXX: should we kill the mark too? Possibly, but maybe that |
932 | * should be a similar check. |
936 | * should be a similar check. |
… | |
… | |
1641 | rxvt_set_font_style(aR); |
1645 | rxvt_set_font_style(aR); |
1642 | } |
1646 | } |
1643 | |
1647 | |
1644 | |
1648 | |
1645 | /* ------------------------------------------------------------------------- * |
1649 | /* ------------------------------------------------------------------------- * |
1646 | * GRAPHICS COLOURS * |
|
|
1647 | * ------------------------------------------------------------------------- */ |
|
|
1648 | |
|
|
1649 | #ifdef RXVT_GRAPHICS |
|
|
1650 | /* EXTPROTO */ |
|
|
1651 | int |
|
|
1652 | rxvt_scr_get_fgcolor(pR) |
|
|
1653 | { |
|
|
1654 | return GET_FGCOLOR(R->rstyle); |
|
|
1655 | } |
|
|
1656 | |
|
|
1657 | /* ------------------------------------------------------------------------- */ |
|
|
1658 | /* EXTPROTO */ |
|
|
1659 | int |
|
|
1660 | rxvt_scr_get_bgcolor(pR) |
|
|
1661 | { |
|
|
1662 | return GET_BGCOLOR(R->rstyle); |
|
|
1663 | } |
|
|
1664 | #endif |
|
|
1665 | |
|
|
1666 | /* ------------------------------------------------------------------------- * |
|
|
1667 | * MAJOR SCREEN MANIPULATION * |
1650 | * MAJOR SCREEN MANIPULATION * |
1668 | * ------------------------------------------------------------------------- */ |
1651 | * ------------------------------------------------------------------------- */ |
1669 | |
1652 | |
1670 | /* |
1653 | /* |
1671 | * Refresh an area |
1654 | * Refresh an area |
… | |
… | |
1850 | * Refresh the screen |
1833 | * Refresh the screen |
1851 | * R->drawn_text/R->drawn_rend contain the screen information before the update. |
1834 | * R->drawn_text/R->drawn_rend contain the screen information before the update. |
1852 | * R->screen.text/R->screen.rend contain what the screen will change to. |
1835 | * R->screen.text/R->screen.rend contain what the screen will change to. |
1853 | */ |
1836 | */ |
1854 | |
1837 | |
1855 | #if defined (NO_BRIGHTCOLOR) || defined (VERYBOLD) |
|
|
1856 | # define MONO_BOLD(x) ((x) & (RS_Bold|RS_Blink)) |
|
|
1857 | # define MONO_BOLD_FG(x, fg) MONO_BOLD(x) |
|
|
1858 | #else |
|
|
1859 | # define MONO_BOLD(x) \ |
|
|
1860 | (((x) & (RS_Bold | RS_fgMask)) == (RS_Bold | Color_fg)) |
|
|
1861 | # define MONO_BOLD_FG(x, fg) (((x) & RS_Bold) && (fg) == Color_fg) |
|
|
1862 | #endif |
|
|
1863 | |
|
|
1864 | #define FONT_WIDTH(X, Y) \ |
1838 | #define FONT_WIDTH(X, Y) \ |
1865 | (X)->per_char[(Y) - (X)->min_char_or_byte2].width |
1839 | (X)->per_char[(Y) - (X)->min_char_or_byte2].width |
1866 | #define FONT_RBEAR(X, Y) \ |
1840 | #define FONT_RBEAR(X, Y) \ |
1867 | (X)->per_char[(Y) - (X)->min_char_or_byte2].rbearing |
1841 | (X)->per_char[(Y) - (X)->min_char_or_byte2].rbearing |
1868 | #define FONT_LBEAR(X, Y) \ |
1842 | #define FONT_LBEAR(X, Y) \ |
… | |
… | |
1874 | rxvt_term::scr_refresh (unsigned char refresh_type) |
1848 | rxvt_term::scr_refresh (unsigned char refresh_type) |
1875 | { |
1849 | { |
1876 | unsigned char clearfirst, /* first character writes before cell */ |
1850 | unsigned char clearfirst, /* first character writes before cell */ |
1877 | clearlast, /* last character writes beyond cell */ |
1851 | clearlast, /* last character writes beyond cell */ |
1878 | must_clear, /* use draw_string not draw_image_string */ |
1852 | must_clear, /* use draw_string not draw_image_string */ |
1879 | #ifndef NO_BOLDFONT |
|
|
1880 | bfont, /* we've changed font to bold font */ |
|
|
1881 | #endif |
|
|
1882 | rvid, /* reverse video this position */ |
1853 | rvid, /* reverse video this position */ |
1883 | wbyte, /* we're in multibyte */ |
|
|
1884 | showcursor; /* show the cursor */ |
1854 | showcursor; /* show the cursor */ |
1885 | int fore, back; /* desired foreground/background */ |
|
|
1886 | int16_t col, row, /* column/row we're processing */ |
1855 | int16_t col, row, /* column/row we're processing */ |
1887 | ocrow; /* old cursor row */ |
1856 | ocrow; /* old cursor row */ |
1888 | int cursorwidth; |
1857 | int cursorwidth; |
1889 | int i, /* tmp */ |
1858 | int i, /* tmp */ |
1890 | row_offset; /* basic offset in screen structure */ |
1859 | row_offset; /* basic offset in screen structure */ |
… | |
… | |
1899 | return; |
1868 | return; |
1900 | |
1869 | |
1901 | /* |
1870 | /* |
1902 | * A: set up vars |
1871 | * A: set up vars |
1903 | */ |
1872 | */ |
1904 | clearfirst = clearlast = must_clear = wbyte = 0; |
1873 | clearfirst = clearlast = must_clear = 0; |
1905 | #ifndef NO_BOLDFONT |
|
|
1906 | bfont = 0; |
|
|
1907 | #endif |
|
|
1908 | |
1874 | |
1909 | if (currmaxcol < TermWin.ncol) |
1875 | if (currmaxcol < TermWin.ncol) |
1910 | { |
1876 | { |
1911 | currmaxcol = TermWin.ncol; |
1877 | currmaxcol = TermWin.ncol; |
1912 | buffer = (char *)rxvt_realloc (buffer, |
1878 | buffer = (char *)rxvt_realloc (buffer, |
… | |
… | |
1983 | #endif |
1949 | #endif |
1984 | *srp = SET_FGCOLOR(*srp, ccol1); |
1950 | *srp = SET_FGCOLOR(*srp, ccol1); |
1985 | *srp = SET_BGCOLOR(*srp, ccol2); |
1951 | *srp = SET_BGCOLOR(*srp, ccol2); |
1986 | #endif |
1952 | #endif |
1987 | } |
1953 | } |
1988 | |
|
|
1989 | while (IS_WIDE (*srp)) |
|
|
1990 | cursorwidth++, srp++; |
|
|
1991 | } |
1954 | } |
1992 | |
1955 | |
1993 | /* make sure no outline cursor is left around */ |
1956 | /* make sure no outline cursor is left around */ |
1994 | setoldcursor = 0; |
1957 | setoldcursor = 0; |
1995 | if (ocrow != -1) { |
1958 | if (ocrow != -1) { |
… | |
… | |
2138 | i++; |
2101 | i++; |
2139 | |
2102 | |
2140 | continue; |
2103 | continue; |
2141 | } |
2104 | } |
2142 | |
2105 | |
2143 | if (((rend ^ srp[col]) & ~RS_wide) != 0) |
2106 | if (rend != srp[col]) |
2144 | break; |
2107 | break; |
2145 | |
2108 | |
2146 | count++; |
2109 | count++; |
2147 | |
2110 | |
2148 | if (stp[col] != dtp[col] |
2111 | if (stp[col] != dtp[col] |
… | |
… | |
2163 | count -= i; /* dump any matching trailing chars */ |
2126 | count -= i; /* dump any matching trailing chars */ |
2164 | |
2127 | |
2165 | /* |
2128 | /* |
2166 | * Determine the attributes for the string |
2129 | * Determine the attributes for the string |
2167 | */ |
2130 | */ |
2168 | int fid = GET_FONT(rend); |
2131 | int fid = GET_FONT (rend); |
2169 | fore = GET_FGCOLOR(rend); |
2132 | int fore = GET_FGCOLOR (rend); // desired foreground |
2170 | back = GET_BGCOLOR(rend); |
2133 | int back = GET_BGCOLOR (rend); // desired background |
|
|
2134 | |
2171 | rend = GET_ATTR(rend); |
2135 | rend = GET_ATTR (rend); |
2172 | |
2136 | |
2173 | rvid = (rend & RS_RVid) ? 1 : 0; |
2137 | rvid = !!(rend & RS_RVid); |
2174 | #ifdef OPTION_HC |
2138 | #ifdef OPTION_HC |
2175 | if (!rvid && (rend & RS_Blink)) |
2139 | if (!rvid && (rend & RS_Blink)) |
2176 | { |
2140 | { |
2177 | if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_HC)) |
2141 | if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_HC)) |
2178 | back = Color_HC; |
2142 | back = Color_HC; |
… | |
… | |
2195 | } |
2159 | } |
2196 | #ifndef NO_BOLD_UNDERLINE_REVERSE |
2160 | #ifndef NO_BOLD_UNDERLINE_REVERSE |
2197 | else if (rend & RS_Bold) |
2161 | else if (rend & RS_Bold) |
2198 | { |
2162 | { |
2199 | if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_BD)) |
2163 | if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_BD)) |
2200 | { |
|
|
2201 | fore = Color_BD; |
2164 | fore = Color_BD; |
2202 | # ifndef VERYBOLD |
|
|
2203 | rend &= ~RS_Bold; /* we've taken care of it */ |
|
|
2204 | # endif |
|
|
2205 | } |
|
|
2206 | } |
2165 | } |
2207 | else if (rend & RS_Uline) |
2166 | else if (rend & RS_Uline) |
2208 | { |
2167 | { |
2209 | if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_UL)) |
2168 | if (Xdepth > 2 && ISSET_PIXCOLOR (this, Color_UL)) |
2210 | { |
|
|
2211 | fore = Color_UL; |
2169 | fore = Color_UL; |
2212 | rend &= ~RS_Uline; /* we've taken care of it */ |
|
|
2213 | } |
|
|
2214 | } |
2170 | } |
2215 | #endif |
2171 | #endif |
2216 | |
2172 | |
2217 | /* |
2173 | /* |
2218 | * Actually do the drawing of the string here |
2174 | * Actually do the drawing of the string here |
… | |
… | |
2479 | rxvt_selection_paste(pR_ Window win, Atom prop, Bool delete_prop) |
2435 | rxvt_selection_paste(pR_ Window win, Atom prop, Bool delete_prop) |
2480 | { |
2436 | { |
2481 | long nread = 0; |
2437 | long nread = 0; |
2482 | unsigned long bytes_after; |
2438 | unsigned long bytes_after; |
2483 | XTextProperty ct; |
2439 | XTextProperty ct; |
2484 | int dummy_count; |
|
|
2485 | char **cl; |
|
|
2486 | |
2440 | |
2487 | D_SELECT((stderr, "rxvt_selection_paste(%08lx, %lu, %d), wait=%2x", win, (unsigned long)prop, (int)delete_prop, R->selection_wait)); |
2441 | D_SELECT((stderr, "rxvt_selection_paste(%08lx, %lu, %d), wait=%2x", win, (unsigned long)prop, (int)delete_prop, R->selection_wait)); |
2488 | |
2442 | |
2489 | if (prop == None) /* check for failed XConvertSelection */ |
2443 | if (prop == None) /* check for failed XConvertSelection */ |
2490 | { |
2444 | { |
… | |
… | |
2493 | int selnum = R->selection_type & Sel_whereMask; |
2447 | int selnum = R->selection_type & Sel_whereMask; |
2494 | |
2448 | |
2495 | R->selection_type = 0; |
2449 | R->selection_type = 0; |
2496 | if (selnum != Sel_direct) |
2450 | if (selnum != Sel_direct) |
2497 | rxvt_selection_request_other(aR_ XA_STRING, selnum); |
2451 | rxvt_selection_request_other(aR_ XA_STRING, selnum); |
|
|
2452 | } |
|
|
2453 | |
|
|
2454 | if ((R->selection_type & Sel_UTF8String)) |
|
|
2455 | { |
|
|
2456 | int selnum = R->selection_type & Sel_whereMask; |
|
|
2457 | |
|
|
2458 | R->selection_type = Sel_CompoundText; |
|
|
2459 | if (selnum != Sel_direct) |
|
|
2460 | rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], selnum); |
|
|
2461 | else |
|
|
2462 | R->selection_type = 0; |
2498 | } |
2463 | } |
2499 | |
2464 | |
2500 | return 0; |
2465 | return 0; |
2501 | } |
2466 | } |
2502 | |
2467 | |
… | |
… | |
2537 | nread = -1; /* discount any previous stuff */ |
2502 | nread = -1; /* discount any previous stuff */ |
2538 | break; |
2503 | break; |
2539 | } |
2504 | } |
2540 | |
2505 | |
2541 | nread += ct.nitems; |
2506 | nread += ct.nitems; |
|
|
2507 | |
|
|
2508 | char **cl; |
|
|
2509 | int cr; |
2542 | if (XmbTextPropertyToTextList (R->Xdisplay, &ct, &cl, |
2510 | if (XmbTextPropertyToTextList (R->Xdisplay, &ct, &cl, |
2543 | &dummy_count) == Success && cl) |
2511 | &cr) >= 0 && cl) |
2544 | { |
2512 | { |
|
|
2513 | for (int i = 0; i < cr; i++) |
2545 | R->paste ((unsigned char *)cl[0], STRLEN (cl[0])); |
2514 | R->paste ((unsigned char *)cl[i], STRLEN (cl[i])); |
|
|
2515 | |
2546 | XFreeStringList (cl); |
2516 | XFreeStringList (cl); |
2547 | } |
2517 | } |
2548 | else |
2518 | else |
2549 | R->paste (ct.value, ct.nitems); |
2519 | R->paste (ct.value, ct.nitems); |
2550 | |
2520 | |
… | |
… | |
2643 | int i; |
2613 | int i; |
2644 | |
2614 | |
2645 | R->selection_request_time = tm; |
2615 | R->selection_request_time = tm; |
2646 | R->selection_wait = Sel_normal; |
2616 | R->selection_wait = Sel_normal; |
2647 | for (i = Sel_Primary; i <= Sel_Clipboard; i++) { |
2617 | for (i = Sel_Primary; i <= Sel_Clipboard; i++) { |
|
|
2618 | #if X_HAVE_UTF8_STRING |
|
|
2619 | R->selection_type = Sel_UTF8String; |
|
|
2620 | if (rxvt_selection_request_other(aR_ R->xa[XA_UTF8_STRING], i)) |
|
|
2621 | return; |
|
|
2622 | #else |
2648 | R->selection_type = Sel_CompoundText; |
2623 | R->selection_type = Sel_CompoundText; |
2649 | if (rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], i)) |
2624 | if (rxvt_selection_request_other(aR_ R->xa[XA_COMPOUND_TEXT], i)) |
2650 | return; |
2625 | return; |
|
|
2626 | #endif |
2651 | } |
2627 | } |
2652 | } |
2628 | } |
2653 | R->selection_wait = Sel_none; /* don't loop in rxvt_selection_paste() */ |
2629 | R->selection_wait = Sel_none; /* don't loop in rxvt_selection_paste() */ |
2654 | D_SELECT((stderr, "rxvt_selection_request: pasting CUT_BUFFER0")); |
2630 | D_SELECT((stderr, "rxvt_selection_request: pasting CUT_BUFFER0")); |
2655 | rxvt_selection_paste(aR_ Xroot, XA_CUT_BUFFER0, False); |
2631 | rxvt_selection_paste(aR_ Xroot, XA_CUT_BUFFER0, False); |
… | |
… | |
2787 | { |
2763 | { |
2788 | free (new_selection_text); |
2764 | free (new_selection_text); |
2789 | return; |
2765 | return; |
2790 | } |
2766 | } |
2791 | |
2767 | |
2792 | // due to MB_MAX_CUR, selection wastage is usually high |
2768 | // due to MB_MAX_CUR, selection wastage is usually high, so realloc |
2793 | if (str - (char *)new_selection_text > 1024) |
2769 | if (str - (char *)new_selection_text > 1024) |
2794 | new_selection_text = (unsigned char *)rxvt_realloc (new_selection_text, i + 1); |
2770 | new_selection_text = (unsigned char *)rxvt_realloc (new_selection_text, i + 1); |
2795 | |
2771 | |
2796 | R->selection.len = i; |
2772 | R->selection.len = i; |
|
|
2773 | |
2797 | if (R->selection.text) |
2774 | if (R->selection.text) |
2798 | free (R->selection.text); |
2775 | free (R->selection.text); |
2799 | |
2776 | |
2800 | R->selection.text = new_selection_text; |
2777 | R->selection.text = new_selection_text; |
2801 | |
2778 | |
2802 | XSetSelectionOwner(R->Xdisplay, XA_PRIMARY, R->TermWin.vt, tm); |
2779 | XSetSelectionOwner(R->Xdisplay, XA_PRIMARY, R->TermWin.vt, tm); |
2803 | if (XGetSelectionOwner(R->Xdisplay, XA_PRIMARY) != R->TermWin.vt) |
2780 | if (XGetSelectionOwner(R->Xdisplay, XA_PRIMARY) != R->TermWin.vt) |
2804 | rxvt_print_error("can't get primary selection"); |
2781 | rxvt_print_error("can't get primary selection"); |
|
|
2782 | |
|
|
2783 | |
|
|
2784 | { |
|
|
2785 | XTextProperty ct; |
|
|
2786 | char *cl = (char *)R->selection.text; |
|
|
2787 | |
|
|
2788 | if (XmbTextListToTextProperty(R->Xdisplay, &cl, 1, XStringStyle, &ct) >= 0) |
|
|
2789 | { |
|
|
2790 | XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8, |
|
|
2791 | PropModeReplace, ct.value, ct.nitems); |
|
|
2792 | XFree (ct.value); |
|
|
2793 | } |
|
|
2794 | else |
2805 | XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8, |
2795 | XChangeProperty(R->Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8, |
2806 | PropModeReplace, R->selection.text, (int)R->selection.len); |
2796 | PropModeReplace, R->selection.text, (int)R->selection.len); |
|
|
2797 | } |
|
|
2798 | |
2807 | R->selection_time = tm; |
2799 | R->selection_time = tm; |
2808 | D_SELECT((stderr, "rxvt_selection_make(): R->selection.len=%d", R->selection.len)); |
2800 | D_SELECT((stderr, "rxvt_selection_make(): R->selection.len=%d", R->selection.len)); |
2809 | } |
2801 | } |
2810 | |
2802 | |
2811 | /* ------------------------------------------------------------------------- */ |
2803 | /* ------------------------------------------------------------------------- */ |
… | |
… | |
3263 | /* |
3255 | /* |
3264 | * On some systems, the Atom typedef is 64 bits wide. We need to have a type |
3256 | * On some systems, the Atom typedef is 64 bits wide. We need to have a type |
3265 | * that is exactly 32 bits wide, because a format of 64 is not allowed by |
3257 | * that is exactly 32 bits wide, because a format of 64 is not allowed by |
3266 | * the X11 protocol. |
3258 | * the X11 protocol. |
3267 | */ |
3259 | */ |
3268 | typedef CARD32 Atom32; |
3260 | typedef CARD32 Atom32; |
3269 | |
3261 | |
3270 | /* ------------------------------------------------------------------------- */ |
3262 | /* ------------------------------------------------------------------------- */ |
3271 | /* |
3263 | /* |
3272 | * Respond to a request for our current selection |
3264 | * Respond to a request for our current selection |
3273 | * EXT: SelectionRequest |
3265 | * EXT: SelectionRequest |
… | |
… | |
3275 | /* EXTPROTO */ |
3267 | /* EXTPROTO */ |
3276 | void |
3268 | void |
3277 | rxvt_selection_send(pR_ const XSelectionRequestEvent *rq) |
3269 | rxvt_selection_send(pR_ const XSelectionRequestEvent *rq) |
3278 | { |
3270 | { |
3279 | XSelectionEvent ev; |
3271 | XSelectionEvent ev; |
3280 | #ifdef USE_XIM |
|
|
3281 | Atom32 target_list[4]; |
|
|
3282 | #else |
|
|
3283 | Atom32 target_list[3]; |
|
|
3284 | #endif |
|
|
3285 | Atom target; |
|
|
3286 | XTextProperty ct; |
3272 | XTextProperty ct; |
3287 | XICCEncodingStyle style; |
3273 | XICCEncodingStyle style; |
3288 | char *cl[2], dummy[1]; |
3274 | Atom target; |
3289 | |
3275 | |
3290 | ev.type = SelectionNotify; |
3276 | ev.type = SelectionNotify; |
3291 | ev.property = None; |
3277 | ev.property = None; |
3292 | ev.display = rq->display; |
3278 | ev.display = rq->display; |
3293 | ev.requestor = rq->requestor; |
3279 | ev.requestor = rq->requestor; |
3294 | ev.selection = rq->selection; |
3280 | ev.selection = rq->selection; |
3295 | ev.target = rq->target; |
3281 | ev.target = rq->target; |
3296 | ev.time = rq->time; |
3282 | ev.time = rq->time; |
3297 | |
3283 | |
3298 | if (rq->target == R->xa[XA_TARGETS]) { |
3284 | if (rq->target == R->xa[XA_TARGETS]) { |
|
|
3285 | Atom32 target_list[5]; |
|
|
3286 | Atom32 *target = target_list; |
|
|
3287 | |
3299 | target_list[0] = (Atom32) R->xa[XA_TARGETS]; |
3288 | *target++ = (Atom32) R->xa[XA_TARGETS]; |
3300 | target_list[1] = (Atom32) XA_STRING; |
3289 | *target++ = (Atom32) XA_STRING; |
3301 | target_list[2] = (Atom32) R->xa[XA_TEXT]; |
3290 | *target++ = (Atom32) R->xa[XA_TEXT]; |
3302 | #ifdef USE_XIM |
|
|
3303 | target_list[3] = (Atom32) R->xa[XA_COMPOUND_TEXT]; |
3291 | *target++ = (Atom32) R->xa[XA_COMPOUND_TEXT]; |
|
|
3292 | #if X_HAVE_UTF8_STRING |
|
|
3293 | *target++ = (Atom32) R->xa[XA_UTF8_STRING]; |
3304 | #endif |
3294 | #endif |
3305 | XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_ATOM, |
3295 | XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_ATOM, |
3306 | (8 * sizeof(target_list[0])), PropModeReplace, |
3296 | (8 * sizeof(target_list[0])), PropModeReplace, |
3307 | (unsigned char *)target_list, |
3297 | (unsigned char *)target_list, |
3308 | (sizeof(target_list) / sizeof(target_list[0]))); |
3298 | target - target_list); |
3309 | ev.property = rq->property; |
3299 | ev.property = rq->property; |
3310 | } else if (rq->target == R->xa[XA_MULTIPLE]) { |
3300 | } else if (rq->target == R->xa[XA_MULTIPLE]) { |
3311 | /* TODO: Handle MULTIPLE */ |
3301 | /* TODO: Handle MULTIPLE */ |
3312 | } else if (rq->target == R->xa[XA_TIMESTAMP] && R->selection.text) { |
3302 | } else if (rq->target == R->xa[XA_TIMESTAMP] && R->selection.text) { |
3313 | XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_INTEGER, |
3303 | XChangeProperty(R->Xdisplay, rq->requestor, rq->property, XA_INTEGER, |
3314 | (8 * sizeof(Time)), PropModeReplace, |
3304 | (8 * sizeof(Time)), PropModeReplace, |
3315 | (unsigned char *)&R->selection_time, 1); |
3305 | (unsigned char *)&R->selection_time, 1); |
3316 | ev.property = rq->property; |
3306 | ev.property = rq->property; |
3317 | } else if (rq->target == XA_STRING |
3307 | } else if (rq->target == XA_STRING |
|
|
3308 | || rq->target == R->xa[XA_TEXT] |
3318 | || rq->target == R->xa[XA_COMPOUND_TEXT] |
3309 | || rq->target == R->xa[XA_COMPOUND_TEXT] |
3319 | || rq->target == R->xa[XA_TEXT]) { |
3310 | || rq->target == R->xa[XA_UTF8_STRING] |
3320 | #ifdef USE_XIM |
3311 | ) { |
3321 | short freect = 0; |
3312 | short freect = 0; |
3322 | #endif |
|
|
3323 | int selectlen; |
3313 | int selectlen; |
|
|
3314 | char *cl; |
3324 | |
3315 | |
3325 | #ifdef USE_XIM |
3316 | target = rq->target; |
|
|
3317 | |
3326 | if (rq->target != XA_STRING) { |
3318 | if (target == XA_STRING) |
|
|
3319 | // we actually don't do XA_STRING, but who cares, as i18n clients |
|
|
3320 | // will ask for another format anyways. |
|
|
3321 | style = XStringStyle; |
|
|
3322 | else if (target == R->xa[XA_TEXT]) |
|
|
3323 | style = XTextStyle; |
|
|
3324 | else if (target == R->xa[XA_COMPOUND_TEXT]) |
|
|
3325 | style = XCompoundTextStyle; |
|
|
3326 | #if X_HAVE_UTF8_STRING |
|
|
3327 | else if (target == R->xa[XA_UTF8_STRING]) |
|
|
3328 | style = XUTF8StringStyle; |
|
|
3329 | #endif |
|
|
3330 | else |
|
|
3331 | { |
3327 | target = R->xa[XA_COMPOUND_TEXT]; |
3332 | target = R->xa[XA_COMPOUND_TEXT]; |
3328 | style = (rq->target == R->xa[XA_COMPOUND_TEXT]) |
|
|
3329 | ? XCompoundTextStyle : XStdICCTextStyle; |
|
|
3330 | } else |
|
|
3331 | #endif |
|
|
3332 | { |
|
|
3333 | target = XA_STRING; |
|
|
3334 | style = XStringStyle; |
3333 | style = XCompoundTextStyle; |
3335 | } |
3334 | } |
|
|
3335 | |
3336 | if (R->selection.text) { |
3336 | if (R->selection.text) { |
3337 | cl[0] = (char *)R->selection.text; |
3337 | cl = (char *)R->selection.text; |
3338 | selectlen = R->selection.len; |
3338 | selectlen = R->selection.len; |
3339 | } else { |
3339 | } else { |
3340 | cl[0] = dummy; |
3340 | cl = ""; |
3341 | *dummy = '\0'; |
|
|
3342 | selectlen = 0; |
3341 | selectlen = 0; |
3343 | } |
3342 | } |
3344 | #ifdef USE_XIM |
3343 | |
3345 | if (XmbTextListToTextProperty(R->Xdisplay, cl, 1, style, &ct) |
3344 | if (XmbTextListToTextProperty(R->Xdisplay, &cl, 1, style, &ct) >= 0) |
3346 | == Success) /* if we failed to convert then send it raw */ |
|
|
3347 | freect = 1; |
3345 | freect = 1; |
3348 | else |
3346 | else |
3349 | #endif |
|
|
3350 | { |
3347 | { |
|
|
3348 | /* if we failed to convert then send it raw */ |
3351 | ct.value = (unsigned char *)cl[0]; |
3349 | ct.value = (unsigned char *)cl; |
3352 | ct.nitems = selectlen; |
3350 | ct.nitems = selectlen; |
3353 | } |
3351 | } |
|
|
3352 | |
3354 | XChangeProperty(R->Xdisplay, rq->requestor, rq->property, |
3353 | XChangeProperty(R->Xdisplay, rq->requestor, rq->property, |
3355 | target, 8, PropModeReplace, |
3354 | target, 8, PropModeReplace, |
3356 | ct.value, (int)ct.nitems); |
3355 | ct.value, (int)ct.nitems); |
3357 | ev.property = rq->property; |
3356 | ev.property = rq->property; |
3358 | #ifdef USE_XIM |
3357 | |
3359 | if (freect) |
3358 | if (freect) |
3360 | XFree(ct.value); |
3359 | XFree (ct.value); |
3361 | #endif |
|
|
3362 | } |
3360 | } |
3363 | XSendEvent(R->Xdisplay, rq->requestor, False, 0L, (XEvent *)&ev); |
3361 | XSendEvent(R->Xdisplay, rq->requestor, False, 0L, (XEvent *)&ev); |
3364 | } |
3362 | } |
3365 | |
3363 | |
3366 | /* ------------------------------------------------------------------------- * |
3364 | /* ------------------------------------------------------------------------- * |