static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) { struct wined3d_wndproc *entry; struct wined3d_device *device; BOOL unicode; WNDPROC proc; wined3d_wndproc_mutex_lock(); entry = wined3d_find_wndproc(window); if (!entry) { wined3d_wndproc_mutex_unlock(); ERR("Window %p is not registered with wined3d.\n", window); return DefWindowProcW(window, message, wparam, lparam); } device = entry->device; unicode = entry->unicode; proc = entry->proc; wined3d_wndproc_mutex_unlock(); if (device) return device_process_message(device, window, unicode, message, wparam, lparam, proc); if (unicode) return CallWindowProcW(proc, window, message, wparam, lparam); return CallWindowProcA(proc, window, message, wparam, lparam); }
void wined3d_unregister_window(HWND window) { struct wined3d_wndproc *entry, *last; LONG_PTR proc; wined3d_wndproc_mutex_lock(); if (!(entry = wined3d_find_wndproc(window))) { wined3d_wndproc_mutex_unlock(); ERR("Window %p is not registered with wined3d.\n", window); return; } if (entry->unicode) { proc = GetWindowLongPtrW(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; } 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]; if (entry != last) *entry = *last; wined3d_wndproc_mutex_unlock(); }
BOOL wined3d_register_window(HWND window, struct wined3d_device *device) { struct wined3d_wndproc *entry; wined3d_wndproc_mutex_lock(); if (wined3d_find_wndproc(window)) { wined3d_wndproc_mutex_unlock(); WARN("Window %p is already registered with wined3d.\n", window); return TRUE; } 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_wndproc_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->unicode = IsWindowUnicode(window); /* Set a window proc that matches the window. Some applications (e.g. NoX) * replace the window proc after we've set ours, and expect to be 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); entry->device = device; wined3d_wndproc_mutex_unlock(); return TRUE; }
static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) { struct wined3d_wndproc *entry; IWineD3DDeviceImpl *device; 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); } device = entry->device; proc = entry->proc; wined3d_mutex_unlock(); return device_process_message(device, window, message, wparam, lparam, proc); }