Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- 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; }