diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index b3e92a4a..d50baea1 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -427,6 +427,7 @@ patch_enable_all () enable_winex11_DefaultDisplayFrequency="$1" enable_winex11_MWM_Decorations="$1" enable_winex11_SC_KEYMENU="$1" + enable_winex11_UpdateLayeredWindow="$1" enable_winex11_WM_WINDOWPOSCHANGING="$1" enable_winex11_Window_Groups="$1" enable_winex11_Window_Style="$1" @@ -1499,6 +1500,9 @@ patch_enable () winex11-SC_KEYMENU) enable_winex11_SC_KEYMENU="$2" ;; + winex11-UpdateLayeredWindow) + enable_winex11_UpdateLayeredWindow="$2" + ;; winex11-WM_WINDOWPOSCHANGING) enable_winex11_WM_WINDOWPOSCHANGING="$2" ;; @@ -8812,6 +8816,21 @@ if test "$enable_winex11_SC_KEYMENU" -eq 1; then ) >> "$patchlist" fi +# Patchset winex11-UpdateLayeredWindow +# | +# | This patchset fixes the following Wine bugs: +# | * [#33943] Fix alpha blending in X11DRV_UpdateLayeredWindow +# | +# | Modified files: +# | * dlls/winex11.drv/window.c +# | +if test "$enable_winex11_UpdateLayeredWindow" -eq 1; then + patch_apply winex11-UpdateLayeredWindow/0001-winex11-Fix-alpha-blending-in-X11DRV_UpdateLayeredWi.patch + ( + printf '%s\n' '+ { "Sebastian Lackner", "winex11: Fix alpha blending in X11DRV_UpdateLayeredWindow.", 1 },'; + ) >> "$patchlist" +fi + # Patchset winex11-_NET_ACTIVE_WINDOW # | # | This patchset fixes the following Wine bugs: diff --git a/patches/winex11-UpdateLayeredWindow/0001-winex11-Fix-alpha-blending-in-X11DRV_UpdateLayeredWi.patch b/patches/winex11-UpdateLayeredWindow/0001-winex11-Fix-alpha-blending-in-X11DRV_UpdateLayeredWi.patch new file mode 100644 index 00000000..4cbb5a1e --- /dev/null +++ b/patches/winex11-UpdateLayeredWindow/0001-winex11-Fix-alpha-blending-in-X11DRV_UpdateLayeredWi.patch @@ -0,0 +1,111 @@ +From 73bf4a03497e732b42fff4e5d0d63c442fd70bc0 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 24 Jan 2017 12:37:46 +0100 +Subject: winex11: Fix alpha blending in X11DRV_UpdateLayeredWindow. + +Based on a patch by Dmitry Timoshkov. +--- + dlls/winex11.drv/window.c | 36 +++++++++++++++++------------------- + 1 file changed, 17 insertions(+), 19 deletions(-) + +diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c +index 7408a0eb480..3f169ea296f 100644 +--- a/dlls/winex11.drv/window.c ++++ b/dlls/winex11.drv/window.c +@@ -410,14 +410,11 @@ static void sync_window_region( struct x11drv_win_data *data, HRGN win_region ) + + + /*********************************************************************** +- * sync_window_opacity ++ * set_window_opacity + */ +-static void sync_window_opacity( Display *display, Window win, +- COLORREF key, BYTE alpha, DWORD flags ) ++static void set_window_opacity( Display *display, Window win, BYTE alpha ) + { +- unsigned long opacity = 0xffffffff; +- +- if (flags & LWA_ALPHA) opacity = (0xffffffff / 0xff) * alpha; ++ unsigned long opacity = (0xffffffff / 0xff) * alpha; + + if (opacity == 0xffffffff) + XDeleteProperty( display, win, x11drv_atom(_NET_WM_WINDOW_OPACITY) ); +@@ -1527,7 +1524,7 @@ static void create_whole_window( struct x11drv_win_data *data ) + + /* set the window opacity */ + if (!GetLayeredWindowAttributes( data->hwnd, &key, &alpha, &layered_flags )) layered_flags = 0; +- sync_window_opacity( data->display, data->whole_window, key, alpha, layered_flags ); ++ set_window_opacity( data->display, data->whole_window, (layered_flags & LWA_ALPHA) ? alpha : 0xff ); + + XFlush( data->display ); /* make sure the window exists before we start painting to it */ + +@@ -1647,7 +1644,7 @@ void CDECL X11DRV_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style ) + { + data->layered = FALSE; + set_window_visual( data, &default_visual ); +- sync_window_opacity( data->display, data->whole_window, 0, 0, 0 ); ++ set_window_opacity( data->display, data->whole_window, 0xff ); + if (data->surface) set_surface_color_key( data->surface, CLR_INVALID ); + } + done: +@@ -2536,7 +2533,7 @@ void CDECL X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alph + if (data) + { + if (data->whole_window) +- sync_window_opacity( data->display, data->whole_window, key, alpha, flags ); ++ set_window_opacity( data->display, data->whole_window, (flags & LWA_ALPHA) ? alpha : 0xff ); + if (data->surface) + set_surface_color_key( data->surface, (flags & LWA_COLORKEY) ? key : CLR_INVALID ); + +@@ -2560,7 +2557,7 @@ void CDECL X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alph + Window win = X11DRV_get_whole_window( hwnd ); + if (win) + { +- sync_window_opacity( gdi_display, win, key, alpha, flags ); ++ set_window_opacity( gdi_display, win, (flags & LWA_ALPHA) ? alpha : 0xff ); + if (flags & LWA_COLORKEY) + FIXME( "LWA_COLORKEY not supported on foreign process window %p\n", hwnd ); + } +@@ -2576,7 +2573,6 @@ BOOL CDECL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO + { + struct window_surface *surface; + struct x11drv_win_data *data; +- BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 }; + COLORREF color_key = (info->dwFlags & ULW_COLORKEY) ? info->crKey : CLR_INVALID; + char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *bmi = (BITMAPINFO *)buffer; +@@ -2604,6 +2600,10 @@ BOOL CDECL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO + } + else set_surface_color_key( surface, color_key ); + ++ if (data->whole_window) ++ set_window_opacity( data->display, data->whole_window, ++ (info->dwFlags & ULW_ALPHA) ? info->pblend->SourceConstantAlpha : 0xff ); ++ + if (surface) window_surface_add_ref( surface ); + release_win_data( data ); + +@@ -2627,14 +2627,12 @@ BOOL CDECL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO + { + IntersectRect( &rect, &rect, info->prcDirty ); + memcpy( src_bits, dst_bits, bmi->bmiHeader.biSizeImage ); +- PatBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, BLACKNESS ); +- } +- ret = GdiAlphaBlend( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, +- info->hdcSrc, +- rect.left + (info->pptSrc ? info->pptSrc->x : 0), +- rect.top + (info->pptSrc ? info->pptSrc->y : 0), +- rect.right - rect.left, rect.bottom - rect.top, +- (info->dwFlags & ULW_ALPHA) ? *info->pblend : blend ); ++ } ++ ret = BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, ++ info->hdcSrc, ++ rect.left + (info->pptSrc ? info->pptSrc->x : 0), ++ rect.top + (info->pptSrc ? info->pptSrc->y : 0), ++ SRCCOPY ); + if (ret) + { + memcpy( dst_bits, src_bits, bmi->bmiHeader.biSizeImage ); +-- +2.11.0 + diff --git a/patches/winex11-UpdateLayeredWindow/definition b/patches/winex11-UpdateLayeredWindow/definition new file mode 100644 index 00000000..fc7874a5 --- /dev/null +++ b/patches/winex11-UpdateLayeredWindow/definition @@ -0,0 +1 @@ +Fixes: [33943] Fix alpha blending in X11DRV_UpdateLayeredWindow