From 7dfdd248ee1f247e887ba72b5a7449d6cfa29e83 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Wed, 7 Jul 2021 11:54:01 +0200 Subject: [PATCH] Monitor coordinates are exclusive (#7145) * Monitor coordinates are exclusive * Remove force override of shadow resolution. The client might ignore the server requested values, in that case retry --- channels/rdpgfx/client/rdpgfx_main.c | 2 +- server/shadow/X11/x11_shadow.c | 60 ++++++++++++++-------------- server/shadow/shadow_client.c | 7 ---- server/shadow/shadow_screen.c | 9 +++-- server/shadow/shadow_server.c | 13 +++--- 5 files changed, 42 insertions(+), 49 deletions(-) diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index 20c13d269..280d9a63a 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -1233,7 +1233,7 @@ static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ - if (Stream_GetRemainingLength(s) < (size_t)(pdu.destPtsCount * 4)) + if (Stream_GetRemainingLength(s) / 4ULL < pdu.destPtsCount) { WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); return ERROR_INVALID_DATA; diff --git a/server/shadow/X11/x11_shadow.c b/server/shadow/X11/x11_shadow.c index 154b65279..3a06f24ea 100644 --- a/server/shadow/X11/x11_shadow.c +++ b/server/shadow/X11/x11_shadow.c @@ -707,7 +707,6 @@ static int x11_shadow_blend_cursor(x11ShadowSubsystem* subsystem) static BOOL x11_shadow_check_resize(x11ShadowSubsystem* subsystem) { - MONITOR_DEF* virtualScreen; XWindowAttributes attr; XLockDisplay(subsystem->display); XGetWindowAttributes(subsystem->display, subsystem->root_window, &attr); @@ -715,16 +714,18 @@ static BOOL x11_shadow_check_resize(x11ShadowSubsystem* subsystem) if (attr.width != (INT64)subsystem->width || attr.height != (INT64)subsystem->height) { + MONITOR_DEF* virtualScreen = &(subsystem->common.virtualScreen); + /* Screen size changed. Refresh monitor definitions and trigger screen resize */ subsystem->common.numMonitors = x11_shadow_enum_monitors(subsystem->common.monitors, 16); shadow_screen_resize(subsystem->common.server->screen); subsystem->width = attr.width; subsystem->height = attr.height; - virtualScreen = &(subsystem->common.virtualScreen); + virtualScreen->left = 0; virtualScreen->top = 0; - virtualScreen->right = subsystem->width; - virtualScreen->bottom = subsystem->height; + virtualScreen->right = subsystem->width - 1; + virtualScreen->bottom = subsystem->height - 1; virtualScreen->flags = 1; return TRUE; } @@ -1156,12 +1157,10 @@ static int x11_shadow_xshm_init(x11ShadowSubsystem* subsystem) UINT32 x11_shadow_enum_monitors(MONITOR_DEF* monitors, UINT32 maxMonitors) { - int index; Display* display; int displayWidth; int displayHeight; int numMonitors = 0; - MONITOR_DEF* monitor; if (!getenv("DISPLAY")) setenv("DISPLAY", ":0", 1); @@ -1181,7 +1180,6 @@ UINT32 x11_shadow_enum_monitors(MONITOR_DEF* monitors, UINT32 maxMonitors) int major, minor; int xinerama_event; int xinerama_error; - XineramaScreenInfo* screen; XineramaScreenInfo* screens; if (XineramaQueryExtension(display, &xinerama_event, &xinerama_error) && @@ -1194,14 +1192,16 @@ UINT32 x11_shadow_enum_monitors(MONITOR_DEF* monitors, UINT32 maxMonitors) if (screens && (numMonitors > 0)) { + UINT32 index; for (index = 0; index < numMonitors; index++) { - screen = &screens[index]; - monitor = &monitors[index]; + MONITOR_DEF* monitor = &monitors[index]; + const XineramaScreenInfo* screen = &screens[index]; + monitor->left = screen->x_org; monitor->top = screen->y_org; - monitor->right = monitor->left + screen->width; - monitor->bottom = monitor->top + screen->height; + monitor->right = monitor->left + screen->width - 1; + monitor->bottom = monitor->top + screen->height - 1; monitor->flags = (index == 0) ? 1 : 0; } } @@ -1214,13 +1214,13 @@ UINT32 x11_shadow_enum_monitors(MONITOR_DEF* monitors, UINT32 maxMonitors) if (numMonitors < 1) { - index = 0; + MONITOR_DEF* monitor = &monitors[0]; numMonitors = 1; - monitor = &monitors[index]; + monitor->left = 0; monitor->top = 0; - monitor->right = displayWidth; - monitor->bottom = displayHeight; + monitor->right = displayWidth - 1; + monitor->bottom = displayHeight - 1; monitor->flags = 1; } @@ -1240,7 +1240,7 @@ static int x11_shadow_subsystem_init(rdpShadowSubsystem* sub) XVisualInfo template; XPixmapFormatValues* pf; XPixmapFormatValues* pfs; - MONITOR_DEF* virtualScreen; + x11ShadowSubsystem* subsystem = (x11ShadowSubsystem*)sub; if (!subsystem) @@ -1355,19 +1355,21 @@ static int x11_shadow_subsystem_init(rdpShadowSubsystem* sub) CreateFileDescriptorEvent(NULL, FALSE, FALSE, subsystem->xfds, WINPR_FD_READ))) return -1; - virtualScreen = &(subsystem->common.virtualScreen); - virtualScreen->left = 0; - virtualScreen->top = 0; - WINPR_ASSERT(subsystem->width <= INT32_MAX); - WINPR_ASSERT(subsystem->height <= INT32_MAX); - virtualScreen->right = (INT32)subsystem->width; - virtualScreen->bottom = (INT32)subsystem->height; - virtualScreen->flags = 1; - WLog_INFO(TAG, - "X11 Extensions: XFixes: %" PRId32 " Xinerama: %" PRId32 " XDamage: %" PRId32 - " XShm: %" PRId32 "", - subsystem->use_xfixes, subsystem->use_xinerama, subsystem->use_xdamage, - subsystem->use_xshm); + { + MONITOR_DEF* virtualScreen = &(subsystem->common.virtualScreen); + virtualScreen->left = 0; + virtualScreen->top = 0; + WINPR_ASSERT(subsystem->width <= INT32_MAX); + WINPR_ASSERT(subsystem->height <= INT32_MAX); + virtualScreen->right = (INT32)subsystem->width - 1; + virtualScreen->bottom = (INT32)subsystem->height - 1; + virtualScreen->flags = 1; + WLog_INFO(TAG, + "X11 Extensions: XFixes: %" PRId32 " Xinerama: %" PRId32 " XDamage: %" PRId32 + " XShm: %" PRId32 "", + subsystem->use_xfixes, subsystem->use_xinerama, subsystem->use_xdamage, + subsystem->use_xshm); + } return 1; } diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index 759c05cbc..673b83bb9 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -361,11 +361,7 @@ static INLINE BOOL shadow_client_recalc_desktop_size(rdpShadowClient* client) WINPR_ASSERT(height >= 0); WINPR_ASSERT(height <= UINT16_MAX); if (settings->DesktopWidth != (UINT32)width || settings->DesktopHeight != (UINT32)height) - { - settings->DesktopWidth = (UINT16)width; - settings->DesktopHeight = (UINT16)height; return TRUE; - } return FALSE; } @@ -390,9 +386,6 @@ static BOOL shadow_client_capabilities(freerdp_peer* peer) if (!ret) WLog_WARN(TAG, "subsystem->ClientCapabilities failed"); - /* Recalculate desktop size regardless whether previous call fail - * or not. Make sure we send correct width/height to client */ - (void)shadow_client_recalc_desktop_size(client); return ret; } diff --git a/server/shadow/shadow_screen.c b/server/shadow/shadow_screen.c index d73219ea7..bd286251e 100644 --- a/server/shadow/shadow_screen.c +++ b/server/shadow/shadow_screen.c @@ -51,12 +51,13 @@ rdpShadowScreen* shadow_screen_new(rdpShadowServer* server) region16_init(&(screen->invalidRegion)); + WINPR_ASSERT(subsystem->selectedMonitor < ARRAYSIZE(subsystem->monitors)); primary = &(subsystem->monitors[subsystem->selectedMonitor]); x = primary->left; y = primary->top; - width = primary->right - primary->left; - height = primary->bottom - primary->top; + width = primary->right - primary->left + 1; + height = primary->bottom - primary->top + 1; WINPR_ASSERT(x >= 0); WINPR_ASSERT(x <= UINT16_MAX); @@ -140,8 +141,8 @@ BOOL shadow_screen_resize(rdpShadowScreen* screen) x = primary->left; y = primary->top; - width = primary->right - primary->left; - height = primary->bottom - primary->top; + width = primary->right - primary->left + 1; + height = primary->bottom - primary->top + 1; WINPR_ASSERT(x >= 0); WINPR_ASSERT(x <= UINT16_MAX); diff --git a/server/shadow/shadow_server.c b/server/shadow/shadow_server.c index 135577815..57cfb77cd 100644 --- a/server/shadow/shadow_server.c +++ b/server/shadow/shadow_server.c @@ -407,7 +407,7 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a { UINT32 index; UINT32 numMonitors; - MONITOR_DEF monitors[16]; + MONITOR_DEF monitors[16] = { 0 }; numMonitors = shadow_enum_monitors(monitors, 16); if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) @@ -422,17 +422,14 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a } else { - int width, height; - MONITOR_DEF* monitor; - /* List monitors */ for (index = 0; index < numMonitors; index++) { - monitor = &monitors[index]; - width = monitor->right - monitor->left; - height = monitor->bottom - monitor->top; - WLog_INFO(TAG, " %s [%d] %dx%d\t+%" PRId32 "+%" PRId32 "", + const MONITOR_DEF* monitor = &monitors[index]; + const INT64 width = monitor->right - monitor->left + 1; + const INT64 height = monitor->bottom - monitor->top + 1; + WLog_INFO(TAG, " %s [%d] %" PRId64 "x%" PRId64 "\t+%" PRId32 "+%" PRId32 "", (monitor->flags == 1) ? "*" : " ", index, width, height, monitor->left, monitor->top); }