From 30e2fbcb6ee30213538dd06918b49738500f9fb2 Mon Sep 17 00:00:00 2001 From: Vitaliy Margolen Date: Fri, 5 Jan 2007 17:14:55 -0700 Subject: [PATCH] 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 469f3d8b81e..530f7461bdf 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -493,7 +493,7 @@ int offset_to_object(LPCDIDATAFORMAT df, int offset) 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 df, int id) { 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 e35c9f45397..638661ad0b4 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -74,6 +74,7 @@ extern void release_DataFormat(DataFormat *df) ; 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 6465482436b..f8eea4caa7e 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_hook( int code, WPARAM wparam, LPARAM lpara 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_hook( int code, WPARAM wparam, LPARAM lpara 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); -- 2.11.4.GIT