/* X Selection processing for Emacs.
- Copyright (C) 1993-1997, 2000-2011 Free Software Foundation, Inc.
+ Copyright (C) 1993-1997, 2000-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#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).
static Atom conversion_fail_tag;
/* Used as an unwind-protect clause so that, if a selection-converter signals
- an error, we tell the requester that we were unable to do what they wanted
+ an error, we tell the requestor that we were unable to do what they wanted
before we throw to top-level or go into the debugger or whatever. */
static Lisp_Object
#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);
bytes_remaining = cs->size;
bytes_remaining *= format_bytes;
- /* Wait for the requester to ack by deleting the property.
+ /* Wait for the requestor to ack by deleting the property.
This can run Lisp code (process handlers) or signal. */
if (! had_errors)
{
if (had_errors) break;
- /* Wait for the requester to ack this chunk by deleting
+ /* Wait for the requestor to ack this chunk by deleting
the property. This can run Lisp code or signal. */
TRACE1 ("Waiting for increment ACK (deletion of %s)",
XGetAtomName (display, cs->property));
}
/* Now write a zero-length chunk to the property to tell the
- requester that we're done. */
+ requestor that we're done. */
BLOCK_INPUT;
if (! waiting_for_other_props_on_window (display, window))
XSelectInput (display, window, 0L);
/* The window we're communicating with may have been deleted
in the meantime (that's a real situation from a bug report).
In this case, there may be events in the event queue still
- refering to the deleted window, and we'll get a BadWindow error
+ referring to the deleted window, and we'll get a BadWindow error
in XTread_socket when processing the events. I don't have
an idea how to fix that. gerd, 2001-01-98. */
/* 2004-09-10: XSync and UNBLOCK so that possible protocol errors are
/* Otherwise, record the converted selection to binary. */
cs = xmalloc (sizeof (struct selection_data));
+ cs->data = NULL;
cs->nofree = 1;
cs->property = property;
cs->wait_object = NULL;
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;
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];
+ EMACS_INT 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. */
|| (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;
- (*(long **) data_ret) [0] = cons_to_signed (obj, X_LONG_MIN, X_LONG_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))
if (NILP (type)) type = QINTEGER;
for (i = 0; i < size; i++)
{
- intmax_t v = cons_to_signed (XVECTOR (obj)->contents[i],
- X_LONG_MIN, X_LONG_MAX);
- if (X_SHRT_MIN <= v && v <= X_SHRT_MAX)
+ 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);
*size_ret = size;
for (i = 0; i < size; i++)
{
- long v = cons_to_signed (XVECTOR (obj)->contents[i],
- X_LONG_MIN, X_LONG_MAX);
if (format == 32)
- (*((long **) data_ret)) [i] = v;
+ (*((unsigned long **) data_ret)) [i] =
+ cons_to_x_long (XVECTOR (obj)->contents[i]);
else
- (*((short **) data_ret)) [i] = v;
+ (*((short **) data_ret)) [i] =
+ XINT (XVECTOR (obj)->contents[i]);
}
}
}
anything that the functions on `selection-converter-alist' know about.
FRAME should be a frame that should own the selection. If omitted or
-nil, it defaults to the selected frame. */)
+nil, it defaults to the selected frame.
+
+On Nextstep, FRAME is unused. */)
(Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
{
if (NILP (frame)) frame = selected_frame;
DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
Sx_get_selection_internal, 2, 4, 0,
doc: /* Return text selected from some X window.
-SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+SELECTION-SYMBOL is typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
\(Those are literal upper-case symbol names, since that's what X expects.)
-TYPE is the type of data desired, typically `STRING'.
-TIME_STAMP is the time to use in the XConvertSelection call for foreign
+TARGET-TYPE is the type of data desired, typically `STRING'.
+
+TIME-STAMP is the time to use in the XConvertSelection call for foreign
selections. If omitted, defaults to the time for the last event.
TERMINAL should be a terminal object or a frame specifying the X
server to query. If omitted or nil, that stands for the selected
-frame's display, or the first available X display. */)
+frame's display, or the first available X display.
+
+On Nextstep, TIME-STAMP and TERMINAL are unused. */)
(Lisp_Object selection_symbol, Lisp_Object target_type,
Lisp_Object time_stamp, Lisp_Object terminal)
{
doc: /* If we own the selection SELECTION, disown it.
Disowning it means there is no such selection.
+Sets the last-change time for the selection to TIME-OBJECT (by default
+the time of the last event).
+
TERMINAL should be a terminal object or a frame specifying the X
server to query. If omitted or nil, that stands for the selected
-frame's display, or the first available X display. */)
+frame's display, or the first available X display.
+
+On Nextstep, the TIME-OBJECT and TERMINAL arguments are unused.
+On MS-DOS, all this does is return non-nil if we own the selection. */)
(Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
{
Time timestamp;
TERMINAL should be a terminal object or a frame specifying the X
server to query. If omitted or nil, that stands for the selected
-frame's display, or the first available X display. */)
+frame's display, or the first available X display.
+
+On Nextstep, TERMINAL is unused. */)
(Lisp_Object selection, Lisp_Object terminal)
{
struct frame *f = frame_for_x_selection (terminal);
0, 2, 0,
doc: /* Whether there is an owner for the given X selection.
SELECTION should be the name of the selection in question, typically
-one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. (X expects
-these literal upper-case names.) The symbol nil is the same as
-`PRIMARY', and t is the same as `SECONDARY'.
+one of the symbols `PRIMARY', `SECONDARY', `CLIPBOARD', or
+`CLIPBOARD_MANAGER' (X expects these literal upper-case names.) The
+symbol nil is the same as `PRIMARY', and t is the same as `SECONDARY'.
TERMINAL should be a terminal object or a frame specifying the X
server to query. If omitted or nil, that stands for the selected
-frame's display, or the first available X display. */)
+frame's display, or the first available X display.
+
+On Nextstep, TERMINAL is unused. */)
(Lisp_Object selection, Lisp_Object terminal)
{
Window owner;
local_frame = XCAR (XCDR (XCDR (XCDR (local_selection))));
if (FRAME_LIVE_P (XFRAME (local_frame)))
- internal_condition_case_1 (x_clipboard_manager_save, local_frame,
- Qt, x_clipboard_manager_error_2);
+ {
+ Lisp_Object args[1];
+ args[0] = build_string ("Saving clipboard to X clipboard manager...");
+ Fmessage (1, args);
+
+ internal_condition_case_1 (x_clipboard_manager_save, local_frame,
+ Qt, x_clipboard_manager_error_2);
+ }
}
}
F is the frame to be used to look up X atoms if the TYPE is XA_ATOM.
DATA is a C array of values to be converted.
TYPE is the type of the data. Only XA_ATOM is special, it converts
- each number in DATA to its corresponfing X atom as a symbol.
+ each number in DATA to its corresponding X atom as a symbol.
FORMAT is 8, 16 or 32 and gives the size in bits for each C value to
be stored in RET.
SIZE is the number of elements in DATA.
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;
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;