From 6ee9faeffcd9dd2e4c262d732e15a3a02278578d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C3=85strand?= Date: Wed, 20 Jan 2010 09:59:47 +0000 Subject: [PATCH] Added RandR support: If the specified geometry depends on the screen size, and the screen size is changed, rdesktop will automatically reconnect using the new screen size. This feature uses the previously implemented autoreconnect feature. The new UI function ui_seamless_end() has been introduced, to make it possible to resize in seamless mode as well. git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/rdesktop/trunk@1556 423420c4-83ab-492f-b58f-81f9feb106b5 --- configure.ac | 9 +++++++++ doc/rdesktop.1 | 5 +++++ proto.h | 1 + rdesktop.c | 9 +++++++++ rdp.c | 9 +++++++-- xwin.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 6 files changed, 73 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index d59bef1..000fefb 100644 --- a/configure.ac +++ b/configure.ac @@ -105,6 +105,15 @@ LIBS="$LIBS $ssldir/lib/libcrypto.a" LIBS="$LIBS -L$ssldir/lib -lcrypto" rpath="$rpath:$ssldir/lib" ]) +# xrandr +if test -n "$PKG_CONFIG"; then + PKG_CHECK_MODULES(XRANDR, xrandr, [HAVE_XRANDR=1], [HAVE_XRANDR=0]) +fi +if test x"$HAVE_XRANDR" = "x1"; then + CFLAGS="$CFLAGS $XRANDR_CFLAGS" + LIBS="$LIBS $XRANDR_LIBS" + AC_DEFINE(HAVE_XRANDR) +fi AC_ARG_ENABLE(smartcard, [ --enable-smartcard Enables smart-card support. diff --git a/doc/rdesktop.1 b/doc/rdesktop.1 index 7e3f597..95f97d3 100644 --- a/doc/rdesktop.1 +++ b/doc/rdesktop.1 @@ -66,6 +66,11 @@ Desktop geometry (WxH). If geometry is the special word "workarea", the geometry will be fetched from the extended window manager hints property _NET_WORKAREA, from the root window. The geometry can also be specified as a percentage of the whole screen, e.g. "-g 80%". + +If the specified geometry depends on the screen size, and the screen +size is changed, rdesktop will automatically reconnect using the new +screen size. This requires that rdesktop has been compiled with RandR +support. .TP .BR "-f" Enable fullscreen mode. This overrides the window manager and causes the diff --git a/proto.h b/proto.h index 3486abc..5813a16 100644 --- a/proto.h +++ b/proto.h @@ -279,6 +279,7 @@ void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy); void ui_begin_update(void); void ui_end_update(void); void ui_seamless_begin(RD_BOOL hidden); +void ui_seamless_end(); void ui_seamless_hide_desktop(void); void ui_seamless_unhide_desktop(void); void ui_seamless_toggle(void); diff --git a/rdesktop.c b/rdesktop.c index 49cc7c8..6f11a4f 100644 --- a/rdesktop.c +++ b/rdesktop.c @@ -106,6 +106,7 @@ uint32 g_reconnect_logonid = 0; char g_reconnect_random[16]; RD_BOOL g_has_reconnect_random = False; uint8 g_client_random[SEC_RANDOM_SIZE]; +RD_BOOL g_pending_resize = False; #ifdef WITH_RDPSND RD_BOOL g_rdpsnd = False; @@ -1001,7 +1002,15 @@ main(int argc, char *argv[]) if (g_redirect) continue; + + ui_seamless_end(); ui_destroy_window(); + if (g_pending_resize) + { + /* If we have a pending resize, reconnect using the new size, rather than exit */ + g_pending_resize = False; + continue; + } break; } diff --git a/rdp.c b/rdp.c index 03d3bdd..318c44a 100644 --- a/rdp.c +++ b/rdp.c @@ -52,6 +52,7 @@ extern int g_height; extern RD_BOOL g_bitmap_cache; extern RD_BOOL g_bitmap_cache_persist_enable; extern RD_BOOL g_numlock_sync; +extern RD_BOOL g_pending_resize; uint8 *g_next_packet; uint32 g_rdp_shareid; @@ -1530,12 +1531,16 @@ process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ ) } /* Process incoming packets */ -/* nevers gets out of here till app is done */ void rdp_main_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason) { while (rdp_loop(deactivated, ext_disc_reason)) - ; + { + if (g_pending_resize) + { + return; + } + } } /* used in uiports and rdp_main_loop, processes the rdp packets waiting */ diff --git a/xwin.c b/xwin.c index 52e2f78..e89b693 100644 --- a/xwin.c +++ b/xwin.c @@ -28,6 +28,9 @@ #include #include "rdesktop.h" #include "xproto.h" +#ifdef HAVE_XRANDR +#include +#endif extern int g_sizeopt; extern int g_width; @@ -39,6 +42,7 @@ extern RD_BOOL g_sendmotion; extern RD_BOOL g_fullscreen; extern RD_BOOL g_grab_keyboard; extern RD_BOOL g_hide_decorations; +extern RD_BOOL g_pending_resize; extern char g_title[]; /* Color depth of the RDP session. As of RDP 5.1, it may be 8, 15, 16 or 24. */ @@ -1946,12 +1950,6 @@ ui_init_connection(void) void ui_deinit(void) { - while (g_seamless_windows) - { - XDestroyWindow(g_display, g_seamless_windows->wnd); - sw_remove_window(g_seamless_windows); - } - xclip_deinit(); if (g_IM != NULL) @@ -2085,6 +2083,9 @@ ui_create_window(void) } XSelectInput(g_display, g_wnd, input_mask); +#ifdef HAVE_XRANDR + XSelectInput(g_display, RootWindowOfScreen(g_screen), StructureNotifyMask); +#endif XMapWindow(g_display, g_wnd); /* wait for VisibilityNotify */ @@ -2303,6 +2304,11 @@ xwin_process_events(void) /* Ignore events between ui_destroy_window and ui_create_window */ continue; + /* Also ignore root window events except ConfigureNotify */ + if (xevent.type != ConfigureNotify + && xevent.xany.window == DefaultRootWindow(g_display)) + continue; + if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True)) { DEBUG_KBD(("Filtering event\n")); @@ -2575,6 +2581,20 @@ xwin_process_events(void) rdp_send_client_window_status(0); break; case ConfigureNotify: +#ifdef HAVE_XRANDR + if ((g_sizeopt || g_fullscreen) + && xevent.xconfigure.window == DefaultRootWindow(g_display)) + { + if (xevent.xconfigure.width != WidthOfScreen(g_screen) + || xevent.xconfigure.height != HeightOfScreen(g_screen)) + { + XRRUpdateConfiguration(&xevent); + XSync(g_display, False); + g_pending_resize = True; + } + + } +#endif if (!g_seamless_active) break; @@ -3774,6 +3794,22 @@ ui_seamless_begin(RD_BOOL hidden) } +void +ui_seamless_end() +{ + /* Destroy all seamless windows */ + while (g_seamless_windows) + { + XDestroyWindow(g_display, g_seamless_windows->wnd); + sw_remove_window(g_seamless_windows); + } + + g_seamless_started = False; + g_seamless_active = False; + g_seamless_hidden = False; +} + + void ui_seamless_hide_desktop() {