[client,x11] Initialize window with 32bit color

Allow alpha channel to be properly processed for rail
This commit is contained in:
akallabeth 2022-11-25 14:14:56 +01:00 committed by akallabeth
parent 7b6023b340
commit 4d885e3a6e
4 changed files with 66 additions and 52 deletions

View File

@ -635,32 +635,57 @@ BOOL xf_create_window(xfContext* xfc)
XEvent xevent = { 0 }; XEvent xevent = { 0 };
int width, height; int width, height;
char* windowTitle; char* windowTitle;
rdpGdi* gdi;
rdpSettings* settings; rdpSettings* settings;
WINPR_ASSERT(xfc); WINPR_ASSERT(xfc);
settings = xfc->common.context.settings; settings = xfc->common.context.settings;
WINPR_ASSERT(settings); WINPR_ASSERT(settings);
gdi = xfc->common.context.gdi;
WINPR_ASSERT(gdi);
width = settings->DesktopWidth; width = settings->DesktopWidth;
height = settings->DesktopHeight; height = settings->DesktopHeight;
if (!xfc->hdc) if (!xfc->hdc)
if (!(xfc->hdc = gdi_CreateDC(gdi->dstFormat))) if (!(xfc->hdc = gdi_CreateDC(xf_get_local_color_format(xfc, TRUE))))
return FALSE; 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) if (!xfc->remote_app)
{ {
xfc->attribs.background_pixel = BlackPixelOfScreen(xfc->screen); xfc->attribs.background_pixel = BlackPixelOfScreen(xfc->screen);
xfc->attribs.border_pixel = WhitePixelOfScreen(xfc->screen); xfc->attribs.border_pixel = WhitePixelOfScreen(xfc->screen);
xfc->attribs.backing_store = xfc->primary ? NotUseful : Always; xfc->attribs.backing_store = xfc->primary ? NotUseful : Always;
xfc->attribs.override_redirect = False; xfc->attribs.override_redirect = False;
xfc->attribs.colormap = xfc->colormap;
xfc->attribs.bit_gravity = NorthWestGravity; xfc->attribs.bit_gravity = NorthWestGravity;
xfc->attribs.win_gravity = NorthWestGravity; xfc->attribs.win_gravity = NorthWestGravity;
xfc->attribs_mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
CWBorderPixel | CWWinGravity | CWBitGravity;
#ifdef WITH_XRENDER #ifdef WITH_XRENDER
xfc->offset_x = 0; xfc->offset_x = 0;
xfc->offset_y = 0; xfc->offset_y = 0;
@ -722,8 +747,15 @@ BOOL xf_create_window(xfContext* xfc)
settings->DesktopHeight); settings->DesktopHeight);
XFlush(xfc->display); XFlush(xfc->display);
return TRUE;
}
BOOL xf_create_image(xfContext* xfc)
{
WINPR_ASSERT(xfc);
if (!xfc->image) if (!xfc->image)
{ {
const rdpSettings* settings = xfc->common.context.settings;
rdpGdi* cgdi = xfc->common.context.gdi; rdpGdi* cgdi = xfc->common.context.gdi;
WINPR_ASSERT(cgdi); WINPR_ASSERT(cgdi);
@ -733,7 +765,6 @@ BOOL xf_create_window(xfContext* xfc)
xfc->image->byte_order = LSBFirst; xfc->image->byte_order = LSBFirst;
xfc->image->bitmap_bit_order = LSBFirst; xfc->image->bitmap_bit_order = LSBFirst;
} }
return TRUE; return TRUE;
} }
@ -839,10 +870,8 @@ void xf_unlock_x11_(xfContext* xfc, const char* fkt)
static BOOL xf_get_pixmap_info(xfContext* xfc) static BOOL xf_get_pixmap_info(xfContext* xfc)
{ {
int i;
int vi_count = 0; int vi_count = 0;
int pf_count = 0; int pf_count = 0;
XVisualInfo* vi = NULL;
XVisualInfo* vis = NULL; XVisualInfo* vis = NULL;
XVisualInfo tpl = { 0 }; XVisualInfo tpl = { 0 };
XPixmapFormatValues* pfs = NULL; XPixmapFormatValues* pfs = NULL;
@ -856,7 +885,7 @@ static BOOL xf_get_pixmap_info(xfContext* xfc)
return 1; return 1;
} }
for (i = 0; i < pf_count; i++) for (int i = 0; i < pf_count; i++)
{ {
const XPixmapFormatValues* pf = &pfs[i]; const XPixmapFormatValues* pf = &pfs[i];
@ -869,6 +898,7 @@ static BOOL xf_get_pixmap_info(xfContext* xfc)
XFree(pfs); XFree(pfs);
tpl.depth = xfc->depth;
tpl.class = TrueColor; tpl.class = TrueColor;
tpl.screen = xfc->screen_number; tpl.screen = xfc->screen_number;
@ -879,7 +909,8 @@ static BOOL xf_get_pixmap_info(xfContext* xfc)
return FALSE; return FALSE;
} }
vis = XGetVisualInfo(xfc->display, VisualClassMask | VisualScreenMask, &tpl, &vi_count); vis = XGetVisualInfo(xfc->display, VisualDepthMask | VisualClassMask | VisualScreenMask, &tpl,
&vi_count);
if (!vis) if (!vis)
{ {
@ -887,31 +918,16 @@ static BOOL xf_get_pixmap_info(xfContext* xfc)
return FALSE; return FALSE;
} }
vi = vis; for (int i = 0; i < vi_count; i++)
for (i = 0; i < vi_count; i++)
{ {
vi = vis + i; const XVisualInfo* vi = &vis[i];
if (vi->visual == window_attributes.visual) if (vi->visual == window_attributes.visual)
{ {
xfc->visual = vi->visual;
break; 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); XFree(vis);
if ((xfc->visual == NULL) || (xfc->scanline_pad == 0)) if ((xfc->visual == NULL) || (xfc->scanline_pad == 0))
@ -1283,9 +1299,18 @@ static BOOL xf_post_connect(freerdp* instance)
update = context->update; update = context->update;
WINPR_ASSERT(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))) if (!gdi_init(instance, xf_get_local_color_format(xfc, TRUE)))
return FALSE; return FALSE;
if (!xf_create_image(xfc))
return FALSE;
if (!xf_register_pointer(context->graphics)) if (!xf_register_pointer(context->graphics))
return FALSE; return FALSE;
@ -1330,12 +1355,6 @@ static BOOL xf_post_connect(freerdp* instance)
if (settings->RemoteApplicationMode) if (settings->RemoteApplicationMode)
xfc->remote_app = TRUE; xfc->remote_app = TRUE;
if (!xf_create_window(xfc))
{
WLog_ERR(TAG, "xf_create_window failed");
return FALSE;
}
if (settings->SoftwareGdi) if (settings->SoftwareGdi)
{ {
update->EndPaint = xf_sw_end_paint; update->EndPaint = xf_sw_end_paint;
@ -1823,7 +1842,7 @@ BOOL xf_setup_x11(xfContext* xfc)
xfc->xfds = ConnectionNumber(xfc->display); xfc->xfds = ConnectionNumber(xfc->display);
xfc->screen_number = DefaultScreen(xfc->display); xfc->screen_number = DefaultScreen(xfc->display);
xfc->screen = ScreenOfDisplay(xfc->display, xfc->screen_number); 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->big_endian = (ImageByteOrder(xfc->display) == MSBFirst);
xfc->invert = TRUE; xfc->invert = TRUE;
xfc->complex_regions = TRUE; xfc->complex_regions = TRUE;
@ -1896,8 +1915,6 @@ BOOL xf_setup_x11(xfContext* xfc)
goto fail; goto fail;
} }
xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number);
if (xfc->debug) if (xfc->debug)
{ {
WLog_INFO(TAG, "Enabling X11 debug mode."); WLog_INFO(TAG, "Enabling X11 debug mode.");
@ -1907,12 +1924,6 @@ BOOL xf_setup_x11(xfContext* xfc)
xf_check_extensions(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)); xfc->vscreen.monitors = calloc(16, sizeof(MONITOR_INFO));
if (!xfc->vscreen.monitors) if (!xfc->vscreen.monitors)

View File

@ -85,6 +85,7 @@ void xf_rail_disable_remoteapp_mode(xfContext* xfc)
xfc->remote_app = FALSE; xfc->remote_app = FALSE;
xf_DestroyDummyWindow(xfc, xfc->drawable); xf_DestroyDummyWindow(xfc, xfc->drawable);
xf_create_window(xfc); xf_create_window(xfc);
xf_create_image(xfc);
} }
} }

View File

@ -496,12 +496,11 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
window->decorations = xfc->decorations; window->decorations = xfc->decorations;
window->is_mapped = FALSE; window->is_mapped = FALSE;
window->is_transient = 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, window->handle =
xfc->depth, InputOutput, xfc->visual, XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen), xfc->workArea.x,
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | xfc->workArea.y, xfc->workArea.width, xfc->workArea.height, 0, xfc->depth,
CWBorderPixel | CWWinGravity | CWBitGravity, InputOutput, xfc->visual, xfc->attribs_mask, &xfc->attribs);
&xfc->attribs);
window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE)); window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE));
if (window->shmid < 0) if (window->shmid < 0)
@ -811,9 +810,10 @@ BOOL xf_AppWindowCreate(xfContext* xfc, xfAppWindow* appWindow)
appWindow->maxHorz = FALSE; appWindow->maxHorz = FALSE;
appWindow->minimized = FALSE; appWindow->minimized = FALSE;
appWindow->rail_ignore_configure = FALSE; appWindow->rail_ignore_configure = FALSE;
appWindow->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen), appWindow->x, appWindow->handle =
appWindow->y, appWindow->width, appWindow->height, 0, XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen), appWindow->x, appWindow->y,
xfc->depth, InputOutput, xfc->visual, 0, &xfc->attribs); appWindow->width, appWindow->height, 0, xfc->depth, InputOutput, xfc->visual,
xfc->attribs_mask, &xfc->attribs);
if (!appWindow->handle) if (!appWindow->handle)
return FALSE; return FALSE;

View File

@ -210,6 +210,7 @@ struct xf_context
wArrayList* xevents; wArrayList* xevents;
BOOL actionScriptExists; BOOL actionScriptExists;
int attribs_mask;
XSetWindowAttributes attribs; XSetWindowAttributes attribs;
BOOL complex_regions; BOOL complex_regions;
VIRTUAL_SCREEN vscreen; VIRTUAL_SCREEN vscreen;
@ -299,6 +300,7 @@ struct xf_context
}; };
BOOL xf_create_window(xfContext* xfc); BOOL xf_create_window(xfContext* xfc);
BOOL xf_create_image(xfContext* xfc);
void xf_toggle_fullscreen(xfContext* xfc); void xf_toggle_fullscreen(xfContext* xfc);
enum XF_EXIT_CODE enum XF_EXIT_CODE