This patch changes the dinput mouse handling to use the WH_MOUSE_LL
hook instead of referencing mouse driver internals. Since I'm not
using dinput, could someone please give this a try?
Index: dlls/dinput/mouse/main.c
===================================================================
RCS file: /opt/cvs-commit/wine/dlls/dinput/mouse/main.c,v
retrieving revision 1.9
diff -u -r1.9 main.c
--- dlls/dinput/mouse/main.c 2001/10/02 18:45:46 1.9
+++ dlls/dinput/mouse/main.c 2001/10/17 19:49:59
@@ -17,7 +17,6 @@
#include "wingdi.h"
#include "winerror.h"
#include "windef.h"
-#include "mouse.h"
#include "winuser.h"
#include "dinput.h"
@@ -105,7 +104,7 @@
BYTE absolute;
/* Previous position for relative moves */
LONG prevX, prevY;
- LPMOUSE_EVENT_PROC prev_handler;
+ HHOOK hook;
HWND win;
DWORD dwCoopLevel;
POINT mapped_center;
@@ -226,10 +225,7 @@
if (This->data_queue != NULL)
HeapFree(GetProcessHeap(),0,This->data_queue);
- /* Install the previous event handler (in case of releasing an acquired
- mouse device) */
- if (This->prev_handler != NULL)
- MOUSE_Enable(This->prev_handler);
+ if (This->hook) UnhookWindowsHookEx( This->hook );
DeleteCriticalSection(&(This->crit));
/* Free the DataFormat */
@@ -318,40 +314,30 @@
return 0;
}
-/* Our private mouse event handler */
-static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
- DWORD cButtons, DWORD dwExtraInfo )
+/* low-level mouse hook */
+static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lparam )
{
- long posX = -1, posY = -1;
- DWORD keyState, xtime, extra;
- SysMouseAImpl* This = (SysMouseAImpl*) current_lock;
-
- EnterCriticalSection(&(This->crit));
- /* Mouse moved -> send event if asked */
- if (This->hEvent)
- SetEvent(This->hEvent);
-
- if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
- && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC ) {
- WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
- keyState = wme->keyState;
- xtime = wme->time;
- extra = (DWORD)wme->hWnd;
-
- if (dwFlags & MOUSEEVENTF_MOVE) {
- if (dwFlags & MOUSEEVENTF_ABSOLUTE) {
- posX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
- posY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
+ LRESULT ret;
+ MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
+ SysMouseAImpl* This = (SysMouseAImpl*) current_lock;
+
+ if (code != HC_ACTION) return CallNextHookEx( This->hook, code, wparam, lparam );
+
+ EnterCriticalSection(&(This->crit));
+ /* Mouse moved -> send event if asked */
+ if (This->hEvent)
+ SetEvent(This->hEvent);
+ if (wparam == WM_MOUSEMOVE) {
if (This->absolute) {
- if (posX != This->prevX)
- GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX, xtime, 0);
- if (posY != This->prevY)
- GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY, xtime, 0);
+ if (hook->pt.x != This->prevX)
+ GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x, hook->time, 0);
+ if (hook->pt.y != This->prevY)
+ GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y, hook->time, 0);
} else {
/* Now, warp handling */
if ((This->need_warp == WARP_STARTED) &&
- (posX == This->mapped_center.x) && (posY == This->mapped_center.y)) {
+ (hook->pt.x == This->mapped_center.x) && (hook->pt.y == This->mapped_center.y)) {
/* Warp has been done... */
This->need_warp = WARP_DONE;
goto end;
@@ -360,122 +346,73 @@
/* Relative mouse input with absolute mouse event : the real fun starts here... */
if ((This->need_warp == WARP_NEEDED) ||
(This->need_warp == WARP_STARTED)) {
- if (posX != This->prevX)
- GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX - This->prevX, xtime, (This->dinput->evsequence)++);
- if (posY != This->prevY)
- GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY - This->prevY, xtime, (This->dinput->evsequence)++);
+ if (hook->pt.x != This->prevX)
+ GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x - This->prevX, hook->time, (This->dinput->evsequence)++);
+ if (hook->pt.y != This->prevY)
+ GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y - This->prevY, hook->time, (This->dinput->evsequence)++);
} else {
/* This is the first time the event handler has been called after a
GetData of GetState. */
- if (posX != This->mapped_center.x) {
- GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX - This->mapped_center.x, xtime, (This->dinput->evsequence)++);
+ if (hook->pt.x != This->mapped_center.x) {
+ GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x - This->mapped_center.x, hook->time, (This->dinput->evsequence)++);
This->need_warp = WARP_NEEDED;
}
- if (posY != This->mapped_center.y) {
- GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY - This->mapped_center.y, xtime, (This->dinput->evsequence)++);
+ if (hook->pt.y != This->mapped_center.y) {
+ GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y - This->mapped_center.y, hook->time, (This->dinput->evsequence)++);
This->need_warp = WARP_NEEDED;
}
}
}
- This->prevX = posX;
- This->prevY = posY;
+ This->prevX = hook->pt.x;
+ This->prevY = hook->pt.y;
- if (This->absolute) {
- This->m_state.lX = posX;
- This->m_state.lY = posY;
- } else {
- This->m_state.lX = posX - This->mapped_center.x;
- This->m_state.lY = posY - This->mapped_center.y;
- }
- } else {
- /* Mouse reporting is in relative mode */
- posX = (long) dx;
- posY = (long) dy;
-
if (This->absolute) {
- long aposX, aposY;
-
- aposX = This->m_state.lX + posX;
- if (aposX < 0)
- aposX = 0;
- if (aposX >= GetSystemMetrics(SM_CXSCREEN))
- aposX = GetSystemMetrics(SM_CXSCREEN);
-
- aposY = This->m_state.lY + posY;
- if (aposY < 0)
- aposY = 0;
- if (aposY >= GetSystemMetrics(SM_CYSCREEN))
- aposY = GetSystemMetrics(SM_CYSCREEN);
-
- if (posX != 0)
- GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], aposX, xtime, (This->dinput->evsequence)++);
- if (posY != 0)
- GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], aposY, xtime, (This->dinput->evsequence)++);
-
- This->m_state.lX = aposX;
- This->m_state.lY = aposY;
+ This->m_state.lX = hook->pt.x;
+ This->m_state.lY = hook->pt.y;
} else {
- if (posX != 0)
- GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX, xtime, (This->dinput->evsequence)++);
- if (posY != 0)
- GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY, xtime, (This->dinput->evsequence)++);
-
- This->m_state.lX = posX;
- This->m_state.lY = posY;
+ This->m_state.lX = hook->pt.x - This->mapped_center.x;
+ This->m_state.lY = hook->pt.y - This->mapped_center.y;
}
- }
}
- } else {
- ERR("Mouse event not supported...\n");
- goto end;
- }
-
- if (TRACE_ON(dinput)) {
- if (dwFlags & MOUSEEVENTF_MOVE)
- TRACE(" %ld %ld (%s)", posX, posY,
- (dwFlags & MOUSEEVENTF_ABSOLUTE ? "abs" : "rel"));
-
- if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) DPRINTF(" LD ");
- if ( dwFlags & MOUSEEVENTF_LEFTUP ) DPRINTF(" LU ");
- if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) DPRINTF(" RD ");
- if ( dwFlags & MOUSEEVENTF_RIGHTUP ) DPRINTF(" RU ");
-
- if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) DPRINTF(" MD ");
- if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) DPRINTF(" MU ");
-
- if (!(This->absolute)) DPRINTF(" W=%d ", This->need_warp);
-
- DPRINTF("\n");
- }
+ TRACE(" msg %x pt %ld %ld (W=%d)",
+ wparam, hook->pt.x, hook->pt.y, This->absolute && This->need_warp );
-
- if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) {
- GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0xFF, xtime, (This->dinput->evsequence)++);
- This->m_state.rgbButtons[0] = 0xFF;
- }
- if ( dwFlags & MOUSEEVENTF_LEFTUP ) {
- GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0x00, xtime, (This->dinput->evsequence)++);
- This->m_state.rgbButtons[0] = 0x00;
- }
- if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) {
- GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0xFF, xtime, (This->dinput->evsequence)++);
- This->m_state.rgbButtons[1] = 0xFF;
- }
- if ( dwFlags & MOUSEEVENTF_RIGHTUP ) {
- GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0x00, xtime, (This->dinput->evsequence)++);
- This->m_state.rgbButtons[1] = 0x00;
- }
- if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) {
- GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0xFF, xtime, (This->dinput->evsequence)++);
- This->m_state.rgbButtons[2] = 0xFF;
- }
- if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) {
- GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0x00, xtime, (This->dinput->evsequence)++);
- This->m_state.rgbButtons[2] = 0x00;
- }
+ switch(wparam)
+ {
+ case WM_LBUTTONDOWN:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0xFF,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[0] = 0xFF;
+ break;
+ case WM_LBUTTONUP:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0x00,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[0] = 0x00;
+ break;
+ case WM_RBUTTONDOWN:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0xFF,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[1] = 0xFF;
+ break;
+ case WM_RBUTTONUP:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0x00,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[1] = 0x00;
+ break;
+ case WM_MBUTTONDOWN:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0xFF,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[2] = 0xFF;
+ break;
+ case WM_MBUTTONUP:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0x00,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[2] = 0x00;
+ break;
+ }
TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
This->m_state.lX, This->m_state.lY,
@@ -484,10 +421,11 @@
end:
if (This->dwCoopLevel & DISCL_NONEXCLUSIVE)
{ /* pass the events down to previous handlers (e.g. win32 input) */
- if (This->prev_handler)
- This->prev_handler(dwFlags, dx, dy, cButtons, dwExtraInfo);
+ ret = CallNextHookEx( This->hook, code, wparam, lparam );
}
+ else ret = 1; /* ignore message */
LeaveCriticalSection(&(This->crit));
+ return ret;
}
@@ -503,10 +441,7 @@
if (This->acquired == 0) {
POINT point;
-
- /* This stores the current mouse handler. */
- This->prev_handler = mouse_event;
-
+
/* Store (in a global variable) the current lock */
current_lock = (IDirectInputDevice2A*)This;
@@ -525,9 +460,9 @@
This->m_state.rgbButtons[1] = (GetKeyState(VK_MBUTTON) ? 0xFF : 0x00);
This->m_state.rgbButtons[2] = (GetKeyState(VK_RBUTTON) ? 0xFF : 0x00);
- /* Install our own mouse event handler */
- MOUSE_Enable(dinput_mouse_event);
-
+ /* Install our mouse hook */
+ This->hook = SetWindowsHookExW( WH_MOUSE_LL, dinput_mouse_hook, 0, 0 );
+
/* Get the window dimension and find the center */
GetWindowRect(This->win, &rect);
This->win_centerX = (rect.right - rect.left) / 2;
@@ -564,9 +499,9 @@
if (This->acquired)
{
/* Reinstall previous mouse event handler */
- MOUSE_Enable(This->prev_handler);
- This->prev_handler = NULL;
-
+ if (This->hook) UnhookWindowsHookEx( This->hook );
+ This->hook = 0;
+
/* No more locks */
current_lock = NULL;
--
Alexandre Julliard
julliard(a)winehq.com