X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fselect-x.c;h=8a2cff352061cdbb87400784bd4f2ad2f1756be7;hp=e2e003f666f34ab8a358aa43bfc8d94e1623072f;hb=0298dde5c47a900f2542bc7ec6c9dafc92ce3015;hpb=3198ed8319f99e19a14447745f4f93e4b4522961 diff --git a/src/select-x.c b/src/select-x.c index e2e003f..8a2cff3 100644 --- a/src/select-x.c +++ b/src/select-x.c @@ -73,7 +73,7 @@ Lisp_Object Vx_sent_selection_hooks; /* 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; @@ -382,7 +382,7 @@ motif_clipboard_cb (Widget widget, int *data_id, int *private_id, int *reason) 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 */ @@ -509,14 +509,41 @@ x_reply_selection_request (XSelectionRequestEvent *event, int format, } 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); @@ -560,10 +587,14 @@ x_reply_selection_request (XSelectionRequestEvent *event, int format, 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 */ } } @@ -1782,7 +1813,7 @@ A value of 0 means wait as long as necessary. This is initialized from the 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 +*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