diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index 0696e4ba2..b84668e49 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "xf_cliprdr.h" @@ -591,6 +592,10 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, size = strlen((char*) data) + 1; srcFormatId = ClipboardGetFormatId(clipboard->system, "text/html"); break; + + case CB_FORMAT_TEXTURILIST: + srcFormatId = ClipboardGetFormatId(clipboard->system, "text/uri-list"); + break; } SrcSize = (UINT32) size; @@ -613,6 +618,31 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, return; } + /* + * File lists require a bit of postprocessing to convert them from WinPR's FILDESCRIPTOR + * format to CLIPRDR_FILELIST expected by the server. + * + * We check for "FileGroupDescriptorW" format being registered (i.e., nonzero) in order + * to not process CF_RAW as a file list in case WinPR does not support file transfers. + */ + if (dstFormatId && + (dstFormatId == ClipboardGetFormatId(clipboard->system, "FileGroupDescriptorW"))) + { + UINT error = NO_ERROR; + FILEDESCRIPTOR* file_array = (FILEDESCRIPTOR*) pDstData; + UINT32 file_count = DstSize / sizeof(FILEDESCRIPTOR); + + pDstData = NULL; + DstSize = 0; + + error = cliprdr_serialize_file_list(file_array, file_count, &pDstData, &DstSize); + + if (error) + WLog_ERR(TAG, "failed to serialize CLIPRDR_FILELIST: 0x%08X", error); + + free(file_array); + } + xf_cliprdr_send_data_response(clipboard, pDstData, (int) DstSize); free(pDstData); } @@ -1491,6 +1521,22 @@ xfClipboard* xf_clipboard_new(xfContext* xfc) goto error; n++; + /* + * Existence of registered format IDs for file formats does not guarantee that they are + * in fact supported by wClipboard (as further initialization may have failed after format + * registration). However, they are definitely not supported if there are no registered + * formats. In this case we should not list file formats in TARGETS. + */ + if (ClipboardGetFormatId(clipboard->system, "text/uri-list")) + { + clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "text/uri-list", False); + clipboard->clientFormats[n].formatId = CB_FORMAT_TEXTURILIST; + clipboard->clientFormats[n].formatName = _strdup("FileGroupDescriptorW"); + if (!clipboard->clientFormats[n].formatName) + goto error; + n++; + } + clipboard->numClientFormats = n; clipboard->targets[0] = XInternAtom(xfc->display, "TIMESTAMP", FALSE); clipboard->targets[1] = XInternAtom(xfc->display, "TARGETS", FALSE); diff --git a/include/freerdp/channels/cliprdr.h b/include/freerdp/channels/cliprdr.h index 2f1d027a0..a9f772778 100644 --- a/include/freerdp/channels/cliprdr.h +++ b/include/freerdp/channels/cliprdr.h @@ -35,6 +35,7 @@ #define CB_FORMAT_PNG 0xD011 #define CB_FORMAT_JPEG 0xD012 #define CB_FORMAT_GIF 0xD013 +#define CB_FORMAT_TEXTURILIST 0xD014 /* CLIPRDR_HEADER.msgType */ #define CB_MONITOR_READY 0x0001