Mercurial > hg > xemacs-beta
comparison src/select-x.c @ 410:de805c49cfc1 r21-2-35
Import from CVS: tag r21-2-35
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:19:21 +0200 |
parents | 74fd4e045ea6 |
children |
comparison
equal
deleted
inserted
replaced
409:301b9ebbdf3b | 410:de805c49cfc1 |
---|---|
198 } | 198 } |
199 } | 199 } |
200 | 200 |
201 | 201 |
202 /* Do protocol to assert ourself as a selection owner. | 202 /* Do protocol to assert ourself as a selection owner. |
203 Update the Vselection_alist so that we can reply to later requests for | |
204 our selection. | |
205 */ | 203 */ |
206 static Lisp_Object | 204 static Lisp_Object |
207 x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value) | 205 x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, |
206 Lisp_Object how_to_add, Lisp_Object selection_type) | |
208 { | 207 { |
209 struct device *d = decode_x_device (Qnil); | 208 struct device *d = decode_x_device (Qnil); |
210 Display *display = DEVICE_X_DISPLAY (d); | 209 Display *display = DEVICE_X_DISPLAY (d); |
211 struct frame *sel_frame = selected_frame (); | 210 struct frame *sel_frame = selected_frame (); |
212 Window selecting_window = XtWindow (FRAME_X_TEXT_WIDGET (sel_frame)); | 211 Window selecting_window = XtWindow (FRAME_X_TEXT_WIDGET (sel_frame)); |
250 static void | 249 static void |
251 hack_motif_clipboard_selection (Atom selection_atom, | 250 hack_motif_clipboard_selection (Atom selection_atom, |
252 Lisp_Object selection_value, | 251 Lisp_Object selection_value, |
253 Time thyme, | 252 Time thyme, |
254 Display *display, | 253 Display *display, |
255 Window selecting_window) | 254 Window selecting_window) |
256 /* Bool owned_p)*/ | 255 /* Bool owned_p)*/ |
257 { | 256 { |
258 struct device *d = get_device_from_display (display); | 257 struct device *d = get_device_from_display (display); |
259 /* Those Motif wankers can't be bothered to follow the ICCCM, and do | 258 /* Those Motif wankers can't be bothered to follow the ICCCM, and do |
260 their own non-Xlib non-Xt clipboard processing. So we have to do | 259 their own non-Xlib non-Xt clipboard processing. So we have to do |
373 { | 372 { |
374 case XmCR_CLIPBOARD_DATA_REQUEST: | 373 case XmCR_CLIPBOARD_DATA_REQUEST: |
375 { | 374 { |
376 Display *dpy = XtDisplay (widget); | 375 Display *dpy = XtDisplay (widget); |
377 Window window = (Window) *private_id; | 376 Window window = (Window) *private_id; |
378 Lisp_Object selection = assq_no_quit (QCLIPBOARD, Vselection_alist); | 377 Lisp_Object selection = select_convert_out (QCLIPBOARD, Qnil, Qnil); |
379 if (NILP (selection)) abort (); | 378 |
380 selection = XCDR (selection); | 379 /* Whichever lazy git wrote this originally just called abort() |
381 if (!STRINGP (selection)) abort (); | 380 when anything didn't go their way... */ |
381 | |
382 /* Try some other text types */ | |
383 if (NILP (selection)) | |
384 selection = select_convert_out (QCLIPBOARD, QSTRING, Qnil); | |
385 if (NILP (selection)) | |
386 selection = select_convert_out (QCLIPBOARD, QTEXT, Qnil); | |
387 if (NILP (selection)) | |
388 selection = select_convert_out (QCLIPBOARD, QCOMPOUND_TEXT, Qnil); | |
389 | |
390 if (CONSP (selection) && SYMBOLP (XCAR (selection)) | |
391 && (EQ (XCAR (selection), QSTRING) | |
392 || EQ (XCAR (selection), QTEXT) | |
393 || EQ (XCAR (selection), QCOMPOUND_TEXT))) | |
394 selection = XCDR (selection); | |
395 | |
396 if (NILP (selection)) | |
397 signal_error (Qselection_conversion_error, | |
398 build_string ("no selection")); | |
399 | |
400 if (!STRINGP (selection)) | |
401 signal_error (Qselection_conversion_error, | |
402 build_string ("couldn't convert selection to string")); | |
403 | |
404 | |
382 XmClipboardCopyByName (dpy, window, *data_id, | 405 XmClipboardCopyByName (dpy, window, *data_id, |
383 (char *) XSTRING_DATA (selection), | 406 (char *) XSTRING_DATA (selection), |
384 XSTRING_LENGTH (selection) + 1, | 407 XSTRING_LENGTH (selection) + 1, |
385 0); | 408 0); |
386 } | 409 } |
544 */ | 567 */ |
545 void | 568 void |
546 x_handle_selection_request (XSelectionRequestEvent *event) | 569 x_handle_selection_request (XSelectionRequestEvent *event) |
547 { | 570 { |
548 /* This function can GC */ | 571 /* This function can GC */ |
549 struct gcpro gcpro1, gcpro2, gcpro3; | 572 struct gcpro gcpro1, gcpro2; |
550 Lisp_Object local_selection_data = Qnil; | 573 Lisp_Object temp_obj; |
551 Lisp_Object selection_symbol; | 574 Lisp_Object selection_symbol; |
552 Lisp_Object target_symbol = Qnil; | 575 Lisp_Object target_symbol = Qnil; |
553 Lisp_Object converted_selection = Qnil; | 576 Lisp_Object converted_selection = Qnil; |
554 Time local_selection_time; | 577 Time local_selection_time; |
555 Lisp_Object successful_p = Qnil; | 578 Lisp_Object successful_p = Qnil; |
556 int count; | 579 int count; |
557 struct device *d = get_device_from_display (event->display); | 580 struct device *d = get_device_from_display (event->display); |
558 | 581 |
559 GCPRO3 (local_selection_data, converted_selection, target_symbol); | 582 GCPRO2 (converted_selection, target_symbol); |
560 | 583 |
561 selection_symbol = x_atom_to_symbol (d, event->selection); | 584 selection_symbol = x_atom_to_symbol (d, event->selection); |
562 | 585 target_symbol = x_atom_to_symbol (d, event->target); |
563 local_selection_data = assq_no_quit (selection_symbol, Vselection_alist); | 586 |
564 | 587 #if 0 /* #### MULTIPLE doesn't work yet */ |
565 #if 0 | 588 if (EQ (target_symbol, QMULTIPLE)) |
566 /* This list isn't user-visible, so it can't "go bad." */ | 589 target_symbol = fetch_multiple_target (event); |
567 assert (CONSP (local_selection_data)); | 590 #endif |
568 assert (CONSP (XCDR (local_selection_data))); | 591 |
569 assert (CONSP (XCDR (XCDR (local_selection_data)))); | 592 temp_obj = Fget_selection_timestamp (selection_symbol); |
570 assert (NILP (XCDR (XCDR (XCDR (local_selection_data))))); | 593 |
571 assert (CONSP (XCAR (XCDR (XCDR (local_selection_data))))); | 594 if (NILP (temp_obj)) |
572 assert (INTP (XCAR (XCAR (XCDR (XCDR (local_selection_data)))))); | 595 { |
573 assert (INTP (XCDR (XCAR (XCDR (XCDR (local_selection_data)))))); | 596 /* We don't appear to have the selection. */ |
574 #endif | |
575 | |
576 if (NILP (local_selection_data)) | |
577 { | |
578 /* Someone asked for the selection, but we don't have it any more. */ | |
579 x_decline_selection_request (event); | 597 x_decline_selection_request (event); |
598 | |
580 goto DONE_LABEL; | 599 goto DONE_LABEL; |
581 } | 600 } |
582 | 601 |
583 local_selection_time = | 602 local_selection_time = * (Time *) XOPAQUE_DATA (temp_obj); |
584 * (Time *) XOPAQUE_DATA (XCAR (XCDR (XCDR (local_selection_data)))); | 603 |
585 | |
586 if (event->time != CurrentTime && | 604 if (event->time != CurrentTime && |
587 local_selection_time > event->time) | 605 local_selection_time > event->time) |
588 { | 606 { |
589 /* Someone asked for the selection, and we have one, but not the one | 607 /* Someone asked for the selection, and we have one, but not the one |
590 they're looking for. */ | 608 they're looking for. */ |
591 x_decline_selection_request (event); | 609 x_decline_selection_request (event); |
592 goto DONE_LABEL; | 610 goto DONE_LABEL; |
593 } | 611 } |
594 | 612 |
613 converted_selection = select_convert_out (selection_symbol, | |
614 target_symbol, Qnil); | |
615 | |
616 /* #### Is this the right thing to do? I'm no X expert. -- ajh */ | |
617 if (NILP (converted_selection)) | |
618 { | |
619 /* We don't appear to have a selection in that data type. */ | |
620 x_decline_selection_request (event); | |
621 goto DONE_LABEL; | |
622 } | |
623 | |
595 count = specpdl_depth (); | 624 count = specpdl_depth (); |
596 record_unwind_protect (x_selection_request_lisp_error, | 625 record_unwind_protect (x_selection_request_lisp_error, |
597 make_opaque_ptr (event)); | 626 make_opaque_ptr (event)); |
598 target_symbol = x_atom_to_symbol (d, event->target); | 627 |
599 | 628 { |
600 #if 0 /* #### MULTIPLE doesn't work yet */ | 629 unsigned char *data; |
601 if (EQ (target_symbol, QMULTIPLE)) | 630 unsigned int size; |
602 target_symbol = fetch_multiple_target (event); | 631 int format; |
603 #endif | 632 Atom type; |
604 | 633 lisp_data_to_selection_data (d, converted_selection, |
605 /* Convert lisp objects back into binary data */ | 634 &data, &type, &size, &format); |
606 | 635 |
607 converted_selection = | 636 x_reply_selection_request (event, format, data, size, type); |
608 get_local_selection (selection_symbol, target_symbol); | 637 successful_p = Qt; |
609 | 638 /* Tell x_selection_request_lisp_error() it's cool. */ |
610 if (! NILP (converted_selection)) | 639 event->type = 0; |
611 { | 640 xfree (data); |
612 unsigned char *data; | 641 } |
613 unsigned int size; | 642 |
614 int format; | |
615 Atom type; | |
616 lisp_data_to_selection_data (d, converted_selection, | |
617 &data, &type, &size, &format); | |
618 | |
619 x_reply_selection_request (event, format, data, size, type); | |
620 successful_p = Qt; | |
621 /* Tell x_selection_request_lisp_error() it's cool. */ event->type = 0; | |
622 xfree (data); | |
623 } | |
624 unbind_to (count, Qnil); | 643 unbind_to (count, Qnil); |
625 | 644 |
626 DONE_LABEL: | 645 DONE_LABEL: |
627 | 646 |
628 UNGCPRO; | 647 UNGCPRO; |
629 | 648 |
630 /* Let random lisp code notice that the selection has been asked for. */ | 649 /* Let random lisp code notice that the selection has been asked for. */ |
631 { | 650 { |
632 Lisp_Object rest; | |
633 Lisp_Object val = Vx_sent_selection_hooks; | 651 Lisp_Object val = Vx_sent_selection_hooks; |
634 if (!UNBOUNDP (val) && !NILP (val)) | 652 if (!UNBOUNDP (val) && !NILP (val)) |
635 { | 653 { |
654 Lisp_Object rest; | |
636 if (CONSP (val) && !EQ (XCAR (val), Qlambda)) | 655 if (CONSP (val) && !EQ (XCAR (val), Qlambda)) |
637 for (rest = val; !NILP (rest); rest = Fcdr (rest)) | 656 for (rest = val; !NILP (rest); rest = Fcdr (rest)) |
638 call3 (Fcar(rest), selection_symbol, target_symbol, | 657 call3 (Fcar (rest), selection_symbol, target_symbol, successful_p); |
639 successful_p); | |
640 else | 658 else |
641 call3 (val, selection_symbol, target_symbol, | 659 call3 (val, selection_symbol, target_symbol, successful_p); |
642 successful_p); | |
643 } | 660 } |
644 } | 661 } |
645 } | 662 } |
646 | 663 |
647 | 664 |
653 Display *display = event->display; | 670 Display *display = event->display; |
654 struct device *d = get_device_from_display (display); | 671 struct device *d = get_device_from_display (display); |
655 Atom selection = event->selection; | 672 Atom selection = event->selection; |
656 Time changed_owner_time = event->time; | 673 Time changed_owner_time = event->time; |
657 | 674 |
658 Lisp_Object selection_symbol, local_selection_data; | 675 Lisp_Object selection_symbol, local_selection_time_lisp; |
659 Time local_selection_time; | 676 Time local_selection_time; |
660 | 677 |
661 selection_symbol = x_atom_to_symbol (d, selection); | 678 selection_symbol = x_atom_to_symbol (d, selection); |
662 | 679 |
663 local_selection_data = assq_no_quit (selection_symbol, Vselection_alist); | 680 local_selection_time_lisp = Fget_selection_timestamp (selection_symbol); |
664 | 681 |
665 /* Well, we already believe that we don't own it, so that's just fine. */ | 682 /* We don't own the selection, so that's fine. */ |
666 if (NILP (local_selection_data)) return; | 683 if (NILP (local_selection_time_lisp)) |
667 | 684 return; |
668 local_selection_time = | 685 |
669 * (Time *) XOPAQUE_DATA (XCAR (XCDR (XCDR (local_selection_data)))); | 686 local_selection_time = * (Time *) XOPAQUE_DATA (local_selection_time_lisp); |
670 | 687 |
671 /* This SelectionClear is for a selection that we no longer own, so we can | 688 /* This SelectionClear is for a selection that we no longer own, so we can |
672 disregard it. (That is, we have reasserted the selection since this | 689 disregard it. (That is, we have reasserted the selection since this |
673 request was generated.) | 690 request was generated.) |
674 */ | 691 */ |
918 error ("timed out waiting for reply from selection owner"); | 935 error ("timed out waiting for reply from selection owner"); |
919 | 936 |
920 unbind_to (speccount, Qnil); | 937 unbind_to (speccount, Qnil); |
921 | 938 |
922 /* otherwise, the selection is waiting for us on the requested property. */ | 939 /* otherwise, the selection is waiting for us on the requested property. */ |
923 return | 940 |
924 x_get_window_property_as_lisp_data (display, requestor_window, | 941 return select_convert_in (selection_symbol, |
925 target_property, target_type, | 942 target_type, |
926 selection_atom); | 943 x_get_window_property_as_lisp_data(display, |
944 requestor_window, | |
945 target_property, | |
946 target_type, | |
947 selection_atom)); | |
927 } | 948 } |
928 | 949 |
929 | 950 |
930 static void | 951 static void |
931 x_get_window_property (Display *display, Window window, Atom property, | 952 x_get_window_property (Display *display, Window window, Atom property, |
1121 | 1142 |
1122 xfree (data); | 1143 xfree (data); |
1123 return val; | 1144 return val; |
1124 } | 1145 } |
1125 | 1146 |
1147 /* #### These are going to move into Lisp code(!) with the aid of | |
1148 some new functions I'm working on - ajh */ | |
1149 | |
1126 /* These functions convert from the selection data read from the server into | 1150 /* These functions convert from the selection data read from the server into |
1127 something that we can use from elisp, and vice versa. | 1151 something that we can use from elisp, and vice versa. |
1128 | 1152 |
1129 Type: Format: Size: Elisp Type: | 1153 Type: Format: Size: Elisp Type: |
1130 ----- ------- ----- ----------- | 1154 ----- ------- ----- ----------- |
1465 | 1489 |
1466 XSetSelectionOwner (display, selection_atom, None, timestamp); | 1490 XSetSelectionOwner (display, selection_atom, None, timestamp); |
1467 } | 1491 } |
1468 | 1492 |
1469 static Lisp_Object | 1493 static Lisp_Object |
1470 x_selection_exists_p (Lisp_Object selection) | 1494 x_selection_exists_p (Lisp_Object selection, |
1495 Lisp_Object selection_type) | |
1471 { | 1496 { |
1472 struct device *d = decode_x_device (Qnil); | 1497 struct device *d = decode_x_device (Qnil); |
1473 Display *dpy = DEVICE_X_DISPLAY (d); | 1498 Display *dpy = DEVICE_X_DISPLAY (d); |
1474 return XGetSelectionOwner (dpy, symbol_to_x_atom (d, selection, 0)) != None ? | 1499 return XGetSelectionOwner (dpy, symbol_to_x_atom (d, selection, 0)) != None ? |
1475 Qt : Qnil; | 1500 Qt : Qnil; |
1765 DEVICE_XATOM_INCR (d) = XInternAtom (D, "INCR", False); | 1790 DEVICE_XATOM_INCR (d) = XInternAtom (D, "INCR", False); |
1766 DEVICE_XATOM_TARGETS (d) = XInternAtom (D, "TARGETS", False); | 1791 DEVICE_XATOM_TARGETS (d) = XInternAtom (D, "TARGETS", False); |
1767 DEVICE_XATOM_NULL (d) = XInternAtom (D, "NULL", False); | 1792 DEVICE_XATOM_NULL (d) = XInternAtom (D, "NULL", False); |
1768 DEVICE_XATOM_ATOM_PAIR (d) = XInternAtom (D, "ATOM_PAIR", False); | 1793 DEVICE_XATOM_ATOM_PAIR (d) = XInternAtom (D, "ATOM_PAIR", False); |
1769 DEVICE_XATOM_COMPOUND_TEXT (d) = XInternAtom (D, "COMPOUND_TEXT", False); | 1794 DEVICE_XATOM_COMPOUND_TEXT (d) = XInternAtom (D, "COMPOUND_TEXT", False); |
1795 | |
1796 /* #### I don't like the looks of this... what is it for? - ajh */ | |
1770 DEVICE_XATOM_EMACS_TMP (d) = XInternAtom (D, "_EMACS_TMP_", False); | 1797 DEVICE_XATOM_EMACS_TMP (d) = XInternAtom (D, "_EMACS_TMP_", False); |
1771 } | 1798 } |