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
This commit is contained in:
Peter Åstrand 2010-01-20 09:59:47 +00:00
parent c47cb3018d
commit 6ee9faeffc
6 changed files with 73 additions and 8 deletions

View File

@ -105,6 +105,15 @@ LIBS="$LIBS $ssldir/lib/libcrypto.a"
LIBS="$LIBS -L$ssldir/lib -lcrypto" LIBS="$LIBS -L$ssldir/lib -lcrypto"
rpath="$rpath:$ssldir/lib" 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, AC_ARG_ENABLE(smartcard,
[ --enable-smartcard Enables smart-card support. [ --enable-smartcard Enables smart-card support.

View File

@ -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 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 the root window. The geometry can also be specified as a percentage of the whole
screen, e.g. "-g 80%". 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 .TP
.BR "-f" .BR "-f"
Enable fullscreen mode. This overrides the window manager and causes the Enable fullscreen mode. This overrides the window manager and causes the

View File

@ -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_begin_update(void);
void ui_end_update(void); void ui_end_update(void);
void ui_seamless_begin(RD_BOOL hidden); void ui_seamless_begin(RD_BOOL hidden);
void ui_seamless_end();
void ui_seamless_hide_desktop(void); void ui_seamless_hide_desktop(void);
void ui_seamless_unhide_desktop(void); void ui_seamless_unhide_desktop(void);
void ui_seamless_toggle(void); void ui_seamless_toggle(void);

View File

@ -106,6 +106,7 @@ uint32 g_reconnect_logonid = 0;
char g_reconnect_random[16]; char g_reconnect_random[16];
RD_BOOL g_has_reconnect_random = False; RD_BOOL g_has_reconnect_random = False;
uint8 g_client_random[SEC_RANDOM_SIZE]; uint8 g_client_random[SEC_RANDOM_SIZE];
RD_BOOL g_pending_resize = False;
#ifdef WITH_RDPSND #ifdef WITH_RDPSND
RD_BOOL g_rdpsnd = False; RD_BOOL g_rdpsnd = False;
@ -1001,7 +1002,15 @@ main(int argc, char *argv[])
if (g_redirect) if (g_redirect)
continue; continue;
ui_seamless_end();
ui_destroy_window(); 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; break;
} }

9
rdp.c
View File

@ -52,6 +52,7 @@ extern int g_height;
extern RD_BOOL g_bitmap_cache; extern RD_BOOL g_bitmap_cache;
extern RD_BOOL g_bitmap_cache_persist_enable; extern RD_BOOL g_bitmap_cache_persist_enable;
extern RD_BOOL g_numlock_sync; extern RD_BOOL g_numlock_sync;
extern RD_BOOL g_pending_resize;
uint8 *g_next_packet; uint8 *g_next_packet;
uint32 g_rdp_shareid; uint32 g_rdp_shareid;
@ -1530,12 +1531,16 @@ process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
} }
/* Process incoming packets */ /* Process incoming packets */
/* nevers gets out of here till app is done */
void void
rdp_main_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason) rdp_main_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
{ {
while (rdp_loop(deactivated, 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 */ /* used in uiports and rdp_main_loop, processes the rdp packets waiting */

48
xwin.c
View File

@ -28,6 +28,9 @@
#include <strings.h> #include <strings.h>
#include "rdesktop.h" #include "rdesktop.h"
#include "xproto.h" #include "xproto.h"
#ifdef HAVE_XRANDR
#include <X11/extensions/Xrandr.h>
#endif
extern int g_sizeopt; extern int g_sizeopt;
extern int g_width; extern int g_width;
@ -39,6 +42,7 @@ extern RD_BOOL g_sendmotion;
extern RD_BOOL g_fullscreen; extern RD_BOOL g_fullscreen;
extern RD_BOOL g_grab_keyboard; extern RD_BOOL g_grab_keyboard;
extern RD_BOOL g_hide_decorations; extern RD_BOOL g_hide_decorations;
extern RD_BOOL g_pending_resize;
extern char g_title[]; extern char g_title[];
/* Color depth of the RDP session. /* Color depth of the RDP session.
As of RDP 5.1, it may be 8, 15, 16 or 24. */ As of RDP 5.1, it may be 8, 15, 16 or 24. */
@ -1946,12 +1950,6 @@ ui_init_connection(void)
void void
ui_deinit(void) ui_deinit(void)
{ {
while (g_seamless_windows)
{
XDestroyWindow(g_display, g_seamless_windows->wnd);
sw_remove_window(g_seamless_windows);
}
xclip_deinit(); xclip_deinit();
if (g_IM != NULL) if (g_IM != NULL)
@ -2085,6 +2083,9 @@ ui_create_window(void)
} }
XSelectInput(g_display, g_wnd, input_mask); XSelectInput(g_display, g_wnd, input_mask);
#ifdef HAVE_XRANDR
XSelectInput(g_display, RootWindowOfScreen(g_screen), StructureNotifyMask);
#endif
XMapWindow(g_display, g_wnd); XMapWindow(g_display, g_wnd);
/* wait for VisibilityNotify */ /* wait for VisibilityNotify */
@ -2303,6 +2304,11 @@ xwin_process_events(void)
/* Ignore events between ui_destroy_window and ui_create_window */ /* Ignore events between ui_destroy_window and ui_create_window */
continue; 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)) if ((g_IC != NULL) && (XFilterEvent(&xevent, None) == True))
{ {
DEBUG_KBD(("Filtering event\n")); DEBUG_KBD(("Filtering event\n"));
@ -2575,6 +2581,20 @@ xwin_process_events(void)
rdp_send_client_window_status(0); rdp_send_client_window_status(0);
break; break;
case ConfigureNotify: 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) if (!g_seamless_active)
break; 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 void
ui_seamless_hide_desktop() ui_seamless_hide_desktop()
{ {