mirror of
https://github.com/reactos/wine.git
synced 2024-11-28 22:20:26 +00:00
dinput: Create single thread for mouse and keyboard hook.
Put keyboard & mouse hook callbacks into separate thread. Move few global variables into object. Delete no longer used crit section. For hooks to work properly hook callback have to be in a thread with message loop. Some games create separate threads just to handle mouse and/or keyboard events that do not have message loop.
This commit is contained in:
parent
253a2d089c
commit
e66e34ef7b
@ -32,9 +32,11 @@
|
|||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
#include "winuser.h"
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
#include "dinput.h"
|
#include "dinput.h"
|
||||||
#include "device_private.h"
|
#include "device_private.h"
|
||||||
|
#include "dinput_private.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
|
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
|
||||||
|
|
||||||
@ -898,3 +900,139 @@ HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface
|
|||||||
|
|
||||||
return DI_OK;
|
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,6 +52,8 @@ 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 DataFormat *create_DataFormat(const DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) ;
|
||||||
extern void release_DataFormat(DataFormat *df) ;
|
extern void release_DataFormat(DataFormat *df) ;
|
||||||
|
|
||||||
|
extern HHOOK set_dinput_hook(int hook_id, LPVOID proc);
|
||||||
|
|
||||||
/* Used to fill events in the queue */
|
/* Used to fill events in the queue */
|
||||||
#define GEN_EVENT(offset,data,xtime,seq) \
|
#define GEN_EVENT(offset,data,xtime,seq) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -52,7 +52,7 @@ struct SysKeyboardImpl
|
|||||||
|
|
||||||
IDirectInputImpl* dinput;
|
IDirectInputImpl* dinput;
|
||||||
|
|
||||||
HANDLE hEvent;
|
HANDLE hEvent;
|
||||||
/* SysKeyboardAImpl */
|
/* SysKeyboardAImpl */
|
||||||
int acquired;
|
int acquired;
|
||||||
int buffersize; /* set in 'SetProperty' */
|
int buffersize; /* set in 'SetProperty' */
|
||||||
@ -78,73 +78,57 @@ static SysKeyboardImpl* current_lock = NULL;
|
|||||||
|
|
||||||
static BYTE DInputKeyState[WINE_DINPUT_KEYBOARD_MAX_KEYS]; /* array for 'GetDeviceState' */
|
static BYTE DInputKeyState[WINE_DINPUT_KEYBOARD_MAX_KEYS]; /* array for 'GetDeviceState' */
|
||||||
|
|
||||||
static CRITICAL_SECTION keyboard_crit;
|
|
||||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
|
||||||
{
|
|
||||||
0, 0, &keyboard_crit,
|
|
||||||
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
|
||||||
0, 0, { (DWORD_PTR)(__FILE__ ": keyboard_crit") }
|
|
||||||
};
|
|
||||||
static CRITICAL_SECTION keyboard_crit = { &critsect_debug, -1, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
static LONG keyboard_users = 0;
|
|
||||||
static HHOOK keyboard_hook = NULL;
|
|
||||||
|
|
||||||
LRESULT CALLBACK KeyboardCallback( int code, WPARAM wparam, LPARAM lparam )
|
LRESULT CALLBACK KeyboardCallback( int code, WPARAM wparam, LPARAM lparam )
|
||||||
{
|
{
|
||||||
BYTE dik_code;
|
SysKeyboardImpl *This = (SysKeyboardImpl *)current_lock;
|
||||||
BOOL down;
|
BYTE dik_code;
|
||||||
DWORD timestamp;
|
BOOL down;
|
||||||
KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
|
KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
|
||||||
BYTE new_diks;
|
BYTE new_diks;
|
||||||
|
|
||||||
TRACE("(%d,%d,%ld)\n", code, wparam, lparam);
|
TRACE("(%d,%d,%ld)\n", code, wparam, lparam);
|
||||||
|
|
||||||
/** returns now if not HC_ACTION */
|
/* returns now if not HC_ACTION */
|
||||||
if (code != HC_ACTION) return CallNextHookEx(keyboard_hook, code, wparam, lparam);
|
if (code != HC_ACTION) return CallNextHookEx(0, code, wparam, lparam);
|
||||||
|
|
||||||
{
|
|
||||||
dik_code = hook->scanCode;
|
dik_code = hook->scanCode;
|
||||||
if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
|
if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
|
||||||
down = !(hook->flags & LLKHF_UP);
|
down = !(hook->flags & LLKHF_UP);
|
||||||
timestamp = hook->time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** returns now if key event already known */
|
/** returns now if key event already known */
|
||||||
new_diks = (down ? 0x80 : 0);
|
new_diks = (down ? 0x80 : 0);
|
||||||
/*if (new_diks != DInputKeyState[dik_code]) return CallNextHookEx(keyboard_hook, code, wparam, lparam); TO BE FIXED */
|
/*if (new_diks != DInputKeyState[dik_code]) return CallNextHookEx(keyboard_hook, code, wparam, lparam); TO BE FIXED */
|
||||||
|
|
||||||
DInputKeyState[dik_code] = new_diks;
|
DInputKeyState[dik_code] = new_diks;
|
||||||
TRACE(" setting %02X to %02X\n", dik_code, DInputKeyState[dik_code]);
|
TRACE(" setting %02X to %02X\n", dik_code, DInputKeyState[dik_code]);
|
||||||
|
|
||||||
if (current_lock != NULL) {
|
if (This->hEvent) SetEvent(This->hEvent);
|
||||||
if (current_lock->hEvent) SetEvent(current_lock->hEvent);
|
|
||||||
|
|
||||||
if (current_lock->buffer != NULL) {
|
if (This->buffer != NULL)
|
||||||
int n;
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
EnterCriticalSection(&(This->crit));
|
||||||
|
|
||||||
|
n = (This->start + This->count) % This->buffersize;
|
||||||
|
|
||||||
|
This->buffer[n].dwOfs = dik_code;
|
||||||
|
This->buffer[n].dwData = down ? 0x80 : 0;
|
||||||
|
This->buffer[n].dwTimeStamp = hook->time;
|
||||||
|
This->buffer[n].dwSequence = This->dinput->evsequence++;
|
||||||
|
|
||||||
EnterCriticalSection(&(current_lock->crit));
|
TRACE("Adding event at offset %d : %ld - %ld - %ld - %ld\n", n,
|
||||||
|
This->buffer[n].dwOfs, This->buffer[n].dwData, This->buffer[n].dwTimeStamp, This->buffer[n].dwSequence);
|
||||||
|
|
||||||
n = (current_lock->start + current_lock->count) % current_lock->buffersize;
|
if (This->count == This->buffersize) {
|
||||||
|
This->start = ++This->start % This->buffersize;
|
||||||
|
This->overflow = TRUE;
|
||||||
|
}
|
||||||
|
else This->count++;
|
||||||
|
|
||||||
current_lock->buffer[n].dwOfs = dik_code;
|
LeaveCriticalSection(&(This->crit));
|
||||||
current_lock->buffer[n].dwData = down ? 0x80 : 0;
|
|
||||||
current_lock->buffer[n].dwTimeStamp = timestamp;
|
|
||||||
current_lock->buffer[n].dwSequence = current_lock->dinput->evsequence++;
|
|
||||||
|
|
||||||
TRACE("Adding event at offset %d : %ld - %ld - %ld - %ld\n", n,
|
|
||||||
current_lock->buffer[n].dwOfs, current_lock->buffer[n].dwData, current_lock->buffer[n].dwTimeStamp, current_lock->buffer[n].dwSequence);
|
|
||||||
|
|
||||||
if (current_lock->count == current_lock->buffersize) {
|
|
||||||
current_lock->start = ++current_lock->start % current_lock->buffersize;
|
|
||||||
current_lock->overflow = TRUE;
|
|
||||||
} else
|
|
||||||
current_lock->count++;
|
|
||||||
|
|
||||||
LeaveCriticalSection(&(current_lock->crit));
|
|
||||||
}
|
}
|
||||||
}
|
return CallNextHookEx(0, code, wparam, lparam);
|
||||||
return CallNextHookEx(keyboard_hook, code, wparam, lparam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
|
static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
|
||||||
@ -241,7 +225,6 @@ static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEI
|
|||||||
static SysKeyboardImpl *alloc_device(REFGUID rguid, const void *kvt, IDirectInputImpl *dinput)
|
static SysKeyboardImpl *alloc_device(REFGUID rguid, const void *kvt, IDirectInputImpl *dinput)
|
||||||
{
|
{
|
||||||
SysKeyboardImpl* newDevice;
|
SysKeyboardImpl* newDevice;
|
||||||
DWORD kbd_users;
|
|
||||||
|
|
||||||
newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardImpl));
|
newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardImpl));
|
||||||
newDevice->lpVtbl = kvt;
|
newDevice->lpVtbl = kvt;
|
||||||
@ -250,13 +233,6 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, const void *kvt, IDirectInpu
|
|||||||
newDevice->dinput = dinput;
|
newDevice->dinput = dinput;
|
||||||
InitializeCriticalSection(&(newDevice->crit));
|
InitializeCriticalSection(&(newDevice->crit));
|
||||||
|
|
||||||
EnterCriticalSection(&keyboard_crit);
|
|
||||||
kbd_users = InterlockedIncrement(&keyboard_users);
|
|
||||||
if (1 == kbd_users) {
|
|
||||||
keyboard_hook = SetWindowsHookExW( WH_KEYBOARD_LL, KeyboardCallback, DINPUT_instance, 0 );
|
|
||||||
}
|
|
||||||
LeaveCriticalSection(&keyboard_crit);
|
|
||||||
|
|
||||||
return newDevice;
|
return newDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,29 +283,21 @@ const struct dinput_device keyboard_device = {
|
|||||||
|
|
||||||
static ULONG WINAPI SysKeyboardAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
|
static ULONG WINAPI SysKeyboardAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
|
||||||
{
|
{
|
||||||
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
|
||||||
ULONG ref;
|
ULONG ref;
|
||||||
DWORD kbd_users;
|
|
||||||
|
|
||||||
ref = InterlockedDecrement(&(This->ref));
|
ref = InterlockedDecrement(&(This->ref));
|
||||||
if (ref)
|
if (ref) return ref;
|
||||||
return ref;
|
|
||||||
|
|
||||||
EnterCriticalSection(&keyboard_crit);
|
set_dinput_hook(WH_KEYBOARD_LL, NULL);
|
||||||
kbd_users = InterlockedDecrement(&keyboard_users);
|
|
||||||
if (0 == kbd_users) {
|
|
||||||
UnhookWindowsHookEx( keyboard_hook );
|
|
||||||
keyboard_hook = 0;
|
|
||||||
}
|
|
||||||
LeaveCriticalSection(&keyboard_crit);
|
|
||||||
|
|
||||||
/* Free the data queue */
|
/* Free the data queue */
|
||||||
HeapFree(GetProcessHeap(),0,This->buffer);
|
HeapFree(GetProcessHeap(),0,This->buffer);
|
||||||
|
|
||||||
DeleteCriticalSection(&(This->crit));
|
DeleteCriticalSection(&(This->crit));
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(),0,This);
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
return DI_OK;
|
return DI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
|
static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
|
||||||
@ -563,7 +531,7 @@ static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
|
|||||||
This->buffer = NULL;
|
This->buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*keyboard_hook = SetWindowsHookExW( WH_KEYBOARD_LL, KeyboardCallback, DINPUT_instance, 0 );*/
|
set_dinput_hook(WH_KEYBOARD_LL, KeyboardCallback);
|
||||||
|
|
||||||
return DI_OK;
|
return DI_OK;
|
||||||
}
|
}
|
||||||
@ -576,6 +544,8 @@ static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
|
|||||||
if (This->acquired == 0)
|
if (This->acquired == 0)
|
||||||
return DI_NOEFFECT;
|
return DI_NOEFFECT;
|
||||||
|
|
||||||
|
set_dinput_hook(WH_KEYBOARD_LL, NULL);
|
||||||
|
|
||||||
/* No more locks */
|
/* No more locks */
|
||||||
if (current_lock == This)
|
if (current_lock == This)
|
||||||
current_lock = NULL;
|
current_lock = NULL;
|
||||||
|
@ -126,7 +126,6 @@ struct SysMouseImpl
|
|||||||
LONG prevX, prevY;
|
LONG prevX, prevY;
|
||||||
/* These are used in case of relative -> absolute transitions */
|
/* These are used in case of relative -> absolute transitions */
|
||||||
POINT org_coords;
|
POINT org_coords;
|
||||||
HHOOK hook;
|
|
||||||
HWND win;
|
HWND win;
|
||||||
DWORD dwCoopLevel;
|
DWORD dwCoopLevel;
|
||||||
POINT mapped_center;
|
POINT mapped_center;
|
||||||
@ -329,15 +328,11 @@ static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
|
|||||||
ref = InterlockedDecrement(&(This->ref));
|
ref = InterlockedDecrement(&(This->ref));
|
||||||
if (ref)
|
if (ref)
|
||||||
return ref;
|
return ref;
|
||||||
|
|
||||||
|
set_dinput_hook(WH_MOUSE_LL, NULL);
|
||||||
|
|
||||||
/* Free the data queue */
|
/* Free the data queue */
|
||||||
HeapFree(GetProcessHeap(),0,This->data_queue);
|
HeapFree(GetProcessHeap(),0,This->data_queue);
|
||||||
|
|
||||||
if (This->hook) {
|
|
||||||
UnhookWindowsHookEx( This->hook );
|
|
||||||
if (This->dwCoopLevel & DISCL_EXCLUSIVE)
|
|
||||||
ShowCursor(TRUE); /* show cursor */
|
|
||||||
}
|
|
||||||
DeleteCriticalSection(&(This->crit));
|
DeleteCriticalSection(&(This->crit));
|
||||||
|
|
||||||
/* Free the DataFormat */
|
/* Free the DataFormat */
|
||||||
@ -426,7 +421,7 @@ static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lpara
|
|||||||
static long last_event = 0;
|
static long last_event = 0;
|
||||||
int wdata;
|
int wdata;
|
||||||
|
|
||||||
if (code != HC_ACTION) return CallNextHookEx( This->hook, code, wparam, lparam );
|
if (code != HC_ACTION) return CallNextHookEx( 0, code, wparam, lparam );
|
||||||
|
|
||||||
EnterCriticalSection(&(This->crit));
|
EnterCriticalSection(&(This->crit));
|
||||||
dwCoop = This->dwCoopLevel;
|
dwCoop = This->dwCoopLevel;
|
||||||
@ -549,7 +544,7 @@ static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lpara
|
|||||||
|
|
||||||
if (dwCoop & DISCL_NONEXCLUSIVE) {
|
if (dwCoop & DISCL_NONEXCLUSIVE) {
|
||||||
/* Pass the events down to previous handlers (e.g. win32 input) */
|
/* Pass the events down to previous handlers (e.g. win32 input) */
|
||||||
ret = CallNextHookEx( This->hook, code, wparam, lparam );
|
ret = CallNextHookEx( 0, code, wparam, lparam );
|
||||||
} else {
|
} else {
|
||||||
/* Ignore message */
|
/* Ignore message */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -557,7 +552,6 @@ static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lpara
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dinput_window_check(SysMouseImpl* This) {
|
static void dinput_window_check(SysMouseImpl* This) {
|
||||||
RECT rect;
|
RECT rect;
|
||||||
DWORD centerX, centerY;
|
DWORD centerX, centerY;
|
||||||
@ -615,7 +609,7 @@ static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
|
|||||||
/* Install our mouse hook */
|
/* Install our mouse hook */
|
||||||
if (This->dwCoopLevel & DISCL_EXCLUSIVE)
|
if (This->dwCoopLevel & DISCL_EXCLUSIVE)
|
||||||
ShowCursor(FALSE); /* hide cursor */
|
ShowCursor(FALSE); /* hide cursor */
|
||||||
This->hook = SetWindowsHookExA( WH_MOUSE_LL, dinput_mouse_hook, DINPUT_instance, 0 );
|
set_dinput_hook(WH_MOUSE_LL, dinput_mouse_hook);
|
||||||
|
|
||||||
/* Get the window dimension and find the center */
|
/* Get the window dimension and find the center */
|
||||||
GetWindowRect(This->win, &rect);
|
GetWindowRect(This->win, &rect);
|
||||||
@ -651,16 +645,11 @@ static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
|
|||||||
if (0 == This->acquired) {
|
if (0 == This->acquired) {
|
||||||
return DI_NOEFFECT;
|
return DI_NOEFFECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reinstall previous mouse event handler */
|
set_dinput_hook(WH_MOUSE_LL, NULL);
|
||||||
if (This->hook) {
|
if (This->dwCoopLevel & DISCL_EXCLUSIVE)
|
||||||
UnhookWindowsHookEx( This->hook );
|
ShowCursor(TRUE); /* show cursor */
|
||||||
This->hook = 0;
|
|
||||||
|
|
||||||
if (This->dwCoopLevel & DISCL_EXCLUSIVE)
|
|
||||||
ShowCursor(TRUE); /* show cursor */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No more locks */
|
/* No more locks */
|
||||||
if (current_lock == (IDirectInputDevice8A*) This)
|
if (current_lock == (IDirectInputDevice8A*) This)
|
||||||
current_lock = NULL;
|
current_lock = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user