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