win32u: Mmove dummy surface implementation from user32.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-03-14 11:45:01 +01:00 committed by Alexandre Julliard
parent e411d91958
commit 4bb7e5af52
8 changed files with 126 additions and 117 deletions

View File

@ -169,9 +169,11 @@ static void update_visible_region( struct dce *dce )
*/ */
static void release_dce( struct dce *dce ) static void release_dce( struct dce *dce )
{ {
struct window_surface *dummy_surface = (struct window_surface *)NtUserCallHwnd( 0, NtUserGetDummySurface );
if (!dce->hwnd) return; /* already released */ if (!dce->hwnd) return; /* already released */
__wine_set_visible_region( dce->hdc, 0, &dummy_surface.rect, &dummy_surface.rect, &dummy_surface ); __wine_set_visible_region( dce->hdc, 0, &dummy_surface->rect, &dummy_surface->rect, dummy_surface );
USER_Driver->pReleaseDC( dce->hwnd, dce->hdc ); USER_Driver->pReleaseDC( dce->hwnd, dce->hdc );
if (dce->clip_rgn) DeleteObject( dce->clip_rgn ); if (dce->clip_rgn) DeleteObject( dce->clip_rgn );

View File

@ -365,72 +365,6 @@ BOOL is_desktop_window( HWND hwnd )
} }
/*******************************************************************
* Dummy window surface for windows that shouldn't get painted.
*/
static void CDECL dummy_surface_lock( struct window_surface *window_surface )
{
/* nothing to do */
}
static void CDECL dummy_surface_unlock( struct window_surface *window_surface )
{
/* nothing to do */
}
static void *CDECL dummy_surface_get_bitmap_info( struct window_surface *window_surface, BITMAPINFO *info )
{
static DWORD dummy_data;
info->bmiHeader.biSize = sizeof( info->bmiHeader );
info->bmiHeader.biWidth = dummy_surface.rect.right;
info->bmiHeader.biHeight = dummy_surface.rect.bottom;
info->bmiHeader.biPlanes = 1;
info->bmiHeader.biBitCount = 32;
info->bmiHeader.biCompression = BI_RGB;
info->bmiHeader.biSizeImage = 0;
info->bmiHeader.biXPelsPerMeter = 0;
info->bmiHeader.biYPelsPerMeter = 0;
info->bmiHeader.biClrUsed = 0;
info->bmiHeader.biClrImportant = 0;
return &dummy_data;
}
static RECT *CDECL dummy_surface_get_bounds( struct window_surface *window_surface )
{
static RECT dummy_bounds;
return &dummy_bounds;
}
static void CDECL dummy_surface_set_region( struct window_surface *window_surface, HRGN region )
{
/* nothing to do */
}
static void CDECL dummy_surface_flush( struct window_surface *window_surface )
{
/* nothing to do */
}
static void CDECL dummy_surface_destroy( struct window_surface *window_surface )
{
/* nothing to do */
}
static const struct window_surface_funcs dummy_surface_funcs =
{
dummy_surface_lock,
dummy_surface_unlock,
dummy_surface_get_bitmap_info,
dummy_surface_get_bounds,
dummy_surface_set_region,
dummy_surface_flush,
dummy_surface_destroy
};
struct window_surface dummy_surface = { &dummy_surface_funcs, { NULL, NULL }, 1, { 0, 0, 1, 1 } };
/******************************************************************* /*******************************************************************
* Off-screen window surface. * Off-screen window surface.
*/ */
@ -569,8 +503,6 @@ void create_offscreen_window_surface( const RECT *visible_rect, struct window_su
*/ */
void register_window_surface( struct window_surface *old, struct window_surface *new ) void register_window_surface( struct window_surface *old, struct window_surface *new )
{ {
if (old == &dummy_surface) old = NULL;
if (new == &dummy_surface) new = NULL;
NtUserCallTwoParam( (UINT_PTR)old, (UINT_PTR)new, NtUserRegisterWindowSurface ); NtUserCallTwoParam( (UINT_PTR)old, (UINT_PTR)new, NtUserRegisterWindowSurface );
} }

View File

@ -36,7 +36,6 @@ struct tagDIALOGINFO;
/* Window functions */ /* Window functions */
extern HWND get_hwnd_message_parent(void) DECLSPEC_HIDDEN; extern HWND get_hwnd_message_parent(void) DECLSPEC_HIDDEN;
extern BOOL is_desktop_window( HWND hwnd ) DECLSPEC_HIDDEN; extern BOOL is_desktop_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern struct window_surface dummy_surface DECLSPEC_HIDDEN;
extern void register_window_surface( struct window_surface *old, struct window_surface *new ) DECLSPEC_HIDDEN; extern void register_window_surface( struct window_surface *old, struct window_surface *new ) DECLSPEC_HIDDEN;
extern void flush_window_surfaces( BOOL idle ) DECLSPEC_HIDDEN; extern void flush_window_surfaces( BOOL idle ) DECLSPEC_HIDDEN;
extern WND *WIN_GetPtr( HWND hwnd ) DECLSPEC_HIDDEN; extern WND *WIN_GetPtr( HWND hwnd ) DECLSPEC_HIDDEN;

View File

@ -1976,10 +1976,11 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
BOOL ret, needs_update = FALSE; BOOL ret, needs_update = FALSE;
RECT visible_rect, old_visible_rect, old_window_rect, old_client_rect, extra_rects[3]; RECT visible_rect, old_visible_rect, old_window_rect, old_client_rect, extra_rects[3];
struct window_surface *old_surface, *new_surface = NULL; struct window_surface *old_surface, *new_surface = NULL;
struct window_surface *dummy_surface = (struct window_surface *)NtUserCallHwnd( 0, NtUserGetDummySurface );
if (!parent || parent == GetDesktopWindow()) if (!parent || parent == GetDesktopWindow())
{ {
new_surface = &dummy_surface; /* provide a default surface for top-level windows */ new_surface = dummy_surface; /* provide a default surface for top-level windows */
window_surface_add_ref( new_surface ); window_surface_add_ref( new_surface );
} }
visible_rect = *window_rect; visible_rect = *window_rect;
@ -2017,8 +2018,8 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags,
old_client_rect = win->client_rect; old_client_rect = win->client_rect;
old_surface = win->surface; old_surface = win->surface;
if (old_surface != new_surface) swp_flags |= SWP_FRAMECHANGED; /* force refreshing non-client area */ if (old_surface != new_surface) swp_flags |= SWP_FRAMECHANGED; /* force refreshing non-client area */
if (new_surface == &dummy_surface) swp_flags |= SWP_NOREDRAW; if (new_surface == dummy_surface) swp_flags |= SWP_NOREDRAW;
else if (old_surface == &dummy_surface) else if (old_surface == dummy_surface)
{ {
swp_flags |= SWP_NOCOPYBITS; swp_flags |= SWP_NOCOPYBITS;
valid_rects = NULL; valid_rects = NULL;

View File

@ -23,9 +23,119 @@
#pragma makedep unix #pragma makedep unix
#endif #endif
#include <pthread.h>
#include "ntgdi_private.h" #include "ntgdi_private.h"
#include "ntuser_private.h" #include "ntuser_private.h"
static struct list window_surfaces = LIST_INIT( window_surfaces );
static pthread_mutex_t surfaces_lock = PTHREAD_MUTEX_INITIALIZER;
/*******************************************************************
* Dummy window surface for windows that shouldn't get painted.
*/
static void CDECL dummy_surface_lock( struct window_surface *window_surface )
{
/* nothing to do */
}
static void CDECL dummy_surface_unlock( struct window_surface *window_surface )
{
/* nothing to do */
}
static void *CDECL dummy_surface_get_bitmap_info( struct window_surface *window_surface, BITMAPINFO *info )
{
static DWORD dummy_data;
info->bmiHeader.biSize = sizeof( info->bmiHeader );
info->bmiHeader.biWidth = dummy_surface.rect.right;
info->bmiHeader.biHeight = dummy_surface.rect.bottom;
info->bmiHeader.biPlanes = 1;
info->bmiHeader.biBitCount = 32;
info->bmiHeader.biCompression = BI_RGB;
info->bmiHeader.biSizeImage = 0;
info->bmiHeader.biXPelsPerMeter = 0;
info->bmiHeader.biYPelsPerMeter = 0;
info->bmiHeader.biClrUsed = 0;
info->bmiHeader.biClrImportant = 0;
return &dummy_data;
}
static RECT *CDECL dummy_surface_get_bounds( struct window_surface *window_surface )
{
static RECT dummy_bounds;
return &dummy_bounds;
}
static void CDECL dummy_surface_set_region( struct window_surface *window_surface, HRGN region )
{
/* nothing to do */
}
static void CDECL dummy_surface_flush( struct window_surface *window_surface )
{
/* nothing to do */
}
static void CDECL dummy_surface_destroy( struct window_surface *window_surface )
{
/* nothing to do */
}
static const struct window_surface_funcs dummy_surface_funcs =
{
dummy_surface_lock,
dummy_surface_unlock,
dummy_surface_get_bitmap_info,
dummy_surface_get_bounds,
dummy_surface_set_region,
dummy_surface_flush,
dummy_surface_destroy
};
struct window_surface dummy_surface = { &dummy_surface_funcs, { NULL, NULL }, 1, { 0, 0, 1, 1 } };
/*******************************************************************
* register_window_surface
*
* Register a window surface in the global list, possibly replacing another one.
*/
void register_window_surface( struct window_surface *old, struct window_surface *new )
{
if (old == &dummy_surface) old = NULL;
if (new == &dummy_surface) new = NULL;
if (old == new) return;
pthread_mutex_lock( &surfaces_lock );
if (old) list_remove( &old->entry );
if (new) list_add_tail( &window_surfaces, &new->entry );
pthread_mutex_unlock( &surfaces_lock );
}
/*******************************************************************
* flush_window_surfaces
*
* Flush pending output from all window surfaces.
*/
void flush_window_surfaces( BOOL idle )
{
static DWORD last_idle;
DWORD now;
struct window_surface *surface;
pthread_mutex_lock( &surfaces_lock );
now = NtGetTickCount();
if (idle) last_idle = now;
/* if not idle, we only flush if there's evidence that the app never goes idle */
else if ((int)(now - last_idle) < 50) goto done;
LIST_FOR_EACH_ENTRY( surface, &window_surfaces, struct window_surface, entry )
surface->funcs->flush( surface );
done:
pthread_mutex_unlock( &surfaces_lock );
}
/********************************************************************** /**********************************************************************
* NtUserWindowFromDC (win32u.@) * NtUserWindowFromDC (win32u.@)
*/ */

View File

@ -280,6 +280,12 @@ extern BOOL get_clip_cursor( RECT *rect ) DECLSPEC_HIDDEN;
extern ULONG_PTR get_icon_param( HICON handle ) DECLSPEC_HIDDEN; extern ULONG_PTR get_icon_param( HICON handle ) DECLSPEC_HIDDEN;
extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param ) DECLSPEC_HIDDEN; extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param ) DECLSPEC_HIDDEN;
/* dce.c */
extern struct window_surface dummy_surface DECLSPEC_HIDDEN;
extern void flush_window_surfaces( BOOL idle ) DECLSPEC_HIDDEN;
extern void register_window_surface( struct window_surface *old,
struct window_surface *new ) DECLSPEC_HIDDEN;
/* hook.c */ /* hook.c */
extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
extern LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode ) DECLSPEC_HIDDEN; extern LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode ) DECLSPEC_HIDDEN;
@ -327,13 +333,10 @@ extern BOOL get_window_placement( HWND hwnd, WINDOWPLACEMENT *placement ) DECLSP
extern DWORD get_window_thread( HWND hwnd, DWORD *process ) DECLSPEC_HIDDEN; extern DWORD get_window_thread( HWND hwnd, DWORD *process ) DECLSPEC_HIDDEN;
extern HWND is_current_thread_window( HWND hwnd ) DECLSPEC_HIDDEN; extern HWND is_current_thread_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern BOOL is_iconic( HWND hwnd ) DECLSPEC_HIDDEN; extern BOOL is_iconic( HWND hwnd ) DECLSPEC_HIDDEN;
extern void flush_window_surfaces( BOOL idle ) DECLSPEC_HIDDEN;
extern DWORD get_window_long( HWND hwnd, INT offset ) DECLSPEC_HIDDEN; extern DWORD get_window_long( HWND hwnd, INT offset ) DECLSPEC_HIDDEN;
extern BOOL get_window_rect( HWND hwnd, RECT *rect, UINT dpi ) DECLSPEC_HIDDEN; extern BOOL get_window_rect( HWND hwnd, RECT *rect, UINT dpi ) DECLSPEC_HIDDEN;
extern HWND *list_window_children( HDESK desktop, HWND hwnd, UNICODE_STRING *class, extern HWND *list_window_children( HDESK desktop, HWND hwnd, UNICODE_STRING *class,
DWORD tid ) DECLSPEC_HIDDEN; DWORD tid ) DECLSPEC_HIDDEN;
extern void register_window_surface( struct window_surface *old,
struct window_surface *new ) DECLSPEC_HIDDEN;
extern void update_window_state( HWND hwnd ) DECLSPEC_HIDDEN; extern void update_window_state( HWND hwnd ) DECLSPEC_HIDDEN;
/* to release pointers retrieved by win_get_ptr */ /* to release pointers retrieved by win_get_ptr */

View File

@ -23,7 +23,6 @@
#pragma makedep unix #pragma makedep unix
#endif #endif
#include <pthread.h>
#include <assert.h> #include <assert.h>
#include "ntstatus.h" #include "ntstatus.h"
@ -40,9 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
static void *user_handles[NB_USER_HANDLES]; static void *user_handles[NB_USER_HANDLES];
static struct list window_surfaces = LIST_INIT( window_surfaces );
static pthread_mutex_t surfaces_lock = PTHREAD_MUTEX_INITIALIZER;
/*********************************************************************** /***********************************************************************
* alloc_user_handle * alloc_user_handle
*/ */
@ -206,43 +202,6 @@ HWND get_full_window_handle( HWND hwnd )
return hwnd; return hwnd;
} }
/*******************************************************************
* register_window_surface
*
* Register a window surface in the global list, possibly replacing another one.
*/
void register_window_surface( struct window_surface *old, struct window_surface *new )
{
if (old == new) return;
pthread_mutex_lock( &surfaces_lock );
if (old) list_remove( &old->entry );
if (new) list_add_tail( &window_surfaces, &new->entry );
pthread_mutex_unlock( &surfaces_lock );
}
/*******************************************************************
* flush_window_surfaces
*
* Flush pending output from all window surfaces.
*/
void flush_window_surfaces( BOOL idle )
{
static DWORD last_idle;
DWORD now;
struct window_surface *surface;
pthread_mutex_lock( &surfaces_lock );
now = NtGetTickCount();
if (idle) last_idle = now;
/* if not idle, we only flush if there's evidence that the app never goes idle */
else if ((int)(now - last_idle) < 50) goto done;
LIST_FOR_EACH_ENTRY( surface, &window_surfaces, struct window_surface, entry )
surface->funcs->flush( surface );
done:
pthread_mutex_unlock( &surfaces_lock );
}
/******************************************************************* /*******************************************************************
* is_desktop_window * is_desktop_window
* *
@ -1896,6 +1855,8 @@ ULONG_PTR WINAPI NtUserCallHwnd( HWND hwnd, DWORD code )
/* temporary exports */ /* temporary exports */
case NtUserCreateDesktopWindow: case NtUserCreateDesktopWindow:
return user_driver->pCreateDesktopWindow( hwnd ); return user_driver->pCreateDesktopWindow( hwnd );
case NtUserGetDummySurface:
return (UINT_PTR)&dummy_surface;
default: default:
FIXME( "invalid code %u\n", code ); FIXME( "invalid code %u\n", code );
return 0; return 0;

View File

@ -151,6 +151,7 @@ enum
NtUserIsWindowVisible, NtUserIsWindowVisible,
/* temporary exports */ /* temporary exports */
NtUserCreateDesktopWindow, NtUserCreateDesktopWindow,
NtUserGetDummySurface,
}; };
/* NtUserCallHwndParam codes, not compatible with Windows */ /* NtUserCallHwndParam codes, not compatible with Windows */