client/X11: improve clipboard format search functions
The functions now have appropriate names which tell what exactly they are searching for: xf_cliprdr_get_client_format_by_id() Get a client-provided format by client-side ID. xf_cliprdr_get_client_format_by_atom() Get a client-provided format by client-side format name. xf_cliprdr_get_server_format_by_atom() Get a corresponding server format by client-side format name. The return types of functions have been adjusted accordingly and correct formats are now used everywhere without mixing them up: client-side formats are used for client -> server data flow, while server-side ones are used for server -> client tranfers. This resolves the issue #1414 as, for some reason, xfreerdp required server format list to be present to be able to provide its own client formats. Actually, we need only client format list to provide these. Also, CF_RAW special case is handled in a more elegant way: it is assumed to be present in every server format list (which is true).
This commit is contained in:
parent
4b67513f3c
commit
8434709fc6
@ -122,9 +122,9 @@ static BOOL xf_cliprdr_is_self_owned(xfClipboard* clipboard)
|
||||
return XGetSelectionOwner(xfc->display, clipboard->clipboard_atom) == xfc->drawable;
|
||||
}
|
||||
|
||||
static xfCliprdrFormat* xf_cliprdr_get_format_by_id(xfClipboard* clipboard, UINT32 formatId)
|
||||
static xfCliprdrFormat* xf_cliprdr_get_client_format_by_id(xfClipboard* clipboard, UINT32 formatId)
|
||||
{
|
||||
UINT32 index;
|
||||
int index;
|
||||
xfCliprdrFormat* format;
|
||||
|
||||
for (index = 0; index < clipboard->numClientFormats; index++)
|
||||
@ -138,25 +138,41 @@ static xfCliprdrFormat* xf_cliprdr_get_format_by_id(xfClipboard* clipboard, UINT
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static xfCliprdrFormat* xf_cliprdr_get_format_by_atom(xfClipboard* clipboard, Atom atom)
|
||||
static xfCliprdrFormat* xf_cliprdr_get_client_format_by_atom(xfClipboard* clipboard, Atom atom)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
xfCliprdrFormat* format;
|
||||
|
||||
for (i = 0; i < clipboard->numClientFormats; i++)
|
||||
{
|
||||
format = &(clipboard->clientFormats[i]);
|
||||
|
||||
if (format->atom != atom)
|
||||
continue;
|
||||
|
||||
if (format->formatId == 0)
|
||||
if (format->atom == atom)
|
||||
return format;
|
||||
}
|
||||
|
||||
for (j = 0; j < clipboard->numServerFormats; j++)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CLIPRDR_FORMAT* xf_cliprdr_get_server_format_by_atom(xfClipboard* clipboard, Atom atom)
|
||||
{
|
||||
int i, j;
|
||||
xfCliprdrFormat* client_format;
|
||||
CLIPRDR_FORMAT* server_format;
|
||||
|
||||
for (i = 0; i < clipboard->numClientFormats; i++)
|
||||
{
|
||||
client_format = &(clipboard->clientFormats[i]);
|
||||
|
||||
if (client_format->atom == atom)
|
||||
{
|
||||
if (clipboard->serverFormats[j].formatId == format->formatId)
|
||||
return format;
|
||||
for (j = 0; j < clipboard->numServerFormats; j++)
|
||||
{
|
||||
server_format = &(clipboard->serverFormats[j]);
|
||||
|
||||
if (server_format->formatId == client_format->formatId)
|
||||
return server_format;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,9 +227,6 @@ static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
||||
CLIPRDR_FORMAT* formats = NULL;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
if (!clipboard->numServerFormats)
|
||||
return; /* server format list was not yet received */
|
||||
|
||||
XGetWindowProperty(xfc->display, xfc->drawable, clipboard->property_atom,
|
||||
0, 200, 0, XA_ATOM, &atom, &format_property, &length, &bytes_left, &data);
|
||||
|
||||
@ -235,7 +248,7 @@ static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
||||
{
|
||||
atom = ((Atom*) data)[i];
|
||||
|
||||
format = xf_cliprdr_get_format_by_atom(clipboard, atom);
|
||||
format = xf_cliprdr_get_client_format_by_atom(clipboard, atom);
|
||||
|
||||
if (format)
|
||||
{
|
||||
@ -273,7 +286,7 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
|
||||
if (clipboard->incr_starts && hasData)
|
||||
return;
|
||||
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
format = xf_cliprdr_get_client_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (!hasData || !data || !format)
|
||||
{
|
||||
@ -346,7 +359,7 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
|
||||
xfCliprdrFormat* format;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
format = xf_cliprdr_get_client_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (!format || (format->atom != target))
|
||||
{
|
||||
@ -501,7 +514,7 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
||||
BOOL delayRespond;
|
||||
unsigned long length;
|
||||
unsigned long bytes_left;
|
||||
xfCliprdrFormat* format;
|
||||
CLIPRDR_FORMAT* format;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
if (xevent->xselectionrequest.owner != xfc->drawable)
|
||||
@ -535,14 +548,14 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
||||
}
|
||||
else
|
||||
{
|
||||
format = xf_cliprdr_get_format_by_atom(clipboard, xevent->xselectionrequest.target);
|
||||
format = xf_cliprdr_get_server_format_by_atom(clipboard, xevent->xselectionrequest.target);
|
||||
|
||||
if (format && (xevent->xselectionrequest.requestor != xfc->drawable))
|
||||
{
|
||||
formatId = format->formatId;
|
||||
altFormatId = formatId;
|
||||
|
||||
if (formatId == 0)
|
||||
if (formatId == CF_RAW)
|
||||
{
|
||||
if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor,
|
||||
clipboard->property_atom, 0, 4, 0, XA_INTEGER,
|
||||
@ -631,7 +644,7 @@ static BOOL xf_cliprdr_process_property_notify(xfClipboard* clipboard, XEvent* x
|
||||
else if ((xevent->xproperty.window == xfc->drawable) &&
|
||||
(xevent->xproperty.state == PropertyNewValue) && clipboard->incr_starts)
|
||||
{
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
format = xf_cliprdr_get_client_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (format)
|
||||
xf_cliprdr_get_requested_data(clipboard, format->atom);
|
||||
@ -867,14 +880,11 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR
|
||||
clipboard->numServerFormats = 0;
|
||||
}
|
||||
|
||||
clipboard->numServerFormats = formatList->numFormats;
|
||||
clipboard->numServerFormats = formatList->numFormats + 1; /* +1 for CF_RAW */
|
||||
|
||||
if (clipboard->numServerFormats)
|
||||
{
|
||||
if (!(clipboard->serverFormats = (CLIPRDR_FORMAT*) calloc(clipboard->numServerFormats, sizeof(CLIPRDR_FORMAT)))) {
|
||||
WLog_ERR(TAG, "failed to allocate %d CLIPRDR_FORMAT structs", clipboard->numServerFormats);
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
if (!(clipboard->serverFormats = (CLIPRDR_FORMAT*) calloc(clipboard->numServerFormats, sizeof(CLIPRDR_FORMAT)))) {
|
||||
WLog_ERR(TAG, "failed to allocate %d CLIPRDR_FORMAT structs", clipboard->numServerFormats);
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (i = 0; i < formatList->numFormats; i++)
|
||||
@ -897,6 +907,11 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR
|
||||
}
|
||||
}
|
||||
|
||||
/* CF_RAW is always implicitly supported by the server */
|
||||
format = &clipboard->serverFormats[formatList->numFormats];
|
||||
format->formatId = CF_RAW;
|
||||
format->formatName = NULL;
|
||||
|
||||
clipboard->numTargets = 2;
|
||||
|
||||
for (i = 0; i < formatList->numFormats; i++)
|
||||
@ -947,13 +962,13 @@ static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context,
|
||||
|
||||
if (xf_cliprdr_is_self_owned(clipboard))
|
||||
{
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, 0);
|
||||
format = xf_cliprdr_get_client_format_by_id(clipboard, CF_RAW);
|
||||
|
||||
XChangeProperty(xfc->display, xfc->drawable, clipboard->property_atom,
|
||||
XA_INTEGER, 32, PropModeReplace, (BYTE*) &formatId, 1);
|
||||
}
|
||||
else
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, formatId);
|
||||
format = xf_cliprdr_get_client_format_by_id(clipboard, formatId);
|
||||
|
||||
if (!format)
|
||||
return xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||
@ -984,7 +999,7 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context
|
||||
UINT32 SrcSize;
|
||||
UINT32 formatId;
|
||||
UINT32 altFormatId;
|
||||
xfCliprdrFormat* format;
|
||||
CLIPRDR_FORMAT* format;
|
||||
BOOL nullTerminated = FALSE;
|
||||
UINT32 size = formatDataResponse->dataLen;
|
||||
BYTE* data = formatDataResponse->requestedFormatData;
|
||||
@ -994,7 +1009,7 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context
|
||||
if (!clipboard->respond)
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
format = xf_cliprdr_get_server_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (clipboard->data)
|
||||
{
|
||||
@ -1140,7 +1155,7 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||
n = 0;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "_FREERDP_RAW", False);
|
||||
clipboard->clientFormats[n].formatId = 0;
|
||||
clipboard->clientFormats[n].formatId = CF_RAW;
|
||||
n++;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "UTF8_STRING", False);
|
||||
|
Loading…
Reference in New Issue
Block a user