diff options
| author | Miles Bader | 2005-02-13 07:19:08 +0000 |
|---|---|---|
| committer | Miles Bader | 2005-02-13 07:19:08 +0000 |
| commit | dd75f82d04b1c7fb91fd3024021a3d7977154857 (patch) | |
| tree | 456488f67c9de7fec805140f39993e1e3bebac8f /src/xselect.c | |
| parent | 3807ffd05dc6b10cef9066b4d3b49b24788313a9 (diff) | |
| parent | 9b981cb6861358a05a241509d73f2b8ea25c64ce (diff) | |
| download | emacs-dd75f82d04b1c7fb91fd3024021a3d7977154857.tar.gz emacs-dd75f82d04b1c7fb91fd3024021a3d7977154857.zip | |
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-13
Merge from emacs--cvs-trunk--0
Patches applied:
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-83
- miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-89
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-90
Update from CVS: man/calc.texi: Add macro for LaTeX for info output.
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-91
- miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-94
Update from CVS
Diffstat (limited to 'src/xselect.c')
| -rw-r--r-- | src/xselect.c | 151 |
1 files changed, 91 insertions, 60 deletions
diff --git a/src/xselect.c b/src/xselect.c index daae84b276c..bf37cde4d0b 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -173,12 +173,6 @@ static Lisp_Object Vselection_converter_alist; | |||
| 173 | /* If the selection owner takes too long to reply to a selection request, | 173 | /* If the selection owner takes too long to reply to a selection request, |
| 174 | we give up on it. This is in milliseconds (0 = no timeout.) */ | 174 | we give up on it. This is in milliseconds (0 = no timeout.) */ |
| 175 | static EMACS_INT x_selection_timeout; | 175 | static EMACS_INT x_selection_timeout; |
| 176 | |||
| 177 | /* Utility functions */ | ||
| 178 | |||
| 179 | static void lisp_data_to_selection_data (); | ||
| 180 | static Lisp_Object selection_data_to_lisp_data (); | ||
| 181 | static Lisp_Object x_get_window_property_as_lisp_data (); | ||
| 182 | 176 | ||
| 183 | 177 | ||
| 184 | 178 | ||
| @@ -769,9 +763,17 @@ x_reply_selection_request (event, format, data, size, type) | |||
| 769 | 763 | ||
| 770 | TRACE1 ("Set %s to number of bytes to send", | 764 | TRACE1 ("Set %s to number of bytes to send", |
| 771 | XGetAtomName (display, reply.property)); | 765 | XGetAtomName (display, reply.property)); |
| 772 | XChangeProperty (display, window, reply.property, dpyinfo->Xatom_INCR, | 766 | { |
| 773 | 32, PropModeReplace, | 767 | /* XChangeProperty expects an array of long even if long is more than |
| 774 | (unsigned char *) &bytes_remaining, 1); | 768 | 32 bits. */ |
| 769 | long value[1]; | ||
| 770 | |||
| 771 | value[0] = bytes_remaining; | ||
| 772 | XChangeProperty (display, window, reply.property, dpyinfo->Xatom_INCR, | ||
| 773 | 32, PropModeReplace, | ||
| 774 | (unsigned char *) value, 1); | ||
| 775 | } | ||
| 776 | |||
| 775 | XSelectInput (display, window, PropertyChangeMask); | 777 | XSelectInput (display, window, PropertyChangeMask); |
| 776 | 778 | ||
| 777 | /* Tell 'em the INCR data is there... */ | 779 | /* Tell 'em the INCR data is there... */ |
| @@ -796,9 +798,9 @@ x_reply_selection_request (event, format, data, size, type) | |||
| 796 | TRACE0 ("Got ACK"); | 798 | TRACE0 ("Got ACK"); |
| 797 | while (bytes_remaining) | 799 | while (bytes_remaining) |
| 798 | { | 800 | { |
| 799 | int i = ((bytes_remaining < max_bytes) | 801 | int i = ((bytes_remaining < max_bytes) |
| 800 | ? bytes_remaining | 802 | ? bytes_remaining |
| 801 | : max_bytes); | 803 | : max_bytes); |
| 802 | 804 | ||
| 803 | BLOCK_INPUT; | 805 | BLOCK_INPUT; |
| 804 | 806 | ||
| @@ -1523,9 +1525,38 @@ x_get_window_property (display, window, property, data_ret, bytes_ret, | |||
| 1523 | reading it. Deal with that, I guess.... */ | 1525 | reading it. Deal with that, I guess.... */ |
| 1524 | if (result != Success) | 1526 | if (result != Success) |
| 1525 | break; | 1527 | break; |
| 1526 | *actual_size_ret *= *actual_format_ret / 8; | 1528 | |
| 1527 | bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret); | 1529 | /* The man page for XGetWindowProperty says: |
| 1528 | offset += *actual_size_ret; | 1530 | "If the returned format is 32, the returned data is represented |
| 1531 | as a long array and should be cast to that type to obtain the | ||
| 1532 | elements." | ||
| 1533 | This applies even if long is more than 32 bits, the X library | ||
| 1534 | converts from 32 bit elements received from the X server to long | ||
| 1535 | and passes the long array to us. Thus, for that case bcopy can not | ||
| 1536 | be used. We convert to a 32 bit type here, because so much code | ||
| 1537 | assume on that. | ||
| 1538 | |||
| 1539 | The bytes and offsets passed to XGetWindowProperty refers to the | ||
| 1540 | property and those are indeed in 32 bit quantities if format is 32. */ | ||
| 1541 | |||
| 1542 | if (*actual_format_ret == 32 && *actual_format_ret < BITS_PER_LONG) | ||
| 1543 | { | ||
| 1544 | unsigned long i; | ||
| 1545 | int *idata = (int *) ((*data_ret) + offset); | ||
| 1546 | long *ldata = (long *) tmp_data; | ||
| 1547 | |||
| 1548 | for (i = 0; i < *actual_size_ret; ++i) | ||
| 1549 | { | ||
| 1550 | idata[i]= (int) ldata[i]; | ||
| 1551 | offset += 4; | ||
| 1552 | } | ||
| 1553 | } | ||
| 1554 | else | ||
| 1555 | { | ||
| 1556 | *actual_size_ret *= *actual_format_ret / 8; | ||
| 1557 | bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret); | ||
| 1558 | offset += *actual_size_ret; | ||
| 1559 | } | ||
| 1529 | 1560 | ||
| 1530 | /* This was allocated by Xlib, so use XFree. */ | 1561 | /* This was allocated by Xlib, so use XFree. */ |
| 1531 | XFree ((char *) tmp_data); | 1562 | XFree ((char *) tmp_data); |
| @@ -1738,7 +1769,11 @@ x_get_window_property_as_lisp_data (display, window, property, target_type, | |||
| 1738 | 1769 | ||
| 1739 | When converting an object to C, it may be of the form (SYMBOL . <data>) | 1770 | When converting an object to C, it may be of the form (SYMBOL . <data>) |
| 1740 | where SYMBOL is what we should claim that the type is. Format and | 1771 | where SYMBOL is what we should claim that the type is. Format and |
| 1741 | representation are as above. */ | 1772 | representation are as above. |
| 1773 | |||
| 1774 | Important: When format is 32, data should contain an array of int, | ||
| 1775 | not an array of long as the X library returns. This makes a difference | ||
| 1776 | when sizeof(long) != sizeof(int). */ | ||
| 1742 | 1777 | ||
| 1743 | 1778 | ||
| 1744 | 1779 | ||
| @@ -1780,15 +1815,21 @@ selection_data_to_lisp_data (display, data, size, type, format) | |||
| 1780 | else if (type == XA_ATOM) | 1815 | else if (type == XA_ATOM) |
| 1781 | { | 1816 | { |
| 1782 | int i; | 1817 | int i; |
| 1783 | if (size == sizeof (Atom)) | 1818 | /* On a 64 bit machine sizeof(Atom) == sizeof(long) == 8. |
| 1784 | return x_atom_to_symbol (display, *((Atom *) data)); | 1819 | But the callers of these function has made sure the data for |
| 1820 | format == 32 is an array of int. Thus, use int instead | ||
| 1821 | of Atom. */ | ||
| 1822 | int *idata = (int *) data; | ||
| 1823 | |||
| 1824 | if (size == sizeof (int)) | ||
| 1825 | return x_atom_to_symbol (display, (Atom) idata[0]); | ||
| 1785 | else | 1826 | else |
| 1786 | { | 1827 | { |
| 1787 | Lisp_Object v = Fmake_vector (make_number (size / sizeof (Atom)), | 1828 | Lisp_Object v = Fmake_vector (make_number (size / sizeof (int)), |
| 1788 | make_number (0)); | 1829 | make_number (0)); |
| 1789 | for (i = 0; i < size / sizeof (Atom); i++) | 1830 | for (i = 0; i < size / sizeof (int); i++) |
| 1790 | Faset (v, make_number (i), | 1831 | Faset (v, make_number (i), |
| 1791 | x_atom_to_symbol (display, ((Atom *) data) [i])); | 1832 | x_atom_to_symbol (display, (Atom) idata[i])); |
| 1792 | return v; | 1833 | return v; |
| 1793 | } | 1834 | } |
| 1794 | } | 1835 | } |
| @@ -1970,6 +2011,7 @@ lisp_data_to_selection_data (display, obj, | |||
| 1970 | else | 2011 | else |
| 1971 | /* This vector is an INTEGER set, or something like it */ | 2012 | /* This vector is an INTEGER set, or something like it */ |
| 1972 | { | 2013 | { |
| 2014 | int data_size = 2; | ||
| 1973 | *size_ret = XVECTOR (obj)->size; | 2015 | *size_ret = XVECTOR (obj)->size; |
| 1974 | if (NILP (type)) type = QINTEGER; | 2016 | if (NILP (type)) type = QINTEGER; |
| 1975 | *format_ret = 16; | 2017 | *format_ret = 16; |
| @@ -1982,7 +2024,11 @@ lisp_data_to_selection_data (display, obj, | |||
| 1982 | ("elements of selection vector must be integers or conses of integers"), | 2024 | ("elements of selection vector must be integers or conses of integers"), |
| 1983 | Fcons (obj, Qnil))); | 2025 | Fcons (obj, Qnil))); |
| 1984 | 2026 | ||
| 1985 | *data_ret = (unsigned char *) xmalloc (*size_ret * (*format_ret/8)); | 2027 | /* Use sizeof(long) even if it is more than 32 bits. See comment |
| 2028 | in x_get_window_property and x_fill_property_data. */ | ||
| 2029 | |||
| 2030 | if (*format_ret == 32) data_size = sizeof(long); | ||
| 2031 | *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); | ||
| 1986 | for (i = 0; i < *size_ret; i++) | 2032 | for (i = 0; i < *size_ret; i++) |
| 1987 | if (*format_ret == 32) | 2033 | if (*format_ret == 32) |
| 1988 | (*((unsigned long **) data_ret)) [i] | 2034 | (*((unsigned long **) data_ret)) [i] |
| @@ -2469,8 +2515,10 @@ x_check_property_data (data) | |||
| 2469 | DATA is a Lisp list of values to be converted. | 2515 | DATA is a Lisp list of values to be converted. |
| 2470 | RET is the C array that contains the converted values. It is assumed | 2516 | RET is the C array that contains the converted values. It is assumed |
| 2471 | it is big enough to hold all values. | 2517 | it is big enough to hold all values. |
| 2472 | FORMAT is 8, 16 or 32 and gives the size in bits for each C value to | 2518 | FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to |
| 2473 | be stored in RET. */ | 2519 | be stored in RET. Note that long is used for 32 even if long is more |
| 2520 | than 32 bits (see man pages for XChangeProperty, XGetWindowProperty and | ||
| 2521 | XClientMessageEvent). */ | ||
| 2474 | 2522 | ||
| 2475 | void | 2523 | void |
| 2476 | x_fill_property_data (dpy, data, ret, format) | 2524 | x_fill_property_data (dpy, data, ret, format) |
| @@ -2479,10 +2527,10 @@ x_fill_property_data (dpy, data, ret, format) | |||
| 2479 | void *ret; | 2527 | void *ret; |
| 2480 | int format; | 2528 | int format; |
| 2481 | { | 2529 | { |
| 2482 | CARD32 val; | 2530 | long val; |
| 2483 | CARD32 *d32 = (CARD32 *) ret; | 2531 | long *d32 = (long *) ret; |
| 2484 | CARD16 *d16 = (CARD16 *) ret; | 2532 | short *d16 = (short *) ret; |
| 2485 | CARD8 *d08 = (CARD8 *) ret; | 2533 | char *d08 = (char *) ret; |
| 2486 | Lisp_Object iter; | 2534 | Lisp_Object iter; |
| 2487 | 2535 | ||
| 2488 | for (iter = data; CONSP (iter); iter = XCDR (iter)) | 2536 | for (iter = data; CONSP (iter); iter = XCDR (iter)) |
| @@ -2490,24 +2538,24 @@ x_fill_property_data (dpy, data, ret, format) | |||
| 2490 | Lisp_Object o = XCAR (iter); | 2538 | Lisp_Object o = XCAR (iter); |
| 2491 | 2539 | ||
| 2492 | if (INTEGERP (o)) | 2540 | if (INTEGERP (o)) |
| 2493 | val = (CARD32) XFASTINT (o); | 2541 | val = (long) XFASTINT (o); |
| 2494 | else if (FLOATP (o)) | 2542 | else if (FLOATP (o)) |
| 2495 | val = (CARD32) XFLOAT_DATA (o); | 2543 | val = (long) XFLOAT_DATA (o); |
| 2496 | else if (CONSP (o)) | 2544 | else if (CONSP (o)) |
| 2497 | val = (CARD32) cons_to_long (o); | 2545 | val = (long) cons_to_long (o); |
| 2498 | else if (STRINGP (o)) | 2546 | else if (STRINGP (o)) |
| 2499 | { | 2547 | { |
| 2500 | BLOCK_INPUT; | 2548 | BLOCK_INPUT; |
| 2501 | val = XInternAtom (dpy, (char *) SDATA (o), False); | 2549 | val = (long) XInternAtom (dpy, (char *) SDATA (o), False); |
| 2502 | UNBLOCK_INPUT; | 2550 | UNBLOCK_INPUT; |
| 2503 | } | 2551 | } |
| 2504 | else | 2552 | else |
| 2505 | error ("Wrong type, must be string, number or cons"); | 2553 | error ("Wrong type, must be string, number or cons"); |
| 2506 | 2554 | ||
| 2507 | if (format == 8) | 2555 | if (format == 8) |
| 2508 | *d08++ = (CARD8) val; | 2556 | *d08++ = (char) val; |
| 2509 | else if (format == 16) | 2557 | else if (format == 16) |
| 2510 | *d16++ = (CARD16) val; | 2558 | *d16++ = (short) val; |
| 2511 | else | 2559 | else |
| 2512 | *d32++ = val; | 2560 | *d32++ = val; |
| 2513 | } | 2561 | } |
| @@ -2522,6 +2570,10 @@ x_fill_property_data (dpy, data, ret, format) | |||
| 2522 | be stored in RET. | 2570 | be stored in RET. |
| 2523 | SIZE is the number of elements in DATA. | 2571 | SIZE is the number of elements in DATA. |
| 2524 | 2572 | ||
| 2573 | Important: When format is 32, data should contain an array of int, | ||
| 2574 | not an array of long as the X library returns. This makes a difference | ||
| 2575 | when sizeof(long) != sizeof(int). | ||
| 2576 | |||
| 2525 | Also see comment for selection_data_to_lisp_data above. */ | 2577 | Also see comment for selection_data_to_lisp_data above. */ |
| 2526 | 2578 | ||
| 2527 | Lisp_Object | 2579 | Lisp_Object |
| @@ -2633,7 +2685,8 @@ x_handle_dnd_message (f, event, dpyinfo, bufp) | |||
| 2633 | { | 2685 | { |
| 2634 | Lisp_Object vec; | 2686 | Lisp_Object vec; |
| 2635 | Lisp_Object frame; | 2687 | Lisp_Object frame; |
| 2636 | unsigned long size = (8*sizeof (event->data))/event->format; | 2688 | /* format 32 => size 5, format 16 => size 10, format 8 => size 20 */ |
| 2689 | unsigned long size = 160/event->format; | ||
| 2637 | int x, y; | 2690 | int x, y; |
| 2638 | unsigned char *data = (unsigned char *) event->data.b; | 2691 | unsigned char *data = (unsigned char *) event->data.b; |
| 2639 | int idata[5]; | 2692 | int idata[5]; |
| @@ -2712,8 +2765,6 @@ are ignored. */) | |||
| 2712 | struct frame *f = check_x_frame (from); | 2765 | struct frame *f = check_x_frame (from); |
| 2713 | int count; | 2766 | int count; |
| 2714 | int to_root; | 2767 | int to_root; |
| 2715 | int idata[5]; | ||
| 2716 | void *data; | ||
| 2717 | 2768 | ||
| 2718 | CHECK_STRING (message_type); | 2769 | CHECK_STRING (message_type); |
| 2719 | CHECK_NUMBER (format); | 2770 | CHECK_NUMBER (format); |
| @@ -2774,30 +2825,10 @@ are ignored. */) | |||
| 2774 | event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; | 2825 | event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; |
| 2775 | 2826 | ||
| 2776 | 2827 | ||
| 2777 | if (event.xclient.format == 32 && event.xclient.format < BITS_PER_LONG) | 2828 | memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); |
| 2778 | { | 2829 | x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, |
| 2779 | /* x_fill_property_data expects data to hold 32 bit values when | 2830 | event.xclient.format); |
| 2780 | format == 32, but on a 64 bit machine long is 64 bits. | ||
| 2781 | event.xclient.l is an array of long, so we must compensate. */ | ||
| 2782 | |||
| 2783 | memset (idata, 0, sizeof (idata)); | ||
| 2784 | data = idata; | ||
| 2785 | } | ||
| 2786 | else | ||
| 2787 | { | ||
| 2788 | memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); | ||
| 2789 | data = event.xclient.data.b; | ||
| 2790 | } | ||
| 2791 | |||
| 2792 | x_fill_property_data (dpyinfo->display, values, data, event.xclient.format); | ||
| 2793 | 2831 | ||
| 2794 | if (data == idata) | ||
| 2795 | { | ||
| 2796 | int i; | ||
| 2797 | for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */ | ||
| 2798 | event.xclient.data.l[i] = (long) idata[i]; | ||
| 2799 | } | ||
| 2800 | |||
| 2801 | /* If event mask is 0 the event is sent to the client that created | 2832 | /* If event mask is 0 the event is sent to the client that created |
| 2802 | the destination window. But if we are sending to the root window, | 2833 | the destination window. But if we are sending to the root window, |
| 2803 | there is no such client. Then we set the event mask to 0xffff. The | 2834 | there is no such client. Then we set the event mask to 0xffff. The |