dinput: Make mouse use axis mode flag set in base class. Add tests.
This commit is contained in:
parent
7b07e4b563
commit
975d7ff292
|
@ -80,7 +80,6 @@ struct SysMouseImpl
|
||||||
IDirectInputImpl *dinput;
|
IDirectInputImpl *dinput;
|
||||||
|
|
||||||
/* SysMouseAImpl */
|
/* SysMouseAImpl */
|
||||||
BYTE absolute;
|
|
||||||
/* Previous position for relative moves */
|
/* Previous position for relative moves */
|
||||||
LONG prevX, prevY;
|
LONG prevX, prevY;
|
||||||
/* These are used in case of relative -> absolute transitions */
|
/* These are used in case of relative -> absolute transitions */
|
||||||
|
@ -300,7 +299,7 @@ static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lpara
|
||||||
dwCoop = This->base.dwCoopLevel;
|
dwCoop = This->base.dwCoopLevel;
|
||||||
|
|
||||||
if (wparam == WM_MOUSEMOVE) {
|
if (wparam == WM_MOUSEMOVE) {
|
||||||
if (This->absolute) {
|
if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS) {
|
||||||
if (hook->pt.x != This->prevX)
|
if (hook->pt.x != This->prevX)
|
||||||
queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_X_POSITION],
|
queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_X_POSITION],
|
||||||
hook->pt.x, hook->time, This->dinput->evsequence);
|
hook->pt.x, hook->time, This->dinput->evsequence);
|
||||||
|
@ -345,7 +344,7 @@ static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lpara
|
||||||
This->prevX = hook->pt.x;
|
This->prevX = hook->pt.x;
|
||||||
This->prevY = hook->pt.y;
|
This->prevY = hook->pt.y;
|
||||||
|
|
||||||
if (This->absolute) {
|
if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS) {
|
||||||
This->m_state.lX = hook->pt.x;
|
This->m_state.lX = hook->pt.x;
|
||||||
This->m_state.lY = hook->pt.y;
|
This->m_state.lY = hook->pt.y;
|
||||||
} else {
|
} else {
|
||||||
|
@ -355,7 +354,7 @@ static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lpara
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(" msg %x pt %d %d (W=%d)\n",
|
TRACE(" msg %x pt %d %d (W=%d)\n",
|
||||||
wparam, hook->pt.x, hook->pt.y, (!This->absolute) && This->need_warp );
|
wparam, hook->pt.x, hook->pt.y, !(This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS) && This->need_warp );
|
||||||
|
|
||||||
switch(wparam) {
|
switch(wparam) {
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
|
@ -454,7 +453,8 @@ static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
|
||||||
|
|
||||||
/* Init the mouse state */
|
/* Init the mouse state */
|
||||||
GetCursorPos( &point );
|
GetCursorPos( &point );
|
||||||
if (This->absolute) {
|
if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS)
|
||||||
|
{
|
||||||
This->m_state.lX = point.x;
|
This->m_state.lX = point.x;
|
||||||
This->m_state.lY = point.y;
|
This->m_state.lY = point.y;
|
||||||
This->prevX = point.x;
|
This->prevX = point.x;
|
||||||
|
@ -480,7 +480,8 @@ static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
|
||||||
This->win_centerY = (rect.bottom - rect.top ) / 2;
|
This->win_centerY = (rect.bottom - rect.top ) / 2;
|
||||||
|
|
||||||
/* Warp the mouse to the center of the window */
|
/* Warp the mouse to the center of the window */
|
||||||
if (This->absolute == 0) {
|
if (!(This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS))
|
||||||
|
{
|
||||||
This->mapped_center.x = This->win_centerX;
|
This->mapped_center.x = This->win_centerX;
|
||||||
This->mapped_center.y = This->win_centerY;
|
This->mapped_center.y = This->win_centerY;
|
||||||
MapWindowPoints(This->base.win, HWND_DESKTOP, &This->mapped_center, 1);
|
MapWindowPoints(This->base.win, HWND_DESKTOP, &This->mapped_center, 1);
|
||||||
|
@ -521,7 +522,8 @@ static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
|
||||||
ERR("this(%p) != current_lock(%p)\n", This, current_lock);
|
ERR("this(%p) != current_lock(%p)\n", This, current_lock);
|
||||||
|
|
||||||
/* And put the mouse cursor back where it was at acquire time */
|
/* And put the mouse cursor back where it was at acquire time */
|
||||||
if (This->absolute == 0) {
|
if (!(This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS))
|
||||||
|
{
|
||||||
TRACE(" warping mouse back to (%d , %d)\n", This->org_coords.x, This->org_coords.y);
|
TRACE(" warping mouse back to (%d , %d)\n", This->org_coords.x, This->org_coords.y);
|
||||||
SetCursorPos(This->org_coords.x, This->org_coords.y);
|
SetCursorPos(This->org_coords.x, This->org_coords.y);
|
||||||
}
|
}
|
||||||
|
@ -552,7 +554,8 @@ static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
|
||||||
fill_DataFormat(ptr, &(This->m_state), &This->base.data_format);
|
fill_DataFormat(ptr, &(This->m_state), &This->base.data_format);
|
||||||
|
|
||||||
/* Initialize the buffer when in relative mode */
|
/* Initialize the buffer when in relative mode */
|
||||||
if (This->absolute == 0) {
|
if (!(This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS))
|
||||||
|
{
|
||||||
This->m_state.lX = 0;
|
This->m_state.lX = 0;
|
||||||
This->m_state.lY = 0;
|
This->m_state.lY = 0;
|
||||||
This->m_state.lZ = 0;
|
This->m_state.lZ = 0;
|
||||||
|
@ -610,33 +613,6 @@ static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* SetProperty : change input device properties
|
|
||||||
*/
|
|
||||||
static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
|
|
||||||
REFGUID rguid,
|
|
||||||
LPCDIPROPHEADER ph)
|
|
||||||
{
|
|
||||||
SysMouseImpl *This = (SysMouseImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
|
|
||||||
|
|
||||||
if (!HIWORD(rguid)) {
|
|
||||||
switch (LOWORD(rguid)) {
|
|
||||||
case (DWORD) DIPROP_AXISMODE: {
|
|
||||||
LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
|
|
||||||
This->absolute = !(pd->dwData);
|
|
||||||
TRACE("Using %s coordinates mode now\n", This->absolute ? "absolute" : "relative");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return IDirectInputDevice2AImpl_SetProperty(iface, rguid, ph);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return DI_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* GetProperty : get input device properties
|
* GetProperty : get input device properties
|
||||||
*/
|
*/
|
||||||
|
@ -858,7 +834,7 @@ static const IDirectInputDevice8AVtbl SysMouseAvt =
|
||||||
SysMouseAImpl_GetCapabilities,
|
SysMouseAImpl_GetCapabilities,
|
||||||
SysMouseAImpl_EnumObjects,
|
SysMouseAImpl_EnumObjects,
|
||||||
SysMouseAImpl_GetProperty,
|
SysMouseAImpl_GetProperty,
|
||||||
SysMouseAImpl_SetProperty,
|
IDirectInputDevice2AImpl_SetProperty,
|
||||||
SysMouseAImpl_Acquire,
|
SysMouseAImpl_Acquire,
|
||||||
SysMouseAImpl_Unacquire,
|
SysMouseAImpl_Unacquire,
|
||||||
SysMouseAImpl_GetDeviceState,
|
SysMouseAImpl_GetDeviceState,
|
||||||
|
@ -900,7 +876,7 @@ static const IDirectInputDevice8WVtbl SysMouseWvt =
|
||||||
XCAST(GetCapabilities)SysMouseAImpl_GetCapabilities,
|
XCAST(GetCapabilities)SysMouseAImpl_GetCapabilities,
|
||||||
SysMouseWImpl_EnumObjects,
|
SysMouseWImpl_EnumObjects,
|
||||||
XCAST(GetProperty)SysMouseAImpl_GetProperty,
|
XCAST(GetProperty)SysMouseAImpl_GetProperty,
|
||||||
XCAST(SetProperty)SysMouseAImpl_SetProperty,
|
XCAST(SetProperty)IDirectInputDevice2AImpl_SetProperty,
|
||||||
XCAST(Acquire)SysMouseAImpl_Acquire,
|
XCAST(Acquire)SysMouseAImpl_Acquire,
|
||||||
XCAST(Unacquire)SysMouseAImpl_Unacquire,
|
XCAST(Unacquire)SysMouseAImpl_Unacquire,
|
||||||
XCAST(GetDeviceState)SysMouseAImpl_GetDeviceState,
|
XCAST(GetDeviceState)SysMouseAImpl_GetDeviceState,
|
||||||
|
|
|
@ -7,6 +7,7 @@ IMPORTS = dinput ole32 version user32 kernel32
|
||||||
EXTRALIBS = -ldxguid -luuid -ldxerr8
|
EXTRALIBS = -ldxguid -luuid -ldxerr8
|
||||||
|
|
||||||
CTESTS = \
|
CTESTS = \
|
||||||
|
device.c \
|
||||||
joystick.c \
|
joystick.c \
|
||||||
keyboard.c \
|
keyboard.c \
|
||||||
mouse.c
|
mouse.c
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Vitaliy Margolen
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DIRECTINPUT_VERSION 0x0700
|
||||||
|
|
||||||
|
#define COBJMACROS
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "wine/test.h"
|
||||||
|
#include "windef.h"
|
||||||
|
#include "dinput.h"
|
||||||
|
#include "dxerr8.h"
|
||||||
|
|
||||||
|
static const DIOBJECTDATAFORMAT obj_data_format[] = {
|
||||||
|
{ &GUID_YAxis, 16, DIDFT_OPTIONAL|DIDFT_AXIS |DIDFT_MAKEINSTANCE(1), 0},
|
||||||
|
{ &GUID_Button,15, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(3), 0},
|
||||||
|
{ &GUID_Key, 0, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(16),0},
|
||||||
|
{ &GUID_Key, 1, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(17),0},
|
||||||
|
{ &GUID_Key, 2, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(18),0},
|
||||||
|
{ &GUID_Key, 3, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(19),0},
|
||||||
|
{ &GUID_Key, 4, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(20),0},
|
||||||
|
{ &GUID_Key, 5, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(21),0},
|
||||||
|
{ &GUID_Key, 6, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(22),0},
|
||||||
|
{ &GUID_Key, 7, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(23),0},
|
||||||
|
{ &GUID_Key, 8, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(24),0},
|
||||||
|
{ &GUID_Key, 9, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(25),0},
|
||||||
|
{ &GUID_Key, 10, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(26),0},
|
||||||
|
{ &GUID_Key, 11, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(27),0},
|
||||||
|
{ &GUID_Key, 12, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(28),0},
|
||||||
|
{ NULL, 13, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(5),0},
|
||||||
|
|
||||||
|
{ &GUID_Button,14, DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_MAKEINSTANCE(32),0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const DIDATAFORMAT data_format = {
|
||||||
|
sizeof(DIDATAFORMAT),
|
||||||
|
sizeof(DIOBJECTDATAFORMAT),
|
||||||
|
DIDF_ABSAXIS,
|
||||||
|
32,
|
||||||
|
sizeof(obj_data_format) / sizeof(obj_data_format[0]),
|
||||||
|
(LPDIOBJECTDATAFORMAT)obj_data_format
|
||||||
|
};
|
||||||
|
|
||||||
|
static BOOL CALLBACK enum_callback(LPCDIDEVICEOBJECTINSTANCE oi, LPVOID info)
|
||||||
|
{
|
||||||
|
if (winetest_debug > 1)
|
||||||
|
trace(" Type:%4x Ofs:%2x Name:%s Flags:%08x\n",
|
||||||
|
oi->dwType, oi->dwOfs, oi->tszName, oi->dwFlags);
|
||||||
|
(*(int*)info)++;
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_object_info(LPDIRECTINPUTDEVICE device, HWND hwnd)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
DIPROPDWORD dp;
|
||||||
|
DIDEVICEOBJECTINSTANCE obj_info;
|
||||||
|
int cnt = 0, cnt1 = 0;
|
||||||
|
|
||||||
|
hr = IDirectInputDevice_EnumObjects(device, enum_callback, &cnt, DIDFT_ALL);
|
||||||
|
ok(SUCCEEDED(hr), "EnumObjects() failed: %s\n", DXGetErrorString8(hr));
|
||||||
|
|
||||||
|
hr = IDirectInputDevice_SetDataFormat(device, &data_format);
|
||||||
|
ok(SUCCEEDED(hr), "SetDataFormat() failed: %s\n", DXGetErrorString8(hr));
|
||||||
|
|
||||||
|
hr = IDirectInputDevice_EnumObjects(device, enum_callback, &cnt1, DIDFT_ALL);
|
||||||
|
ok(SUCCEEDED(hr), "EnumObjects() failed: %s\n", DXGetErrorString8(hr));
|
||||||
|
if (0) /* fails for joystick only */
|
||||||
|
ok(cnt == cnt1, "Enum count changed from %d to %d\n", cnt, cnt1);
|
||||||
|
|
||||||
|
/* No need to test devices without axis */
|
||||||
|
obj_info.dwSize = sizeof(obj_info);
|
||||||
|
hr = IDirectInputDevice_GetObjectInfo(device, &obj_info, 16, DIPH_BYOFFSET);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
/* No device supports per axis relative/absolute mode */
|
||||||
|
memset(&dp, 0, sizeof(dp));
|
||||||
|
dp.diph.dwSize = sizeof(DIPROPDWORD);
|
||||||
|
dp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||||
|
dp.diph.dwHow = DIPH_BYOFFSET;
|
||||||
|
dp.diph.dwObj = 16;
|
||||||
|
dp.dwData = DIPROPAXISMODE_ABS;
|
||||||
|
hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
|
||||||
|
ok(hr == DIERR_UNSUPPORTED, "SetProperty() returned: %s\n", DXGetErrorString8(hr));
|
||||||
|
dp.diph.dwHow = DIPH_DEVICE;
|
||||||
|
hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
|
||||||
|
ok(hr == DIERR_INVALIDPARAM, "SetProperty() returned: %s\n", DXGetErrorString8(hr));
|
||||||
|
dp.diph.dwObj = 0;
|
||||||
|
hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
|
||||||
|
ok(hr == DI_OK, "SetProperty() failed: %s\n", DXGetErrorString8(hr));
|
||||||
|
|
||||||
|
/* Can not change mode while acquired */
|
||||||
|
hr = IDirectInputDevice_Acquire(device);
|
||||||
|
ok(hr == DI_OK, "Acquire() failed: %s\n", DXGetErrorString8(hr));
|
||||||
|
hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
|
||||||
|
ok(hr == DIERR_ACQUIRED, "SetProperty() returned: %s\n", DXGetErrorString8(hr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct enum_data
|
||||||
|
{
|
||||||
|
LPDIRECTINPUT pDI;
|
||||||
|
HWND hwnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
static BOOL CALLBACK enum_devices(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
|
||||||
|
{
|
||||||
|
struct enum_data *data = (struct enum_data*)pvRef;
|
||||||
|
LPDIRECTINPUTDEVICE device;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, &device, NULL);
|
||||||
|
ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %s\n", DXGetErrorString8(hr));
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
trace("Testing device \"%s\"\n", lpddi->tszInstanceName);
|
||||||
|
test_object_info(device, data->hwnd);
|
||||||
|
IUnknown_Release(device);
|
||||||
|
}
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void device_tests(void)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
LPDIRECTINPUT pDI = NULL;
|
||||||
|
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||||
|
HWND hwnd;
|
||||||
|
struct enum_data data;
|
||||||
|
|
||||||
|
hr = DirectInputCreate(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
|
||||||
|
ok(SUCCEEDED(hr), "DirectInputCreate() failed: %s\n", DXGetErrorString8(hr));
|
||||||
|
if (FAILED(hr)) return;
|
||||||
|
|
||||||
|
hwnd = CreateWindow("static", "Title", WS_OVERLAPPEDWINDOW,
|
||||||
|
10, 10, 200, 200, NULL, NULL, NULL, NULL);
|
||||||
|
ok(hwnd != NULL, "err: %d\n", GetLastError());
|
||||||
|
if (hwnd)
|
||||||
|
{
|
||||||
|
ShowWindow(hwnd, SW_SHOW);
|
||||||
|
|
||||||
|
data.pDI = pDI;
|
||||||
|
data.hwnd = hwnd;
|
||||||
|
hr = IDirectInput_EnumDevices(pDI, 0, enum_devices, &data, DIEDFL_ALLDEVICES);
|
||||||
|
ok(SUCCEEDED(hr), "IDirectInput_EnumDevices() failed: %s\n", DXGetErrorString8(hr));
|
||||||
|
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
}
|
||||||
|
if (pDI) IUnknown_Release(pDI);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(device)
|
||||||
|
{
|
||||||
|
CoInitialize(NULL);
|
||||||
|
|
||||||
|
device_tests();
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
Loading…
Reference in New Issue