wined3d: Send window messages through the swapchain before sending them to the application.
This commit is contained in:
parent
0a59c65e74
commit
0e270bbd22
|
@ -90,8 +90,10 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
|
|||
mode.Format = This->orig_fmt;
|
||||
IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)This->device, 0, &mode);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, This->context);
|
||||
|
||||
wined3d_unregister_window(This->win_handle);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, This->context);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
|
@ -676,6 +678,12 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
|
|||
|
||||
window = present_parameters->hDeviceWindow ? present_parameters->hDeviceWindow : device->createParms.hFocusWindow;
|
||||
|
||||
if (!wined3d_register_window(window, swapchain))
|
||||
{
|
||||
ERR("Failed to register window %p.\n", window);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
swapchain->device = device;
|
||||
swapchain->parent = parent;
|
||||
swapchain->ref = 1;
|
||||
|
@ -907,6 +915,8 @@ err:
|
|||
|
||||
if (swapchain->frontBuffer) IWineD3DSurface_Release(swapchain->frontBuffer);
|
||||
|
||||
wined3d_unregister_window(window);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -951,3 +961,15 @@ void get_drawable_size_swapchain(struct wined3d_context *context, UINT *width, U
|
|||
*width = surface->currentDesc.Width;
|
||||
*height = surface->currentDesc.Height;
|
||||
}
|
||||
|
||||
LRESULT swapchain_process_message(IWineD3DSwapChainImpl *swapchain, HWND window,
|
||||
UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc)
|
||||
{
|
||||
if (message == WM_DESTROY)
|
||||
{
|
||||
TRACE("unregister window %p.\n", window);
|
||||
wined3d_unregister_window(window);
|
||||
}
|
||||
|
||||
return CallWindowProcW(proc, window, message, wparam, lparam);
|
||||
}
|
||||
|
|
|
@ -70,6 +70,8 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface)
|
|||
IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)This->device, 0, &mode);
|
||||
}
|
||||
|
||||
wined3d_unregister_window(This->win_handle);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, This->context);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,22 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
|
||||
struct wined3d_wndproc
|
||||
{
|
||||
HWND window;
|
||||
WNDPROC proc;
|
||||
IWineD3DSwapChainImpl *swapchain;
|
||||
};
|
||||
|
||||
struct wined3d_wndproc_table
|
||||
{
|
||||
struct wined3d_wndproc *entries;
|
||||
unsigned int count;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
static struct wined3d_wndproc_table wndproc_table;
|
||||
|
||||
int num_lock = 0;
|
||||
void (*CDECL wine_tsx11_lock_ptr)(void) = NULL;
|
||||
void (*CDECL wine_tsx11_unlock_ptr)(void) = NULL;
|
||||
|
@ -325,6 +341,7 @@ static BOOL wined3d_init(HINSTANCE hInstDLL)
|
|||
static BOOL wined3d_destroy(HINSTANCE hInstDLL)
|
||||
{
|
||||
DWORD wined3d_context_tls_idx = context_get_tls_idx();
|
||||
unsigned int i;
|
||||
|
||||
if (!TlsFree(wined3d_context_tls_idx))
|
||||
{
|
||||
|
@ -332,6 +349,13 @@ static BOOL wined3d_destroy(HINSTANCE hInstDLL)
|
|||
ERR("Failed to free context TLS index, err %#x.\n", err);
|
||||
}
|
||||
|
||||
for (i = 0; i < wndproc_table.count; ++i)
|
||||
{
|
||||
struct wined3d_wndproc *entry = &wndproc_table.entries[i];
|
||||
SetWindowLongPtrW(entry->window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, wndproc_table.entries);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, wined3d_settings.logo);
|
||||
UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
|
||||
|
||||
|
@ -348,6 +372,104 @@ void WINAPI wined3d_mutex_unlock(void)
|
|||
LeaveCriticalSection(&wined3d_cs);
|
||||
}
|
||||
|
||||
static struct wined3d_wndproc *wined3d_find_wndproc(HWND window)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < wndproc_table.count; ++i)
|
||||
{
|
||||
if (wndproc_table.entries[i].window == window)
|
||||
{
|
||||
return &wndproc_table.entries[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
IWineD3DSwapChainImpl *swapchain;
|
||||
struct wined3d_wndproc *entry;
|
||||
WNDPROC proc;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
entry = wined3d_find_wndproc(window);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
wined3d_mutex_unlock();
|
||||
ERR("Window %p is not registered with wined3d.\n", window);
|
||||
return DefWindowProcW(window, message, wparam, lparam);
|
||||
}
|
||||
|
||||
swapchain = entry->swapchain;
|
||||
proc = entry->proc;
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
return swapchain_process_message(swapchain, window, message, wparam, lparam, proc);
|
||||
}
|
||||
|
||||
BOOL wined3d_register_window(HWND window, IWineD3DSwapChainImpl *swapchain)
|
||||
{
|
||||
struct wined3d_wndproc *entry;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
|
||||
if (wndproc_table.size == wndproc_table.count)
|
||||
{
|
||||
unsigned int new_size = max(1, wndproc_table.size * 2);
|
||||
struct wined3d_wndproc *new_entries;
|
||||
|
||||
if (!wndproc_table.entries) new_entries = HeapAlloc(GetProcessHeap(), 0, new_size * sizeof(*new_entries));
|
||||
else new_entries = HeapReAlloc(GetProcessHeap(), 0, wndproc_table.entries, new_size * sizeof(*new_entries));
|
||||
|
||||
if (!new_entries)
|
||||
{
|
||||
wined3d_mutex_unlock();
|
||||
ERR("Failed to grow table.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wndproc_table.entries = new_entries;
|
||||
wndproc_table.size = new_size;
|
||||
}
|
||||
|
||||
entry = &wndproc_table.entries[wndproc_table.count++];
|
||||
entry->window = window;
|
||||
entry->proc = (WNDPROC)SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc);
|
||||
entry->swapchain = swapchain;
|
||||
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void wined3d_unregister_window(HWND window)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
for (i = 0; i < wndproc_table.count; ++i)
|
||||
{
|
||||
if (wndproc_table.entries[i].window == window)
|
||||
{
|
||||
struct wined3d_wndproc *entry = &wndproc_table.entries[i];
|
||||
struct wined3d_wndproc *last = &wndproc_table.entries[--wndproc_table.count];
|
||||
|
||||
if (GetWindowLongPtrW(window, GWLP_WNDPROC) == (LONG_PTR)wined3d_wndproc)
|
||||
SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
|
||||
if (entry != last) *entry = *last;
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
ERR("Window %p is not registered with wined3d.\n", window);
|
||||
}
|
||||
|
||||
/* At process attach */
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||
{
|
||||
|
|
|
@ -816,6 +816,7 @@ typedef struct IWineD3DStateBlockImpl IWineD3DStateBlockImpl;
|
|||
typedef struct IWineD3DSurfaceImpl IWineD3DSurfaceImpl;
|
||||
typedef struct IWineD3DPaletteImpl IWineD3DPaletteImpl;
|
||||
typedef struct IWineD3DDeviceImpl IWineD3DDeviceImpl;
|
||||
typedef struct IWineD3DSwapChainImpl IWineD3DSwapChainImpl;
|
||||
|
||||
/* Global variables */
|
||||
extern const float identity[16] DECLSPEC_HIDDEN;
|
||||
|
@ -1439,6 +1440,8 @@ typedef struct IWineD3DImpl
|
|||
|
||||
extern const IWineD3DVtbl IWineD3D_Vtbl DECLSPEC_HIDDEN;
|
||||
|
||||
BOOL wined3d_register_window(HWND window, struct IWineD3DSwapChainImpl *swapchain) DECLSPEC_HIDDEN;
|
||||
void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
|
||||
BOOL InitAdapters(IWineD3DImpl *This) DECLSPEC_HIDDEN;
|
||||
|
||||
/* A helper function that dumps a resource list */
|
||||
|
@ -2397,7 +2400,7 @@ extern const IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl DECLSPE
|
|||
* IWineD3DSwapChainImpl implementation structure (extends IUnknown)
|
||||
*/
|
||||
|
||||
typedef struct IWineD3DSwapChainImpl
|
||||
struct IWineD3DSwapChainImpl
|
||||
{
|
||||
/*IUnknown part*/
|
||||
const IWineD3DSwapChainVtbl *lpVtbl;
|
||||
|
@ -2422,7 +2425,7 @@ typedef struct IWineD3DSwapChainImpl
|
|||
unsigned int num_contexts;
|
||||
|
||||
HWND win_handle;
|
||||
} IWineD3DSwapChainImpl;
|
||||
};
|
||||
|
||||
const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl DECLSPEC_HIDDEN;
|
||||
void x11_copy_to_screen(IWineD3DSwapChainImpl *This, const RECT *rc) DECLSPEC_HIDDEN;
|
||||
|
@ -2452,8 +2455,10 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface,
|
|||
struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *iface) DECLSPEC_HIDDEN;
|
||||
HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type,
|
||||
IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, IUnknown *parent) DECLSPEC_HIDDEN;
|
||||
void swapchain_setup_fullscreen_window(IWineD3DSwapChainImpl *swapchain, UINT w, UINT h) DECLSPEC_HIDDEN;
|
||||
LRESULT swapchain_process_message(IWineD3DSwapChainImpl *device, HWND window,
|
||||
UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN;
|
||||
void swapchain_restore_fullscreen_window(IWineD3DSwapChainImpl *swapchain) DECLSPEC_HIDDEN;
|
||||
void swapchain_setup_fullscreen_window(IWineD3DSwapChainImpl *swapchain, UINT w, UINT h) DECLSPEC_HIDDEN;
|
||||
|
||||
#define DEFAULT_REFRESH_RATE 0
|
||||
|
||||
|
|
Loading…
Reference in New Issue