From 626e40a9c15f0e8e9d878e702155ccbbafc35b77 Mon Sep 17 00:00:00 2001 From: ilammy Date: Fri, 14 Aug 2015 22:57:42 +0300 Subject: [PATCH] client/X11: add raw clipboard transfer indication Some time ago there was a property _FREERDP_CLIPRDR_ID which was indended to indicate that an XFreeRDP window owns a clipboard. This was necessary for raw transfers. This property was used by xf_cliprdr_is_self_owned() function. However, raw transfer support was broken and the meaning of xf_cliprdr_is_self_owned() gradually changed into checking whether the *current* window owns the clipboard, not just any XFreeRDP window. Thus _FREERDP_CLIPRDR_ID was removed in a4580923e77b4690 (xfreerdp/clipr: fix self owned test and hardening). However, now we are going to fix raw transfers and we need that property. This patch reintroduces a similar property "_FREERDP_CLIPRDR_RAW" which indicates that a window is an XFreeRDP window with enabled raw transfer. It is currently used by xf_cliprdr_server_format_data_request() to correctly request format data from another XFreeRDP instance via raw transfer protocol. This property can be queried from the clipboard owner with the function xf_cliprdr_is_raw_transfer_available() and can be enabled or disabled on the current window by xf_cliprdr_set_raw_transfer_enabled(). Disabling raw transfers will be necesary to correctly implement file transfers in the future. However, currently raw transfers are always enabled. --- client/X11/xf_cliprdr.c | 53 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index 6dea2c1a4..04abea08f 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -64,6 +64,8 @@ struct xf_clipboard Atom clipboard_atom; Atom property_atom; + Atom raw_transfer_atom; + int numClientFormats; xfCliprdrFormat clientFormats[20]; @@ -122,6 +124,51 @@ static BOOL xf_cliprdr_is_self_owned(xfClipboard* clipboard) return XGetSelectionOwner(xfc->display, clipboard->clipboard_atom) == xfc->drawable; } +static void xf_cliprdr_set_raw_transfer_enabled(xfClipboard* clipboard, BOOL enabled) +{ + UINT32 data = enabled; + xfContext* xfc = clipboard->xfc; + + XChangeProperty(xfc->display, xfc->drawable, clipboard->raw_transfer_atom, + XA_INTEGER, 32, PropModeReplace, (BYTE*) &data, 1); +} + +static BOOL xf_cliprdr_is_raw_transfer_available(xfClipboard* clipboard) +{ + Atom type; + int format; + int result = 0; + unsigned long length; + unsigned long bytes_left; + UINT32* data = NULL; + UINT32 is_enabled = 0; + Window owner = None; + xfContext* xfc = clipboard->xfc; + + owner = XGetSelectionOwner(xfc->display, clipboard->clipboard_atom); + + if (owner != None) + { + result = XGetWindowProperty(xfc->display, owner, + clipboard->raw_transfer_atom, 0, 4, 0, XA_INTEGER, + &type, &format, &length, &bytes_left, (BYTE**) &data); + } + + if (data) + { + is_enabled = *data; + XFree(data); + } + + if ((owner == None) || (owner == xfc->drawable)) + return FALSE; + + if (result != Success) + return FALSE; + + return is_enabled ? TRUE : FALSE; +} + static BOOL xf_cliprdr_formats_equal(const CLIPRDR_FORMAT* server, const xfCliprdrFormat* client) { if (server->formatName && client->formatName) @@ -968,7 +1015,7 @@ static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context, xfClipboard* clipboard = (xfClipboard*) context->custom; xfContext* xfc = clipboard->xfc; - if (xf_cliprdr_is_self_owned(clipboard)) + if (xf_cliprdr_is_raw_transfer_available(clipboard)) { format = xf_cliprdr_get_client_format_by_id(clipboard, CF_RAW); @@ -1140,6 +1187,10 @@ xfClipboard* xf_clipboard_new(xfContext* xfc) clipboard->property_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR", FALSE); + clipboard->raw_transfer_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR_RAW", FALSE); + + xf_cliprdr_set_raw_transfer_enabled(clipboard, TRUE); + XSelectInput(xfc->display, clipboard->root_window, PropertyChangeMask); #ifdef WITH_XFIXES