From cf3c03c60e7cb582f48a903087a43620eaaf4c27 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Mon, 2 Jan 2012 10:27:04 +0100 Subject: [PATCH] xfreerdp: a quick workaround for some issues with TS Remote App. Currently in Remote App mode we have no option to interact with the remote desktop host before the first RAIL window is created. In many situations this interaction possibility is absolutely required. One example is that screen which gets displayed if another user is logged on. It requires clicking a button in pre-RAIL mode so that the currently logged on user gets notified to confirm or deny the connection. Another example is the option to log on graphically (e.g. for hosts that don't support NLA) without predefined credentials. Also if the administrator sets the "User must change password at next logon" option there is currently no way to do this in TS Remote App mode. This change basically lets xfreerdp create the main window in Remote App mode like in a normal session and xfi->remote_app is not set to true initially. As soon as the rail exec result event or the first rail window creation request is received (whatever comes first) the main window gets destroyed and xfi->remote_app is set to true. The second change is to disconnect immediately if the rail exec result event reports an error, e.g. if the specified app cannot be found or if it is not in the list of allowed applications. This fixes FreeRDP github issue #143 and issue #308. I'm aware that this is not the most elegant solution but it is definitely an improvement and probably good enough for 1.0. A nicer solution would be hiding the main window and only displaying it if no rail exec result or rail window creation event is received after a certain timeout ... --- client/X11/xf_rail.c | 18 ++++++++++ client/X11/xfreerdp.c | 82 ++++++++++++++++++++----------------------- client/X11/xfreerdp.h | 1 + 3 files changed, 57 insertions(+), 44 deletions(-) diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index edd5a74cf..b437d3f0b 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -28,6 +28,17 @@ #include "xf_window.h" #include "xf_rail.h" +void xf_rail_enable_remoteapp_mode(xfInfo* xfi) +{ + if (xfi->remote_app == false) + { + xfi->remote_app = true; + xfi->drawable = DefaultRootWindow(xfi->display); + xf_DestroyWindow(xfi, xfi->window); + xfi->window = NULL; + } +} + void xf_rail_paint(xfInfo* xfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 uright, uint32 ubottom) { xfWindow* xfw; @@ -75,6 +86,8 @@ void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window) xfi = (xfInfo*) rail->extra; + xf_rail_enable_remoteapp_mode(xfi); + xfw = xf_CreateWindow((xfInfo*) rail->extra, window, window->windowOffsetX, window->windowOffsetY, window->windowWidth, window->windowHeight, @@ -365,6 +378,11 @@ void xf_process_rail_exec_result_event(xfInfo* xfi, rdpChannels* channels, RDP_E { printf("RAIL exec error: execResult=%s NtError=0x%X\n", error_code_names[exec_result->execResult], exec_result->rawResult); + xfi->disconnect = True; + } + else + { + xf_rail_enable_remoteapp_mode(xfi); } } diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index 7ce3bba7c..0e384a9d2 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -291,49 +291,42 @@ void xf_create_window(xfInfo* xfi) xfi->attribs.bit_gravity = ForgetGravity; xfi->attribs.win_gravity = StaticGravity; - if (xfi->remote_app != true) + if (xfi->instance->settings->window_title != NULL) { - if (xfi->instance->settings->window_title != NULL) - { - win_title = xmalloc(sizeof(xfi->instance->settings->window_title)); - sprintf(win_title, "%s", xfi->instance->settings->window_title); - } - else if (xfi->instance->settings->port == 3389) - { - win_title = xmalloc(sizeof("FreeRDP: ") + strlen(xfi->instance->settings->hostname)); - sprintf(win_title, "FreeRDP: %s", xfi->instance->settings->hostname); - } - else - { - win_title = xmalloc(sizeof("FreeRDP: ") + strlen(xfi->instance->settings->hostname) + sizeof(":00000")); - sprintf(win_title, "FreeRDP: %s:%i", xfi->instance->settings->hostname, xfi->instance->settings->port); - } - - xfi->window = xf_CreateDesktopWindow(xfi, win_title, width, height, xfi->decorations); - xfree(win_title); - - if (xfi->parent_window) - XReparentWindow(xfi->display, xfi->window->handle, xfi->parent_window, 0, 0); - - if (xfi->fullscreen) - xf_SetWindowFullscreen(xfi, xfi->window, xfi->fullscreen); - - /* wait for VisibilityNotify */ - do - { - XMaskEvent(xfi->display, VisibilityChangeMask, &xevent); - } - while (xevent.type != VisibilityNotify); - - xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured); - - XSetWMProtocols(xfi->display, xfi->window->handle, &(xfi->WM_DELETE_WINDOW), 1); - xfi->drawable = xfi->window->handle; + win_title = xmalloc(sizeof(xfi->instance->settings->window_title)); + sprintf(win_title, "%s", xfi->instance->settings->window_title); + } + else if (xfi->instance->settings->port == 3389) + { + win_title = xmalloc(sizeof("FreeRDP: ") + strlen(xfi->instance->settings->hostname)); + sprintf(win_title, "FreeRDP: %s", xfi->instance->settings->hostname); } else { - xfi->drawable = DefaultRootWindow(xfi->display); + win_title = xmalloc(sizeof("FreeRDP: ") + strlen(xfi->instance->settings->hostname) + sizeof(":00000")); + sprintf(win_title, "FreeRDP: %s:%i", xfi->instance->settings->hostname, xfi->instance->settings->port); } + + xfi->window = xf_CreateDesktopWindow(xfi, win_title, width, height, xfi->decorations); + xfree(win_title); + + if (xfi->parent_window) + XReparentWindow(xfi->display, xfi->window->handle, xfi->parent_window, 0, 0); + + if (xfi->fullscreen) + xf_SetWindowFullscreen(xfi, xfi->window, xfi->fullscreen); + + /* wait for VisibilityNotify */ + do + { + XMaskEvent(xfi->display, VisibilityChangeMask, &xevent); + } + while (xevent.type != VisibilityNotify); + + xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured); + + XSetWMProtocols(xfi->display, xfi->window->handle, &(xfi->WM_DELETE_WINDOW), 1); + xfi->drawable = xfi->window->handle; } void xf_toggle_fullscreen(xfInfo* xfi) @@ -567,7 +560,6 @@ boolean xf_pre_connect(freerdp* instance) xfi->mouse_motion = settings->mouse_motion; xfi->complex_regions = true; xfi->decorations = settings->decorations; - xfi->remote_app = settings->remote_app; xfi->fullscreen = settings->fullscreen; xfi->grab_keyboard = settings->grab_keyboard; xfi->fullscreen_toggle = true; @@ -742,8 +734,7 @@ boolean xf_post_connect(freerdp* instance) xf_tsmf_init(xfi, xv_port); - if (xfi->remote_app != true) - xf_cliprdr_init(xfi, channels); + xf_cliprdr_init(xfi, channels); return true; } @@ -889,8 +880,11 @@ void xf_window_free(xfInfo* xfi) XFreeGC(xfi->display, xfi->gc); xfi->gc = 0; - xf_DestroyWindow(xfi, xfi->window); - xfi->window = NULL; + if (xfi->window != NULL) + { + xf_DestroyWindow(xfi, xfi->window); + xfi->window = NULL; + } if (xfi->primary) { @@ -965,7 +959,7 @@ int xfreerdp_run(freerdp* instance) xfi = ((xfContext*) instance->context)->xfi; channels = instance->context->channels; - while (1) + while (!xfi->disconnect) { rcount = 0; wcount = 0; diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 9cb70d856..88850cade 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -107,6 +107,7 @@ struct xf_info xfWorkArea workArea; int current_desktop; boolean remote_app; + boolean disconnect; HCLRCONV clrconv; Window parent_window;