Vitaliy Margolen : dinput: Fix mouse to use proper offset when queuing new events. Add handling of X-buttons.

Alexandre Julliard julliard at wine.codeweavers.com
Sat Jan 6 05:12:53 CST 2007


Module: wine
Branch: master
Commit: 30e2fbcb6ee30213538dd06918b49738500f9fb2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=30e2fbcb6ee30213538dd06918b49738500f9fb2

Author: Vitaliy Margolen <wine-patches at kievinfo.com>
Date:   Fri Jan  5 17:14:55 2007 -0700

dinput: Fix mouse to use proper offset when queuing new events. Add handling of X-buttons.

We should use instance IDs instead of sequential numbers to get correct offset.

---

 dlls/dinput/device.c         |   12 +++++-
 dlls/dinput/device_private.h |    1 +
 dlls/dinput/mouse.c          |   88 +++++++++++++++++++++---------------------
 3 files changed, 55 insertions(+), 46 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 469f3d8..530f746 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -493,7 +493,7 @@ int offset_to_object(LPCDIDATAFORMAT df,
     int i;
 
     for (i = 0; i < df->dwNumObjs; i++)
-        if (df->rgodf[i].dwOfs == offset)
+        if (dataformat_to_odf(df, i)->dwOfs == offset)
             return i;
 
     return -1;
@@ -503,13 +503,21 @@ static int id_to_object(LPCDIDATAFORMAT
 {
     int i;
 
+    id &= 0x00ffffff;
     for (i = 0; i < df->dwNumObjs; i++)
-        if ((df->rgodf[i].dwType & 0x00ffffff) == (id & 0x00ffffff))
+        if ((dataformat_to_odf(df, i)->dwType & 0x00ffffff) == id)
             return i;
 
     return -1;
 }
 
+int id_to_offset(DataFormat *df, int id)
+{
+    int obj = id_to_object(df->wine_df, id);
+
+    return obj >= 0 && df->offsets ? df->offsets[obj] : -1;
+}
+
 int find_property(LPCDIDATAFORMAT df, LPCDIPROPHEADER ph)
 {
     switch (ph->dwHow)
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index e35c9f4..638661a 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -74,6 +74,7 @@ extern void release_DataFormat(DataForma
 extern void queue_event(LPDIRECTINPUTDEVICE8A iface, int ofs, DWORD data, DWORD time, DWORD seq);
 /* Helper functions to work with data format */
 extern int offset_to_object(LPCDIDATAFORMAT df, int offset);
+extern int id_to_offset(DataFormat *df, int id);
 extern int find_property(LPCDIDATAFORMAT df, LPCDIPROPHEADER ph);
 
 /**
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index 6465482..f8eea4c 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -42,18 +42,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput);
 /* Wine mouse driver object instances */
 #define WINE_MOUSE_X_AXIS_INSTANCE   0
 #define WINE_MOUSE_Y_AXIS_INSTANCE   1
-
-/* ------------------------------- */
-/* Wine mouse internal data format */
-/* ------------------------------- */
-
-/* Constants used to access the offset array */
-#define WINE_MOUSE_X_POSITION 0
-#define WINE_MOUSE_Y_POSITION 1
-#define WINE_MOUSE_Z_POSITION 2
-#define WINE_MOUSE_L_POSITION 3
-#define WINE_MOUSE_R_POSITION 4
-#define WINE_MOUSE_M_POSITION 5
+#define WINE_MOUSE_Z_AXIS_INSTANCE   2
+#define WINE_MOUSE_BUTTONS_INSTANCE  3
 
 static const IDirectInputDevice8AVtbl SysMouseAvt;
 static const IDirectInputDevice8WVtbl SysMouseWvt;
@@ -298,7 +288,7 @@ static LRESULT CALLBACK dinput_mouse_hoo
     MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
     SysMouseImpl* This = (SysMouseImpl*) current_lock;
     DWORD dwCoop;
-    int wdata;
+    int wdata = 0, inst_id = -1;
 
     if (code != HC_ACTION) return CallNextHookEx( 0, code, wparam, lparam );
 
@@ -322,58 +312,68 @@ static LRESULT CALLBACK dinput_mouse_hoo
                 pt1 = pt;
 
             if (pt.x)
-                queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_X_POSITION],
+                queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format,
+                            DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS),
                             pt1.x, hook->time, This->dinput->evsequence);
             if (pt.y)
-                queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_Y_POSITION],
-                            pt1.y, hook->time, This->dinput->evsequence);
+            {
+                inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS;
+                wdata = pt1.y;
+            }
 
             This->need_warp = (pt.x || pt.y) && dwCoop & DISCL_EXCLUSIVE;
             break;
         }
+        case WM_MOUSEWHEEL:
+            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS;
+            This->m_state.lZ += wdata = (short)HIWORD(hook->mouseData);
+            break;
         case WM_LBUTTONDOWN:
-            queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_L_POSITION],
-                        0x80, hook->time, This->dinput->evsequence);
-	    This->m_state.rgbButtons[0] = 0x80;
+            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON;
+            This->m_state.rgbButtons[0] = wdata = 0x80;
 	    break;
 	case WM_LBUTTONUP:
-            queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_L_POSITION],
-                        0x00, hook->time, This->dinput->evsequence);
-	    This->m_state.rgbButtons[0] = 0x00;
+            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 0) | DIDFT_PSHBUTTON;
+            This->m_state.rgbButtons[0] = wdata = 0x00;
 	    break;
 	case WM_RBUTTONDOWN:
-            queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_R_POSITION],
-                        0x80, hook->time, This->dinput->evsequence);
-	    This->m_state.rgbButtons[1] = 0x80;
+            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON;
+            This->m_state.rgbButtons[1] = wdata = 0x80;
 	    break;
 	case WM_RBUTTONUP:
-            queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_R_POSITION],
-                        0x00, hook->time, This->dinput->evsequence);
-	    This->m_state.rgbButtons[1] = 0x00;
+            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 1) | DIDFT_PSHBUTTON;
+            This->m_state.rgbButtons[1] = wdata = 0x00;
 	    break;
 	case WM_MBUTTONDOWN:
-            queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_M_POSITION],
-                        0x80, hook->time, This->dinput->evsequence);
-	    This->m_state.rgbButtons[2] = 0x80;
+            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON;
+            This->m_state.rgbButtons[2] = wdata = 0x80;
 	    break;
 	case WM_MBUTTONUP:
-            queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_M_POSITION],
-                        0x00, hook->time, This->dinput->evsequence);
-	    This->m_state.rgbButtons[2] = 0x00;
-	    break;
-	case WM_MOUSEWHEEL:
-	    wdata = (short)HIWORD(hook->mouseData);
-            queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_Z_POSITION],
-                        wdata, hook->time, This->dinput->evsequence);
-	    This->m_state.lZ += wdata;
+            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2) | DIDFT_PSHBUTTON;
+            This->m_state.rgbButtons[2] = wdata = 0x00;
 	    break;
+        case WM_XBUTTONDOWN:
+            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON;
+            This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x80;
+            break;
+        case WM_XBUTTONUP:
+            inst_id = DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + 2 + HIWORD(hook->mouseData)) | DIDFT_PSHBUTTON;
+            This->m_state.rgbButtons[2 + HIWORD(hook->mouseData)] = wdata = 0x00;
+            break;
     }
 
-    TRACE("msg %x @ (%d %d): (X: %d - Y: %d   L: %02x M: %02x R: %02x)\n",
-          wparam, hook->pt.x, hook->pt.y, This->m_state.lX, This->m_state.lY,
-	  This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]);
+    if (TRACE_ON(dinput))
+    {
+        int i;
 
-    This->dinput->evsequence++;
+        TRACE("msg %x @ (%d %d): (X: %d Y: %d Z: %d\n", wparam, hook->pt.x, hook->pt.y,
+              This->m_state.lX, This->m_state.lY, This->m_state.lZ);
+        for (i = 0; i < 5; i++) TRACE(" B%d: %02x", i, This->m_state.rgbButtons[i]);
+        TRACE(")\n");
+    }
+    if (inst_id != -1)
+        queue_event((LPDIRECTINPUTDEVICE8A)This, id_to_offset(&This->base.data_format, inst_id),
+                    wdata, hook->time, This->dinput->evsequence++);
 
     /* Mouse moved -> send event if asked */
     if (This->base.hEvent) SetEvent(This->base.hEvent);




More information about the wine-cvs mailing list