Mercurial > emacs
comparison src/xselect.c @ 59975:501c2e5945ff
* xselect.c (x_reply_selection_request): Pass long array to
XChangeProperty so that 64 bit longs are handeled correctly.
(x_get_window_property): If format is 32 and long is bigger than 32
bits convert data from XGetWindowProperty from long array to int array.
(lisp_data_to_selection_data): When the input is a vector and the
format is 32, allocate a long array even if long is bigger than 32 bits.
(x_fill_property_data): Use char, short and long as the man page
for XChangeProperty specifies. This way the data returned is OK for
both 32 and 64 bit machines.
(x_handle_dnd_message): Calculate size correctly even for 64 bit
machines.
(Fx_send_client_event): Undo change from 2005-02-05,
x_fill_property_data now handles that case.
author | Jan Djärv <jan.h.d@swipnet.se> |
---|---|
date | Mon, 07 Feb 2005 19:59:36 +0000 |
parents | f5f2fbf049bc |
children | 22a410b2373b |
comparison
equal
deleted
inserted
replaced
59974:bb6a99f86b5d | 59975:501c2e5945ff |
---|---|
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. */ |
767 wait_object = expect_property_change (display, window, reply.property, | 761 wait_object = expect_property_change (display, window, reply.property, |
768 PropertyDelete); | 762 PropertyDelete); |
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... */ |
778 TRACE0 ("Send SelectionNotify event"); | 780 TRACE0 ("Send SelectionNotify event"); |
779 XSendEvent (display, window, False, 0L, (XEvent *) &reply); | 781 XSendEvent (display, window, False, 0L, (XEvent *) &reply); |
794 unexpect_property_change (wait_object); | 796 unexpect_property_change (wait_object); |
795 | 797 |
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 |
805 wait_object | 807 wait_object |
806 = expect_property_change (display, window, reply.property, | 808 = expect_property_change (display, window, reply.property, |
1521 /* If this doesn't return Success at this point, it means that | 1523 /* If this doesn't return Success at this point, it means that |
1522 some clod deleted the selection while we were in the midst of | 1524 some clod deleted the selection while we were in the midst of |
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); |
1532 } | 1563 } |
1533 | 1564 |
1968 } | 1999 } |
1969 #endif | 2000 #endif |
1970 else | 2001 else |
1971 /* This vector is an INTEGER set, or something like it */ | 2002 /* This vector is an INTEGER set, or something like it */ |
1972 { | 2003 { |
2004 int data_size = 2; | |
1973 *size_ret = XVECTOR (obj)->size; | 2005 *size_ret = XVECTOR (obj)->size; |
1974 if (NILP (type)) type = QINTEGER; | 2006 if (NILP (type)) type = QINTEGER; |
1975 *format_ret = 16; | 2007 *format_ret = 16; |
1976 for (i = 0; i < *size_ret; i++) | 2008 for (i = 0; i < *size_ret; i++) |
1977 if (CONSP (XVECTOR (obj)->contents [i])) | 2009 if (CONSP (XVECTOR (obj)->contents [i])) |
1980 Fsignal (Qerror, /* Qselection_error */ | 2012 Fsignal (Qerror, /* Qselection_error */ |
1981 Fcons (build_string | 2013 Fcons (build_string |
1982 ("elements of selection vector must be integers or conses of integers"), | 2014 ("elements of selection vector must be integers or conses of integers"), |
1983 Fcons (obj, Qnil))); | 2015 Fcons (obj, Qnil))); |
1984 | 2016 |
1985 *data_ret = (unsigned char *) xmalloc (*size_ret * (*format_ret/8)); | 2017 /* Use sizeof(long) even if it is more than 32 bits. See comment |
2018 in x_get_window_property and x_fill_property_data. */ | |
2019 | |
2020 if (*format_ret == 32) data_size = sizeof(long); | |
2021 *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); | |
1986 for (i = 0; i < *size_ret; i++) | 2022 for (i = 0; i < *size_ret; i++) |
1987 if (*format_ret == 32) | 2023 if (*format_ret == 32) |
1988 (*((unsigned long **) data_ret)) [i] | 2024 (*((unsigned long **) data_ret)) [i] |
1989 = cons_to_long (XVECTOR (obj)->contents [i]); | 2025 = cons_to_long (XVECTOR (obj)->contents [i]); |
1990 else | 2026 else |
2467 | 2503 |
2468 DPY is the display use to look up X atoms. | 2504 DPY is the display use to look up X atoms. |
2469 DATA is a Lisp list of values to be converted. | 2505 DATA is a Lisp list of values to be converted. |
2470 RET is the C array that contains the converted values. It is assumed | 2506 RET is the C array that contains the converted values. It is assumed |
2471 it is big enough to hold all values. | 2507 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 | 2508 FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to |
2473 be stored in RET. */ | 2509 be stored in RET. Note that long is used for 32 even if long is more |
2510 than 32 bits (see man pages for XChangeProperty, XGetWindowProperty and | |
2511 XClientMessageEvent). */ | |
2474 | 2512 |
2475 void | 2513 void |
2476 x_fill_property_data (dpy, data, ret, format) | 2514 x_fill_property_data (dpy, data, ret, format) |
2477 Display *dpy; | 2515 Display *dpy; |
2478 Lisp_Object data; | 2516 Lisp_Object data; |
2479 void *ret; | 2517 void *ret; |
2480 int format; | 2518 int format; |
2481 { | 2519 { |
2482 CARD32 val; | 2520 long val; |
2483 CARD32 *d32 = (CARD32 *) ret; | 2521 long *d32 = (long *) ret; |
2484 CARD16 *d16 = (CARD16 *) ret; | 2522 short *d16 = (short *) ret; |
2485 CARD8 *d08 = (CARD8 *) ret; | 2523 char *d08 = (char *) ret; |
2486 Lisp_Object iter; | 2524 Lisp_Object iter; |
2487 | 2525 |
2488 for (iter = data; CONSP (iter); iter = XCDR (iter)) | 2526 for (iter = data; CONSP (iter); iter = XCDR (iter)) |
2489 { | 2527 { |
2490 Lisp_Object o = XCAR (iter); | 2528 Lisp_Object o = XCAR (iter); |
2491 | 2529 |
2492 if (INTEGERP (o)) | 2530 if (INTEGERP (o)) |
2493 val = (CARD32) XFASTINT (o); | 2531 val = (long) XFASTINT (o); |
2494 else if (FLOATP (o)) | 2532 else if (FLOATP (o)) |
2495 val = (CARD32) XFLOAT_DATA (o); | 2533 val = (long) XFLOAT_DATA (o); |
2496 else if (CONSP (o)) | 2534 else if (CONSP (o)) |
2497 val = (CARD32) cons_to_long (o); | 2535 val = (long) cons_to_long (o); |
2498 else if (STRINGP (o)) | 2536 else if (STRINGP (o)) |
2499 { | 2537 { |
2500 BLOCK_INPUT; | 2538 BLOCK_INPUT; |
2501 val = XInternAtom (dpy, (char *) SDATA (o), False); | 2539 val = (long) XInternAtom (dpy, (char *) SDATA (o), False); |
2502 UNBLOCK_INPUT; | 2540 UNBLOCK_INPUT; |
2503 } | 2541 } |
2504 else | 2542 else |
2505 error ("Wrong type, must be string, number or cons"); | 2543 error ("Wrong type, must be string, number or cons"); |
2506 | 2544 |
2507 if (format == 8) | 2545 if (format == 8) |
2508 *d08++ = (CARD8) val; | 2546 *d08++ = (char) val; |
2509 else if (format == 16) | 2547 else if (format == 16) |
2510 *d16++ = (CARD16) val; | 2548 *d16++ = (short) val; |
2511 else | 2549 else |
2512 *d32++ = val; | 2550 *d32++ = val; |
2513 } | 2551 } |
2514 } | 2552 } |
2515 | 2553 |
2631 struct x_display_info *dpyinfo; | 2669 struct x_display_info *dpyinfo; |
2632 struct input_event *bufp; | 2670 struct input_event *bufp; |
2633 { | 2671 { |
2634 Lisp_Object vec; | 2672 Lisp_Object vec; |
2635 Lisp_Object frame; | 2673 Lisp_Object frame; |
2636 unsigned long size = (8*sizeof (event->data))/event->format; | 2674 /* format 32 => size 5, format 16 => size 10, format 8 => size 20 */ |
2675 unsigned long size = 160/event->format; | |
2637 int x, y; | 2676 int x, y; |
2638 unsigned char *data = (unsigned char *) event->data.b; | 2677 unsigned char *data = (unsigned char *) event->data.b; |
2639 int idata[5]; | 2678 int idata[5]; |
2640 | 2679 |
2641 XSETFRAME (frame, f); | 2680 XSETFRAME (frame, f); |
2710 Lisp_Object cons; | 2749 Lisp_Object cons; |
2711 int size; | 2750 int size; |
2712 struct frame *f = check_x_frame (from); | 2751 struct frame *f = check_x_frame (from); |
2713 int count; | 2752 int count; |
2714 int to_root; | 2753 int to_root; |
2715 int idata[5]; | |
2716 void *data; | |
2717 | 2754 |
2718 CHECK_STRING (message_type); | 2755 CHECK_STRING (message_type); |
2719 CHECK_NUMBER (format); | 2756 CHECK_NUMBER (format); |
2720 CHECK_CONS (values); | 2757 CHECK_CONS (values); |
2721 | 2758 |
2772 /* Some clients (metacity for example) expects sending window to be here | 2809 /* Some clients (metacity for example) expects sending window to be here |
2773 when sending to the root window. */ | 2810 when sending to the root window. */ |
2774 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; | 2811 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; |
2775 | 2812 |
2776 | 2813 |
2777 if (event.xclient.format == 32 && event.xclient.format < BITS_PER_LONG) | 2814 memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); |
2778 { | 2815 x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, |
2779 /* x_fill_property_data expects data to hold 32 bit values when | 2816 event.xclient.format); |
2780 format == 32, but on a 64 bit machine long is 64 bits. | 2817 |
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 | |
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 | 2818 /* 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, | 2819 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 | 2820 there is no such client. Then we set the event mask to 0xffff. The |
2804 event then goes to clients selecting for events on the root window. */ | 2821 event then goes to clients selecting for events on the root window. */ |
2805 count = x_catch_errors (dpyinfo->display); | 2822 count = x_catch_errors (dpyinfo->display); |