/* X Selection processing for Emacs.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2003
Free Software Foundation.
This file is part of GNU Emacs.
static Atom symbol_to_x_atom P_ ((struct x_display_info *, Display *,
Lisp_Object));
static void x_own_selection P_ ((Lisp_Object, Lisp_Object));
-static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object));
+static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int));
static void x_decline_selection_request P_ ((struct input_event *));
static Lisp_Object x_selection_request_lisp_error P_ ((Lisp_Object));
static Lisp_Object queue_selection_requests_unwind P_ ((Lisp_Object));
QATOM_PAIR;
Lisp_Object QCOMPOUND_TEXT; /* This is a type of selection. */
+Lisp_Object QUTF8_STRING; /* This is a type of selection. */
+
+Lisp_Object Qcompound_text_with_extensions;
#ifdef CUT_BUFFER_SUPPORT
Lisp_Object QCUT_BUFFER0, QCUT_BUFFER1, QCUT_BUFFER2, QCUT_BUFFER3,
/* 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
than this. The max-request-size is usually around 64k, so if you want
- emacs to use incremental selection transfers when the selection is
+ emacs to use incremental selection transfers when the selection is
smaller than that, set this. I added this mostly for debugging the
incremental transfer stuff, but it might improve server performance. */
#define MAX_SELECTION_QUANTUM 0xFFFFFF
/* This is an alist whose CARs are selection-types (whose names are the same
as the names of X Atoms) and whose CDRs are the names of Lisp functions to
- call to convert the given Emacs selection value to a string representing
+ call to convert the given Emacs selection value to a string representing
the given selection type. This is for Lisp-level extension of the emacs
selection handling. */
static Lisp_Object Vselection_converter_alist;
/* If the selection owner takes too long to reply to a selection request,
we give up on it. This is in milliseconds (0 = no timeout.) */
-static int x_selection_timeout;
+static EMACS_INT x_selection_timeout;
\f
/* Utility functions */
static Lisp_Object selection_data_to_lisp_data ();
static Lisp_Object x_get_window_property_as_lisp_data ();
-/* This converts a Lisp symbol to a server Atom, avoiding a server
+/* This converts a Lisp symbol to a server Atom, avoiding a server
roundtrip whenever possible. */
static Atom
if (EQ (sym, QTIMESTAMP)) return dpyinfo->Xatom_TIMESTAMP;
if (EQ (sym, QTEXT)) return dpyinfo->Xatom_TEXT;
if (EQ (sym, QCOMPOUND_TEXT)) return dpyinfo->Xatom_COMPOUND_TEXT;
+ if (EQ (sym, QUTF8_STRING)) return dpyinfo->Xatom_UTF8_STRING;
if (EQ (sym, QDELETE)) return dpyinfo->Xatom_DELETE;
if (EQ (sym, QMULTIPLE)) return dpyinfo->Xatom_MULTIPLE;
if (EQ (sym, QINCR)) return dpyinfo->Xatom_INCR;
#endif
if (!SYMBOLP (sym)) abort ();
- TRACE1 (" XInternAtom %s", (char *) XSYMBOL (sym)->name->data);
+ TRACE1 (" XInternAtom %s", (char *) SDATA (SYMBOL_NAME (sym)));
BLOCK_INPUT;
- val = XInternAtom (display, (char *) XSYMBOL (sym)->name->data, False);
+ val = XInternAtom (display, (char *) SDATA (SYMBOL_NAME (sym)), False);
UNBLOCK_INPUT;
return val;
}
struct x_display_info *dpyinfo;
char *str;
Lisp_Object val;
-
+
if (! atom)
return Qnil;
-
+
switch (atom)
{
case XA_PRIMARY:
return QTEXT;
if (atom == dpyinfo->Xatom_COMPOUND_TEXT)
return QCOMPOUND_TEXT;
+ if (atom == dpyinfo->Xatom_UTF8_STRING)
+ return QUTF8_STRING;
if (atom == dpyinfo->Xatom_DELETE)
return QDELETE;
if (atom == dpyinfo->Xatom_MULTIPLE)
}
\f
/* Do protocol to assert ourself as a selection owner.
- Update the Vselection_alist so that we can reply to later requests for
+ Update the Vselection_alist so that we can reply to later requests for
our selection. */
static void
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (sf);
int count;
- CHECK_SYMBOL (selection_name, 0);
+ CHECK_SYMBOL (selection_name);
selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name);
BLOCK_INPUT;
for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
if (EQ (prev_value, Fcar (XCDR (rest))))
{
- XCDR (rest) = Fcdr (XCDR (rest));
+ XSETCDR (rest, Fcdr (XCDR (rest)));
break;
}
}
/* 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.
- This function is used both for remote requests
- and for local x-get-selection-internal.
+ This function is used both for remote requests (LOCAL_REQUEST is zero)
+ and for local x-get-selection-internal (LOCAL_REQUEST is nonzero).
This calls random Lisp code, and may signal or gc. */
static Lisp_Object
-x_get_local_selection (selection_symbol, target_type)
+x_get_local_selection (selection_symbol, target_type, local_request)
Lisp_Object selection_symbol, target_type;
+ int local_request;
{
Lisp_Object local_value;
Lisp_Object handler_fn, value, type, check;
pair = XVECTOR (pairs)->contents [i];
XVECTOR (pair)->contents [1]
= x_get_local_selection (XVECTOR (pair)->contents [0],
- XVECTOR (pair)->contents [1]);
+ XVECTOR (pair)->contents [1],
+ local_request);
}
return pairs;
}
/* 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_ptr - specpdl;
+ count = SPECPDL_INDEX ();
specbind (Qinhibit_quit, Qt);
- CHECK_SYMBOL (target_type, 0);
+ CHECK_SYMBOL (target_type);
handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist));
+ /* gcpro is not needed here since nothing but HANDLER_FN
+ is live, and that ought to be a symbol. */
+
if (!NILP (handler_fn))
value = call3 (handler_fn,
- selection_symbol, target_type,
+ selection_symbol, (local_request ? Qnil : target_type),
XCAR (XCDR (local_value)));
else
value = Qnil;
&& SYMBOLP (XCAR (value)))
type = XCAR (value),
check = XCDR (value);
-
+
if (STRINGP (check)
|| VECTORP (check)
|| SYMBOLP (check)
{
XSelectionEvent reply;
int count;
-
+
reply.type = SelectionNotify;
reply.display = SELECTION_EVENT_DISPLAY (event);
reply.requestor = SELECTION_EVENT_REQUESTOR (event);
if (x_window_to_frame (dpyinfo, window)) /* #### debug */
error ("Attempt to transfer an INCR to ourself!");
-
+
TRACE2 ("Start sending %d bytes incrementally (%s)",
bytes_remaining, XGetAtomName (display, reply.property));
wait_object = expect_property_change (display, window, reply.property,
32, PropModeReplace,
(unsigned char *) &bytes_remaining, 1);
XSelectInput (display, window, PropertyChangeMask);
-
+
/* Tell 'em the INCR data is there... */
TRACE0 ("Send SelectionNotify event");
XSendEvent (display, window, False, 0L, (XEvent *) &reply);
TRACE1 ("Sending increment of %d bytes", i);
TRACE1 ("Set %s to increment data",
XGetAtomName (display, reply.property));
-
+
/* Append the next chunk of data to the property. */
XChangeProperty (display, window, reply.property, type, format,
PropModeAppend, data, i / format_bytes);
XGetAtomName (display, reply.property));
wait_for_property_change (wait_object);
}
-
+
/* Now write a zero-length chunk to the property to tell the
requester that we're done. */
BLOCK_INPUT;
TRACE0 ("Done sending incrementally");
}
+ /* rms, 2003-01-03: I think I have fixed this bug. */
/* 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
}
x_selection_current_request = event;
- count = BINDING_STACK_SIZE ();
+ count = SPECPDL_INDEX ();
selection_request_dpyinfo = dpyinfo;
record_unwind_protect (x_selection_request_lisp_error, Qnil);
if (EQ (target_symbol, QMULTIPLE))
target_symbol = fetch_multiple_target (event);
#endif
-
+
/* Convert lisp objects back into binary data */
-
+
converted_selection
- = x_get_local_selection (selection_symbol, target_symbol);
-
+ = x_get_local_selection (selection_symbol, target_symbol, 0);
+
if (! NILP (converted_selection))
{
unsigned char *data;
lisp_data_to_selection_data (SELECTION_EVENT_DISPLAY (event),
converted_selection,
&data, &type, &size, &format, &nofree);
-
+
x_reply_selection_request (event, format, data, size, type);
successful_p = Qt;
DONE:
- UNGCPRO;
-
/* Let random lisp code notice that the selection has been asked for. */
{
Lisp_Object rest;
for (; CONSP (rest); rest = Fcdr (rest))
call3 (Fcar (rest), selection_symbol, target_symbol, successful_p);
}
+
+ UNGCPRO;
}
\f
/* Handle a SelectionClear event EVENT, which indicates that some
Display *display = SELECTION_EVENT_DISPLAY (event);
Atom selection = SELECTION_EVENT_SELECTION (event);
Time changed_owner_time = SELECTION_EVENT_TIME (event);
-
+
Lisp_Object selection_symbol, local_selection_data;
Time local_selection_time;
struct x_display_info *dpyinfo = x_display_info_for_display (display);
for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
if (EQ (local_selection_data, Fcar (XCDR (rest))))
{
- XCDR (rest) = Fcdr (XCDR (rest));
+ XSETCDR (rest, Fcdr (XCDR (rest)));
break;
}
}
redisplay_preserve_echo_area (22);
#endif
}
- XCDR (rest) = Fcdr (XCDR (rest));
+ XSETCDR (rest, Fcdr (XCDR (rest)));
break;
}
}
struct prop_location *location;
{
int secs, usecs;
- int count = specpdl_ptr - specpdl;
+ int count = SPECPDL_INDEX ();
Lisp_Object tem;
tem = Fcons (Qnil, Qnil);
- XSETFASTINT (XCAR (tem), (EMACS_UINT)location >> 16);
- XSETFASTINT (XCDR (tem), (EMACS_UINT)location & 0xffff);
+ XSETCARFASTINT (tem, (EMACS_UINT)location >> 16);
+ XSETCDRFASTINT (tem, (EMACS_UINT)location & 0xffff);
/* Make sure to do unexpect_property_change if we quit or err. */
record_unwind_protect (wait_for_property_change_unwind, tem);
- XCAR (property_change_reply) = Qnil;
+ XSETCAR (property_change_reply, Qnil);
property_change_reply_object = location;
/* If the event we are waiting for arrives beyond here, it will set
/* If this is the one wait_for_property_change is waiting for,
tell it to wake up. */
if (rest == property_change_reply_object)
- XCAR (property_change_reply) = Qt;
+ XSETCAR (property_change_reply, Qt);
if (prev)
prev->next = rest->next;
xfree (rest);
return;
}
-
+
prev = rest;
rest = rest->next;
}
int size;
if (CONSP (obj))
return Fcons (XCAR (obj), copy_multiple_data (XCDR (obj)));
-
- CHECK_VECTOR (obj, 0);
+
+ CHECK_VECTOR (obj);
vec = Fmake_vector (size = XVECTOR (obj)->size, Qnil);
for (i = 0; i < size; i++)
{
Lisp_Object vec2 = XVECTOR (obj)->contents [i];
- CHECK_VECTOR (vec2, 0);
+ CHECK_VECTOR (vec2);
if (XVECTOR (vec2)->size != 2)
/* ??? Confusing error message */
Fsignal (Qerror, Fcons (build_string ("vectors must be of length 2"),
type_atom = symbol_to_x_atom (dpyinfo, display, target_type);
BLOCK_INPUT;
-
+
count = x_catch_errors (display);
-
+
TRACE2 ("Get selection %s, type %s",
XGetAtomName (display, type_atom),
XGetAtomName (display, target_property));
/* Prepare to block until the reply has been read. */
reading_selection_window = requestor_window;
reading_which_selection = selection_atom;
- XCAR (reading_selection_reply) = Qnil;
+ XSETCAR (reading_selection_reply, Qnil);
frame = some_frame_on_display (dpyinfo);
if (NILP (XCAR (reading_selection_reply)))
error ("Timed out waiting for reply from selection owner");
if (EQ (XCAR (reading_selection_reply), Qlambda))
- error ("No `%s' selection", XSYMBOL (selection_symbol)->name->data);
+ error ("No `%s' selection", SDATA (SYMBOL_NAME (selection_symbol)));
/* Otherwise, the selection is waiting for us on the requested property. */
return
unsigned char *tmp_data = 0;
int result;
int buffer_size = SELECTION_QUANTUM (display);
-
+
if (buffer_size > MAX_SELECTION_QUANTUM)
buffer_size = MAX_SELECTION_QUANTUM;
-
+
BLOCK_INPUT;
-
+
/* First probe the thing to find out how big it is. */
result = XGetWindowProperty (display, window, property,
0L, 0L, False, AnyPropertyType,
*bytes_ret = 0;
return;
}
-
+
/* This was allocated by Xlib, so use XFree. */
XFree ((char *) tmp_data);
-
+
if (*actual_type_ret == None || *actual_format_ret == 0)
{
UNBLOCK_INPUT;
total_size = bytes_remaining + 1;
*data_ret = (unsigned char *) xmalloc (total_size);
-
+
/* Now read, until we've gotten it all. */
while (bytes_remaining)
{
*actual_size_ret *= *actual_format_ret / 8;
bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret);
offset += *actual_size_ret;
-
+
/* This was allocated by Xlib, so use XFree. */
XFree ((char *) tmp_data);
}
TRACE0 (" Wait for property change");
wait_for_property_change (wait_object);
-
+
/* expect it again immediately, because x_get_window_property may
.. no it won't, I don't get it.
.. Ok, I get it now, the Xt code that implements INCR is broken. */
*size_bytes_ret = offset + tmp_size_bytes;
*data_ret = (unsigned char *) xrealloc (*data_ret, *size_bytes_ret);
}
-
+
bcopy (tmp_data, (*data_ret) + offset, tmp_size_bytes);
offset += tmp_size_bytes;
-
+
/* Use xfree, not XFree, because x_get_window_property
calls xmalloc itself. */
xfree (tmp_data);
selection_atom),
Qnil)));
}
-
+
if (actual_type == dpyinfo->Xatom_INCR)
{
/* That wasn't really the data, just the beginning. */
manner. */
val = selection_data_to_lisp_data (display, data, bytes,
actual_type, actual_format);
-
+
/* Use xfree, not XFree, because x_get_window_property
calls xmalloc itself. */
xfree ((char *) data);
coding.dst_multibyte = 1;
Vnext_selection_coding_system = Qnil;
coding.mode |= CODING_MODE_LAST_BLOCK;
+ /* We explicitely disable composition handling because
+ selection data should not contain any composition
+ sequence. */
+ coding.composing = COMPOSITION_DISABLED;
bufsize = decoding_buffer_size (&coding, size);
buf = (unsigned char *) xmalloc (bufsize);
decode_coding (&coding, data, buf, size, bufsize);
str = make_string_from_bytes ((char *) buf,
coding.produced_char, coding.produced);
xfree (buf);
+
+ if (SYMBOLP (coding.post_read_conversion)
+ && !NILP (Ffboundp (coding.post_read_conversion)))
+ str = run_pre_post_conversion_on_str (str, &coding, 0);
Vlast_coding_system_used = coding.symbol;
}
- compose_chars_in_text (0, XSTRING (str)->size, str);
+ compose_chars_in_text (0, SCHARS (str), str);
return str;
}
/* Convert a single atom to a Lisp_Symbol. Convert a set of atoms to
If the number is > 16 bits, convert it to a cons of integers,
16 bits in each half.
*/
- else if (format == 32 && size == sizeof (long))
- return long_to_cons (((unsigned long *) data) [0]);
+ else if (format == 32 && size == sizeof (int))
+ return long_to_cons (((unsigned int *) data) [0]);
else if (format == 16 && size == sizeof (short))
return make_number ((int) (((unsigned short *) data) [0]));
Lisp_Object v = Fmake_vector (make_number (size / 4), make_number (0));
for (i = 0; i < size / 4; i++)
{
- unsigned long j = ((unsigned long *) data) [i];
+ unsigned int j = ((unsigned int *) data) [i];
Faset (v, make_number (i), long_to_cons (j));
}
return v;
}
else if (STRINGP (obj))
{
- /* Since we are now handling multilingual text, we must consider
- sending back compound text. */
- int stringp;
-
- if (NILP (Vnext_selection_coding_system))
- Vnext_selection_coding_system = Vselection_coding_system;
-
- *format_ret = 8;
- *data_ret = x_encode_text (obj, Vnext_selection_coding_system,
- (int *) size_ret, &stringp);
- *nofree_ret = (*data_ret == XSTRING (obj)->data);
+ xassert (! STRING_MULTIBYTE (obj));
if (NILP (type))
- type = (stringp ? QSTRING : QCOMPOUND_TEXT);
- Vlast_coding_system_used = (*nofree_ret
- ? Qraw_text
- : Vnext_selection_coding_system);
- Vnext_selection_coding_system = Qnil;
+ type = QSTRING;
+ *format_ret = 8;
+ *size_ret = SBYTES (obj);
+ *data_ret = SDATA (obj);
+ *nofree_ret = 1;
}
else if (SYMBOLP (obj))
{
Lisp_Object pair = XVECTOR (obj)->contents [i];
if (XVECTOR (pair)->size != 2)
Fsignal (Qerror,
- Fcons (build_string
+ Fcons (build_string
("elements of the vector must be vectors of exactly two elements"),
Fcons (pair, Qnil)));
-
+
(*(Atom **) data_ret) [i * 2]
= symbol_to_x_atom (dpyinfo, display,
XVECTOR (pair)->contents [0]);
Fcons (build_string
("all elements of the vector must be of the same type"),
Fcons (obj, Qnil)));
-
+
}
#endif
else
return;
TRACE0 ("Received SelectionNotify");
- XCAR (reading_selection_reply)
- = (event->property != 0 ? Qt : Qlambda);
+ XSETCAR (reading_selection_reply,
+ (event->property != 0 ? Qt : Qlambda));
}
\f
DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
- Sx_own_selection_internal, 2, 2, 0,
- "Assert an X selection of the given TYPE with the given VALUE.\n\
-TYPE is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
-\(Those are literal upper-case symbol names, since that's what X expects.)\n\
-VALUE is typically a string, or a cons of two markers, but may be\n\
-anything that the functions on `selection-converter-alist' know about.")
- (selection_name, selection_value)
+ Sx_own_selection_internal, 2, 2, 0,
+ doc: /* Assert an X selection of the given TYPE with the given VALUE.
+TYPE is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+\(Those are literal upper-case symbol names, since that's what X expects.)
+VALUE is typically a string, or a cons of two markers, but may be
+anything that the functions on `selection-converter-alist' know about. */)
+ (selection_name, selection_value)
Lisp_Object selection_name, selection_value;
{
check_x ();
- CHECK_SYMBOL (selection_name, 0);
+ CHECK_SYMBOL (selection_name);
if (NILP (selection_value)) error ("selection-value may not be nil");
x_own_selection (selection_name, selection_value);
return selection_value;
will block until all of the data has arrived. */
DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
- Sx_get_selection_internal, 2, 2, 0,
- "Return text selected from some X window.\n\
-SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
-\(Those are literal upper-case symbol names, since that's what X expects.)\n\
-TYPE is the type of data desired, typically `STRING'.")
- (selection_symbol, target_type)
+ Sx_get_selection_internal, 2, 2, 0,
+ doc: /* Return text selected from some X window.
+SELECTION is a symbol, 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'. */)
+ (selection_symbol, target_type)
Lisp_Object selection_symbol, target_type;
{
Lisp_Object val = Qnil;
struct gcpro gcpro1, gcpro2;
GCPRO2 (target_type, val); /* we store newly consed data into these */
check_x ();
- CHECK_SYMBOL (selection_symbol, 0);
+ CHECK_SYMBOL (selection_symbol);
#if 0 /* #### MULTIPLE doesn't work yet */
if (CONSP (target_type)
&& XCAR (target_type) == QMULTIPLE)
{
- CHECK_VECTOR (XCDR (target_type), 0);
+ CHECK_VECTOR (XCDR (target_type));
/* So we don't destructively modify this... */
target_type = copy_multiple_data (target_type);
}
else
#endif
- CHECK_SYMBOL (target_type, 0);
+ CHECK_SYMBOL (target_type);
- val = x_get_local_selection (selection_symbol, target_type);
+ val = x_get_local_selection (selection_symbol, target_type, 1);
if (NILP (val))
{
}
DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
- Sx_disown_selection_internal, 1, 2, 0,
- "If we own the selection SELECTION, disown it.\n\
-Disowning it means there is no such selection.")
- (selection, time)
+ Sx_disown_selection_internal, 1, 2, 0,
+ doc: /* If we own the selection SELECTION, disown it.
+Disowning it means there is no such selection. */)
+ (selection, time)
Lisp_Object selection;
Lisp_Object time;
{
check_x ();
display = FRAME_X_DISPLAY (sf);
dpyinfo = FRAME_X_DISPLAY_INFO (sf);
- CHECK_SYMBOL (selection, 0);
+ CHECK_SYMBOL (selection);
if (NILP (time))
timestamp = last_event_timestamp;
else
}
DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p,
- 0, 1, 0,
- "Whether the current Emacs process owns the given X Selection.\n\
-The arg should be the name of the selection in question, typically one of\n\
-the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
-\(Those are literal upper-case symbol names, since that's what X expects.)\n\
-For convenience, the symbol nil is the same as `PRIMARY',\n\
-and t is the same as `SECONDARY'.)")
- (selection)
+ 0, 1, 0,
+ doc: /* Whether the current Emacs process owns the given X Selection.
+The arg should be the name of the selection in question, typically one of
+the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+\(Those are literal upper-case symbol names, since that's what X expects.)
+For convenience, the symbol nil is the same as `PRIMARY',
+and t is the same as `SECONDARY'. */)
+ (selection)
Lisp_Object selection;
{
check_x ();
- CHECK_SYMBOL (selection, 0);
+ CHECK_SYMBOL (selection);
if (EQ (selection, Qnil)) selection = QPRIMARY;
if (EQ (selection, Qt)) selection = QSECONDARY;
-
+
if (NILP (Fassq (selection, Vselection_alist)))
return Qnil;
return Qt;
}
DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
- 0, 1, 0,
- "Whether there is an owner for the given X Selection.\n\
-The arg should be the name of the selection in question, typically one of\n\
-the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
-\(Those are literal upper-case symbol names, since that's what X expects.)\n\
-For convenience, the symbol nil is the same as `PRIMARY',\n\
-and t is the same as `SECONDARY'.)")
- (selection)
+ 0, 1, 0,
+ doc: /* Whether there is an owner for the given X Selection.
+The arg should be the name of the selection in question, typically one of
+the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+\(Those are literal upper-case symbol names, since that's what X expects.)
+For convenience, the symbol nil is the same as `PRIMARY',
+and t is the same as `SECONDARY'. */)
+ (selection)
Lisp_Object selection;
{
Window owner;
return Qnil;
dpy = FRAME_X_DISPLAY (sf);
- CHECK_SYMBOL (selection, 0);
+ CHECK_SYMBOL (selection);
if (!NILP (Fx_selection_owner_p (selection)))
return Qt;
if (EQ (selection, Qnil)) selection = QPRIMARY;
}
-#define CHECK_CUT_BUFFER(symbol,n) \
- { CHECK_SYMBOL ((symbol), (n)); \
+#define CHECK_CUT_BUFFER(symbol) \
+ { CHECK_SYMBOL ((symbol)); \
if (!EQ((symbol), QCUT_BUFFER0) && !EQ((symbol), QCUT_BUFFER1) \
&& !EQ((symbol), QCUT_BUFFER2) && !EQ((symbol), QCUT_BUFFER3) \
&& !EQ((symbol), QCUT_BUFFER4) && !EQ((symbol), QCUT_BUFFER5) \
}
DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal,
- Sx_get_cut_buffer_internal, 1, 1, 0,
- "Returns the value of the named cut buffer (typically CUT_BUFFER0).")
- (buffer)
+ Sx_get_cut_buffer_internal, 1, 1, 0,
+ doc: /* Returns the value of the named cut buffer (typically CUT_BUFFER0). */)
+ (buffer)
Lisp_Object buffer;
{
Window window;
display = FRAME_X_DISPLAY (sf);
dpyinfo = FRAME_X_DISPLAY_INFO (sf);
window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
- CHECK_CUT_BUFFER (buffer, 0);
+ CHECK_CUT_BUFFER (buffer);
buffer_atom = symbol_to_x_atom (dpyinfo, display, buffer);
x_get_window_property (display, window, buffer_atom, &data, &bytes,
&type, &format, &size, 0);
if (!data || !format)
return Qnil;
-
+
if (format != 8 || type != XA_STRING)
Fsignal (Qerror,
Fcons (build_string ("cut buffer doesn't contain 8-bit data"),
DEFUN ("x-store-cut-buffer-internal", Fx_store_cut_buffer_internal,
- Sx_store_cut_buffer_internal, 2, 2, 0,
- "Sets the value of the named cut buffer (typically CUT_BUFFER0).")
- (buffer, string)
+ Sx_store_cut_buffer_internal, 2, 2, 0,
+ doc: /* Sets the value of the named cut buffer (typically CUT_BUFFER0). */)
+ (buffer, string)
Lisp_Object buffer, string;
{
Window window;
if (max_bytes > MAX_SELECTION_QUANTUM)
max_bytes = MAX_SELECTION_QUANTUM;
- CHECK_CUT_BUFFER (buffer, 0);
- CHECK_STRING (string, 0);
+ CHECK_CUT_BUFFER (buffer);
+ CHECK_STRING (string);
buffer_atom = symbol_to_x_atom (FRAME_X_DISPLAY_INFO (sf),
display, buffer);
- data = (unsigned char *) XSTRING (string)->data;
- bytes = STRING_BYTES (XSTRING (string));
+ data = (unsigned char *) SDATA (string);
+ bytes = SBYTES (string);
bytes_remaining = bytes;
if (! FRAME_X_DISPLAY_INFO (sf)->cut_buffers_initialized)
DEFUN ("x-rotate-cut-buffers-internal", Fx_rotate_cut_buffers_internal,
- Sx_rotate_cut_buffers_internal, 1, 1, 0,
- "Rotate the values of the cut buffers by the given number of step.\n\
-Positive means shift the values forward, negative means backward.")
- (n)
+ Sx_rotate_cut_buffers_internal, 1, 1, 0,
+ doc: /* Rotate the values of the cut buffers by the given number of step.
+Positive means shift the values forward, negative means backward. */)
+ (n)
Lisp_Object n;
{
Window window;
check_x ();
display = FRAME_X_DISPLAY (sf);
window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
- CHECK_NUMBER (n, 0);
+ CHECK_NUMBER (n);
if (XINT (n) == 0)
return n;
if (! FRAME_X_DISPLAY_INFO (sf)->cut_buffers_initialized)
staticpro (&Vselection_alist);
DEFVAR_LISP ("selection-converter-alist", &Vselection_converter_alist,
- "An alist associating X Windows selection-types with functions.\n\
-These functions are called to convert the selection, with three args:\n\
-the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');\n\
-a desired type to which the selection should be converted;\n\
-and the local selection value (whatever was given to `x-own-selection').\n\
-\n\
-The function should return the value to send to the X server\n\
-\(typically a string). A return value of nil\n\
-means that the conversion could not be done.\n\
-A return value which is the symbol `NULL'\n\
-means that a side-effect was executed,\n\
-and there is no meaningful selection value.");
+ doc: /* An alist associating X Windows selection-types with functions.
+These functions are called to convert the selection, with three args:
+the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
+a desired type to which the selection should be converted;
+and the local selection value (whatever was given to `x-own-selection').
+
+The function should return the value to send to the X server
+\(typically a string). A return value of nil
+means that the conversion could not be done.
+A return value which is the symbol `NULL'
+means that a side-effect was executed,
+and there is no meaningful selection value. */);
Vselection_converter_alist = Qnil;
DEFVAR_LISP ("x-lost-selection-hooks", &Vx_lost_selection_hooks,
- "A list of functions to be called when Emacs loses an X selection.\n\
-\(This happens when some other X client makes its own selection\n\
-or when a Lisp program explicitly clears the selection.)\n\
-The functions are called with one argument, the selection type\n\
-\(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD').");
+ doc: /* A list of functions to be called when Emacs loses an X selection.
+\(This happens when some other X client makes its own selection
+or when a Lisp program explicitly clears the selection.)
+The functions are called with one argument, the selection type
+\(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'). */);
Vx_lost_selection_hooks = Qnil;
DEFVAR_LISP ("x-sent-selection-hooks", &Vx_sent_selection_hooks,
- "A list of functions to be called when Emacs answers a selection request.\n\
-The functions are called with four arguments:\n\
- - the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');\n\
- - the selection-type which Emacs was asked to convert the\n\
- selection into before sending (for example, `STRING' or `LENGTH');\n\
- - a flag indicating success or failure for responding to the request.\n\
-We might have failed (and declined the request) for any number of reasons,\n\
-including being asked for a selection that we no longer own, or being asked\n\
-to convert into a type that we don't know about or that is inappropriate.\n\
-This hook doesn't let you change the behavior of Emacs's selection replies,\n\
-it merely informs you that they have happened.");
+ doc: /* A list of functions to be called when Emacs answers a selection request.
+The functions are called with four arguments:
+ - the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
+ - the selection-type which Emacs was asked to convert the
+ selection into before sending (for example, `STRING' or `LENGTH');
+ - a flag indicating success or failure for responding to the request.
+We might have failed (and declined the request) for any number of reasons,
+including being asked for a selection that we no longer own, or being asked
+to convert into a type that we don't know about or that is inappropriate.
+This hook doesn't let you change the behavior of Emacs's selection replies,
+it merely informs you that they have happened. */);
Vx_sent_selection_hooks = Qnil;
DEFVAR_LISP ("selection-coding-system", &Vselection_coding_system,
- "Coding system for communicating with other X clients.\n\
-When sending or receiving text via cut_buffer, selection, and clipboard,\n\
-the text is encoded or decoded by this coding system.\n\
-The default value is `compound-text'.");
- Vselection_coding_system = intern ("compound-text");
+ doc: /* Coding system for communicating with other X clients.
+When sending or receiving text via cut_buffer, selection, and clipboard,
+the text is encoded or decoded by this coding system.
+The default value is `compound-text-with-extensions'. */);
+ Vselection_coding_system = intern ("compound-text-with-extensions");
DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system,
- "Coding system for the next communication with other X clients.\n\
-Usually, `selection-coding-system' is used for communicating with\n\
-other X clients. But, if this variable is set, it is used for the\n\
-next communication only. After the communication, this variable is\n\
-set to nil.");
+ doc: /* Coding system for the next communication with other X clients.
+Usually, `selection-coding-system' is used for communicating with
+other X clients. But, if this variable is set, it is used for the
+next communication only. After the communication, this variable is
+set to nil. */);
Vnext_selection_coding_system = Qnil;
DEFVAR_INT ("x-selection-timeout", &x_selection_timeout,
- "Number of milliseconds to wait for a selection reply.\n\
-If the selection owner doesn't reply in this time, we give up.\n\
-A value of 0 means wait as long as necessary. This is initialized from the\n\
-\"*selectionTimeout\" resource.");
+ doc: /* Number of milliseconds to wait for a selection reply.
+If the selection owner doesn't reply in this time, we give up.
+A value of 0 means wait as long as necessary. This is initialized from the
+\"*selectionTimeout\" resource. */);
x_selection_timeout = 0;
QPRIMARY = intern ("PRIMARY"); staticpro (&QPRIMARY);
QTIMESTAMP = intern ("TIMESTAMP"); staticpro (&QTIMESTAMP);
QTEXT = intern ("TEXT"); staticpro (&QTEXT);
QCOMPOUND_TEXT = intern ("COMPOUND_TEXT"); staticpro (&QCOMPOUND_TEXT);
+ QUTF8_STRING = intern ("UTF8_STRING"); staticpro (&QUTF8_STRING);
QTIMESTAMP = intern ("TIMESTAMP"); staticpro (&QTIMESTAMP);
QDELETE = intern ("DELETE"); staticpro (&QDELETE);
QMULTIPLE = intern ("MULTIPLE"); staticpro (&QMULTIPLE);
QATOM = intern ("ATOM"); staticpro (&QATOM);
QATOM_PAIR = intern ("ATOM_PAIR"); staticpro (&QATOM_PAIR);
QNULL = intern ("NULL"); staticpro (&QNULL);
+ Qcompound_text_with_extensions = intern ("compound-text-with-extensions");
+ staticpro (&Qcompound_text_with_extensions);
#ifdef CUT_BUFFER_SUPPORT
QCUT_BUFFER0 = intern ("CUT_BUFFER0"); staticpro (&QCUT_BUFFER0);