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; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=51375
Your paranoid android.
=== debian9 (64 bit WoW report) ===
Report errors: dxgi:dxgi has no test summary line (early exit of the main process?) dxgi:dxgi has unaccounted for todo messages
=== debian9 (build log) ===
X Error of failed request: GLXBadFBConfig Major opcode of failed request: 154 (GLX) Minor opcode of failed request: 34 ()
On Tue, 23 Apr 2019 at 17:29, Zhiyi Zhang zzhang@codeweavers.com wrote:
dlls/dxgi/dxgi_private.h | 1 + dlls/dxgi/factory.c | 74 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 3 deletions(-)
Would it make sense to adapt the existing wined3d_wndproc_table in wined3d to handle DXGI window associations?
On 4/24/19 1:54 AM, Henri Verbeet wrote:
On Tue, 23 Apr 2019 at 17:29, Zhiyi Zhang zzhang@codeweavers.com wrote:
dlls/dxgi/dxgi_private.h | 1 + dlls/dxgi/factory.c | 74 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 3 deletions(-)
Would it make sense to adapt the existing wined3d_wndproc_table in wined3d to handle DXGI window associations?
I am sure it will make more sense. If we use wined3d_wndproc_table then it doesn't explain why set up a hook to ignore WM_SYSKEYDOWN breaks Alt+Enter, or why SendMessage(WM_SYSKEYDOWN) don't trigger Alt+Enter while PostMessage(WM_SYSKEYDOWN) does. It seems more accurate to set up a hook to intercept message before GetMessage returns.
Another thing may be of interest. Application doesn't receive a WM_SYSKEYDOWN(Alt+Enter) when Alt+Enter is pressed.
On Wed, 24 Apr 2019 at 07:15, Zhiyi Zhang zzhang@codeweavers.com wrote:
On 4/24/19 1:54 AM, Henri Verbeet wrote:
Would it make sense to adapt the existing wined3d_wndproc_table in wined3d to handle DXGI window associations?
I am sure it will make more sense. If we use wined3d_wndproc_table then it doesn't explain why set up a hook to ignore WM_SYSKEYDOWN breaks Alt+Enter, or why SendMessage(WM_SYSKEYDOWN) don't trigger Alt+Enter while PostMessage(WM_SYSKEYDOWN) does. It seems more accurate to set up a hook to intercept message before GetMessage returns.
Another thing may be of interest. Application doesn't receive a WM_SYSKEYDOWN(Alt+Enter) when Alt+Enter is pressed.
I'm not objecting to using hooks, although it would still be good to have tests to validate that e.g. MakeWindowAssociation() or swapchain creation doesn't change GWLP_WNDPROC on the window. It seems undesirable though to track the window to swapchain/device association in two different places, and to a lesser extent the same goes for handling the events themselves.
On 4/24/19 6:48 PM, Henri Verbeet wrote:
On Wed, 24 Apr 2019 at 07:15, Zhiyi Zhang zzhang@codeweavers.com wrote:
On 4/24/19 1:54 AM, Henri Verbeet wrote:
Would it make sense to adapt the existing wined3d_wndproc_table in wined3d to handle DXGI window associations?
I am sure it will make more sense. If we use wined3d_wndproc_table then it doesn't explain
Sorry, typo. I shouldn't get up so early and reply emails. I meant I am *not* sure it will make more sense
why set up a hook to ignore WM_SYSKEYDOWN breaks Alt+Enter, or why SendMessage(WM_SYSKEYDOWN) don't trigger Alt+Enter while PostMessage(WM_SYSKEYDOWN) does. It seems more accurate to set up a hook to intercept message before GetMessage returns.
Another thing may be of interest. Application doesn't receive a WM_SYSKEYDOWN(Alt+Enter) when Alt+Enter is pressed.
I'm not objecting to using hooks, although it would still be good to have tests to validate that e.g. MakeWindowAssociation() or swapchain
I'll add more tests.
creation doesn't change GWLP_WNDPROC on the window. It seems undesirable though to track the window to swapchain/device association in two different places, and to a lesser extent the same goes for handling the events themselves.
Right. It doesn't look nice this way. MakeWindowAssociation being in IDXGIFactory puzzles me at the very start. I haven't found a way for it to look nicer.