Vitaliy Margolen : dinput:
Use CALLWINDPROC hook to monitor focus loses away from acquired
windows.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Jul 16 16:27:18 CDT 2007
Module: wine
Branch: master
Commit: 41ce4a01583d552a976cb921d2991a043e0363e4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=41ce4a01583d552a976cb921d2991a043e0363e4
Author: Vitaliy Margolen <wine-patches at kievinfo.com>
Date: Sun Jul 15 10:40:00 2007 -0600
dinput: Use CALLWINDPROC hook to monitor focus loses away from acquired windows.
---
dlls/dinput/dinput_main.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
dlls/dinput/tests/mouse.c | 1 -
2 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 5052829..4f15c58 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -848,6 +848,41 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM 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 HHOOK kbd_hook, mouse_hook;
@@ -976,7 +1011,30 @@ static BOOL check_hook_thread(void)
void check_dinput_hooks(LPDIRECTINPUTDEVICE8A iface)
{
+ static HHOOK callwndproc_hook;
+ static ULONG foreground_cnt;
+ IDirectInputDevice2AImpl *dev = (IDirectInputDevice2AImpl *)iface;
+
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 );
+
LeaveCriticalSection(&dinput_hook_crit);
}
diff --git a/dlls/dinput/tests/mouse.c b/dlls/dinput/tests/mouse.c
index 0f9c88b..3ea2147 100644
--- a/dlls/dinput/tests/mouse.c
+++ b/dlls/dinput/tests/mouse.c
@@ -95,7 +95,6 @@ static void test_acquire(LPDIRECTINPUT pDI, HWND hwnd)
SetActiveWindow( 0 );
hr = IDirectInputDevice_GetDeviceState(pMouse, sizeof(m_state), &m_state);
- todo_wine
ok(hr == DIERR_NOTACQUIRED, "GetDeviceState() should have failed: %s\n", DXGetErrorString8(hr));
/* Workaround so we can test other things. Remove when Wine is fixed */
IDirectInputDevice_Unacquire(pMouse);
More information about the wine-cvs
mailing list