From 4d885e3a6efd0c45cb5760cb486961b35f21c080 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Fri, 25 Nov 2022 14:14:56 +0100 Subject: [PATCH] [client,x11] Initialize window with 32bit color Allow alpha channel to be properly processed for rail --- client/X11/xf_client.c | 97 +++++++++++++++++++++++------------------- client/X11/xf_rail.c | 1 + client/X11/xf_window.c | 18 ++++---- client/X11/xfreerdp.h | 2 + 4 files changed, 66 insertions(+), 52 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index b310a283d..4df3782fb 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -635,32 +635,57 @@ BOOL xf_create_window(xfContext* xfc) XEvent xevent = { 0 }; int width, height; char* windowTitle; - rdpGdi* gdi; rdpSettings* settings; WINPR_ASSERT(xfc); settings = xfc->common.context.settings; WINPR_ASSERT(settings); - gdi = xfc->common.context.gdi; - WINPR_ASSERT(gdi); - width = settings->DesktopWidth; height = settings->DesktopHeight; if (!xfc->hdc) - if (!(xfc->hdc = gdi_CreateDC(gdi->dstFormat))) + if (!(xfc->hdc = gdi_CreateDC(xf_get_local_color_format(xfc, TRUE)))) return FALSE; + const XSetWindowAttributes empty = { 0 }; + xfc->attribs = empty; + + XVisualInfo vinfo = { 0 }; + if (XMatchVisualInfo(xfc->display, xfc->screen_number, 32, TrueColor, &vinfo)) + { + Window root = XDefaultRootWindow(xfc->display); + xfc->visual = vinfo.visual; + xfc->attribs.colormap = xfc->colormap = + XCreateColormap(xfc->display, root, vinfo.visual, AllocNone); + } + else + { + xfc->visual = DefaultVisual(xfc->display, xfc->screen_number); + xfc->attribs.colormap = xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number); + } + + /* + * Detect if the server visual has an inverted colormap + * (BGR vs RGB, or red being the least significant byte) + */ + if (vinfo.red_mask & 0xFF) + { + xfc->invert = FALSE; + } + if (!xfc->remote_app) { xfc->attribs.background_pixel = BlackPixelOfScreen(xfc->screen); xfc->attribs.border_pixel = WhitePixelOfScreen(xfc->screen); xfc->attribs.backing_store = xfc->primary ? NotUseful : Always; xfc->attribs.override_redirect = False; - xfc->attribs.colormap = xfc->colormap; + xfc->attribs.bit_gravity = NorthWestGravity; xfc->attribs.win_gravity = NorthWestGravity; + xfc->attribs_mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | + CWBorderPixel | CWWinGravity | CWBitGravity; + #ifdef WITH_XRENDER xfc->offset_x = 0; xfc->offset_y = 0; @@ -722,8 +747,15 @@ BOOL xf_create_window(xfContext* xfc) settings->DesktopHeight); XFlush(xfc->display); + return TRUE; +} + +BOOL xf_create_image(xfContext* xfc) +{ + WINPR_ASSERT(xfc); if (!xfc->image) { + const rdpSettings* settings = xfc->common.context.settings; rdpGdi* cgdi = xfc->common.context.gdi; WINPR_ASSERT(cgdi); @@ -733,7 +765,6 @@ BOOL xf_create_window(xfContext* xfc) xfc->image->byte_order = LSBFirst; xfc->image->bitmap_bit_order = LSBFirst; } - return TRUE; } @@ -839,10 +870,8 @@ void xf_unlock_x11_(xfContext* xfc, const char* fkt) static BOOL xf_get_pixmap_info(xfContext* xfc) { - int i; int vi_count = 0; int pf_count = 0; - XVisualInfo* vi = NULL; XVisualInfo* vis = NULL; XVisualInfo tpl = { 0 }; XPixmapFormatValues* pfs = NULL; @@ -856,7 +885,7 @@ static BOOL xf_get_pixmap_info(xfContext* xfc) return 1; } - for (i = 0; i < pf_count; i++) + for (int i = 0; i < pf_count; i++) { const XPixmapFormatValues* pf = &pfs[i]; @@ -869,6 +898,7 @@ static BOOL xf_get_pixmap_info(xfContext* xfc) XFree(pfs); + tpl.depth = xfc->depth; tpl.class = TrueColor; tpl.screen = xfc->screen_number; @@ -879,7 +909,8 @@ static BOOL xf_get_pixmap_info(xfContext* xfc) return FALSE; } - vis = XGetVisualInfo(xfc->display, VisualClassMask | VisualScreenMask, &tpl, &vi_count); + vis = XGetVisualInfo(xfc->display, VisualDepthMask | VisualClassMask | VisualScreenMask, &tpl, + &vi_count); if (!vis) { @@ -887,31 +918,16 @@ static BOOL xf_get_pixmap_info(xfContext* xfc) return FALSE; } - vi = vis; - - for (i = 0; i < vi_count; i++) + for (int i = 0; i < vi_count; i++) { - vi = vis + i; + const XVisualInfo* vi = &vis[i]; if (vi->visual == window_attributes.visual) { - xfc->visual = vi->visual; break; } } - if (xfc->visual) - { - /* - * Detect if the server visual has an inverted colormap - * (BGR vs RGB, or red being the least significant byte) - */ - if (vi->red_mask & 0xFF) - { - xfc->invert = FALSE; - } - } - XFree(vis); if ((xfc->visual == NULL) || (xfc->scanline_pad == 0)) @@ -1283,9 +1299,18 @@ static BOOL xf_post_connect(freerdp* instance) update = context->update; WINPR_ASSERT(update); + if (!xf_create_window(xfc)) + return FALSE; + + if (!xf_get_pixmap_info(xfc)) + return FALSE; + if (!gdi_init(instance, xf_get_local_color_format(xfc, TRUE))) return FALSE; + if (!xf_create_image(xfc)) + return FALSE; + if (!xf_register_pointer(context->graphics)) return FALSE; @@ -1330,12 +1355,6 @@ static BOOL xf_post_connect(freerdp* instance) if (settings->RemoteApplicationMode) xfc->remote_app = TRUE; - if (!xf_create_window(xfc)) - { - WLog_ERR(TAG, "xf_create_window failed"); - return FALSE; - } - if (settings->SoftwareGdi) { update->EndPaint = xf_sw_end_paint; @@ -1823,7 +1842,7 @@ BOOL xf_setup_x11(xfContext* xfc) xfc->xfds = ConnectionNumber(xfc->display); xfc->screen_number = DefaultScreen(xfc->display); xfc->screen = ScreenOfDisplay(xfc->display, xfc->screen_number); - xfc->depth = DefaultDepthOfScreen(xfc->screen); + xfc->depth = 32; // DefaultDepthOfScreen(xfc->screen); xfc->big_endian = (ImageByteOrder(xfc->display) == MSBFirst); xfc->invert = TRUE; xfc->complex_regions = TRUE; @@ -1896,8 +1915,6 @@ BOOL xf_setup_x11(xfContext* xfc) goto fail; } - xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number); - if (xfc->debug) { WLog_INFO(TAG, "Enabling X11 debug mode."); @@ -1907,12 +1924,6 @@ BOOL xf_setup_x11(xfContext* xfc) xf_check_extensions(xfc); - if (!xf_get_pixmap_info(xfc)) - { - WLog_ERR(TAG, "Failed to get pixmap info"); - goto fail; - } - xfc->vscreen.monitors = calloc(16, sizeof(MONITOR_INFO)); if (!xfc->vscreen.monitors) diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index e5ddb69f3..d6da446eb 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -85,6 +85,7 @@ void xf_rail_disable_remoteapp_mode(xfContext* xfc) xfc->remote_app = FALSE; xf_DestroyDummyWindow(xfc, xfc->drawable); xf_create_window(xfc); + xf_create_image(xfc); } } diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 02c7a4cad..6cdc9578e 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -496,12 +496,11 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig window->decorations = xfc->decorations; window->is_mapped = FALSE; window->is_transient = FALSE; - window->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen), xfc->workArea.x, - xfc->workArea.y, xfc->workArea.width, xfc->workArea.height, 0, - xfc->depth, InputOutput, xfc->visual, - CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | - CWBorderPixel | CWWinGravity | CWBitGravity, - &xfc->attribs); + + window->handle = + XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen), xfc->workArea.x, + xfc->workArea.y, xfc->workArea.width, xfc->workArea.height, 0, xfc->depth, + InputOutput, xfc->visual, xfc->attribs_mask, &xfc->attribs); window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE)); if (window->shmid < 0) @@ -811,9 +810,10 @@ BOOL xf_AppWindowCreate(xfContext* xfc, xfAppWindow* appWindow) appWindow->maxHorz = FALSE; appWindow->minimized = FALSE; appWindow->rail_ignore_configure = FALSE; - appWindow->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen), appWindow->x, - appWindow->y, appWindow->width, appWindow->height, 0, - xfc->depth, InputOutput, xfc->visual, 0, &xfc->attribs); + appWindow->handle = + XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen), appWindow->x, appWindow->y, + appWindow->width, appWindow->height, 0, xfc->depth, InputOutput, xfc->visual, + xfc->attribs_mask, &xfc->attribs); if (!appWindow->handle) return FALSE; diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index b40cf602a..458728324 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -210,6 +210,7 @@ struct xf_context wArrayList* xevents; BOOL actionScriptExists; + int attribs_mask; XSetWindowAttributes attribs; BOOL complex_regions; VIRTUAL_SCREEN vscreen; @@ -299,6 +300,7 @@ struct xf_context }; BOOL xf_create_window(xfContext* xfc); +BOOL xf_create_image(xfContext* xfc); void xf_toggle_fullscreen(xfContext* xfc); enum XF_EXIT_CODE