Alexandre Julliard : winex11: Reimplement targets enumeration using standard clipboard APIs.

Alexandre Julliard julliard at winehq.org
Wed Sep 21 10:14:50 CDT 2016


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Sep 21 12:10:32 2016 +0900

winex11: Reimplement targets enumeration using standard clipboard APIs.

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

---

 dlls/winex11.drv/clipboard.c | 147 ++++++++++++++++++++++++-------------------
 1 file changed, 82 insertions(+), 65 deletions(-)

diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 62171d2..f4c8866 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -2,10 +2,11 @@
  * X11 clipboard windows driver
  *
  * Copyright 1994 Martin Ayotte
- *	     1996 Alex Korobka
- *	     1999 Noel Borthwick
- *           2003 Ulrich Czekalla for CodeWeavers
- *           2014 Damjan Jovanovic
+ * Copyright 1996 Alex Korobka
+ * Copyright 1999 Noel Borthwick
+ * Copyright 2003 Ulrich Czekalla for CodeWeavers
+ * Copyright 2014 Damjan Jovanovic
+ * Copyright 2016 Alexandre Julliard
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -211,6 +212,7 @@ static const struct
 
 static struct list format_list = LIST_INIT( format_list );
 
+#define NB_BUILTIN_FORMATS (sizeof(builtin_formats) / sizeof(builtin_formats[0]))
 #define GET_ATOM(prop)  (((prop) < FIRST_XATOM) ? (Atom)(prop) : X11DRV_Atoms[(prop) - FIRST_XATOM])
 
 
@@ -306,13 +308,12 @@ static const char *debugstr_xatom( Atom atom )
  */
 void X11DRV_InitClipboard(void)
 {
-    static const unsigned int count = sizeof(builtin_formats) / sizeof(builtin_formats[0]);
     struct clipboard_format *formats;
     UINT i;
 
-    if (!(formats = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*formats)))) return;
+    if (!(formats = HeapAlloc( GetProcessHeap(), 0, NB_BUILTIN_FORMATS * sizeof(*formats)))) return;
 
-    for (i = 0; i < count; i++)
+    for (i = 0; i < NB_BUILTIN_FORMATS; i++)
     {
         if (builtin_formats[i].name)
             formats[i].id = RegisterClipboardFormatW( builtin_formats[i].name );
@@ -1660,6 +1661,80 @@ failed:
 }
 
 
+/***********************************************************************
+ *           get_clipboard_formats
+ *
+ * Return a list of all formats currently available on the Win32 clipboard.
+ * Helper for export_targets.
+ */
+static UINT *get_clipboard_formats( UINT *size )
+{
+    UINT *ids;
+
+    *size = 256;
+    for (;;)
+    {
+        if (!(ids = HeapAlloc( GetProcessHeap(), 0, *size * sizeof(*ids) ))) return NULL;
+        if (GetUpdatedClipboardFormats( ids, *size, size )) break;
+        HeapFree( GetProcessHeap(), 0, ids );
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return NULL;
+    }
+    return ids;
+}
+
+
+/***********************************************************************
+ *           is_format_available
+ *
+ * Check if a clipboard format is included in the list.
+ * Helper for export_targets.
+ */
+static BOOL is_format_available( UINT format, const UINT *ids, unsigned int count )
+{
+    while (count--) if (*ids++ == format) return TRUE;
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *           export_targets
+ *
+ *  Service a TARGETS selection request event
+ */
+static BOOL export_targets( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
+{
+    struct clipboard_format *format;
+    UINT pos, count, *formats;
+    Atom *targets;
+
+    intern_atoms();
+
+    if (!(formats = get_clipboard_formats( &count ))) return FALSE;
+
+    /* the builtin formats contain duplicates, so allocate some extra space */
+    if (!(targets = HeapAlloc( GetProcessHeap(), 0, (count + NB_BUILTIN_FORMATS) * sizeof(*targets) )))
+    {
+        HeapFree( GetProcessHeap(), 0, formats );
+        return FALSE;
+    }
+
+    pos = 0;
+    LIST_FOR_EACH_ENTRY( format, &format_list, struct clipboard_format, entry )
+    {
+        if (!format->export) continue;
+        /* formats with id==0 are always exported */
+        if (format->id && !is_format_available( format->id, formats, count )) continue;
+        TRACE( "%d: %s -> %s\n", pos, debugstr_format( format->id ), debugstr_xatom( format->atom ));
+        targets[pos++] = format->atom;
+    }
+
+    put_property( display, win, prop, XA_ATOM, 32, targets, pos );
+    HeapFree( GetProcessHeap(), 0, targets );
+    HeapFree( GetProcessHeap(), 0, formats );
+    return TRUE;
+}
+
+
 /**************************************************************************
  *      export_selection
  *
@@ -2485,64 +2560,6 @@ void X11DRV_ResetSelectionOwner(void)
 
 
 /***********************************************************************
- *           export_targets
- *
- *  Service a TARGETS selection request event
- */
-static BOOL export_targets( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
-{
-    UINT i;
-    Atom* targets;
-    ULONG cTargets;
-    LPWINE_CLIPFORMAT format;
-    LPWINE_CLIPDATA lpData;
-
-    /* Create X atoms for any clipboard types which don't have atoms yet.
-     * This avoids sending bogus zero atoms.
-     * Without this, copying might not have access to all clipboard types.
-     * FIXME: is it safe to call this here?
-     */
-    intern_atoms();
-
-    /*
-     * Count the number of items we wish to expose as selection targets.
-     */
-    cTargets = 1; /* Include TARGETS */
-
-    if (!list_head( &data_list )) return FALSE;
-
-    LIST_FOR_EACH_ENTRY( lpData, &data_list, WINE_CLIPDATA, entry )
-        LIST_FOR_EACH_ENTRY( format, &format_list, WINE_CLIPFORMAT, entry )
-            if (format->id == lpData->wFormatID && format->export && format->atom)
-                cTargets++;
-
-    TRACE(" found %d formats\n", cTargets);
-
-    /* Allocate temp buffer */
-    targets = HeapAlloc( GetProcessHeap(), 0, cTargets * sizeof(Atom));
-    if(targets == NULL)
-        return FALSE;
-
-    i = 0;
-    targets[i++] = x11drv_atom(TARGETS);
-
-    LIST_FOR_EACH_ENTRY( lpData, &data_list, WINE_CLIPDATA, entry )
-        LIST_FOR_EACH_ENTRY( format, &format_list, WINE_CLIPFORMAT, entry )
-            if (format->id == lpData->wFormatID && format->export && format->atom)
-            {
-                TRACE( "%d: %s -> %s\n", i, debugstr_format( format->id ),
-                       debugstr_xatom( format->atom ));
-                targets[i++] = format->atom;
-            }
-
-    put_property( display, win, prop, XA_ATOM, 32, targets, cTargets );
-
-    HeapFree(GetProcessHeap(), 0, targets);
-    return TRUE;
-}
-
-
-/***********************************************************************
  *           X11DRV_HandleSelectionRequest
  */
 BOOL X11DRV_SelectionRequest( HWND hwnd, XEvent *xev )




More information about the wine-cvs mailing list