[PATCH v3 1/5] dxgi: Implement dxgi_factory_MakeWindowAssociation().
Zhiyi Zhang
zzhang at codeweavers.com
Tue May 21 07:54:31 CDT 2019
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
v2: Add tests to show that window association doesn't modify WNDPROC.
v3: Move most of the code into wined3d. Supersede 163626~163629
dlls/dxgi/factory.c | 15 ++++++--
dlls/wined3d/swapchain.c | 1 +
dlls/wined3d/wined3d.spec | 2 ++
dlls/wined3d/wined3d_main.c | 62 ++++++++++++++++++++++++++++++++++
dlls/wined3d/wined3d_private.h | 10 ++++++
include/wine/wined3d.h | 2 ++
6 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/dlls/dxgi/factory.c b/dlls/dxgi/factory.c
index 52c145bc6a..a574090026 100644
--- a/dlls/dxgi/factory.c
+++ b/dlls/dxgi/factory.c
@@ -174,9 +174,20 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumAdapters(IWineDXGIFactory *ifa
static HRESULT STDMETHODCALLTYPE dxgi_factory_MakeWindowAssociation(IWineDXGIFactory *iface,
HWND window, UINT flags)
{
- FIXME("iface %p, window %p, flags %#x stub!\n", iface, window, flags);
+ struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface);
- return S_OK;
+ TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
+
+ if (flags > DXGI_MWA_VALID)
+ return DXGI_ERROR_INVALID_CALL;
+
+ if (!window)
+ {
+ wined3d_remove_window_association(factory->wined3d);
+ return S_OK;
+ }
+
+ return wined3d_add_window_association(factory->wined3d, window, flags);
}
static HRESULT STDMETHODCALLTYPE dxgi_factory_GetWindowAssociation(IWineDXGIFactory *iface, HWND *window)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index fbedd7470d..808602cb15 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -22,6 +22,7 @@
#include "config.h"
#include "wine/port.h"
+#include "wine/list.h"
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 040b9fc4ac..733eedb485 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -1,6 +1,7 @@
@ stdcall wined3d_mutex_lock()
@ stdcall wined3d_mutex_unlock()
+@ cdecl wined3d_add_window_association(ptr ptr long)
@ cdecl wined3d_calculate_format_pitch(ptr long long long)
@ cdecl wined3d_check_depth_stencil_match(ptr long long long long long)
@ cdecl wined3d_check_device_format(ptr long long long long long long long)
@@ -20,6 +21,7 @@
@ cdecl wined3d_get_output_desc(ptr long ptr)
@ cdecl wined3d_incref(ptr)
@ cdecl wined3d_register_software_device(ptr ptr)
+@ cdecl wined3d_remove_window_association(ptr)
@ cdecl wined3d_set_adapter_display_mode(ptr long ptr)
@ cdecl wined3d_blend_state_create(ptr ptr ptr ptr ptr)
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index 180e2d262e..9ef023dfb7 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -48,6 +48,8 @@ struct wined3d_wndproc_table
static struct wined3d_wndproc_table wndproc_table;
+struct list window_associations = LIST_INIT(window_associations);
+
static CRITICAL_SECTION wined3d_cs;
static CRITICAL_SECTION_DEBUG wined3d_cs_debug =
{
@@ -555,6 +557,66 @@ void wined3d_unregister_window(HWND window)
wined3d_wndproc_mutex_unlock();
}
+HRESULT CDECL wined3d_add_window_association(struct wined3d *wined3d, HWND hwnd, UINT flags)
+{
+ struct wined3d_window_association *association;
+ BOOL found = FALSE;
+ HRESULT hr = S_OK;
+
+ wined3d_mutex_lock();
+ LIST_FOR_EACH_ENTRY(association, &window_associations, struct wined3d_window_association, entry)
+ {
+ if (hwnd == association->hwnd)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (found)
+ {
+ if(association->wined3d != wined3d)
+ WARN("window %p is already associated\n", hwnd);
+ else
+ association->flags = flags;
+ goto done;
+ }
+ else
+ {
+ association = heap_alloc_zero(sizeof(*association));
+ if (!association)
+ {
+ hr = E_OUTOFMEMORY;
+ goto done;
+ }
+
+ association->wined3d = wined3d;
+ association->hwnd = hwnd;
+ association->flags = flags;
+ list_add_head(&window_associations, &association->entry);
+ }
+
+done:
+ wined3d_mutex_unlock();
+ return hr;
+}
+
+void CDECL wined3d_remove_window_association(struct wined3d *wined3d)
+{
+ struct wined3d_window_association *association, *association2;
+
+ wined3d_mutex_lock();
+ LIST_FOR_EACH_ENTRY_SAFE(association, association2, &window_associations, struct wined3d_window_association, entry)
+ {
+ if (wined3d == association->wined3d)
+ {
+ list_remove(&association->entry);
+ heap_free(association);
+ }
+ }
+ wined3d_mutex_unlock();
+}
+
/* At process attach */
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
{
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0fc56462b0..f277d898f3 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -215,6 +215,16 @@ struct wined3d_d3d_info
DWORD multisample_draw_location;
};
+struct wined3d_window_association
+{
+ struct wined3d *wined3d;
+ HWND hwnd;
+ UINT flags;
+ struct list entry;
+};
+
+extern struct list window_associations DECLSPEC_HIDDEN;
+
static const struct color_fixup_desc COLOR_FIXUP_IDENTITY =
{0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W};
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 958ade166c..8514860a79 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2172,6 +2172,7 @@ typedef HRESULT (CDECL *wined3d_device_reset_cb)(struct wined3d_resource *resour
void __stdcall wined3d_mutex_lock(void);
void __stdcall wined3d_mutex_unlock(void);
+HRESULT __cdecl wined3d_add_window_association(struct wined3d *wined3d, HWND hwnd, UINT flags);
UINT __cdecl wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT adapter_idx,
enum wined3d_format_id format_id, UINT width);
HRESULT __cdecl wined3d_check_depth_stencil_match(const struct wined3d *wined3d, UINT adapter_idx,
@@ -2211,6 +2212,7 @@ HRESULT __cdecl wined3d_get_output_desc(const struct wined3d *wined3d, unsigned
struct wined3d_output_desc *desc);
ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
HRESULT __cdecl wined3d_register_software_device(struct wined3d *wined3d, void *init_function);
+void __cdecl wined3d_remove_window_association(struct wined3d *wined3d);
HRESULT __cdecl wined3d_set_adapter_display_mode(struct wined3d *wined3d,
UINT adapter_idx, const struct wined3d_display_mode *mode);
--
2.20.1
More information about the wine-devel
mailing list