[PATCH v3 0/15] MR11162: winmm: Avoid loop counter underflow when dwLoops is 0.
dwFlags = WHDR_BEGINLOOP|WHDR_ENDLOOP with dwLoops 0 underflowed loop_counter to 0xffffffff, so the buffer was never finished and playback looped forever. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59874 -- v3: win32u: Implement NtUserGetPointerDeviceRects for INVALID_HANDLE_VALUE. user32/tests: Add more GetPointerDeviceRects tests with DPI scaling. user32/tests: Use 1024x768 as test resolution for DPI scaling on Windows. win32u/tests: Add NtUserGetPointerDeviceRects test for INVALID_HANDLE_VALUE. win32u: Stub NtUserGetPointerDeviceRects. win32u: Stub NtUserGetPointerType. win32u: Create OpenGL client surfaces from win32u. win32u: Create vulkan client surfaces from win32u. win32u: Add a new driver entry to create client surfaces. win32u: Always flush the window surface in expose_window_surface. winewayland: Fix missing wayland_win_data_release. gdi.exe: Don't use biSizeImage when calculating DIB pitch. nsiproxy.sys: Link to pthread libs for pthread_once. user32: Don't send a message in GetComboBoxInfo(). https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Ned Son <nedsociety@gmail.com> dwFlags = WHDR_BEGINLOOP|WHDR_ENDLOOP with dwLoops 0 underflowed loop_counter to 0xffffffff, so the buffer was never finished and playback looped forever. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59874 --- dlls/winmm/waveform.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dlls/winmm/waveform.c b/dlls/winmm/waveform.c index 5b9134da696..e3a4f5faca9 100644 --- a/dlls/winmm/waveform.c +++ b/dlls/winmm/waveform.c @@ -1570,8 +1570,7 @@ static void WOD_PushData(WINMM_Device *device) device->loop_counter = queue->dwLoops; } if(queue->dwFlags & WHDR_ENDLOOP){ - --device->loop_counter; - if(device->loop_counter) + if(device->loop_counter && --device->loop_counter) device->playing = device->loop_start; else device->loop_start = device->playing = queue->lpNext; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Alexandre Julliard <julliard@winehq.org> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59820 --- dlls/user32/combo.c | 24 ++++++++---------- dlls/user32/tests/combo.c | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 14 deletions(-) diff --git a/dlls/user32/combo.c b/dlls/user32/combo.c index b251402602c..cb927341222 100644 --- a/dlls/user32/combo.c +++ b/dlls/user32/combo.c @@ -1672,11 +1672,17 @@ static void COMBO_MouseMove( LPHEADCOMBO lphc, WPARAM wParam, LPARAM lParam ) } } -static LRESULT COMBO_GetComboBoxInfo(const HEADCOMBO *lphc, COMBOBOXINFO *pcbi) + +/************************************************************************* + * GetComboBoxInfo (USER32.@) + */ +BOOL WINAPI GetComboBoxInfo( HWND hwnd, COMBOBOXINFO *pcbi ) { - if (!pcbi || (pcbi->cbSize < sizeof(COMBOBOXINFO))) - return FALSE; + HEADCOMBO *lphc = get_control_state( hwnd ); + if (!lphc || !pcbi || (pcbi->cbSize < sizeof(COMBOBOXINFO))) + return FALSE; + TRACE("(%p, %p)\n", hwnd, pcbi); pcbi->rcItem = lphc->textRect; pcbi->rcButton = lphc->buttonRect; pcbi->stateButton = 0; @@ -2078,7 +2084,7 @@ LRESULT ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar case CB_GETEXTENDEDUI: return (lphc->wState & CBF_EUI) != 0; case CB_GETCOMBOBOXINFO: - return COMBO_GetComboBoxInfo(lphc, (COMBOBOXINFO *)lParam); + return GetComboBoxInfo(hwnd, (COMBOBOXINFO *)lParam); case CB_LIMITTEXT: if( lphc->wState & CBF_EDIT ) return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam); @@ -2092,13 +2098,3 @@ LRESULT ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar return unicode ? DefWindowProcW(hwnd, message, wParam, lParam) : DefWindowProcA(hwnd, message, wParam, lParam); } - -/************************************************************************* - * GetComboBoxInfo (USER32.@) - */ -BOOL WINAPI GetComboBoxInfo(HWND hwndCombo, /* [in] handle to combo box */ - PCOMBOBOXINFO pcbi /* [in/out] combo box information */) -{ - TRACE("(%p, %p)\n", hwndCombo, pcbi); - return SendMessageW(hwndCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi); -} diff --git a/dlls/user32/tests/combo.c b/dlls/user32/tests/combo.c index 8d93369d79a..cb190e32ae2 100644 --- a/dlls/user32/tests/combo.c +++ b/dlls/user32/tests/combo.c @@ -1026,6 +1026,56 @@ static void test_combo_measureitem(DWORD style) winetest_pop_context(); } +static int got_info; +static WNDPROC old_combo_proc; + +static LRESULT CALLBACK combo_wnd_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + if (msg == CB_GETCOMBOBOXINFO) got_info++; + return CallWindowProcA( old_combo_proc, hwnd, msg, wparam, lparam ); +} + +static DWORD CALLBACK combo_thread( void *arg ) +{ + unsigned int ret; + COMBOBOXINFO info = { .cbSize = sizeof(COMBOBOXINFO) }; + HWND combo = arg; + + got_info = 0; + ret = GetComboBoxInfo(combo, &info); + ok( ret, "Failed to get combobox info structure.\n" ); + ok( !got_info, "CB_GETCOMBOBOXINFO was sent from other thread\n" ); + return 0; +} + +static void test_combo_info(void) +{ + unsigned int ret; + COMBOBOXINFO info = { .cbSize = sizeof(COMBOBOXINFO) }; + HWND combo; + HANDLE thread; + DWORD id; + + combo = build_combo(CBS_DROPDOWN); + ok(!!combo, "Failed to create combo window.\n"); + + old_combo_proc = (void *)SetWindowLongPtrA( combo, GWLP_WNDPROC, (ULONG_PTR)combo_wnd_proc ); + + got_info = 0; + ret = GetComboBoxInfo( combo, &info ); + ok( ret, "Failed to get combobox info structure.\n" ); + ok( !got_info, "CB_GETCOMBOBOXINFO was sent\n" ); + thread = CreateThread( NULL, 0, combo_thread, combo, 0, &id ); + while (MsgWaitForMultipleObjects( 1, &thread, FALSE, INFINITE, MWMO_WAITALL ) != WAIT_OBJECT_0) + { + MSG msg; + while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg ); + } + CloseHandle( thread ); + SetWindowLongPtrA( combo, GWLP_WNDPROC, (ULONG_PTR)old_combo_proc ); + DestroyWindow( combo ); +} + START_TEST(combo) { brush_red = CreateSolidBrush(RGB(255, 0, 0)); @@ -1054,6 +1104,7 @@ START_TEST(combo) test_combo_measureitem(CBS_DROPDOWNLIST | CBS_OWNERDRAWVARIABLE); test_combo_measureitem(CBS_DROPDOWNLIST); test_combo_measureitem(CBS_DROPDOWN | CBS_OWNERDRAWFIXED); + test_combo_info(); DestroyWindow(hMainWnd); DeleteObject(brush_red); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Alexandre Julliard <julliard@winehq.org> --- dlls/nsiproxy.sys/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/nsiproxy.sys/Makefile.in b/dlls/nsiproxy.sys/Makefile.in index 40ea0701a46..6b5fbe7aa6d 100644 --- a/dlls/nsiproxy.sys/Makefile.in +++ b/dlls/nsiproxy.sys/Makefile.in @@ -1,7 +1,7 @@ MODULE = nsiproxy.sys UNIXLIB = nsiproxy.so IMPORTS = ntoskrnl -UNIX_LIBS = $(PROCSTAT_LIBS) +UNIX_LIBS = $(PROCSTAT_LIBS) $(PTHREAD_LIBS) EXTRADLLFLAGS = -Wl,--subsystem,native -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Dmitry Timoshkov <dmitry@baikal.ru> An application may set biSizeImage to 0. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59871 Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> --- dlls/gdi.exe16/gdi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dlls/gdi.exe16/gdi.c b/dlls/gdi.exe16/gdi.c index 564b0484857..38b0b12ea89 100644 --- a/dlls/gdi.exe16/gdi.c +++ b/dlls/gdi.exe16/gdi.c @@ -1190,12 +1190,13 @@ HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output, { .Width = info->bmiHeader.biWidth, .Height = abs( info->bmiHeader.biHeight ), - .Pitch = info->bmiHeader.biSizeImage / abs( info->bmiHeader.biHeight ), }; struct saved_bitmap *bitmap; UINT status; int color; + desc.Pitch = ((info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) >> 3) & ~3; + if (info->bmiHeader.biBitCount <= 8) { if (info->bmiHeader.biClrUsed) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_surface.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 7ba2a1ea2fd..beb7f5734a7 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -170,6 +170,8 @@ void wp_fractional_scale_handle_scale(void* user_data, surface->processing.processed = TRUE; } + wayland_win_data_release(data); + NtUserExposeWindowSurface(hwnd, 0, NULL, 0); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/win32u/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index c3a32dde6cf..7c17b32787e 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2383,7 +2383,7 @@ static BOOL expose_window_surface( HWND hwnd, UINT flags, const RECT *rect, UINT add_bounds_rect( &surface->bounds, &exposed_rect ); } window_surface_unlock( surface ); - if (surface->alpha_mask) window_surface_flush( surface ); + window_surface_flush( surface ); window_surface_release( surface ); return TRUE; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/driver.c | 60 +++++++++++++------------- dlls/win32u/opengl.c | 2 +- dlls/win32u/vulkan.c | 2 +- dlls/win32u/win32u_private.h | 1 - dlls/wineandroid.drv/android.h | 1 + dlls/wineandroid.drv/init.c | 1 + dlls/wineandroid.drv/opengl.c | 7 ++- dlls/winemac.drv/gdi.c | 1 + dlls/winemac.drv/macdrv.h | 8 +--- dlls/winemac.drv/opengl.c | 8 ++-- dlls/winemac.drv/vulkan.c | 4 +- dlls/winemac.drv/window.c | 10 ++++- dlls/winewayland.drv/opengl.c | 14 +++--- dlls/winewayland.drv/vulkan.c | 5 ++- dlls/winewayland.drv/wayland_surface.c | 15 ++++--- dlls/winewayland.drv/waylanddrv.h | 4 +- dlls/winewayland.drv/waylanddrv_main.c | 1 + dlls/winex11.drv/init.c | 38 ++++++---------- dlls/winex11.drv/opengl.c | 18 ++++---- dlls/winex11.drv/vulkan.c | 7 ++- dlls/winex11.drv/x11drv.h | 16 ++++++- include/wine/gdi_driver.h | 3 +- 22 files changed, 129 insertions(+), 97 deletions(-) diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index c7a78cd327d..cfe0650648b 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -879,6 +879,35 @@ static BOOL nulldrv_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *swp return FALSE; } +static void nulldrv_surface_destroy( struct client_surface *client ) +{ +} + +static void nulldrv_surface_detach( struct client_surface *client ) +{ +} + +static void nulldrv_surface_update( struct client_surface *client ) +{ +} + +static void nulldrv_surface_present( struct client_surface *client, HDC hdc ) +{ +} + +static const struct client_surface_funcs nulldrv_surface_funcs = +{ + .destroy = nulldrv_surface_destroy, + .detach = nulldrv_surface_detach, + .update = nulldrv_surface_update, + .present = nulldrv_surface_present, +}; + +static struct client_surface *nulldrv_CreateClientSurface( HWND hwnd, int pixel_format ) +{ + return client_surface_create( sizeof(struct client_surface), &nulldrv_surface_funcs, hwnd ); +} + static BOOL nulldrv_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ) { return FALSE; @@ -1302,6 +1331,7 @@ static const struct user_driver_funcs lazy_load_driver = nulldrv_WindowPosChanging, nulldrv_GetWindowStyleMasks, nulldrv_GetWindowStateUpdates, + nulldrv_CreateClientSurface, nulldrv_CreateWindowSurface, nulldrv_MoveWindowBits, nulldrv_WindowPosChanged, @@ -1401,6 +1431,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(WindowPosChanging); SET_USER_FUNC(GetWindowStyleMasks); SET_USER_FUNC(GetWindowStateUpdates); + SET_USER_FUNC(CreateClientSurface); SET_USER_FUNC(CreateWindowSurface); SET_USER_FUNC(MoveWindowBits); SET_USER_FUNC(WindowPosChanged); @@ -1439,32 +1470,3 @@ INT WINAPI NtGdiExtEscape( HDC hdc, WCHAR *driver, int driver_id, INT escape, IN release_dc_ptr( dc ); return ret; } - -static void nulldrv_surface_destroy( struct client_surface *client ) -{ -} - -static void nulldrv_surface_detach( struct client_surface *client ) -{ -} - -static void nulldrv_surface_update( struct client_surface *client ) -{ -} - -static void nulldrv_surface_present( struct client_surface *client, HDC hdc ) -{ -} - -static const struct client_surface_funcs nulldrv_surface_funcs = -{ - .destroy = nulldrv_surface_destroy, - .detach = nulldrv_surface_detach, - .update = nulldrv_surface_update, - .present = nulldrv_surface_present, -}; - -struct client_surface *nulldrv_client_surface_create( HWND hwnd ) -{ - return client_surface_create( sizeof(struct client_surface), &nulldrv_surface_funcs, hwnd ); -} diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 3d03b41fc24..089452198de 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -664,7 +664,7 @@ static BOOL egldrv_surface_create( HWND hwnd, int format, struct opengl_drawable { struct client_surface *client; - if (!(client = nulldrv_client_surface_create( hwnd ))) return FALSE; + if (!(client = user_driver->pCreateClientSurface( hwnd, format ))) return FALSE; *drawable = framebuffer_surface_create( format, client ); client_surface_release( client ); diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index bf8f6f1daba..c95038ed6a4 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -2930,7 +2930,7 @@ static VkResult nulldrv_vulkan_surface_create( HWND hwnd, const struct vulkan_in VkHeadlessSurfaceCreateInfoEXT create_info = {.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; VkResult res; - if (!(*client = nulldrv_client_surface_create( hwnd ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (!(*client = user_driver->pCreateClientSurface( hwnd, 0 ))) return VK_ERROR_OUT_OF_HOST_MEMORY; if ((res = instance->p_vkCreateHeadlessSurfaceEXT( instance->host.instance, &create_info, NULL, surface ))) { client_surface_release(*client); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index be303ae4d13..620d848488d 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -354,7 +354,6 @@ extern HKEY hkcu_key; /* driver.c */ extern const struct user_driver_funcs *user_driver; -extern struct client_surface *nulldrv_client_surface_create( HWND hwnd ); extern ULONG_PTR zero_bits; diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index cc558aa01f6..c63e7b1fd79 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -115,6 +115,7 @@ extern void ANDROID_SetCapture( HWND hwnd, UINT flags ); extern UINT ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ); extern LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ); +extern struct client_surface *ANDROID_CreateClientSurface( HWND hwnd, int pixel_format ); extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface ); diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index df0cb2b72ec..2dca7362a69 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -322,6 +322,7 @@ static const struct user_driver_funcs android_drv_funcs = .pShowWindow = ANDROID_ShowWindow, .pWindowMessage = ANDROID_WindowMessage, .pWindowPosChanging = ANDROID_WindowPosChanging, + .pCreateClientSurface = ANDROID_CreateClientSurface, .pCreateWindowSurface = ANDROID_CreateWindowSurface, .pWindowPosChanged = ANDROID_WindowPosChanged, .pOpenGLInit = ANDROID_OpenGLInit, diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 62b4fa7dd6c..2800126761f 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -108,7 +108,7 @@ static BOOL android_surface_create( HWND hwnd, int format, struct opengl_drawabl EGLConfig config = egl_config_for_format( format ); struct client_surface *client; - if (!(client = client_surface_create( sizeof(*client), &android_client_surface_funcs, hwnd ))) return FALSE; + if (!(client = ANDROID_CreateClientSurface( hwnd, format ))) return FALSE; gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, client ); client_surface_release( client ); if (!gl) return FALSE; @@ -194,6 +194,11 @@ static const struct client_surface_funcs android_client_surface_funcs = .present = android_client_surface_present, }; +struct client_surface *ANDROID_CreateClientSurface( HWND hwnd, int pixel_format ) +{ + return client_surface_create( sizeof(struct client_surface), &android_client_surface_funcs, hwnd ); +} + static const struct opengl_drawable_funcs android_drawable_funcs = { .destroy = android_drawable_destroy, diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index a0f314234b9..906bb4d09e6 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -284,6 +284,7 @@ static const struct user_driver_funcs macdrv_funcs = .pWindowPosChanged = macdrv_WindowPosChanged, .pWindowPosChanging = macdrv_WindowPosChanging, .pGetWindowStyleMasks = macdrv_GetWindowStyleMasks, + .pCreateClientSurface = macdrv_CreateClientSurface, .pCreateWindowSurface = macdrv_CreateWindowSurface, .pVulkanInit = macdrv_VulkanInit, .pOpenGLInit = macdrv_OpenGLInit, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 4f7107baf68..0aef8cdd60f 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -150,6 +150,7 @@ extern void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alph extern LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects); extern BOOL macdrv_GetWindowStyleMasks(HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask); +extern struct client_surface *macdrv_CreateClientSurface(HWND hwnd, int pixel_format); extern BOOL macdrv_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface); @@ -200,12 +201,7 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p macdrv_metal_swapchain metal_swapchain; }; -static inline struct macdrv_client_surface *impl_from_client_surface(struct client_surface *client) -{ - return CONTAINING_RECORD(client, struct macdrv_client_surface, client); -} - -extern struct macdrv_client_surface *macdrv_client_surface_create(HWND hwnd); +extern struct macdrv_client_surface *impl_from_client_surface(struct client_surface *client); extern BOOL macdrv_client_surface_acquire_metal_swapchain(struct macdrv_client_surface *surface); extern struct macdrv_win_data *get_win_data(HWND hwnd); diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 0af1d3f7192..86830bffc80 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -1457,7 +1457,7 @@ static BOOL create_context(struct macdrv_context *context, CGLContextObj share, static BOOL macdrv_surface_create(HWND hwnd, int format, struct opengl_drawable **drawable) { - struct macdrv_client_surface *client; + struct client_surface *client; struct macdrv_win_data *data; struct gl_drawable *gl; @@ -1472,9 +1472,9 @@ static BOOL macdrv_surface_create(HWND hwnd, int format, struct opengl_drawable data->pixel_format = format; release_win_data(data); - if (!(client = macdrv_client_surface_create(hwnd))) return FALSE; - gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, &client->client); - client_surface_release(&client->client); + if (!(client = macdrv_CreateClientSurface(hwnd, format))) return FALSE; + gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, client); + client_surface_release(client); if (!gl) return FALSE; *drawable = &gl->base; diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c index f1643e3e5c4..41c148627fb 100644 --- a/dlls/winemac.drv/vulkan.c +++ b/dlls/winemac.drv/vulkan.c @@ -45,10 +45,12 @@ static VkResult macdrv_vulkan_surface_create(HWND hwnd, const struct vulkan_inst { VkResult res; struct macdrv_client_surface *surface; + struct client_surface *ptr; TRACE("%p %p %p %p\n", hwnd, instance, handle, client); - if (!(surface = macdrv_client_surface_create(hwnd))) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (!(ptr = macdrv_CreateClientSurface(hwnd, 0))) return VK_ERROR_OUT_OF_HOST_MEMORY; + surface = impl_from_client_surface( ptr ); if (!macdrv_client_surface_acquire_metal_swapchain(surface)) goto err; diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index adfc059e34f..4ed488cd760 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1144,7 +1144,13 @@ static const struct client_surface_funcs macdrv_client_surface_funcs = .present = macdrv_client_surface_present, }; -struct macdrv_client_surface *macdrv_client_surface_create(HWND hwnd) +struct macdrv_client_surface *impl_from_client_surface(struct client_surface *client) +{ + assert(client->funcs == &macdrv_client_surface_funcs); + return CONTAINING_RECORD(client, struct macdrv_client_surface, client); +} + +struct client_surface *macdrv_CreateClientSurface(HWND hwnd, int pixel_format) { HWND toplevel = NtUserGetAncestor(hwnd, GA_ROOT); struct macdrv_client_surface *surface; @@ -1163,7 +1169,7 @@ struct macdrv_client_surface *macdrv_client_surface_create(HWND hwnd) macdrv_client_surface_present(&surface->client, 0); } - return surface; + return &surface->client; } BOOL macdrv_client_surface_acquire_metal_swapchain(struct macdrv_client_surface *surface) diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 66457e1aea5..9719c63719d 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -83,10 +83,11 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_drawable **drawable) { EGLConfig config = egl_config_for_format(format); - struct wayland_client_surface *client; + struct wayland_client_surface *surface; EGLint attribs[4], *attrib = attribs; struct opengl_drawable *previous; struct wayland_gl_drawable *gl; + struct client_surface *client; RECT rect; TRACE("hwnd=%p format=%d\n", hwnd, format); @@ -106,9 +107,10 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_d } *attrib++ = EGL_NONE; - if (!(client = wayland_client_surface_create(hwnd))) return FALSE; - gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, &client->client); - client_surface_release(&client->client); + if (!(client = WAYLAND_CreateClientSurface(hwnd, format))) return FALSE; + gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, client); + surface = impl_from_client_surface(client); /* reference held by gl */ + client_surface_release(client); if (!gl) return FALSE; opengl_drawable_map_buffer(&gl->base, GL_FRONT_LEFT, GL_BACK_LEFT); @@ -116,9 +118,9 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_d opengl_drawable_map_buffer(&gl->base, GL_FRONT_AND_BACK, GL_BACK); if (gl->base.stereo) opengl_drawable_map_buffer(&gl->base, GL_FRONT_RIGHT, GL_BACK_RIGHT); - if (!(gl->wl_egl_window = wl_egl_window_create(client->wl_surface, rect.right, rect.bottom))) goto err; + if (!(gl->wl_egl_window = wl_egl_window_create(surface->wl_surface, rect.right, rect.bottom))) goto err; if (!(gl->base.surface = funcs->p_eglCreateWindowSurface(egl->display, config, gl->wl_egl_window, attribs))) goto err; - set_client_surface(hwnd, client); + set_client_surface(hwnd, surface); TRACE("Created drawable %s with egl_surface %p\n", debugstr_opengl_drawable(&gl->base), gl->base.surface); diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index b2e91102f58..65ebbc40b1f 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -44,10 +44,13 @@ static VkResult wayland_vulkan_surface_create(HWND hwnd, const struct vulkan_ins VkResult res; VkWaylandSurfaceCreateInfoKHR create_info_host; struct wayland_client_surface *surface; + struct client_surface *ptr; TRACE("%p %p %p %p\n", hwnd, instance, handle, client); - if (!(surface = wayland_client_surface_create(hwnd))) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (!(ptr = WAYLAND_CreateClientSurface(hwnd, 0))) return VK_ERROR_OUT_OF_HOST_MEMORY; + surface = impl_from_client_surface( ptr ); + create_info_host.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; create_info_host.pNext = NULL; create_info_host.flags = 0; /* reserved */ diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index beb7f5734a7..b28072331d6 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -1149,11 +1149,6 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, *window_y = round(surface_y * surface->window.scale); } -static struct wayland_client_surface *impl_from_client_surface(struct client_surface *client) -{ - return CONTAINING_RECORD(client, struct wayland_client_surface, client); -} - static void wayland_client_surface_destroy(struct client_surface *client) { struct wayland_client_surface *surface = impl_from_client_surface(client); @@ -1213,7 +1208,13 @@ static const struct client_surface_funcs wayland_client_surface_funcs = .present = wayland_client_surface_present, }; -struct wayland_client_surface *wayland_client_surface_create(HWND hwnd) +struct wayland_client_surface *impl_from_client_surface(struct client_surface *client) +{ + assert(client->funcs == &wayland_client_surface_funcs); + return CONTAINING_RECORD(client, struct wayland_client_surface, client); +} + +struct client_surface *WAYLAND_CreateClientSurface(HWND hwnd, int pixel_format) { struct wayland_client_surface *client; struct wl_region *empty_region; @@ -1248,7 +1249,7 @@ struct wayland_client_surface *wayland_client_surface_create(HWND hwnd) goto err; } - return client; + return &client->client; err: client_surface_release(&client->client); diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 3d30ab3d59c..07ac10e9f9e 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -254,6 +254,8 @@ struct wayland_client_surface struct wp_viewport *wp_viewport; }; +extern struct wayland_client_surface *impl_from_client_surface(struct client_surface *client); + struct wayland_shm_buffer { struct wl_list link; @@ -338,7 +340,6 @@ void wayland_surface_coords_from_window(struct wayland_surface *surface, void wayland_surface_coords_to_window(struct wayland_surface *surface, double surface_x, double surface_y, int *window_x, int *window_y); -struct wayland_client_surface *wayland_client_surface_create(HWND hwnd); void wayland_client_surface_attach(struct wayland_client_surface *client, HWND toplevel); void wayland_surface_ensure_contents(struct wayland_surface *surface); void wayland_surface_set_title(struct wayland_surface *surface, LPCWSTR title); @@ -469,6 +470,7 @@ LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface); BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects); +struct client_surface *WAYLAND_CreateClientSurface(HWND hwnd, int pixel_format); BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs); UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, const struct opengl_driver_funcs **driver_funcs); diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index 5fae15c81eb..275a3907f92 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -53,6 +53,7 @@ static const struct user_driver_funcs waylanddrv_funcs = .pWindowMessage = WAYLAND_WindowMessage, .pWindowPosChanged = WAYLAND_WindowPosChanged, .pWindowPosChanging = WAYLAND_WindowPosChanging, + .pCreateClientSurface = WAYLAND_CreateClientSurface, .pCreateWindowSurface = WAYLAND_CreateWindowSurface, .pVulkanInit = WAYLAND_VulkanInit, .pOpenGLInit = WAYLAND_OpenGLInit, diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 09ef2bf8664..d5b4fdbf0aa 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -26,6 +26,7 @@ #include <stdarg.h> #include <string.h> +#include <assert.h> #include "windef.h" #include "winbase.h" @@ -264,25 +265,6 @@ HRGN get_dc_monitor_region( HWND hwnd, HDC hdc ) return 0; } -static const struct client_surface_funcs x11drv_client_surface_funcs; - -struct x11drv_client_surface -{ - struct client_surface client; - XWindowChanges changes; - Colormap colormap; - Window window; - RECT rect; - - HDC hdc_src; - HDC hdc_dst; -}; - -static struct x11drv_client_surface *impl_from_client_surface( struct client_surface *client ) -{ - return CONTAINING_RECORD( client, struct x11drv_client_surface, client ); -} - static void x11drv_client_surface_destroy( struct client_surface *client ) { struct x11drv_client_surface *surface = impl_from_client_surface( client ); @@ -477,17 +459,23 @@ static int visual_class_alloc( int class ) return class == PseudoColor || class == GrayScale || class == DirectColor ? AllocAll : AllocNone; } -Window x11drv_client_surface_create( HWND hwnd, int format, struct client_surface **client ) +struct x11drv_client_surface *impl_from_client_surface( struct client_surface *client ) +{ + assert( client->funcs == &x11drv_client_surface_funcs ); + return CONTAINING_RECORD( client, struct x11drv_client_surface, client ); +} + +struct client_surface *X11DRV_CreateClientSurface( HWND hwnd, int format ) { struct x11drv_client_surface *surface; XVisualInfo visual = default_visual; Colormap colormap; - if (format && !visual_from_pixel_format( format, &visual )) return None; + if (format && !visual_from_pixel_format( format, &visual )) return NULL; if (visual.visualid == default_visual.visualid) colormap = default_colormap; else colormap = XCreateColormap( gdi_display, get_dummy_parent(), visual.visual, visual_class_alloc( visual.class ) ); - if (!colormap) return None; + if (!colormap) return NULL; if (!(surface = client_surface_create( sizeof(*surface), &x11drv_client_surface_funcs, hwnd ))) goto failed; surface->colormap = colormap; @@ -496,13 +484,12 @@ Window x11drv_client_surface_create( HWND hwnd, int format, struct client_surfac if (!(surface->window = create_client_window( hwnd, surface->rect, &visual, colormap ))) goto failed; TRACE( "Created %s for client window %lx\n", debugstr_client_surface( &surface->client ), surface->window ); - *client = &surface->client; - return surface->window; + return &surface->client; failed: if (surface) client_surface_release( &surface->client ); else if (colormap != default_colormap) XFreeColormap( gdi_display, colormap ); - return None; + return NULL; } /********************************************************************** @@ -711,6 +698,7 @@ static const struct user_driver_funcs x11drv_funcs = .pWindowPosChanging = X11DRV_WindowPosChanging, .pGetWindowStyleMasks = X11DRV_GetWindowStyleMasks, .pGetWindowStateUpdates = X11DRV_GetWindowStateUpdates, + .pCreateClientSurface = X11DRV_CreateClientSurface, .pCreateWindowSurface = X11DRV_CreateWindowSurface, .pMoveWindowBits = X11DRV_MoveWindowBits, .pWindowPosChanged = X11DRV_WindowPosChanged, diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 56c22ab7ee7..2b6e1145e47 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -521,14 +521,15 @@ static BOOL x11drv_egl_describe_pixel_format( int format, struct wgl_pixel_forma static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) { + struct x11drv_client_surface *surface; struct opengl_drawable *previous; struct client_surface *client; struct gl_drawable *gl; - Window window; if ((previous = *drawable) && previous->format == format) return TRUE; - if (!(window = x11drv_client_surface_create( hwnd, format, &client ))) return FALSE; + if (!(client = X11DRV_CreateClientSurface( hwnd, format ))) return FALSE; gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, client ); + surface = impl_from_client_surface( client ); /* reference held by gl */ client_surface_release( client ); if (!gl) return FALSE; @@ -538,13 +539,13 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_draw if (gl->base.stereo) opengl_drawable_map_buffer( &gl->base, GL_FRONT_RIGHT, GL_BACK_RIGHT ); if (!(gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format( format ), - (void *)window, NULL ))) + (void *)surface->window, NULL ))) { opengl_drawable_release( &gl->base ); return FALSE; } - TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), window ); + TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), surface->window ); XFlush( gdi_display ); if (previous) opengl_drawable_release( previous ); @@ -959,24 +960,25 @@ static GLXContext create_glxcontext( int format, GLXContext share, const int *at static BOOL x11drv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) { struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); + struct x11drv_client_surface *surface; struct opengl_drawable *previous; struct client_surface *client; struct gl_drawable *gl; - Window window; if ((previous = *drawable) && previous->format == format) return TRUE; - if (!(window = x11drv_client_surface_create( hwnd, format, &client ))) return FALSE; + if (!(client = X11DRV_CreateClientSurface( hwnd, format ))) return FALSE; gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, client ); + surface = impl_from_client_surface( client ); /* reference held by gl */ client_surface_release( client ); if (!gl) return FALSE; - if (!(gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, window, NULL ))) + if (!(gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, surface->window, NULL ))) { opengl_drawable_release( &gl->base ); return FALSE; } - TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), window ); + TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), surface->window ); XFlush( gdi_display ); if (previous) opengl_drawable_release( previous ); diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index e11a989f02d..fd58d4662d7 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -54,10 +54,15 @@ static VkResult X11DRV_vulkan_surface_create( HWND hwnd, const struct vulkan_ins .sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, .dpy = gdi_display, }; + struct x11drv_client_surface *surface; + struct client_surface *ptr; TRACE( "%p %p %p %p\n", hwnd, instance, handle, client ); - if (!(info.window = x11drv_client_surface_create( hwnd, 0, client ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (!(ptr = X11DRV_CreateClientSurface( hwnd, 0 ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + surface = impl_from_client_surface( ptr ); + + info.window = surface->window; if (instance->p_vkCreateXlibSurfaceKHR( instance->host.instance, &info, NULL /* allocator */, handle )) { ERR("Failed to create Xlib surface\n"); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 3def37a8f21..56d6c814aad 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -251,6 +251,7 @@ extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ); extern BOOL X11DRV_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask ); extern BOOL X11DRV_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *swp_flags, RECT *rect, HWND *foreground ); +extern struct client_surface *X11DRV_CreateClientSurface( HWND hwnd, int format ); extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); extern void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *old_rects, const struct window_rects *new_rects, const RECT *valid_rects ); @@ -364,11 +365,24 @@ struct x11drv_escape_get_drawable RECT dc_rect; /* DC rectangle relative to drawable */ }; +struct x11drv_client_surface +{ + struct client_surface client; + XWindowChanges changes; + Colormap colormap; + Window window; + RECT rect; + + HDC hdc_src; + HDC hdc_dst; +}; + +extern struct x11drv_client_surface *impl_from_client_surface( struct client_surface *client ); + extern BOOL needs_offscreen_rendering( HWND hwnd ); extern void set_dc_drawable( HDC hdc, Drawable drawable, const RECT *rect, int mode ); extern Drawable get_dc_drawable( HDC hdc, RECT *rect ); extern HRGN get_dc_monitor_region( HWND hwnd, HDC hdc ); -extern Window x11drv_client_surface_create( HWND hwnd, int format, struct client_surface **client ); /************************************************************************** * X11 USER driver diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 97c646d6ec9..fa1f7232505 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -218,7 +218,7 @@ struct gdi_dc_funcs }; /* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 108 +#define WINE_GDI_DRIVER_VERSION 109 #define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -420,6 +420,7 @@ struct user_driver_funcs BOOL (*pWindowPosChanging)(HWND,UINT,BOOL,const struct window_rects *); BOOL (*pGetWindowStyleMasks)(HWND,UINT,UINT,UINT*,UINT*); BOOL (*pGetWindowStateUpdates)(HWND,UINT*,UINT*,RECT*,HWND*); + struct client_surface *(*pCreateClientSurface)(HWND,int); BOOL (*pCreateWindowSurface)(HWND,BOOL,const RECT *,struct window_surface**); void (*pMoveWindowBits)(HWND,const struct window_rects *,const struct window_rects *,const RECT *); void (*pWindowPosChanged)(HWND,HWND,HWND,UINT,const struct window_rects*,struct window_surface*); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/vulkan.c | 24 ++++++++---------------- dlls/winemac.drv/vulkan.c | 29 +++++++---------------------- dlls/winewayland.drv/vulkan.c | 25 ++++++------------------- dlls/winex11.drv/vulkan.c | 23 +++++++---------------- include/wine/vulkan_driver.h | 4 ++-- 5 files changed, 30 insertions(+), 75 deletions(-) diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index c95038ed6a4..00f85243a3f 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -1533,8 +1533,11 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance client_instance, cons surface->hwnd = dummy; } - if ((res = driver_funcs->p_vulkan_surface_create( surface->hwnd, instance, &host_surface, &surface->client ))) + if (!(surface->client = user_driver->pCreateClientSurface( surface->hwnd, 0 ))) res = VK_ERROR_OUT_OF_HOST_MEMORY; + else res = driver_funcs->p_vulkan_surface_create( surface->client, instance, &host_surface ); + if (res) { + if (surface->client) client_surface_release( surface->client ); if (dummy) NtUserDestroyWindow( dummy ); free( surface ); return res; @@ -2924,20 +2927,10 @@ static struct vulkan_funcs vulkan_funcs = .p_vkUnmapMemory2KHR = win32u_vkUnmapMemory2KHR, }; -static VkResult nulldrv_vulkan_surface_create( HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *surface, - struct client_surface **client ) +static VkResult nulldrv_vulkan_surface_create( struct client_surface *client, const struct vulkan_instance *instance, VkSurfaceKHR *surface ) { VkHeadlessSurfaceCreateInfoEXT create_info = {.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; - VkResult res; - - if (!(*client = user_driver->pCreateClientSurface( hwnd, 0 ))) return VK_ERROR_OUT_OF_HOST_MEMORY; - if ((res = instance->p_vkCreateHeadlessSurfaceEXT( instance->host.instance, &create_info, NULL, surface ))) - { - client_surface_release(*client); - *client = NULL; - } - - return res; + return instance->p_vkCreateHeadlessSurfaceEXT( instance->host.instance, &create_info, NULL, surface ); } static VkBool32 nulldrv_get_physical_device_presentation_support( struct vulkan_physical_device *physical_device, uint32_t queue ) @@ -2989,11 +2982,10 @@ static void vulkan_driver_load(void) pthread_once( &init_once, vulkan_driver_init ); } -static VkResult lazydrv_vulkan_surface_create( HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *surface, - struct client_surface **client ) +static VkResult lazydrv_vulkan_surface_create( struct client_surface *client, const struct vulkan_instance *instance, VkSurfaceKHR *surface ) { vulkan_driver_load(); - return driver_funcs->p_vulkan_surface_create( hwnd, instance, surface, client ); + return driver_funcs->p_vulkan_surface_create( client, instance, surface ); } static VkBool32 lazydrv_get_physical_device_presentation_support( struct vulkan_physical_device *physical_device, uint32_t queue ) diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c index 41c148627fb..532f792ed46 100644 --- a/dlls/winemac.drv/vulkan.c +++ b/dlls/winemac.drv/vulkan.c @@ -40,19 +40,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); static const struct vulkan_driver_funcs macdrv_vulkan_driver_funcs; -static VkResult macdrv_vulkan_surface_create(HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *handle, - struct client_surface **client) +static VkResult macdrv_vulkan_surface_create(struct client_surface *client, const struct vulkan_instance *instance, VkSurfaceKHR *handle) { VkResult res; - struct macdrv_client_surface *surface; - struct client_surface *ptr; + struct macdrv_client_surface *surface = impl_from_client_surface(client); - TRACE("%p %p %p %p\n", hwnd, instance, handle, client); + TRACE("%s %p %p\n", debugstr_client_surface(client), instance, handle); - if (!(ptr = macdrv_CreateClientSurface(hwnd, 0))) return VK_ERROR_OUT_OF_HOST_MEMORY; - surface = impl_from_client_surface( ptr ); - - if (!macdrv_client_surface_acquire_metal_swapchain(surface)) goto err; + if (!macdrv_client_surface_acquire_metal_swapchain(surface)) return VK_ERROR_INCOMPATIBLE_DRIVER; if (instance->p_vkCreateMetalSurfaceEXT) { @@ -62,7 +57,7 @@ static VkResult macdrv_vulkan_surface_create(HWND hwnd, const struct vulkan_inst create_info_host.flags = 0; /* reserved */ create_info_host.pLayer = macdrv_swapchain_get_layer(surface->metal_swapchain); - res = instance->p_vkCreateMetalSurfaceEXT(instance->host.instance, &create_info_host, NULL /* allocator */, handle); + if ((res = instance->p_vkCreateMetalSurfaceEXT(instance->host.instance, &create_info_host, NULL /* allocator */, handle))) return res; } else { @@ -72,21 +67,11 @@ static VkResult macdrv_vulkan_surface_create(HWND hwnd, const struct vulkan_inst create_info_host.flags = 0; /* reserved */ create_info_host.pView = macdrv_swapchain_get_layer(surface->metal_swapchain); - res = instance->p_vkCreateMacOSSurfaceMVK(instance->host.instance, &create_info_host, NULL /* allocator */, handle); - } - if (res != VK_SUCCESS) - { - ERR("Failed to create MoltenVK surface, res=%d\n", res); - goto err; + if ((res = instance->p_vkCreateMacOSSurfaceMVK(instance->host.instance, &create_info_host, NULL /* allocator */, handle))) return res; } - *client = &surface->client; - TRACE("Created surface=0x%s, client=%p\n", wine_dbgstr_longlong(*handle), *client); + TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*handle)); return VK_SUCCESS; - -err: - client_surface_release(&surface->client); - return VK_ERROR_INCOMPATIBLE_DRIVER; } static VkBool32 macdrv_get_physical_device_presentation_support(struct vulkan_physical_device *physical_device, diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 65ebbc40b1f..b2c435cb7a4 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -38,37 +38,24 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs; -static VkResult wayland_vulkan_surface_create(HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *handle, - struct client_surface **client) +static VkResult wayland_vulkan_surface_create(struct client_surface *client, const struct vulkan_instance *instance, VkSurfaceKHR *handle) { VkResult res; VkWaylandSurfaceCreateInfoKHR create_info_host; - struct wayland_client_surface *surface; - struct client_surface *ptr; + struct wayland_client_surface *surface = impl_from_client_surface(client); + HWND hwnd = client->hwnd; - TRACE("%p %p %p %p\n", hwnd, instance, handle, client); - - if (!(ptr = WAYLAND_CreateClientSurface(hwnd, 0))) return VK_ERROR_OUT_OF_HOST_MEMORY; - surface = impl_from_client_surface( ptr ); + TRACE("%s %p %p\n", debugstr_client_surface(client), instance, handle); create_info_host.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; create_info_host.pNext = NULL; create_info_host.flags = 0; /* reserved */ create_info_host.display = process_wayland.wl_display; create_info_host.surface = surface->wl_surface; - - res = instance->p_vkCreateWaylandSurfaceKHR(instance->host.instance, &create_info_host, NULL /* allocator */, handle); - if (res != VK_SUCCESS) - { - ERR("Failed to create vulkan wayland surface, res=%d\n", res); - client_surface_release(&surface->client); - return res; - } - + if ((res = instance->p_vkCreateWaylandSurfaceKHR(instance->host.instance, &create_info_host, NULL /* allocator */, handle))) return res; set_client_surface(hwnd, surface); - *client = &surface->client; - TRACE("Created surface=0x%s, client=%p\n", wine_dbgstr_longlong(*handle), *client); + TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*handle)); return VK_SUCCESS; } diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index fd58d4662d7..1c1b9cf3ba1 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -46,31 +46,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs; -static VkResult X11DRV_vulkan_surface_create( HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *handle, - struct client_surface **client ) +static VkResult X11DRV_vulkan_surface_create( struct client_surface *client, const struct vulkan_instance *instance, VkSurfaceKHR *handle ) { + struct x11drv_client_surface *surface = impl_from_client_surface( client ); VkXlibSurfaceCreateInfoKHR info = { .sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, .dpy = gdi_display, + .window = surface->window, }; - struct x11drv_client_surface *surface; - struct client_surface *ptr; + VkResult res; - TRACE( "%p %p %p %p\n", hwnd, instance, handle, client ); + TRACE( "%s %p %p\n", debugstr_client_surface( client ), instance, handle ); - if (!(ptr = X11DRV_CreateClientSurface( hwnd, 0 ))) return VK_ERROR_OUT_OF_HOST_MEMORY; - surface = impl_from_client_surface( ptr ); + if ((res = instance->p_vkCreateXlibSurfaceKHR( instance->host.instance, &info, NULL /* allocator */, handle ))) return res; + TRACE( "Created surface 0x%s\n", wine_dbgstr_longlong( *handle ) ); - info.window = surface->window; - if (instance->p_vkCreateXlibSurfaceKHR( instance->host.instance, &info, NULL /* allocator */, handle )) - { - ERR("Failed to create Xlib surface\n"); - client_surface_release( *client ); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - TRACE( "Created surface 0x%s, client %s\n", wine_dbgstr_longlong( *handle ), debugstr_client_surface( *client ) ); return VK_SUCCESS; } diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 9c18f6d20db..d2209a3ef54 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -89,7 +89,7 @@ struct VkDevice_T #include "wine/list.h" /* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */ -#define WINE_VULKAN_DRIVER_VERSION 47 +#define WINE_VULKAN_DRIVER_VERSION 48 struct vulkan_object { @@ -358,7 +358,7 @@ struct vulkan_funcs struct client_surface; struct vulkan_driver_funcs { - VkResult (*p_vulkan_surface_create)(HWND, const struct vulkan_instance *, VkSurfaceKHR *, struct client_surface **); + VkResult (*p_vulkan_surface_create)(struct client_surface *, const struct vulkan_instance *, VkSurfaceKHR *); VkBool32 (*p_get_physical_device_presentation_support)(struct vulkan_physical_device *, uint32_t); void (*p_map_instance_extensions)( struct vulkan_instance_extensions *extensions ); void (*p_map_device_extensions)( struct vulkan_device_extensions *extensions ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/opengl.c | 21 +++++++++++++-------- dlls/wineandroid.drv/opengl.c | 13 ++++--------- dlls/winemac.drv/opengl.c | 13 ++++--------- dlls/winewayland.drv/opengl.c | 18 +++++------------- dlls/winex11.drv/opengl.c | 29 ++++++----------------------- include/wine/opengl_driver.h | 4 ++-- 6 files changed, 34 insertions(+), 64 deletions(-) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 089452198de..5e09b7ced13 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -660,14 +660,9 @@ static void egldrv_init_extensions( struct opengl_funcs *funcs, BOOLEAN extensio { } -static BOOL egldrv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) +static BOOL egldrv_surface_create( struct client_surface *client, int format, struct opengl_drawable **drawable ) { - struct client_surface *client; - - if (!(client = user_driver->pCreateClientSurface( hwnd, format ))) return FALSE; *drawable = framebuffer_surface_create( format, client ); - client_surface_release( client ); - return !!*drawable; } @@ -1276,7 +1271,7 @@ static void nulldrv_init_extensions( struct opengl_funcs *funcs, BOOLEAN extensi { } -static BOOL nulldrv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) +static BOOL nulldrv_surface_create( struct client_surface *client, int format, struct opengl_drawable **drawable ) { return TRUE; } @@ -1407,7 +1402,17 @@ static struct opengl_drawable *get_window_unused_drawable( HWND hwnd, int format */ if (!drawable) { - driver_funcs->p_surface_create( hwnd, format, &drawable ); + struct client_surface *client; + + if (!(client = user_driver->pCreateClientSurface( hwnd, format ))) + WARN( "Failed to create a surface for window %p, format %d\n", hwnd, format ); + else + { + if (!(driver_funcs->p_surface_create( client, format, &drawable ))) + WARN( "Failed to create a drawable for window %p, format %d\n", hwnd, format ); + client_surface_release( client ); + } + if (drawable && drawable->client) add_window_client_surface( hwnd, drawable->client ); } diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 2800126761f..12bae7fca29 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -47,7 +47,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(android); static const struct egl_platform *egl; static const struct opengl_funcs *funcs; -static const struct client_surface_funcs android_client_surface_funcs; static const struct opengl_drawable_funcs android_drawable_funcs; struct gl_drawable @@ -82,11 +81,11 @@ void update_gl_drawable( HWND hwnd ) NtUserRedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE ); } -static BOOL android_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) +static BOOL android_surface_create( struct client_surface *client, int format, struct opengl_drawable **drawable ) { struct gl_drawable *gl; - TRACE( "hwnd %p, format %d, drawable %p\n", hwnd, format, drawable ); + TRACE( "hwnd %p, format %d, drawable %p\n", client->hwnd, format, drawable ); if (*drawable) { @@ -106,14 +105,10 @@ static BOOL android_surface_create( HWND hwnd, int format, struct opengl_drawabl { static const int attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; EGLConfig config = egl_config_for_format( format ); - struct client_surface *client; - - if (!(client = ANDROID_CreateClientSurface( hwnd, format ))) return FALSE; - gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, client ); - client_surface_release( client ); - if (!gl) return FALSE; + if (!(gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, client ))) return FALSE; gl->window = get_client_window( client->hwnd ); + if (!has_client_surface( client->hwnd )) gl->base.surface = funcs->p_eglCreatePbufferSurface( egl->display, config, attribs ); else gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, config, gl->window, NULL ); diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 86830bffc80..37e63a449b7 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -1455,28 +1455,23 @@ static BOOL create_context(struct macdrv_context *context, CGLContextObj share, return TRUE; } -static BOOL macdrv_surface_create(HWND hwnd, int format, struct opengl_drawable **drawable) +static BOOL macdrv_surface_create(struct client_surface *client, int format, struct opengl_drawable **drawable) { - struct client_surface *client; struct macdrv_win_data *data; + HWND hwnd = client->hwnd; struct gl_drawable *gl; - TRACE("hwnd %p, format %d, drawable %p\n", hwnd, format, drawable); + TRACE("client %s, format %d, drawable %p\n", debugstr_client_surface(client), format, drawable); if (!(data = get_win_data(hwnd))) { FIXME("DC for window %p of other process: not implemented\n", hwnd); return FALSE; } - data->pixel_format = format; release_win_data(data); - if (!(client = macdrv_CreateClientSurface(hwnd, format))) return FALSE; - gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, client); - client_surface_release(client); - if (!gl) return FALSE; - + if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, client))) return FALSE; *drawable = &gl->base; return TRUE; } diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 9719c63719d..14cb4ce5a25 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -80,19 +80,16 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) wl_egl_window_resize(gl->wl_egl_window, client_width, client_height, 0, 0); } -static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_drawable **drawable) +static BOOL wayland_opengl_surface_create(struct client_surface *client, int format, struct opengl_drawable **drawable) { + struct wayland_client_surface *surface = impl_from_client_surface(client); EGLConfig config = egl_config_for_format(format); - struct wayland_client_surface *surface; EGLint attribs[4], *attrib = attribs; - struct opengl_drawable *previous; struct wayland_gl_drawable *gl; - struct client_surface *client; + HWND hwnd = client->hwnd; RECT rect; - TRACE("hwnd=%p format=%d\n", hwnd, format); - - if ((previous = *drawable) && previous->format == format) return TRUE; + TRACE("client=%s format=%d\n", debugstr_client_surface(client), format); NtUserGetClientRect(hwnd, &rect, NtUserGetDpiForWindow(hwnd)); if (rect.right == rect.left) rect.right = rect.left + 1; @@ -107,11 +104,7 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_d } *attrib++ = EGL_NONE; - if (!(client = WAYLAND_CreateClientSurface(hwnd, format))) return FALSE; - gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, client); - surface = impl_from_client_surface(client); /* reference held by gl */ - client_surface_release(client); - if (!gl) return FALSE; + if (!(gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, client))) return FALSE; opengl_drawable_map_buffer(&gl->base, GL_FRONT_LEFT, GL_BACK_LEFT); opengl_drawable_map_buffer(&gl->base, GL_FRONT, GL_BACK); @@ -124,7 +117,6 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_d TRACE("Created drawable %s with egl_surface %p\n", debugstr_opengl_drawable(&gl->base), gl->base.surface); - if (previous) opengl_drawable_release( previous ); *drawable = &gl->base; return TRUE; diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 2b6e1145e47..f080d5dddca 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -519,19 +519,12 @@ static BOOL x11drv_egl_describe_pixel_format( int format, struct wgl_pixel_forma return TRUE; } -static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) +static BOOL x11drv_egl_surface_create( struct client_surface *client, int format, struct opengl_drawable **drawable ) { - struct x11drv_client_surface *surface; - struct opengl_drawable *previous; - struct client_surface *client; + struct x11drv_client_surface *surface = impl_from_client_surface( client ); struct gl_drawable *gl; - if ((previous = *drawable) && previous->format == format) return TRUE; - if (!(client = X11DRV_CreateClientSurface( hwnd, format ))) return FALSE; - gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, client ); - surface = impl_from_client_surface( client ); /* reference held by gl */ - client_surface_release( client ); - if (!gl) return FALSE; + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, client ))) return FALSE; opengl_drawable_map_buffer( &gl->base, GL_FRONT_LEFT, GL_BACK_LEFT ); opengl_drawable_map_buffer( &gl->base, GL_FRONT, GL_BACK ); @@ -548,7 +541,6 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_draw TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), surface->window ); XFlush( gdi_display ); - if (previous) opengl_drawable_release( previous ); *drawable = &gl->base; return TRUE; } @@ -957,21 +949,13 @@ static GLXContext create_glxcontext( int format, GLXContext share, const int *at return ctx; } -static BOOL x11drv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) +static BOOL x11drv_surface_create( struct client_surface *client, int format, struct opengl_drawable **drawable ) { + struct x11drv_client_surface *surface = impl_from_client_surface( client ); struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); - struct x11drv_client_surface *surface; - struct opengl_drawable *previous; - struct client_surface *client; struct gl_drawable *gl; - if ((previous = *drawable) && previous->format == format) return TRUE; - if (!(client = X11DRV_CreateClientSurface( hwnd, format ))) return FALSE; - gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, client ); - surface = impl_from_client_surface( client ); /* reference held by gl */ - client_surface_release( client ); - if (!gl) return FALSE; - + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, client ))) return FALSE; if (!(gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, surface->window, NULL ))) { opengl_drawable_release( &gl->base ); @@ -981,7 +965,6 @@ static BOOL x11drv_surface_create( HWND hwnd, int format, struct opengl_drawable TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), surface->window ); XFlush( gdi_display ); - if (previous) opengl_drawable_release( previous ); *drawable = &gl->base; return TRUE; } diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index af745e038a6..3fa0aa91d97 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -111,7 +111,7 @@ struct __GLsync #include "wine/gdi_driver.h" /* Wine internal opengl driver version, needs to be bumped upon opengl_funcs changes. */ -#define WINE_OPENGL_DRIVER_VERSION 37 +#define WINE_OPENGL_DRIVER_VERSION 38 struct opengl_drawable; @@ -244,7 +244,7 @@ struct opengl_driver_funcs UINT (*p_init_pixel_formats)(UINT*); BOOL (*p_describe_pixel_format)(int,struct wgl_pixel_format*); void (*p_init_extensions)( struct opengl_funcs *funcs, BOOLEAN extensions[GL_EXTENSION_COUNT] ); - BOOL (*p_surface_create)( HWND hwnd, int format, struct opengl_drawable **drawable ); + BOOL (*p_surface_create)( struct client_surface *client, int format, struct opengl_drawable **drawable ); BOOL (*p_context_create)( int format, void *share, const int *attribs, void **context ); BOOL (*p_context_destroy)(void*); BOOL (*p_make_current)( struct opengl_drawable *draw, struct opengl_drawable *read, void *private ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/input.c | 10 ++++++++++ dlls/win32u/main.c | 5 +++++ dlls/win32u/win32syscalls.h | 5 ++--- dlls/win32u/win32u.spec | 2 +- dlls/wow64win/user.c | 8 ++++++++ include/ntuser.h | 1 + 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 733eb604fdc..10c563d197a 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2876,3 +2876,13 @@ BOOL WINAPI NtUserInitializeTouchInjection( UINT max_count, UINT mode ) FIXME( "max_count %u, mode %#x stub!\n", max_count, mode ); return TRUE; } + +/********************************************************************** + * NtUserGetPointerType (win32u.@) + */ +BOOL WINAPI NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ) +{ + FIXME( "id %u, type %p stub!\n", id, type ); + RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; +} diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c index edb1d98b3f0..69f36a815a1 100644 --- a/dlls/win32u/main.c +++ b/dlls/win32u/main.c @@ -1748,6 +1748,11 @@ BOOL SYSCALL_API NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, U SYSCALL_FUNC( NtUserGetPointerInfoList ); } +BOOL SYSCALL_API NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ) +{ + SYSCALL_FUNC( NtUserGetPointerType ); +} + INT SYSCALL_API NtUserGetPriorityClipboardFormat( UINT *list, INT count ) { SYSCALL_FUNC( NtUserGetPriorityClipboardFormat ); diff --git a/dlls/win32u/win32syscalls.h b/dlls/win32u/win32syscalls.h index 3e631c74da1..66043201b29 100644 --- a/dlls/win32u/win32syscalls.h +++ b/dlls/win32u/win32syscalls.h @@ -1074,7 +1074,7 @@ SYSCALL_ENTRY( 0x142e, NtUserGetPointerInfoList, 32 ) \ SYSCALL_ENTRY( 0x142f, NtUserGetPointerInputTransform, 0 ) \ SYSCALL_ENTRY( 0x1430, NtUserGetPointerProprietaryId, 0 ) \ - SYSCALL_ENTRY( 0x1431, NtUserGetPointerType, 0 ) \ + SYSCALL_ENTRY( 0x1431, NtUserGetPointerType, 8 ) \ SYSCALL_ENTRY( 0x1432, NtUserGetPrecisionTouchPadConfiguration, 0 ) \ SYSCALL_ENTRY( 0x1433, NtUserGetPriorityClipboardFormat, 8 ) \ SYSCALL_ENTRY( 0x1434, NtUserGetProcessDefaultLayout, 4 ) \ @@ -2616,7 +2616,7 @@ SYSCALL_ENTRY( 0x142e, NtUserGetPointerInfoList, 64 ) \ SYSCALL_ENTRY( 0x142f, NtUserGetPointerInputTransform, 0 ) \ SYSCALL_ENTRY( 0x1430, NtUserGetPointerProprietaryId, 0 ) \ - SYSCALL_ENTRY( 0x1431, NtUserGetPointerType, 0 ) \ + SYSCALL_ENTRY( 0x1431, NtUserGetPointerType, 16 ) \ SYSCALL_ENTRY( 0x1432, NtUserGetPrecisionTouchPadConfiguration, 0 ) \ SYSCALL_ENTRY( 0x1433, NtUserGetPriorityClipboardFormat, 16 ) \ SYSCALL_ENTRY( 0x1434, NtUserGetProcessDefaultLayout, 8 ) \ @@ -3836,7 +3836,6 @@ SYSCALL_STUB( NtUserGetPointerFrameTimes ) \ SYSCALL_STUB( NtUserGetPointerInputTransform ) \ SYSCALL_STUB( NtUserGetPointerProprietaryId ) \ - SYSCALL_STUB( NtUserGetPointerType ) \ SYSCALL_STUB( NtUserGetPrecisionTouchPadConfiguration ) \ SYSCALL_STUB( NtUserGetProcessUIContextInformation ) \ SYSCALL_STUB( NtUserGetProp2 ) \ diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index a58fda6af9c..05ddbd85478 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1072,7 +1072,7 @@ @ stdcall -syscall NtUserGetPointerInfoList(long long long long long ptr ptr ptr) @ stub -syscall NtUserGetPointerInputTransform @ stub -syscall NtUserGetPointerProprietaryId -@ stub -syscall NtUserGetPointerType +@ stdcall -syscall NtUserGetPointerType(long ptr) @ stub -syscall NtUserGetPrecisionTouchPadConfiguration @ stdcall -syscall NtUserGetPriorityClipboardFormat(ptr long) @ stdcall -syscall NtUserGetProcessDefaultLayout(ptr) diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 61c2da3e228..a07966c2ae4 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -2834,6 +2834,14 @@ NTSTATUS WINAPI wow64_NtUserGetPointerInfoList( UINT *args ) return NtUserGetPointerInfoList( id, type, unk0, unk1, size, entry_count, pointer_count, pointer_info ); } +NTSTATUS WINAPI wow64_NtUserGetPointerType( UINT *args ) +{ + UINT id = get_ulong( &args ); + POINTER_INPUT_TYPE *type = get_ptr( &args ); + + return NtUserGetPointerType( id, type ); +} + NTSTATUS WINAPI wow64_NtUserGetPriorityClipboardFormat( UINT *args ) { UINT *list = get_ptr( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index 2bbf77a4cf1..a5aeb28123e 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -881,6 +881,7 @@ W32KAPI BOOL WINAPI NtUserGetObjectInformation( HANDLE handle, INT index, voi W32KAPI HWND WINAPI NtUserGetOpenClipboardWindow(void); W32KAPI BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_PTR, UINT_PTR, SIZE_T size, UINT32 *entry_count, UINT32 *pointer_count, void *pointer_info ); +W32KAPI BOOL WINAPI NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ); W32KAPI INT WINAPI NtUserGetPriorityClipboardFormat( UINT *list, INT count ); W32KAPI BOOL WINAPI NtUserGetProcessDefaultLayout( ULONG *layout ); W32KAPI ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/user32/input.c | 8 -------- dlls/user32/user32.spec | 2 +- dlls/win32u/input.c | 10 ++++++++++ dlls/win32u/main.c | 5 +++++ dlls/win32u/win32syscalls.h | 5 ++--- dlls/win32u/win32u.spec | 2 +- dlls/wow64win/user.c | 9 +++++++++ include/ntuser.h | 1 + 8 files changed, 29 insertions(+), 13 deletions(-) diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 48b38166b75..623fab14d11 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -750,14 +750,6 @@ BOOL WINAPI GetPointerDeviceProperties( HANDLE device, UINT32 *count, return FALSE; } -BOOL WINAPI GetPointerDeviceRects( HANDLE device, RECT *device_rect, RECT *display_rect ) -{ - FIXME( "device %p, device_rect %p, display_rect %p stub!\n", - device, device_rect, display_rect ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; -} - BOOL WINAPI GetPointerPenInfo( UINT32 id, POINTER_PEN_INFO *info ) { FIXME( "id %u, info %p stub!\n", id, info ); diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index fe41f9cb2e7..93ced8d8f3d 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -630,7 +630,7 @@ # @ stub GetPointerDeviceInputSpace # @ stub GetPointerDeviceOrientation @ stdcall GetPointerDeviceProperties(ptr ptr ptr) -@ stdcall GetPointerDeviceRects(ptr ptr ptr) +@ stdcall GetPointerDeviceRects(ptr ptr ptr) NtUserGetPointerDeviceRects @ stdcall GetPointerDevices(ptr ptr) # @ stub GetPointerFrameInfo # @ stub GetPointerFrameInfoHistory diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 10c563d197a..41d871958f6 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2886,3 +2886,13 @@ BOOL WINAPI NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ) RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); return FALSE; } + +/********************************************************************** + * NtUserGetPointerDeviceRects (win32u.@) + */ +BOOL WINAPI NtUserGetPointerDeviceRects( HANDLE handle, RECT *device_rect, RECT *display_rect ) +{ + FIXME( "handle %p, device_rect %p, display_rect %p stub!\n", handle, device_rect, display_rect ); + RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; +} diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c index 69f36a815a1..22e5368b132 100644 --- a/dlls/win32u/main.c +++ b/dlls/win32u/main.c @@ -1753,6 +1753,11 @@ BOOL SYSCALL_API NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ) SYSCALL_FUNC( NtUserGetPointerType ); } +BOOL SYSCALL_API NtUserGetPointerDeviceRects( HANDLE handle, RECT *device_rect, RECT *display_rect ) +{ + SYSCALL_FUNC( NtUserGetPointerDeviceRects ); +} + INT SYSCALL_API NtUserGetPriorityClipboardFormat( UINT *list, INT count ) { SYSCALL_FUNC( NtUserGetPriorityClipboardFormat ); diff --git a/dlls/win32u/win32syscalls.h b/dlls/win32u/win32syscalls.h index 66043201b29..132ac47836b 100644 --- a/dlls/win32u/win32syscalls.h +++ b/dlls/win32u/win32syscalls.h @@ -1068,7 +1068,7 @@ SYSCALL_ENTRY( 0x1428, NtUserGetPointerDeviceInputSpace, 0 ) \ SYSCALL_ENTRY( 0x1429, NtUserGetPointerDeviceOrientation, 0 ) \ SYSCALL_ENTRY( 0x142a, NtUserGetPointerDeviceProperties, 0 ) \ - SYSCALL_ENTRY( 0x142b, NtUserGetPointerDeviceRects, 0 ) \ + SYSCALL_ENTRY( 0x142b, NtUserGetPointerDeviceRects, 12 ) \ SYSCALL_ENTRY( 0x142c, NtUserGetPointerDevices, 0 ) \ SYSCALL_ENTRY( 0x142d, NtUserGetPointerFrameTimes, 0 ) \ SYSCALL_ENTRY( 0x142e, NtUserGetPointerInfoList, 32 ) \ @@ -2610,7 +2610,7 @@ SYSCALL_ENTRY( 0x1428, NtUserGetPointerDeviceInputSpace, 0 ) \ SYSCALL_ENTRY( 0x1429, NtUserGetPointerDeviceOrientation, 0 ) \ SYSCALL_ENTRY( 0x142a, NtUserGetPointerDeviceProperties, 0 ) \ - SYSCALL_ENTRY( 0x142b, NtUserGetPointerDeviceRects, 0 ) \ + SYSCALL_ENTRY( 0x142b, NtUserGetPointerDeviceRects, 24 ) \ SYSCALL_ENTRY( 0x142c, NtUserGetPointerDevices, 0 ) \ SYSCALL_ENTRY( 0x142d, NtUserGetPointerFrameTimes, 0 ) \ SYSCALL_ENTRY( 0x142e, NtUserGetPointerInfoList, 64 ) \ @@ -3831,7 +3831,6 @@ SYSCALL_STUB( NtUserGetPointerDeviceInputSpace ) \ SYSCALL_STUB( NtUserGetPointerDeviceOrientation ) \ SYSCALL_STUB( NtUserGetPointerDeviceProperties ) \ - SYSCALL_STUB( NtUserGetPointerDeviceRects ) \ SYSCALL_STUB( NtUserGetPointerDevices ) \ SYSCALL_STUB( NtUserGetPointerFrameTimes ) \ SYSCALL_STUB( NtUserGetPointerInputTransform ) \ diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 05ddbd85478..2c409010cd2 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1066,7 +1066,7 @@ @ stub -syscall NtUserGetPointerDeviceInputSpace @ stub -syscall NtUserGetPointerDeviceOrientation @ stub -syscall NtUserGetPointerDeviceProperties -@ stub -syscall NtUserGetPointerDeviceRects +@ stdcall -syscall NtUserGetPointerDeviceRects(long ptr ptr) @ stub -syscall NtUserGetPointerDevices @ stub -syscall NtUserGetPointerFrameTimes @ stdcall -syscall NtUserGetPointerInfoList(long long long long long ptr ptr ptr) diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index a07966c2ae4..5506c9fc5b0 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -2842,6 +2842,15 @@ NTSTATUS WINAPI wow64_NtUserGetPointerType( UINT *args ) return NtUserGetPointerType( id, type ); } +NTSTATUS WINAPI wow64_NtUserGetPointerDeviceRects( UINT *args ) +{ + HANDLE device = get_handle( &args ); + RECT *device_rect = get_ptr( &args ); + RECT *display_rect = get_ptr( &args ); + + return NtUserGetPointerDeviceRects( device, device_rect, display_rect ); +} + NTSTATUS WINAPI wow64_NtUserGetPriorityClipboardFormat( UINT *args ) { UINT *list = get_ptr( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index a5aeb28123e..c3c4c8cdcf2 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -882,6 +882,7 @@ W32KAPI HWND WINAPI NtUserGetOpenClipboardWindow(void); W32KAPI BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_PTR, UINT_PTR, SIZE_T size, UINT32 *entry_count, UINT32 *pointer_count, void *pointer_info ); W32KAPI BOOL WINAPI NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ); +W32KAPI BOOL WINAPI NtUserGetPointerDeviceRects( HANDLE handle, RECT *device_rect, RECT *display_rect ); W32KAPI INT WINAPI NtUserGetPriorityClipboardFormat( UINT *list, INT count ); W32KAPI BOOL WINAPI NtUserGetProcessDefaultLayout( ULONG *layout ); W32KAPI ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/win32u/tests/win32u.c | 65 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 4481ffa1b32..479d0532461 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -3004,6 +3004,59 @@ static void test_NtUserRegisterWindowMessage(void) ok( !wcscmp( buf, L"#0xabc" ), "buf = %s\n", debugstr_w(buf) ); } +static BOOL CALLBACK get_virtual_screen_proc( HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lp ) +{ + RECT *virtual_rect = (RECT *)lp; + UnionRect( virtual_rect, virtual_rect, rect ); + return TRUE; +} + +static RECT get_virtual_screen_rect(void) +{ + RECT rect = {0}; + EnumDisplayMonitors( 0, NULL, get_virtual_screen_proc, (LPARAM)&rect ); + return rect; +} + +void test_NtUserGetPointerDeviceRects( const char *arg ) +{ + RECT screen, himetric_dev = {0}, device = {0}, display = {0}; + DPI_AWARENESS_CONTEXT ctx = 0; + const UINT himetric = 2540; + UINT ret, dpi; + + if (!strcmp( arg, "unaware" )) ctx = DPI_AWARENESS_CONTEXT_UNAWARE; + else if (!strcmp( arg, "system" )) ctx = DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; + else if (!strcmp( arg, "monitor" )) ctx = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE; + + if (ctx) + { + ret = SetProcessDpiAwarenessContext( ctx ); + ok( ret, "SetProcessDpiAwarenessContext failed, error %lu.\n", GetLastError() ); + } + + screen = get_virtual_screen_rect(); + + /* operating on unaware scaled values returns wrong values */ + ctx = SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ); + + dpi = GetDpiForSystem(); + himetric_dev.right = GetSystemMetrics( SM_CXVIRTUALSCREEN ) * himetric / dpi; + himetric_dev.bottom = GetSystemMetrics( SM_CYVIRTUALSCREEN ) * himetric / dpi; + + SetThreadDpiAwarenessContext( ctx ); + + ret = NtUserGetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &display ); + todo_wine + { + ok( ret, "NtUserGetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + ok( EqualRect( &device, &himetric_dev ), "device %s, expected %s\n", + wine_dbgstr_rect( &device ), wine_dbgstr_rect( &himetric_dev ) ); + ok( EqualRect( &display, &screen ), "display %s, expected %s\n", + wine_dbgstr_rect( &display ), wine_dbgstr_rect( &screen ) ); + } +} + START_TEST(win32u) { char **argv; @@ -3033,6 +3086,14 @@ START_TEST(win32u) return; } + if (argc > 3 && !strcmp( argv[2], "NtUserGetPointerDeviceRects" )) + { + winetest_push_context( "dpi context %s", argv[3] ); + test_NtUserGetPointerDeviceRects( argv[3] ); + winetest_pop_context(); + return; + } + test_NtUserEnumDisplayDevices(); test_window_props(); test_class(); @@ -3059,6 +3120,10 @@ START_TEST(win32u) run_in_process( argv, "NtUserEnableMouseInPointer 0" ); run_in_process( argv, "NtUserEnableMouseInPointer 1" ); + run_in_process( argv, "NtUserGetPointerDeviceRects unaware" ); + run_in_process( argv, "NtUserGetPointerDeviceRects system" ); + run_in_process( argv, "NtUserGetPointerDeviceRects monitor" ); + run_in_process( argv, "NtUserSetProcessDpiAwarenessContext 0x6010" ); run_in_process( argv, "NtUserSetProcessDpiAwarenessContext 0x11" ); run_in_process( argv, "NtUserSetProcessDpiAwarenessContext 0x12" ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Rémi Bernon <rbernon@codeweavers.com> Native doesn't support DPI scaling otherwise and the tests are skipped. --- dlls/user32/tests/monitor.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index 69a46faba28..eaf3d268469 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -3755,7 +3755,10 @@ static void test_monitor_dpi(void) { int min = 0, max = 0, cur = 0; - set_display_settings( infos[i].handle, 800, 600 ); + /* native disables DPI scaling when resolution is below 1024x768, but Wine default CI resolution is 1024x768 */ + if (winetest_platform_is_wine) set_display_settings( infos[i].handle, 800, 600 ); + else set_display_settings( infos[i].handle, 1024, 768 ); + get_monitor_infos( infos ); /* refresh infos as changing display settings may invalidate HMONITOR */ get_monitor_dpi_scale( infos[i].handle, &min, &cur, &max ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/user32/tests/monitor.c | 50 ++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index eaf3d268469..be5882405f0 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -38,6 +38,8 @@ #include <stdio.h> #include <math.h> +#define HIMETRIC_PER_INCH 2540 + DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_GPU_LUID, 0xca085853, 0x16ce, 0x48aa, 0xb1, 0x14, 0xde, 0x9c, 0x72, 0x33, 0x42, 0x23, 1); DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID, 0xca085853, 0x16ce, 0x48aa, 0xb1, 0x14, 0xde, 0x9c, 0x72, 0x33, 0x42, 0x23, 2); @@ -3217,7 +3219,7 @@ static void test_monitor_dpi_awareness( const struct monitor_info *infos, UINT c DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED, (DPI_AWARENESS_CONTEXT)0x7811, }; - RECT virtual = {0}, scaled_virtual = {0}, monitor = {0}, scaled = {0}, primary = {0}, rect, expect_rect; + RECT virtual = {0}, scaled_virtual = {0}, monitor = {0}, scaled = {0}, primary = {0}, rect, expect_rect, device, scaled_device, expect_device; struct monitor_info tmp_info = {.handle = info->handle}; UINT ret, i, x, y, expect_width, expect_height; HWND unaware_hwnd, aware_hwnd, primary_hwnd; @@ -3233,16 +3235,26 @@ static void test_monitor_dpi_awareness( const struct monitor_info *infos, UINT c { if (infos[i].rect.left == 0 && infos[i].rect.top == 0) primary = infos[i].rect; - if (info != infos + i) UnionRect( &scaled_virtual, &scaled_virtual, &infos[i].rect ); + SetRect( &device, infos[i].rect.left * HIMETRIC_PER_INCH / system_dpi, infos[i].rect.top * HIMETRIC_PER_INCH / system_dpi, + infos[i].rect.right * HIMETRIC_PER_INCH / system_dpi, infos[i].rect.bottom * HIMETRIC_PER_INCH / system_dpi ); + UnionRect( &virtual, &virtual, &infos[i].rect ); + UnionRect( &expect_device, &expect_device, &device ); + + if (info != infos + i) + { + UnionRect( &scaled_virtual, &scaled_virtual, &infos[i].rect ); + UnionRect( &scaled_device, &scaled_device, &device ); + } else { scaled = monitor = infos[i].rect; scaled.right = scaled.left + MulDiv( scaled.right - scaled.left, 100, scale ); scaled.bottom = scaled.top + MulDiv( scaled.bottom - scaled.top, 100, scale ); UnionRect( &scaled_virtual, &scaled_virtual, &scaled ); + SetRect( &device, scaled.left * HIMETRIC_PER_INCH / system_dpi, scaled.top * HIMETRIC_PER_INCH / system_dpi, + scaled.right * HIMETRIC_PER_INCH / system_dpi, scaled.bottom * HIMETRIC_PER_INCH / system_dpi ); + UnionRect( &scaled_device, &scaled_device, &device ); } - - UnionRect( &virtual, &virtual, &infos[i].rect ); } unaware_hwnd = CreateWindowW( L"static", NULL, WS_POPUP | WS_VISIBLE, monitor.left + 100, @@ -3279,6 +3291,12 @@ static void test_monitor_dpi_awareness( const struct monitor_info *infos, UINT c check_logical_physical_dpi( unaware_hwnd, monitor.left + 2 * scale + 1, monitor.top + 2 * scale + 1, monitor.left + 2 * scale + 1, monitor.top + 2 * scale + 1, FALSE ); + ret = GetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &rect ); + todo_wine ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + todo_wine ok( EqualRect( &rect, &scaled_virtual ), "got %s\n", wine_dbgstr_rect(&rect) ); + todo_wine ok( EqualRect( &device, &expect_device ) /* w10 */ || EqualRect( &device, &scaled_device ) /* w11 */, + "got %s vs %s / %s\n", wine_dbgstr_rect(&device), wine_dbgstr_rect(&expect_device), wine_dbgstr_rect(&scaled_device) ); + for (i = 0; i < ARRAY_SIZE(tests); i++) { BOOL monitor_aware = tests[i] == DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE || @@ -3565,6 +3583,12 @@ static void test_monitor_dpi_awareness( const struct monitor_info *infos, UINT c check_logical_physical_dpi( primary_hwnd, primary.left + 4 * scale + 1, primary.top + 4 * scale + 1, primary.left + 4 * scale + 1, primary.top + 4 * scale + 1, FALSE ); + ret = GetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &rect ); + todo_wine ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + todo_wine ok( EqualRect( &rect, monitor_aware ? &virtual : &scaled_virtual ), "got %s\n", wine_dbgstr_rect(&rect) ); + todo_wine ok( EqualRect( &device, &expect_device ) /* w10 */ || EqualRect( &device, &scaled_device ) /* w11 */, + "got %s vs %s / %s\n", wine_dbgstr_rect(&device), wine_dbgstr_rect(&expect_device), wine_dbgstr_rect(&scaled_device) ); + DestroyWindow( primary_hwnd ); DestroyWindow( aware_hwnd ); @@ -3630,6 +3654,7 @@ static void test_monitor_dpi(void) {1024, 768}, }; UINT i, j, count, system_dpi, dpi_x, dpi_y; + RECT expect_rect, device, display; DPI_AWARENESS_CONTEXT old_ctx; float scale_x, scale_y; BOOL ret, is_virtual; @@ -3660,11 +3685,14 @@ static void test_monitor_dpi(void) { for (j = 0; j < ARRAY_SIZE(tests); j++) { + RECT virtual = {0}; + if (tests[j].width && tests[j].height && !set_display_settings( infos[i].handle, tests[j].width, tests[j].height )) continue; get_monitor_infos( infos ); /* refresh infos as changing display settings may invalidate HMONITOR */ scale_x = (infos[i].rect.right - infos[i].rect.left) / (float)(phys_infos[i].rect.right - phys_infos[i].rect.left); scale_y = (infos[i].rect.bottom - infos[i].rect.top) / (float)(phys_infos[i].rect.bottom - phys_infos[i].rect.top); + for (UINT i = 0; i < count; i++) UnionRect( &virtual, &virtual, &infos[i].rect ); ret = pGetDpiForMonitorInternal( infos[i].handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y ); ok( ret, "GetDpiForMonitorInternal failed, error %lu\n", GetLastError() ); @@ -3704,6 +3732,13 @@ static void test_monitor_dpi(void) ok( fabs( dpi_y - system_dpi * scale_y ) < system_dpi * 0.05, "got MDT_RAW_DPI y %u\n", dpi_y ); } + ret = GetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &display ); + todo_wine ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + todo_wine ok( EqualRect( &display, &virtual ), "got %s\n", wine_dbgstr_rect( &display ) ); + SetRect( &expect_rect, 0, 0, virtual.right * HIMETRIC_PER_INCH / system_dpi, + virtual.bottom * HIMETRIC_PER_INCH / system_dpi ); + todo_wine ok( EqualRect( &device, &expect_rect ), "got %s\n", wine_dbgstr_rect( &device ) ); + pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ); ret = pGetDpiForMonitorInternal( infos[i].handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y ); @@ -3744,6 +3779,13 @@ static void test_monitor_dpi(void) ok( fabs( dpi_y - system_dpi * scale_y ) < system_dpi * 0.05, "got MDT_RAW_DPI y %u\n", dpi_y ); } + ret = GetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &display ); + todo_wine ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + todo_wine ok( EqualRect( &display, &virtual ), "got %s\n", wine_dbgstr_rect( &display ) ); + SetRect( &expect_rect, 0, 0, virtual.right * HIMETRIC_PER_INCH / system_dpi, + virtual.bottom * HIMETRIC_PER_INCH / system_dpi ); + todo_wine ok( EqualRect( &device, &expect_rect ), "got %s\n", wine_dbgstr_rect( &device ) ); + pSetThreadDpiAwarenessContext( old_ctx ); } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
From: "Anna (navi) Figueiredo Gomes" <navi@vlhl.dev> --- dlls/user32/tests/monitor.c | 24 ++++++++++++------------ dlls/win32u/input.c | 21 ++++++++++++++++++--- dlls/win32u/tests/win32u.c | 13 +++++-------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index be5882405f0..b5c8f5bc629 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -3292,9 +3292,9 @@ static void test_monitor_dpi_awareness( const struct monitor_info *infos, UINT c monitor.left + 2 * scale + 1, monitor.top + 2 * scale + 1, FALSE ); ret = GetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &rect ); - todo_wine ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); - todo_wine ok( EqualRect( &rect, &scaled_virtual ), "got %s\n", wine_dbgstr_rect(&rect) ); - todo_wine ok( EqualRect( &device, &expect_device ) /* w10 */ || EqualRect( &device, &scaled_device ) /* w11 */, + ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + ok( EqualRect( &rect, &scaled_virtual ), "got %s\n", wine_dbgstr_rect(&rect) ); + ok( EqualRect( &device, &expect_device ) /* w10 */ || EqualRect( &device, &scaled_device ) /* w11 */, "got %s vs %s / %s\n", wine_dbgstr_rect(&device), wine_dbgstr_rect(&expect_device), wine_dbgstr_rect(&scaled_device) ); for (i = 0; i < ARRAY_SIZE(tests); i++) @@ -3584,9 +3584,9 @@ static void test_monitor_dpi_awareness( const struct monitor_info *infos, UINT c primary.left + 4 * scale + 1, primary.top + 4 * scale + 1, FALSE ); ret = GetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &rect ); - todo_wine ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); - todo_wine ok( EqualRect( &rect, monitor_aware ? &virtual : &scaled_virtual ), "got %s\n", wine_dbgstr_rect(&rect) ); - todo_wine ok( EqualRect( &device, &expect_device ) /* w10 */ || EqualRect( &device, &scaled_device ) /* w11 */, + ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + ok( EqualRect( &rect, monitor_aware ? &virtual : &scaled_virtual ), "got %s\n", wine_dbgstr_rect(&rect) ); + ok( EqualRect( &device, &expect_device ) /* w10 */ || EqualRect( &device, &scaled_device ) /* w11 */, "got %s vs %s / %s\n", wine_dbgstr_rect(&device), wine_dbgstr_rect(&expect_device), wine_dbgstr_rect(&scaled_device) ); DestroyWindow( primary_hwnd ); @@ -3733,11 +3733,11 @@ static void test_monitor_dpi(void) } ret = GetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &display ); - todo_wine ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); - todo_wine ok( EqualRect( &display, &virtual ), "got %s\n", wine_dbgstr_rect( &display ) ); + ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + ok( EqualRect( &display, &virtual ), "got %s\n", wine_dbgstr_rect( &display ) ); SetRect( &expect_rect, 0, 0, virtual.right * HIMETRIC_PER_INCH / system_dpi, virtual.bottom * HIMETRIC_PER_INCH / system_dpi ); - todo_wine ok( EqualRect( &device, &expect_rect ), "got %s\n", wine_dbgstr_rect( &device ) ); + ok( EqualRect( &device, &expect_rect ), "got %s\n", wine_dbgstr_rect( &device ) ); pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ); @@ -3780,11 +3780,11 @@ static void test_monitor_dpi(void) } ret = GetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &display ); - todo_wine ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); - todo_wine ok( EqualRect( &display, &virtual ), "got %s\n", wine_dbgstr_rect( &display ) ); + ok( ret, "GetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + ok( EqualRect( &display, &virtual ), "got %s\n", wine_dbgstr_rect( &display ) ); SetRect( &expect_rect, 0, 0, virtual.right * HIMETRIC_PER_INCH / system_dpi, virtual.bottom * HIMETRIC_PER_INCH / system_dpi ); - todo_wine ok( EqualRect( &device, &expect_rect ), "got %s\n", wine_dbgstr_rect( &device ) ); + ok( EqualRect( &device, &expect_rect ), "got %s\n", wine_dbgstr_rect( &device ) ); pSetThreadDpiAwarenessContext( old_ctx ); } diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 41d871958f6..048950345b3 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -40,6 +40,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(win); WINE_DECLARE_DEBUG_CHANNEL(keyboard); +#define HIMETRIC_PER_INCH 2540 + static const WCHAR keyboard_layouts_keyW[] = { '\\','R','e','g','i','s','t','r','y', @@ -2892,7 +2894,20 @@ BOOL WINAPI NtUserGetPointerType( UINT32 id, POINTER_INPUT_TYPE *type ) */ BOOL WINAPI NtUserGetPointerDeviceRects( HANDLE handle, RECT *device_rect, RECT *display_rect ) { - FIXME( "handle %p, device_rect %p, display_rect %p stub!\n", handle, device_rect, display_rect ); - RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + RECT rect; + + if (handle != INVALID_HANDLE_VALUE) + { + FIXME( "Pointer devices are not implemented!\n" ); + RtlSetLastWin32Error( ERROR_NO_DATA ); + return FALSE; + } + + rect = get_virtual_screen_rect( 0, MDT_DEFAULT ); + SetRect( device_rect, 0, 0, (rect.right - rect.left) * HIMETRIC_PER_INCH / get_system_dpi(), + (rect.bottom - rect.top) * HIMETRIC_PER_INCH / get_system_dpi() ); + *display_rect = get_virtual_screen_rect( get_thread_dpi(), MDT_DEFAULT ); + + TRACE( "returning device %s, display %s\n", wine_dbgstr_rect(device_rect), wine_dbgstr_rect(display_rect) ); + return TRUE; } diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 479d0532461..a67b918626d 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -3047,14 +3047,11 @@ void test_NtUserGetPointerDeviceRects( const char *arg ) SetThreadDpiAwarenessContext( ctx ); ret = NtUserGetPointerDeviceRects( INVALID_HANDLE_VALUE, &device, &display ); - todo_wine - { - ok( ret, "NtUserGetPointerDeviceRects failed, error %lu.\n", GetLastError() ); - ok( EqualRect( &device, &himetric_dev ), "device %s, expected %s\n", - wine_dbgstr_rect( &device ), wine_dbgstr_rect( &himetric_dev ) ); - ok( EqualRect( &display, &screen ), "display %s, expected %s\n", - wine_dbgstr_rect( &display ), wine_dbgstr_rect( &screen ) ); - } + ok( ret, "NtUserGetPointerDeviceRects failed, error %lu.\n", GetLastError() ); + ok( EqualRect( &device, &himetric_dev ), "device %s, expected %s\n", + wine_dbgstr_rect( &device ), wine_dbgstr_rect( &himetric_dev ) ); + ok( EqualRect( &display, &screen ), "display %s, expected %s\n", + wine_dbgstr_rect( &display ), wine_dbgstr_rect( &screen ) ); } START_TEST(win32u) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11162
participants (7)
-
Alexandre Julliard -
Anna (navi) Figueiredo Gomes -
Dmitry Timoshkov -
Etaash Mathamsetty -
Myungbae Son (@nedsociety) -
Ned Son -
Rémi Bernon