#ifdef TRACE_SELECTION
#define TRACE0(fmt) \
- fprintf (stderr, "%d: " fmt "\n", getpid ())
+ fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid ())
#define TRACE1(fmt, a0) \
- fprintf (stderr, "%d: " fmt "\n", getpid (), a0)
+ fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid (), a0)
#define TRACE2(fmt, a0, a1) \
- fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1)
+ fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid (), a0, a1)
#define TRACE3(fmt, a0, a1, a2) \
- fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1, a2)
+ fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid (), a0, a1, a2)
#else
#define TRACE0(fmt) (void) 0
#define TRACE1(fmt, a0) (void) 0
is not necessarily sizeof (long). */
#define X_LONG_SIZE 4
-/* Maximum unsigned 'short' and 'long' values suitable for libX11. */
-#define X_USHRT_MAX 0xffff
-#define X_ULONG_MAX 0xffffffff
+/* Extreme 'short' and 'long' values suitable for libX11. */
+#define X_SHRT_MAX 0x7fff
+#define X_SHRT_MIN (-1 - X_SHRT_MAX)
+#define X_LONG_MAX 0x7fffffff
+#define X_LONG_MIN (-1 - X_LONG_MAX)
+#define X_ULONG_MAX 0xffffffffUL
/* If this is a smaller number than the max-request-size of the display,
emacs will use INCR selection transfer when the selection is larger
\f
/* Given a selection-name and desired type, look up our local copy of
the selection value and convert it to the type.
- The value is nil or a string.
+ Return nil, a string, a vector, a symbol, an integer, or a cons
+ that CONS_TO_INTEGER could plausibly handle.
This function is used both for remote requests (LOCAL_REQUEST is zero)
and for local x-get-selection-internal (LOCAL_REQUEST is nonzero).
{
Lisp_Object local_value;
Lisp_Object handler_fn, value, check;
- int count;
local_value = LOCAL_SELECTION (selection_symbol, dpyinfo);
/* Don't allow a quit within the converter.
When the user types C-g, he would be surprised
if by luck it came during a converter. */
- count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
specbind (Qinhibit_quit, Qt);
CHECK_SYMBOL (target_type);
#endif /* TRACE_SELECTION */
static void
-x_reply_selection_request (struct input_event *event, struct x_display_info *dpyinfo)
+x_reply_selection_request (struct input_event *event,
+ struct x_display_info *dpyinfo)
{
XEvent reply_base;
XSelectionEvent *reply = &(reply_base.xselection);
Window window = SELECTION_EVENT_REQUESTOR (event);
ptrdiff_t bytes_remaining;
int max_bytes = selection_quantum (display);
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
struct selection_data *cs;
reply->type = SelectionNotify;
else
{
/* Send an INCR tag to initiate incremental transfer. */
- unsigned long value[1];
+ long value[1];
TRACE2 ("Start sending %"pD"d bytes incrementally (%s)",
bytes_remaining, XGetAtomName (display, cs->property));
/* XChangeProperty expects an array of long even if long is
more than 32 bits. */
- value[0] = min (bytes_remaining, X_ULONG_MAX);
+ value[0] = min (bytes_remaining, X_LONG_MAX);
XChangeProperty (display, window, cs->property,
dpyinfo->Xatom_INCR, 32, PropModeReplace,
(unsigned char *) value, 1);
Atom property = SELECTION_EVENT_PROPERTY (event);
Lisp_Object local_selection_data;
int success = 0;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
GCPRO2 (local_selection_data, target_symbol);
if (!dpyinfo) goto DONE;
this awaited property change. */
static struct prop_location *
-expect_property_change (Display *display, Window window, Atom property, int state)
+expect_property_change (Display *display, Window window,
+ Atom property, int state)
{
struct prop_location *pl = (struct prop_location *) xmalloc (sizeof *pl);
pl->identifier = ++prop_location_identifier;
wait_for_property_change (struct prop_location *location)
{
int secs, usecs;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
if (property_change_reply_object)
abort ();
convert it to a cons of integers, 16 bits in each half.
*/
else if (format == 32 && size == sizeof (int))
- return INTEGER_TO_CONS (((unsigned int *) data) [0]);
+ return INTEGER_TO_CONS (((int *) data) [0]);
else if (format == 16 && size == sizeof (short))
- return make_number (((unsigned short *) data) [0]);
+ return make_number (((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.)
v = Fmake_vector (make_number (size / 2), make_number (0));
for (i = 0; i < size / 2; i++)
{
- EMACS_INT j = ((unsigned short *) data) [i];
+ short j = ((short *) data) [i];
Faset (v, make_number (i), make_number (j));
}
return v;
make_number (0));
for (i = 0; i < size / X_LONG_SIZE; i++)
{
- unsigned int j = ((unsigned int *) data) [i];
+ int j = ((int *) data) [i];
Faset (v, make_number (i), INTEGER_TO_CONS (j));
}
return v;
}
}
+/* Convert OBJ to an X long value, and return it as unsigned long.
+ OBJ should be an integer or a cons representing an integer.
+ Treat values in the range X_LONG_MAX + 1 .. X_ULONG_MAX as X
+ unsigned long values: in theory these values are supposed to be
+ signed but in practice unsigned 32-bit data are communicated via X
+ selections and we need to support that. */
+static unsigned long
+cons_to_x_long (Lisp_Object obj)
+{
+ if (X_ULONG_MAX <= INTMAX_MAX
+ || XINT (INTEGERP (obj) ? obj : XCAR (obj)) < 0)
+ return cons_to_signed (obj, X_LONG_MIN, min (X_ULONG_MAX, INTMAX_MAX));
+ else
+ return cons_to_unsigned (obj, X_ULONG_MAX);
+}
/* Use xfree, not XFree, to free the data obtained with this function. */
(*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj);
if (NILP (type)) type = QATOM;
}
- else if (RANGED_INTEGERP (0, obj, X_USHRT_MAX))
+ else if (RANGED_INTEGERP (X_SHRT_MIN, obj, X_SHRT_MAX))
{
*data_ret = (unsigned char *) xmalloc (sizeof (short) + 1);
*format_ret = 16;
*size_ret = 1;
(*data_ret) [sizeof (short)] = 0;
- (*(unsigned short **) data_ret) [0] = XINT (obj);
+ (*(short **) data_ret) [0] = XINT (obj);
if (NILP (type)) type = QINTEGER;
}
else if (INTEGERP (obj)
|| (CONSP (XCDR (obj))
&& INTEGERP (XCAR (XCDR (obj)))))))
{
- *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1);
+ *data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1);
*format_ret = 32;
*size_ret = 1;
- (*data_ret) [sizeof (long)] = 0;
- (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, X_ULONG_MAX);
+ (*data_ret) [sizeof (unsigned long)] = 0;
+ (*(unsigned long **) data_ret) [0] = cons_to_x_long (obj);
if (NILP (type)) type = QINTEGER;
}
else if (VECTORP (obj))
int data_size = sizeof (short);
if (NILP (type)) type = QINTEGER;
for (i = 0; i < size; i++)
- if (X_USHRT_MAX
- < cons_to_unsigned (XVECTOR (obj)->contents[i], X_ULONG_MAX))
- {
- /* Use sizeof (long) even if it is more than 32 bits.
- See comment in x_get_window_property and
- x_fill_property_data. */
- data_size = sizeof (long);
- format = 32;
- }
+ {
+ if (! RANGED_INTEGERP (X_SHRT_MIN, XVECTOR (obj)->contents[i],
+ X_SHRT_MAX))
+ {
+ /* Use sizeof (long) even if it is more than 32 bits.
+ See comment in x_get_window_property and
+ x_fill_property_data. */
+ data_size = sizeof (long);
+ format = 32;
+ break;
+ }
+ }
*data_ret = xnmalloc (size, data_size);
*format_ret = format;
*size_ret = size;
for (i = 0; i < size; i++)
- if (format == 32)
- (*((unsigned long **) data_ret)) [i] =
- cons_to_unsigned (XVECTOR (obj)->contents[i], X_ULONG_MAX);
- else
- (*((unsigned short **) data_ret)) [i] =
- cons_to_unsigned (XVECTOR (obj)->contents[i], X_USHRT_MAX);
+ {
+ if (format == 32)
+ (*((unsigned long **) data_ret)) [i] =
+ cons_to_x_long (XVECTOR (obj)->contents[i]);
+ else
+ (*((short **) data_ret)) [i] =
+ XINT (XVECTOR (obj)->contents[i]);
+ }
}
}
else
return Qnil;
if (dpyinfo->x_dnd_atoms_length == dpyinfo->x_dnd_atoms_size)
- {
- if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *dpyinfo->x_dnd_atoms / 2
- < dpyinfo->x_dnd_atoms_size)
- memory_full (SIZE_MAX);
- dpyinfo->x_dnd_atoms = xrealloc (dpyinfo->x_dnd_atoms,
- (2 * sizeof *dpyinfo->x_dnd_atoms
- * dpyinfo->x_dnd_atoms_size));
- dpyinfo->x_dnd_atoms_size *= 2;
- }
+ dpyinfo->x_dnd_atoms =
+ xpalloc (dpyinfo->x_dnd_atoms, &dpyinfo->x_dnd_atoms_size,
+ 1, -1, sizeof *dpyinfo->x_dnd_atoms);
dpyinfo->x_dnd_atoms[dpyinfo->x_dnd_atoms_length++] = x_atom;
return Qnil;
/* Convert an XClientMessageEvent to a Lisp event of type DRAG_N_DROP_EVENT. */
int
-x_handle_dnd_message (struct frame *f, XClientMessageEvent *event, struct x_display_info *dpyinfo, struct input_event *bufp)
+x_handle_dnd_message (struct frame *f, XClientMessageEvent *event,
+ struct x_display_info *dpyinfo, struct input_event *bufp)
{
Lisp_Object vec;
Lisp_Object frame;
unsigned long size = 160/event->format;
int x, y;
unsigned char *data = (unsigned char *) event->data.b;
- unsigned int idata[5];
+ int idata[5];
ptrdiff_t i;
for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
with the high 16 bits from the car and the lower 16 bit from the cdr.
If more values than fits into the event is given, the excessive values
are ignored. */)
- (Lisp_Object display, Lisp_Object dest, Lisp_Object from, Lisp_Object message_type, Lisp_Object format, Lisp_Object values)
+ (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
+ Lisp_Object message_type, Lisp_Object format, Lisp_Object values)
{
struct x_display_info *dpyinfo = check_x_display_info (display);
CHECK_STRING (message_type);
- x_send_client_event(display, dest, from,
- XInternAtom (dpyinfo->display,
- SSDATA (message_type),
- False),
- format, values);
+ x_send_client_event (display, dest, from,
+ XInternAtom (dpyinfo->display,
+ SSDATA (message_type),
+ False),
+ format, values);
return Qnil;
}
void
-x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, Atom message_type, Lisp_Object format, Lisp_Object values)
+x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
+ Atom message_type, Lisp_Object format, Lisp_Object values)
{
struct x_display_info *dpyinfo = check_x_display_info (display);
Window wdest;
if (x_check_property_data (values) == -1)
error ("Bad data in VALUES, must be number, cons or string");
- event.xclient.type = ClientMessage;
- event.xclient.format = XFASTINT (format);
-
- if (event.xclient.format != 8 && event.xclient.format != 16
- && event.xclient.format != 32)
+ if (XINT (format) != 8 && XINT (format) != 16 && XINT (format) != 32)
error ("FORMAT must be one of 8, 16 or 32");
+ event.xclient.type = ClientMessage;
+ event.xclient.format = XINT (format);
+
if (FRAMEP (dest) || NILP (dest))
{
struct frame *fdest = check_x_frame (dest);