aboutsummaryrefslogtreecommitdiffstats
path: root/src/xselect.c
diff options
context:
space:
mode:
authorRichard M. Stallman1995-02-02 18:49:38 +0000
committerRichard M. Stallman1995-02-02 18:49:38 +0000
commitafe1529d6faf7afafd95243cb39a128ff60cdcdc (patch)
tree9afefee35e8c3d7f602fca8a673a0084e02b6546 /src/xselect.c
parent8b66759af7c1735a39bb43d2bb395c8f71978841 (diff)
downloademacs-afe1529d6faf7afafd95243cb39a128ff60cdcdc.tar.gz
emacs-afe1529d6faf7afafd95243cb39a128ff60cdcdc.zip
(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
17along with GNU Emacs; see the file COPYING. If not, write to 17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19 19
20/* x_handle_selection_notify
21x_reply_selection_request */
22
23 20
24/* Rewritten by jwz */ 21/* Rewritten by jwz */
25 22
26#include <config.h> 23#include <config.h>
27#include "lisp.h" 24#include "lisp.h"
28#if 0
29#include <stdio.h> /* termhooks.h needs this */
30#include "termhooks.h"
31#endif
32#include "xterm.h" /* for all of the X includes */ 25#include "xterm.h" /* for all of the X includes */
33#include "dispextern.h" /* frame.h seems to want this */ 26#include "dispextern.h" /* frame.h seems to want this */
34#include "frame.h" /* Need this to get the X window of selected_frame */ 27#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)
500 reply.property = reply.target; 493 reply.property = reply.target;
501 494
502 /* #### XChangeProperty can generate BadAlloc, and we must handle it! */ 495 /* #### XChangeProperty can generate BadAlloc, and we must handle it! */
496 BLOCK_INPUT;
497 x_catch_errors (display);
503 498
504 /* Store the data on the requested property. 499 /* Store the data on the requested property.
505 If the selection is large, only store the first N bytes of it. 500 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)
511#if 0 506#if 0
512 fprintf (stderr,"\nStoring all %d\n", bytes_remaining); 507 fprintf (stderr,"\nStoring all %d\n", bytes_remaining);
513#endif 508#endif
514 BLOCK_INPUT;
515 XChangeProperty (display, window, reply.property, type, format, 509 XChangeProperty (display, window, reply.property, type, format,
516 PropModeReplace, data, size); 510 PropModeReplace, data, size);
517 /* At this point, the selection was successfully stored; ack it. */ 511 /* At this point, the selection was successfully stored; ack it. */
518 XSendEvent (display, window, False, 0L, (XEvent *) &reply); 512 XSendEvent (display, window, False, 0L, (XEvent *) &reply);
519 XFlush (display);
520 UNBLOCK_INPUT;
521 } 513 }
522 else 514 else
523 { 515 {
524 /* Send an INCR selection. */ 516 /* Send an INCR selection. */
525 struct prop_location *wait_object; 517 struct prop_location *wait_object;
518 int had_errors;
526 519
527 BLOCK_INPUT; 520 x_start_queuing_selection_requests (display);
528 521
529 if (x_window_to_frame (window)) /* #### debug */ 522 if (x_window_to_frame (window)) /* #### debug */
530 error ("attempt to transfer an INCR to ourself!"); 523 error ("attempt to transfer an INCR to ourself!");
@@ -541,11 +534,14 @@ x_reply_selection_request (event, format, data, size, type)
541 /* Tell 'em the INCR data is there... */ 534 /* Tell 'em the INCR data is there... */
542 (void) XSendEvent (display, window, False, 0L, (XEvent *) &reply); 535 (void) XSendEvent (display, window, False, 0L, (XEvent *) &reply);
543 XFlush (display); 536 XFlush (display);
537
538 had_errors = x_had_errors_p (display);
544 UNBLOCK_INPUT; 539 UNBLOCK_INPUT;
545 540
546 /* First, wait for the requestor to ack by deleting the property. 541 /* First, wait for the requestor to ack by deleting the property.
547 This can run random lisp code (process handlers) or signal. */ 542 This can run random lisp code (process handlers) or signal. */
548 wait_for_property_change (wait_object); 543 if (! had_errors)
544 wait_for_property_change (wait_object);
549 545
550 while (bytes_remaining) 546 while (bytes_remaining)
551 { 547 {
@@ -567,8 +563,12 @@ x_reply_selection_request (event, format, data, size, type)
567 bytes_remaining -= i; 563 bytes_remaining -= i;
568 data += i; 564 data += i;
569 XFlush (display); 565 XFlush (display);
566 had_errors = x_had_errors_p (display);
570 UNBLOCK_INPUT; 567 UNBLOCK_INPUT;
571 568
569 if (had_errors)
570 break;
571
572 /* Now wait for the requestor to ack this chunk by deleting the 572 /* Now wait for the requestor to ack this chunk by deleting the
573 property. This can run random lisp code or signal. 573 property. This can run random lisp code or signal.
574 */ 574 */
@@ -585,9 +585,12 @@ x_reply_selection_request (event, format, data, size, type)
585 585
586 XChangeProperty (display, window, reply.property, type, format, 586 XChangeProperty (display, window, reply.property, type, format,
587 PropModeReplace, data, 0); 587 PropModeReplace, data, 0);
588 XFlush (display); 588 x_stop_queuing_selection_requests (display);
589 UNBLOCK_INPUT;
590 } 589 }
590
591 XFlush (display);
592 x_uncatch_errors (display);
593 UNBLOCK_INPUT;
591} 594}
592 595
593/* Handle a SelectionRequest event EVENT. 596/* Handle a SelectionRequest event EVENT.
@@ -912,9 +915,11 @@ wait_for_property_change (location)
912 915
913 XCONS (property_change_reply)->car = Qnil; 916 XCONS (property_change_reply)->car = Qnil;
914 917
918 property_change_reply_object = location;
919 /* If the event we are waiting for arrives beyond here, it will set
920 property_change_reply, because property_change_reply_object says so. */
915 if (! location->arrived) 921 if (! location->arrived)
916 { 922 {
917 property_change_reply_object = location;
918 secs = x_selection_timeout / 1000; 923 secs = x_selection_timeout / 1000;
919 usecs = (x_selection_timeout % 1000) * 1000; 924 usecs = (x_selection_timeout % 1000) * 1000;
920 wait_reading_process_input (secs, usecs, property_change_reply, 0); 925 wait_reading_process_input (secs, usecs, property_change_reply, 0);
@@ -1062,7 +1067,7 @@ x_get_foreign_selection (selection_symbol, target_type)
1062 reading_selection_window = requestor_window; 1067 reading_selection_window = requestor_window;
1063 reading_which_selection = selection_atom; 1068 reading_which_selection = selection_atom;
1064 XCONS (reading_selection_reply)->car = Qnil; 1069 XCONS (reading_selection_reply)->car = Qnil;
1065 x_start_queuing_selection_requests (selected_frame); 1070 x_start_queuing_selection_requests (display);
1066 UNBLOCK_INPUT; 1071 UNBLOCK_INPUT;
1067 1072
1068 /* This allows quits. Also, don't wait forever. */ 1073 /* This allows quits. Also, don't wait forever. */
@@ -1073,7 +1078,7 @@ x_get_foreign_selection (selection_symbol, target_type)
1073 BLOCK_INPUT; 1078 BLOCK_INPUT;
1074 x_check_errors (display, "Cannot get selection: %s"); 1079 x_check_errors (display, "Cannot get selection: %s");
1075 x_uncatch_errors (display); 1080 x_uncatch_errors (display);
1076 x_stop_queuing_selection_requests (selected_frame); 1081 x_stop_queuing_selection_requests (display);
1077 UNBLOCK_INPUT; 1082 UNBLOCK_INPUT;
1078 1083
1079 if (NILP (XCONS (reading_selection_reply)->car)) 1084 if (NILP (XCONS (reading_selection_reply)->car))