Mercurial > emacs
diff 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 |
line wrap: on
line diff
--- a/src/xselect.c Fri Feb 04 16:29:25 2005 +0000 +++ b/src/xselect.c Thu Feb 10 20:43:55 2005 +0000 @@ -173,12 +173,6 @@ /* If the selection owner takes too long to reply to a selection request, we give up on it. This is in milliseconds (0 = no 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 (); @@ -777,9 +771,17 @@ TRACE1 ("Set %s to number of bytes to send", XGetAtomName (display, reply.property)); - XChangeProperty (display, window, reply.property, dpyinfo->Xatom_INCR, - 32, PropModeReplace, - (unsigned char *) &bytes_remaining, 1); + { + /* XChangeProperty expects an array of long even if long is more than + 32 bits. */ + long value[1]; + + value[0] = bytes_remaining; + XChangeProperty (display, window, reply.property, dpyinfo->Xatom_INCR, + 32, PropModeReplace, + (unsigned char *) value, 1); + } + XSelectInput (display, window, PropertyChangeMask); /* Tell 'em the INCR data is there... */ @@ -804,9 +806,9 @@ TRACE0 ("Got ACK"); while (bytes_remaining) { - int i = ((bytes_remaining < max_bytes) - ? bytes_remaining - : max_bytes); + int i = ((bytes_remaining < max_bytes) + ? bytes_remaining + : max_bytes); BLOCK_INPUT; @@ -1540,9 +1542,38 @@ reading it. Deal with that, I guess.... */ if (result != Success) break; - *actual_size_ret *= *actual_format_ret / 8; - bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret); - offset += *actual_size_ret; + + /* The man page for XGetWindowProperty says: + "If the returned format is 32, the returned data is represented + as a long array and should be cast to that type to obtain the + elements." + This applies even if long is more than 32 bits, the X library + converts from 32 bit elements received from the X server to long + and passes the long array to us. Thus, for that case bcopy can not + be used. We convert to a 32 bit type here, because so much code + assume on that. + + The bytes and offsets passed to XGetWindowProperty refers to the + property and those are indeed in 32 bit quantities if format is 32. */ + + if (*actual_format_ret == 32 && *actual_format_ret < BITS_PER_LONG) + { + unsigned long i; + int *idata = (int *) ((*data_ret) + offset); + long *ldata = (long *) tmp_data; + + for (i = 0; i < *actual_size_ret; ++i) + { + idata[i]= (int) ldata[i]; + offset += 4; + } + } + else + { + *actual_size_ret *= *actual_format_ret / 8; + bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret); + offset += *actual_size_ret; + } /* This was allocated by Xlib, so use XFree. */ XFree ((char *) tmp_data); @@ -1755,7 +1786,11 @@ When converting an object to C, it may be of the form (SYMBOL . <data>) where SYMBOL is what we should claim that the type is. Format and - representation are as above. */ + representation are as above. + + Important: When format is 32, data should contain an array of int, + not an array of long as the X library returns. This makes a difference + when sizeof(long) != sizeof(int). */ @@ -1797,15 +1832,21 @@ else if (type == XA_ATOM) { int i; - if (size == sizeof (Atom)) - return x_atom_to_symbol (display, *((Atom *) data)); + /* On a 64 bit machine sizeof(Atom) == sizeof(long) == 8. + But the callers of these function has made sure the data for + format == 32 is an array of int. Thus, use int instead + of Atom. */ + int *idata = (int *) data; + + if (size == sizeof (int)) + return x_atom_to_symbol (display, (Atom) idata[0]); else { - Lisp_Object v = Fmake_vector (make_number (size / sizeof (Atom)), + Lisp_Object v = Fmake_vector (make_number (size / sizeof (int)), make_number (0)); - for (i = 0; i < size / sizeof (Atom); i++) + for (i = 0; i < size / sizeof (int); i++) Faset (v, make_number (i), - x_atom_to_symbol (display, ((Atom *) data) [i])); + x_atom_to_symbol (display, (Atom) idata[i])); return v; } } @@ -1987,6 +2028,7 @@ else /* This vector is an INTEGER set, or something like it */ { + int data_size = 2; *size_ret = XVECTOR (obj)->size; if (NILP (type)) type = QINTEGER; *format_ret = 16; @@ -1999,7 +2041,11 @@ ("elements of selection vector must be integers or conses of integers"), Fcons (obj, Qnil))); - *data_ret = (unsigned char *) xmalloc (*size_ret * (*format_ret/8)); + /* Use sizeof(long) even if it is more than 32 bits. See comment + in x_get_window_property and x_fill_property_data. */ + + if (*format_ret == 32) data_size = sizeof(long); + *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); for (i = 0; i < *size_ret; i++) if (*format_ret == 32) (*((unsigned long **) data_ret)) [i] @@ -2501,8 +2547,10 @@ DATA is a Lisp list of values to be converted. RET is the C array that contains the converted values. It is assumed it is big enough to hold all values. - FORMAT is 8, 16 or 32 and gives the size in bits for each C value to - be stored in RET. */ + FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to + be stored in RET. Note that long is used for 32 even if long is more + than 32 bits (see man pages for XChangeProperty, XGetWindowProperty and + XClientMessageEvent). */ void x_fill_property_data (dpy, data, ret, format) @@ -2511,10 +2559,10 @@ void *ret; int format; { - CARD32 val; - CARD32 *d32 = (CARD32 *) ret; - CARD16 *d16 = (CARD16 *) ret; - CARD8 *d08 = (CARD8 *) ret; + long val; + long *d32 = (long *) ret; + short *d16 = (short *) ret; + char *d08 = (char *) ret; Lisp_Object iter; for (iter = data; CONSP (iter); iter = XCDR (iter)) @@ -2522,24 +2570,24 @@ Lisp_Object o = XCAR (iter); if (INTEGERP (o)) - val = (CARD32) XFASTINT (o); + val = (long) XFASTINT (o); else if (FLOATP (o)) - val = (CARD32) XFLOAT_DATA (o); + val = (long) XFLOAT_DATA (o); else if (CONSP (o)) - val = (CARD32) cons_to_long (o); + val = (long) cons_to_long (o); else if (STRINGP (o)) { BLOCK_INPUT; - val = XInternAtom (dpy, (char *) SDATA (o), False); + val = (long) XInternAtom (dpy, (char *) SDATA (o), False); UNBLOCK_INPUT; } else error ("Wrong type, must be string, number or cons"); if (format == 8) - *d08++ = (CARD8) val; + *d08++ = (char) val; else if (format == 16) - *d16++ = (CARD16) val; + *d16++ = (short) val; else *d32++ = val; } @@ -2554,6 +2602,10 @@ be stored in RET. SIZE is the number of elements in DATA. + Important: When format is 32, data should contain an array of int, + not an array of long as the X library returns. This makes a difference + when sizeof(long) != sizeof(int). + Also see comment for selection_data_to_lisp_data above. */ Lisp_Object @@ -2568,7 +2620,7 @@ data, size*format/8, type, format); } -/* Get the mouse position frame relative coordinates. */ +/* Get the mouse position in frame relative coordinates. */ static void mouse_position_for_drop (f, x, y) @@ -2665,18 +2717,34 @@ { Lisp_Object vec; Lisp_Object frame; - unsigned long size = (8*sizeof (event->data))/event->format; + /* format 32 => size 5, format 16 => size 10, format 8 => size 20 */ + unsigned long size = 160/event->format; int x, y; + unsigned char *data = (unsigned char *) event->data.b; + int idata[5]; XSETFRAME (frame, f); + /* On a 64 bit machine, the event->data.l array members are 64 bits (long), + but the x_property_data_to_lisp (or rather selection_data_to_lisp_data) + function expects them to be of size int (i.e. 32). So to be able to + use that function, put the data in the form it expects if format is 32. */ + + if (event->format == 32 && event->format < BITS_PER_LONG) + { + int i; + for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */ + idata[i] = (int) event->data.l[i]; + data = (unsigned char *) idata; + } + vec = Fmake_vector (make_number (4), Qnil); AREF (vec, 0) = SYMBOL_NAME (x_atom_to_symbol (FRAME_X_DISPLAY (f), event->message_type)); AREF (vec, 1) = frame; AREF (vec, 2) = make_number (event->format); AREF (vec, 3) = x_property_data_to_lisp (f, - event->data.b, + data, event->message_type, event->format, size); @@ -2788,6 +2856,7 @@ when sending to the root window. */ event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; + memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, event.xclient.format);