diff 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
line wrap: on
line diff
--- a/src/select-x.c	Mon Aug 13 11:18:12 2007 +0200
+++ b/src/select-x.c	Mon Aug 13 11:19:21 2007 +0200
@@ -200,11 +200,10 @@
 
 
 /* Do protocol to assert ourself as a selection owner.
-   Update the Vselection_alist so that we can reply to later requests for
-   our selection.
  */
 static Lisp_Object
-x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value)
+x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
+		 Lisp_Object how_to_add, Lisp_Object selection_type)
 {
   struct device *d = decode_x_device (Qnil);
   Display *display = DEVICE_X_DISPLAY (d);
@@ -252,7 +251,7 @@
 				Lisp_Object selection_value,
 				Time thyme,
 				Display *display,
-                                                Window selecting_window)
+				Window selecting_window)
      /*				Bool owned_p)*/
 {
   struct device *d = get_device_from_display (display);
@@ -375,10 +374,34 @@
       {
 	Display *dpy = XtDisplay (widget);
 	Window window = (Window) *private_id;
-	Lisp_Object selection = assq_no_quit (QCLIPBOARD, Vselection_alist);
-	if (NILP (selection)) abort ();
-	selection = XCDR (selection);
-	if (!STRINGP (selection)) abort ();
+	Lisp_Object selection = select_convert_out (QCLIPBOARD, Qnil, Qnil);
+
+	/* Whichever lazy git wrote this originally just called abort()
+	   when anything didn't go their way... */
+	
+	/* Try some other text types */
+	if (NILP (selection))
+	  selection = select_convert_out (QCLIPBOARD, QSTRING, Qnil);
+	if (NILP (selection))
+	  selection = select_convert_out (QCLIPBOARD, QTEXT, Qnil);
+	if (NILP (selection))
+	  selection = select_convert_out (QCLIPBOARD, QCOMPOUND_TEXT, Qnil);
+	
+	if (CONSP (selection) && SYMBOLP (XCAR (selection))
+	    && (EQ (XCAR (selection), QSTRING)
+		|| EQ (XCAR (selection), QTEXT)
+		|| EQ (XCAR (selection), QCOMPOUND_TEXT)))
+	  selection = XCDR (selection);
+
+	if (NILP (selection))
+	  signal_error (Qselection_conversion_error,
+			build_string ("no selection"));
+
+	if (!STRINGP (selection))
+	  signal_error (Qselection_conversion_error,
+			build_string ("couldn't convert selection to string"));
+			       
+	
 	XmClipboardCopyByName (dpy, window, *data_id,
 			       (char *) XSTRING_DATA (selection),
 			       XSTRING_LENGTH (selection) + 1,
@@ -546,8 +569,8 @@
 x_handle_selection_request (XSelectionRequestEvent *event)
 {
   /* This function can GC */
-  struct gcpro gcpro1, gcpro2, gcpro3;
-  Lisp_Object local_selection_data = Qnil;
+  struct gcpro gcpro1, gcpro2;
+  Lisp_Object temp_obj;
   Lisp_Object selection_symbol;
   Lisp_Object target_symbol = Qnil;
   Lisp_Object converted_selection = Qnil;
@@ -556,33 +579,28 @@
   int count;
   struct device *d = get_device_from_display (event->display);
 
-  GCPRO3 (local_selection_data, converted_selection, target_symbol);
+  GCPRO2 (converted_selection, target_symbol);
 
   selection_symbol = x_atom_to_symbol (d, event->selection);
-
-  local_selection_data = assq_no_quit (selection_symbol, Vselection_alist);
+  target_symbol = x_atom_to_symbol (d, event->target);
 
-#if 0
-  /* This list isn't user-visible, so it can't "go bad." */
-  assert (CONSP (local_selection_data));
-  assert (CONSP (XCDR (local_selection_data)));
-  assert (CONSP (XCDR (XCDR (local_selection_data))));
-  assert (NILP  (XCDR (XCDR (XCDR (local_selection_data)))));
-  assert (CONSP (XCAR (XCDR (XCDR (local_selection_data)))));
-  assert (INTP  (XCAR (XCAR (XCDR (XCDR (local_selection_data))))));
-  assert (INTP  (XCDR (XCAR (XCDR (XCDR (local_selection_data))))));
+#if 0 /* #### MULTIPLE doesn't work yet */
+  if (EQ (target_symbol, QMULTIPLE))
+    target_symbol = fetch_multiple_target (event);
 #endif
 
-  if (NILP (local_selection_data))
+  temp_obj = Fget_selection_timestamp (selection_symbol);
+
+  if (NILP (temp_obj))
     {
-      /* Someone asked for the selection, but we don't have it any more. */
+      /* We don't appear to have the selection. */
       x_decline_selection_request (event);
+
       goto DONE_LABEL;
     }
 
-  local_selection_time =
-    * (Time *) XOPAQUE_DATA (XCAR (XCDR (XCDR (local_selection_data))));
-
+  local_selection_time = * (Time *) XOPAQUE_DATA (temp_obj);
+  
   if (event->time != CurrentTime &&
       local_selection_time > event->time)
     {
@@ -592,35 +610,36 @@
       goto DONE_LABEL;
     }
 
+  converted_selection = select_convert_out (selection_symbol,
+					    target_symbol, Qnil);
+
+  /* #### Is this the right thing to do? I'm no X expert. -- ajh */
+  if (NILP (converted_selection))
+    {
+      /* We don't appear to have a selection in that data type. */
+      x_decline_selection_request (event);
+      goto DONE_LABEL;
+    }
+
   count = specpdl_depth ();
   record_unwind_protect (x_selection_request_lisp_error,
 			 make_opaque_ptr (event));
-  target_symbol = x_atom_to_symbol (d, event->target);
 
-#if 0 /* #### MULTIPLE doesn't work yet */
-  if (EQ (target_symbol, QMULTIPLE))
-    target_symbol = fetch_multiple_target (event);
-#endif
-
-  /* Convert lisp objects back into binary data */
-
-  converted_selection =
-    get_local_selection (selection_symbol, target_symbol);
-
-  if (! NILP (converted_selection))
-    {
-      unsigned char *data;
-      unsigned int size;
-      int format;
-      Atom type;
-      lisp_data_to_selection_data (d, converted_selection,
-				   &data, &type, &size, &format);
-
-      x_reply_selection_request (event, format, data, size, type);
-      successful_p = Qt;
-      /* Tell x_selection_request_lisp_error() it's cool. */      event->type = 0;
-      xfree (data);
-    }
+  {
+    unsigned char *data;
+    unsigned int size;
+    int format;
+    Atom type;
+    lisp_data_to_selection_data (d, converted_selection,
+				 &data, &type, &size, &format);
+    
+    x_reply_selection_request (event, format, data, size, type);
+    successful_p = Qt;
+    /* Tell x_selection_request_lisp_error() it's cool. */
+    event->type = 0;
+    xfree (data);
+  }
+  
   unbind_to (count, Qnil);
 
  DONE_LABEL:
@@ -629,17 +648,15 @@
 
   /* Let random lisp code notice that the selection has been asked for. */
   {
-    Lisp_Object rest;
     Lisp_Object val = Vx_sent_selection_hooks;
     if (!UNBOUNDP (val) && !NILP (val))
       {
+	Lisp_Object rest;
 	if (CONSP (val) && !EQ (XCAR (val), Qlambda))
 	  for (rest = val; !NILP (rest); rest = Fcdr (rest))
-	    call3 (Fcar(rest), selection_symbol, target_symbol,
-		   successful_p);
+	    call3 (Fcar (rest), selection_symbol, target_symbol, successful_p);
 	else
-	  call3 (val, selection_symbol, target_symbol,
-		 successful_p);
+	  call3 (val, selection_symbol, target_symbol, successful_p);
       }
   }
 }
@@ -655,18 +672,18 @@
   Atom selection = event->selection;
   Time changed_owner_time = event->time;
 
-  Lisp_Object selection_symbol, local_selection_data;
+  Lisp_Object selection_symbol, local_selection_time_lisp;
   Time local_selection_time;
 
   selection_symbol = x_atom_to_symbol (d, selection);
 
-  local_selection_data = assq_no_quit (selection_symbol, Vselection_alist);
+  local_selection_time_lisp = Fget_selection_timestamp (selection_symbol);
 
-  /* Well, we already believe that we don't own it, so that's just fine. */
-  if (NILP (local_selection_data)) return;
-
-  local_selection_time =
-    * (Time *) XOPAQUE_DATA (XCAR (XCDR (XCDR (local_selection_data))));
+  /* We don't own the selection, so that's fine. */
+  if (NILP (local_selection_time_lisp))
+    return;
+  
+  local_selection_time = * (Time *) XOPAQUE_DATA (local_selection_time_lisp);
 
   /* This SelectionClear is for a selection that we no longer own, so we can
      disregard it.  (That is, we have reasserted the selection since this
@@ -920,10 +937,14 @@
   unbind_to (speccount, Qnil);
 
   /* otherwise, the selection is waiting for us on the requested property. */
-  return
-    x_get_window_property_as_lisp_data (display, requestor_window,
-					target_property, target_type,
-					selection_atom);
+
+  return select_convert_in (selection_symbol,
+			    target_type,
+			    x_get_window_property_as_lisp_data(display,
+							       requestor_window,
+							       target_property,
+							       target_type,
+							       selection_atom));
 }
 
 
@@ -1123,6 +1144,9 @@
   return val;
 }
 
+/* #### These are going to move into Lisp code(!) with the aid of
+        some new functions I'm working on - ajh */
+
 /* These functions convert from the selection data read from the server into
    something that we can use from elisp, and vice versa.
 
@@ -1467,7 +1491,8 @@
 }
 
 static Lisp_Object
-x_selection_exists_p (Lisp_Object selection)
+x_selection_exists_p (Lisp_Object selection,
+		      Lisp_Object selection_type)
 {
   struct device *d = decode_x_device (Qnil);
   Display *dpy = DEVICE_X_DISPLAY (d);
@@ -1767,5 +1792,7 @@
   DEVICE_XATOM_NULL          (d) = XInternAtom (D, "NULL",          False);
   DEVICE_XATOM_ATOM_PAIR     (d) = XInternAtom (D, "ATOM_PAIR",     False);
   DEVICE_XATOM_COMPOUND_TEXT (d) = XInternAtom (D, "COMPOUND_TEXT", False);
+
+  /* #### I don't like the looks of this... what is it for? - ajh */
   DEVICE_XATOM_EMACS_TMP     (d) = XInternAtom (D, "_EMACS_TMP_",   False);
 }