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);