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;
     }

Reply via email to