emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master c3640fc: Support 'TARGETS' in clipboard selections


From: Eli Zaretskii
Subject: [Emacs-diffs] master c3640fc: Support 'TARGETS' in clipboard selections on MS-Windows
Date: Tue, 1 Nov 2016 16:05:23 +0000 (UTC)

branch: master
commit c3640fcc96ed80368209c73d7ac9a0f0d1833d93
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Support 'TARGETS' in clipboard selections on MS-Windows
    
    * src/w32select.c (Fw32_selection_targets): New function.
    
    * lisp/term/w32-win.el (w32--get-selection): Call
    'w32-selection-targets' to obtain the list of data formats
    available in the clipboard.
---
 lisp/term/w32-win.el |   14 ++++---
 src/w32select.c      |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+), 5 deletions(-)

diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el
index f705ec1..d8cf5ef 100644
--- a/lisp/term/w32-win.el
+++ b/lisp/term/w32-win.el
@@ -400,11 +400,15 @@ See the documentation of 
`create-fontset-from-fontset-spec' for the format.")
     (put 'x-selections (or type 'PRIMARY) value)))
 
 (defun w32--get-selection  (&optional type data-type)
-  (if (and (eq type 'CLIPBOARD)
-           (eq data-type 'STRING))
-      (with-demoted-errors "w32-get-clipboard-data:%S"
-        (w32-get-clipboard-data))
-    (get 'x-selections (or type 'PRIMARY))))
+  (cond ((and (eq type 'CLIPBOARD)
+              (eq data-type 'STRING))
+         (with-demoted-errors "w32-get-clipboard-data:%S"
+           (w32-get-clipboard-data)))
+        ((eq data-type 'TARGETS)
+         (if (eq type 'CLIPBOARD)
+             (w32-selection-targets type)
+           (if (get 'x-selections (or type 'PRIMARY)) '[STRING])))
+        (t (get 'x-selections (or type 'PRIMARY)))))
 
 (defun w32--selection-owner-p (selection)
   (and (memq selection '(nil PRIMARY SECONDARY))
diff --git a/src/w32select.c b/src/w32select.c
index a38a42c..1754534 100644
--- a/src/w32select.c
+++ b/src/w32select.c
@@ -1052,6 +1052,113 @@ frame's display, or the first available X display.  */)
   return Qnil;
 }
 
+/* Support enumerating available clipboard selection formats.  */
+
+DEFUN ("w32-selection-targets", Fw32_selection_targets, Sw32_selection_targets,
+       0, 2, 0,
+       doc: /* Return a vector of data formats available in the specified 
SELECTION.
+SELECTION should be the name of the selection in question, typically
+one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+The symbol nil is the same as `PRIMARY', and t is the same as `SECONDARY'.
+
+TERMINAL should be a terminal object or a frame specifying the X
+server to query.  If omitted or nil, that stands for the selected
+frame's display, or the first available X display.
+
+This function currently ignores TERMINAL, and only returns non-nil
+for `CLIPBOARD'.  The return value is a vector of symbols, each symbol
+representing a data format that is currently available in the clipboard.  */)
+  (Lisp_Object selection, Lisp_Object terminal)
+{
+  /* Xlib-like names for standard Windows clipboard data formats.
+     They are in upper-case to mimic xselect.c.  A couple of the names
+     were changed to be more like their X counterparts.  */
+  static const char *stdfmt_name[] = {
+    "UNDEFINED",
+    "STRING",
+    "BITMAP",
+    "METAFILE",
+    "SYMLINK",
+    "DIF",
+    "TIFF",
+    "OEM_STRING",
+    "DIB",
+    "PALETTE",
+    "PENDATA",
+    "RIFF",
+    "WAVE",
+    "UTF8_STRING",
+    "ENHMETAFILE",
+    "FILE_NAMES", /* DND */
+    "LOCALE", /* not used */
+    "DIBV5"
+  };
+  CHECK_SYMBOL (selection);
+
+  /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
+     if the clipboard currently has valid text format contents.  */
+
+  if (EQ (selection, QCLIPBOARD))
+    {
+      Lisp_Object val = Qnil;
+
+      setup_config ();
+
+      if (OpenClipboard (NULL))
+       {
+         UINT format = 0;
+
+         /* Count how many formats are available.  We ignore the
+            CF_LOCALE format, and don't put it into the vector we
+            return, because CF_LOCALE is automatically created by
+            Windows for any text in the clipboard, so its presence in
+            the value will simply confuse.  */
+         int fmtcount = 0;
+         while ((format = EnumClipboardFormats (format)))
+           if (format != CF_LOCALE)
+             fmtcount++;
+
+         if (fmtcount > 0)
+           {
+             int i;
+
+             /* We generate a vector because that's what xselect.c
+                does in this case.  */
+             val = Fmake_vector (make_number (fmtcount), Qnil);
+             /* Note: when stepping with GDB through this code, the
+                loop below terminates immediately because
+                EnumClipboardFormats for some reason returns with
+                "Thread does not have a clipboard open" error.  */
+             for (i = 0, format = 0;
+                  (format = EnumClipboardFormats (format)) != 0; )
+               {
+                 const char *name;
+
+                 if (format == CF_LOCALE)
+                   continue;
+                 else if (format < CF_MAX)
+                   name = stdfmt_name[format];
+                 else
+                   {
+                     char fmt_name[256];
+
+                     if (!GetClipboardFormatName (format, fmt_name,
+                                                  sizeof (fmt_name)))
+                       continue;
+                     name = fmt_name;
+                   }
+                 ASET (val, i, intern (name));
+                 i++;
+               }
+           }
+         CloseClipboard ();
+       }
+      return val;
+    }
+  /* For PRIMARY and SECONDARY we cons the values in w32--get-selection.  */
+  return Qnil;
+}
+
 /* One-time init.  Called in the un-dumped Emacs, but not in the
    dumped version.  */
 
@@ -1061,6 +1168,7 @@ syms_of_w32select (void)
   defsubr (&Sw32_set_clipboard_data);
   defsubr (&Sw32_get_clipboard_data);
   defsubr (&Sw32_selection_exists_p);
+  defsubr (&Sw32_selection_targets);
 
   DEFVAR_LISP ("selection-coding-system", Vselection_coding_system,
               doc: /* Coding system for communicating with other programs.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]