From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 16 +++++++++++++++- dlls/win32u/win32u_private.h | 4 ++-- dlls/win32u/window.c | 24 ++++++++++-------------- 3 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 6749e2b1725..8bad1949ebd 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -115,7 +115,7 @@ static const struct window_surface_funcs offscreen_window_surface_funcs = offscreen_window_surface_destroy };
-void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect, struct window_surface **window_surface ) +static void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect, struct window_surface **window_surface ) { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; struct window_surface *surface, *previous; @@ -138,6 +138,20 @@ void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect, struc *window_surface = window_surface_create( sizeof(*surface), &offscreen_window_surface_funcs, hwnd, surface_rect, info, 0 ); }
+void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *surface_rect, + struct window_surface **window_surface ) +{ + if (!user_driver->pCreateWindowSurface( hwnd, create_layered, surface_rect, window_surface )) + { + if (*window_surface) + { + window_surface_release( *window_surface ); + /* create an offscreen window surface if the driver doesn't implement CreateWindowSurface */ + create_offscreen_window_surface( hwnd, surface_rect, window_surface ); + } + } +} + /* window surface common helpers */
static UINT get_color_component( UINT color, UINT mask ) diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 3155ebab984..c8b2eb4c529 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -45,8 +45,8 @@ extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param );
/* dce.c */ extern struct window_surface dummy_surface; -extern void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect, - struct window_surface **surface ); +extern void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *surface_rect, + struct window_surface **window_surface ); extern void erase_now( HWND hwnd, UINT rdw_flags ); extern void flush_window_surfaces( BOOL idle ); extern void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *old_visible_rect, diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index ca36d9bb56d..1835bfa3f47 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1890,8 +1890,8 @@ static BOOL get_default_window_surface( HWND hwnd, const RECT *surface_rect, str return TRUE; }
-static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, BOOL create_layered, - struct window_rects *rects, RECT *surface_rect ) +static struct window_surface *get_window_surface( HWND hwnd, UINT swp_flags, BOOL create_layered, + struct window_rects *rects, RECT *surface_rect ) { BOOL shaped, needs_surface, create_opaque, is_layered; HWND parent = NtUserGetAncestor( hwnd, GA_PARENT ); @@ -1940,17 +1940,13 @@ static struct window_surface *create_window_surface( HWND hwnd, UINT swp_flags, if (IsRectEmpty( surface_rect )) needs_surface = FALSE; else if (create_layered || is_layered) needs_surface = TRUE;
- if (!needs_surface && new_surface && new_surface != &dummy_surface) + if (needs_surface) + create_window_surface( hwnd, create_layered, surface_rect, &new_surface ); + else if (new_surface && new_surface != &dummy_surface) { window_surface_release( new_surface ); window_surface_add_ref( (new_surface = &dummy_surface) ); } - else if (needs_surface && !user_driver->pCreateWindowSurface( hwnd, create_layered, surface_rect, &new_surface ) && new_surface) - { - /* create or update window surface for top-level windows if the driver doesn't implement CreateWindowSurface */ - window_surface_release( new_surface ); - create_offscreen_window_surface( hwnd, surface_rect, &new_surface ); - }
if (new_surface && !is_layered) { @@ -2384,7 +2380,7 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_
TRACE( "window %p new_rects %s\n", hwnd, debugstr_window_rects( &new_rects ) );
- surface = create_window_surface( hwnd, swp_flags, TRUE, &new_rects, &surface_rect ); + surface = get_window_surface( hwnd, swp_flags, TRUE, &new_rects, &surface_rect ); apply_window_pos( hwnd, 0, swp_flags, surface, &new_rects, NULL ); if (!surface) return FALSE;
@@ -3699,7 +3695,7 @@ BOOL set_window_pos( WINDOWPOS *winpos, int parent_x, int parent_y )
calc_ncsize( winpos, &old_rects, &new_rects, valid_rects, parent_x, parent_y );
- surface = create_window_surface( winpos->hwnd, winpos->flags, FALSE, &new_rects, &surface_rect ); + surface = get_window_surface( winpos->hwnd, winpos->flags, FALSE, &new_rects, &surface_rect ); if (!apply_window_pos( winpos->hwnd, winpos->hwndInsertAfter, winpos->flags, surface, &new_rects, valid_rects )) { @@ -4498,7 +4494,7 @@ void update_window_state( HWND hwnd ) get_window_rects( hwnd, COORDS_PARENT, &new_rects, get_thread_dpi() ); valid_rects[0] = valid_rects[1] = new_rects.client;
- surface = create_window_surface( hwnd, swp_flags, FALSE, &new_rects, &surface_rect ); + surface = get_window_surface( hwnd, swp_flags, FALSE, &new_rects, &surface_rect ); apply_window_pos( hwnd, 0, swp_flags, surface, &new_rects, valid_rects ); if (surface) window_surface_release( surface );
@@ -5552,7 +5548,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, if (cs.y > 0x7fffffff - cy) new_rects.window.bottom = 0x7fffffff; new_rects.client = new_rects.window;
- surface = create_window_surface( hwnd, SWP_NOZORDER | SWP_NOACTIVATE, FALSE, &new_rects, &surface_rect ); + surface = get_window_surface( hwnd, SWP_NOZORDER | SWP_NOACTIVATE, FALSE, &new_rects, &surface_rect ); if (!apply_window_pos( hwnd, 0, SWP_NOZORDER | SWP_NOACTIVATE, surface, &new_rects, NULL )) { if (surface) window_surface_release( surface ); @@ -5591,7 +5587,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, send_message( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&new_rects.client ); map_window_points( 0, parent, (POINT *)&new_rects.client, 2, win_dpi );
- surface = create_window_surface( hwnd, SWP_NOACTIVATE, FALSE, &new_rects, &surface_rect ); + surface = get_window_surface( hwnd, SWP_NOACTIVATE, FALSE, &new_rects, &surface_rect ); apply_window_pos( hwnd, insert_after, SWP_NOACTIVATE, surface, &new_rects, NULL ); if (surface) window_surface_release( surface ); }