173 |
/* If the selection owner takes too long to reply to a selection request, |
/* 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.) */ |
we give up on it. This is in milliseconds (0 = no timeout.) */ |
175 |
static EMACS_INT x_selection_timeout; |
static EMACS_INT x_selection_timeout; |
|
|
|
|
/* Utility functions */ |
|
|
|
|
|
static void lisp_data_to_selection_data (); |
|
|
static Lisp_Object selection_data_to_lisp_data (); |
|
|
static Lisp_Object x_get_window_property_as_lisp_data (); |
|
176 |
|
|
177 |
|
|
178 |
|
|
763 |
|
|
764 |
TRACE1 ("Set %s to number of bytes to send", |
TRACE1 ("Set %s to number of bytes to send", |
765 |
XGetAtomName (display, reply.property)); |
XGetAtomName (display, reply.property)); |
766 |
XChangeProperty (display, window, reply.property, dpyinfo->Xatom_INCR, |
{ |
767 |
32, PropModeReplace, |
/* XChangeProperty expects an array of long even if long is more than |
768 |
(unsigned char *) &bytes_remaining, 1); |
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 |
|
|
777 |
XSelectInput (display, window, PropertyChangeMask); |
XSelectInput (display, window, PropertyChangeMask); |
778 |
|
|
779 |
/* Tell 'em the INCR data is there... */ |
/* Tell 'em the INCR data is there... */ |
798 |
TRACE0 ("Got ACK"); |
TRACE0 ("Got ACK"); |
799 |
while (bytes_remaining) |
while (bytes_remaining) |
800 |
{ |
{ |
801 |
int i = ((bytes_remaining < max_bytes) |
int i = ((bytes_remaining < max_bytes) |
802 |
? bytes_remaining |
? bytes_remaining |
803 |
: max_bytes); |
: max_bytes); |
804 |
|
|
805 |
BLOCK_INPUT; |
BLOCK_INPUT; |
806 |
|
|
1525 |
reading it. Deal with that, I guess.... */ |
reading it. Deal with that, I guess.... */ |
1526 |
if (result != Success) |
if (result != Success) |
1527 |
break; |
break; |
1528 |
*actual_size_ret *= *actual_format_ret / 8; |
|
1529 |
bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret); |
/* The man page for XGetWindowProperty says: |
1530 |
offset += *actual_size_ret; |
"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 |
|
} |
1560 |
|
|
1561 |
/* This was allocated by Xlib, so use XFree. */ |
/* This was allocated by Xlib, so use XFree. */ |
1562 |
XFree ((char *) tmp_data); |
XFree ((char *) tmp_data); |
2001 |
else |
else |
2002 |
/* This vector is an INTEGER set, or something like it */ |
/* This vector is an INTEGER set, or something like it */ |
2003 |
{ |
{ |
2004 |
|
int data_size = 2; |
2005 |
*size_ret = XVECTOR (obj)->size; |
*size_ret = XVECTOR (obj)->size; |
2006 |
if (NILP (type)) type = QINTEGER; |
if (NILP (type)) type = QINTEGER; |
2007 |
*format_ret = 16; |
*format_ret = 16; |
2014 |
("elements of selection vector must be integers or conses of integers"), |
("elements of selection vector must be integers or conses of integers"), |
2015 |
Fcons (obj, Qnil))); |
Fcons (obj, Qnil))); |
2016 |
|
|
2017 |
*data_ret = (unsigned char *) xmalloc (*size_ret * (*format_ret/8)); |
/* 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); |
2022 |
for (i = 0; i < *size_ret; i++) |
for (i = 0; i < *size_ret; i++) |
2023 |
if (*format_ret == 32) |
if (*format_ret == 32) |
2024 |
(*((unsigned long **) data_ret)) [i] |
(*((unsigned long **) data_ret)) [i] |
2505 |
DATA is a Lisp list of values to be converted. |
DATA is a Lisp list of values to be converted. |
2506 |
RET is the C array that contains the converted values. It is assumed |
RET is the C array that contains the converted values. It is assumed |
2507 |
it is big enough to hold all values. |
it is big enough to hold all values. |
2508 |
FORMAT is 8, 16 or 32 and gives the size in bits for each C value to |
FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to |
2509 |
be stored in RET. */ |
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). */ |
2512 |
|
|
2513 |
void |
void |
2514 |
x_fill_property_data (dpy, data, ret, format) |
x_fill_property_data (dpy, data, ret, format) |
2517 |
void *ret; |
void *ret; |
2518 |
int format; |
int format; |
2519 |
{ |
{ |
2520 |
CARD32 val; |
long val; |
2521 |
CARD32 *d32 = (CARD32 *) ret; |
long *d32 = (long *) ret; |
2522 |
CARD16 *d16 = (CARD16 *) ret; |
short *d16 = (short *) ret; |
2523 |
CARD8 *d08 = (CARD8 *) ret; |
char *d08 = (char *) ret; |
2524 |
Lisp_Object iter; |
Lisp_Object iter; |
2525 |
|
|
2526 |
for (iter = data; CONSP (iter); iter = XCDR (iter)) |
for (iter = data; CONSP (iter); iter = XCDR (iter)) |
2528 |
Lisp_Object o = XCAR (iter); |
Lisp_Object o = XCAR (iter); |
2529 |
|
|
2530 |
if (INTEGERP (o)) |
if (INTEGERP (o)) |
2531 |
val = (CARD32) XFASTINT (o); |
val = (long) XFASTINT (o); |
2532 |
else if (FLOATP (o)) |
else if (FLOATP (o)) |
2533 |
val = (CARD32) XFLOAT_DATA (o); |
val = (long) XFLOAT_DATA (o); |
2534 |
else if (CONSP (o)) |
else if (CONSP (o)) |
2535 |
val = (CARD32) cons_to_long (o); |
val = (long) cons_to_long (o); |
2536 |
else if (STRINGP (o)) |
else if (STRINGP (o)) |
2537 |
{ |
{ |
2538 |
BLOCK_INPUT; |
BLOCK_INPUT; |
2539 |
val = XInternAtom (dpy, (char *) SDATA (o), False); |
val = (long) XInternAtom (dpy, (char *) SDATA (o), False); |
2540 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
2541 |
} |
} |
2542 |
else |
else |
2543 |
error ("Wrong type, must be string, number or cons"); |
error ("Wrong type, must be string, number or cons"); |
2544 |
|
|
2545 |
if (format == 8) |
if (format == 8) |
2546 |
*d08++ = (CARD8) val; |
*d08++ = (char) val; |
2547 |
else if (format == 16) |
else if (format == 16) |
2548 |
*d16++ = (CARD16) val; |
*d16++ = (short) val; |
2549 |
else |
else |
2550 |
*d32++ = val; |
*d32++ = val; |
2551 |
} |
} |
2671 |
{ |
{ |
2672 |
Lisp_Object vec; |
Lisp_Object vec; |
2673 |
Lisp_Object frame; |
Lisp_Object frame; |
2674 |
unsigned long size = (8*sizeof (event->data))/event->format; |
/* format 32 => size 5, format 16 => size 10, format 8 => size 20 */ |
2675 |
|
unsigned long size = 160/event->format; |
2676 |
int x, y; |
int x, y; |
2677 |
unsigned char *data = (unsigned char *) event->data.b; |
unsigned char *data = (unsigned char *) event->data.b; |
2678 |
int idata[5]; |
int idata[5]; |
2751 |
struct frame *f = check_x_frame (from); |
struct frame *f = check_x_frame (from); |
2752 |
int count; |
int count; |
2753 |
int to_root; |
int to_root; |
|
int idata[5]; |
|
|
void *data; |
|
2754 |
|
|
2755 |
CHECK_STRING (message_type); |
CHECK_STRING (message_type); |
2756 |
CHECK_NUMBER (format); |
CHECK_NUMBER (format); |
2811 |
event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; |
event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; |
2812 |
|
|
2813 |
|
|
2814 |
if (event.xclient.format == 32 && event.xclient.format < BITS_PER_LONG) |
memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); |
2815 |
{ |
x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, |
2816 |
/* x_fill_property_data expects data to hold 32 bit values when |
event.xclient.format); |
|
format == 32, but on a 64 bit machine long is 64 bits. |
|
|
event.xclient.l is an array of long, so we must compensate. */ |
|
|
|
|
|
memset (idata, 0, sizeof (idata)); |
|
|
data = idata; |
|
|
} |
|
|
else |
|
|
{ |
|
|
memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); |
|
|
data = event.xclient.data.b; |
|
|
} |
|
2817 |
|
|
|
x_fill_property_data (dpyinfo->display, values, data, event.xclient.format); |
|
|
|
|
|
if (data == idata) |
|
|
{ |
|
|
int i; |
|
|
for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */ |
|
|
event.xclient.data.l[i] = (long) idata[i]; |
|
|
} |
|
|
|
|
2818 |
/* If event mask is 0 the event is sent to the client that created |
/* If event mask is 0 the event is sent to the client that created |
2819 |
the destination window. But if we are sending to the root window, |
the destination window. But if we are sending to the root window, |
2820 |
there is no such client. Then we set the event mask to 0xffff. The |
there is no such client. Then we set the event mask to 0xffff. The |