summaryrefslogtreecommitdiff
path: root/src/xselect.c
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1995-02-02 18:49:38 +0000
committerRichard M. Stallman <rms@gnu.org>1995-02-02 18:49:38 +0000
commit95a8a747e4be74008041681e61757f2d37ce6caf (patch)
tree0ee72b8ef9f5a1e4b456022969d97f09a2e37c85 /src/xselect.c
parente9f0bf5568595cebbb07d6396148c7eb2b5b4ee1 (diff)
downloademacs-95a8a747e4be74008041681e61757f2d37ce6caf.tar.gz
(wait_for_property_change): Avoid unlikely timing error.
(x_get_foreign_selection): Pass display to x_start_queueing_selection_events and x_stop_queueing_selection_events. (x_reply_selection_request): Call x_start_queueing_selection_events and x_stop_queueing_selection_events. Handle X protocol errors.
Diffstat (limited to 'src/xselect.c')
-rw-r--r--src/xselect.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/src/xselect.c b/src/xselect.c
index 90ccdbbfde4..5e7432e9e47 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -17,18 +17,11 @@ You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* x_handle_selection_notify
-x_reply_selection_request */
-
/* Rewritten by jwz */
#include <config.h>
#include "lisp.h"
-#if 0
-#include <stdio.h> /* termhooks.h needs this */
-#include "termhooks.h"
-#endif
#include "xterm.h" /* for all of the X includes */
#include "dispextern.h" /* frame.h seems to want this */
#include "frame.h" /* Need this to get the X window of selected_frame */
@@ -500,6 +493,8 @@ x_reply_selection_request (event, format, data, size, type)
reply.property = reply.target;
/* #### XChangeProperty can generate BadAlloc, and we must handle it! */
+ BLOCK_INPUT;
+ x_catch_errors (display);
/* Store the data on the requested property.
If the selection is large, only store the first N bytes of it.
@@ -511,20 +506,18 @@ x_reply_selection_request (event, format, data, size, type)
#if 0
fprintf (stderr,"\nStoring all %d\n", bytes_remaining);
#endif
- BLOCK_INPUT;
XChangeProperty (display, window, reply.property, type, format,
PropModeReplace, data, size);
/* At this point, the selection was successfully stored; ack it. */
XSendEvent (display, window, False, 0L, (XEvent *) &reply);
- XFlush (display);
- UNBLOCK_INPUT;
}
else
{
/* Send an INCR selection. */
struct prop_location *wait_object;
+ int had_errors;
- BLOCK_INPUT;
+ x_start_queuing_selection_requests (display);
if (x_window_to_frame (window)) /* #### debug */
error ("attempt to transfer an INCR to ourself!");
@@ -541,11 +534,14 @@ x_reply_selection_request (event, format, data, size, type)
/* Tell 'em the INCR data is there... */
(void) XSendEvent (display, window, False, 0L, (XEvent *) &reply);
XFlush (display);
+
+ had_errors = x_had_errors_p (display);
UNBLOCK_INPUT;
/* First, wait for the requestor to ack by deleting the property.
This can run random lisp code (process handlers) or signal. */
- wait_for_property_change (wait_object);
+ if (! had_errors)
+ wait_for_property_change (wait_object);
while (bytes_remaining)
{
@@ -567,8 +563,12 @@ x_reply_selection_request (event, format, data, size, type)
bytes_remaining -= i;
data += i;
XFlush (display);
+ had_errors = x_had_errors_p (display);
UNBLOCK_INPUT;
+ if (had_errors)
+ break;
+
/* Now wait for the requestor to ack this chunk by deleting the
property. This can run random lisp code or signal.
*/
@@ -585,9 +585,12 @@ x_reply_selection_request (event, format, data, size, type)
XChangeProperty (display, window, reply.property, type, format,
PropModeReplace, data, 0);
- XFlush (display);
- UNBLOCK_INPUT;
+ x_stop_queuing_selection_requests (display);
}
+
+ XFlush (display);
+ x_uncatch_errors (display);
+ UNBLOCK_INPUT;
}
/* Handle a SelectionRequest event EVENT.
@@ -912,9 +915,11 @@ wait_for_property_change (location)
XCONS (property_change_reply)->car = Qnil;
+ property_change_reply_object = location;
+ /* If the event we are waiting for arrives beyond here, it will set
+ property_change_reply, because property_change_reply_object says so. */
if (! location->arrived)
{
- property_change_reply_object = location;
secs = x_selection_timeout / 1000;
usecs = (x_selection_timeout % 1000) * 1000;
wait_reading_process_input (secs, usecs, property_change_reply, 0);
@@ -1062,7 +1067,7 @@ x_get_foreign_selection (selection_symbol, target_type)
reading_selection_window = requestor_window;
reading_which_selection = selection_atom;
XCONS (reading_selection_reply)->car = Qnil;
- x_start_queuing_selection_requests (selected_frame);
+ x_start_queuing_selection_requests (display);
UNBLOCK_INPUT;
/* This allows quits. Also, don't wait forever. */
@@ -1073,7 +1078,7 @@ x_get_foreign_selection (selection_symbol, target_type)
BLOCK_INPUT;
x_check_errors (display, "Cannot get selection: %s");
x_uncatch_errors (display);
- x_stop_queuing_selection_requests (selected_frame);
+ x_stop_queuing_selection_requests (display);
UNBLOCK_INPUT;
if (NILP (XCONS (reading_selection_reply)->car))