static void hack_motif_clipboard_selection (Atom selection_atom,
Lisp_Object selection_value,
Time thyme, Display *display,
- Window selecting_window,
- int owned_p);
+ Window selecting_window);
#endif
#define CUT_BUFFER_SUPPORT
/* If the selection owner takes too long to reply to a selection request,
we give up on it. This is in seconds (0 = no timeout).
*/
-Fixnum x_selection_timeout;
-
-/* Enable motif selection optimizations. */
-int x_selection_strict_motif_ownership;
+int x_selection_timeout;
\f
/* Utility functions */
unsigned int *size_ret,
int *format_ret);
static Lisp_Object selection_data_to_lisp_data (struct device *,
- Extbyte *data,
+ unsigned char *data,
size_t size,
Atom type,
int format);
#endif /* CUT_BUFFER_SUPPORT */
{
- const char *nameext;
- LISP_STRING_TO_EXTERNAL (Fsymbol_name (sym), nameext, Qctext);
+ CONST char *nameext;
+ GET_C_STRING_CTEXT_DATA_ALLOCA (Fsymbol_name (sym), nameext);
return XInternAtom (display, nameext, only_if_exists ? True : False);
}
}
#endif
{
- char *intstr;
+ Lisp_Object newsym;
+ CONST Bufbyte *intstr;
char *str = XGetAtomName (display, atom);
if (! str) return Qnil;
- TO_INTERNAL_FORMAT (C_STRING, str,
- C_STRING_ALLOCA, intstr,
- Qctext);
+ GET_C_CHARPTR_INT_CTEXT_DATA_ALLOCA (str, intstr);
+ newsym = intern ((char *) intstr);
XFree (str);
- return intern (intstr);
+ return newsym;
}
}
\f
/* Do protocol to assert ourself as a selection owner.
+ Update the Vselection_alist so that we can reply to later requests for
+ our selection.
*/
static Lisp_Object
-x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
- Lisp_Object how_to_add, Lisp_Object selection_type,
- int owned_p)
+x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value)
{
struct device *d = decode_x_device (Qnil);
Display *display = DEVICE_X_DISPLAY (d);
That assumed equivalence of time_t and Time, which is not
necessarily the case (e.g. under OSF on the Alphas, where
Time is a 64-bit quantity and time_t is a 32-bit quantity).
-
+
Opaque pointers are the clean way to go here.
*/
- selection_time = make_opaque (&thyme, sizeof (thyme));
+ selection_time = make_opaque (sizeof (thyme), (void *) &thyme);
#ifdef MOTIF_CLIPBOARDS
hack_motif_clipboard_selection (selection_atom, selection_value,
- thyme, display, selecting_window, owned_p);
+ thyme, display, selecting_window);
#endif
return selection_time;
}
Lisp_Object selection_value,
Time thyme,
Display *display,
- Window selecting_window,
- int owned_p)
+ Window selecting_window)
+ /* Bool owned_p)*/
{
struct device *d = get_device_from_display (display);
/* Those Motif wankers can't be bothered to follow the ICCCM, and do
to look up the new value, and you can't Copy from a buffer, Paste
into a text field, then Copy something else from the buffer and
paste it into the text field -- it pastes the first thing again. */
- && (!owned_p
- /* Selectively re-enable this because for most users its
- just too painful - especially over a remote link. */
- || x_selection_strict_motif_ownership)
+/* && !owned_p */
)
{
#ifdef MOTIF_INCREMENTAL_CLIPBOARDS_WORK
#endif
XmString fmh;
String encoding = "STRING";
- const Bufbyte *data = XSTRING_DATA (selection_value);
- Bytecount bytes = XSTRING_LENGTH (selection_value);
+ CONST Extbyte *data = XSTRING_DATA (selection_value);
+ Extcount bytes = XSTRING_LENGTH (selection_value);
#ifdef MULE
{
enum { ASCII, LATIN_1, WORLD } chartypes = ASCII;
- const Bufbyte *ptr = data, *end = ptr + bytes;
+ CONST Bufbyte *ptr = data, *end = ptr + bytes;
/* Optimize for the common ASCII case */
while (ptr <= end)
{
}
if (chartypes == LATIN_1)
- TO_EXTERNAL_FORMAT (LISP_STRING, selection_value,
- ALLOCA, (data, bytes),
- Qbinary);
+ GET_STRING_BINARY_DATA_ALLOCA (selection_value, data, bytes);
else if (chartypes == WORLD)
{
- TO_EXTERNAL_FORMAT (LISP_STRING, selection_value,
- ALLOCA, (data, bytes),
- Qctext);
+ GET_STRING_CTEXT_DATA_ALLOCA (selection_value, data, bytes);
encoding = "COMPOUND_TEXT";
}
}
{
Display *dpy = XtDisplay (widget);
Window window = (Window) *private_id;
- Lisp_Object selection = select_convert_out (QCLIPBOARD, Qnil, Qnil);
-
- /* Whichever lazy git wrote this originally just called abort()
- when anything didn't go their way... */
-
- /* Try some other text types */
- if (NILP (selection))
- selection = select_convert_out (QCLIPBOARD, QSTRING, Qnil);
- if (NILP (selection))
- selection = select_convert_out (QCLIPBOARD, QTEXT, Qnil);
- if (NILP (selection))
- selection = select_convert_out (QCLIPBOARD, QCOMPOUND_TEXT, Qnil);
-
- if (CONSP (selection) && SYMBOLP (XCAR (selection))
- && (EQ (XCAR (selection), QSTRING)
- || EQ (XCAR (selection), QTEXT)
- || EQ (XCAR (selection), QCOMPOUND_TEXT)))
- selection = XCDR (selection);
-
- if (NILP (selection))
- signal_error (Qselection_conversion_error,
- build_string ("no selection"));
-
- if (!STRINGP (selection))
- signal_error (Qselection_conversion_error,
- build_string ("couldn't convert selection to string"));
-
-
+ Lisp_Object selection = assq_no_quit (QCLIPBOARD, Vselection_alist);
+ if (NILP (selection)) abort ();
+ selection = XCDR (selection);
+ if (!STRINGP (selection)) abort ();
XmClipboardCopyByName (dpy, window, *data_id,
(char *) XSTRING_DATA (selection),
XSTRING_LENGTH (selection) + 1,
x_handle_selection_request (XSelectionRequestEvent *event)
{
/* This function can GC */
- struct gcpro gcpro1, gcpro2;
- Lisp_Object temp_obj;
+ struct gcpro gcpro1, gcpro2, gcpro3;
+ Lisp_Object local_selection_data = Qnil;
Lisp_Object selection_symbol;
Lisp_Object target_symbol = Qnil;
Lisp_Object converted_selection = Qnil;
int count;
struct device *d = get_device_from_display (event->display);
- GCPRO2 (converted_selection, target_symbol);
+ GCPRO3 (local_selection_data, converted_selection, target_symbol);
selection_symbol = x_atom_to_symbol (d, event->selection);
- target_symbol = x_atom_to_symbol (d, event->target);
-#if 0 /* #### MULTIPLE doesn't work yet */
- if (EQ (target_symbol, QMULTIPLE))
- target_symbol = fetch_multiple_target (event);
-#endif
+ local_selection_data = assq_no_quit (selection_symbol, Vselection_alist);
- temp_obj = Fget_selection_timestamp (selection_symbol);
+#if 0
+ /* This list isn't user-visible, so it can't "go bad." */
+ assert (CONSP (local_selection_data));
+ assert (CONSP (XCDR (local_selection_data)));
+ assert (CONSP (XCDR (XCDR (local_selection_data))));
+ assert (NILP (XCDR (XCDR (XCDR (local_selection_data)))));
+ assert (CONSP (XCAR (XCDR (XCDR (local_selection_data)))));
+ assert (INTP (XCAR (XCAR (XCDR (XCDR (local_selection_data))))));
+ assert (INTP (XCDR (XCAR (XCDR (XCDR (local_selection_data))))));
+#endif
- if (NILP (temp_obj))
+ if (NILP (local_selection_data))
{
- /* We don't appear to have the selection. */
+ /* Someone asked for the selection, but we don't have it any more. */
x_decline_selection_request (event);
-
goto DONE_LABEL;
}
- local_selection_time = * (Time *) XOPAQUE_DATA (temp_obj);
+ local_selection_time =
+ * (Time *) XOPAQUE_DATA (XCAR (XCDR (XCDR (local_selection_data))));
if (event->time != CurrentTime &&
local_selection_time > event->time)
goto DONE_LABEL;
}
- converted_selection = select_convert_out (selection_symbol,
- target_symbol, Qnil);
-
- /* #### Is this the right thing to do? I'm no X expert. -- ajh */
- if (NILP (converted_selection))
- {
- /* We don't appear to have a selection in that data type. */
- x_decline_selection_request (event);
- goto DONE_LABEL;
- }
-
count = specpdl_depth ();
record_unwind_protect (x_selection_request_lisp_error,
make_opaque_ptr (event));
+ target_symbol = x_atom_to_symbol (d, event->target);
- {
- unsigned char *data;
- unsigned int size;
- int format;
- Atom type;
- lisp_data_to_selection_data (d, converted_selection,
- &data, &type, &size, &format);
-
- x_reply_selection_request (event, format, data, size, type);
- successful_p = Qt;
- /* Tell x_selection_request_lisp_error() it's cool. */
- event->type = 0;
- xfree (data);
- }
+#if 0 /* #### MULTIPLE doesn't work yet */
+ if (EQ (target_symbol, QMULTIPLE))
+ target_symbol = fetch_multiple_target (event);
+#endif
+ /* Convert lisp objects back into binary data */
+
+ converted_selection =
+ get_local_selection (selection_symbol, target_symbol);
+
+ if (! NILP (converted_selection))
+ {
+ unsigned char *data;
+ unsigned int size;
+ int format;
+ Atom type;
+ lisp_data_to_selection_data (d, converted_selection,
+ &data, &type, &size, &format);
+
+ x_reply_selection_request (event, format, data, size, type);
+ successful_p = Qt;
+ /* Tell x_selection_request_lisp_error() it's cool. */ event->type = 0;
+ xfree (data);
+ }
unbind_to (count, Qnil);
DONE_LABEL:
/* Let random lisp code notice that the selection has been asked for. */
{
+ Lisp_Object rest;
Lisp_Object val = Vx_sent_selection_hooks;
if (!UNBOUNDP (val) && !NILP (val))
{
- Lisp_Object rest;
if (CONSP (val) && !EQ (XCAR (val), Qlambda))
for (rest = val; !NILP (rest); rest = Fcdr (rest))
- call3 (Fcar (rest), selection_symbol, target_symbol, successful_p);
+ call3 (Fcar(rest), selection_symbol, target_symbol,
+ successful_p);
else
- call3 (val, selection_symbol, target_symbol, successful_p);
+ call3 (val, selection_symbol, target_symbol,
+ successful_p);
}
}
}
Atom selection = event->selection;
Time changed_owner_time = event->time;
- Lisp_Object selection_symbol, local_selection_time_lisp;
+ Lisp_Object selection_symbol, local_selection_data;
Time local_selection_time;
selection_symbol = x_atom_to_symbol (d, selection);
- local_selection_time_lisp = Fget_selection_timestamp (selection_symbol);
+ local_selection_data = assq_no_quit (selection_symbol, Vselection_alist);
- /* We don't own the selection, so that's fine. */
- if (NILP (local_selection_time_lisp))
- return;
+ /* Well, we already believe that we don't own it, so that's just fine. */
+ if (NILP (local_selection_data)) return;
- local_selection_time = * (Time *) XOPAQUE_DATA (local_selection_time_lisp);
+ local_selection_time =
+ * (Time *) XOPAQUE_DATA (XCAR (XCDR (XCDR (local_selection_data))));
/* This SelectionClear is for a selection that we no longer own, so we can
disregard it. (That is, we have reasserted the selection since this
if (changed_owner_time != CurrentTime &&
local_selection_time > changed_owner_time)
return;
-
+
handle_selection_clear (selection_symbol);
}
unbind_to (speccount, Qnil);
/* otherwise, the selection is waiting for us on the requested property. */
-
- return select_convert_in (selection_symbol,
- target_type,
- x_get_window_property_as_lisp_data(display,
- requestor_window,
- target_property,
- target_type,
- selection_atom));
+ return
+ x_get_window_property_as_lisp_data (display, requestor_window,
+ target_property, target_type,
+ selection_atom);
}
static void
x_get_window_property (Display *display, Window window, Atom property,
- Extbyte **data_ret, int *bytes_ret,
+ unsigned char **data_ret, int *bytes_ret,
Atom *actual_type_ret, int *actual_format_ret,
unsigned long *actual_size_ret, int delete_p)
{
- size_t total_size;
+ int total_size;
unsigned long bytes_remaining;
int offset = 0;
unsigned char *tmp_data = 0;
}
total_size = bytes_remaining + 1;
- *data_ret = (Extbyte *) xmalloc (total_size);
+ *data_ret = (unsigned char *) xmalloc (total_size);
/* Now read, until we've gotten it all. */
while (bytes_remaining)
/* this one is for error messages only */
Lisp_Object target_type,
unsigned int min_size_bytes,
- Extbyte **data_ret, int *size_bytes_ret,
+ unsigned char **data_ret, int *size_bytes_ret,
Atom *type_ret, int *format_ret,
unsigned long *size_ret)
{
int offset = 0;
int prop_id;
*size_bytes_ret = min_size_bytes;
- *data_ret = (Extbyte *) xmalloc (*size_bytes_ret);
+ *data_ret = (unsigned char *) xmalloc (*size_bytes_ret);
#if 0
stderr_out ("\nread INCR %d\n", min_size_bytes);
#endif
PropertyNewValue);
while (1)
{
- Extbyte *tmp_data;
+ unsigned char *tmp_data;
int tmp_size_bytes;
wait_for_property_change (prop_id);
/* expect it again immediately, because x_get_window_property may
*size_bytes_ret, offset + tmp_size_bytes);
#endif
*size_bytes_ret = offset + tmp_size_bytes;
- *data_ret = (Extbyte *) xrealloc (*data_ret, *size_bytes_ret);
+ *data_ret = (unsigned char *) xrealloc (*data_ret, *size_bytes_ret);
}
memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes);
offset += tmp_size_bytes;
Atom actual_type;
int actual_format;
unsigned long actual_size;
- Extbyte *data = NULL;
+ unsigned char *data = NULL;
int bytes = 0;
Lisp_Object val;
struct device *d = get_device_from_display (display);
return val;
}
\f
-/* #### These are going to move into Lisp code(!) with the aid of
- some new functions I'm working on - ajh */
-
/* These functions convert from the selection data read from the server into
something that we can use from elisp, and vice versa.
static Lisp_Object
selection_data_to_lisp_data (struct device *d,
- Extbyte *data,
+ unsigned char *data,
size_t size,
Atom type,
int format)
return make_ext_string (data, size,
type == DEVICE_XATOM_TEXT (d) ||
type == DEVICE_XATOM_COMPOUND_TEXT (d)
- ? Qctext : Qbinary);
+ ? FORMAT_CTEXT : FORMAT_BINARY);
/* Convert a single atom to a Lisp Symbol.
Convert a set of atoms to a vector of symbols. */
}
else if (STRINGP (obj))
{
- const Extbyte *extval;
+ CONST Extbyte *extval;
Extcount extvallen;
- TO_EXTERNAL_FORMAT (LISP_STRING, obj,
- ALLOCA, (extval, extvallen),
- (NILP (type) ? Qctext : Qbinary));
+ if (NILP (type))
+ GET_STRING_CTEXT_DATA_ALLOCA (obj, extval, extvallen);
+ else
+ GET_STRING_BINARY_DATA_ALLOCA (obj, extval, extvallen);
*format_ret = 8;
*size_ret = extvallen;
*data_ret = (unsigned char *) xmalloc (*size_ret);
{
Bufbyte buf[MAX_EMCHAR_LEN];
Bytecount len;
- const Extbyte *extval;
+ CONST Extbyte *extval;
Extcount extvallen;
*format_ret = 8;
len = set_charptr_emchar (buf, XCHAR (obj));
- TO_EXTERNAL_FORMAT (DATA, (buf, len),
- ALLOCA, (extval, extvallen),
- Qctext);
+ GET_CHARPTR_EXT_CTEXT_DATA_ALLOCA (buf, len, extval, extvallen);
*size_ret = extvallen;
*data_ret = (unsigned char *) xmalloc (*size_ret);
memcpy (*data_ret, extval, *size_ret);
}
static Lisp_Object
-x_selection_exists_p (Lisp_Object selection,
- Lisp_Object selection_type)
+x_selection_exists_p (Lisp_Object selection)
{
struct device *d = decode_x_device (Qnil);
Display *dpy = DEVICE_X_DISPLAY (d);
static void
initialize_cut_buffers (Display *display, Window window)
{
- static unsigned const char * const data = (unsigned const char *) "";
+ static unsigned CONST char * CONST data = (unsigned CONST char *) "";
#define FROB(atom) XChangeProperty (display, window, atom, XA_STRING, 8, \
PropModeAppend, data, 0)
FROB (XA_CUT_BUFFER0);
cut_buffers_initialized = 1;
}
-#define CHECK_CUTBUFFER(symbol) do { \
- 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) || \
- EQ (symbol, QCUT_BUFFER6) || \
- EQ (symbol, QCUT_BUFFER7))) \
- signal_simple_error ("Doesn't name a cutbuffer", symbol); \
-} while (0)
+#define CHECK_CUTBUFFER(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) && \
+ !EQ((symbol),QCUT_BUFFER6) && !EQ((symbol),QCUT_BUFFER7)) \
+ signal_error (Qerror, list2 (build_string ("Doesn't name a cutbuffer"), \
+ (symbol))); \
+ }
DEFUN ("x-get-cutbuffer-internal", Fx_get_cutbuffer_internal, 1, 1, 0, /*
Return the value of the named CUTBUFFER (typically CUT_BUFFER0).
Display *display = DEVICE_X_DISPLAY (d);
Window window = RootWindow (display, 0); /* Cutbuffers are on frame 0 */
Atom cut_buffer_atom;
- Extbyte *data;
+ unsigned char *data;
int bytes;
Atom type;
int format;
ret = (bytes ?
make_ext_string (data, bytes,
memchr (data, 0x1b, bytes) ?
- Qctext : Qbinary)
+ FORMAT_CTEXT : FORMAT_BINARY)
: Qnil);
xfree (data);
return ret;
Display *display = DEVICE_X_DISPLAY (d);
Window window = RootWindow (display, 0); /* Cutbuffers are on frame 0 */
Atom cut_buffer_atom;
- const Bufbyte *data = XSTRING_DATA (string);
- Bytecount bytes = XSTRING_LENGTH (string);
- Bytecount bytes_remaining;
+ CONST Extbyte *data = XSTRING_DATA (string);
+ Extcount bytes = XSTRING_LENGTH (string);
+ Extcount bytes_remaining;
int max_bytes = SELECTION_QUANTUM (display);
#ifdef MULE
- const Bufbyte *ptr, *end;
+ CONST Bufbyte *ptr, *end;
enum { ASCII, LATIN_1, WORLD } chartypes = ASCII;
#endif
}
if (chartypes == LATIN_1)
- TO_EXTERNAL_FORMAT (LISP_STRING, string,
- ALLOCA, (data, bytes),
- Qbinary);
+ GET_STRING_BINARY_DATA_ALLOCA (string, data, bytes);
else if (chartypes == WORLD)
- TO_EXTERNAL_FORMAT (LISP_STRING, string,
- ALLOCA, (data, bytes),
- Qctext);
+ GET_STRING_CTEXT_DATA_ALLOCA (string, data, bytes);
#endif /* MULE */
bytes_remaining = bytes;
/************************************************************************/
void
-syms_of_select_x (void)
+syms_of_xselect (void)
{
#ifdef CUT_BUFFER_SUPPORT
}
void
-reinit_vars_of_select_x (void)
+vars_of_xselect (void)
{
+#ifdef CUT_BUFFER_SUPPORT
+ cut_buffers_initialized = 0;
+ Fprovide (intern ("cut-buffer"));
+#endif
+
reading_selection_reply = 0;
reading_which_selection = 0;
selection_reply_timed_out = 0;
for_whom_the_bell_tolls = 0;
prop_location_tick = 0;
-}
-
-void
-vars_of_select_x (void)
-{
- reinit_vars_of_select_x ();
-
-#ifdef CUT_BUFFER_SUPPORT
- cut_buffers_initialized = 0;
- Fprovide (intern ("cut-buffer"));
-#endif
DEFVAR_LISP ("x-sent-selection-hooks", &Vx_sent_selection_hooks /*
A function or functions to be called after we have responded to some
\"*selectionTimeout\" resource (which is expressed in milliseconds).
*/ );
x_selection_timeout = 0;
-
- DEFVAR_BOOL ("x-selection-strict-motif-ownership", &x_selection_strict_motif_ownership /*
-*If true and XEmacs already owns the clipboard, don't own it again in the
-Motif way. Owning the selection on the Motif way does a huge amount of
-X protocol, and it makes killing text incredibly slow when using an
-X terminal. However, when enabled Motif text fields don't bother to look up
-the new value, and you can't Copy from a buffer, Paste into a text
-field, then Copy something else from the buffer and paste it into the
-text field; it pastes the first thing again.
-*/ );
- x_selection_strict_motif_ownership = 1;
}
void
-Xatoms_of_select_x (struct device *d)
+Xatoms_of_xselect (struct device *d)
{
Display *D = DEVICE_X_DISPLAY (d);
DEVICE_XATOM_NULL (d) = XInternAtom (D, "NULL", False);
DEVICE_XATOM_ATOM_PAIR (d) = XInternAtom (D, "ATOM_PAIR", False);
DEVICE_XATOM_COMPOUND_TEXT (d) = XInternAtom (D, "COMPOUND_TEXT", False);
-
- /* #### I don't like the looks of this... what is it for? - ajh */
DEVICE_XATOM_EMACS_TMP (d) = XInternAtom (D, "_EMACS_TMP_", False);
}