diff options
| author | Richard M. Stallman | 1993-07-31 05:55:52 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1993-07-31 05:55:52 +0000 |
| commit | 2f65feb682856f64e9ea4f755b5f320e674cde2a (patch) | |
| tree | 32f31c8631cdd4d4956c353f2e631b6a6eae6667 /src/xselect.c | |
| parent | 7c011261b702092e005c901972af405c7b7c9f3b (diff) | |
| download | emacs-2f65feb682856f64e9ea4f755b5f320e674cde2a.tar.gz emacs-2f65feb682856f64e9ea4f755b5f320e674cde2a.zip | |
(prop_location_identifier): Was named prop_location_tick.
(property_change_reply_identifier): Renamed from ...-tick.
(struct prop_location): Field `identifier' renamed from `tick'.
Various functions changed accordingly.
(x_handle_selection_request): Delete local struct var `reply'.
(wait_for_property_change_unwind): New function.
(wait_for_property_change): Add unwind protect.
(wait_for_property_change): Eventually time out with error.
(x_reply_selection_request): XFlushQueue and UNBLOCK_INPUT
before calling wait_for_property_change.
(x_get_window_property): Simplify input blocking/unblocking.
Don't delete the property here.
(receive_incremental_selection): Delete property here.
Call XSelectInput to enable and disable PropertyChangeMask.
(x_get_window_property_as_lisp_data): And here.
Diffstat (limited to 'src/xselect.c')
| -rw-r--r-- | src/xselect.c | 157 |
1 files changed, 93 insertions, 64 deletions
diff --git a/src/xselect.c b/src/xselect.c index 891523a5fa6..b0675a63f0d 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -471,7 +471,6 @@ x_reply_selection_request (event, format, data, size, type) | |||
| 471 | 471 | ||
| 472 | /* #### XChangeProperty can generate BadAlloc, and we must handle it! */ | 472 | /* #### XChangeProperty can generate BadAlloc, and we must handle it! */ |
| 473 | 473 | ||
| 474 | BLOCK_INPUT; | ||
| 475 | /* Store the data on the requested property. | 474 | /* Store the data on the requested property. |
| 476 | If the selection is large, only store the first N bytes of it. | 475 | If the selection is large, only store the first N bytes of it. |
| 477 | */ | 476 | */ |
| @@ -482,16 +481,21 @@ x_reply_selection_request (event, format, data, size, type) | |||
| 482 | #if 0 | 481 | #if 0 |
| 483 | fprintf (stderr,"\nStoring all %d\n", bytes_remaining); | 482 | fprintf (stderr,"\nStoring all %d\n", bytes_remaining); |
| 484 | #endif | 483 | #endif |
| 484 | BLOCK_INPUT; | ||
| 485 | XChangeProperty (display, window, reply.property, type, format, | 485 | XChangeProperty (display, window, reply.property, type, format, |
| 486 | PropModeReplace, data, size); | 486 | PropModeReplace, data, size); |
| 487 | /* At this point, the selection was successfully stored; ack it. */ | 487 | /* At this point, the selection was successfully stored; ack it. */ |
| 488 | (void) XSendEvent (display, window, False, 0L, (XEvent *) &reply); | 488 | XSendEvent (display, window, False, 0L, (XEvent *) &reply); |
| 489 | XFlushQueue (); | ||
| 490 | UNBLOCK_INPUT; | ||
| 489 | } | 491 | } |
| 490 | else | 492 | else |
| 491 | { | 493 | { |
| 492 | /* Send an INCR selection. */ | 494 | /* Send an INCR selection. */ |
| 493 | int prop_id; | 495 | int prop_id; |
| 494 | 496 | ||
| 497 | BLOCK_INPUT; | ||
| 498 | |||
| 495 | if (x_window_to_frame (window)) /* #### debug */ | 499 | if (x_window_to_frame (window)) /* #### debug */ |
| 496 | error ("attempt to transfer an INCR to ourself!"); | 500 | error ("attempt to transfer an INCR to ourself!"); |
| 497 | #if 0 | 501 | #if 0 |
| @@ -506,6 +510,8 @@ x_reply_selection_request (event, format, data, size, type) | |||
| 506 | XSelectInput (display, window, PropertyChangeMask); | 510 | XSelectInput (display, window, PropertyChangeMask); |
| 507 | /* Tell 'em the INCR data is there... */ | 511 | /* Tell 'em the INCR data is there... */ |
| 508 | (void) XSendEvent (display, window, False, 0L, (XEvent *) &reply); | 512 | (void) XSendEvent (display, window, False, 0L, (XEvent *) &reply); |
| 513 | XFlushQueue (); | ||
| 514 | UNBLOCK_INPUT; | ||
| 509 | 515 | ||
| 510 | /* First, wait for the requestor to ack by deleting the property. | 516 | /* First, wait for the requestor to ack by deleting the property. |
| 511 | This can run random lisp code (process handlers) or signal. */ | 517 | This can run random lisp code (process handlers) or signal. */ |
| @@ -516,6 +522,9 @@ x_reply_selection_request (event, format, data, size, type) | |||
| 516 | int i = ((bytes_remaining < max_bytes) | 522 | int i = ((bytes_remaining < max_bytes) |
| 517 | ? bytes_remaining | 523 | ? bytes_remaining |
| 518 | : max_bytes); | 524 | : max_bytes); |
| 525 | |||
| 526 | BLOCK_INPUT; | ||
| 527 | |||
| 519 | prop_id = expect_property_change (display, window, reply.property, | 528 | prop_id = expect_property_change (display, window, reply.property, |
| 520 | PropertyDelete); | 529 | PropertyDelete); |
| 521 | #if 0 | 530 | #if 0 |
| @@ -526,6 +535,8 @@ x_reply_selection_request (event, format, data, size, type) | |||
| 526 | PropModeAppend, data, i / format_bytes); | 535 | PropModeAppend, data, i / format_bytes); |
| 527 | bytes_remaining -= i; | 536 | bytes_remaining -= i; |
| 528 | data += i; | 537 | data += i; |
| 538 | XFlushQueue (); | ||
| 539 | UNBLOCK_INPUT; | ||
| 529 | 540 | ||
| 530 | /* Now wait for the requestor to ack this chunk by deleting the | 541 | /* Now wait for the requestor to ack this chunk by deleting the |
| 531 | property. This can run random lisp code or signal. | 542 | property. This can run random lisp code or signal. |
| @@ -537,14 +548,15 @@ x_reply_selection_request (event, format, data, size, type) | |||
| 537 | #if 0 | 548 | #if 0 |
| 538 | fprintf (stderr," INCR done\n"); | 549 | fprintf (stderr," INCR done\n"); |
| 539 | #endif | 550 | #endif |
| 551 | BLOCK_INPUT; | ||
| 540 | if (! waiting_for_other_props_on_window (display, window)) | 552 | if (! waiting_for_other_props_on_window (display, window)) |
| 541 | XSelectInput (display, window, 0L); | 553 | XSelectInput (display, window, 0L); |
| 542 | 554 | ||
| 543 | XChangeProperty (display, window, reply.property, type, format, | 555 | XChangeProperty (display, window, reply.property, type, format, |
| 544 | PropModeReplace, data, 0); | 556 | PropModeReplace, data, 0); |
| 557 | XFlushQueue (); | ||
| 558 | UNBLOCK_INPUT; | ||
| 545 | } | 559 | } |
| 546 | XFlushQueue (); | ||
| 547 | UNBLOCK_INPUT; | ||
| 548 | } | 560 | } |
| 549 | 561 | ||
| 550 | /* Handle a SelectionRequest event EVENT. | 562 | /* Handle a SelectionRequest event EVENT. |
| @@ -555,7 +567,6 @@ x_handle_selection_request (event) | |||
| 555 | struct input_event *event; | 567 | struct input_event *event; |
| 556 | { | 568 | { |
| 557 | struct gcpro gcpro1, gcpro2, gcpro3; | 569 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 558 | XSelectionEvent reply; | ||
| 559 | Lisp_Object local_selection_data = Qnil; | 570 | Lisp_Object local_selection_data = Qnil; |
| 560 | Lisp_Object selection_symbol; | 571 | Lisp_Object selection_symbol; |
| 561 | Lisp_Object target_symbol = Qnil; | 572 | Lisp_Object target_symbol = Qnil; |
| @@ -566,35 +577,10 @@ x_handle_selection_request (event) | |||
| 566 | 577 | ||
| 567 | GCPRO3 (local_selection_data, converted_selection, target_symbol); | 578 | GCPRO3 (local_selection_data, converted_selection, target_symbol); |
| 568 | 579 | ||
| 569 | reply.type = SelectionNotify; /* Construct the reply event */ | 580 | selection_symbol = x_atom_to_symbol (SELECTION_EVENT_DISPLAY (event), |
| 570 | reply.display = SELECTION_EVENT_DISPLAY (event); | ||
| 571 | reply.requestor = SELECTION_EVENT_REQUESTOR (event); | ||
| 572 | reply.selection = SELECTION_EVENT_SELECTION (event); | ||
| 573 | reply.time = SELECTION_EVENT_TIME (event); | ||
| 574 | reply.target = SELECTION_EVENT_TARGET (event); | ||
| 575 | reply.property = SELECTION_EVENT_PROPERTY (event); | ||
| 576 | if (reply.property == None) | ||
| 577 | reply.property = reply.target; | ||
| 578 | |||
| 579 | selection_symbol = x_atom_to_symbol (reply.display, | ||
| 580 | SELECTION_EVENT_SELECTION (event)); | 581 | SELECTION_EVENT_SELECTION (event)); |
| 581 | 582 | ||
| 582 | local_selection_data = assq_no_quit (selection_symbol, Vselection_alist); | 583 | local_selection_data = assq_no_quit (selection_symbol, Vselection_alist); |
| 583 | |||
| 584 | #if 0 | ||
| 585 | # define CDR(x) (XCONS (x)->cdr) | ||
| 586 | # define CAR(x) (XCONS (x)->car) | ||
| 587 | /* This list isn't user-visible, so it can't "go bad." */ | ||
| 588 | if (!CONSP (local_selection_data)) abort (); | ||
| 589 | if (!CONSP (CDR (local_selection_data))) abort (); | ||
| 590 | if (!CONSP (CDR (CDR (local_selection_data)))) abort (); | ||
| 591 | if (!NILP (CDR (CDR (CDR (local_selection_data))))) abort (); | ||
| 592 | if (!CONSP (CAR (CDR (CDR (local_selection_data))))) abort (); | ||
| 593 | if (!INTEGERP (CAR (CAR (CDR (CDR (local_selection_data)))))) abort (); | ||
| 594 | if (!INTEGERP (CDR (CAR (CDR (CDR (local_selection_data)))))) abort (); | ||
| 595 | # undef CAR | ||
| 596 | # undef CDR | ||
| 597 | #endif | ||
| 598 | 584 | ||
| 599 | if (NILP (local_selection_data)) | 585 | if (NILP (local_selection_data)) |
| 600 | { | 586 | { |
| @@ -621,7 +607,7 @@ x_handle_selection_request (event) | |||
| 621 | x_selection_current_request = event; | 607 | x_selection_current_request = event; |
| 622 | record_unwind_protect (x_selection_request_lisp_error, Qnil); | 608 | record_unwind_protect (x_selection_request_lisp_error, Qnil); |
| 623 | 609 | ||
| 624 | target_symbol = x_atom_to_symbol (reply.display, | 610 | target_symbol = x_atom_to_symbol (SELECTION_EVENT_DISPLAY (event), |
| 625 | SELECTION_EVENT_TARGET (event)); | 611 | SELECTION_EVENT_TARGET (event)); |
| 626 | 612 | ||
| 627 | #if 0 /* #### MULTIPLE doesn't work yet */ | 613 | #if 0 /* #### MULTIPLE doesn't work yet */ |
| @@ -642,7 +628,8 @@ x_handle_selection_request (event) | |||
| 642 | Atom type; | 628 | Atom type; |
| 643 | int nofree; | 629 | int nofree; |
| 644 | 630 | ||
| 645 | lisp_data_to_selection_data (reply.display, converted_selection, | 631 | lisp_data_to_selection_data (SELECTION_EVENT_DISPLAY (event), |
| 632 | converted_selection, | ||
| 646 | &data, &type, &size, &format, &nofree); | 633 | &data, &type, &size, &format, &nofree); |
| 647 | 634 | ||
| 648 | x_reply_selection_request (event, format, data, size, type); | 635 | x_reply_selection_request (event, format, data, size, type); |
| @@ -733,16 +720,16 @@ x_handle_selection_clear (event) | |||
| 733 | be servicing multiple INCR selection requests simultaneously.) I haven't | 720 | be servicing multiple INCR selection requests simultaneously.) I haven't |
| 734 | actually tested that yet. */ | 721 | actually tested that yet. */ |
| 735 | 722 | ||
| 736 | static int prop_location_tick; | 723 | static int prop_location_identifier; |
| 737 | 724 | ||
| 738 | static Lisp_Object property_change_reply; | 725 | static Lisp_Object property_change_reply; |
| 739 | static int property_change_reply_tick; | 726 | static int property_change_reply_identifier; |
| 740 | 727 | ||
| 741 | /* Keep a list of the property changes that are awaited. */ | 728 | /* Keep a list of the property changes that are awaited. */ |
| 742 | 729 | ||
| 743 | struct prop_location | 730 | struct prop_location |
| 744 | { | 731 | { |
| 745 | int tick; | 732 | int identifier; |
| 746 | Display *display; | 733 | Display *display; |
| 747 | Window window; | 734 | Window window; |
| 748 | Atom property; | 735 | Atom property; |
| @@ -753,12 +740,12 @@ struct prop_location | |||
| 753 | static struct prop_location *property_change_wait_list; | 740 | static struct prop_location *property_change_wait_list; |
| 754 | 741 | ||
| 755 | static int | 742 | static int |
| 756 | property_deleted_p (tick) | 743 | property_deleted_p (identifier) |
| 757 | void *tick; | 744 | void *identifier; |
| 758 | { | 745 | { |
| 759 | struct prop_location *rest = property_change_wait_list; | 746 | struct prop_location *rest = property_change_wait_list; |
| 760 | while (rest) | 747 | while (rest) |
| 761 | if (rest->tick == (int) tick) | 748 | if (rest->identifier == (int) identifier) |
| 762 | return 0; | 749 | return 0; |
| 763 | else | 750 | else |
| 764 | rest = rest->next; | 751 | rest = rest->next; |
| @@ -796,27 +783,27 @@ expect_property_change (display, window, property, state) | |||
| 796 | { | 783 | { |
| 797 | struct prop_location *pl | 784 | struct prop_location *pl |
| 798 | = (struct prop_location *) xmalloc (sizeof (struct prop_location)); | 785 | = (struct prop_location *) xmalloc (sizeof (struct prop_location)); |
| 799 | pl->tick = ++prop_location_tick; | 786 | pl->identifier = ++prop_location_identifier; |
| 800 | pl->display = display; | 787 | pl->display = display; |
| 801 | pl->window = window; | 788 | pl->window = window; |
| 802 | pl->property = property; | 789 | pl->property = property; |
| 803 | pl->desired_state = state; | 790 | pl->desired_state = state; |
| 804 | pl->next = property_change_wait_list; | 791 | pl->next = property_change_wait_list; |
| 805 | property_change_wait_list = pl; | 792 | property_change_wait_list = pl; |
| 806 | return pl->tick; | 793 | return pl->identifier; |
| 807 | } | 794 | } |
| 808 | 795 | ||
| 809 | /* Delete an entry from the list of property changes we are waiting for. | 796 | /* Delete an entry from the list of property changes we are waiting for. |
| 810 | TICK is the number that uniquely identifies the entry. */ | 797 | IDENTIFIER is the number that uniquely identifies the entry. */ |
| 811 | 798 | ||
| 812 | static void | 799 | static void |
| 813 | unexpect_property_change (tick) | 800 | unexpect_property_change (identifier) |
| 814 | int tick; | 801 | int identifier; |
| 815 | { | 802 | { |
| 816 | struct prop_location *prev = 0, *rest = property_change_wait_list; | 803 | struct prop_location *prev = 0, *rest = property_change_wait_list; |
| 817 | while (rest) | 804 | while (rest) |
| 818 | { | 805 | { |
| 819 | if (rest->tick == tick) | 806 | if (rest->identifier == identifier) |
| 820 | { | 807 | { |
| 821 | if (prev) | 808 | if (prev) |
| 822 | prev->next = rest->next; | 809 | prev->next = rest->next; |
| @@ -830,15 +817,38 @@ unexpect_property_change (tick) | |||
| 830 | } | 817 | } |
| 831 | } | 818 | } |
| 832 | 819 | ||
| 820 | /* Remove the property change expectation element for IDENTIFIER. */ | ||
| 821 | |||
| 822 | static Lisp_Object | ||
| 823 | wait_for_property_change_unwind (identifierval) | ||
| 824 | Lisp_Object identifierval; | ||
| 825 | { | ||
| 826 | unexpect_property_change (XFASTINT (identifierval)); | ||
| 827 | } | ||
| 828 | |||
| 833 | /* Actually wait for a property change. | 829 | /* Actually wait for a property change. |
| 834 | TICK should be the value that expect_property_change returned. */ | 830 | IDENTIFIER should be the value that expect_property_change returned. */ |
| 835 | 831 | ||
| 836 | static void | 832 | static void |
| 837 | wait_for_property_change (tick) | 833 | wait_for_property_change (identifier) |
| 838 | { | 834 | { |
| 835 | int secs, usecs; | ||
| 836 | int count = specpdl_ptr - specpdl; | ||
| 837 | |||
| 838 | /* Make sure to do unexpect_property_change if we quit or err. */ | ||
| 839 | record_unwind_protect (wait_for_property_change_unwind, | ||
| 840 | make_number (identifier)); | ||
| 841 | |||
| 839 | XCONS (property_change_reply)->car = Qnil; | 842 | XCONS (property_change_reply)->car = Qnil; |
| 840 | property_change_reply_tick = tick; | 843 | property_change_reply_identifier = identifier; |
| 841 | wait_reading_process_input (0, 0, property_change_reply, 0); | 844 | secs = x_selection_timeout / 1000; |
| 845 | usecs = (x_selection_timeout % 1000) * 1000; | ||
| 846 | wait_reading_process_input (secs, usecs, property_change_reply, 0); | ||
| 847 | |||
| 848 | if (NILP (XCONS (property_change_reply)->car)) | ||
| 849 | error ("timed out waiting for property-notify event"); | ||
| 850 | |||
| 851 | unbind_to (count, Qnil); | ||
| 842 | } | 852 | } |
| 843 | 853 | ||
| 844 | /* Called from XTread_socket in response to a PropertyNotify event. */ | 854 | /* Called from XTread_socket in response to a PropertyNotify event. */ |
| @@ -865,7 +875,7 @@ x_handle_property_notify (event) | |||
| 865 | 875 | ||
| 866 | /* If this is the one wait_for_property_change is waiting for, | 876 | /* If this is the one wait_for_property_change is waiting for, |
| 867 | tell it to wake up. */ | 877 | tell it to wake up. */ |
| 868 | if (rest->tick == property_change_reply_tick) | 878 | if (rest->identifier == property_change_reply_identifier) |
| 869 | XCONS (property_change_reply)->car = Qt; | 879 | XCONS (property_change_reply)->car = Qt; |
| 870 | 880 | ||
| 871 | if (prev) | 881 | if (prev) |
| @@ -1024,20 +1034,18 @@ x_get_window_property (display, window, property, data_ret, bytes_ret, | |||
| 1024 | actual_type_ret, actual_format_ret, | 1034 | actual_type_ret, actual_format_ret, |
| 1025 | actual_size_ret, | 1035 | actual_size_ret, |
| 1026 | &bytes_remaining, &tmp_data); | 1036 | &bytes_remaining, &tmp_data); |
| 1027 | UNBLOCK_INPUT; | ||
| 1028 | if (result != Success) | 1037 | if (result != Success) |
| 1029 | { | 1038 | { |
| 1039 | UNBLOCK_INPUT; | ||
| 1030 | *data_ret = 0; | 1040 | *data_ret = 0; |
| 1031 | *bytes_ret = 0; | 1041 | *bytes_ret = 0; |
| 1032 | return; | 1042 | return; |
| 1033 | } | 1043 | } |
| 1034 | BLOCK_INPUT; | 1044 | xfree ((char *) tmp_data); |
| 1035 | XFree ((char *) tmp_data); | ||
| 1036 | UNBLOCK_INPUT; | ||
| 1037 | 1045 | ||
| 1038 | if (*actual_type_ret == None || *actual_format_ret == 0) | 1046 | if (*actual_type_ret == None || *actual_format_ret == 0) |
| 1039 | { | 1047 | { |
| 1040 | if (delete_p) XDeleteProperty (display, window, property); | 1048 | UNBLOCK_INPUT; |
| 1041 | return; | 1049 | return; |
| 1042 | } | 1050 | } |
| 1043 | 1051 | ||
| @@ -1045,7 +1053,6 @@ x_get_window_property (display, window, property, data_ret, bytes_ret, | |||
| 1045 | *data_ret = (unsigned char *) xmalloc (total_size); | 1053 | *data_ret = (unsigned char *) xmalloc (total_size); |
| 1046 | 1054 | ||
| 1047 | /* Now read, until weve gotten it all. */ | 1055 | /* Now read, until weve gotten it all. */ |
| 1048 | BLOCK_INPUT; | ||
| 1049 | while (bytes_remaining) | 1056 | while (bytes_remaining) |
| 1050 | { | 1057 | { |
| 1051 | #if 0 | 1058 | #if 0 |
| @@ -1054,7 +1061,7 @@ x_get_window_property (display, window, property, data_ret, bytes_ret, | |||
| 1054 | result | 1061 | result |
| 1055 | = XGetWindowProperty (display, window, property, | 1062 | = XGetWindowProperty (display, window, property, |
| 1056 | offset/4, buffer_size/4, | 1063 | offset/4, buffer_size/4, |
| 1057 | (delete_p ? True : False), | 1064 | False, |
| 1058 | AnyPropertyType, | 1065 | AnyPropertyType, |
| 1059 | actual_type_ret, actual_format_ret, | 1066 | actual_type_ret, actual_format_ret, |
| 1060 | actual_size_ret, &bytes_remaining, &tmp_data); | 1067 | actual_size_ret, &bytes_remaining, &tmp_data); |
| @@ -1069,8 +1076,10 @@ x_get_window_property (display, window, property, data_ret, bytes_ret, | |||
| 1069 | *actual_size_ret *= *actual_format_ret / 8; | 1076 | *actual_size_ret *= *actual_format_ret / 8; |
| 1070 | bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret); | 1077 | bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret); |
| 1071 | offset += *actual_size_ret; | 1078 | offset += *actual_size_ret; |
| 1072 | XFree ((char *) tmp_data); | 1079 | xfree ((char *) tmp_data); |
| 1073 | } | 1080 | } |
| 1081 | |||
| 1082 | XFlushQueue (); | ||
| 1074 | UNBLOCK_INPUT; | 1083 | UNBLOCK_INPUT; |
| 1075 | *bytes_ret = offset; | 1084 | *bytes_ret = offset; |
| 1076 | } | 1085 | } |
| @@ -1097,16 +1106,23 @@ receive_incremental_selection (display, window, property, target_type, | |||
| 1097 | #if 0 | 1106 | #if 0 |
| 1098 | fprintf (stderr, "\nread INCR %d\n", min_size_bytes); | 1107 | fprintf (stderr, "\nread INCR %d\n", min_size_bytes); |
| 1099 | #endif | 1108 | #endif |
| 1100 | /* At this point, we have read an INCR property, and deleted it (which | 1109 | |
| 1101 | is how we ack its receipt: the sending window will be selecting | 1110 | /* At this point, we have read an INCR property. |
| 1102 | PropertyNotify events on our window to notice this.) | 1111 | Delete the property to ack it. |
| 1112 | (But first, prepare to receive the next event in this handshake.) | ||
| 1103 | 1113 | ||
| 1104 | Now, we must loop, waiting for the sending window to put a value on | 1114 | Now, we must loop, waiting for the sending window to put a value on |
| 1105 | that property, then reading the property, then deleting it to ack. | 1115 | that property, then reading the property, then deleting it to ack. |
| 1106 | We are done when the sender places a property of length 0. | 1116 | We are done when the sender places a property of length 0. |
| 1107 | */ | 1117 | */ |
| 1118 | BLOCK_INPUT; | ||
| 1119 | XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask); | ||
| 1120 | XDeleteProperty (display, window, property); | ||
| 1108 | prop_id = expect_property_change (display, window, property, | 1121 | prop_id = expect_property_change (display, window, property, |
| 1109 | PropertyNewValue); | 1122 | PropertyNewValue); |
| 1123 | XFlushQueue (); | ||
| 1124 | UNBLOCK_INPUT; | ||
| 1125 | |||
| 1110 | while (1) | 1126 | while (1) |
| 1111 | { | 1127 | { |
| 1112 | unsigned char *tmp_data; | 1128 | unsigned char *tmp_data; |
| @@ -1116,8 +1132,6 @@ receive_incremental_selection (display, window, property, target_type, | |||
| 1116 | .. no it wont, I dont get it. | 1132 | .. no it wont, I dont get it. |
| 1117 | .. Ok, I get it now, the Xt code that implements INCR is broken. | 1133 | .. Ok, I get it now, the Xt code that implements INCR is broken. |
| 1118 | */ | 1134 | */ |
| 1119 | prop_id = expect_property_change (display, window, property, | ||
| 1120 | PropertyNewValue); | ||
| 1121 | x_get_window_property (display, window, property, | 1135 | x_get_window_property (display, window, property, |
| 1122 | &tmp_data, &tmp_size_bytes, | 1136 | &tmp_data, &tmp_size_bytes, |
| 1123 | type_ret, format_ret, size_ret, 1); | 1137 | type_ret, format_ret, size_ret, 1); |
| @@ -1127,10 +1141,20 @@ receive_incremental_selection (display, window, property, target_type, | |||
| 1127 | #if 0 | 1141 | #if 0 |
| 1128 | fprintf (stderr, " read INCR done\n"); | 1142 | fprintf (stderr, " read INCR done\n"); |
| 1129 | #endif | 1143 | #endif |
| 1144 | if (! waiting_for_other_props_on_window (display, window)) | ||
| 1145 | XSelectInput (display, window, STANDARD_EVENT_SET); | ||
| 1130 | unexpect_property_change (prop_id); | 1146 | unexpect_property_change (prop_id); |
| 1131 | if (tmp_data) xfree (tmp_data); | 1147 | if (tmp_data) xfree (tmp_data); |
| 1132 | break; | 1148 | break; |
| 1133 | } | 1149 | } |
| 1150 | |||
| 1151 | BLOCK_INPUT; | ||
| 1152 | XDeleteProperty (display, window, property); | ||
| 1153 | prop_id = expect_property_change (display, window, property, | ||
| 1154 | PropertyNewValue); | ||
| 1155 | XFlushQueue (); | ||
| 1156 | UNBLOCK_INPUT; | ||
| 1157 | |||
| 1134 | #if 0 | 1158 | #if 0 |
| 1135 | fprintf (stderr, " read INCR %d\n", tmp_size_bytes); | 1159 | fprintf (stderr, " read INCR %d\n", tmp_size_bytes); |
| 1136 | #endif | 1160 | #endif |
| @@ -1206,6 +1230,11 @@ x_get_window_property_as_lisp_data (display, window, property, target_type, | |||
| 1206 | &actual_size); | 1230 | &actual_size); |
| 1207 | } | 1231 | } |
| 1208 | 1232 | ||
| 1233 | BLOCK_INPUT; | ||
| 1234 | XDeleteProperty (display, window, property); | ||
| 1235 | XFlushQueue (); | ||
| 1236 | UNBLOCK_INPUT; | ||
| 1237 | |||
| 1209 | /* It's been read. Now convert it to a lisp object in some semi-rational | 1238 | /* It's been read. Now convert it to a lisp object in some semi-rational |
| 1210 | manner. */ | 1239 | manner. */ |
| 1211 | val = selection_data_to_lisp_data (display, data, bytes, | 1240 | val = selection_data_to_lisp_data (display, data, bytes, |
| @@ -1899,7 +1928,7 @@ syms_of_xselect () | |||
| 1899 | reading_which_selection = 0; | 1928 | reading_which_selection = 0; |
| 1900 | 1929 | ||
| 1901 | property_change_wait_list = 0; | 1930 | property_change_wait_list = 0; |
| 1902 | prop_location_tick = 0; | 1931 | prop_location_identifier = 0; |
| 1903 | property_change_reply = Fcons (Qnil, Qnil); | 1932 | property_change_reply = Fcons (Qnil, Qnil); |
| 1904 | staticpro (&property_change_reply); | 1933 | staticpro (&property_change_reply); |
| 1905 | 1934 | ||