mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 09:50:52 +00:00
dinput: Make mouse use axis mode flag set in base class. Add tests.
This commit is contained in:
parent
7b07e4b563
commit
975d7ff292
3 changed files with 188 additions and 37 deletions
|
@ -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,
|
||||
|
|
|
@ -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
174
dlls/dinput/tests/device.c
Normal 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();
|
||||
}
|
Loading…
Reference in a new issue