diff --git a/proto.h b/proto.h index addc6fd..7d54e93 100644 --- a/proto.h +++ b/proto.h @@ -257,7 +257,9 @@ void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode); /* xwin.c */ RD_BOOL get_key_state(unsigned int state, uint32 keysym); 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); RD_BOOL ui_create_window(uint32 width, uint32 height); void ui_resize_window(uint32 width, uint32 height); diff --git a/rdesktop.c b/rdesktop.c index 8ea0f6b..298b2b6 100644 --- a/rdesktop.c +++ b/rdesktop.c @@ -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_subtype = 0x0; /* 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 */ -/* 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 what size of session we want to have. Set to decent defaults. */ -uint32 g_initial_width = 1024; -uint32 g_initial_height = 768; +uint32 g_requested_session_width = 1024; +uint32 g_requested_session_height = 768; + +window_size_type_t g_window_size_type = Fixed; + int g_xpos = 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 */ int main(int argc, char *argv[]) @@ -709,70 +872,14 @@ main(int argc, char *argv[]) case 'g': geometry_option = True; 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; } - - 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; case 'f': + g_window_size_type = Fullscreen; g_fullscreen = True; break; @@ -1097,7 +1204,8 @@ main(int argc, char *argv[]) logger(Core, Error, "You cannot use -4 and -A at the same time"); return EX_USAGE; } - g_sizeopt = -100; + + g_window_size_type = Fullscreen; g_grab_keyboard = False; } @@ -1216,6 +1324,8 @@ main(int argc, char *argv[]) dvc_init(); rdpedisp_init(); + setup_user_requested_session_size(); + g_reconnect_loop = False; while (1) { @@ -1239,8 +1349,7 @@ main(int argc, char *argv[]) g_network_error = False; } - ui_init_connection(); - utils_apply_session_size_limitations(&g_initial_width, &g_initial_height); + utils_apply_session_size_limitations(&g_requested_session_width, &g_requested_session_height); if (!rdp_connect (server, flags, domain, g_password, shell, directory, g_reconnect_loop)) @@ -1310,7 +1419,7 @@ main(int argc, char *argv[]) if (g_pending_resize) { 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_reconnect_loop = True; continue; @@ -1843,7 +1952,7 @@ rd_create_ui() if (!ui_have_window()) { /* 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); } else diff --git a/rdp.c b/rdp.c index 13e9f95..54e51d9 100644 --- a/rdp.c +++ b/rdp.c @@ -43,8 +43,8 @@ extern RDP_VERSION g_rdp_version; extern uint16 g_server_rdp_version; extern uint32 g_rdp5_performanceflags; extern int g_server_depth; -extern uint32 g_initial_width; -extern uint32 g_initial_height; +extern uint32 g_requested_session_width; +extern uint32 g_requested_session_height; extern RD_BOOL g_bitmap_cache; extern RD_BOOL g_bitmap_cache_persist_enable; extern RD_BOOL g_numlock_sync; diff --git a/secure.c b/secure.c index d5b69b1..f416aba 100644 --- a/secure.c +++ b/secure.c @@ -23,8 +23,8 @@ #include "ssl.h" extern char g_hostname[16]; -extern uint32 g_initial_width; -extern uint32 g_initial_height; +extern uint32 g_requested_session_width; +extern uint32 g_requested_session_height; extern int g_dpi; extern unsigned int g_keylayout; 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, 216 + (g_dpi > 0 ? 18 : 0)); /* length */ out_uint32_le(s, rdpversion); /* version */ - out_uint16_le(s, g_initial_width); /* desktopWidth */ - out_uint16_le(s, g_initial_height); /* desktopHeight */ + out_uint16_le(s, g_requested_session_width); /* desktopWidth */ + out_uint16_le(s, g_requested_session_height); /* desktopHeight */ out_uint16_le(s, RNS_UD_COLOR_8BPP); /* colorDepth */ out_uint16_le(s, RNS_UD_SAS_DEL); /* SASSequence */ 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) { /* 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, &desktopscale, &devicescale); out_uint32_le(s, physwidth); /* physicalwidth */ diff --git a/tests/Makefile b/tests/Makefile index 8e52b47..f7b39c8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -2,7 +2,7 @@ CC=gcc CFLAGS=-fPIC -Wall -Wextra -ggdb -gdwarf-2 -g3 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 \ @@ -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 \ 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 @@ -43,6 +46,8 @@ utils: utils_test.o $(UTILS_MOCKS) resize: resize_test.o $(RESIZE_MOCKS) $(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 clean: diff --git a/tests/cache_mock.c b/tests/cache_mock.c index ba28194..dc46fdd 100644 --- a/tests/cache_mock.c +++ b/tests/cache_mock.c @@ -44,3 +44,9 @@ cache_put_desktop(uint32 offset, int cx, int cy, int scanline, { mock(offset, cx, cy, scanline, bytes_per_pixel, data); } + +void +cache_save_state() +{ + mock(); +} diff --git a/tests/cliprdr_mock.c b/tests/cliprdr_mock.c new file mode 100644 index 0000000..001f010 --- /dev/null +++ b/tests/cliprdr_mock.c @@ -0,0 +1,8 @@ +#include +#include "../rdesktop.h" + +void +cliprdr_set_mode(const char *optarg) +{ + mock(optarg); +} diff --git a/tests/ctrl_mock.c b/tests/ctrl_mock.c index 89e7684..8e326fc 100644 --- a/tests/ctrl_mock.c +++ b/tests/ctrl_mock.c @@ -12,3 +12,21 @@ ctrl_check_fds(fd_set * rfds, fd_set * 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); +} diff --git a/tests/disk_mock.c b/tests/disk_mock.c new file mode 100644 index 0000000..1a01120 --- /dev/null +++ b/tests/disk_mock.c @@ -0,0 +1,8 @@ +#include +#include "../rdesktop.h" + +int +disk_enum_devices(uint32 *id, char *optarg) +{ + return mock(id, optarg); +} diff --git a/tests/lspci_mock.c b/tests/lspci_mock.c new file mode 100644 index 0000000..19141fe --- /dev/null +++ b/tests/lspci_mock.c @@ -0,0 +1,9 @@ +#include +#include "../rdesktop.h" + + +RD_BOOL +lspci_init(void) +{ + return mock(); +} diff --git a/tests/parallel_mock.c b/tests/parallel_mock.c new file mode 100644 index 0000000..1072a05 --- /dev/null +++ b/tests/parallel_mock.c @@ -0,0 +1,8 @@ +#include +#include "../rdesktop.h" + +int +parallel_enum_devices(uint32 * id, char *optarg) +{ + return mock(id, optarg); +} diff --git a/tests/parse_geometry_test.c b/tests/parse_geometry_test.c new file mode 100644 index 0000000..1a28222 --- /dev/null +++ b/tests/parse_geometry_test.c @@ -0,0 +1,229 @@ +#include +#include +#include "../rdesktop.h" +#include "../proto.h" +#include +#include + +#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)); +} + diff --git a/tests/printer_mock.c b/tests/printer_mock.c new file mode 100644 index 0000000..f059536 --- /dev/null +++ b/tests/printer_mock.c @@ -0,0 +1,8 @@ +#include +#include "../rdesktop.h" + +int +printer_enum_devices(uint32 * id, char *optarg) +{ + return mock(id, optarg); +} diff --git a/tests/rdp_mock.c b/tests/rdp_mock.c index 45b0eec..14a5ef6 100644 --- a/tests/rdp_mock.c +++ b/tests/rdp_mock.c @@ -13,3 +13,27 @@ rdp_send_suppress_output_pdu(enum RDP_SUPPRESS_STATUS 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(); +} diff --git a/tests/rdp_test.c b/tests/rdp_test.c index 6ccdc87..22a5f1a 100644 --- a/tests/rdp_test.c +++ b/tests/rdp_test.c @@ -21,8 +21,6 @@ RDP_VERSION g_rdp_version; uint16 g_server_rdp_version; uint32 g_rdp5_performanceflags; int g_server_depth; -uint32 g_initial_width; -uint32 g_initial_height; RD_BOOL g_bitmap_cache; RD_BOOL g_bitmap_cache_persist_enable; RD_BOOL g_numlock_sync; diff --git a/tests/rdpdr_mock.c b/tests/rdpdr_mock.c index b73c743..43b1c45 100644 --- a/tests/rdpdr_mock.c +++ b/tests/rdpdr_mock.c @@ -12,3 +12,9 @@ rdpdr_check_fds(fd_set * rfds, fd_set * wfds, RD_BOOL timed_out) { mock(rfds, wfds, timed_out); } + +RD_BOOL +rdpdr_init() +{ + return mock(); +} diff --git a/tests/rdpedisp_mock.c b/tests/rdpedisp_mock.c index 6e52377..4033f24 100644 --- a/tests/rdpedisp_mock.c +++ b/tests/rdpedisp_mock.c @@ -1,6 +1,12 @@ #include #include "../rdesktop.h" +void +rdpedisp_init() +{ + mock(); +} + RD_BOOL rdpedisp_is_available() { diff --git a/tests/resize_test.c b/tests/resize_test.c index 6a12ef1..80da9b8 100644 --- a/tests/resize_test.c +++ b/tests/resize_test.c @@ -11,9 +11,9 @@ AfterEach(Resize) {}; /* globals driven by xwin.c */ RD_BOOL g_user_quit; RD_BOOL g_exit_mainloop; -int g_sizeopt; -uint32 g_initial_width; -uint32 g_initial_height; +uint32 g_requested_session_width; +uint32 g_requested_session_height; +window_size_type_t g_window_size_type; uint16 g_session_width; uint16 g_session_height; int g_xpos; @@ -56,8 +56,8 @@ RDP_VERSION g_rdp_version; uint16 g_server_rdp_version; uint32 g_rdp5_performanceflags; int g_server_depth; -uint32 g_initial_width; -uint32 g_initial_height; +uint32 g_requested_session_width; +uint32 g_requested_session_height; RD_BOOL g_bitmap_cache; RD_BOOL g_bitmap_cache_persist_enable; RD_BOOL g_numlock_sync; @@ -87,8 +87,8 @@ RD_BOOL g_local_cursor; /* globals from secure.c */ char g_hostname[16]; -uint32 g_initial_width; -uint32 g_initial_height; +uint32 g_requested_session_width; +uint32 g_requested_session_height; int g_dpi; unsigned int g_keylayout; int g_keyboard_type; diff --git a/tests/secure_mock.c b/tests/secure_mock.c index b219b16..8d19c7d 100644 --- a/tests/secure_mock.c +++ b/tests/secure_mock.c @@ -30,3 +30,15 @@ void sec_send(STREAM s, uint32 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); +} diff --git a/tests/serial_mock.c b/tests/serial_mock.c new file mode 100644 index 0000000..9a07ab8 --- /dev/null +++ b/tests/serial_mock.c @@ -0,0 +1,8 @@ +#include +#include "../rdesktop.h" + +int +serial_enum_devices(uint32 * id, char *optarg) +{ + return mock(id, optarg); +} diff --git a/tests/tcp_mock.c b/tests/tcp_mock.c index 49a101c..f35740b 100644 --- a/tests/tcp_mock.c +++ b/tests/tcp_mock.c @@ -5,3 +5,9 @@ char *tcp_get_address() { return (char *) mock(); } + +void +tcp_run_ui(RD_BOOL run) +{ + mock(run); +} diff --git a/tests/ui_mock.c b/tests/ui_mock.c index bb53320..0cb74b8 100644 --- a/tests/ui_mock.c +++ b/tests/ui_mock.c @@ -70,3 +70,51 @@ void ui_set_clip(int x,int y, int cx, int 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(); +} diff --git a/tests/utils_mock.c b/tests/utils_mock.c new file mode 100644 index 0000000..d79102e --- /dev/null +++ b/tests/utils_mock.c @@ -0,0 +1,19 @@ +#include +#include + +#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); } diff --git a/tests/xkeymap_mock.c b/tests/xkeymap_mock.c index e815721..f0db87e 100644 --- a/tests/xkeymap_mock.c +++ b/tests/xkeymap_mock.c @@ -61,3 +61,9 @@ uint16 ui_get_numlock_state(unsigned int state) { return mock(state); } + +RD_BOOL +xkeymap_from_locale(const char *locale) +{ + return mock(locale); +} diff --git a/tests/xwin_mock.c b/tests/xwin_mock.c new file mode 100644 index 0000000..6f84821 --- /dev/null +++ b/tests/xwin_mock.c @@ -0,0 +1,17 @@ +#include +#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); +} diff --git a/tests/xwin_test.c b/tests/xwin_test.c index de6a202..8dd1f3d 100644 --- a/tests/xwin_test.c +++ b/tests/xwin_test.c @@ -17,9 +17,9 @@ AfterEach(XWIN) {}; RD_BOOL g_user_quit; RD_BOOL g_exit_mainloop; -int g_sizeopt; -uint32 g_initial_width; -uint32 g_initial_height; +uint32 g_requested_session_width; +uint32 g_requested_session_height; +window_size_type_t g_window_size_type; uint16 g_session_width; uint16 g_session_height; int g_xpos; diff --git a/types.h b/types.h index f2d6aef..922af8a 100644 --- a/types.h +++ b/types.h @@ -308,4 +308,11 @@ FILEINFO; 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 */ diff --git a/xwin.c b/xwin.c index 474c774..c538ed9 100644 --- a/xwin.c +++ b/xwin.c @@ -45,9 +45,9 @@ extern RD_BOOL g_user_quit; extern RD_BOOL g_exit_mainloop; -extern int g_sizeopt; -extern uint32 g_initial_width; -extern uint32 g_initial_height; +extern window_size_type_t g_window_size_type; +extern uint32 g_requested_session_width; +extern uint32 g_requested_session_height; extern uint16 g_session_width; extern uint16 g_session_height; extern int g_xpos; @@ -1961,54 +1961,37 @@ ui_init(void) return True; } - -/* - Initialize connection specific data, such as initial session size. - */ void -ui_init_connection(void) +ui_get_screen_size(uint32 *width, uint32 *height) { - /* - * Determine desktop size - */ - if (g_fullscreen) + *width = WidthOfScreen(g_screen); + *height = HeightOfScreen(g_screen); +} + +void +ui_get_screen_size_from_percentage(uint32 pw, uint32 ph, uint32 *width, uint32 *height) +{ + uint32 sw,sh; + ui_get_screen_size(&sw, &sh); + *width = sw * pw / 100; + *height = sh * ph / 100; +} + +void +ui_get_workarea_size(uint32 *width, uint32 *height) +{ + uint32 x, y, w, h; + if (get_current_workarea(&x, &y, &w, &h) == 0) { - g_initial_width = WidthOfScreen(g_screen); - g_initial_height = HeightOfScreen(g_screen); + *width = w; + *height = h; g_using_full_workarea = True; } - else if (g_sizeopt < 0) + else { - /* Percent of screen */ - if (-g_sizeopt >= 100) - g_using_full_workarea = True; - - 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) - { - /* Fetch geometry from _NET_WORKAREA */ - uint32 x, y, cx, cy; - if (get_current_workarea(&x, &y, &cx, &cy) == 0) - { - g_initial_width = cx; - g_initial_height = cy; - g_using_full_workarea = True; - } - else - { - logger(GUI, Warning, - "Failed to get workarea: probably your window manager does not support extended hints\n"); - g_initial_width = WidthOfScreen(g_screen); - g_initial_height = HeightOfScreen(g_screen); - } + logger(GUI, Warning, + "Failed to get workarea: probably your window manager does not support extended hints, using full screensize as fallback\n"); + ui_get_screen_size(width, height); } } @@ -2304,8 +2287,6 @@ xwin_toggle_fullscreen(void) { uint32 x, y, width, height; XWindowAttributes attr; - XSetWindowAttributes setattr; - unsigned long value_mask; Pixmap contents = 0; Window unused; int dest_x, dest_y; @@ -2364,20 +2345,18 @@ xwin_toggle_fullscreen(void) } /* Resize rdesktop window using new size and window attributes */ - XUnmapWindow(g_display, g_wnd); - - XMoveResizeWindow(g_display, g_wnd, x, y, width, height); - - value_mask = get_window_attribs(&setattr); - XChangeWindowAttributes(g_display, g_wnd, value_mask, &setattr); - - XMapWindow(g_display, g_wnd); + g_xpos = x; + g_ypos = y; + ui_destroy_window(); + ui_create_window(width, height); /* Change session size to match new window size */ if (rdpedisp_is_available() == False) { /* Change session size using disconnect / reconnect mechanism */ g_pending_resize = True; + g_window_width = width; + g_window_height = height; return; } else @@ -2836,7 +2815,9 @@ xwin_process_events(void) if (xevent.xconfigure.window == DefaultRootWindow(g_display)) { /* 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) || xevent.xconfigure.height != HeightOfScreen(g_screen)) @@ -3034,12 +3015,12 @@ process_pending_resize () * server. */ - g_initial_width = g_window_width; - g_initial_height = g_window_height; + g_requested_session_width = g_window_width; + g_requested_session_height = g_window_height; logger(GUI, Verbose, "Window resize detected, reconnecting to new size %dx%d", - g_initial_width, - g_initial_height); + g_requested_session_width, + g_requested_session_height); return True; }