client/X11: transfer raw clipboard format data
The second step of raw transfer is to transfer the format data itself. This has been already implemented in XFreeRDP before, but several tweaks are required for it to work correctly. The idea of raw data transfer is to request for _FREERDP_RAW clipboard format while putting the actual formatId into _FREERDP_CLIPRDR property where the requested data is expected to arrive to. Then the clipboard owner will check for the real formatId and deliver the expected data. This stays true, but the check is performed in a more straightforward way, and CF_RAW format (numerically equal to zero) is not considered an unknown destination format when performing (identity) conversions with wClipboard. This is not an issue because wClipboard will allow only identity conversion for CF_RAW, it will fail if something else is going to be converted into CF_RAW.
This commit is contained in:
parent
391ed0d91d
commit
7bce7ef372
@ -79,6 +79,7 @@ struct xf_clipboard
|
|||||||
int requestedFormatId;
|
int requestedFormatId;
|
||||||
|
|
||||||
BYTE* data;
|
BYTE* data;
|
||||||
|
BOOL data_raw_format;
|
||||||
UINT32 data_format_id;
|
UINT32 data_format_id;
|
||||||
const char* data_format_name;
|
const char* data_format_name;
|
||||||
int data_length;
|
int data_length;
|
||||||
@ -554,6 +555,10 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
|
|||||||
|
|
||||||
switch (format->formatId)
|
switch (format->formatId)
|
||||||
{
|
{
|
||||||
|
case CF_RAW:
|
||||||
|
srcFormatId = CF_RAW;
|
||||||
|
break;
|
||||||
|
|
||||||
case CF_TEXT:
|
case CF_TEXT:
|
||||||
case CF_OEMTEXT:
|
case CF_OEMTEXT:
|
||||||
case CF_UNICODETEXT:
|
case CF_UNICODETEXT:
|
||||||
@ -593,7 +598,7 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
|
|||||||
dstFormatId = format->formatId;
|
dstFormatId = format->formatId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bSuccess && dstFormatId)
|
if (bSuccess)
|
||||||
{
|
{
|
||||||
DstSize = 0;
|
DstSize = 0;
|
||||||
pDstData = (BYTE*) ClipboardGetData(clipboard->system, dstFormatId, &DstSize);
|
pDstData = (BYTE*) ClipboardGetData(clipboard->system, dstFormatId, &DstSize);
|
||||||
@ -774,6 +779,7 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
|||||||
XEvent* respond;
|
XEvent* respond;
|
||||||
BYTE* data = NULL;
|
BYTE* data = NULL;
|
||||||
BOOL delayRespond;
|
BOOL delayRespond;
|
||||||
|
BOOL rawTransfer;
|
||||||
unsigned long length;
|
unsigned long length;
|
||||||
unsigned long bytes_left;
|
unsigned long bytes_left;
|
||||||
CLIPRDR_FORMAT* format;
|
CLIPRDR_FORMAT* format;
|
||||||
@ -816,6 +822,7 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
|||||||
{
|
{
|
||||||
formatId = format->formatId;
|
formatId = format->formatId;
|
||||||
formatName = format->formatName;
|
formatName = format->formatName;
|
||||||
|
rawTransfer = FALSE;
|
||||||
|
|
||||||
if (formatId == CF_RAW)
|
if (formatId == CF_RAW)
|
||||||
{
|
{
|
||||||
@ -828,6 +835,7 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
|||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
|
rawTransfer = TRUE;
|
||||||
CopyMemory(&formatId, data, 4);
|
CopyMemory(&formatId, data, 4);
|
||||||
XFree(data);
|
XFree(data);
|
||||||
}
|
}
|
||||||
@ -859,6 +867,7 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
|||||||
clipboard->respond = respond;
|
clipboard->respond = respond;
|
||||||
clipboard->data_format_id = formatId;
|
clipboard->data_format_id = formatId;
|
||||||
clipboard->data_format_name = formatName;
|
clipboard->data_format_name = formatName;
|
||||||
|
clipboard->data_raw_format = rawTransfer;
|
||||||
delayRespond = TRUE;
|
delayRespond = TRUE;
|
||||||
|
|
||||||
xf_cliprdr_send_data_request(clipboard, formatId);
|
xf_cliprdr_send_data_request(clipboard, formatId);
|
||||||
@ -1204,12 +1213,15 @@ static UINT xf_cliprdr_server_format_list_response(CliprdrClientContext* context
|
|||||||
*/
|
*/
|
||||||
static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
|
static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
|
||||||
{
|
{
|
||||||
|
BOOL rawTransfer;
|
||||||
xfCliprdrFormat* format = NULL;
|
xfCliprdrFormat* format = NULL;
|
||||||
UINT32 formatId = formatDataRequest->requestedFormatId;
|
UINT32 formatId = formatDataRequest->requestedFormatId;
|
||||||
xfClipboard* clipboard = (xfClipboard*) context->custom;
|
xfClipboard* clipboard = (xfClipboard*) context->custom;
|
||||||
xfContext* xfc = clipboard->xfc;
|
xfContext* xfc = clipboard->xfc;
|
||||||
|
|
||||||
if (xf_cliprdr_is_raw_transfer_available(clipboard))
|
rawTransfer = xf_cliprdr_is_raw_transfer_available(clipboard);
|
||||||
|
|
||||||
|
if (rawTransfer)
|
||||||
{
|
{
|
||||||
format = xf_cliprdr_get_client_format_by_id(clipboard, CF_RAW);
|
format = xf_cliprdr_get_client_format_by_id(clipboard, CF_RAW);
|
||||||
|
|
||||||
@ -1222,7 +1234,7 @@ static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context,
|
|||||||
if (!format)
|
if (!format)
|
||||||
return xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
return xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||||
|
|
||||||
clipboard->requestedFormatId = formatId;
|
clipboard->requestedFormatId = rawTransfer ? CF_RAW : formatId;
|
||||||
|
|
||||||
XConvertSelection(xfc->display, clipboard->clipboard_atom,
|
XConvertSelection(xfc->display, clipboard->clipboard_atom,
|
||||||
format->atom, clipboard->property_atom, xfc->drawable, CurrentTime);
|
format->atom, clipboard->property_atom, xfc->drawable, CurrentTime);
|
||||||
@ -1269,7 +1281,12 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context
|
|||||||
srcFormatId = 0;
|
srcFormatId = 0;
|
||||||
dstFormatId = 0;
|
dstFormatId = 0;
|
||||||
|
|
||||||
if (clipboard->data_format_name)
|
if (clipboard->data_raw_format)
|
||||||
|
{
|
||||||
|
srcFormatId = CF_RAW;
|
||||||
|
dstFormatId = CF_RAW;
|
||||||
|
}
|
||||||
|
else if (clipboard->data_format_name)
|
||||||
{
|
{
|
||||||
if (strcmp(clipboard->data_format_name, "HTML Format") == 0)
|
if (strcmp(clipboard->data_format_name, "HTML Format") == 0)
|
||||||
{
|
{
|
||||||
@ -1320,7 +1337,7 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context
|
|||||||
if (!bSuccess)
|
if (!bSuccess)
|
||||||
free (pSrcData);
|
free (pSrcData);
|
||||||
|
|
||||||
if (bSuccess && dstFormatId)
|
if (bSuccess)
|
||||||
{
|
{
|
||||||
DstSize = 0;
|
DstSize = 0;
|
||||||
pDstData = (BYTE*) ClipboardGetData(clipboard->system, dstFormatId, &DstSize);
|
pDstData = (BYTE*) ClipboardGetData(clipboard->system, dstFormatId, &DstSize);
|
||||||
|
Loading…
Reference in New Issue
Block a user