From 82f3abac494d7a5c01ee60b76c4892a3379502a1 Mon Sep 17 00:00:00 2001 From: ilammy Date: Thu, 18 Aug 2016 21:14:52 +0300 Subject: [PATCH] client/X11: teach RAIL to use clipboard redirection XSelection protocol does not define any global clipboard as there is on Windows. Instead each window has its own property for clipboard content (like CLIPBOARD or PRIMARY) and there is a global notion of clipboard ownership. Only one window can claim ownership of some clipboard type at the moment. FreeRDP uses CLIPBOARD for clipboard transfers (it's the one used by applications when Ctrl+V is pressed). For regular desktop sessions the session window itself is used for clipboard interactions via xfc->drawable field. However, for remote app session there is no session window. We cannot use the current remote app window as it may change or be destroyed without closing the session. We also cannot use the root window as it is already used for CF_RAW transfer protocol. Therefore we create a simple dummy window to put into xfc->drawable for this exact job: to act as a clipboard vessel on behalf of the entire remote app session. xf_create_window() usually creates the window as we immediately start in RAIL mode when possible. xf_rail_enable_remoteapp_mode() is invoked only when autologin failed or remote desktop had to show the session window to the user for some reason. --- client/X11/xf_client.c | 2 +- client/X11/xf_event.c | 5 +---- client/X11/xf_rail.c | 3 ++- client/X11/xf_window.c | 12 ++++++++++++ client/X11/xf_window.h | 3 +++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 5b5bc51..ccc1796 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -585,7 +585,7 @@ BOOL xf_create_window(xfContext* xfc) } else { - xfc->drawable = DefaultRootWindow(xfc->display); + xfc->drawable = xf_CreateDummyWindow(xfc); } ZeroMemory(&gcv, sizeof(gcv)); diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index f072021..d1a30f4 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -1061,10 +1061,7 @@ BOOL xf_event_process(freerdp* instance, XEvent* event) break; } - if (!xfc->remote_app) - { - xf_cliprdr_handle_xevent(xfc, event); - } + xf_cliprdr_handle_xevent(xfc, event); xf_input_handle_event(xfc, event); XSync(xfc->display, FALSE); diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index 5f40057..51c565b 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -64,7 +64,7 @@ void xf_rail_enable_remoteapp_mode(xfContext* xfc) if (!xfc->remote_app) { xfc->remote_app = TRUE; - xfc->drawable = DefaultRootWindow(xfc->display); + xfc->drawable = xf_CreateDummyWindow(xfc); xf_DestroyDesktopWindow(xfc, xfc->window); xfc->window = NULL; } @@ -75,6 +75,7 @@ void xf_rail_disable_remoteapp_mode(xfContext* xfc) if (xfc->remote_app) { xfc->remote_app = FALSE; + xf_DestroyDummyWindow(xfc, xfc->drawable); xf_create_window(xfc); } } diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 03ea662..76a64f4 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -336,6 +336,18 @@ static const char* get_shm_id() return shm_id; } +Window xf_CreateDummyWindow(xfContext *xfc) +{ + return XCreateSimpleWindow(xfc->display, DefaultRootWindow(xfc->display), + 0, 0, 1, 1, 0, 0, 0); +} + +void xf_DestroyDummyWindow(xfContext *xfc, Window window) +{ + if (window) + XDestroyWindow(xfc->display, window); +} + xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height) { diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index 0a41c79..37c92ae 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -150,6 +150,9 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height); void xf_DestroyDesktopWindow(xfContext* xfc, xfWindow* window); +Window xf_CreateDummyWindow(xfContext* xfc); +void xf_DestroyDummyWindow(xfContext* xfc, Window window); + BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int length, unsigned long* nitems, unsigned long* bytes, BYTE** prop); void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int numArgs, ...); -- 2.7.4