From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 21 +++++++++++++++--- dlls/win32u/window.c | 10 ++++++++- dlls/wineandroid.drv/android.h | 4 +++- dlls/wineandroid.drv/init.c | 1 + dlls/wineandroid.drv/window.c | 39 ++++++++++++++++++--------------- dlls/winemac.drv/gdi.c | 1 + dlls/winemac.drv/macdrv.h | 4 +++- dlls/winemac.drv/window.c | 37 ++++++++++++++++++------------- dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/window.c | 40 +++++++++++++++++++--------------- dlls/winex11.drv/x11drv.h | 4 +++- include/wine/gdi_driver.h | 3 ++- 12 files changed, 106 insertions(+), 59 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 4bb59536efe..fdba2524300 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -867,8 +867,15 @@ static LRESULT nulldrv_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam ) return -1; }
+static BOOL nulldrv_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key, + struct window_surface **surface ) +{ + *surface = NULL; + return TRUE; +} + static BOOL nulldrv_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, - const RECT *window_rect ) + const RECT *window_rect, struct window_surface *surface ) { return TRUE; } @@ -1208,10 +1215,16 @@ static void loaderdrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) load_driver()->pSetWindowRgn( hwnd, hrgn, redraw ); }
+static BOOL loaderdrv_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key, + struct window_surface **surface ) +{ + return load_driver()->pCreateLayeredWindow( hwnd, window_rect, color_key, surface ); +} + static BOOL loaderdrv_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, - const RECT *window_rect ) + const RECT *window_rect, struct window_surface *surface ) { - return load_driver()->pUpdateLayeredWindow( hwnd, info, window_rect ); + return load_driver()->pUpdateLayeredWindow( hwnd, info, window_rect, surface ); }
static UINT loaderdrv_VulkanInit( UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs ) @@ -1278,6 +1291,7 @@ static const struct user_driver_funcs lazy_load_driver = nulldrv_SetWindowText, nulldrv_ShowWindow, nulldrv_SysCommand, + loaderdrv_CreateLayeredWindow, loaderdrv_UpdateLayeredWindow, nulldrv_WindowMessage, nulldrv_WindowPosChanging, @@ -1364,6 +1378,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(SetWindowText); SET_USER_FUNC(ShowWindow); SET_USER_FUNC(SysCommand); + SET_USER_FUNC(CreateLayeredWindow); SET_USER_FUNC(UpdateLayeredWindow); SET_USER_FUNC(WindowMessage); SET_USER_FUNC(WindowPosChanging); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 12f2a9027f0..0c70b90a8e8 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2119,9 +2119,11 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_ const BLENDFUNCTION *blend, DWORD flags, const RECT *dirty ) { DWORD swp_flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW; + struct window_surface *surface; RECT window_rect, client_rect; UPDATELAYEREDWINDOWINFO info; SIZE offset; + BOOL ret;
if (flags & ~(ULW_COLORKEY | ULW_ALPHA | ULW_OPAQUE | ULW_EX_NORESIZE) || !(get_window_long( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED) || @@ -2167,6 +2169,9 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_
apply_window_pos( hwnd, 0, swp_flags, &window_rect, &client_rect, NULL );
+ if (!(flags & ULW_COLORKEY)) key = CLR_INVALID; + if (!(user_driver->pCreateLayeredWindow( hwnd, &window_rect, key, &surface )) || !surface) return FALSE; + info.cbSize = sizeof(info); info.hdcDst = hdc_dst; info.pptDst = pts_dst; @@ -2177,7 +2182,10 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_ info.pblend = blend; info.dwFlags = flags; info.prcDirty = dirty; - return user_driver->pUpdateLayeredWindow( hwnd, &info, &window_rect ); + ret = user_driver->pUpdateLayeredWindow( hwnd, &info, &window_rect, surface ); + + window_surface_release( surface ); + return ret; }
/*********************************************************************** diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 2512976089b..7831bb20ee2 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -98,8 +98,10 @@ extern void ANDROID_SetParent( HWND hwnd, HWND parent, HWND old_parent ); extern void ANDROID_SetCapture( HWND hwnd, UINT flags ); extern void ANDROID_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style ); extern UINT ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ); +extern BOOL ANDROID_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key, + struct window_surface **surface ); extern BOOL ANDROID_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, - const RECT *window_rect ); + const RECT *window_rect, struct window_surface *surface ); extern LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL ANDROID_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index 5b4ec59d2fa..cda9cd657b7 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -348,6 +348,7 @@ static const struct user_driver_funcs android_drv_funcs = .pSetParent = ANDROID_SetParent, .pSetWindowStyle = ANDROID_SetWindowStyle, .pShowWindow = ANDROID_ShowWindow, + .pCreateLayeredWindow = ANDROID_CreateLayeredWindow, .pUpdateLayeredWindow = ANDROID_UpdateLayeredWindow, .pWindowMessage = ANDROID_WindowMessage, .pWindowPosChanging = ANDROID_WindowPosChanging, diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 55ca444f970..1b5a991f812 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1388,18 +1388,14 @@ void ANDROID_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DW
/***************************************************************************** - * ANDROID_UpdateLayeredWindow + * ANDROID_CreateLayeredWindow */ -BOOL ANDROID_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, - const RECT *window_rect ) +BOOL ANDROID_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key, + struct window_surface **window_surface ) { struct window_surface *surface; struct android_win_data *data; - BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 }; - COLORREF color_key = (info->dwFlags & ULW_COLORKEY) ? info->crKey : CLR_INVALID; - RECT rect, src_rect; - HDC hdc; - BOOL ret = FALSE; + RECT rect;
if (!(data = get_win_data( hwnd ))) return FALSE;
@@ -1421,17 +1417,26 @@ BOOL ANDROID_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info } else set_surface_layered( surface, 255, color_key );
- if (surface) window_surface_add_ref( surface ); + if ((*window_surface = surface)) window_surface_add_ref( surface ); release_win_data( data );
- if (!surface) return FALSE; - if (!info->hdcSrc) - { - window_surface_release( surface ); - return TRUE; - } + return TRUE; +} + +/***************************************************************************** + * ANDROID_UpdateLayeredWindow + */ +BOOL ANDROID_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, + const RECT *window_rect, struct window_surface *surface ) +{ + BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 }; + RECT rect, src_rect; + HDC hdc; + BOOL ret;
- if (!(hdc = NtGdiCreateCompatibleDC( 0 ))) goto done; + if (!info->hdcSrc) return TRUE; + + if (!(hdc = NtGdiCreateCompatibleDC( 0 ))) return FALSE; window_surface_lock( surface ); NtGdiSelectBitmap( hdc, surface->color_bitmap );
@@ -1452,8 +1457,6 @@ BOOL ANDROID_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info window_surface_unlock( surface ); window_surface_flush( surface );
-done: - window_surface_release( surface ); return ret; }
diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index a06314ed62c..9d3c2adb26c 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -301,6 +301,7 @@ static const struct user_driver_funcs macdrv_funcs = .pToUnicodeEx = macdrv_ToUnicodeEx, .pUnregisterHotKey = macdrv_UnregisterHotKey, .pUpdateClipboard = macdrv_UpdateClipboard, + .pCreateLayeredWindow = macdrv_CreateLayeredWindow, .pUpdateLayeredWindow = macdrv_UpdateLayeredWindow, .pVkKeyScanEx = macdrv_VkKeyScanEx, .pImeProcessKey = macdrv_ImeProcessKey, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index a7905050f16..9f9782864ec 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -147,8 +147,10 @@ extern void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alph extern void macdrv_SetWindowText(HWND hwnd, LPCWSTR text); extern UINT macdrv_ShowWindow(HWND hwnd, INT cmd, RECT *rect, UINT swp); extern LRESULT macdrv_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam); +extern BOOL macdrv_CreateLayeredWindow(HWND hwnd, const RECT *window_rect, COLORREF color_key, + struct window_surface **surface); extern BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, - const RECT *window_rect); + const RECT *window_rect, struct window_surface *surface); extern LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); extern BOOL macdrv_WindowPosChanging(HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 9d5d20b8f92..adee3ffe412 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1887,16 +1887,14 @@ done:
/*********************************************************************** - * UpdateLayeredWindow (MACDRV.@) + * CreateLayeredWindow (MACDRV.@) */ -BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, - const RECT *window_rect) +BOOL macdrv_CreateLayeredWindow(HWND hwnd, const RECT *window_rect, COLORREF color_key, + struct window_surface **window_surface) { struct window_surface *surface; struct macdrv_win_data *data; - BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 }; - RECT rect, src_rect; - HDC hdc; + RECT rect; BOOL ret = FALSE;
if (!(data = get_win_data(hwnd))) return FALSE; @@ -1922,7 +1920,7 @@ BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, } else set_surface_use_alpha(surface, TRUE);
- if (surface) window_surface_add_ref(surface); + if ((*window_surface = surface)) window_surface_add_ref(surface);
/* Since layered attributes are now set, can now show the window */ if (data->cocoa_window && !data->on_screen && NtUserGetWindowLongW(hwnd, GWL_STYLE) & WS_VISIBLE) @@ -1930,14 +1928,24 @@ BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
release_win_data(data);
- if (!surface) return FALSE; - if (!info->hdcSrc) - { - window_surface_release(surface); - return TRUE; - } + return ret; +} + +/*********************************************************************** + * UpdateLayeredWindow (MACDRV.@) + */ +BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, + const RECT *window_rect, struct window_surface *surface) +{ + struct macdrv_win_data *data; + BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 }; + RECT rect, src_rect; + HDC hdc; + BOOL ret = FALSE; + + if (!info->hdcSrc) return TRUE;
- if (!(hdc = NtGdiCreateCompatibleDC(0))) goto done; + if (!(hdc = NtGdiCreateCompatibleDC(0))) return FALSE; window_surface_lock(surface); NtGdiSelectBitmap(hdc, surface->color_bitmap);
@@ -1967,7 +1975,6 @@ BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, }
done: - window_surface_release(surface); return ret; }
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index e3b3a3e2557..66e73035ddb 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -420,6 +420,7 @@ static const struct user_driver_funcs x11drv_funcs = .pSysCommand = X11DRV_SysCommand, .pClipboardWindowProc = X11DRV_ClipboardWindowProc, .pUpdateClipboard = X11DRV_UpdateClipboard, + .pCreateLayeredWindow = X11DRV_CreateLayeredWindow, .pUpdateLayeredWindow = X11DRV_UpdateLayeredWindow, .pWindowMessage = X11DRV_WindowMessage, .pWindowPosChanging = X11DRV_WindowPosChanging, diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index bf1b2bab325..3b669c5260b 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2963,18 +2963,15 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO
/***************************************************************************** - * UpdateLayeredWindow (X11DRV.@) + * CreateLayeredWindow (X11DRV.@) */ -BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, - const RECT *window_rect ) +BOOL X11DRV_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key, + struct window_surface **window_surface ) { 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; - RECT rect, src_rect; - HDC hdc; - BOOL mapped, ret = FALSE; + BOOL mapped; + RECT rect;
if (!(data = get_win_data( hwnd ))) return FALSE;
@@ -2994,7 +2991,7 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, } else set_surface_color_key( surface, color_key );
- if (surface) window_surface_add_ref( surface ); + if ((*window_surface = surface)) window_surface_add_ref( surface ); mapped = data->mapped; release_win_data( data );
@@ -3007,14 +3004,23 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, map_window( hwnd, style ); }
- if (!surface) return FALSE; - if (!info->hdcSrc) - { - window_surface_release( surface ); - return TRUE; - } + return TRUE; +} + +/***************************************************************************** + * UpdateLayeredWindow (X11DRV.@) + */ +BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, + const RECT *window_rect, struct window_surface *surface ) +{ + BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 }; + RECT rect, src_rect; + HDC hdc; + BOOL ret;
- if (!(hdc = NtGdiCreateCompatibleDC( 0 ))) goto done; + if (!info->hdcSrc) return TRUE; + + if (!(hdc = NtGdiCreateCompatibleDC( 0 ))) return FALSE; window_surface_lock( surface ); NtGdiSelectBitmap( hdc, surface->color_bitmap );
@@ -3035,8 +3041,6 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, window_surface_unlock( surface ); window_surface_flush( surface );
-done: - window_surface_release( surface ); return ret; }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 2a326b07a4c..42b6048cdb5 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -240,8 +240,10 @@ extern UINT X11DRV_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ); extern LRESULT X11DRV_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam ); extern LRESULT X11DRV_ClipboardWindowProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern void X11DRV_UpdateClipboard(void); +extern BOOL X11DRV_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COLORREF color_key, + struct window_surface **surface ); extern BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, - const RECT *window_rect ); + const RECT *window_rect, struct window_surface *surface ); extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect, diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index ce954a7f4d8..723a40f5474 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -336,7 +336,8 @@ struct user_driver_funcs void (*pSetWindowText)(HWND,LPCWSTR); UINT (*pShowWindow)(HWND,INT,RECT*,UINT); LRESULT (*pSysCommand)(HWND,WPARAM,LPARAM); - BOOL (*pUpdateLayeredWindow)(HWND,const struct tagUPDATELAYEREDWINDOWINFO *,const RECT *); + BOOL (*pCreateLayeredWindow)(HWND,const RECT *,COLORREF,struct window_surface **); + BOOL (*pUpdateLayeredWindow)(HWND,const struct tagUPDATELAYEREDWINDOWINFO*,const RECT*,struct window_surface*); LRESULT (*pWindowMessage)(HWND,UINT,WPARAM,LPARAM); BOOL (*pWindowPosChanging)(HWND,HWND,UINT,const RECT *,const RECT *,RECT *, struct window_surface**);