Am Dienstag, den 27.07.2004, 00:18 +0200 schrieb Michael Schlüter: > The keyboard hasn't that problem because it calls SetWindowsHookExW and > UnhookWindowsHookEx from keyboarddev_create_deviceA/W and > SysKeyboardAImpl_Release and are only called once in a program. Maybe > this could be done for the mouse too. I'll will try this later.
Ok, here is a first patch but I don't know where to put the /* Warp the mouse to the center of the window */ stuff. Lionel can you please have a look at the patch. Bye, Michael
Index: mouse.c =================================================================== RCS file: /home/wine/wine/dlls/dinput/mouse.c,v retrieving revision 1.3 diff -u -d -r1.3 mouse.c --- mouse.c 4 Jun 2004 18:06:37 -0000 1.3 +++ mouse.c 26 Jul 2004 23:10:58 -0000 @@ -147,6 +147,18 @@ /* FIXME: This is ugly and not thread safe :/ */ static IDirectInputDevice8A* current_lock = NULL; +static CRITICAL_SECTION mouse_crit; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &mouse_crit, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { 0, (DWORD)(__FILE__ ": mouse_crit") } +}; +static CRITICAL_SECTION mouse_crit = { &critsect_debug, -1, 0, 0, 0, 0 }; + +static DWORD mouse_users; +static HHOOK mouse_hook; + static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */ 0x9e573ed8, 0x7734, @@ -232,6 +244,8 @@ return FALSE; } +static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lparam ); + static SysMouseImpl *alloc_device(REFGUID rguid, LPVOID mvt, IDirectInputImpl *dinput) { int offset_array[WINE_INTERNALMOUSE_NUM_OBJS] = { @@ -258,6 +272,11 @@ newDevice->wine_df->dt = NULL; newDevice->dinput = dinput; + EnterCriticalSection(&mouse_crit); + if (!mouse_users++) + mouse_hook = SetWindowsHookExA( WH_MOUSE_LL, dinput_mouse_hook, DINPUT_instance, 0 ); + LeaveCriticalSection(&mouse_crit); + return newDevice; } @@ -328,11 +347,15 @@ if (This->data_queue != NULL) HeapFree(GetProcessHeap(),0,This->data_queue); - if (This->hook) { - UnhookWindowsHookEx( This->hook ); + EnterCriticalSection(&mouse_crit); + if (!--mouse_users) { + UnhookWindowsHookEx( mouse_hook ); + mouse_hook = 0; if (This->dwCoopLevel & DISCL_EXCLUSIVE) ShowCursor(TRUE); /* show cursor */ } + LeaveCriticalSection(&mouse_crit); + DeleteCriticalSection(&(This->crit)); /* Free the DataFormat */ @@ -537,7 +560,7 @@ end: LeaveCriticalSection(&(This->crit)); - + if (dwCoop & DISCL_NONEXCLUSIVE) { /* Pass the events down to previous handlers (e.g. win32 input) */ ret = CallNextHookEx( This->hook, code, wparam, lparam ); @@ -579,7 +602,7 @@ if (This->acquired == 0) { POINT point; - + /* Store (in a global variable) the current lock */ current_lock = (IDirectInputDevice8A*)This; @@ -603,8 +626,8 @@ /* Install our mouse hook */ if (This->dwCoopLevel & DISCL_EXCLUSIVE) ShowCursor(FALSE); /* hide cursor */ - This->hook = SetWindowsHookExA( WH_MOUSE_LL, dinput_mouse_hook, DINPUT_instance, 0 ); - + This->hook = mouse_hook; + /* Get the window dimension and find the center */ GetWindowRect(This->win, &rect); This->win_centerX = (rect.right - rect.left) / 2; @@ -614,9 +637,9 @@ if (This->absolute == 0) { This->mapped_center.x = This->win_centerX; This->mapped_center.y = This->win_centerY; - MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1); +// MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1); TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y); - SetCursorPos( This->mapped_center.x, This->mapped_center.y ); +// SetCursorPos( This->mapped_center.x, This->mapped_center.y ); #ifdef MOUSE_HACK This->need_warp = WARP_DONE; #else @@ -642,7 +665,12 @@ if (This->acquired) { /* Reinstall previous mouse event handler */ if (This->hook) { - UnhookWindowsHookEx( This->hook ); +// if (UnhookWindowsHookEx( This->hook )) { +// TRACE("UNHOOK=TRUE\n"); +// } else { +// TRACE("UNHOOK=FALSE\n"); +// } + This->hook = 0; if (This->dwCoopLevel & DISCL_EXCLUSIVE) @@ -656,10 +684,10 @@ This->acquired = 0; /* And put the mouse cursor back where it was at acquire time */ - if (This->absolute == 0) { - TRACE(" warping mouse back to (%ld , %ld)\n", This->org_coords.x, This->org_coords.y); - SetCursorPos(This->org_coords.x, This->org_coords.y); - } +// if (This->absolute == 0) { +// TRACE(" warping mouse back to (%ld , %ld)\n", This->org_coords.x, This->org_coords.y); +// SetCursorPos(This->org_coords.x, This->org_coords.y); +// } } else { return DI_NOEFFECT; }