Needed by UE4 VR games.
Proton-Issue: https://github.com/ValveSoftware/Proton/issues/6533 Proton-Issue: https://github.com/ValveSoftware/Proton/issues/8457
-- v4: windows.perception.stub: Stub some functions. windows.perception.stub: Implement IHolographicSpace_get_PrimaryAdapterId(). windows.perception.stub/tests: Add IHolographicSpace::get_PrimaryAdapterId() tests. windows.perception.stub: Implement IHolographicSpaceInterop::CreateForWindow(). windows.perception.stub/tests: Add IHolographicSpaceInterop::CreateForWindow() tests.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- .../windows.perception.stub/tests/Makefile.in | 2 +- .../tests/perception.c | 112 ++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/dlls/windows.perception.stub/tests/Makefile.in b/dlls/windows.perception.stub/tests/Makefile.in index 9de867787b3..0783751d75e 100644 --- a/dlls/windows.perception.stub/tests/Makefile.in +++ b/dlls/windows.perception.stub/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = windows.perception.stub.dll -IMPORTS = combase +IMPORTS = combase user32
SOURCES = \ perception.c diff --git a/dlls/windows.perception.stub/tests/perception.c b/dlls/windows.perception.stub/tests/perception.c index 29d7f1ea475..2e9b2db2904 100644 --- a/dlls/windows.perception.stub/tests/perception.c +++ b/dlls/windows.perception.stub/tests/perception.c @@ -49,6 +49,60 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid, BOOL IUnknown_Release( unk ); }
+static void flush_events(void) +{ + int min_timeout = 100, diff = 200; + DWORD time = GetTickCount() + diff; + MSG msg; + + while (diff > 0) + { + if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break; + while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) + { + TranslateMessage( &msg ); + DispatchMessageW( &msg ); + } + diff = time - GetTickCount(); + } +} + +#define create_foreground_window( a ) create_foreground_window_( __FILE__, __LINE__, a, 5 ) +HWND create_foreground_window_( const char *file, int line, BOOL fullscreen, UINT retries ) +{ + for (;;) + { + HWND hwnd; + BOOL ret; + + hwnd = CreateWindowW( L"static", NULL, WS_POPUP | (fullscreen ? 0 : WS_VISIBLE), + 100, 100, 200, 200, NULL, NULL, NULL, NULL ); + ok_(file, line)( hwnd != NULL, "CreateWindowW failed, error %lu\n", GetLastError() ); + + if (fullscreen) + { + HMONITOR hmonitor = MonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY ); + MONITORINFO mi = {.cbSize = sizeof(MONITORINFO)}; + + ok_(file, line)( hmonitor != NULL, "MonitorFromWindow failed, error %lu\n", GetLastError() ); + ret = GetMonitorInfoW( hmonitor, &mi ); + ok_(file, line)( ret, "GetMonitorInfoW failed, error %lu\n", GetLastError() ); + ret = SetWindowPos( hwnd, 0, mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, + mi.rcMonitor.bottom - mi.rcMonitor.top, SWP_FRAMECHANGED | SWP_SHOWWINDOW ); + ok_(file, line)( ret, "SetWindowPos failed, error %lu\n", GetLastError() ); + } + flush_events(); + + if (GetForegroundWindow() == hwnd) return hwnd; + ok_(file, line)( retries > 0, "failed to create foreground window\n" ); + if (!retries--) return hwnd; + + ret = DestroyWindow( hwnd ); + ok_(file, line)( ret, "DestroyWindow failed, error %lu\n", GetLastError() ); + flush_events(); + } +} + static void test_ObserverStatics(void) { static const WCHAR *observer_statics_name = L"Windows.Perception.Spatial.Surfaces.SpatialSurfaceObserver"; @@ -102,8 +156,11 @@ static void test_HolographicSpaceStatics(void) static const WCHAR *holographicspace_statics_name = L"Windows.Graphics.Holographic.HolographicSpace"; IHolographicSpaceStatics2 *holographicspace_statics2; IHolographicSpaceStatics3 *holographicspace_statics3; + IHolographicSpaceInterop *holographic_space_interop; + IHolographicSpace *holographic_space; IActivationFactory *factory; BOOLEAN value; + HWND window; HSTRING str; HRESULT hr; LONG ref; @@ -163,6 +220,61 @@ static void test_HolographicSpaceStatics(void)
ref = IHolographicSpaceStatics3_Release( holographicspace_statics3 ); ok( ref == 2, "got ref %ld.\n", ref ); + + hr = IActivationFactory_QueryInterface( factory, &IID_IHolographicSpaceInterop, (void **)&holographic_space_interop ); + if (hr == E_NOINTERFACE) /* win1703 */ + { + win_skip( "IHolographicSpaceInterop is not supported, skipping tests.\n" ); + goto done; + } + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + holographic_space = (void *)0xdeadbeef; + hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, NULL, &IID_IHolographicSpaceInterop, (void **)&holographic_space ); + todo_wine + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + todo_wine + ok( holographic_space == (void *)0xdeadbeef, "got holographic_space %p.\n", holographic_space ); + hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, (void *)0xdeadbeef, &IID_IHolographicSpaceInterop, (void **)&holographic_space ); + ok( IsWindowVisible( (void *)0xdeadbeef ) == FALSE, "got IsWindowVisible %d\n", IsWindowVisible( (void *)0xdeadbeef ) ); + todo_wine + ok( hr == E_INVALIDARG || broken(hr == E_ACCESSDENIED) /* w1064v1709 */ || broken(hr == E_NOINTERFACE) /* w11 */, "got hr %#lx.\n", hr ); + ok( holographic_space == NULL, "got holographic_space %p.\n", holographic_space ); + if (hr == E_ACCESSDENIED) goto cleanup; + + window = create_foreground_window( FALSE ); + ok( IsWindowVisible( window ) == TRUE, "got IsWindowVisible %d\n", IsWindowVisible( window ) ); + + holographic_space = (void *)0xdeadbeef; + hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, window, &IID_IHolographicSpace, (void **)&holographic_space ); + todo_wine + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + ok( holographic_space == NULL, "got holographic_space %p.\n", holographic_space ); + + ShowWindow( window, SW_HIDE ); + ok( IsWindowVisible( window ) == FALSE, "got IsWindowVisible %d\n", IsWindowVisible( window ) ); + hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, window, &IID_IHolographicSpace, (void **)&holographic_space ); + todo_wine + ok( hr == S_OK, "got hr %#lx.\n", hr ); + ok( IsWindowVisible( window ) == FALSE, "got IsWindowVisible %d\n", IsWindowVisible( window ) ); + + if (SUCCEEDED(hr)) + { + check_interface( holographic_space, &IID_IUnknown, FALSE ); + check_interface( holographic_space, &IID_IInspectable, FALSE ); + check_interface( holographic_space, &IID_IAgileObject, FALSE ); + + ref = IHolographicSpace_Release( holographic_space ); + ok( ref == 0, "got ref %ld.\n", ref ); + + hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, window, &IID_IHolographicSpace, (void **)&holographic_space ); + todo_wine + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + } + DestroyWindow( window ); +cleanup: + ref = IHolographicSpaceInterop_Release( holographic_space_interop ); + ok( ref == 2, "got ref %ld.\n", ref ); done: ref = IActivationFactory_Release( factory ); ok( ref == 1, "got ref %ld.\n", ref );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.perception.stub/Makefile.in | 4 +- .../holographic_space.c | 385 ++++++++++++++++++ .../holographicspace.c | 237 ----------- dlls/windows.perception.stub/main.c | 2 +- dlls/windows.perception.stub/private.h | 3 +- .../tests/perception.c | 25 +- 6 files changed, 400 insertions(+), 256 deletions(-) create mode 100644 dlls/windows.perception.stub/holographic_space.c delete mode 100644 dlls/windows.perception.stub/holographicspace.c
diff --git a/dlls/windows.perception.stub/Makefile.in b/dlls/windows.perception.stub/Makefile.in index 18c90e697c4..f7b6065cb0d 100644 --- a/dlls/windows.perception.stub/Makefile.in +++ b/dlls/windows.perception.stub/Makefile.in @@ -1,8 +1,8 @@ MODULE = windows.perception.stub.dll -IMPORTS = combase +IMPORTS = combase user32
SOURCES = \ classes.idl \ - holographicspace.c \ + holographic_space.c \ main.c \ observer.c diff --git a/dlls/windows.perception.stub/holographic_space.c b/dlls/windows.perception.stub/holographic_space.c new file mode 100644 index 00000000000..0e5121e9c7c --- /dev/null +++ b/dlls/windows.perception.stub/holographic_space.c @@ -0,0 +1,385 @@ +/* WinRT Windows.Perception.Stub HolographicSpace Implementation + * + * Copyright (C) 2023 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(perception); + +struct holographic_space_statics +{ + IActivationFactory IActivationFactory_iface; + IHolographicSpaceStatics2 IHolographicSpaceStatics2_iface; + IHolographicSpaceStatics3 IHolographicSpaceStatics3_iface; + IHolographicSpaceInterop IHolographicSpaceInterop_iface; + LONG ref; +}; + +static inline struct holographic_space_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct holographic_space_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct holographic_space_statics *impl = impl_from_IActivationFactory( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IActivationFactory )) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + if (IsEqualGUID( iid, &IID_IHolographicSpaceStatics2 )) + { + *out = &impl->IHolographicSpaceStatics2_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + if (IsEqualGUID( iid, &IID_IHolographicSpaceStatics3 )) + { + *out = &impl->IHolographicSpaceStatics3_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + if (IsEqualGUID( iid, &IID_IHolographicSpaceInterop )) + { + *out = &impl->IHolographicSpaceInterop_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) +{ + struct holographic_space_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_Release( IActivationFactory *iface ) +{ + struct holographic_space_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p stub!\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +DEFINE_IINSPECTABLE( holographic_space_statics2, IHolographicSpaceStatics2, struct holographic_space_statics, IActivationFactory_iface ) + +static HRESULT WINAPI holographic_space_statics2_get_IsSupported( IHolographicSpaceStatics2 *iface, boolean *value ) +{ + TRACE( "iface %p, value %p\n", iface, value ); + + *value = FALSE; + return S_OK; +} + +static HRESULT WINAPI holographic_space_statics2_get_IsAvailable( IHolographicSpaceStatics2 *iface, boolean *value ) +{ + TRACE( "iface %p, value %p\n", iface, value ); + + *value = FALSE; + return S_OK; +} + +static HRESULT WINAPI holographic_space_statics2_add_IsAvailableChanged( IHolographicSpaceStatics2 *iface, IEventHandler_IInspectable *handler, + EventRegistrationToken *token ) +{ + FIXME( "iface %p, handler %p, token %p stub!\n", iface, handler, token ); + return E_NOTIMPL; +} + +static HRESULT WINAPI holographic_space_statics2_remove_IsAvailableChanged( IHolographicSpaceStatics2 *iface, EventRegistrationToken token ) +{ + FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); + return E_NOTIMPL; +} + +static const struct IHolographicSpaceStatics2Vtbl holographic_space_statics2_vtbl = +{ + holographic_space_statics2_QueryInterface, + holographic_space_statics2_AddRef, + holographic_space_statics2_Release, + /* IInspectable methods */ + holographic_space_statics2_GetIids, + holographic_space_statics2_GetRuntimeClassName, + holographic_space_statics2_GetTrustLevel, + /* IHolographicSpaceStatics2 methods */ + holographic_space_statics2_get_IsSupported, + holographic_space_statics2_get_IsAvailable, + holographic_space_statics2_add_IsAvailableChanged, + holographic_space_statics2_remove_IsAvailableChanged, +}; + +DEFINE_IINSPECTABLE( holographic_space_statics3, IHolographicSpaceStatics3, struct holographic_space_statics, IActivationFactory_iface ) + +static HRESULT WINAPI holographic_space_statics3_get_IsConfigured( IHolographicSpaceStatics3 *iface, boolean *value ) +{ + TRACE( "iface %p, value %p\n", iface, value ); + + *value = FALSE; + return S_OK; +} + +static const struct IHolographicSpaceStatics3Vtbl holographic_space_statics3_vtbl = +{ + holographic_space_statics3_QueryInterface, + holographic_space_statics3_AddRef, + holographic_space_statics3_Release, + /* IInspectable methods */ + holographic_space_statics3_GetIids, + holographic_space_statics3_GetRuntimeClassName, + holographic_space_statics3_GetTrustLevel, + /* IHolographicSpaceStatics3 methods */ + holographic_space_statics3_get_IsConfigured, +}; + +struct holographic_space +{ + IHolographicSpace IHolographicSpace_iface; + LONG ref; +}; + +static inline struct holographic_space *impl_from_IHolographicSpace( IHolographicSpace *iface ) +{ + return CONTAINING_RECORD( iface, struct holographic_space, IHolographicSpace_iface ); +} + +static HRESULT WINAPI holographic_space_QueryInterface( IHolographicSpace *iface, REFIID iid, void **out ) +{ + struct holographic_space *impl = impl_from_IHolographicSpace( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IHolographicSpace )) + { + *out = &impl->IHolographicSpace_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI holographic_space_AddRef( IHolographicSpace *iface ) +{ + struct holographic_space *impl = impl_from_IHolographicSpace( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI holographic_space_Release( IHolographicSpace *iface ) +{ + struct holographic_space *impl = impl_from_IHolographicSpace( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + + if (!ref) free( impl ); + return ref; +} + +static HRESULT WINAPI holographic_space_GetIids( IHolographicSpace *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI holographic_space_GetRuntimeClassName( IHolographicSpace *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI holographic_space_GetTrustLevel( IHolographicSpace *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI holographic_space_get_PrimaryAdapterId( IHolographicSpace *iface, HolographicAdapterId *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI holographic_space_SetDirect3D11Device( IHolographicSpace *iface, IDirect3DDevice *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI holographic_space_add_CameraAdded( IHolographicSpace *iface, ITypedEventHandler_HolographicSpace_HolographicSpaceCameraAddedEventArgs *handler, + EventRegistrationToken *cookie ) +{ + FIXME( "iface %p, handler %p, cookie %p stub!\n", iface, handler, cookie ); + return E_NOTIMPL; +} + +static HRESULT WINAPI holographic_space_remove_CameraAdded( IHolographicSpace *iface, EventRegistrationToken cookie ) +{ + FIXME( "iface %p, cookie %#I64x stub!\n", iface, cookie.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI holographic_space_add_CameraRemoved( IHolographicSpace *iface, ITypedEventHandler_HolographicSpace_HolographicSpaceCameraRemovedEventArgs *handler, + EventRegistrationToken *cookie ) +{ + FIXME( "iface %p, handler %p, cookie %p stub!\n", iface, handler, cookie ); + return E_NOTIMPL; +} + +static HRESULT WINAPI holographic_space_remove_CameraRemoved( IHolographicSpace *iface, EventRegistrationToken cookie ) +{ + FIXME( "iface %p, cookie %#I64x stub!\n", iface, cookie.value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI holographic_space_CreateNextFrame( IHolographicSpace *iface, IHolographicFrame **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static const struct IHolographicSpaceVtbl holographic_space_vtbl = +{ + /* IUnknown methods */ + holographic_space_QueryInterface, + holographic_space_AddRef, + holographic_space_Release, + /* IInspectable methods */ + holographic_space_GetIids, + holographic_space_GetRuntimeClassName, + holographic_space_GetTrustLevel, + /* IHolographicSpace methods */ + holographic_space_get_PrimaryAdapterId, + holographic_space_SetDirect3D11Device, + holographic_space_add_CameraAdded, + holographic_space_remove_CameraAdded, + holographic_space_add_CameraRemoved, + holographic_space_remove_CameraRemoved, + holographic_space_CreateNextFrame, +}; + +DEFINE_IINSPECTABLE( holographic_space_interop, IHolographicSpaceInterop, struct holographic_space_statics, IActivationFactory_iface ) + +static HRESULT WINAPI holographic_space_interop_CreateForWindow( IHolographicSpaceInterop *iface, + HWND window, REFIID iid, void **holographic_space ) +{ + struct holographic_space *impl; + HRESULT hr; + + TRACE( "iface %p, window %p, iid %s, holographic_space %p.\n", iface, window, debugstr_guid( iid ), holographic_space ); + + if (!IsWindow( window ) || IsWindowVisible( window )) + { + *holographic_space = NULL; + return E_INVALIDARG; + } + if (!(impl = calloc( 1, sizeof( *impl ) ))) return E_OUTOFMEMORY; + + impl->IHolographicSpace_iface.lpVtbl = &holographic_space_vtbl; + impl->ref = 1; + + hr = IHolographicSpace_QueryInterface( &impl->IHolographicSpace_iface, iid, holographic_space ); + IHolographicSpace_Release( &impl->IHolographicSpace_iface ); + TRACE( "created IHolographicSpace %p.\n", *holographic_space ); + return hr; +} + +static const struct IHolographicSpaceInteropVtbl holographic_space_interop_vtbl = +{ + holographic_space_interop_QueryInterface, + holographic_space_interop_AddRef, + holographic_space_interop_Release, + /* IInspectable methods */ + holographic_space_interop_GetIids, + holographic_space_interop_GetRuntimeClassName, + holographic_space_interop_GetTrustLevel, + /* IHolographicSpaceInterop methods */ + holographic_space_interop_CreateForWindow, +}; + +static struct holographic_space_statics holographic_space_statics = +{ + {&factory_vtbl}, + {&holographic_space_statics2_vtbl}, + {&holographic_space_statics3_vtbl}, + {&holographic_space_interop_vtbl}, + 1, +}; + +IActivationFactory *holographic_space_factory = &holographic_space_statics.IActivationFactory_iface; diff --git a/dlls/windows.perception.stub/holographicspace.c b/dlls/windows.perception.stub/holographicspace.c deleted file mode 100644 index 53e6be0e712..00000000000 --- a/dlls/windows.perception.stub/holographicspace.c +++ /dev/null @@ -1,237 +0,0 @@ -/* WinRT Windows.Perception.Stub HolographicSpace Implementation - * - * Copyright (C) 2023 Mohamad Al-Jaf - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "private.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(perception); - -struct holographicspace -{ - IActivationFactory IActivationFactory_iface; - IHolographicSpaceStatics2 IHolographicSpaceStatics2_iface; - IHolographicSpaceStatics3 IHolographicSpaceStatics3_iface; - IHolographicSpaceInterop IHolographicSpaceInterop_iface; - LONG ref; -}; - -static inline struct holographicspace *impl_from_IActivationFactory( IActivationFactory *iface ) -{ - return CONTAINING_RECORD( iface, struct holographicspace, IActivationFactory_iface ); -} - -static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) -{ - struct holographicspace *impl = impl_from_IActivationFactory( iface ); - - TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); - - if (IsEqualGUID( iid, &IID_IUnknown ) || - IsEqualGUID( iid, &IID_IInspectable ) || - IsEqualGUID( iid, &IID_IAgileObject ) || - IsEqualGUID( iid, &IID_IActivationFactory )) - { - *out = &impl->IActivationFactory_iface; - IInspectable_AddRef( *out ); - return S_OK; - } - - if (IsEqualGUID( iid, &IID_IHolographicSpaceStatics2 )) - { - *out = &impl->IHolographicSpaceStatics2_iface; - IInspectable_AddRef( *out ); - return S_OK; - } - - if (IsEqualGUID( iid, &IID_IHolographicSpaceStatics3 )) - { - *out = &impl->IHolographicSpaceStatics3_iface; - IInspectable_AddRef( *out ); - return S_OK; - } - - if (IsEqualGUID( iid, &IID_IHolographicSpaceInterop )) - { - *out = &impl->IHolographicSpaceInterop_iface; - IInspectable_AddRef( *out ); - return S_OK; - } - - FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); - *out = NULL; - return E_NOINTERFACE; -} - -static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) -{ - struct holographicspace *impl = impl_from_IActivationFactory( iface ); - ULONG ref = InterlockedIncrement( &impl->ref ); - TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); - return ref; -} - -static ULONG WINAPI factory_Release( IActivationFactory *iface ) -{ - struct holographicspace *impl = impl_from_IActivationFactory( iface ); - ULONG ref = InterlockedDecrement( &impl->ref ); - TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); - return ref; -} - -static HRESULT WINAPI factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids ) -{ - FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); - return E_NOTIMPL; -} - -static HRESULT WINAPI factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) -{ - FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); - return E_NOTIMPL; -} - -static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) -{ - FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); - return E_NOTIMPL; -} - -static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) -{ - FIXME( "iface %p, instance %p stub!\n", iface, instance ); - return E_NOTIMPL; -} - -static const struct IActivationFactoryVtbl factory_vtbl = -{ - factory_QueryInterface, - factory_AddRef, - factory_Release, - /* IInspectable methods */ - factory_GetIids, - factory_GetRuntimeClassName, - factory_GetTrustLevel, - /* IActivationFactory methods */ - factory_ActivateInstance, -}; - -DEFINE_IINSPECTABLE( holographicspace_statics2, IHolographicSpaceStatics2, struct holographicspace, IActivationFactory_iface ) - -static HRESULT WINAPI holographicspace_statics2_get_IsSupported( IHolographicSpaceStatics2 *iface, boolean *value ) -{ - TRACE( "iface %p, value %p\n", iface, value ); - - *value = FALSE; - return S_OK; -} - -static HRESULT WINAPI holographicspace_statics2_get_IsAvailable( IHolographicSpaceStatics2 *iface, boolean *value ) -{ - TRACE( "iface %p, value %p\n", iface, value ); - - *value = FALSE; - return S_OK; -} - -static HRESULT WINAPI holographicspace_statics2_add_IsAvailableChanged( IHolographicSpaceStatics2 *iface, IEventHandler_IInspectable *handler, - EventRegistrationToken *token ) -{ - FIXME( "iface %p, handler %p, token %p stub!\n", iface, handler, token ); - return E_NOTIMPL; -} - -static HRESULT WINAPI holographicspace_statics2_remove_IsAvailableChanged( IHolographicSpaceStatics2 *iface, EventRegistrationToken token ) -{ - FIXME( "iface %p, token %#I64x stub!\n", iface, token.value ); - return E_NOTIMPL; -} - -static const struct IHolographicSpaceStatics2Vtbl holographicspace_statics2_vtbl = -{ - holographicspace_statics2_QueryInterface, - holographicspace_statics2_AddRef, - holographicspace_statics2_Release, - /* IInspectable methods */ - holographicspace_statics2_GetIids, - holographicspace_statics2_GetRuntimeClassName, - holographicspace_statics2_GetTrustLevel, - /* IHolographicSpaceStatics2 methods */ - holographicspace_statics2_get_IsSupported, - holographicspace_statics2_get_IsAvailable, - holographicspace_statics2_add_IsAvailableChanged, - holographicspace_statics2_remove_IsAvailableChanged, -}; - -DEFINE_IINSPECTABLE( holographicspace_statics3, IHolographicSpaceStatics3, struct holographicspace, IActivationFactory_iface ) - -static HRESULT WINAPI holographicspace_statics3_get_IsConfigured( IHolographicSpaceStatics3 *iface, boolean *value ) -{ - TRACE( "iface %p, value %p\n", iface, value ); - - *value = FALSE; - return S_OK; -} - -static const struct IHolographicSpaceStatics3Vtbl holographicspace_statics3_vtbl = -{ - holographicspace_statics3_QueryInterface, - holographicspace_statics3_AddRef, - holographicspace_statics3_Release, - /* IInspectable methods */ - holographicspace_statics3_GetIids, - holographicspace_statics3_GetRuntimeClassName, - holographicspace_statics3_GetTrustLevel, - /* IHolographicSpaceStatics3 methods */ - holographicspace_statics3_get_IsConfigured, -}; - -DEFINE_IINSPECTABLE( holographicspace_interop, IHolographicSpaceInterop, struct holographicspace, IActivationFactory_iface ) - -static HRESULT WINAPI holographicspace_interop_CreateForWindow( IHolographicSpaceInterop *iface, - HWND window, REFIID iid, void **holographic_space ) -{ - FIXME( "iface %p, window %p, iid %s, holographic_space %p.\n", iface, window, debugstr_guid( iid ), holographic_space ); - - *holographic_space = NULL; - return E_NOTIMPL; -} - -static const struct IHolographicSpaceInteropVtbl holographicspace_interop_vtbl = -{ - holographicspace_interop_QueryInterface, - holographicspace_interop_AddRef, - holographicspace_interop_Release, - /* IInspectable methods */ - holographicspace_interop_GetIids, - holographicspace_interop_GetRuntimeClassName, - holographicspace_interop_GetTrustLevel, - /* IHolographicSpaceInterop methods */ - holographicspace_interop_CreateForWindow, -}; - -static struct holographicspace holographicspace_statics = -{ - {&factory_vtbl}, - {&holographicspace_statics2_vtbl}, - {&holographicspace_statics3_vtbl}, - {&holographicspace_interop_vtbl}, - 1, -}; - -IActivationFactory *holographicspace_factory = &holographicspace_statics.IActivationFactory_iface; diff --git a/dlls/windows.perception.stub/main.c b/dlls/windows.perception.stub/main.c index 5db2c3015ca..de3b7d389e8 100644 --- a/dlls/windows.perception.stub/main.c +++ b/dlls/windows.perception.stub/main.c @@ -41,7 +41,7 @@ HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **fa if (!wcscmp( buffer, RuntimeClass_Windows_Perception_Spatial_Surfaces_SpatialSurfaceObserver )) IActivationFactory_QueryInterface( observer_factory, &IID_IActivationFactory, (void **)factory ); if (!wcscmp( buffer, RuntimeClass_Windows_Graphics_Holographic_HolographicSpace )) - IActivationFactory_QueryInterface( holographicspace_factory, &IID_IActivationFactory, (void **)factory ); + IActivationFactory_QueryInterface( holographic_space_factory, &IID_IActivationFactory, (void **)factory );
if (*factory) return S_OK; return CLASS_E_CLASSNOTAVAILABLE; diff --git a/dlls/windows.perception.stub/private.h b/dlls/windows.perception.stub/private.h index ceaa2944174..bf233e72fd4 100644 --- a/dlls/windows.perception.stub/private.h +++ b/dlls/windows.perception.stub/private.h @@ -35,11 +35,12 @@ #define WIDL_using_Windows_Perception_Spatial_Surfaces #include "windows.perception.spatial.surfaces.h" #define WIDL_using_Windows_Graphics_Holographic +#define WIDL_using_Windows_Graphics_DirectX_Direct3D11 #include "windows.graphics.holographic.h" #include "holographicspaceinterop.h"
extern IActivationFactory *observer_factory; -extern IActivationFactory *holographicspace_factory; +extern IActivationFactory *holographic_space_factory;
#define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ static inline impl_type *impl_from( iface_type *iface ) \ diff --git a/dlls/windows.perception.stub/tests/perception.c b/dlls/windows.perception.stub/tests/perception.c index 2e9b2db2904..4623ae281dc 100644 --- a/dlls/windows.perception.stub/tests/perception.c +++ b/dlls/windows.perception.stub/tests/perception.c @@ -231,13 +231,11 @@ static void test_HolographicSpaceStatics(void)
holographic_space = (void *)0xdeadbeef; hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, NULL, &IID_IHolographicSpaceInterop, (void **)&holographic_space ); - todo_wine ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); todo_wine ok( holographic_space == (void *)0xdeadbeef, "got holographic_space %p.\n", holographic_space ); hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, (void *)0xdeadbeef, &IID_IHolographicSpaceInterop, (void **)&holographic_space ); ok( IsWindowVisible( (void *)0xdeadbeef ) == FALSE, "got IsWindowVisible %d\n", IsWindowVisible( (void *)0xdeadbeef ) ); - todo_wine ok( hr == E_INVALIDARG || broken(hr == E_ACCESSDENIED) /* w1064v1709 */ || broken(hr == E_NOINTERFACE) /* w11 */, "got hr %#lx.\n", hr ); ok( holographic_space == NULL, "got holographic_space %p.\n", holographic_space ); if (hr == E_ACCESSDENIED) goto cleanup; @@ -247,30 +245,27 @@ static void test_HolographicSpaceStatics(void)
holographic_space = (void *)0xdeadbeef; hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, window, &IID_IHolographicSpace, (void **)&holographic_space ); - todo_wine ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); ok( holographic_space == NULL, "got holographic_space %p.\n", holographic_space );
ShowWindow( window, SW_HIDE ); ok( IsWindowVisible( window ) == FALSE, "got IsWindowVisible %d\n", IsWindowVisible( window ) ); hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, window, &IID_IHolographicSpace, (void **)&holographic_space ); - todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); ok( IsWindowVisible( window ) == FALSE, "got IsWindowVisible %d\n", IsWindowVisible( window ) );
- if (SUCCEEDED(hr)) - { - check_interface( holographic_space, &IID_IUnknown, FALSE ); - check_interface( holographic_space, &IID_IInspectable, FALSE ); - check_interface( holographic_space, &IID_IAgileObject, FALSE ); + check_interface( holographic_space, &IID_IUnknown, FALSE ); + check_interface( holographic_space, &IID_IInspectable, FALSE ); + check_interface( holographic_space, &IID_IAgileObject, FALSE );
- ref = IHolographicSpace_Release( holographic_space ); - ok( ref == 0, "got ref %ld.\n", ref ); + ref = IHolographicSpace_Release( holographic_space ); + ok( ref == 0, "got ref %ld.\n", ref ); + + hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, window, &IID_IHolographicSpace, (void **)&holographic_space ); + todo_wine + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + if (SUCCEEDED(hr)) IHolographicSpace_Release( holographic_space );
- hr = IHolographicSpaceInterop_CreateForWindow( holographic_space_interop, window, &IID_IHolographicSpace, (void **)&holographic_space ); - todo_wine - ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); - } DestroyWindow( window ); cleanup: ref = IHolographicSpaceInterop_Release( holographic_space_interop );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/windows.perception.stub/tests/perception.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/dlls/windows.perception.stub/tests/perception.c b/dlls/windows.perception.stub/tests/perception.c index 4623ae281dc..fa03aed42c8 100644 --- a/dlls/windows.perception.stub/tests/perception.c +++ b/dlls/windows.perception.stub/tests/perception.c @@ -158,6 +158,7 @@ static void test_HolographicSpaceStatics(void) IHolographicSpaceStatics3 *holographicspace_statics3; IHolographicSpaceInterop *holographic_space_interop; IHolographicSpace *holographic_space; + HolographicAdapterId adapter_id; IActivationFactory *factory; BOOLEAN value; HWND window; @@ -258,6 +259,14 @@ static void test_HolographicSpaceStatics(void) check_interface( holographic_space, &IID_IInspectable, FALSE ); check_interface( holographic_space, &IID_IAgileObject, FALSE );
+ hr = IHolographicSpace_get_PrimaryAdapterId( holographic_space, &adapter_id ); + todo_wine + ok( hr == S_OK, "got hr %#lx.\n", hr ); + todo_wine + ok( adapter_id.LowPart == 0, "got adapter_id.LowPart %u.\n", adapter_id.LowPart ); + todo_wine + ok( adapter_id.HighPart == 0, "got adapter_id.HighPart %u.\n", adapter_id.HighPart ); + ref = IHolographicSpace_Release( holographic_space ); ok( ref == 0, "got ref %ld.\n", ref );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by UE4 VR games.
Proton-Issue: https://github.com/ValveSoftware/Proton/issues/6533 Proton-Issue: https://github.com/ValveSoftware/Proton/issues/8457 --- dlls/windows.perception.stub/holographic_space.c | 8 ++++++-- dlls/windows.perception.stub/tests/perception.c | 3 --- 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/windows.perception.stub/holographic_space.c b/dlls/windows.perception.stub/holographic_space.c index 0e5121e9c7c..0eb2e262cd7 100644 --- a/dlls/windows.perception.stub/holographic_space.c +++ b/dlls/windows.perception.stub/holographic_space.c @@ -272,8 +272,12 @@ static HRESULT WINAPI holographic_space_GetTrustLevel( IHolographicSpace *iface,
static HRESULT WINAPI holographic_space_get_PrimaryAdapterId( IHolographicSpace *iface, HolographicAdapterId *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + TRACE( "iface %p, value %p\n", iface, value ); + + value->LowPart = 0; + value->HighPart = 0; + + return S_OK; }
static HRESULT WINAPI holographic_space_SetDirect3D11Device( IHolographicSpace *iface, IDirect3DDevice *value ) diff --git a/dlls/windows.perception.stub/tests/perception.c b/dlls/windows.perception.stub/tests/perception.c index fa03aed42c8..08849af3a94 100644 --- a/dlls/windows.perception.stub/tests/perception.c +++ b/dlls/windows.perception.stub/tests/perception.c @@ -260,11 +260,8 @@ static void test_HolographicSpaceStatics(void) check_interface( holographic_space, &IID_IAgileObject, FALSE );
hr = IHolographicSpace_get_PrimaryAdapterId( holographic_space, &adapter_id ); - todo_wine ok( hr == S_OK, "got hr %#lx.\n", hr ); - todo_wine ok( adapter_id.LowPart == 0, "got adapter_id.LowPart %u.\n", adapter_id.LowPart ); - todo_wine ok( adapter_id.HighPart == 0, "got adapter_id.HighPart %u.\n", adapter_id.HighPart );
ref = IHolographicSpace_Release( holographic_space );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- .../holographic_space.c | 18 +++++++++++++----- .../windows.perception.stub/tests/perception.c | 3 +++ 2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/dlls/windows.perception.stub/holographic_space.c b/dlls/windows.perception.stub/holographic_space.c index 0eb2e262cd7..8e523fe6fd6 100644 --- a/dlls/windows.perception.stub/holographic_space.c +++ b/dlls/windows.perception.stub/holographic_space.c @@ -22,6 +22,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(perception);
+static EventRegistrationToken dummy_cookie = {.value = 0xdeadbeef}; + struct holographic_space_statics { IActivationFactory IActivationFactory_iface; @@ -283,33 +285,39 @@ static HRESULT WINAPI holographic_space_get_PrimaryAdapterId( IHolographicSpace static HRESULT WINAPI holographic_space_SetDirect3D11Device( IHolographicSpace *iface, IDirect3DDevice *value ) { FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + + if (!value) return E_INVALIDARG; + return S_OK; }
static HRESULT WINAPI holographic_space_add_CameraAdded( IHolographicSpace *iface, ITypedEventHandler_HolographicSpace_HolographicSpaceCameraAddedEventArgs *handler, EventRegistrationToken *cookie ) { FIXME( "iface %p, handler %p, cookie %p stub!\n", iface, handler, cookie ); - return E_NOTIMPL; + + *cookie = dummy_cookie; + return S_OK; }
static HRESULT WINAPI holographic_space_remove_CameraAdded( IHolographicSpace *iface, EventRegistrationToken cookie ) { FIXME( "iface %p, cookie %#I64x stub!\n", iface, cookie.value ); - return E_NOTIMPL; + return S_OK; }
static HRESULT WINAPI holographic_space_add_CameraRemoved( IHolographicSpace *iface, ITypedEventHandler_HolographicSpace_HolographicSpaceCameraRemovedEventArgs *handler, EventRegistrationToken *cookie ) { FIXME( "iface %p, handler %p, cookie %p stub!\n", iface, handler, cookie ); - return E_NOTIMPL; + + *cookie = dummy_cookie; + return S_OK; }
static HRESULT WINAPI holographic_space_remove_CameraRemoved( IHolographicSpace *iface, EventRegistrationToken cookie ) { FIXME( "iface %p, cookie %#I64x stub!\n", iface, cookie.value ); - return E_NOTIMPL; + return S_OK; }
static HRESULT WINAPI holographic_space_CreateNextFrame( IHolographicSpace *iface, IHolographicFrame **value ) diff --git a/dlls/windows.perception.stub/tests/perception.c b/dlls/windows.perception.stub/tests/perception.c index 08849af3a94..8fea17882b0 100644 --- a/dlls/windows.perception.stub/tests/perception.c +++ b/dlls/windows.perception.stub/tests/perception.c @@ -264,6 +264,9 @@ static void test_HolographicSpaceStatics(void) ok( adapter_id.LowPart == 0, "got adapter_id.LowPart %u.\n", adapter_id.LowPart ); ok( adapter_id.HighPart == 0, "got adapter_id.HighPart %u.\n", adapter_id.HighPart );
+ hr = IHolographicSpace_SetDirect3D11Device( holographic_space, NULL ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + ref = IHolographicSpace_Release( holographic_space ); ok( ref == 0, "got ref %ld.\n", ref );
On Mon Nov 10 05:44:05 2025 +0000, Mohamad Al-Jaf wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/9355/diffs?diff_id=222496&start_sha=30e9f8deec4b09cc2f458a9dc108f89b65da4700#1b417e40d879bb765372c2d86a2f0776b5fe8e71_200_244)
Windows does something internally to the HWND regardless of whether the function succeeds or not. Whatever it does to the HWND it checks for when called again.
On Fri Nov 7 11:33:10 2025 +0000, Rémi Bernon wrote:
Why does it work now and failed above? If this is a timing issue you probably should try processing window messages after its creation. Creating visible windows many times is also the best way to get flaky tests, on Linux this will cause a lot of asynchronous requests to the window manager and races to get the foreground window. I think you should create the window once as soon as possible, make sure it's foreground (copy create_foreground_window from some other tests for instance), then use it for as long as possible. Also, I'm not sure it's very useful to tests all the failure cases above with unsupported interfaces, you should try to make it succeed with the most obvious interface *then* test the available interfaces on the created object.
I don't think it's a timing issue. As above, Windows does something internally to the HWND. Tested quite a lot of things, but I couldn't figure out what exactly it does. At the very least, it requires the window to not be visible.
Sure, removed most of the unsupported interface tests. Used create_foreground_window to create one window. Also, fullscreen has no apparent effect.
On Mon Nov 10 05:44:06 2025 +0000, Mohamad Al-Jaf wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/9355/diffs?diff_id=222496&start_sha=30e9f8deec4b09cc2f458a9dc108f89b65da4700#7947494b099157a26b9637f946038c6438e45acf_362_359)
Sure, got rid of the separate condition.
This merge request was approved by Rémi Bernon.