mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
x11/cliprdr: handle text/uri-list format
To handle a new format we should first be able to transform the format name from the local clipboard owner into its remote representation. In our case this will be trasforming the "text/uri-list" target into the "FileGroupDescriptorW" named format. Add CB_FORMAT_TEXTURILIST to identify the local format by its ID during the data conversion step. This numeric ID has nothing to do with the ID which will be sent to server. It's a bit weird, but that's how XFreeRDP works. After that add a new client format with this ID and appropriate local and remote format names (in atom and formatName fields respectively). Do this only if wClipboard actually supports "text/uri-list" format. (It could fail to initialize the local file subsystem, in which case it will fail all file-related requests and there would be no point in advertising the file format support in the first place.) Finally, handle the actual format data request for a new named format in xf_cliprdr_process_requested_data(). Remember to convert the FILEDESCRIPTOR array we receive from wClipboard into the CLIPRDR_FILELIST expected by the server. Also take care to not leak memory during this conversion. Note that this handles only the CLIPRDR_FORMAT_DATA_REQUEST. The server is still not able to retrieve the file content as this is done via a separate request-reply sequence.
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/client/cliprdr.h>
|
||||
#include <freerdp/channels/channels.h>
|
||||
#include <freerdp/channels/cliprdr.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user