mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
xfreerdp: fix clipboard sync
This commit is contained in:
@@ -214,6 +214,8 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data
|
||||
{
|
||||
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatList");
|
||||
|
||||
if (context->custom)
|
||||
{
|
||||
UINT32 index;
|
||||
@@ -376,6 +378,8 @@ void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UI
|
||||
{
|
||||
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatListResponse");
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/hh872154.aspx */
|
||||
|
||||
if (context->custom)
|
||||
@@ -406,6 +410,8 @@ void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UIN
|
||||
{
|
||||
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatDataRequest");
|
||||
|
||||
if (context->custom)
|
||||
{
|
||||
CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;
|
||||
@@ -465,6 +471,8 @@ void cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UI
|
||||
{
|
||||
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatDataResponse");
|
||||
|
||||
if (context->custom)
|
||||
{
|
||||
CLIPRDR_FORMAT_DATA_RESPONSE formatDataResponse;
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "cliprdr_main.h"
|
||||
#include "cliprdr_format.h"
|
||||
|
||||
#ifdef WITH_DEBUG_CLIPRDR
|
||||
static const char* const CB_MSG_TYPE_STRINGS[] =
|
||||
{
|
||||
"",
|
||||
@@ -52,7 +51,6 @@ static const char* const CB_MSG_TYPE_STRINGS[] =
|
||||
"CB_LOCK_CLIPDATA"
|
||||
"CB_UNLOCK_CLIPDATA"
|
||||
};
|
||||
#endif
|
||||
|
||||
CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr)
|
||||
{
|
||||
@@ -171,7 +169,8 @@ static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16
|
||||
UINT16 capabilitySetType;
|
||||
Stream_Read_UINT16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */
|
||||
Stream_Seek_UINT16(s); /* pad1 (2 bytes) */
|
||||
DEBUG_CLIPRDR("cCapabilitiesSets %d", cCapabilitiesSets);
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerCapabilities");
|
||||
|
||||
for (i = 0; i < cCapabilitiesSets; i++)
|
||||
{
|
||||
@@ -215,6 +214,8 @@ static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI
|
||||
{
|
||||
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "MonitorReady");
|
||||
|
||||
if (context->custom)
|
||||
{
|
||||
CLIPRDR_MONITOR_READY monitorReady;
|
||||
@@ -240,8 +241,12 @@ static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, wStream* s, UI
|
||||
static void cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
|
||||
{
|
||||
RDP_CB_FILECONTENTS_REQUEST_EVENT* cb_event;
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsRequest");
|
||||
|
||||
cb_event = (RDP_CB_FILECONTENTS_REQUEST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||
CliprdrChannel_FilecontentsRequest, NULL, NULL);
|
||||
|
||||
Stream_Read_UINT32(s, cb_event->streamId);
|
||||
Stream_Read_UINT32(s, cb_event->lindex);
|
||||
Stream_Read_UINT32(s, cb_event->dwFlags);
|
||||
@@ -255,8 +260,12 @@ static void cliprdr_process_filecontents_request(cliprdrPlugin* cliprdr, wStream
|
||||
static void cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
|
||||
{
|
||||
RDP_CB_FILECONTENTS_RESPONSE_EVENT* cb_event;
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "FileContentsResponse");
|
||||
|
||||
cb_event = (RDP_CB_FILECONTENTS_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||
CliprdrChannel_FilecontentsResponse, NULL, NULL);
|
||||
|
||||
Stream_Read_UINT32(s, cb_event->streamId);
|
||||
|
||||
if (length > 0)
|
||||
@@ -272,18 +281,28 @@ static void cliprdr_process_filecontents_response(cliprdrPlugin* cliprdr, wStrea
|
||||
static void cliprdr_process_lock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
|
||||
{
|
||||
RDP_CB_LOCK_CLIPDATA_EVENT* cb_event;
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "LockClipData");
|
||||
|
||||
cb_event = (RDP_CB_LOCK_CLIPDATA_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||
CliprdrChannel_LockClipdata, NULL, NULL);
|
||||
|
||||
Stream_Read_UINT32(s, cb_event->clipDataId);
|
||||
|
||||
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
|
||||
}
|
||||
|
||||
static void cliprdr_process_unlock_clipdata(cliprdrPlugin* cliprdr, wStream* s, UINT32 length, UINT16 flags)
|
||||
{
|
||||
RDP_CB_UNLOCK_CLIPDATA_EVENT* cb_event;
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "UnlockClipData");
|
||||
|
||||
cb_event = (RDP_CB_UNLOCK_CLIPDATA_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||
CliprdrChannel_UnLockClipdata, NULL, NULL);
|
||||
|
||||
Stream_Read_UINT32(s, cb_event->clipDataId);
|
||||
|
||||
svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event);
|
||||
}
|
||||
|
||||
@@ -296,6 +315,7 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s)
|
||||
Stream_Read_UINT16(s, msgType);
|
||||
Stream_Read_UINT16(s, msgFlags);
|
||||
Stream_Read_UINT32(s, dataLen);
|
||||
|
||||
DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d",
|
||||
CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen);
|
||||
#ifdef WITH_DEBUG_CLIPRDR
|
||||
@@ -452,15 +472,21 @@ int cliprdr_client_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILIT
|
||||
wStream* s;
|
||||
CLIPRDR_GENERAL_CAPABILITY_SET* generalCapabilitySet;
|
||||
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
|
||||
|
||||
s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN);
|
||||
|
||||
Stream_Write_UINT16(s, 1); /* cCapabilitiesSets */
|
||||
Stream_Write_UINT16(s, 0); /* pad1 */
|
||||
|
||||
generalCapabilitySet = (CLIPRDR_GENERAL_CAPABILITY_SET*) capabilities->capabilitySets;
|
||||
Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetType); /* capabilitySetType */
|
||||
Stream_Write_UINT16(s, generalCapabilitySet->capabilitySetLength); /* lengthCapability */
|
||||
Stream_Write_UINT32(s, generalCapabilitySet->version); /* version */
|
||||
Stream_Write_UINT32(s, generalCapabilitySet->generalFlags); /* generalFlags */
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientCapabilities");
|
||||
cliprdr_packet_send(cliprdr, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -499,7 +525,7 @@ int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIS
|
||||
lpWideCharStr = (LPWSTR) Stream_Pointer(s);
|
||||
cchWideChar = (Stream_Capacity(s) - Stream_GetPosition(s)) / 2;
|
||||
formatNameSize = MultiByteToWideChar(CP_UTF8, 0,
|
||||
format->formatName, -1, lpWideCharStr, cchWideChar) * 2;
|
||||
format->formatName, -1, lpWideCharStr, cchWideChar) * 2;
|
||||
Stream_Seek(s, formatNameSize);
|
||||
}
|
||||
else
|
||||
@@ -508,7 +534,10 @@ int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIS
|
||||
}
|
||||
}
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatList: numFormats: %d",
|
||||
formatList->cFormats);
|
||||
cliprdr_packet_send(cliprdr, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -516,10 +545,15 @@ int cliprdr_client_format_list_response(CliprdrClientContext* context, CLIPRDR_F
|
||||
{
|
||||
wStream* s;
|
||||
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
|
||||
|
||||
formatListResponse->msgType = CB_FORMAT_LIST_RESPONSE;
|
||||
formatListResponse->dataLen = 0;
|
||||
|
||||
s = cliprdr_packet_new(formatListResponse->msgType, formatListResponse->msgFlags, formatListResponse->dataLen);
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatListResponse");
|
||||
cliprdr_packet_send(cliprdr, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -527,12 +561,17 @@ int cliprdr_client_format_data_request(CliprdrClientContext* context, CLIPRDR_FO
|
||||
{
|
||||
wStream* s;
|
||||
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
|
||||
|
||||
formatDataRequest->msgType = CB_FORMAT_DATA_REQUEST;
|
||||
formatDataRequest->msgFlags = 0;
|
||||
formatDataRequest->dataLen = 4;
|
||||
|
||||
s = cliprdr_packet_new(formatDataRequest->msgType, formatDataRequest->msgFlags, formatDataRequest->dataLen);
|
||||
Stream_Write_UINT32(s, formatDataRequest->requestedFormatId); /* requestedFormatId (4 bytes) */
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatDataRequest");
|
||||
cliprdr_packet_send(cliprdr, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -540,10 +579,16 @@ int cliprdr_client_format_data_response(CliprdrClientContext* context, CLIPRDR_F
|
||||
{
|
||||
wStream* s;
|
||||
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
|
||||
|
||||
formatDataResponse->msgType = CB_FORMAT_DATA_RESPONSE;
|
||||
|
||||
s = cliprdr_packet_new(formatDataResponse->msgType, formatDataResponse->msgFlags, formatDataResponse->dataLen);
|
||||
|
||||
Stream_Write(s, formatDataResponse->requestedFormatData, formatDataResponse->dataLen);
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatDataResponse");
|
||||
cliprdr_packet_send(cliprdr, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -566,6 +611,8 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
|
||||
strcpy(cliprdr->plugin.channel_def.name, "cliprdr");
|
||||
|
||||
cliprdr->log = WLog_Get("com.freerdp.channels.cliprdr.client");
|
||||
|
||||
cliprdr->plugin.connect_callback = cliprdr_process_connect;
|
||||
cliprdr->plugin.receive_callback = cliprdr_process_receive;
|
||||
cliprdr->plugin.event_callback = cliprdr_process_event;
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
struct cliprdr_plugin
|
||||
{
|
||||
rdpSvcPlugin plugin;
|
||||
|
||||
wLog* log;
|
||||
BOOL received_caps;
|
||||
BOOL use_long_format_names;
|
||||
BOOL stream_fileclip_enabled;
|
||||
|
||||
@@ -39,17 +39,6 @@
|
||||
#include "xf_cliprdr.h"
|
||||
|
||||
#define TAG CLIENT_TAG("x11")
|
||||
#ifdef WITH_DEBUG_X11
|
||||
#define DEBUG_X11(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_X11(fmt, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DEBUG_X11_CLIPRDR
|
||||
#define DEBUG_X11_CLIPRDR(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_X11_CLIPRDR(fmt, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
struct xf_cliprdr_format
|
||||
{
|
||||
@@ -102,6 +91,8 @@ struct xf_clipboard
|
||||
BOOL xfixes_supported;
|
||||
};
|
||||
|
||||
int xf_cliprdr_send_client_format_list(xfClipboard* clipboard);
|
||||
|
||||
static BYTE* lf2crlf(BYTE* data, int* size)
|
||||
{
|
||||
BYTE c;
|
||||
@@ -272,43 +263,8 @@ static void xf_cliprdr_send_supported_format_list(xfClipboard* clipboard)
|
||||
}
|
||||
|
||||
clipboard->context->ClientFormatList(clipboard->context, &formatList);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_send_format_list(xfClipboard* clipboard)
|
||||
{
|
||||
CLIPRDR_FORMAT_LIST formatList;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST));
|
||||
|
||||
if (xf_cliprdr_is_self_owned(clipboard))
|
||||
{
|
||||
/**
|
||||
* TODO: handle (raw?) format data
|
||||
* The original code appears to be sending back the original,
|
||||
* unmodified server format list here.
|
||||
*/
|
||||
|
||||
formatList.msgFlags = CB_RESPONSE_OK;
|
||||
formatList.cFormats = clipboard->numServerFormats;
|
||||
formatList.formats = clipboard->serverFormats;
|
||||
|
||||
clipboard->context->ClientFormatList(clipboard->context, &formatList);
|
||||
}
|
||||
else if (clipboard->owner == None)
|
||||
{
|
||||
formatList.msgFlags = CB_RESPONSE_OK;
|
||||
formatList.cFormats = 0;
|
||||
formatList.formats = NULL;
|
||||
|
||||
clipboard->context->ClientFormatList(clipboard->context, &formatList);
|
||||
}
|
||||
else if (clipboard->owner != xfc->drawable)
|
||||
{
|
||||
/* Request the owner for TARGETS, and wait for SelectionNotify event */
|
||||
XConvertSelection(xfc->display, clipboard->clipboard_atom,
|
||||
clipboard->targets[1], clipboard->property_atom, xfc->drawable, CurrentTime);
|
||||
}
|
||||
free(formats);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_send_data_request(xfClipboard* clipboard, UINT32 formatId)
|
||||
@@ -419,10 +375,7 @@ static BYTE* xf_cliprdr_process_requested_dib(BYTE* data, int* size)
|
||||
/* length should be at least BMP header (14) + sizeof(BITMAPINFOHEADER) */
|
||||
|
||||
if (*size < 54)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("bmp length %d too short", *size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*size -= 14;
|
||||
outbuf = (BYTE*) calloc(1, *size);
|
||||
@@ -559,7 +512,7 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL has_d
|
||||
if (!clipboard->xfixes_supported)
|
||||
{
|
||||
/* Resend the format list, otherwise the server won't request again for the next paste */
|
||||
xf_cliprdr_send_format_list(clipboard);
|
||||
xf_cliprdr_send_client_format_list(clipboard);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,26 +669,19 @@ static BOOL xf_cliprdr_process_dib(xfClipboard* clipboard, BYTE* data, int size)
|
||||
/* size should be at least sizeof(BITMAPINFOHEADER) */
|
||||
|
||||
if (size < 40)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("dib size %d too short", size);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s = Stream_New(data, size);
|
||||
Stream_Seek(s, 14);
|
||||
Stream_Read_UINT16(s, bpp);
|
||||
|
||||
if ((bpp < 1) || (bpp > 32))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid bpp value %d", bpp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, ncolors);
|
||||
offset = 14 + 40 + (bpp <= 8 ? (ncolors == 0 ? (1 << bpp) : ncolors) * 4 : 0);
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
DEBUG_X11_CLIPRDR("offset=%d bpp=%d ncolors=%d", offset, bpp, ncolors);
|
||||
|
||||
s = Stream_New(NULL, 14 + size);
|
||||
Stream_Write_UINT8(s, 'B');
|
||||
Stream_Write_UINT8(s, 'M');
|
||||
@@ -747,6 +693,7 @@ static BOOL xf_cliprdr_process_dib(xfClipboard* clipboard, BYTE* data, int size)
|
||||
clipboard->data = Stream_Buffer(s);
|
||||
clipboard->data_length = Stream_GetPosition(s);
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -761,19 +708,13 @@ static void xf_cliprdr_process_html(xfClipboard* clipboard, BYTE* data, int size
|
||||
end_str = strstr((char*) data, "EndHTML:");
|
||||
|
||||
if (!start_str || !end_str)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("invalid HTML clipboard format");
|
||||
return;
|
||||
}
|
||||
|
||||
start = atoi(start_str + 10);
|
||||
end = atoi(end_str + 8);
|
||||
|
||||
if ((start > size) || (end > size) || (start >= end))
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("invalid HTML offset");
|
||||
return;
|
||||
}
|
||||
|
||||
clipboard->data = (BYTE*) malloc(size - start + 1);
|
||||
CopyMemory(clipboard->data, data + start, end - start);
|
||||
@@ -856,8 +797,9 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
||||
clipboard->property_atom, 0, 4, 0, XA_INTEGER,
|
||||
&type, &fmt, &length, &bytes_left, &data) != Success)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("XGetWindowProperty failed");
|
||||
|
||||
}
|
||||
|
||||
if (data)
|
||||
{
|
||||
CopyMemory(&altFormatId, data, 4);
|
||||
@@ -873,7 +815,7 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
||||
}
|
||||
else if (clipboard->respond)
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("duplicated request");
|
||||
/* duplicate request */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -933,7 +875,7 @@ static BOOL xf_cliprdr_process_property_notify(xfClipboard* clipboard, XEvent* x
|
||||
|
||||
if (xevent->xproperty.window == clipboard->root_window)
|
||||
{
|
||||
xf_cliprdr_send_format_list(clipboard);
|
||||
xf_cliprdr_send_client_format_list(clipboard);
|
||||
}
|
||||
else if ((xevent->xproperty.window == xfc->drawable) &&
|
||||
(xevent->xproperty.state == PropertyNewValue) && clipboard->incr_starts)
|
||||
@@ -959,7 +901,7 @@ static void xf_cliprdr_check_owner(xfClipboard* clipboard)
|
||||
if (clipboard->owner != owner)
|
||||
{
|
||||
clipboard->owner = owner;
|
||||
xf_cliprdr_send_format_list(clipboard);
|
||||
xf_cliprdr_send_client_format_list(clipboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1045,7 +987,64 @@ int xf_cliprdr_send_client_capabilities(xfClipboard* clipboard)
|
||||
|
||||
int xf_cliprdr_send_client_format_list(xfClipboard* clipboard)
|
||||
{
|
||||
xf_cliprdr_send_format_list(clipboard);
|
||||
CLIPRDR_FORMAT_LIST formatList;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST));
|
||||
|
||||
if (!clipboard->sync)
|
||||
{
|
||||
UINT32 i, numFormats;
|
||||
CLIPRDR_FORMAT* formats;
|
||||
|
||||
numFormats = clipboard->numClientFormats;
|
||||
formats = (CLIPRDR_FORMAT*) calloc(numFormats, sizeof(CLIPRDR_FORMAT));
|
||||
|
||||
for (i = 0; i < numFormats; i++)
|
||||
{
|
||||
formats[i].formatId = clipboard->clientFormats[i].formatId;
|
||||
formats[i].formatName = clipboard->clientFormats[i].formatName;
|
||||
}
|
||||
|
||||
formatList.msgFlags = CB_RESPONSE_OK;
|
||||
formatList.cFormats = numFormats;
|
||||
formatList.formats = formats;
|
||||
|
||||
clipboard->context->ClientFormatList(clipboard->context, &formatList);
|
||||
|
||||
free(formats);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (xf_cliprdr_is_self_owned(clipboard))
|
||||
{
|
||||
/**
|
||||
* TODO: handle (raw?) format data
|
||||
* The original code appears to be sending back the original,
|
||||
* unmodified server format list here.
|
||||
*/
|
||||
|
||||
formatList.msgFlags = CB_RESPONSE_OK;
|
||||
formatList.cFormats = clipboard->numServerFormats;
|
||||
formatList.formats = clipboard->serverFormats;
|
||||
|
||||
clipboard->context->ClientFormatList(clipboard->context, &formatList);
|
||||
}
|
||||
else if (clipboard->owner == None)
|
||||
{
|
||||
formatList.msgFlags = CB_RESPONSE_OK;
|
||||
formatList.cFormats = 0;
|
||||
formatList.formats = NULL;
|
||||
|
||||
clipboard->context->ClientFormatList(clipboard->context, &formatList);
|
||||
}
|
||||
else if (clipboard->owner != xfc->drawable)
|
||||
{
|
||||
/* Request the owner for TARGETS, and wait for SelectionNotify event */
|
||||
XConvertSelection(xfc->display, clipboard->clipboard_atom,
|
||||
clipboard->targets[1], clipboard->property_atom, xfc->drawable, CurrentTime);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1154,6 +1153,9 @@ static int xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR_
|
||||
|
||||
if (clipboard->serverFormats)
|
||||
{
|
||||
for (i = 0; i < clipboard->numServerFormats; i++)
|
||||
free(clipboard->serverFormats[i].formatName);
|
||||
|
||||
free(clipboard->serverFormats);
|
||||
clipboard->serverFormats = NULL;
|
||||
}
|
||||
@@ -1186,25 +1188,13 @@ static int xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR_
|
||||
}
|
||||
}
|
||||
|
||||
xf_cliprdr_send_client_format_list_response(clipboard, TRUE);
|
||||
|
||||
XSetSelectionOwner(xfc->display, clipboard->clipboard_atom, xfc->drawable, CurrentTime);
|
||||
|
||||
XFlush(xfc->display);
|
||||
|
||||
return 1;
|
||||
|
||||
xf_cliprdr_send_client_format_list_response(clipboard, TRUE);
|
||||
|
||||
for (i = 0; i < formatList->cFormats; i++)
|
||||
{
|
||||
format = &formatList->formats[i];
|
||||
|
||||
if (format->formatId == CLIPRDR_FORMAT_UNICODETEXT)
|
||||
{
|
||||
xf_cliprdr_send_client_format_data_request(clipboard, format->formatId);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int xf_cliprdr_server_format_list_response(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse)
|
||||
@@ -1362,9 +1352,9 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||
if (XFixesQueryExtension(xfc->display, &clipboard->xfixes_event_base, &clipboard->xfixes_error_base))
|
||||
{
|
||||
int xfmajor, xfminor;
|
||||
|
||||
if (XFixesQueryVersion(xfc->display, &xfmajor, &xfminor))
|
||||
{
|
||||
DEBUG_X11_CLIPRDR("Found X Fixes extension version %d.%d", xfmajor, xfminor);
|
||||
XFixesSelectSelectionInput(xfc->display, clipboard->root_window,
|
||||
clipboard->clipboard_atom, XFixesSetSelectionOwnerNotifyMask);
|
||||
clipboard->xfixes_supported = TRUE;
|
||||
|
||||
Reference in New Issue
Block a user