Merge pull request #232 from rdesktop/dynamic_resize_fixes

Dynamic resize fixes and some refactor
This commit is contained in:
Henrik Andersson 2018-01-11 17:47:35 +01:00 committed by GitHub
commit 1553760a1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 699 additions and 151 deletions

View File

@ -257,7 +257,9 @@ void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode);
/* xwin.c */ /* xwin.c */
RD_BOOL get_key_state(unsigned int state, uint32 keysym); RD_BOOL get_key_state(unsigned int state, uint32 keysym);
RD_BOOL ui_init(void); RD_BOOL ui_init(void);
void ui_init_connection(void); void ui_get_screen_size(uint32 *width, uint32 *height);
void ui_get_screen_size_from_percentage(uint32 pw, uint32 ph, uint32 *width, uint32 *height);
void ui_get_workarea_size(uint32 *width, uint32 *height);
void ui_deinit(void); void ui_deinit(void);
RD_BOOL ui_create_window(uint32 width, uint32 height); RD_BOOL ui_create_window(uint32 width, uint32 height);
void ui_resize_window(uint32 width, uint32 height); void ui_resize_window(uint32 width, uint32 height);

View File

@ -67,17 +67,16 @@ unsigned int g_keylayout = 0x409; /* Defaults to US keyboard layout */
int g_keyboard_type = 0x4; /* Defaults to US keyboard layout */ int g_keyboard_type = 0x4; /* Defaults to US keyboard layout */
int g_keyboard_subtype = 0x0; /* Defaults to US keyboard layout */ int g_keyboard_subtype = 0x0; /* Defaults to US keyboard layout */
int g_keyboard_functionkeys = 0xc; /* Defaults to US keyboard layout */ int g_keyboard_functionkeys = 0xc; /* Defaults to US keyboard layout */
int g_sizeopt = 0; /* If non-zero, a special size has been
requested. If 1, the geometry will be fetched
from _NET_WORKAREA. If negative, absolute value
specifies the percent of the whole screen. */
int g_dpi = 0; /* device DPI: default not set */ int g_dpi = 0; /* device DPI: default not set */
/* Following variables holds the initial width and height for a /* Following variables holds the requested width and height for a
rdesktop window, this is sent upon connect and tells the server rdesktop window, this is sent upon connect and tells the server
what size of session we want to have. Set to decent defaults. */ what size of session we want to have. Set to decent defaults. */
uint32 g_initial_width = 1024; uint32 g_requested_session_width = 1024;
uint32 g_initial_height = 768; uint32 g_requested_session_height = 768;
window_size_type_t g_window_size_type = Fixed;
int g_xpos = 0; int g_xpos = 0;
int g_ypos = 0; int g_ypos = 0;
@ -592,6 +591,170 @@ parse_server_and_port(char *server)
} }
// [WxH|P%|W%xH%][@DPI][+X[+Y]]|workarea
int parse_geometry_string(const char *optarg)
{
sint32 value;
const char *ps;
char *pe;
/* special keywords */
if (strcmp(optarg, "workarea") == 0)
{
g_window_size_type = Workarea;
return 0;
}
/* parse first integer */
ps = optarg;
value = strtol(ps, &pe, 10);
if (ps == pe || value <= 0)
{
logger(Core, Error, "invalid geometry, expected positive integer for width");
return -1;
}
g_requested_session_width = value;
ps = pe;
/* expect % or x */
if (*ps != '%' && *ps != 'x')
{
logger(Core, Error, "invalid geometry, expected '%%' or 'x' after width");
return -1;
}
if (*ps == '%')
{
g_window_size_type = PercentageOfScreen;
ps++;
pe++;
}
if (*ps == 'x')
{
ps++;
value = strtol(ps, &pe, 10);
if (ps == pe || value <= 0)
{
logger(Core, Error, "invalid geometry, expected positive integer for height");
return -1;
}
g_requested_session_height = value;
ps = pe;
if (*ps == '%' && g_window_size_type == Fixed)
{
logger(Core, Error, "invalid geometry, unexpected '%%' after height");
return -1;
}
if (g_window_size_type == PercentageOfScreen)
{
if (*ps != '%')
{
logger(Core, Error, "invalid geometry, expected '%%' after height");
return -1;
}
ps++;
pe++;
}
}
else
{
if (g_window_size_type == PercentageOfScreen)
{
/* percentage of screen used for both width and height */
g_requested_session_height = g_requested_session_width;
}
else
{
logger(Core, Error, "invalid geometry, missing height (WxH)");
return -1;
}
}
/* parse optional dpi */
if (*ps == '@')
{
ps++;
pe++;
value = strtol(ps, &pe, 10);
if (ps == pe || value <= 0)
{
logger(Core, Error, "invalid geometry, expected positive integer for DPI");
return -1;
}
g_dpi = value;
ps = pe;
}
/* parse optional window position */
if (*ps == '+' || *ps == '-')
{
/* parse x position */
value = strtol(ps, &pe, 10);
if (ps == pe)
{
logger(Core, Error, "invalid geometry, expected an integer for X position");
return -1;
}
g_pos |= (value < 0) ? 2 : 1;
g_xpos = value;
ps = pe;
}
if (*ps == '+' || *ps == '-')
{
/* parse y position */
value = strtol(ps, &pe, 10);
if (ps == pe)
{
logger(Core, Error, "invalid geometry, expected an integer for Y position");
return -1;
}
g_pos |= (value < 0) ? 4 : 1;
g_ypos = value;
ps = pe;
}
if (*pe != '\0')
{
logger(Core, Error, "invalid geometry, unexpected characters at end of string");
return -1;
}
return 0;
}
static void
setup_user_requested_session_size()
{
switch(g_window_size_type)
{
case Fullscreen:
ui_get_screen_size(&g_requested_session_width, &g_requested_session_height);
break;
case Workarea:
ui_get_workarea_size(&g_requested_session_width, &g_requested_session_height);
break;
case Fixed:
break;
case PercentageOfScreen:
ui_get_screen_size_from_percentage(g_requested_session_width,
g_requested_session_height,
&g_requested_session_width,
&g_requested_session_height);
break;
}
}
/* Client program */ /* Client program */
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
@ -709,70 +872,14 @@ main(int argc, char *argv[])
case 'g': case 'g':
geometry_option = True; geometry_option = True;
g_fullscreen = False; g_fullscreen = False;
if (!strcmp(optarg, "workarea")) if (parse_geometry_string(optarg) != 0)
{ {
g_sizeopt = 1;
break;
}
g_initial_width = strtol(optarg, &p, 10);
if (g_initial_width <= 0)
{
logger(Core, Error, "invalid geometry width specified");
return EX_USAGE; return EX_USAGE;
} }
if (*p == 'x')
g_initial_height = strtol(p + 1, &p, 10);
if (g_initial_height <= 0)
{
logger(Core, Error, "invalid geometry height specified");
return EX_USAGE;
}
if (*p == '%')
{
g_sizeopt = -g_initial_width;
g_initial_width = g_sizeopt;
if (*(p + 1) == 'x')
{
g_initial_height = -strtol(p + 2, &p, 10);
}
else
{
g_initial_height = g_sizeopt;
}
p++;
}
if (*p == '@')
{
g_dpi = strtol(p + 1, &p, 10);
if (g_dpi <= 0)
{
logger(Core, Error, "invalid DPI: expected a positive integer after @\n");
return EX_USAGE;
}
}
if (*p == '+' || *p == '-')
{
g_pos |= (*p == '-') ? 2 : 1;
g_xpos = strtol(p, &p, 10);
}
if (*p == '+' || *p == '-')
{
g_pos |= (*p == '-') ? 4 : 1;
g_ypos = strtol(p, NULL, 10);
}
break; break;
case 'f': case 'f':
g_window_size_type = Fullscreen;
g_fullscreen = True; g_fullscreen = True;
break; break;
@ -1097,7 +1204,8 @@ main(int argc, char *argv[])
logger(Core, Error, "You cannot use -4 and -A at the same time"); logger(Core, Error, "You cannot use -4 and -A at the same time");
return EX_USAGE; return EX_USAGE;
} }
g_sizeopt = -100;
g_window_size_type = Fullscreen;
g_grab_keyboard = False; g_grab_keyboard = False;
} }
@ -1216,6 +1324,8 @@ main(int argc, char *argv[])
dvc_init(); dvc_init();
rdpedisp_init(); rdpedisp_init();
setup_user_requested_session_size();
g_reconnect_loop = False; g_reconnect_loop = False;
while (1) while (1)
{ {
@ -1239,8 +1349,7 @@ main(int argc, char *argv[])
g_network_error = False; g_network_error = False;
} }
ui_init_connection(); utils_apply_session_size_limitations(&g_requested_session_width, &g_requested_session_height);
utils_apply_session_size_limitations(&g_initial_width, &g_initial_height);
if (!rdp_connect if (!rdp_connect
(server, flags, domain, g_password, shell, directory, g_reconnect_loop)) (server, flags, domain, g_password, shell, directory, g_reconnect_loop))
@ -1310,7 +1419,7 @@ main(int argc, char *argv[])
if (g_pending_resize) if (g_pending_resize)
{ {
logger(Core, Verbose, "Resize reconnect loop triggered, new size %dx%d", logger(Core, Verbose, "Resize reconnect loop triggered, new size %dx%d",
g_initial_width, g_initial_height); g_requested_session_width, g_requested_session_height);
g_pending_resize = False; g_pending_resize = False;
g_reconnect_loop = True; g_reconnect_loop = True;
continue; continue;
@ -1843,7 +1952,7 @@ rd_create_ui()
if (!ui_have_window()) if (!ui_have_window())
{ {
/* create a window if we don't have one initialized */ /* create a window if we don't have one initialized */
if (!ui_create_window(g_initial_width, g_initial_height)) if (!ui_create_window(g_requested_session_width, g_requested_session_height))
exit(EX_OSERR); exit(EX_OSERR);
} }
else else

4
rdp.c
View File

@ -43,8 +43,8 @@ extern RDP_VERSION g_rdp_version;
extern uint16 g_server_rdp_version; extern uint16 g_server_rdp_version;
extern uint32 g_rdp5_performanceflags; extern uint32 g_rdp5_performanceflags;
extern int g_server_depth; extern int g_server_depth;
extern uint32 g_initial_width; extern uint32 g_requested_session_width;
extern uint32 g_initial_height; extern uint32 g_requested_session_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;

View File

@ -23,8 +23,8 @@
#include "ssl.h" #include "ssl.h"
extern char g_hostname[16]; extern char g_hostname[16];
extern uint32 g_initial_width; extern uint32 g_requested_session_width;
extern uint32 g_initial_height; extern uint32 g_requested_session_height;
extern int g_dpi; extern int g_dpi;
extern unsigned int g_keylayout; extern unsigned int g_keylayout;
extern int g_keyboard_type; extern int g_keyboard_type;
@ -426,8 +426,8 @@ sec_out_mcs_connect_initial_pdu(STREAM s, uint32 selected_protocol)
out_uint16_le(s, CS_CORE); /* type */ out_uint16_le(s, CS_CORE); /* type */
out_uint16_le(s, 216 + (g_dpi > 0 ? 18 : 0)); /* length */ out_uint16_le(s, 216 + (g_dpi > 0 ? 18 : 0)); /* length */
out_uint32_le(s, rdpversion); /* version */ out_uint32_le(s, rdpversion); /* version */
out_uint16_le(s, g_initial_width); /* desktopWidth */ out_uint16_le(s, g_requested_session_width); /* desktopWidth */
out_uint16_le(s, g_initial_height); /* desktopHeight */ out_uint16_le(s, g_requested_session_height); /* desktopHeight */
out_uint16_le(s, RNS_UD_COLOR_8BPP); /* colorDepth */ out_uint16_le(s, RNS_UD_COLOR_8BPP); /* colorDepth */
out_uint16_le(s, RNS_UD_SAS_DEL); /* SASSequence */ out_uint16_le(s, RNS_UD_SAS_DEL); /* SASSequence */
out_uint32_le(s, g_keylayout); /* keyboardLayout */ out_uint32_le(s, g_keylayout); /* keyboardLayout */
@ -459,7 +459,7 @@ sec_out_mcs_connect_initial_pdu(STREAM s, uint32 selected_protocol)
if (g_dpi > 0) if (g_dpi > 0)
{ {
/* Extended client info describing monitor geometry */ /* Extended client info describing monitor geometry */
utils_calculate_dpi_scale_factors(g_initial_width, g_initial_height, g_dpi, utils_calculate_dpi_scale_factors(g_requested_session_width, g_requested_session_height, g_dpi,
&physwidth, &physheight, &physwidth, &physheight,
&desktopscale, &devicescale); &desktopscale, &devicescale);
out_uint32_le(s, physwidth); /* physicalwidth */ out_uint32_le(s, physwidth); /* physicalwidth */

View File

@ -2,7 +2,7 @@ CC=gcc
CFLAGS=-fPIC -Wall -Wextra -ggdb -gdwarf-2 -g3 CFLAGS=-fPIC -Wall -Wextra -ggdb -gdwarf-2 -g3
CGREEN_RUNNER=cgreen-runner CGREEN_RUNNER=cgreen-runner
TESTS=resize rdp xwin utils TESTS=resize rdp xwin utils parse_geometry
RDP_MOCKS=ui_mock.o bitmap_mock.o secure_mock.o ssl_mock.o mppc_mock.o \ RDP_MOCKS=ui_mock.o bitmap_mock.o secure_mock.o ssl_mock.o mppc_mock.o \
@ -19,6 +19,9 @@ RESIZE_MOCKS=x11_mock.o cache_mock.o xclip_mock.o xkeymap_mock.o seamless_mock.o
ssl_mock.o mppc_mock.o pstcache_mock.o orders_mock.o rdesktop_mock.o rdp5_mock.o \ ssl_mock.o mppc_mock.o pstcache_mock.o orders_mock.o rdesktop_mock.o rdp5_mock.o \
tcp_mock.o licence_mock.o mcs_mock.o channels_mock.o tcp_mock.o licence_mock.o mcs_mock.o channels_mock.o
PARSE_MOCKS=ui_mock.o rdpdr_mock.o rdpedisp_mock.o ssl_mock.o ctrl_mock.o secure_mock.o \
tcp_mock.o dvc_mock.o rdp_mock.o cache_mock.o cliprdr_mock.o disk_mock.o lspci_mock.o \
parallel_mock.o printer_mock.o serial_mock.o xkeymap_mock.o utils_mock.o xwin_mock.o
all: test all: test
@ -43,6 +46,8 @@ utils: utils_test.o $(UTILS_MOCKS)
resize: resize_test.o $(RESIZE_MOCKS) resize: resize_test.o $(RESIZE_MOCKS)
$(CC) $(CFLAGS) -shared -lcgreen -o $@ $^ -lX11 -lXcursor $(CC) $(CFLAGS) -shared -lcgreen -o $@ $^ -lX11 -lXcursor
parse_geometry: parse_geometry_test.o $(PARSE_MOCKS) ../rdesktop.c
$(CC) $(CFLAGS) -shared -lcgreen -o $@ parse_geometry_test.o $(PARSE_MOCKS)
.PHONY: clean .PHONY: clean
clean: clean:

View File

@ -44,3 +44,9 @@ cache_put_desktop(uint32 offset, int cx, int cy, int scanline,
{ {
mock(offset, cx, cy, scanline, bytes_per_pixel, data); mock(offset, cx, cy, scanline, bytes_per_pixel, data);
} }
void
cache_save_state()
{
mock();
}

8
tests/cliprdr_mock.c Normal file
View File

@ -0,0 +1,8 @@
#include <cgreen/mocks.h>
#include "../rdesktop.h"
void
cliprdr_set_mode(const char *optarg)
{
mock(optarg);
}

View File

@ -12,3 +12,21 @@ ctrl_check_fds(fd_set * rfds, fd_set * wfds)
{ {
mock(rfds, wfds); mock(rfds, wfds);
} }
int
ctrl_init(const char *user, const char *domain, const char *host)
{
return mock(user, domain, host);
}
RD_BOOL
ctrl_is_slave()
{
return mock();
}
int
ctrl_send_command(const char *cmd, const char *args)
{
return mock(cmd, args);
}

8
tests/disk_mock.c Normal file
View File

@ -0,0 +1,8 @@
#include <cgreen/mocks.h>
#include "../rdesktop.h"
int
disk_enum_devices(uint32 *id, char *optarg)
{
return mock(id, optarg);
}

9
tests/lspci_mock.c Normal file
View File

@ -0,0 +1,9 @@
#include <cgreen/mocks.h>
#include "../rdesktop.h"
RD_BOOL
lspci_init(void)
{
return mock();
}

8
tests/parallel_mock.c Normal file
View File

@ -0,0 +1,8 @@
#include <cgreen/mocks.h>
#include "../rdesktop.h"
int
parallel_enum_devices(uint32 * id, char *optarg)
{
return mock(id, optarg);
}

229
tests/parse_geometry_test.c Normal file
View File

@ -0,0 +1,229 @@
#include <cgreen/cgreen.h>
#include <cgreen/mocks.h>
#include "../rdesktop.h"
#include "../proto.h"
#include <locale.h>
#include <langinfo.h>
#define always_expect_error_log() always_expect(logger, when(lvl, is_equal_to(Error)))
/* Boilerplate */
Describe(ParseGeometry);
BeforeEach(ParseGeometry) {};
AfterEach(ParseGeometry) {};
/* Global Variables.. :( */
int g_tcp_port_rdp;
RDPDR_DEVICE g_rdpdr_device[16];
uint32 g_num_devices;
char *g_rdpdr_clientname;
RD_BOOL g_using_full_workarea;
#define PACKAGE_VERSION "test"
#include "../rdesktop.c"
Ensure(ParseGeometry, HandlesWxH)
{
g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("1234x2345"), is_equal_to(0));
assert_that(g_requested_session_width, is_equal_to(1234));
assert_that(g_requested_session_height, is_equal_to(2345));
assert_that(g_window_size_type, is_equal_to(Fixed));
}
Ensure(ParseGeometry, FailsOnMissingHeight)
{
always_expect_error_log();
g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("1234"), is_equal_to(-1));
assert_that(g_requested_session_width, is_equal_to(1234));
assert_that(g_requested_session_height, is_equal_to(0));
assert_that(g_window_size_type, is_equal_to(Fixed));
}
Ensure(ParseGeometry, FailsOnMissingHeightVariant2)
{
always_expect_error_log();
g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("1234x"), is_equal_to(-1));
assert_that(g_requested_session_width, is_equal_to(1234));
assert_that(g_requested_session_height, is_equal_to(0));
assert_that(g_window_size_type, is_equal_to(Fixed));
}
Ensure(ParseGeometry, HandlesPercentageOfScreen)
{
g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("80%"), is_equal_to(0));
assert_that(g_requested_session_width, is_equal_to(80));
assert_that(g_requested_session_height, is_equal_to(80));
assert_that(g_window_size_type, is_equal_to(PercentageOfScreen));
}
Ensure(ParseGeometry, HandlesSpecificWidthAndHeightPercentageOfScreen)
{
g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("100%x60%"), is_equal_to(0));
assert_that(g_requested_session_width, is_equal_to(100));
assert_that(g_requested_session_height, is_equal_to(60));
assert_that(g_window_size_type, is_equal_to(PercentageOfScreen));
}
Ensure(ParseGeometry, HandlesSpecifiedDPI)
{
g_dpi = g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("1234x2345@234"), is_equal_to(0));
assert_that(g_dpi, is_equal_to(234));
assert_that(g_requested_session_width, is_equal_to(1234));
assert_that(g_requested_session_height, is_equal_to(2345));
assert_that(g_window_size_type, is_equal_to(Fixed));
}
Ensure(ParseGeometry, HandlesSpecifiedXPosition)
{
g_xpos = g_ypos = g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("1234x2345+123"), is_equal_to(0));
assert_that(g_xpos, is_equal_to(123));
assert_that(g_ypos, is_equal_to(0));
assert_that(g_pos, is_equal_to(1));
assert_that(g_requested_session_width, is_equal_to(1234));
assert_that(g_requested_session_height, is_equal_to(2345));
assert_that(g_window_size_type, is_equal_to(Fixed));
}
Ensure(ParseGeometry, HandlesSpecifiedNegativeXPosition)
{
g_ypos = g_xpos = g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("1234x2345-500"), is_equal_to(0));
assert_that(g_xpos, is_equal_to(-500));
assert_that(g_ypos, is_equal_to(0));
assert_that(g_pos, is_equal_to(2));
assert_that(g_requested_session_width, is_equal_to(1234));
assert_that(g_requested_session_height, is_equal_to(2345));
assert_that(g_window_size_type, is_equal_to(Fixed));
}
Ensure(ParseGeometry, HandlesSpecifiedNegativeXAndYPosition)
{
g_ypos = g_xpos = g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("1234x2345-500-501"), is_equal_to(0));
assert_that(g_xpos, is_equal_to(-500));
assert_that(g_ypos, is_equal_to(-501));
assert_that(g_pos, is_equal_to(2 | 4));
assert_that(g_requested_session_width, is_equal_to(1234));
assert_that(g_requested_session_height, is_equal_to(2345));
assert_that(g_window_size_type, is_equal_to(Fixed));
}
Ensure(ParseGeometry, HandlesSpecifiedXandYPosition)
{
g_xpos = g_ypos = g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("1234x2345+123+234"), is_equal_to(0));
assert_that(g_xpos, is_equal_to(123));
assert_that(g_ypos, is_equal_to(234));
assert_that(g_pos, is_equal_to(1));
assert_that(g_requested_session_width, is_equal_to(1234));
assert_that(g_requested_session_height, is_equal_to(2345));
assert_that(g_window_size_type, is_equal_to(Fixed));
}
Ensure(ParseGeometry, HandlesSpecifiedXandYPositionWithDPI)
{
g_dpi = g_xpos = g_ypos = g_requested_session_width = g_requested_session_height = 0;
assert_that(parse_geometry_string("1234x2345@678+123+234"), is_equal_to(0));
assert_that(g_dpi, is_equal_to(678));
assert_that(g_xpos, is_equal_to(123));
assert_that(g_ypos, is_equal_to(234));
assert_that(g_requested_session_width, is_equal_to(1234));
assert_that(g_requested_session_height, is_equal_to(2345));
assert_that(g_window_size_type, is_equal_to(Fixed));
}
Ensure(ParseGeometry, HandlesSpecialNameWorkarea)
{
assert_that(parse_geometry_string("workarea"), is_equal_to(0));
assert_that(g_window_size_type, is_equal_to(Workarea));
}
Ensure(ParseGeometry, FailsOnNegativeDPI)
{
always_expect_error_log();
assert_that(parse_geometry_string("1234x2345@-105"), is_equal_to(-1));
}
Ensure(ParseGeometry, FailsOnNegativeWidth)
{
always_expect_error_log();
assert_that(parse_geometry_string("-1234x2345"), is_equal_to(-1));
}
Ensure(ParseGeometry, FailsOnNegativeHeight)
{
always_expect_error_log();
assert_that(parse_geometry_string("1234x-2345"), is_equal_to(-1));
}
Ensure(ParseGeometry, FailsOnMixingPixelsAndPercents)
{
always_expect_error_log();
g_window_size_type = Fixed;
assert_that(parse_geometry_string("1234%x2345"), is_equal_to(-1));
g_window_size_type = Fixed;
assert_that(parse_geometry_string("1234x2345%"), is_equal_to(-1));
}
Ensure(ParseGeometry, FailsOnGarbageAtEndOfString)
{
always_expect_error_log();
g_window_size_type = Fixed;
assert_that(parse_geometry_string("1234%1239123081232345abcdefgadkfjafa4af048"), is_equal_to(-1));
g_window_size_type = Fixed;
assert_that(parse_geometry_string("1235abcer9823461"), is_equal_to(-1));
g_window_size_type = Fixed;
assert_that(parse_geometry_string("1235%x123%+123123+123123asdkjfasdf"), is_equal_to(-1));
g_window_size_type = Fixed;
assert_that(parse_geometry_string("1235%x123%@123asdkjfasdf"), is_equal_to(-1));
g_window_size_type = Fixed;
assert_that(parse_geometry_string("1235%x123%@123+1-2asdkjfasdf"), is_equal_to(-1));
}

8
tests/printer_mock.c Normal file
View File

@ -0,0 +1,8 @@
#include <cgreen/mocks.h>
#include "../rdesktop.h"
int
printer_enum_devices(uint32 * id, char *optarg)
{
return mock(id, optarg);
}

View File

@ -13,3 +13,27 @@ rdp_send_suppress_output_pdu(enum RDP_SUPPRESS_STATUS allowupdates)
mock(allowupdates); mock(allowupdates);
} }
RD_BOOL
rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory, RD_BOOL reconnect)
{
return mock(server, flags, domain, password, command, directory, reconnect);
}
void
rdp_disconnect()
{
mock();
}
void
rdp_main_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
{
mock(deactivated, ext_disc_reason);
}
void
rdp_reset_state()
{
mock();
}

View File

@ -21,8 +21,6 @@ RDP_VERSION g_rdp_version;
uint16 g_server_rdp_version; uint16 g_server_rdp_version;
uint32 g_rdp5_performanceflags; uint32 g_rdp5_performanceflags;
int g_server_depth; int g_server_depth;
uint32 g_initial_width;
uint32 g_initial_height;
RD_BOOL g_bitmap_cache; RD_BOOL g_bitmap_cache;
RD_BOOL g_bitmap_cache_persist_enable; RD_BOOL g_bitmap_cache_persist_enable;
RD_BOOL g_numlock_sync; RD_BOOL g_numlock_sync;

View File

@ -12,3 +12,9 @@ rdpdr_check_fds(fd_set * rfds, fd_set * wfds, RD_BOOL timed_out)
{ {
mock(rfds, wfds, timed_out); mock(rfds, wfds, timed_out);
} }
RD_BOOL
rdpdr_init()
{
return mock();
}

View File

@ -1,6 +1,12 @@
#include <cgreen/mocks.h> #include <cgreen/mocks.h>
#include "../rdesktop.h" #include "../rdesktop.h"
void
rdpedisp_init()
{
mock();
}
RD_BOOL RD_BOOL
rdpedisp_is_available() rdpedisp_is_available()
{ {

View File

@ -11,9 +11,9 @@ AfterEach(Resize) {};
/* globals driven by xwin.c */ /* globals driven by xwin.c */
RD_BOOL g_user_quit; RD_BOOL g_user_quit;
RD_BOOL g_exit_mainloop; RD_BOOL g_exit_mainloop;
int g_sizeopt; uint32 g_requested_session_width;
uint32 g_initial_width; uint32 g_requested_session_height;
uint32 g_initial_height; window_size_type_t g_window_size_type;
uint16 g_session_width; uint16 g_session_width;
uint16 g_session_height; uint16 g_session_height;
int g_xpos; int g_xpos;
@ -56,8 +56,8 @@ RDP_VERSION g_rdp_version;
uint16 g_server_rdp_version; uint16 g_server_rdp_version;
uint32 g_rdp5_performanceflags; uint32 g_rdp5_performanceflags;
int g_server_depth; int g_server_depth;
uint32 g_initial_width; uint32 g_requested_session_width;
uint32 g_initial_height; uint32 g_requested_session_height;
RD_BOOL g_bitmap_cache; RD_BOOL g_bitmap_cache;
RD_BOOL g_bitmap_cache_persist_enable; RD_BOOL g_bitmap_cache_persist_enable;
RD_BOOL g_numlock_sync; RD_BOOL g_numlock_sync;
@ -87,8 +87,8 @@ RD_BOOL g_local_cursor;
/* globals from secure.c */ /* globals from secure.c */
char g_hostname[16]; char g_hostname[16];
uint32 g_initial_width; uint32 g_requested_session_width;
uint32 g_initial_height; uint32 g_requested_session_height;
int g_dpi; int g_dpi;
unsigned int g_keylayout; unsigned int g_keylayout;
int g_keyboard_type; int g_keyboard_type;

View File

@ -30,3 +30,15 @@ void sec_send(STREAM s, uint32 flags)
{ {
mock(s, flags); mock(s, flags);
} }
void
sec_hash_sha1_16(uint8 * out, uint8 * in, uint8 * salt1)
{
mock(out, in, salt1);
}
void
sec_hash_to_string(char *out, int out_size, uint8 * in, int in_size)
{
mock(out, out_size, in, in_size);
}

8
tests/serial_mock.c Normal file
View File

@ -0,0 +1,8 @@
#include <cgreen/mocks.h>
#include "../rdesktop.h"
int
serial_enum_devices(uint32 * id, char *optarg)
{
return mock(id, optarg);
}

View File

@ -5,3 +5,9 @@ char *tcp_get_address()
{ {
return (char *) mock(); return (char *) mock();
} }
void
tcp_run_ui(RD_BOOL run)
{
mock(run);
}

View File

@ -70,3 +70,51 @@ void ui_set_clip(int x,int y, int cx, int cy)
{ {
mock(x,y,cx,cy); mock(x,y,cx,cy);
} }
RD_BOOL
ui_create_window(uint32 width, uint32 height)
{
return mock(width, height);
}
void
ui_deinit()
{
mock();
}
void
ui_destroy_window()
{
mock();
}
void
ui_init_connection()
{
mock();
}
RD_BOOL
ui_have_window()
{
return mock();
}
RD_BOOL
ui_init()
{
return mock();
}
void
ui_reset_clip()
{
mock();
}
void
ui_seamless_end()
{
mock();
}

19
tests/utils_mock.c Normal file
View File

@ -0,0 +1,19 @@
#include <cgreen/cgreen.h>
#include <cgreen/mocks.h>
#include "../rdesktop.h"
uint32 utils_djb2_hash(const char *str) { return mock(str); }
char *utils_string_escape(const char *str) { return (char *)mock(str); }
char *utils_string_unescape(const char *str) { return (char *)mock(str); }
int utils_locale_to_utf8(const char *src, size_t is, char *dest, size_t os) { return mock(src, is, dest, os); }
int utils_mkdir_safe(const char *path, int mask) { return mock(path, mask); }
int utils_mkdir_p(const char *path, int mask) { return mock(path, mask); }
void utils_calculate_dpi_scale_factors(uint32 width, uint32 height, uint32 dpi,
uint32 *physwidth, uint32 *physheight,
uint32 *desktopscale, uint32 *devicescale) { mock(width, height, dpi, physwidth, physheight, desktopscale, devicescale); }
void utils_apply_session_size_limitations(uint32 *width, uint32 *height) { mock(width, height); }
void logger(log_subject_t c, log_level_t lvl, char *format, ...) { mock(c, lvl, format); }
void logger_set_verbose(int verbose) { mock(verbose); }
void logger_set_subjects(char *subjects) { mock(subjects); }

View File

@ -61,3 +61,9 @@ uint16 ui_get_numlock_state(unsigned int state)
{ {
return mock(state); return mock(state);
} }
RD_BOOL
xkeymap_from_locale(const char *locale)
{
return mock(locale);
}

17
tests/xwin_mock.c Normal file
View File

@ -0,0 +1,17 @@
#include <cgreen/mocks.h>
#include "../rdesktop.h"
void ui_get_screen_size(uint32 *width, uint32 *height)
{
mock(width, height);
}
void ui_get_screen_size_from_percentage(uint32 pw, uint32 ph, uint32 *width, uint32 *height)
{
mock(pw, ph, width, height);
}
void ui_get_workarea_size(uint32 *width, uint32 *height)
{
mock(width, height);
}

View File

@ -17,9 +17,9 @@ AfterEach(XWIN) {};
RD_BOOL g_user_quit; RD_BOOL g_user_quit;
RD_BOOL g_exit_mainloop; RD_BOOL g_exit_mainloop;
int g_sizeopt; uint32 g_requested_session_width;
uint32 g_initial_width; uint32 g_requested_session_height;
uint32 g_initial_height; window_size_type_t g_window_size_type;
uint16 g_session_width; uint16 g_session_width;
uint16 g_session_height; uint16 g_session_height;
int g_xpos; int g_xpos;

View File

@ -308,4 +308,11 @@ FILEINFO;
typedef RD_BOOL(*str_handle_lines_t) (const char *line, void *data); typedef RD_BOOL(*str_handle_lines_t) (const char *line, void *data);
typedef enum {
Fixed,
PercentageOfScreen,
Workarea,
Fullscreen,
} window_size_type_t;
#endif /* _TYPES_H */ #endif /* _TYPES_H */

89
xwin.c
View File

@ -45,9 +45,9 @@
extern RD_BOOL g_user_quit; extern RD_BOOL g_user_quit;
extern RD_BOOL g_exit_mainloop; extern RD_BOOL g_exit_mainloop;
extern int g_sizeopt; extern window_size_type_t g_window_size_type;
extern uint32 g_initial_width; extern uint32 g_requested_session_width;
extern uint32 g_initial_height; extern uint32 g_requested_session_height;
extern uint16 g_session_width; extern uint16 g_session_width;
extern uint16 g_session_height; extern uint16 g_session_height;
extern int g_xpos; extern int g_xpos;
@ -1961,54 +1961,37 @@ ui_init(void)
return True; return True;
} }
/*
Initialize connection specific data, such as initial session size.
*/
void void
ui_init_connection(void) ui_get_screen_size(uint32 *width, uint32 *height)
{ {
/* *width = WidthOfScreen(g_screen);
* Determine desktop size *height = HeightOfScreen(g_screen);
*/
if (g_fullscreen)
{
g_initial_width = WidthOfScreen(g_screen);
g_initial_height = HeightOfScreen(g_screen);
g_using_full_workarea = True;
} }
else if (g_sizeopt < 0)
void
ui_get_screen_size_from_percentage(uint32 pw, uint32 ph, uint32 *width, uint32 *height)
{ {
/* Percent of screen */ uint32 sw,sh;
if (-g_sizeopt >= 100) ui_get_screen_size(&sw, &sh);
g_using_full_workarea = True; *width = sw * pw / 100;
*height = sh * ph / 100;
if (g_initial_width > 0)
g_initial_width = g_sizeopt;
if (g_initial_height > 0)
g_initial_height = g_sizeopt;
g_initial_height = HeightOfScreen(g_screen) * (-g_initial_height) / 100;
g_initial_width = WidthOfScreen(g_screen) * (-g_initial_width) / 100;
} }
else if (g_sizeopt == 1)
void
ui_get_workarea_size(uint32 *width, uint32 *height)
{ {
/* Fetch geometry from _NET_WORKAREA */ uint32 x, y, w, h;
uint32 x, y, cx, cy; if (get_current_workarea(&x, &y, &w, &h) == 0)
if (get_current_workarea(&x, &y, &cx, &cy) == 0)
{ {
g_initial_width = cx; *width = w;
g_initial_height = cy; *height = h;
g_using_full_workarea = True; g_using_full_workarea = True;
} }
else else
{ {
logger(GUI, Warning, logger(GUI, Warning,
"Failed to get workarea: probably your window manager does not support extended hints\n"); "Failed to get workarea: probably your window manager does not support extended hints, using full screensize as fallback\n");
g_initial_width = WidthOfScreen(g_screen); ui_get_screen_size(width, height);
g_initial_height = HeightOfScreen(g_screen);
}
} }
} }
@ -2304,8 +2287,6 @@ xwin_toggle_fullscreen(void)
{ {
uint32 x, y, width, height; uint32 x, y, width, height;
XWindowAttributes attr; XWindowAttributes attr;
XSetWindowAttributes setattr;
unsigned long value_mask;
Pixmap contents = 0; Pixmap contents = 0;
Window unused; Window unused;
int dest_x, dest_y; int dest_x, dest_y;
@ -2364,20 +2345,18 @@ xwin_toggle_fullscreen(void)
} }
/* Resize rdesktop window using new size and window attributes */ /* Resize rdesktop window using new size and window attributes */
XUnmapWindow(g_display, g_wnd); g_xpos = x;
g_ypos = y;
XMoveResizeWindow(g_display, g_wnd, x, y, width, height); ui_destroy_window();
ui_create_window(width, height);
value_mask = get_window_attribs(&setattr);
XChangeWindowAttributes(g_display, g_wnd, value_mask, &setattr);
XMapWindow(g_display, g_wnd);
/* Change session size to match new window size */ /* Change session size to match new window size */
if (rdpedisp_is_available() == False) if (rdpedisp_is_available() == False)
{ {
/* Change session size using disconnect / reconnect mechanism */ /* Change session size using disconnect / reconnect mechanism */
g_pending_resize = True; g_pending_resize = True;
g_window_width = width;
g_window_height = height;
return; return;
} }
else else
@ -2836,7 +2815,9 @@ xwin_process_events(void)
if (xevent.xconfigure.window == DefaultRootWindow(g_display)) if (xevent.xconfigure.window == DefaultRootWindow(g_display))
{ {
/* only for fullscreen or x%-of-screen-sized windows */ /* only for fullscreen or x%-of-screen-sized windows */
if (g_sizeopt || g_fullscreen) if (g_window_size_type == PercentageOfScreen
|| g_window_size_type == Fullscreen
|| g_fullscreen)
{ {
if (xevent.xconfigure.width != WidthOfScreen(g_screen) if (xevent.xconfigure.width != WidthOfScreen(g_screen)
|| xevent.xconfigure.height != HeightOfScreen(g_screen)) || xevent.xconfigure.height != HeightOfScreen(g_screen))
@ -3034,12 +3015,12 @@ process_pending_resize ()
* server. * server.
*/ */
g_initial_width = g_window_width; g_requested_session_width = g_window_width;
g_initial_height = g_window_height; g_requested_session_height = g_window_height;
logger(GUI, Verbose, "Window resize detected, reconnecting to new size %dx%d", logger(GUI, Verbose, "Window resize detected, reconnecting to new size %dx%d",
g_initial_width, g_requested_session_width,
g_initial_height); g_requested_session_height);
return True; return True;
} }