Damjan Jovanovic : winex11.drv: Allow the clipboard to copy files to other X11 apps.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Jul 18 14:20:23 CDT 2014


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

Author: Damjan Jovanovic <damjan.jov at gmail.com>
Date:   Thu Jul 17 20:14:35 2014 +0200

winex11.drv: Allow the clipboard to copy files to other X11 apps.

---

 dlls/winex11.drv/clipboard.c | 93 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 91 insertions(+), 2 deletions(-)

diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 727a2a4..b2705b4 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -163,6 +163,8 @@ static HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(Display *display, Window reques
     Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
 static HANDLE X11DRV_CLIPBOARD_ExportTextHtml(Display *display, Window requestor, Atom aTarget,
     Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
+static HANDLE X11DRV_CLIPBOARD_ExportHDROP(Display *display, Window requestor, Atom aTarget,
+    Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
 static WINE_CLIPFORMAT *X11DRV_CLIPBOARD_InsertClipboardFormat(UINT id, Atom prop);
 static BOOL X11DRV_CLIPBOARD_RenderSynthesizedText(Display *display, UINT wFormatID);
 static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData);
@@ -207,8 +209,7 @@ static const struct
     /* If UTF8_STRING is not available, attempt COMPOUND_TEXT */
     { CF_UNICODETEXT, XATOM_COMPOUND_TEXT, X11DRV_CLIPBOARD_ImportCompoundText, X11DRV_CLIPBOARD_ExportString },
     { CF_ENHMETAFILE, XATOM_WCF_ENHMETAFILE, X11DRV_CLIPBOARD_ImportEnhMetaFile, X11DRV_CLIPBOARD_ExportEnhMetaFile },
-    { CF_HDROP, XATOM_WCF_HDROP, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
-    { CF_HDROP, XATOM_text_uri_list, X11DRV_CLIPBOARD_ImportTextUriList, X11DRV_CLIPBOARD_ExportClipboardData },
+    { CF_HDROP, XATOM_text_uri_list, X11DRV_CLIPBOARD_ImportTextUriList, X11DRV_CLIPBOARD_ExportHDROP },
     { CF_LOCALE, XATOM_WCF_LOCALE, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_DIBV5, XATOM_WCF_DIBV5, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
     { CF_OWNERDISPLAY, XATOM_WCF_OWNERDISPLAY, X11DRV_CLIPBOARD_ImportClipboardData, X11DRV_CLIPBOARD_ExportClipboardData },
@@ -2179,6 +2180,94 @@ end:
 
 
 /**************************************************************************
+ *      X11DRV_CLIPBOARD_ExportHDROP
+ *
+ *  Export CF_HDROP format to text/uri-list.
+ */
+static HANDLE X11DRV_CLIPBOARD_ExportHDROP(Display *display, Window requestor, Atom aTarget,
+    Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
+{
+    HDROP hDrop;
+    UINT i;
+    UINT numFiles;
+    HGLOBAL hClipData = NULL;
+    char *textUriList = NULL;
+    UINT textUriListSize = 32;
+    UINT next = 0;
+
+    *lpBytes = 0;
+
+    if (!X11DRV_CLIPBOARD_RenderFormat(display, lpdata))
+    {
+        ERR("Failed to export %04x format\n", lpdata->wFormatID);
+        return 0;
+    }
+    hClipData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, textUriListSize);
+    if (hClipData == NULL)
+        return 0;
+    hDrop = (HDROP) lpdata->hData;
+    numFiles = DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
+    for (i = 0; i < numFiles; i++)
+    {
+        UINT dosFilenameSize;
+        WCHAR *dosFilename = NULL;
+        char *unixFilename = NULL;
+        UINT uriSize;
+        UINT u;
+
+        dosFilenameSize = 1 + DragQueryFileW(hDrop, i, NULL, 0);
+        dosFilename = HeapAlloc(GetProcessHeap(), 0, dosFilenameSize*sizeof(WCHAR));
+        if (dosFilename == NULL) goto failed;
+        DragQueryFileW(hDrop, i, dosFilename, dosFilenameSize);
+        unixFilename = wine_get_unix_file_name(dosFilename);
+        HeapFree(GetProcessHeap(), 0, dosFilename);
+        if (unixFilename == NULL) goto failed;
+        uriSize = 8 + /* file:/// */
+                3 * (lstrlenA(unixFilename) - 1) + /* "%xy" per char except first '/' */
+                2; /* \r\n */
+        if ((next + uriSize) > textUriListSize)
+        {
+            UINT biggerSize = max( 2 * textUriListSize, next + uriSize );
+            HGLOBAL bigger = GlobalReAlloc(hClipData, biggerSize, 0);
+            if (bigger)
+            {
+                hClipData = bigger;
+                textUriListSize = biggerSize;
+            }
+            else
+            {
+                HeapFree(GetProcessHeap(), 0, unixFilename);
+                goto failed;
+            }
+        }
+        textUriList = GlobalLock(hClipData);
+        lstrcpyA(&textUriList[next], "file:///");
+        next += 8;
+        /* URL encode everything - unnecessary, but easier/lighter than linking in shlwapi, and can't hurt */
+        for (u = 1; unixFilename[u]; u++)
+        {
+            static const char hex_table[] = "0123456789abcdef";
+            textUriList[next++] = '%';
+            textUriList[next++] = hex_table[unixFilename[u] >> 4];
+            textUriList[next++] = hex_table[unixFilename[u] & 0xf];
+        }
+        textUriList[next++] = '\r';
+        textUriList[next++] = '\n';
+        GlobalUnlock(hClipData);
+        HeapFree(GetProcessHeap(), 0, unixFilename);
+    }
+
+    *lpBytes = next;
+    return hClipData;
+
+failed:
+    GlobalFree(hClipData);
+    *lpBytes = 0;
+    return 0;
+}
+
+
+/**************************************************************************
  *		X11DRV_CLIPBOARD_QueryTargets
  */
 static BOOL X11DRV_CLIPBOARD_QueryTargets(Display *display, Window w, Atom selection,




More information about the wine-cvs mailing list