mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 09:50:52 +00:00
dinput: Use CALLWINDPROC hook to monitor focus loses away from acquired windows.
This commit is contained in:
parent
233cd46a22
commit
41ce4a0158
2 changed files with 58 additions and 1 deletions
|
@ -848,6 +848,41 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
|
||||||
return CallNextHookEx( 0, code, wparam, lparam );
|
return CallNextHookEx( 0, code, wparam, lparam );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam )
|
||||||
|
{
|
||||||
|
CWPSTRUCT *msg = (CWPSTRUCT *)lparam;
|
||||||
|
IDirectInputImpl *dinput;
|
||||||
|
HWND foreground;
|
||||||
|
|
||||||
|
if (code != HC_ACTION || msg->message != WM_KILLFOCUS)
|
||||||
|
return CallNextHookEx( 0, code, wparam, lparam );
|
||||||
|
|
||||||
|
foreground = GetForegroundWindow();
|
||||||
|
|
||||||
|
EnterCriticalSection( &dinput_hook_crit );
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
|
||||||
|
{
|
||||||
|
IDirectInputDevice2AImpl *dev;
|
||||||
|
|
||||||
|
EnterCriticalSection( &dinput->crit );
|
||||||
|
LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDevice2AImpl, entry )
|
||||||
|
{
|
||||||
|
if (!dev->acquired) continue;
|
||||||
|
|
||||||
|
if (msg->hwnd == dev->win && msg->hwnd != foreground)
|
||||||
|
{
|
||||||
|
TRACE( "%p window is not foreground - unacquiring %p\n", dev->win, dev );
|
||||||
|
IDirectInputDevice_Unacquire( (LPDIRECTINPUTDEVICE8A)dev );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LeaveCriticalSection( &dinput->crit );
|
||||||
|
}
|
||||||
|
LeaveCriticalSection( &dinput_hook_crit );
|
||||||
|
|
||||||
|
return CallNextHookEx( 0, code, wparam, lparam );
|
||||||
|
}
|
||||||
|
|
||||||
static DWORD WINAPI hook_thread_proc(void *param)
|
static DWORD WINAPI hook_thread_proc(void *param)
|
||||||
{
|
{
|
||||||
static HHOOK kbd_hook, mouse_hook;
|
static HHOOK kbd_hook, mouse_hook;
|
||||||
|
@ -976,7 +1011,30 @@ static BOOL check_hook_thread(void)
|
||||||
|
|
||||||
void check_dinput_hooks(LPDIRECTINPUTDEVICE8A iface)
|
void check_dinput_hooks(LPDIRECTINPUTDEVICE8A iface)
|
||||||
{
|
{
|
||||||
|
static HHOOK callwndproc_hook;
|
||||||
|
static ULONG foreground_cnt;
|
||||||
|
IDirectInputDevice2AImpl *dev = (IDirectInputDevice2AImpl *)iface;
|
||||||
|
|
||||||
EnterCriticalSection(&dinput_hook_crit);
|
EnterCriticalSection(&dinput_hook_crit);
|
||||||
|
|
||||||
|
if (dev->dwCoopLevel & DISCL_FOREGROUND)
|
||||||
|
{
|
||||||
|
if (dev->acquired)
|
||||||
|
foreground_cnt++;
|
||||||
|
else
|
||||||
|
foreground_cnt--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foreground_cnt && !callwndproc_hook)
|
||||||
|
callwndproc_hook = SetWindowsHookExW( WH_CALLWNDPROC, callwndproc_proc,
|
||||||
|
DINPUT_instance, GetCurrentThreadId() );
|
||||||
|
else if (!foreground_cnt && callwndproc_hook)
|
||||||
|
{
|
||||||
|
UnhookWindowsHookEx( callwndproc_hook );
|
||||||
|
callwndproc_hook = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
PostThreadMessageW( hook_thread_id, WM_USER+0x10, 1, 0 );
|
PostThreadMessageW( hook_thread_id, WM_USER+0x10, 1, 0 );
|
||||||
|
|
||||||
LeaveCriticalSection(&dinput_hook_crit);
|
LeaveCriticalSection(&dinput_hook_crit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,6 @@ static void test_acquire(LPDIRECTINPUT pDI, HWND hwnd)
|
||||||
SetActiveWindow( 0 );
|
SetActiveWindow( 0 );
|
||||||
|
|
||||||
hr = IDirectInputDevice_GetDeviceState(pMouse, sizeof(m_state), &m_state);
|
hr = IDirectInputDevice_GetDeviceState(pMouse, sizeof(m_state), &m_state);
|
||||||
todo_wine
|
|
||||||
ok(hr == DIERR_NOTACQUIRED, "GetDeviceState() should have failed: %s\n", DXGetErrorString8(hr));
|
ok(hr == DIERR_NOTACQUIRED, "GetDeviceState() should have failed: %s\n", DXGetErrorString8(hr));
|
||||||
/* Workaround so we can test other things. Remove when Wine is fixed */
|
/* Workaround so we can test other things. Remove when Wine is fixed */
|
||||||
IDirectInputDevice_Unacquire(pMouse);
|
IDirectInputDevice_Unacquire(pMouse);
|
||||||
|
|
Loading…
Reference in a new issue