dxgi: Implement Alt+Enter handling.
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b94a6b1efd
commit
a600760fa1
|
@ -174,7 +174,21 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumAdapters(IWineDXGIFactory *ifa
|
||||||
static HRESULT STDMETHODCALLTYPE dxgi_factory_MakeWindowAssociation(IWineDXGIFactory *iface,
|
static HRESULT STDMETHODCALLTYPE dxgi_factory_MakeWindowAssociation(IWineDXGIFactory *iface,
|
||||||
HWND window, UINT flags)
|
HWND window, UINT flags)
|
||||||
{
|
{
|
||||||
FIXME("iface %p, window %p, flags %#x stub!\n", iface, window, flags);
|
struct dxgi_factory *factory = impl_from_IWineDXGIFactory(iface);
|
||||||
|
|
||||||
|
TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags);
|
||||||
|
|
||||||
|
if (flags > DXGI_MWA_VALID)
|
||||||
|
return DXGI_ERROR_INVALID_CALL;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
wined3d_unregister_windows(factory->wined3d);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wined3d_register_window(factory->wined3d, window, NULL, flags))
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5086,7 +5086,7 @@ static void test_window_association(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IDXGIFactory_MakeWindowAssociation(factory, swapchain_desc.OutputWindow, DXGI_MWA_VALID + 1);
|
hr = IDXGIFactory_MakeWindowAssociation(factory, swapchain_desc.OutputWindow, DXGI_MWA_VALID + 1);
|
||||||
todo_wine ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
|
ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
/* Alt+Enter tests. */
|
/* Alt+Enter tests. */
|
||||||
hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
|
hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
|
||||||
|
@ -5134,10 +5134,9 @@ static void test_window_association(void)
|
||||||
flush_events();
|
flush_events();
|
||||||
hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
|
hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
|
||||||
ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
|
ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
|
||||||
todo_wine_if(tests[i].expect_fullscreen)
|
ok(fullscreen == tests[i].expect_fullscreen
|
||||||
ok(fullscreen == tests[i].expect_fullscreen
|
|| broken(tests[i].broken_d3d10 && fullscreen),
|
||||||
|| broken(tests[i].broken_d3d10 && fullscreen),
|
"Test %u: Got unexpected fullscreen %#x.\n", i, fullscreen);
|
||||||
"Test %u: Got unexpected fullscreen %#x.\n", i, fullscreen);
|
|
||||||
|
|
||||||
wndproc = GetWindowLongPtrW(swapchain_desc.OutputWindow, GWLP_WNDPROC);
|
wndproc = GetWindowLongPtrW(swapchain_desc.OutputWindow, GWLP_WNDPROC);
|
||||||
ok(wndproc == original_wndproc, "Text %u: Got unexpected wndproc %#lx, expected %#lx.\n",
|
ok(wndproc == original_wndproc, "Text %u: Got unexpected wndproc %#lx, expected %#lx.\n",
|
||||||
|
|
|
@ -511,7 +511,7 @@ unsigned int wined3d_bind_flags_from_dxgi_usage(DXGI_USAGE dxgi_usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DXGI_WINED3D_SWAPCHAIN_FLAGS \
|
#define DXGI_WINED3D_SWAPCHAIN_FLAGS \
|
||||||
(WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE | WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT)
|
(WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE | WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT | WINED3D_SWAPCHAIN_HOOK)
|
||||||
|
|
||||||
unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags)
|
unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1015,7 +1015,7 @@ HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device,
|
||||||
{
|
{
|
||||||
TRACE("device %p, window %p.\n", device, window);
|
TRACE("device %p, window %p.\n", device, window);
|
||||||
|
|
||||||
if (!wined3d_register_window(window, device))
|
if (!wined3d_register_window(NULL, window, device, 0))
|
||||||
{
|
{
|
||||||
ERR("Failed to register window %p.\n", window);
|
ERR("Failed to register window %p.\n", window);
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
|
@ -121,6 +121,7 @@ ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain)
|
||||||
device = swapchain->device;
|
device = swapchain->device;
|
||||||
if (device->swapchain_count && device->swapchains[0] == swapchain)
|
if (device->swapchain_count && device->swapchains[0] == swapchain)
|
||||||
wined3d_device_uninit_3d(device);
|
wined3d_device_uninit_3d(device);
|
||||||
|
wined3d_unhook_swapchain(swapchain);
|
||||||
wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
|
wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
|
||||||
|
|
||||||
swapchain_cleanup(swapchain);
|
swapchain_cleanup(swapchain);
|
||||||
|
@ -1037,6 +1038,9 @@ HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct win
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (desc->flags & WINED3D_SWAPCHAIN_HOOK)
|
||||||
|
wined3d_hook_swapchain(object);
|
||||||
|
|
||||||
if (desc->flags & WINED3D_SWAPCHAIN_IMPLICIT)
|
if (desc->flags & WINED3D_SWAPCHAIN_IMPLICIT)
|
||||||
{
|
{
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
@ cdecl wined3d_get_output_desc(ptr long ptr)
|
@ cdecl wined3d_get_output_desc(ptr long ptr)
|
||||||
@ cdecl wined3d_incref(ptr)
|
@ cdecl wined3d_incref(ptr)
|
||||||
@ cdecl wined3d_register_software_device(ptr ptr)
|
@ cdecl wined3d_register_software_device(ptr ptr)
|
||||||
|
@ cdecl wined3d_register_window(ptr ptr ptr long)
|
||||||
@ cdecl wined3d_set_adapter_display_mode(ptr long ptr)
|
@ cdecl wined3d_set_adapter_display_mode(ptr long ptr)
|
||||||
|
@ cdecl wined3d_unregister_windows(ptr)
|
||||||
|
|
||||||
@ cdecl wined3d_blend_state_create(ptr ptr ptr ptr ptr)
|
@ cdecl wined3d_blend_state_create(ptr ptr ptr ptr ptr)
|
||||||
@ cdecl wined3d_blend_state_decref(ptr)
|
@ cdecl wined3d_blend_state_decref(ptr)
|
||||||
|
|
|
@ -33,20 +33,47 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||||
|
|
||||||
struct wined3d_wndproc
|
struct wined3d_wndproc
|
||||||
{
|
{
|
||||||
|
struct wined3d *wined3d;
|
||||||
HWND window;
|
HWND window;
|
||||||
BOOL unicode;
|
BOOL unicode;
|
||||||
WNDPROC proc;
|
WNDPROC proc;
|
||||||
struct wined3d_device *device;
|
struct wined3d_device *device;
|
||||||
|
uint32_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wined3d_wndproc_table
|
struct wined3d_wndproc_table
|
||||||
{
|
{
|
||||||
struct wined3d_wndproc *entries;
|
struct wined3d_wndproc *entries;
|
||||||
unsigned int count;
|
SIZE_T count;
|
||||||
SIZE_T size;
|
SIZE_T size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wined3d_window_hook
|
||||||
|
{
|
||||||
|
HHOOK hook;
|
||||||
|
DWORD thread_id;
|
||||||
|
unsigned int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wined3d_hooked_swapchain
|
||||||
|
{
|
||||||
|
struct wined3d_swapchain *swapchain;
|
||||||
|
DWORD thread_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wined3d_hook_table
|
||||||
|
{
|
||||||
|
struct wined3d_window_hook *hooks;
|
||||||
|
SIZE_T hooks_size;
|
||||||
|
SIZE_T hook_count;
|
||||||
|
|
||||||
|
struct wined3d_hooked_swapchain *swapchains;
|
||||||
|
SIZE_T swapchains_size;
|
||||||
|
SIZE_T swapchain_count;
|
||||||
|
};
|
||||||
|
|
||||||
static struct wined3d_wndproc_table wndproc_table;
|
static struct wined3d_wndproc_table wndproc_table;
|
||||||
|
static struct wined3d_hook_table hook_table;
|
||||||
|
|
||||||
static CRITICAL_SECTION wined3d_cs;
|
static CRITICAL_SECTION wined3d_cs;
|
||||||
static CRITICAL_SECTION_DEBUG wined3d_cs_debug =
|
static CRITICAL_SECTION_DEBUG wined3d_cs_debug =
|
||||||
|
@ -396,6 +423,14 @@ static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL)
|
||||||
}
|
}
|
||||||
heap_free(wndproc_table.entries);
|
heap_free(wndproc_table.entries);
|
||||||
|
|
||||||
|
heap_free(hook_table.swapchains);
|
||||||
|
for (i = 0; i < hook_table.hook_count; ++i)
|
||||||
|
{
|
||||||
|
WARN("Leftover hook table entry %p.\n", &hook_table.hooks[i]);
|
||||||
|
UnhookWindowsHookEx(hook_table.hooks[i].hook);
|
||||||
|
}
|
||||||
|
heap_free(hook_table.hooks);
|
||||||
|
|
||||||
heap_free(wined3d_settings.logo);
|
heap_free(wined3d_settings.logo);
|
||||||
UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
|
UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
|
||||||
|
|
||||||
|
@ -424,16 +459,16 @@ static void wined3d_wndproc_mutex_unlock(void)
|
||||||
LeaveCriticalSection(&wined3d_wndproc_cs);
|
LeaveCriticalSection(&wined3d_wndproc_cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wined3d_wndproc *wined3d_find_wndproc(HWND window)
|
static struct wined3d_wndproc *wined3d_find_wndproc(HWND window, struct wined3d *wined3d)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < wndproc_table.count; ++i)
|
for (i = 0; i < wndproc_table.count; ++i)
|
||||||
{
|
{
|
||||||
if (wndproc_table.entries[i].window == window)
|
struct wined3d_wndproc *entry = &wndproc_table.entries[i];
|
||||||
{
|
|
||||||
return &wndproc_table.entries[i];
|
if (entry->window == window && entry->wined3d == wined3d)
|
||||||
}
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -447,9 +482,8 @@ static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam
|
||||||
WNDPROC proc;
|
WNDPROC proc;
|
||||||
|
|
||||||
wined3d_wndproc_mutex_lock();
|
wined3d_wndproc_mutex_lock();
|
||||||
entry = wined3d_find_wndproc(window);
|
|
||||||
|
|
||||||
if (!entry)
|
if (!(entry = wined3d_find_wndproc(window, NULL)))
|
||||||
{
|
{
|
||||||
wined3d_wndproc_mutex_unlock();
|
wined3d_wndproc_mutex_unlock();
|
||||||
ERR("Window %p is not registered with wined3d.\n", window);
|
ERR("Window %p is not registered with wined3d.\n", window);
|
||||||
|
@ -468,16 +502,62 @@ static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam
|
||||||
return CallWindowProcA(proc, window, message, wparam, lparam);
|
return CallWindowProcA(proc, window, message, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL wined3d_register_window(HWND window, struct wined3d_device *device)
|
static LRESULT CALLBACK wined3d_hook_proc(int code, WPARAM wparam, LPARAM lparam)
|
||||||
|
{
|
||||||
|
struct wined3d_swapchain_desc swapchain_desc;
|
||||||
|
struct wined3d_swapchain *swapchain;
|
||||||
|
struct wined3d_wndproc *entry;
|
||||||
|
MSG *msg = (MSG *)lparam;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
/* Handle Alt+Enter. */
|
||||||
|
if (code == HC_ACTION && msg->message == WM_SYSKEYDOWN
|
||||||
|
&& msg->wParam == VK_RETURN && (msg->lParam & (KF_ALTDOWN << 16)))
|
||||||
|
{
|
||||||
|
wined3d_wndproc_mutex_lock();
|
||||||
|
|
||||||
|
for (i = 0; i < hook_table.swapchain_count; ++i)
|
||||||
|
{
|
||||||
|
swapchain = hook_table.swapchains[i].swapchain;
|
||||||
|
|
||||||
|
if (swapchain->device_window != msg->hwnd)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((entry = wined3d_find_wndproc(msg->hwnd, swapchain->device->wined3d))
|
||||||
|
&& (entry->flags & (WINED3D_REGISTER_WINDOW_NO_WINDOW_CHANGES
|
||||||
|
| WINED3D_REGISTER_WINDOW_NO_ALT_ENTER)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wined3d_swapchain_get_desc(swapchain, &swapchain_desc);
|
||||||
|
swapchain_desc.windowed = !swapchain_desc.windowed;
|
||||||
|
wined3d_swapchain_set_fullscreen(swapchain, &swapchain_desc, NULL);
|
||||||
|
|
||||||
|
wined3d_wndproc_mutex_unlock();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wined3d_wndproc_mutex_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return CallNextHookEx(0, code, wparam, lparam);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CDECL wined3d_register_window(struct wined3d *wined3d, HWND window,
|
||||||
|
struct wined3d_device *device, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct wined3d_wndproc *entry;
|
struct wined3d_wndproc *entry;
|
||||||
|
|
||||||
|
TRACE("wined3d %p, window %p, device %p, flags %#x.\n", wined3d, window, device, flags);
|
||||||
|
|
||||||
wined3d_wndproc_mutex_lock();
|
wined3d_wndproc_mutex_lock();
|
||||||
|
|
||||||
if (wined3d_find_wndproc(window))
|
if ((entry = wined3d_find_wndproc(window, wined3d)))
|
||||||
{
|
{
|
||||||
|
if (!wined3d)
|
||||||
|
WARN("Window %p is already registered with wined3d.\n", window);
|
||||||
|
entry->flags = flags;
|
||||||
wined3d_wndproc_mutex_unlock();
|
wined3d_wndproc_mutex_unlock();
|
||||||
WARN("Window %p is already registered with wined3d.\n", window);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,61 +572,71 @@ BOOL wined3d_register_window(HWND window, struct wined3d_device *device)
|
||||||
entry = &wndproc_table.entries[wndproc_table.count++];
|
entry = &wndproc_table.entries[wndproc_table.count++];
|
||||||
entry->window = window;
|
entry->window = window;
|
||||||
entry->unicode = IsWindowUnicode(window);
|
entry->unicode = IsWindowUnicode(window);
|
||||||
/* Set a window proc that matches the window. Some applications (e.g. NoX)
|
if (!wined3d)
|
||||||
* replace the window proc after we've set ours, and expect to be able to
|
{
|
||||||
* call the previous one (ours) directly, without using CallWindowProc(). */
|
/* Set a window proc that matches the window. Some applications (e.g.
|
||||||
if (entry->unicode)
|
* NoX) replace the window proc after we've set ours, and expect to be
|
||||||
entry->proc = (WNDPROC)SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc);
|
* able to call the previous one (ours) directly, without using
|
||||||
|
* CallWindowProc(). */
|
||||||
|
if (entry->unicode)
|
||||||
|
entry->proc = (WNDPROC)SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc);
|
||||||
|
else
|
||||||
|
entry->proc = (WNDPROC)SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
entry->proc = (WNDPROC)SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc);
|
{
|
||||||
|
entry->proc = NULL;
|
||||||
|
}
|
||||||
entry->device = device;
|
entry->device = device;
|
||||||
|
entry->wined3d = wined3d;
|
||||||
|
entry->flags = flags;
|
||||||
|
|
||||||
wined3d_wndproc_mutex_unlock();
|
wined3d_wndproc_mutex_unlock();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL restore_wndproc(struct wined3d_wndproc *entry)
|
||||||
|
{
|
||||||
|
LONG_PTR proc;
|
||||||
|
|
||||||
|
if (entry->unicode)
|
||||||
|
{
|
||||||
|
proc = GetWindowLongPtrW(entry->window, GWLP_WNDPROC);
|
||||||
|
if (proc != (LONG_PTR)wined3d_wndproc)
|
||||||
|
return FALSE;
|
||||||
|
SetWindowLongPtrW(entry->window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proc = GetWindowLongPtrA(entry->window, GWLP_WNDPROC);
|
||||||
|
if (proc != (LONG_PTR)wined3d_wndproc)
|
||||||
|
return FALSE;
|
||||||
|
SetWindowLongPtrA(entry->window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void wined3d_unregister_window(HWND window)
|
void wined3d_unregister_window(HWND window)
|
||||||
{
|
{
|
||||||
struct wined3d_wndproc *entry, *last;
|
struct wined3d_wndproc *entry, *last;
|
||||||
LONG_PTR proc;
|
|
||||||
|
|
||||||
wined3d_wndproc_mutex_lock();
|
wined3d_wndproc_mutex_lock();
|
||||||
|
|
||||||
if (!(entry = wined3d_find_wndproc(window)))
|
if (!(entry = wined3d_find_wndproc(window, NULL)))
|
||||||
{
|
{
|
||||||
wined3d_wndproc_mutex_unlock();
|
wined3d_wndproc_mutex_unlock();
|
||||||
ERR("Window %p is not registered with wined3d.\n", window);
|
ERR("Window %p is not registered with wined3d.\n", window);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->unicode)
|
if (entry->proc && !restore_wndproc(entry))
|
||||||
{
|
{
|
||||||
proc = GetWindowLongPtrW(window, GWLP_WNDPROC);
|
entry->device = NULL;
|
||||||
if (proc != (LONG_PTR)wined3d_wndproc)
|
WARN("Not unregistering window %p, current window proc doesn't match wined3d window proc.\n", window);
|
||||||
{
|
wined3d_wndproc_mutex_unlock();
|
||||||
entry->device = NULL;
|
return;
|
||||||
wined3d_wndproc_mutex_unlock();
|
|
||||||
WARN("Not unregistering window %p, window proc %#lx doesn't match wined3d window proc %p.\n",
|
|
||||||
window, proc, wined3d_wndproc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
|
|
||||||
if (proc != (LONG_PTR)wined3d_wndproc)
|
|
||||||
{
|
|
||||||
entry->device = NULL;
|
|
||||||
wined3d_wndproc_mutex_unlock();
|
|
||||||
WARN("Not unregistering window %p, window proc %#lx doesn't match wined3d window proc %p.\n",
|
|
||||||
window, proc, wined3d_wndproc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
last = &wndproc_table.entries[--wndproc_table.count];
|
last = &wndproc_table.entries[--wndproc_table.count];
|
||||||
|
@ -555,6 +645,131 @@ void wined3d_unregister_window(HWND window)
|
||||||
wined3d_wndproc_mutex_unlock();
|
wined3d_wndproc_mutex_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDECL wined3d_unregister_windows(struct wined3d *wined3d)
|
||||||
|
{
|
||||||
|
struct wined3d_wndproc *entry, *last;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
TRACE("wined3d %p.\n", wined3d);
|
||||||
|
|
||||||
|
wined3d_wndproc_mutex_lock();
|
||||||
|
|
||||||
|
while (i < wndproc_table.count)
|
||||||
|
{
|
||||||
|
entry = &wndproc_table.entries[i];
|
||||||
|
|
||||||
|
if (entry->wined3d != wined3d)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->proc && !restore_wndproc(entry))
|
||||||
|
{
|
||||||
|
entry->device = NULL;
|
||||||
|
WARN("Not unregistering window %p, current window proc doesn't match wined3d window proc.\n",
|
||||||
|
entry->window);
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = &wndproc_table.entries[--wndproc_table.count];
|
||||||
|
if (entry != last)
|
||||||
|
*entry = *last;
|
||||||
|
else
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
wined3d_wndproc_mutex_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wined3d_window_hook *wined3d_find_hook(DWORD thread_id)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < hook_table.hook_count; ++i)
|
||||||
|
{
|
||||||
|
if (hook_table.hooks[i].thread_id == thread_id)
|
||||||
|
return &hook_table.hooks[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wined3d_hook_swapchain(struct wined3d_swapchain *swapchain)
|
||||||
|
{
|
||||||
|
struct wined3d_hooked_swapchain *swapchain_entry;
|
||||||
|
struct wined3d_window_hook *hook;
|
||||||
|
|
||||||
|
wined3d_wndproc_mutex_lock();
|
||||||
|
|
||||||
|
if (!wined3d_array_reserve((void **)&hook_table.swapchains, &hook_table.swapchains_size,
|
||||||
|
hook_table.swapchain_count + 1, sizeof(*swapchain_entry)))
|
||||||
|
{
|
||||||
|
wined3d_wndproc_mutex_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
swapchain_entry = &hook_table.swapchains[hook_table.swapchain_count++];
|
||||||
|
swapchain_entry->swapchain = swapchain;
|
||||||
|
swapchain_entry->thread_id = GetWindowThreadProcessId(swapchain->device_window, NULL);
|
||||||
|
|
||||||
|
if ((hook = wined3d_find_hook(swapchain_entry->thread_id)))
|
||||||
|
{
|
||||||
|
++hook->count;
|
||||||
|
wined3d_wndproc_mutex_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wined3d_array_reserve((void **)&hook_table.hooks, &hook_table.hooks_size,
|
||||||
|
hook_table.hook_count + 1, sizeof(*hook)))
|
||||||
|
{
|
||||||
|
--hook_table.swapchain_count;
|
||||||
|
wined3d_wndproc_mutex_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hook = &hook_table.hooks[hook_table.hook_count++];
|
||||||
|
hook->thread_id = swapchain_entry->thread_id;
|
||||||
|
hook->hook = SetWindowsHookExW(WH_GETMESSAGE, wined3d_hook_proc, 0, hook->thread_id);
|
||||||
|
hook->count = 1;
|
||||||
|
|
||||||
|
wined3d_wndproc_mutex_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wined3d_unhook_swapchain(struct wined3d_swapchain *swapchain)
|
||||||
|
{
|
||||||
|
struct wined3d_hooked_swapchain *swapchain_entry, *last_swapchain_entry;
|
||||||
|
struct wined3d_window_hook *hook, *last_hook;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
wined3d_wndproc_mutex_lock();
|
||||||
|
|
||||||
|
for (i = 0; i < hook_table.swapchain_count; ++i)
|
||||||
|
{
|
||||||
|
swapchain_entry = &hook_table.swapchains[i];
|
||||||
|
|
||||||
|
if (swapchain_entry->swapchain != swapchain)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((hook = wined3d_find_hook(swapchain_entry->thread_id)) && !--hook->count)
|
||||||
|
{
|
||||||
|
UnhookWindowsHookEx(hook->hook);
|
||||||
|
last_hook = &hook_table.hooks[--hook_table.hook_count];
|
||||||
|
if (hook != last_hook)
|
||||||
|
*hook = *last_hook;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_swapchain_entry = &hook_table.swapchains[--hook_table.swapchain_count];
|
||||||
|
if (swapchain_entry != last_swapchain_entry)
|
||||||
|
*swapchain_entry = *last_swapchain_entry;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wined3d_wndproc_mutex_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/* At process attach */
|
/* At process attach */
|
||||||
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
|
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2978,8 +2978,9 @@ struct wined3d
|
||||||
struct wined3d_adapter *adapters[1];
|
struct wined3d_adapter *adapters[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void wined3d_hook_swapchain(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
|
||||||
HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) DECLSPEC_HIDDEN;
|
HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) DECLSPEC_HIDDEN;
|
||||||
BOOL wined3d_register_window(HWND window, struct wined3d_device *device) DECLSPEC_HIDDEN;
|
void wined3d_unhook_swapchain(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
|
||||||
void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
|
void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size) DECLSPEC_HIDDEN;
|
BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -903,6 +903,7 @@ enum wined3d_shader_type
|
||||||
#define WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT 0x00004000u
|
#define WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT 0x00004000u
|
||||||
#define WINED3D_SWAPCHAIN_GDI_COMPATIBLE 0x00008000u
|
#define WINED3D_SWAPCHAIN_GDI_COMPATIBLE 0x00008000u
|
||||||
#define WINED3D_SWAPCHAIN_IMPLICIT 0x00010000u
|
#define WINED3D_SWAPCHAIN_IMPLICIT 0x00010000u
|
||||||
|
#define WINED3D_SWAPCHAIN_HOOK 0x00020000u
|
||||||
|
|
||||||
#define WINED3DDP_MAXTEXCOORD 8
|
#define WINED3DDP_MAXTEXCOORD 8
|
||||||
|
|
||||||
|
@ -1584,6 +1585,10 @@ enum wined3d_shader_type
|
||||||
|
|
||||||
#define WINED3D_MAX_VIEWPORTS 16
|
#define WINED3D_MAX_VIEWPORTS 16
|
||||||
|
|
||||||
|
#define WINED3D_REGISTER_WINDOW_NO_WINDOW_CHANGES 0x00000001u
|
||||||
|
#define WINED3D_REGISTER_WINDOW_NO_ALT_ENTER 0x00000002u
|
||||||
|
#define WINED3D_REGISTER_WINDOW_NO_PRINT_SCREEN 0x00000004u
|
||||||
|
|
||||||
struct wined3d_display_mode
|
struct wined3d_display_mode
|
||||||
{
|
{
|
||||||
UINT width;
|
UINT width;
|
||||||
|
@ -2210,8 +2215,11 @@ HRESULT __cdecl wined3d_get_output_desc(const struct wined3d *wined3d, unsigned
|
||||||
struct wined3d_output_desc *desc);
|
struct wined3d_output_desc *desc);
|
||||||
ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
|
ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
|
||||||
HRESULT __cdecl wined3d_register_software_device(struct wined3d *wined3d, void *init_function);
|
HRESULT __cdecl wined3d_register_software_device(struct wined3d *wined3d, void *init_function);
|
||||||
|
BOOL __cdecl wined3d_register_window(struct wined3d *wined3d, HWND window,
|
||||||
|
struct wined3d_device *device, unsigned int flags);
|
||||||
HRESULT __cdecl wined3d_set_adapter_display_mode(struct wined3d *wined3d,
|
HRESULT __cdecl wined3d_set_adapter_display_mode(struct wined3d *wined3d,
|
||||||
UINT adapter_idx, const struct wined3d_display_mode *mode);
|
UINT adapter_idx, const struct wined3d_display_mode *mode);
|
||||||
|
void __cdecl wined3d_unregister_windows(struct wined3d *wined3d);
|
||||||
|
|
||||||
HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
|
HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
|
||||||
const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops,
|
const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops,
|
||||||
|
|
Loading…
Reference in New Issue