changeset 33697:e7765cb122c3

(Fw32_set_clipboard_data): Save a copy of what is put on the clipboard. (Fw32_get_clipboard_data): Compare data on clipboard with saved copy of what Emacs last put there. If they are the same, do not use the clipboard copy to avoid losing data due to coding conversions.
author Jason Rumney <jasonr@gnu.org>
date Tue, 21 Nov 2000 19:18:13 +0000
parents 22ead1a1c750
children 6864fead9622
files src/w32select.c
diffstat 1 files changed, 44 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/w32select.c	Tue Nov 21 19:16:16 2000 +0000
+++ b/src/w32select.c	Tue Nov 21 19:18:13 2000 +0000
@@ -37,9 +37,18 @@
    clipboard.  */
 static Lisp_Object Vselection_coding_system;
 
-/* Coding system for the next communicating with other X clients.  */
+/* Coding system for the next communicating with other Windows programs.  */
 static Lisp_Object Vnext_selection_coding_system;
 
+/* The last text we put into the clipboard.  This is used to prevent
+   passing back our own text from the clipboard, instead of using the
+   kill ring.  The former is undesirable because the clipboard data
+   could be MULEtilated by inappropriately chosen
+   (next-)selection-coding-system.  For this reason, we must store the
+   text *after* it was encoded/Unix-to-DOS-converted.  */
+static unsigned char *last_clipboard_text = NULL;
+static size_t clipboard_storage_size = 0;
+
 #if 0
 DEFUN ("w32-open-clipboard", Fw32_open_clipboard, Sw32_open_clipboard, 0, 1, 0,
        "This opens the clipboard with the given frame pointer.")
@@ -174,10 +183,8 @@
       }
     else
       {
-	/* We must encode contents of OBJ to compound text format.
-	   The format is compatible with what the target `STRING'
-	   expects if OBJ contains only ASCII and Latin-1
-	   characters.  */
+	/* We must encode contents of OBJ to the selection coding
+           system. */
 	int bufsize;
 	struct coding_system coding;
 	HANDLE htext2;
@@ -197,16 +204,31 @@
 	  goto error;
 	encode_coding (&coding, src, dst, nbytes, bufsize);
 	Vlast_coding_system_used = coding.symbol;
+
+        /* Stash away the data we are about to put into the clipboard, so we
+           could later check inside Fw32_get_clipboard_data whether
+           the clipboard still holds our data.  */
+        if (clipboard_storage_size < coding.produced)
+          {
+            clipboard_storage_size = coding.produced + 100;
+            last_clipboard_text = (char *) xrealloc (last_clipboard_text,
+                                                     clipboard_storage_size);
+          }
+        if (last_clipboard_text)
+          memcpy (last_clipboard_text, dst, coding.produced);
+
 	GlobalUnlock (htext);
+
 	/* Shrink data block to actual size.  */
-	htext2 = GlobalReAlloc (htext, coding.produced, GMEM_MOVEABLE | GMEM_DDESHARE);
+	htext2 = GlobalReAlloc (htext, coding.produced,
+                                GMEM_MOVEABLE | GMEM_DDESHARE);
 	if (htext2 != NULL) htext = htext2;
       }
   }
   
   if (!OpenClipboard ((!NILP (frame) && FRAME_W32_P (XFRAME (frame))) ? FRAME_W32_WINDOW (XFRAME (frame)) : NULL))
     goto error;
-  
+
   ok = EmptyClipboard () && SetClipboardData (CF_TEXT, htext);
   
   CloseClipboard ();
@@ -217,7 +239,9 @@
   
   ok = FALSE;
   if (htext) GlobalFree (htext);
-  
+  if (last_clipboard_text)
+    *last_clipboard_text = '\0';
+
  done:
   UNBLOCK_INPUT;
   
@@ -255,6 +279,16 @@
     
     nbytes = strlen (src);
 
+    /* If the text in clipboard is identical to what we put there
+       last time w32_set_clipboard_data was called, pretend there's no
+       data in the clipboard.  This is so we don't pass our own text
+       from the clipboard (which might be troublesome if the killed
+       text includes null characters).  */
+    if (last_clipboard_text
+        && clipboard_storage_size >= nbytes
+        && memcmp(last_clipboard_text, src, nbytes) == 0)
+      goto closeclip;
+
     if (
 #if 1
 	1
@@ -295,8 +329,8 @@
 	buf = (unsigned char *) xmalloc (bufsize);
 	decode_coding (&coding, src, buf, nbytes, bufsize);
 	Vlast_coding_system_used = coding.symbol;
-	ret = make_string_from_bytes ((char *) buf,
-				      coding.produced_char, coding.produced);
+        ret = make_string_from_bytes ((char *) buf,
+                                      coding.produced_char, coding.produced);
 	xfree (buf);
       }
     else