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.
This commit is contained in:
ilammy 2016-08-18 21:14:52 +03:00
parent 38ca328739
commit 82f3abac49
5 changed files with 19 additions and 6 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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)
{

View File

@ -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, ...);