GdkWindow *, GdkAtom,
Lisp_Object, GdkAtom, bool);
static Lisp_Object selection_data_to_lisp_data (struct pgtk_display_info *,
- void const *,
+ const unsigned char *,
ptrdiff_t, GdkAtom, int);
static void lisp_data_to_selection_data (struct pgtk_display_info *, Lisp_Object,
struct selection_data *);
guint32 timestamp = gtk_get_current_event_time ();
GdkAtom selection_atom = symbol_to_gdk_atom (selection_name);
Lisp_Object targets;
- ptrdiff_t ntargets;
+ ptrdiff_t i, ntargets;
GtkTargetEntry *gtargets;
if (timestamp == GDK_CURRENT_TIME)
gtargets = xzalloc (sizeof *gtargets * ASIZE (targets));
ntargets = 0;
- for (ptrdiff_t i = 0; i < ASIZE (targets); i++)
+ for (i = 0; i < ASIZE (targets); ++i)
{
if (SYMBOLP (AREF (targets, i)))
gtargets[ntargets++].target
/* Subroutines of pgtk_get_window_property_as_lisp_data */
+static ptrdiff_t
+pgtk_size_for_format (gint format)
+{
+ switch (format)
+ {
+ case 8:
+ return sizeof (unsigned char);
+ case 16:
+ return sizeof (unsigned short);
+ case 32:
+ return sizeof (unsigned long);
+
+ default:
+ emacs_abort ();
+ }
+}
+
/* Use xfree, not g_free, to free the data obtained with this function. */
static void
-pgtk_get_window_property (GdkWindow *window, void **data_ret,
+pgtk_get_window_property (GdkWindow *window, unsigned char **data_ret,
ptrdiff_t *bytes_ret, GdkAtom *actual_type_ret,
- int *actual_format_ret)
+ int *actual_format_ret, unsigned long *actual_size_ret)
{
gint length, actual_format;
unsigned char *data;
+ ptrdiff_t element_size;
void *xdata;
GdkAtom actual_type;
+ unsigned long i;
+ unsigned int *idata;
+ unsigned long *ldata;
data = NULL;
*actual_type_ret = GDK_NONE;
*bytes_ret = 0;
*actual_format_ret = 8;
+ *actual_size_ret = 0;
return;
}
- if (! (actual_type == GDK_SELECTION_TYPE_ATOM
- || actual_type == gdk_atom_intern_static_string ("ATOM_PAIR")))
- actual_type = GDK_NONE;
+ if (actual_type == GDK_SELECTION_TYPE_ATOM
+ || actual_type == gdk_atom_intern_static_string ("ATOM_PAIR"))
+ {
+ /* GDK should not allow anything else. */
+ eassert (actual_format == 32);
+
+ length = length / sizeof (GdkAtom);
+ xdata = xmalloc (sizeof (GdkAtom) * length + 1);
+ memcpy (xdata, data, 1 + length * sizeof (GdkAtom));
+
+ g_free (data);
- if (ULONG_WIDTH > 32 && actual_format == 32)
+ *data_ret = xdata;
+ *actual_type_ret = actual_type;
+ *bytes_ret = length * sizeof (GdkAtom);
+ *actual_format_ret = 32;
+ *actual_size_ret = length;
+
+ return;
+ }
+
+ element_size = pgtk_size_for_format (actual_format);
+ length = length / element_size;
+
+ /* Add an extra byte on the end. GDK guarantees that it is
+ NULL. */
+ xdata = xmalloc (1 + element_size * length);
+ memcpy (xdata, data, 1 + element_size * length);
+
+ if (actual_format == 32 && LONG_WIDTH > 32)
{
- unsigned long int *ldata = (unsigned long int *) data;
- gint n = length / sizeof *ldata;
- unsigned int *idata;
- length = n * sizeof *idata;
- idata = xdata = xmalloc (length);
- for (gint i = 0; i < n; i++)
+ ldata = (typeof (ldata)) data;
+ idata = xdata;
+
+ for (i = 0; i < length; ++i)
idata[i] = ldata[i];
+
+ /* There is always enough space in idata. */
+ idata[length] = 0;
+ *bytes_ret = sizeof *idata * length;
}
else
- {
- /* Add an extra byte on the end. GDK guarantees that it is
- NULL. */
- xdata = xmalloc (length + 1);
- memcpy (xdata, data, length + 1);
- }
-
- *bytes_ret = length;
+ /* I think GDK itself prevents element_size from exceeding the
+ length at which this computation fails. */
+ *bytes_ret = element_size * length;
/* Now free the original `data' allocated by GDK. */
g_free (data);
*data_ret = xdata;
*actual_type_ret = GDK_NONE;
+ *actual_size_ret = length;
*actual_format_ret = actual_format;
*actual_type_ret = actual_type;
}
{
GdkAtom actual_type;
int actual_format;
- void *data;
+ unsigned long actual_size;
+ unsigned char *data = 0;
ptrdiff_t bytes = 0;
Lisp_Object val;
GdkDisplay *display = dpyinfo->display;
pgtk_get_window_property (window, &data, &bytes,
- &actual_type, &actual_format);
+ &actual_type, &actual_format,
+ &actual_size);
if (!data)
{
static Lisp_Object
selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo,
- void const *data,
+ const unsigned char *data,
ptrdiff_t size, GdkAtom type, int format)
{
if (type == gdk_atom_intern_static_string ("NULL"))
{
Lisp_Object str, lispy_type;
- str = make_unibyte_string (data, size);
+ str = make_unibyte_string ((char *) data, size);
/* Indicate that this string is from foreign selection by a text
property `foreign-selection' so that the caller of
x-get-selection-internal (usually x-get-selection) can know
/* Treat ATOM_PAIR type similar to list of atoms. */
|| type == gdk_atom_intern_static_string ("ATOM_PAIR")))
{
- GdkAtom const *idata = data;
+ ptrdiff_t i;
+ GdkAtom *idata = (GdkAtom *) data;
if (size == sizeof (GdkAtom))
return gdk_atom_to_symbol (idata[0]);
{
Lisp_Object v = make_nil_vector (size / sizeof (GdkAtom));
- for (ptrdiff_t i = 0; i < size / sizeof (GdkAtom); i++)
+ for (i = 0; i < size / sizeof (GdkAtom); i++)
ASET (v, i, gdk_atom_to_symbol (idata[i]));
return v;
}
*/
else if (format == 16)
{
+ ptrdiff_t i;
Lisp_Object v = make_uninit_vector (size / 2);
if (type == GDK_SELECTION_TYPE_INTEGER)
{
- for (ptrdiff_t i = 0; i < size / 2; i++)
+ for (i = 0; i < size / 2; i++)
{
short j = ((short *) data) [i];
ASET (v, i, make_fixnum (j));
}
else
{
- for (ptrdiff_t i = 0; i < size / 2; i++)
+ for (i = 0; i < size / 2; i++)
{
unsigned short j = ((unsigned short *) data) [i];
ASET (v, i, make_fixnum (j));
}
else
{
+ ptrdiff_t i;
Lisp_Object v = make_nil_vector (size / sizeof (gint));
if (type == GDK_SELECTION_TYPE_INTEGER)
{
- for (ptrdiff_t i = 0; i < size / sizeof (gint); i++)
+ for (i = 0; i < size / sizeof (gint); i++)
{
int j = ((gint *) data) [i];
ASET (v, i, INT_TO_INTEGER (j));
}
else
{
- for (ptrdiff_t i = 0; i < size / sizeof (gint); i++)
+ for (i = 0; i < size / sizeof (gint); i++)
{
unsigned int j = ((unsigned int *) data) [i];
ASET (v, i, INT_TO_INTEGER (j));
a set of 16 or 32 bit INTEGERs;
or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...]
*/
+ ptrdiff_t i;
ptrdiff_t size = ASIZE (obj);
if (SYMBOLP (AREF (obj, 0)))
void *data;
GdkAtom *x_atoms;
if (NILP (type)) type = QATOM;
- for (ptrdiff_t i = 0; i < size; i++)
+ for (i = 0; i < size; i++)
if (!SYMBOLP (AREF (obj, i)))
signal_error ("All elements of selection vector must have same type", obj);
x_atoms = data;
cs->format = 32;
cs->size = size;
- for (ptrdiff_t i = 0; i < size; i++)
+ for (i = 0; i < size; i++)
x_atoms[i] = symbol_to_gdk_atom (AREF (obj, i));
}
else
unsigned long *x_atoms;
short *shorts;
if (NILP (type)) type = QINTEGER;
- for (ptrdiff_t i = 0; i < size; i++)
+ for (i = 0; i < size; i++)
{
if (! RANGED_FIXNUMP (SHRT_MIN, AREF (obj, i), SHRT_MAX))
{
shorts = data;
cs->format = format;
cs->size = size;
- for (ptrdiff_t i = 0; i < size; i++)
+ for (i = 0; i < size; i++)
{
if (format == 32)
x_atoms[i] = cons_to_gdk_long (AREF (obj, i));
}
if (VECTORP (obj))
{
+ ptrdiff_t i;
ptrdiff_t size = ASIZE (obj);
+ Lisp_Object copy;
if (size == 1)
return clean_local_selection_data (AREF (obj, 0));
- Lisp_Object copy = make_nil_vector (size);
- for (ptrdiff_t i = 0; i < size; i++)
+ copy = make_nil_vector (size);
+ for (i = 0; i < size; i++)
ASET (copy, i, clean_local_selection_data (AREF (obj, i)));
return copy;
}