static void hack_motif_clipboard_selection (Atom selection_atom,
Lisp_Object selection_value,
Time thyme, Display *display,
- Window selecting_window);
+ Window selecting_window,
+ int owned_p);
#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).
*/
-int x_selection_timeout;
+Fixnum x_selection_timeout;
+
+/* Enable motif selection optimizations. */
+int x_selection_strict_motif_ownership;
\f
/* Utility functions */
*/
static Lisp_Object
x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
- Lisp_Object how_to_add, Lisp_Object selection_type)
+ Lisp_Object how_to_add, Lisp_Object selection_type,
+ int owned_p)
{
struct device *d = decode_x_device (Qnil);
Display *display = DEVICE_X_DISPLAY (d);
#ifdef MOTIF_CLIPBOARDS
hack_motif_clipboard_selection (selection_atom, selection_value,
- thyme, display, selecting_window);
+ thyme, display, selecting_window, owned_p);
#endif
return selection_time;
}
Lisp_Object selection_value,
Time thyme,
Display *display,
- Window selecting_window)
- /* Bool owned_p)*/
+ Window selecting_window,
+ int 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 */
+ && (!owned_p
+ /* Selectively re-enable this because for most users its
+ just too painful - especially over a remote link. */
+ || x_selection_strict_motif_ownership)
)
{
#ifdef MOTIF_INCREMENTAL_CLIPBOARDS_WORK
Window window = (Window) *private_id;
Lisp_Object selection = select_convert_out (QCLIPBOARD, Qnil, Qnil);
- /* Whichever lazy git wrote this originally just called abort()
+ /* Whichever lazy git wrote this originally just called ABORT()
when anything didn't go their way... */
/* Try some other text types */
}
else
{
+#ifndef HAVE_XTREGISTERDRAWABLE
+ invalid_operation("Copying that much data requires X11R6.", Qunbound);
+#else
/* Send an INCR selection. */
int prop_id;
+ Widget widget = FRAME_X_TEXT_WIDGET (XFRAME(DEVICE_SELECTED_FRAME(d)));
if (x_window_to_frame (d, window)) /* #### debug */
error ("attempt to transfer an INCR to ourself!");
#if 0
stderr_out ("\nINCR %d\n", bytes_remaining);
#endif
+ /* Tell Xt not to drop PropertyNotify events that arrive for the
+ target window, rather, pass them to us. This would be a hack, but
+ the Xt selection routines are broken for our purposes--we can't
+ pass them callbacks from Lisp, for example. Let's call it a
+ workaround.
+
+ The call to wait_for_property_change means we can break out of that
+ function, switch to another frame on the same display (which will
+ be another Xt widget), select a huge amount of text, and have the
+ same (foreign) app ask for another incremental selection
+ transfer. Programming like X11 made sense, would mean that, in that
+ case, XtRegisterDrawable is called twice with different widgets.
+
+ Since the results of calling XtRegisterDrawable when the drawable
+ is already registered with another widget are undefined, we want to
+ avoid that--so, only call it when XtWindowToWidget returns NULL,
+ which it will only do with a valid Window if it's not already
+ registered. */
+ if (NULL == XtWindowToWidget(display, window))
+ {
+ XtRegisterDrawable(display, (Drawable)window, widget);
+ }
+
prop_id = expect_property_change (display, window, reply.property,
PropertyDelete);
stderr_out (" INCR done\n");
#endif
if (! waiting_for_other_props_on_window (display, window))
- XSelectInput (display, window, 0L);
+ {
+ XSelectInput (display, window, 0L);
+ XtUnregisterDrawable(display, (Drawable)window);
+ }
XChangeProperty (display, window, reply.property, type, format,
PropModeReplace, data, 0);
+#endif /* HAVE_XTREGISTERDRAWABLE */
}
}
continue;
}
+#ifdef UTF2000
+ if ((*ptr) <= 0xC3)
+ {
+ chartypes = LATIN_1;
+ ptr += 2;
+ continue;
+ }
+#else
if ((*ptr) == LEADING_BYTE_LATIN_ISO8859_1 ||
(*ptr) == LEADING_BYTE_CONTROL_1)
{
ptr += 2;
continue;
}
+#endif
chartypes = WORLD;
break;
\"*selectionTimeout\" resource (which is expressed in milliseconds).
*/ );
x_selection_timeout = 0;
+
+ DEFVAR_BOOL ("x-selection-strict-motif-ownership", &x_selection_strict_motif_ownership /*
+*If nil 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