Mercurial > emacs
comparison src/xselect.c @ 83250:89ac10c67e45
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
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Thu, 10 Feb 2005 20:43:55 +0000 |
parents | 3dcba0bc766b 22a410b2373b |
children | 9684495d72bc |
comparison
equal
deleted
inserted
replaced
83249:267c2ab562ab | 83250:89ac10c67e45 |
---|---|
171 static Lisp_Object Vselection_converter_alist; | 171 static Lisp_Object Vselection_converter_alist; |
172 | 172 |
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 |
185 /* Define a queue to save up SELECTION_REQUEST_EVENT events for later | 179 /* Define a queue to save up SELECTION_REQUEST_EVENT events for later |
186 handling. */ | 180 handling. */ |
775 wait_object = expect_property_change (display, window, reply.property, | 769 wait_object = expect_property_change (display, window, reply.property, |
776 PropertyDelete); | 770 PropertyDelete); |
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... */ |
786 TRACE0 ("Send SelectionNotify event"); | 788 TRACE0 ("Send SelectionNotify event"); |
787 XSendEvent (display, window, False, 0L, (XEvent *) &reply); | 789 XSendEvent (display, window, False, 0L, (XEvent *) &reply); |
802 unexpect_property_change (wait_object); | 804 unexpect_property_change (wait_object); |
803 | 805 |
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 |
813 wait_object | 815 wait_object |
814 = expect_property_change (display, window, reply.property, | 816 = expect_property_change (display, window, reply.property, |
1538 /* If this doesn't return Success at this point, it means that | 1540 /* If this doesn't return Success at this point, it means that |
1539 some clod deleted the selection while we were in the midst of | 1541 some clod deleted the selection while we were in the midst of |
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); |
1549 } | 1580 } |
1550 | 1581 |
1753 of format 16 if every element in the vector is an integer, and is assumed | 1784 of format 16 if every element in the vector is an integer, and is assumed |
1754 to be of format 32 if any element is a cons of two integers. | 1785 to be of format 32 if any element is a cons of two integers. |
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 |
1762 static Lisp_Object | 1797 static Lisp_Object |
1763 selection_data_to_lisp_data (display, data, size, type, format) | 1798 selection_data_to_lisp_data (display, data, size, type, format) |
1795 a vector of symbols. | 1830 a vector of symbols. |
1796 */ | 1831 */ |
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 } |
1812 | 1853 |
1813 /* Convert a single 16 or small 32 bit number to a Lisp_Int. | 1854 /* Convert a single 16 or small 32 bit number to a Lisp_Int. |
1985 } | 2026 } |
1986 #endif | 2027 #endif |
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; |
1993 for (i = 0; i < *size_ret; i++) | 2035 for (i = 0; i < *size_ret; i++) |
1994 if (CONSP (XVECTOR (obj)->contents [i])) | 2036 if (CONSP (XVECTOR (obj)->contents [i])) |
1997 Fsignal (Qerror, /* Qselection_error */ | 2039 Fsignal (Qerror, /* Qselection_error */ |
1998 Fcons (build_string | 2040 Fcons (build_string |
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] |
2006 = cons_to_long (XVECTOR (obj)->contents [i]); | 2052 = cons_to_long (XVECTOR (obj)->contents [i]); |
2007 else | 2053 else |
2499 | 2545 |
2500 DPY is the display use to look up X atoms. | 2546 DPY is the display use to look up X atoms. |
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) |
2509 Display *dpy; | 2557 Display *dpy; |
2510 Lisp_Object data; | 2558 Lisp_Object data; |
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)) |
2521 { | 2569 { |
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 } |
2546 } | 2594 } |
2547 | 2595 |
2552 each number in DATA to its corresponfing X atom as a symbol. | 2600 each number in DATA to its corresponfing X atom as a symbol. |
2553 FORMAT is 8, 16 or 32 and gives the size in bits for each C value to | 2601 FORMAT is 8, 16 or 32 and gives the size in bits for each C value to |
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 |
2560 x_property_data_to_lisp (f, data, type, format, size) | 2612 x_property_data_to_lisp (f, data, type, format, size) |
2561 struct frame *f; | 2613 struct frame *f; |
2566 { | 2618 { |
2567 return selection_data_to_lisp_data (FRAME_X_DISPLAY (f), | 2619 return selection_data_to_lisp_data (FRAME_X_DISPLAY (f), |
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) |
2575 FRAME_PTR f; | 2627 FRAME_PTR f; |
2576 int *x; | 2628 int *x; |
2663 struct x_display_info *dpyinfo; | 2715 struct x_display_info *dpyinfo; |
2664 struct input_event *bufp; | 2716 struct input_event *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); |
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 } | |
2672 | 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); |
2683 | 2751 |
2684 mouse_position_for_drop (f, &x, &y); | 2752 mouse_position_for_drop (f, &x, &y); |
2786 | 2854 |
2787 /* Some clients (metacity for example) expects sending window to be here | 2855 /* Some clients (metacity for example) expects sending window to be here |
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); |
2794 | 2863 |
2795 /* If event mask is 0 the event is sent to the client that created | 2864 /* If event mask is 0 the event is sent to the client that created |