From 1bc110518d36e2fddf283e086ffa585017eb93aa Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 28 Nov 2022 08:39:08 +0100 Subject: [PATCH] [x11,rail] cleaned up rail drawing code The remote application drawing code was simplified --- client/X11/xf_client.c | 38 ++++++++++++++++- client/X11/xf_gfx.c | 11 ++--- client/X11/xf_rail.c | 94 +++++++++++++++++++++--------------------- client/X11/xf_rail.h | 8 ++-- 4 files changed, 92 insertions(+), 59 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index e0d416aea..1c88f9b56 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -830,9 +830,12 @@ void xf_unlock_x11_(xfContext* xfc, const char* fkt) static BOOL xf_get_pixmap_info(xfContext* xfc) { + int vi_count = 0; int pf_count = 0; + XVisualInfo* vis = NULL; + XVisualInfo tpl = { 0 }; XPixmapFormatValues* pfs = NULL; - + XWindowAttributes window_attributes = { 0 }; WINPR_ASSERT(xfc->display); pfs = XListPixmapFormats(xfc->display, &pf_count); @@ -855,6 +858,39 @@ static BOOL xf_get_pixmap_info(xfContext* xfc) } XFree(pfs); + + tpl.depth = xfc->depth; + tpl.class = TrueColor; + tpl.screen = xfc->screen_number; + + if (XGetWindowAttributes(xfc->display, RootWindowOfScreen(xfc->screen), &window_attributes) == + 0) + { + WLog_ERR(TAG, "XGetWindowAttributes failed"); + return FALSE; + } + + vis = XGetVisualInfo(xfc->display, VisualDepthMask | VisualClassMask | VisualScreenMask, &tpl, + &vi_count); + + if (!vis) + { + WLog_ERR(TAG, "XGetVisualInfo failed"); + return FALSE; + } + + for (int i = 0; i < vi_count; i++) + { + const XVisualInfo* vi = &vis[i]; + + if (vi->visual == window_attributes.visual) + { + break; + } + } + + XFree(vis); + if ((xfc->visual == NULL) || (xfc->scanline_pad == 0)) return FALSE; diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 9a4dc8c28..c1a583a07 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -69,10 +69,11 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface) for (x = 0; x < nbRects; x++) { - const UINT32 nXSrc = rects[x].left; - const UINT32 nYSrc = rects[x].top; - const UINT32 swidth = rects[x].right - nXSrc; - const UINT32 sheight = rects[x].bottom - nYSrc; + const RECTANGLE_16* rect = &rects[x]; + const UINT32 nXSrc = rect->left; + const UINT32 nYSrc = rect->top; + const UINT32 swidth = rect->right - nXSrc; + const UINT32 sheight = rect->bottom - nYSrc; const UINT32 nXDst = surfaceX + nXSrc * sx; const UINT32 nYDst = surfaceY + nYSrc * sy; const UINT32 dwidth = swidth * sx; @@ -91,7 +92,7 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface) XPutImage(xfc->display, xfc->primary, xfc->gc, surface->image, nXSrc, nYSrc, nXDst, nYDst, dwidth, dheight); xf_lock_x11(xfc); - xf_rail_paint(xfc, nXDst, nYDst, nXDst + dwidth, nYDst + dheight); + xf_rail_paint_surface(xfc, surface->gdi.windowId, rect); xf_unlock_x11(xfc); } else diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index d6da446eb..9b7a070f9 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -210,63 +210,61 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow) appWindow->local_move.state = LMS_TERMINATING; } -static void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion) +BOOL xf_rail_paint_surface(xfContext* xfc, UINT64 windowId, const RECTANGLE_16* rect) { - int index; - int count = 0; - RECTANGLE_16 updateRect; - RECTANGLE_16 windowRect; - ULONG_PTR* pKeys = NULL; - xfAppWindow* appWindow; - const RECTANGLE_16* extents; - REGION16 windowInvalidRegion; + xfAppWindow* appWindow = xf_rail_get_window(xfc, windowId); + + WINPR_ASSERT(rect); + + if (!appWindow) + return FALSE; + + const RECTANGLE_16 windowRect = { .left = MAX(appWindow->x, 0), + .top = MAX(appWindow->y, 0), + .right = MAX(appWindow->x + appWindow->width, 0), + .bottom = MAX(appWindow->y + appWindow->height, 0) }; + + REGION16 windowInvalidRegion = { 0 }; region16_init(&windowInvalidRegion); + region16_union_rect(&windowInvalidRegion, &windowInvalidRegion, &windowRect); + region16_intersect_rect(&windowInvalidRegion, &windowInvalidRegion, rect); + + if (!region16_is_empty(&windowInvalidRegion)) + { + const RECTANGLE_16* extents = region16_extents(&windowInvalidRegion); + const RECTANGLE_16 updateRect = { .left = extents->left - appWindow->x, + .top = extents->top - appWindow->y, + .right = extents->right - appWindow->x, + .bottom = extents->bottom - appWindow->y }; + + xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top, + updateRect.right - updateRect.left, updateRect.bottom - updateRect.top); + } + region16_uninit(&windowInvalidRegion); + return TRUE; +} + +BOOL xf_rail_paint(xfContext* xfc, const RECTANGLE_16* rect) +{ + BOOL rc = TRUE; + ULONG_PTR* pKeys = NULL; + size_t count = 0; + + WINPR_ASSERT(xfc); + WINPR_ASSERT(rect); + if (xfc->railWindows) count = HashTable_GetKeys(xfc->railWindows, &pKeys); - for (index = 0; index < count; index++) + for (size_t index = 0; index < count; index++) { - appWindow = xf_rail_get_window(xfc, *(UINT64*)pKeys[index]); - - if (appWindow) - { - windowRect.left = MAX(appWindow->x, 0); - windowRect.top = MAX(appWindow->y, 0); - windowRect.right = MAX(appWindow->x + appWindow->width, 0); - windowRect.bottom = MAX(appWindow->y + appWindow->height, 0); - region16_clear(&windowInvalidRegion); - region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect); - - if (!region16_is_empty(&windowInvalidRegion)) - { - extents = region16_extents(&windowInvalidRegion); - updateRect.left = extents->left - appWindow->x; - updateRect.top = extents->top - appWindow->y; - updateRect.right = extents->right - appWindow->x; - updateRect.bottom = extents->bottom - appWindow->y; - xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top, - updateRect.right - updateRect.left, - updateRect.bottom - updateRect.top); - } - } + const UINT64 key = *(UINT64*)pKeys[index]; + if (!xf_rail_paint_surface(xfc, key, rect)) + rc = FALSE; } free(pKeys); - region16_uninit(&windowInvalidRegion); -} - -void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom) -{ - REGION16 invalidRegion; - RECTANGLE_16 invalidRect; - invalidRect.left = uleft; - invalidRect.top = utop; - invalidRect.right = uright; - invalidRect.bottom = ubottom; - region16_init(&invalidRegion); - region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect); - xf_rail_invalidate_region(xfc, &invalidRegion); - region16_uninit(&invalidRegion); + return rc; } /* RemoteApp Core Protocol Extension */ diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h index c99ed7050..32b5f44c3 100644 --- a/client/X11/xf_rail.h +++ b/client/X11/xf_rail.h @@ -25,7 +25,9 @@ #include -void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom); +BOOL xf_rail_paint(xfContext* xfc, const RECTANGLE_16* rect); +BOOL xf_rail_paint_surface(xfContext* xfc, UINT64 windowId, const RECTANGLE_16* rect); + void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16 command); void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled); void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow); @@ -39,10 +41,6 @@ xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id); BOOL xf_rail_del_window(xfContext* xfc, UINT64 id); -BOOL xf_rail_draw_window(xfContext* xfc, xfAppWindow* window, const char* data, UINT32 scanline, - UINT32 width, UINT32 height, const RECTANGLE_16* src, - const RECTANGLE_16* dst); - int xf_rail_init(xfContext* xfc, RailClientContext* rail); int xf_rail_uninit(xfContext* xfc, RailClientContext* rail);