Alexandre Julliard : winex11: Add helper functions to find and register Win32 clipboard formats.

Alexandre Julliard julliard at winehq.org
Thu Sep 22 10:00:02 CDT 2016


Module: wine
Branch: master
Commit: f4f6353079fe16d164f207422573d3ef93f78177
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f4f6353079fe16d164f207422573d3ef93f78177

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Sep 22 13:13:25 2016 +0900

winex11: Add helper functions to find and register Win32 clipboard formats.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winex11.drv/clipboard.c | 76 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 72 insertions(+), 4 deletions(-)

diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index d7480ae..34ca1bd 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -304,6 +304,75 @@ static const char *debugstr_xatom( Atom atom )
     return ret;
 }
 
+
+/**************************************************************************
+ *		find_win32_format
+ */
+static struct clipboard_format *find_win32_format( UINT id )
+{
+    struct clipboard_format *format;
+
+    LIST_FOR_EACH_ENTRY( format, &format_list, struct clipboard_format, entry )
+        if (format->id == id) return format;
+    return NULL;
+}
+
+
+/**************************************************************************
+ *		register_formats
+ */
+static void register_formats( const UINT *ids, const Atom *atoms, unsigned int count )
+{
+    struct clipboard_format *formats;
+    unsigned int i;
+
+    if (!(formats = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*formats)))) return;
+
+    for (i = 0; i < count; i++)
+    {
+        formats[i].id     = ids[i];
+        formats[i].atom   = atoms[i];
+        formats[i].import = import_data;
+        formats[i].export = export_data;
+        list_add_tail( &format_list, &formats[i].entry );
+        TRACE( "registered %s atom %s\n", debugstr_format( ids[i] ), debugstr_xatom( atoms[i] ));
+    }
+}
+
+
+/**************************************************************************
+ *		register_win32_formats
+ *
+ * Register Win32 clipboard formats the first time we encounter them.
+ */
+static void register_win32_formats( const UINT *ids, UINT size )
+{
+    unsigned int count, len;
+    UINT new_ids[256];
+    char *names[256];
+    Atom atoms[256];
+    WCHAR buffer[256];
+
+    while (size)
+    {
+        for (count = 0; count < 256 && size; ids++, size--)
+        {
+            if (find_win32_format( *ids )) continue;  /* it already exists */
+            if (!GetClipboardFormatNameW( *ids, buffer, 256 )) continue;  /* not a named format */
+            if (!(len = WideCharToMultiByte( CP_UNIXCP, 0, buffer, -1, NULL, 0, NULL, NULL ))) continue;
+            if (!(names[count] = HeapAlloc( GetProcessHeap(), 0, len ))) continue;
+            WideCharToMultiByte( CP_UNIXCP, 0, buffer, -1, names[count], len, NULL, NULL );
+            new_ids[count++] = *ids;
+        }
+        if (!count) return;
+
+        XInternAtoms( thread_display(), names, count, False, atoms );
+        register_formats( new_ids, atoms, count );
+        while (count) HeapFree( GetProcessHeap(), 0, names[--count] );
+    }
+}
+
+
 /**************************************************************************
  *		X11DRV_InitClipboard
  */
@@ -394,11 +463,9 @@ static void intern_atoms(void)
  */
 static struct clipboard_format *register_format( UINT id, Atom prop )
 {
-    struct clipboard_format *format;
+    struct clipboard_format *format = find_win32_format( id );
 
-    /* walk format chain to see if it's already registered */
-    LIST_FOR_EACH_ENTRY( format, &format_list, struct clipboard_format, entry )
-        if (format->id == id) return format;
+    if (format) return format;
 
     if (!(format = HeapAlloc( GetProcessHeap(), 0, sizeof(*format) ))) return NULL;
     format->id     = id;
@@ -1688,6 +1755,7 @@ static UINT *get_clipboard_formats( UINT *size )
         HeapFree( GetProcessHeap(), 0, ids );
         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return NULL;
     }
+    register_win32_formats( ids, *size );
     return ids;
 }
 




More information about the wine-cvs mailing list