Commit 722a686d authored by Vitaliy Margolen's avatar Vitaliy Margolen Committed by Alexandre Julliard

dinput: Move hook_thread from device to DirectInput.

parent abae1e81
......@@ -901,139 +901,3 @@ HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface
return DI_OK;
}
/******************************************************************************
* DInput hook thread
*/
static LRESULT CALLBACK dinput_hook_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HHOOK kbd_hook, mouse_hook;
BOOL res;
TRACE("got message %x %p %p\n", message, (LPVOID)wParam, (LPVOID)lParam);
switch (message)
{
case WM_USER+0x10:
if (wParam == WH_KEYBOARD_LL)
{
if (lParam)
{
if (kbd_hook) return 0;
kbd_hook = SetWindowsHookExW(WH_KEYBOARD_LL, (LPVOID)lParam, DINPUT_instance, 0);
return (LRESULT)kbd_hook;
}
else
{
if (!kbd_hook) return 0;
res = UnhookWindowsHookEx(kbd_hook);
kbd_hook = NULL;
return res;
}
}
else if (wParam == WH_MOUSE_LL)
{
if (lParam)
{
if (mouse_hook) return 0;
mouse_hook = SetWindowsHookExW(WH_MOUSE_LL, (LPVOID)lParam, DINPUT_instance, 0);
return (LRESULT)mouse_hook;
}
else
{
if (!mouse_hook) return 0;
res = UnhookWindowsHookEx(mouse_hook);
mouse_hook = NULL;
return res;
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
}
return DefWindowProcW(hWnd, message, wParam, lParam);
}
static HANDLE signal_event;
static DWORD WINAPI hook_thread_proc(void *param)
{
static const WCHAR classW[]={'H','o','o','k','_','L','L','_','C','L',0};
MSG msg;
WNDCLASSEXW wcex;
HWND hwnd;
memset(&wcex, 0, sizeof(wcex));
wcex.cbSize = sizeof(wcex);
wcex.lpfnWndProc = dinput_hook_WndProc;
wcex.lpszClassName = classW;
wcex.hInstance = GetModuleHandleW(0);
if (!RegisterClassExW(&wcex)) ERR("Error registering window class\n");
hwnd = CreateWindowExW(0, classW, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, 0);
*(HWND*)param = hwnd;
SetEvent(signal_event);
if (hwnd)
{
while (GetMessageW(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
else ERR("Error creating message window\n");
DestroyWindow(hwnd);
UnregisterClassW(wcex.lpszClassName, wcex.hInstance);
return 0;
}
static CRITICAL_SECTION dinput_hook_crit;
static CRITICAL_SECTION_DEBUG dinput_critsect_debug =
{
0, 0, &dinput_hook_crit,
{ &dinput_critsect_debug.ProcessLocksList, &dinput_critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": dinput_hook_crit") }
};
static CRITICAL_SECTION dinput_hook_crit = { &dinput_critsect_debug, -1, 0, 0, 0, 0 };
static HWND get_thread_hwnd(void)
{
static HANDLE hook_thread;
static HWND hook_thread_hwnd;
EnterCriticalSection(&dinput_hook_crit);
if (!hook_thread)
{
DWORD tid;
HWND hwnd;
signal_event = CreateEventW(NULL, FALSE, FALSE, NULL);
hook_thread = CreateThread(NULL, 0, hook_thread_proc, &hwnd, 0, &tid);
if (signal_event && hook_thread)
{
HANDLE handles[2];
handles[0] = signal_event;
handles[1] = hook_thread;
WaitForMultipleObjects(2, handles, FALSE, INFINITE);
}
CloseHandle(signal_event);
if (!(hook_thread_hwnd = hwnd))
{
/* Thread failed to create window - reset things so we could try again later */
CloseHandle(hook_thread);
hook_thread = 0;
}
}
LeaveCriticalSection(&dinput_hook_crit);
return hook_thread_hwnd;
}
HHOOK set_dinput_hook(int hook_id, LPVOID proc)
{
return (HHOOK)SendMessageW(get_thread_hwnd(), WM_USER+0x10, (WPARAM)hook_id, (LPARAM)proc);
}
......@@ -52,8 +52,6 @@ extern void fill_DataFormat(void *out, const void *in, DataFormat *df) ;
extern DataFormat *create_DataFormat(const DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) ;
extern void release_DataFormat(DataFormat *df) ;
extern HHOOK set_dinput_hook(int hook_id, LPVOID proc);
/* Used to fill events in the queue */
#define GEN_EVENT(offset,data,xtime,seq) \
{ \
......
......@@ -686,3 +686,139 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
FIXME("(%s,%s,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
return CLASS_E_CLASSNOTAVAILABLE;
}
/******************************************************************************
* DInput hook thread
*/
static LRESULT CALLBACK dinput_hook_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HHOOK kbd_hook, mouse_hook;
BOOL res;
TRACE("got message %x %p %p\n", message, (LPVOID)wParam, (LPVOID)lParam);
switch (message)
{
case WM_USER+0x10:
if (wParam == WH_KEYBOARD_LL)
{
if (lParam)
{
if (kbd_hook) return 0;
kbd_hook = SetWindowsHookExW(WH_KEYBOARD_LL, (LPVOID)lParam, DINPUT_instance, 0);
return (LRESULT)kbd_hook;
}
else
{
if (!kbd_hook) return 0;
res = UnhookWindowsHookEx(kbd_hook);
kbd_hook = NULL;
return res;
}
}
else if (wParam == WH_MOUSE_LL)
{
if (lParam)
{
if (mouse_hook) return 0;
mouse_hook = SetWindowsHookExW(WH_MOUSE_LL, (LPVOID)lParam, DINPUT_instance, 0);
return (LRESULT)mouse_hook;
}
else
{
if (!mouse_hook) return 0;
res = UnhookWindowsHookEx(mouse_hook);
mouse_hook = NULL;
return res;
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
}
return DefWindowProcW(hWnd, message, wParam, lParam);
}
static HANDLE signal_event;
static DWORD WINAPI hook_thread_proc(void *param)
{
static const WCHAR classW[]={'H','o','o','k','_','L','L','_','C','L',0};
MSG msg;
WNDCLASSEXW wcex;
HWND hwnd;
memset(&wcex, 0, sizeof(wcex));
wcex.cbSize = sizeof(wcex);
wcex.lpfnWndProc = dinput_hook_WndProc;
wcex.lpszClassName = classW;
wcex.hInstance = GetModuleHandleW(0);
if (!RegisterClassExW(&wcex)) ERR("Error registering window class\n");
hwnd = CreateWindowExW(0, classW, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, 0);
*(HWND*)param = hwnd;
SetEvent(signal_event);
if (hwnd)
{
while (GetMessageW(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
else ERR("Error creating message window\n");
DestroyWindow(hwnd);
UnregisterClassW(wcex.lpszClassName, wcex.hInstance);
return 0;
}
static CRITICAL_SECTION dinput_hook_crit;
static CRITICAL_SECTION_DEBUG dinput_critsect_debug =
{
0, 0, &dinput_hook_crit,
{ &dinput_critsect_debug.ProcessLocksList, &dinput_critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": dinput_hook_crit") }
};
static CRITICAL_SECTION dinput_hook_crit = { &dinput_critsect_debug, -1, 0, 0, 0, 0 };
static HWND get_thread_hwnd(void)
{
static HANDLE hook_thread;
static HWND hook_thread_hwnd;
EnterCriticalSection(&dinput_hook_crit);
if (!hook_thread)
{
DWORD tid;
HWND hwnd;
signal_event = CreateEventW(NULL, FALSE, FALSE, NULL);
hook_thread = CreateThread(NULL, 0, hook_thread_proc, &hwnd, 0, &tid);
if (signal_event && hook_thread)
{
HANDLE handles[2];
handles[0] = signal_event;
handles[1] = hook_thread;
WaitForMultipleObjects(2, handles, FALSE, INFINITE);
}
CloseHandle(signal_event);
if (!(hook_thread_hwnd = hwnd))
{
/* Thread failed to create window - reset things so we could try again later */
CloseHandle(hook_thread);
hook_thread = 0;
}
}
LeaveCriticalSection(&dinput_hook_crit);
return hook_thread_hwnd;
}
HHOOK set_dinput_hook(int hook_id, LPVOID proc)
{
return (HHOOK)SendMessageW(get_thread_hwnd(), WM_USER+0x10, (WPARAM)hook_id, (LPARAM)proc);
}
......@@ -54,4 +54,6 @@ extern const struct dinput_device joystick_linuxinput_device;
extern HINSTANCE DINPUT_instance;
extern HHOOK set_dinput_hook(int hook_id, LPVOID proc);
#endif /* __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment