[PATCH v2 1/4] dxgi: Implement dxgi_factory_MakeWindowAssociation().
Zhiyi Zhang
zzhang at codeweavers.com
Wed Apr 24 09:19:13 CDT 2019
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
v2: Add tests to show that window association doesn't modify WNDPROC.
dlls/dxgi/dxgi_private.h | 1 +
dlls/dxgi/factory.c | 74 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 72 insertions(+), 3 deletions(-)
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index b6999c729a..7fb28287ad 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -115,6 +115,7 @@ struct dxgi_factory
struct wined3d *wined3d;
BOOL extended;
HWND device_window;
+ struct list associated_windows;
};
HRESULT dxgi_factory_create(REFIID riid, void **factory, BOOL extended) DECLSPEC_HIDDEN;
diff --git a/dlls/dxgi/factory.c b/dlls/dxgi/factory.c
index 52c145bc6a..5aadef62e4 100644
--- a/dlls/dxgi/factory.c
+++ b/dlls/dxgi/factory.c
@@ -24,6 +24,17 @@
WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
+const WCHAR wine_dxgi_associated_factory_propW[] =
+ {'W','i','n','e','D','X','G','I','A','s','s','o','c','i','a','t','e','d','F','a','c','t','o','r','y',0};
+const WCHAR wine_dxgi_associated_flags_propW[] =
+ {'W','i','n','e','D','X','G','I','A','s','s','o','c','i','a','t','e','d','F','l','a','g','s',0};
+
+struct dxgi_associated_window
+{
+ HWND hwnd;
+ struct list entry;
+};
+
static inline struct dxgi_factory *impl_from_IWineDXGIFactory(IWineDXGIFactory *iface)
{
return CONTAINING_RECORD(iface, struct dxgi_factory, IWineDXGIFactory_iface);
@@ -70,11 +81,20 @@ static ULONG STDMETHODCALLTYPE dxgi_factory_Release(IWineDXGIFactory *iface)
{
struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface);
ULONG refcount = InterlockedDecrement(&factory->refcount);
+ struct dxgi_associated_window *window, *window2;
TRACE("%p decreasing refcount to %u.\n", iface, refcount);
if (!refcount)
{
+ LIST_FOR_EACH_ENTRY_SAFE(window, window2, &factory->associated_windows, struct dxgi_associated_window, entry)
+ {
+ RemovePropW(window->hwnd, wine_dxgi_associated_factory_propW);
+ RemovePropW(window->hwnd, wine_dxgi_associated_flags_propW);
+ list_remove(&window->entry);
+ heap_free(window);
+ }
+
if (factory->device_window)
DestroyWindow(factory->device_window);
@@ -172,11 +192,58 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumAdapters(IWineDXGIFactory *ifa
}
static HRESULT STDMETHODCALLTYPE dxgi_factory_MakeWindowAssociation(IWineDXGIFactory *iface,
- HWND window, UINT flags)
+ HWND hwnd, UINT flags)
{
- FIXME("iface %p, window %p, flags %#x stub!\n", iface, window, flags);
+ struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface);
+ struct dxgi_associated_window *window, *window2;
+ HANDLE handle;
+ HRESULT hr = S_OK;
- return S_OK;
+ TRACE("iface %p, window %p, flags %#x.\n", iface, hwnd, flags);
+
+ if (flags > DXGI_MWA_VALID)
+ return DXGI_ERROR_INVALID_CALL;
+
+ wined3d_mutex_lock();
+
+ /* Delete all associated windows from this factory */
+ if (!hwnd)
+ {
+ LIST_FOR_EACH_ENTRY_SAFE(window, window2, &factory->associated_windows, struct dxgi_associated_window, entry)
+ {
+ RemovePropW(window->hwnd, wine_dxgi_associated_factory_propW);
+ RemovePropW(window->hwnd, wine_dxgi_associated_flags_propW);
+ list_remove(&window->entry);
+ heap_free(window);
+ }
+ }
+ /* Add a new window association */
+ else
+ {
+ handle = GetPropW(hwnd, wine_dxgi_associated_factory_propW);
+ if (!handle)
+ {
+ window = heap_alloc_zero(sizeof(struct dxgi_associated_window));
+ if (!window)
+ {
+ hr = E_OUTOFMEMORY;
+ goto done;
+ }
+
+ SetPropW(hwnd, wine_dxgi_associated_factory_propW, iface);
+ SetPropW(hwnd, wine_dxgi_associated_flags_propW, (HANDLE)(UINT_PTR)flags);
+ window->hwnd = hwnd;
+ list_add_head(&factory->associated_windows, &window->entry);
+ }
+ else if (handle == iface)
+ SetPropW(hwnd, wine_dxgi_associated_flags_propW, (HANDLE)(UINT_PTR)flags);
+ else
+ WARN("Window is already associated to another factory.\n");
+ }
+
+done:
+ wined3d_mutex_unlock();
+ return hr;
}
static HRESULT STDMETHODCALLTYPE dxgi_factory_GetWindowAssociation(IWineDXGIFactory *iface, HWND *window)
@@ -501,6 +568,7 @@ static HRESULT dxgi_factory_init(struct dxgi_factory *factory, BOOL extended)
}
factory->extended = extended;
+ list_init(&factory->associated_windows);
return S_OK;
}
--
2.20.1
More information about the wine-devel
mailing list