dinput: Make mouse use axis mode flag set in base class. Add tests.

This commit is contained in:
Vitaliy Margolen 2006-12-17 23:22:34 -07:00 committed by Alexandre Julliard
parent 7b07e4b563
commit 975d7ff292
3 changed files with 188 additions and 37 deletions

View file

@ -80,7 +80,6 @@ struct SysMouseImpl
IDirectInputImpl *dinput;
/* SysMouseAImpl */
BYTE absolute;
/* Previous position for relative moves */
LONG prevX, prevY;
/* 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;
if (wparam == WM_MOUSEMOVE) {
if (This->absolute) {
if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS) {
if (hook->pt.x != This->prevX)
queue_event((LPDIRECTINPUTDEVICE8A)This, This->base.data_format.offsets[WINE_MOUSE_X_POSITION],
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->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.lY = hook->pt.y;
} 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",
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) {
case WM_LBUTTONDOWN:
@ -454,7 +453,8 @@ static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
/* Init the mouse state */
GetCursorPos( &point );
if (This->absolute) {
if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS)
{
This->m_state.lX = point.x;
This->m_state.lY = point.y;
This->prevX = point.x;
@ -480,7 +480,8 @@ static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
This->win_centerY = (rect.bottom - rect.top ) / 2;
/* 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.y = This->win_centerY;
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);
/* 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);
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);
/* 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.lY = 0;
This->m_state.lZ = 0;
@ -610,33 +613,6 @@ static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,
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
*/
@ -858,7 +834,7 @@ static const IDirectInputDevice8AVtbl SysMouseAvt =
SysMouseAImpl_GetCapabilities,
SysMouseAImpl_EnumObjects,
SysMouseAImpl_GetProperty,
SysMouseAImpl_SetProperty,
IDirectInputDevice2AImpl_SetProperty,
SysMouseAImpl_Acquire,
SysMouseAImpl_Unacquire,
SysMouseAImpl_GetDeviceState,
@ -900,7 +876,7 @@ static const IDirectInputDevice8WVtbl SysMouseWvt =
XCAST(GetCapabilities)SysMouseAImpl_GetCapabilities,
SysMouseWImpl_EnumObjects,
XCAST(GetProperty)SysMouseAImpl_GetProperty,
XCAST(SetProperty)SysMouseAImpl_SetProperty,
XCAST(SetProperty)IDirectInputDevice2AImpl_SetProperty,
XCAST(Acquire)SysMouseAImpl_Acquire,
XCAST(Unacquire)SysMouseAImpl_Unacquire,
XCAST(GetDeviceState)SysMouseAImpl_GetDeviceState,

View file

@ -7,6 +7,7 @@ IMPORTS = dinput ole32 version user32 kernel32
EXTRALIBS = -ldxguid -luuid -ldxerr8
CTESTS = \
device.c \
joystick.c \
keyboard.c \
mouse.c

174
dlls/dinput/tests/device.c Normal file
View file

@ -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();
}