diff options
| author | Karoly Lorentey | 2005-02-10 20:43:55 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2005-02-10 20:43:55 +0000 |
| commit | bdfec2134d38a605c95baab0e38ef321a6b1d59e (patch) | |
| tree | f2c616c523590a8a8f294ea3c6258d72f5de86a1 /src/xselect.c | |
| parent | fc8bcb58bc6e96beed7ad20bae40d28d3d2ea058 (diff) | |
| parent | d25e21dddcd4df58a4029f106ad7eea82c5726dd (diff) | |
| download | emacs-bdfec2134d38a605c95baab0e38ef321a6b1d59e.tar.gz emacs-bdfec2134d38a605c95baab0e38ef321a6b1d59e.zip | |
Merged from miles@gnu.org--gnu-2005 (patch 12-13, 79-90)
Patches applied:
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-79
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-80
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-81
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-82
Merge from gnus--rel--5.10
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-83
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-84
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-85
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-86
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-87
Update from CVS
* miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-88
Update from CVS
* 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/gnus--rel--5.10--patch-12
Merge from emacs--cvs-trunk--0
* miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-13
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-290
Diffstat (limited to 'src/xselect.c')
| -rw-r--r-- | src/xselect.c | 143 |
1 files changed, 106 insertions, 37 deletions
diff --git a/src/xselect.c b/src/xselect.c index f26014746ba..adea1f3c2d6 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 | ||
| @@ -777,9 +771,17 @@ x_reply_selection_request (event, format, data, size, type) | |||
| 777 | 771 | ||
| 778 | TRACE1 ("Set %s to number of bytes to send", | 772 | TRACE1 ("Set %s to number of bytes to send", |
| 779 | XGetAtomName (display, reply.property)); | 773 | XGetAtomName (display, reply.property)); |
| 780 | XChangeProperty (display, window, reply.property, dpyinfo->Xatom_INCR, | 774 | { |
| 781 | 32, PropModeReplace, | 775 | /* XChangeProperty expects an array of long even if long is more than |
| 782 | (unsigned char *) &bytes_remaining, 1); | 776 | 32 bits. */ |
| 777 | long value[1]; | ||
| 778 | |||
| 779 | value[0] = bytes_remaining; | ||
| 780 | XChangeProperty (display, window, reply.property, dpyinfo->Xatom_INCR, | ||
| 781 | 32, PropModeReplace, | ||
| 782 | (unsigned char *) value, 1); | ||
| 783 | } | ||
| 784 | |||
| 783 | XSelectInput (display, window, PropertyChangeMask); | 785 | XSelectInput (display, window, PropertyChangeMask); |
| 784 | 786 | ||
| 785 | /* Tell 'em the INCR data is there... */ | 787 | /* Tell 'em the INCR data is there... */ |
| @@ -804,9 +806,9 @@ x_reply_selection_request (event, format, data, size, type) | |||
| 804 | TRACE0 ("Got ACK"); | 806 | TRACE0 ("Got ACK"); |
| 805 | while (bytes_remaining) | 807 | while (bytes_remaining) |
| 806 | { | 808 | { |
| 807 | int i = ((bytes_remaining < max_bytes) | 809 | int i = ((bytes_remaining < max_bytes) |
| 808 | ? bytes_remaining | 810 | ? bytes_remaining |
| 809 | : max_bytes); | 811 | : max_bytes); |
| 810 | 812 | ||
| 811 | BLOCK_INPUT; | 813 | BLOCK_INPUT; |
| 812 | 814 | ||
| @@ -1540,9 +1542,38 @@ x_get_window_property (display, window, property, data_ret, bytes_ret, | |||
| 1540 | reading it. Deal with that, I guess.... */ | 1542 | reading it. Deal with that, I guess.... */ |
| 1541 | if (result != Success) | 1543 | if (result != Success) |
| 1542 | break; | 1544 | break; |
| 1543 | *actual_size_ret *= *actual_format_ret / 8; | 1545 | |
| 1544 | bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret); | 1546 | /* The man page for XGetWindowProperty says: |
| 1545 | offset += *actual_size_ret; | 1547 | "If the returned format is 32, the returned data is represented |
| 1548 | as a long array and should be cast to that type to obtain the | ||
| 1549 | elements." | ||
| 1550 | This applies even if long is more than 32 bits, the X library | ||
| 1551 | converts from 32 bit elements received from the X server to long | ||
| 1552 | and passes the long array to us. Thus, for that case bcopy can not | ||
| 1553 | be used. We convert to a 32 bit type here, because so much code | ||
| 1554 | assume on that. | ||
| 1555 | |||
| 1556 | The bytes and offsets passed to XGetWindowProperty refers to the | ||
| 1557 | property and those are indeed in 32 bit quantities if format is 32. */ | ||
| 1558 | |||
| 1559 | if (*actual_format_ret == 32 && *actual_format_ret < BITS_PER_LONG) | ||
| 1560 | { | ||
| 1561 | unsigned long i; | ||
| 1562 | int *idata = (int *) ((*data_ret) + offset); | ||
| 1563 | long *ldata = (long *) tmp_data; | ||
| 1564 | |||
| 1565 | for (i = 0; i < *actual_size_ret; ++i) | ||
| 1566 | { | ||
| 1567 | idata[i]= (int) ldata[i]; | ||
| 1568 | offset += 4; | ||
| 1569 | } | ||
| 1570 | } | ||
| 1571 | else | ||
| 1572 | { | ||
| 1573 | *actual_size_ret *= *actual_format_ret / 8; | ||
| 1574 | bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret); | ||
| 1575 | offset += *actual_size_ret; | ||
| 1576 | } | ||
| 1546 | 1577 | ||
| 1547 | /* This was allocated by Xlib, so use XFree. */ | 1578 | /* This was allocated by Xlib, so use XFree. */ |
| 1548 | XFree ((char *) tmp_data); | 1579 | XFree ((char *) tmp_data); |
| @@ -1755,7 +1786,11 @@ x_get_window_property_as_lisp_data (display, window, property, target_type, | |||
| 1755 | 1786 | ||
| 1756 | When converting an object to C, it may be of the form (SYMBOL . <data>) | 1787 | When converting an object to C, it may be of the form (SYMBOL . <data>) |
| 1757 | where SYMBOL is what we should claim that the type is. Format and | 1788 | where SYMBOL is what we should claim that the type is. Format and |
| 1758 | representation are as above. */ | 1789 | representation are as above. |
| 1790 | |||
| 1791 | Important: When format is 32, data should contain an array of int, | ||
| 1792 | not an array of long as the X library returns. This makes a difference | ||
| 1793 | when sizeof(long) != sizeof(int). */ | ||
| 1759 | 1794 | ||
| 1760 | 1795 | ||
| 1761 | 1796 | ||
| @@ -1797,15 +1832,21 @@ selection_data_to_lisp_data (display, data, size, type, format) | |||
| 1797 | else if (type == XA_ATOM) | 1832 | else if (type == XA_ATOM) |
| 1798 | { | 1833 | { |
| 1799 | int i; | 1834 | int i; |
| 1800 | if (size == sizeof (Atom)) | 1835 | /* On a 64 bit machine sizeof(Atom) == sizeof(long) == 8. |
| 1801 | return x_atom_to_symbol (display, *((Atom *) data)); | 1836 | But the callers of these function has made sure the data for |
| 1837 | format == 32 is an array of int. Thus, use int instead | ||
| 1838 | of Atom. */ | ||
| 1839 | int *idata = (int *) data; | ||
| 1840 | |||
| 1841 | if (size == sizeof (int)) | ||
| 1842 | return x_atom_to_symbol (display, (Atom) idata[0]); | ||
| 1802 | else | 1843 | else |
| 1803 | { | 1844 | { |
| 1804 | Lisp_Object v = Fmake_vector (make_number (size / sizeof (Atom)), | 1845 | Lisp_Object v = Fmake_vector (make_number (size / sizeof (int)), |
| 1805 | make_number (0)); | 1846 | make_number (0)); |
| 1806 | for (i = 0; i < size / sizeof (Atom); i++) | 1847 | for (i = 0; i < size / sizeof (int); i++) |
| 1807 | Faset (v, make_number (i), | 1848 | Faset (v, make_number (i), |
| 1808 | x_atom_to_symbol (display, ((Atom *) data) [i])); | 1849 | x_atom_to_symbol (display, (Atom) idata[i])); |
| 1809 | return v; | 1850 | return v; |
| 1810 | } | 1851 | } |
| 1811 | } | 1852 | } |
| @@ -1987,6 +2028,7 @@ lisp_data_to_selection_data (display, obj, | |||
| 1987 | else | 2028 | else |
| 1988 | /* This vector is an INTEGER set, or something like it */ | 2029 | /* This vector is an INTEGER set, or something like it */ |
| 1989 | { | 2030 | { |
| 2031 | int data_size = 2; | ||
| 1990 | *size_ret = XVECTOR (obj)->size; | 2032 | *size_ret = XVECTOR (obj)->size; |
| 1991 | if (NILP (type)) type = QINTEGER; | 2033 | if (NILP (type)) type = QINTEGER; |
| 1992 | *format_ret = 16; | 2034 | *format_ret = 16; |
| @@ -1999,7 +2041,11 @@ lisp_data_to_selection_data (display, obj, | |||
| 1999 | ("elements of selection vector must be integers or conses of integers"), | 2041 | ("elements of selection vector must be integers or conses of integers"), |
| 2000 | Fcons (obj, Qnil))); | 2042 | Fcons (obj, Qnil))); |
| 2001 | 2043 | ||
| 2002 | *data_ret = (unsigned char *) xmalloc (*size_ret * (*format_ret/8)); | 2044 | /* Use sizeof(long) even if it is more than 32 bits. See comment |
| 2045 | in x_get_window_property and x_fill_property_data. */ | ||
| 2046 | |||
| 2047 | if (*format_ret == 32) data_size = sizeof(long); | ||
| 2048 | *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); | ||
| 2003 | for (i = 0; i < *size_ret; i++) | 2049 | for (i = 0; i < *size_ret; i++) |
| 2004 | if (*format_ret == 32) | 2050 | if (*format_ret == 32) |
| 2005 | (*((unsigned long **) data_ret)) [i] | 2051 | (*((unsigned long **) data_ret)) [i] |
| @@ -2501,8 +2547,10 @@ x_check_property_data (data) | |||
| 2501 | DATA is a Lisp list of values to be converted. | 2547 | DATA is a Lisp list of values to be converted. |
| 2502 | RET is the C array that contains the converted values. It is assumed | 2548 | RET is the C array that contains the converted values. It is assumed |
| 2503 | it is big enough to hold all values. | 2549 | it is big enough to hold all values. |
| 2504 | FORMAT is 8, 16 or 32 and gives the size in bits for each C value to | 2550 | FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to |
| 2505 | be stored in RET. */ | 2551 | be stored in RET. Note that long is used for 32 even if long is more |
| 2552 | than 32 bits (see man pages for XChangeProperty, XGetWindowProperty and | ||
| 2553 | XClientMessageEvent). */ | ||
| 2506 | 2554 | ||
| 2507 | void | 2555 | void |
| 2508 | x_fill_property_data (dpy, data, ret, format) | 2556 | x_fill_property_data (dpy, data, ret, format) |
| @@ -2511,10 +2559,10 @@ x_fill_property_data (dpy, data, ret, format) | |||
| 2511 | void *ret; | 2559 | void *ret; |
| 2512 | int format; | 2560 | int format; |
| 2513 | { | 2561 | { |
| 2514 | CARD32 val; | 2562 | long val; |
| 2515 | CARD32 *d32 = (CARD32 *) ret; | 2563 | long *d32 = (long *) ret; |
| 2516 | CARD16 *d16 = (CARD16 *) ret; | 2564 | short *d16 = (short *) ret; |
| 2517 | CARD8 *d08 = (CARD8 *) ret; | 2565 | char *d08 = (char *) ret; |
| 2518 | Lisp_Object iter; | 2566 | Lisp_Object iter; |
| 2519 | 2567 | ||
| 2520 | for (iter = data; CONSP (iter); iter = XCDR (iter)) | 2568 | for (iter = data; CONSP (iter); iter = XCDR (iter)) |
| @@ -2522,24 +2570,24 @@ x_fill_property_data (dpy, data, ret, format) | |||
| 2522 | Lisp_Object o = XCAR (iter); | 2570 | Lisp_Object o = XCAR (iter); |
| 2523 | 2571 | ||
| 2524 | if (INTEGERP (o)) | 2572 | if (INTEGERP (o)) |
| 2525 | val = (CARD32) XFASTINT (o); | 2573 | val = (long) XFASTINT (o); |
| 2526 | else if (FLOATP (o)) | 2574 | else if (FLOATP (o)) |
| 2527 | val = (CARD32) XFLOAT_DATA (o); | 2575 | val = (long) XFLOAT_DATA (o); |
| 2528 | else if (CONSP (o)) | 2576 | else if (CONSP (o)) |
| 2529 | val = (CARD32) cons_to_long (o); | 2577 | val = (long) cons_to_long (o); |
| 2530 | else if (STRINGP (o)) | 2578 | else if (STRINGP (o)) |
| 2531 | { | 2579 | { |
| 2532 | BLOCK_INPUT; | 2580 | BLOCK_INPUT; |
| 2533 | val = XInternAtom (dpy, (char *) SDATA (o), False); | 2581 | val = (long) XInternAtom (dpy, (char *) SDATA (o), False); |
| 2534 | UNBLOCK_INPUT; | 2582 | UNBLOCK_INPUT; |
| 2535 | } | 2583 | } |
| 2536 | else | 2584 | else |
| 2537 | error ("Wrong type, must be string, number or cons"); | 2585 | error ("Wrong type, must be string, number or cons"); |
| 2538 | 2586 | ||
| 2539 | if (format == 8) | 2587 | if (format == 8) |
| 2540 | *d08++ = (CARD8) val; | 2588 | *d08++ = (char) val; |
| 2541 | else if (format == 16) | 2589 | else if (format == 16) |
| 2542 | *d16++ = (CARD16) val; | 2590 | *d16++ = (short) val; |
| 2543 | else | 2591 | else |
| 2544 | *d32++ = val; | 2592 | *d32++ = val; |
| 2545 | } | 2593 | } |
| @@ -2554,6 +2602,10 @@ x_fill_property_data (dpy, data, ret, format) | |||
| 2554 | be stored in RET. | 2602 | be stored in RET. |
| 2555 | SIZE is the number of elements in DATA. | 2603 | SIZE is the number of elements in DATA. |
| 2556 | 2604 | ||
| 2605 | Important: When format is 32, data should contain an array of int, | ||
| 2606 | not an array of long as the X library returns. This makes a difference | ||
| 2607 | when sizeof(long) != sizeof(int). | ||
| 2608 | |||
| 2557 | Also see comment for selection_data_to_lisp_data above. */ | 2609 | Also see comment for selection_data_to_lisp_data above. */ |
| 2558 | 2610 | ||
| 2559 | Lisp_Object | 2611 | Lisp_Object |
| @@ -2568,7 +2620,7 @@ x_property_data_to_lisp (f, data, type, format, size) | |||
| 2568 | data, size*format/8, type, format); | 2620 | data, size*format/8, type, format); |
| 2569 | } | 2621 | } |
| 2570 | 2622 | ||
| 2571 | /* Get the mouse position frame relative coordinates. */ | 2623 | /* Get the mouse position in frame relative coordinates. */ |
| 2572 | 2624 | ||
| 2573 | static void | 2625 | static void |
| 2574 | mouse_position_for_drop (f, x, y) | 2626 | mouse_position_for_drop (f, x, y) |
| @@ -2665,18 +2717,34 @@ x_handle_dnd_message (f, event, dpyinfo, bufp) | |||
| 2665 | { | 2717 | { |
| 2666 | Lisp_Object vec; | 2718 | Lisp_Object vec; |
| 2667 | Lisp_Object frame; | 2719 | Lisp_Object frame; |
| 2668 | unsigned long size = (8*sizeof (event->data))/event->format; | 2720 | /* format 32 => size 5, format 16 => size 10, format 8 => size 20 */ |
| 2721 | unsigned long size = 160/event->format; | ||
| 2669 | int x, y; | 2722 | int x, y; |
| 2723 | unsigned char *data = (unsigned char *) event->data.b; | ||
| 2724 | int idata[5]; | ||
| 2670 | 2725 | ||
| 2671 | XSETFRAME (frame, f); | 2726 | XSETFRAME (frame, f); |
| 2672 | 2727 | ||
| 2728 | /* On a 64 bit machine, the event->data.l array members are 64 bits (long), | ||
| 2729 | but the x_property_data_to_lisp (or rather selection_data_to_lisp_data) | ||
| 2730 | function expects them to be of size int (i.e. 32). So to be able to | ||
| 2731 | use that function, put the data in the form it expects if format is 32. */ | ||
| 2732 | |||
| 2733 | if (event->format == 32 && event->format < BITS_PER_LONG) | ||
| 2734 | { | ||
| 2735 | int i; | ||
| 2736 | for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */ | ||
| 2737 | idata[i] = (int) event->data.l[i]; | ||
| 2738 | data = (unsigned char *) idata; | ||
| 2739 | } | ||
| 2740 | |||
| 2673 | vec = Fmake_vector (make_number (4), Qnil); | 2741 | vec = Fmake_vector (make_number (4), Qnil); |
| 2674 | AREF (vec, 0) = SYMBOL_NAME (x_atom_to_symbol (FRAME_X_DISPLAY (f), | 2742 | AREF (vec, 0) = SYMBOL_NAME (x_atom_to_symbol (FRAME_X_DISPLAY (f), |
| 2675 | event->message_type)); | 2743 | event->message_type)); |
| 2676 | AREF (vec, 1) = frame; | 2744 | AREF (vec, 1) = frame; |
| 2677 | AREF (vec, 2) = make_number (event->format); | 2745 | AREF (vec, 2) = make_number (event->format); |
| 2678 | AREF (vec, 3) = x_property_data_to_lisp (f, | 2746 | AREF (vec, 3) = x_property_data_to_lisp (f, |
| 2679 | event->data.b, | 2747 | data, |
| 2680 | event->message_type, | 2748 | event->message_type, |
| 2681 | event->format, | 2749 | event->format, |
| 2682 | size); | 2750 | size); |
| @@ -2788,6 +2856,7 @@ are ignored. */) | |||
| 2788 | when sending to the root window. */ | 2856 | when sending to the root window. */ |
| 2789 | event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; | 2857 | event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; |
| 2790 | 2858 | ||
| 2859 | |||
| 2791 | memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); | 2860 | memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); |
| 2792 | x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, | 2861 | x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, |
| 2793 | event.xclient.format); | 2862 | event.xclient.format); |