summaryrefslogtreecommitdiff
path: root/src/xselect.c
diff options
context:
space:
mode:
authorNoah Friedman <friedman@splode.com>2016-08-21 14:03:46 -0700
committerNoah Friedman <friedman@splode.com>2016-08-21 14:04:37 -0700
commit7a6b3d0fb793864a1f5deb5a22de78a4dced652d (patch)
tree2da0a23eff517e5b5aa8417936500b0586d98131 /src/xselect.c
parent14a86f837762af8d16eef57c315da93b56699901 (diff)
downloademacs-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.c59
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;
}
}