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 }