From: Paul Gofman pgofman@codeweavers.com
--- dlls/winex11.drv/opengl.c | 2 +- dlls/winex11.drv/window.c | 19 ++++++++++++------- dlls/winex11.drv/x11drv.h | 2 ++ dlls/winex11.drv/xrender.c | 38 +++++++++++++++++++++++++++++--------- 4 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 74f78482b41..158f2f846f2 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -2292,7 +2292,7 @@ static BOOL X11DRV_wglDestroyPbufferARB( struct wgl_pbuffer *object ) */ static HDC X11DRV_wglGetPbufferDCARB( struct wgl_pbuffer *object ) { - struct x11drv_escape_set_drawable escape; + struct x11drv_escape_set_drawable escape = { 0 }; struct gl_drawable *prev; HDC hdc;
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index b13c54531ac..d86321a4649 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2694,7 +2694,7 @@ Window X11DRV_get_whole_window( HWND hwnd ) void X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect, const RECT *top_rect, DWORD flags ) { - struct x11drv_escape_set_drawable escape; + struct x11drv_escape_set_drawable escape = { 0 };
escape.code = X11DRV_SET_DRAWABLE; escape.mode = IncludeInferiors; @@ -2709,11 +2709,16 @@ void X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect, { struct x11drv_win_data *data = get_win_data( hwnd );
- escape.drawable = data ? data->whole_window : X11DRV_get_whole_window( hwnd ); - - /* special case: when repainting the root window, clip out top-level windows */ - if (data && data->whole_window == root_window) escape.mode = ClipByChildren; - release_win_data( data ); + if (data) + { + escape.drawable = data->whole_window; + escape.use_alpha = data->use_alpha; + escape.visual = data->vis; + /* special case: when repainting the root window, clip out top-level windows */ + if (data->whole_window == root_window) escape.mode = ClipByChildren; + release_win_data( data ); + } + else escape.drawable = X11DRV_get_whole_window( hwnd ); } else { @@ -2730,7 +2735,7 @@ void X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect, */ void X11DRV_ReleaseDC( HWND hwnd, HDC hdc ) { - struct x11drv_escape_set_drawable escape; + struct x11drv_escape_set_drawable escape = { 0 };
escape.code = X11DRV_SET_DRAWABLE; escape.drawable = root_window; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index ee5bbe07dd4..9e73e9d473f 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -344,6 +344,8 @@ struct x11drv_escape_set_drawable Drawable drawable; /* X drawable */ int mode; /* ClipByChildren or IncludeInferiors */ RECT dc_rect; /* DC rectangle relative to drawable */ + BOOL use_alpha; /* drawable use an alpha channel */ + XVisualInfo visual; /* X visual used by drawable, may be unspecified when alpha is not used. */ };
struct x11drv_escape_get_drawable diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index bac3e6fac4b..968b79b38d2 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -250,15 +250,14 @@ static BOOL get_xrender_template(const WineXRenderFormatTemplate *fmt, XRenderPi return TRUE; }
-static BOOL is_wxrformat_compatible_with_default_visual(const WineXRenderFormatTemplate *fmt) +static BOOL is_wxrformat_compatible_with_visual(const WineXRenderFormatTemplate *fmt, const XVisualInfo *visual, BOOL use_alpha) { - if(fmt->depth != default_visual.depth) return FALSE; - if( (fmt->redMask << fmt->red) != default_visual.red_mask) return FALSE; - if( (fmt->greenMask << fmt->green) != default_visual.green_mask) return FALSE; - if( (fmt->blueMask << fmt->blue) != default_visual.blue_mask) return FALSE; + if(fmt->depth != visual->depth) return FALSE; + if( (fmt->redMask << fmt->red) != visual->red_mask) return FALSE; + if( (fmt->greenMask << fmt->green) != visual->green_mask) return FALSE; + if( (fmt->blueMask << fmt->blue) != visual->blue_mask) return FALSE;
- /* We never select a default ARGB visual */ - if(fmt->alphaMask) return FALSE; + if(!fmt->alphaMask != !use_alpha) return FALSE; return TRUE; }
@@ -278,7 +277,7 @@ static int load_xrender_formats(void) TRACE( "Loaded root pict_format with id=%#lx\n", pict_formats[i]->id ); continue; } - if(is_wxrformat_compatible_with_default_visual(&wxr_formats_template[i])) + if(is_wxrformat_compatible_with_visual(&wxr_formats_template[i], &default_visual, FALSE)) { pict_formats[i] = pXRenderFindVisualFormat(gdi_display, default_visual.visual); if (!pict_formats[i]) @@ -985,8 +984,29 @@ static INT xrenderdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID BOOL ret = dev->funcs->pExtEscape( dev, escape, in_count, in_data, out_count, out_data ); if (ret) { + const struct x11drv_escape_set_drawable *set = in_data; + enum wxr_format format = default_format; + unsigned int i; + + /* When alpha is not used visual format should be compatible with default and visual info may be + * not specified. */ + if (set->use_alpha) + { + for (i = 0; i < WXR_NB_FORMATS; ++i) + { + if (!pict_formats[i]) continue; + if (is_wxrformat_compatible_with_visual( &wxr_formats_template[i], &set->visual, TRUE )) + { + TRACE( "Found argb format %u.\n", i ); + format = i; + break; + } + } + if (i == WXR_NB_FORMATS) + WARN( "Format not found for argb visual.\n" ); + } free_xrender_picture( physdev ); - set_physdev_format( physdev, default_format ); + set_physdev_format( physdev, format ); } return ret; }