mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-04-27 16:51:06 -07:00
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.
This commit is contained in:
parent
14a86f8377
commit
7a6b3d0fb7
2 changed files with 106 additions and 13 deletions
60
src/xfns.c
60
src/xfns.c
|
|
@ -5113,6 +5113,7 @@ FRAME. Default is to change on the edit X window. */)
|
|||
if (INT_MAX < SBYTES (value))
|
||||
error ("VALUE too long");
|
||||
nelements = SBYTES (value);
|
||||
element_format = 8; /* ignore any provided format */
|
||||
}
|
||||
|
||||
block_input ();
|
||||
|
|
@ -5223,7 +5224,7 @@ x_window_property_intern (struct frame *f,
|
|||
}
|
||||
|
||||
if (NILP (vector_ret_p))
|
||||
prop_value = make_string ((char *) tmp_data, actual_size);
|
||||
prop_value = make_string ((char *) tmp_data, (actual_format / 8) * actual_size);
|
||||
else
|
||||
prop_value = x_property_data_to_lisp (f,
|
||||
tmp_data,
|
||||
|
|
@ -5310,6 +5311,62 @@ no value of TYPE (always string in the MS Windows case). */)
|
|||
return prop_value;
|
||||
}
|
||||
|
||||
DEFUN ("x-window-property-attributes", Fx_window_property_attributes, Sx_window_property_attributes,
|
||||
1, 3, 0,
|
||||
doc: /* Retrieve metadata about window property PROP on FRAME.
|
||||
If FRAME is nil or omitted, use the selected frame.
|
||||
If SOURCE is non-nil, get the property on that window instead of from
|
||||
FRAME. The number 0 denotes the root window.
|
||||
|
||||
Return value is nil if FRAME hasn't a property with name PROP.
|
||||
Otherwise, the return value is a vector with the following fields:
|
||||
|
||||
0. The property type, as an integer. The symbolic name of
|
||||
the type can be obtained with `x-get-atom-name'.
|
||||
1. The format of each element; one of 8, 16, or 32.
|
||||
2. The length of the property, in number of elements. */)
|
||||
(Lisp_Object prop, Lisp_Object frame, Lisp_Object source)
|
||||
{
|
||||
struct frame *f = decode_window_system_frame (frame);
|
||||
Window target_window = FRAME_X_WINDOW (f);
|
||||
Atom prop_atom;
|
||||
Lisp_Object prop_attr = Qnil;
|
||||
Atom actual_type;
|
||||
int actual_format;
|
||||
unsigned long actual_size, bytes_remaining;
|
||||
unsigned char *tmp_data = NULL;
|
||||
int rc;
|
||||
|
||||
CHECK_STRING (prop);
|
||||
|
||||
if (! NILP (source))
|
||||
{
|
||||
CONS_TO_INTEGER (source, Window, target_window);
|
||||
if (! target_window)
|
||||
target_window = FRAME_DISPLAY_INFO (f)->root_window;
|
||||
}
|
||||
|
||||
block_input ();
|
||||
|
||||
prop_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (prop), False);
|
||||
rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
|
||||
prop_atom, 0, 0, False, AnyPropertyType,
|
||||
&actual_type, &actual_format, &actual_size,
|
||||
&bytes_remaining, &tmp_data);
|
||||
if (rc == Success && actual_format != 0)
|
||||
{
|
||||
XFree (tmp_data);
|
||||
|
||||
prop_attr = Fmake_vector (make_number (3), Qnil);
|
||||
ASET (prop_attr, 0, make_number (actual_type));
|
||||
ASET (prop_attr, 1, make_number (actual_format));
|
||||
ASET (prop_attr, 2, make_number (bytes_remaining / (actual_format / 8)));
|
||||
}
|
||||
|
||||
unblock_input ();
|
||||
return prop_attr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Tool tips
|
||||
***********************************************************************/
|
||||
|
|
@ -6966,6 +7023,7 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
|
|||
defsubr (&Sx_change_window_property);
|
||||
defsubr (&Sx_delete_window_property);
|
||||
defsubr (&Sx_window_property);
|
||||
defsubr (&Sx_window_property_attributes);
|
||||
|
||||
defsubr (&Sxw_display_color_p);
|
||||
defsubr (&Sx_display_grayscale_p);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue