diff options
author | Noah Friedman <friedman@splode.com> | 2016-08-21 14:03:46 -0700 |
---|---|---|
committer | Noah Friedman <friedman@splode.com> | 2016-08-21 14:04:37 -0700 |
commit | 7a6b3d0fb793864a1f5deb5a22de78a4dced652d (patch) | |
tree | 2da0a23eff517e5b5aa8417936500b0586d98131 /src/xselect.c | |
parent | 14a86f837762af8d16eef57c315da93b56699901 (diff) | |
download | emacs-7a6b3d0fb793864a1f5deb5a22de78a4dced652d.tar.gz |
Fix interpretation of signed vs unsigned values when retrieving X
Window properties, and make sure the full value is returned when not
parsed.
New subr to export type and format information about X Window
properties to lisp.
* src/xselect.c (selection_data_to_lisp_data): Treat any data as
unsigned unless its actual type is INTEGER.
CARDINALs, in particular, are unsigned.
* src/xfns.c (Fx_change_window_property): If value is a string, ignore
any provided format and force to 8.
(x_window_property_intern): If returning value as a string, the length
is actual_size times the actual format of each element, which is not
necessarily bytes.
(Fx_window_property_attributes): New subr.
(syms_of_xfns): Declare it.
Diffstat (limited to 'src/xselect.c')
-rw-r--r-- | src/xselect.c | 59 |
1 files changed, 47 insertions, 12 deletions
diff --git a/src/xselect.c b/src/xselect.c index 616d12c7cab..156888a540b 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -1612,11 +1612,24 @@ selection_data_to_lisp_data (struct x_display_info *dpyinfo, /* Convert a single 16-bit number or a small 32-bit number to a Lisp_Int. If the number is 32 bits and won't fit in a Lisp_Int, convert it to a cons of integers, 16 bits in each half. + + INTEGER is a signed type, CARDINAL is unsigned. + Assume any other types are unsigned as well. */ else if (format == 32 && size == sizeof (int)) - return INTEGER_TO_CONS (((int *) data) [0]); + { + if (type == XA_INTEGER) + return INTEGER_TO_CONS (((int *) data) [0]); + else + return INTEGER_TO_CONS (((unsigned int *) data) [0]); + } else if (format == 16 && size == sizeof (short)) - return make_number (((short *) data) [0]); + { + if (type == XA_INTEGER) + return make_number (((short *) data) [0]); + else + return make_number (((unsigned short *) data) [0]); + } /* Convert any other kind of data to a vector of numbers, represented as above (as an integer, or a cons of two 16 bit integers.) @@ -1626,11 +1639,22 @@ selection_data_to_lisp_data (struct x_display_info *dpyinfo, ptrdiff_t i; Lisp_Object v = make_uninit_vector (size / 2); - for (i = 0; i < size / 2; i++) - { - short j = ((short *) data) [i]; - ASET (v, i, make_number (j)); - } + if (type == XA_INTEGER) + { + for (i = 0; i < size / 2; i++) + { + short j = ((short *) data) [i]; + ASET (v, i, make_number (j)); + } + } + else + { + for (i = 0; i < size / 2; i++) + { + unsigned short j = ((unsigned short *) data) [i]; + ASET (v, i, make_number (j)); + } + } return v; } else @@ -1638,11 +1662,22 @@ selection_data_to_lisp_data (struct x_display_info *dpyinfo, ptrdiff_t i; Lisp_Object v = make_uninit_vector (size / X_LONG_SIZE); - for (i = 0; i < size / X_LONG_SIZE; i++) - { - int j = ((int *) data) [i]; - ASET (v, i, INTEGER_TO_CONS (j)); - } + if (type == XA_INTEGER) + { + for (i = 0; i < size / X_LONG_SIZE; i++) + { + int j = ((int *) data) [i]; + ASET (v, i, INTEGER_TO_CONS (j)); + } + } + else + { + for (i = 0; i < size / X_LONG_SIZE; i++) + { + unsigned int j = ((unsigned int *) data) [i]; + ASET (v, i, INTEGER_TO_CONS (j)); + } + } return v; } } |