From: Ivo Ivanov logos128@gmail.com Signed-off-by: Ivo Ivanov logos128@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v2: Fix dinput:device test failure, set dwObj to 0 in SetActionMap when setting device properties, check for dwObj == 0 in SetProperty for device properties.
include/dinput.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/dinput.h b/include/dinput.h index a073054b388..71cc55aece5 100644 --- a/include/dinput.h +++ b/include/dinput.h @@ -917,6 +917,9 @@ typedef const DIPROPPOINTER *LPCDIPROPPOINTER; #define DIPROP_PRODUCTNAME MAKEDIPROP(14) #define DIPROP_JOYSTICKID MAKEDIPROP(15)
+#define DIPROP_PHYSICALRANGE MAKEDIPROP(18) +#define DIPROP_LOGICALRANGE MAKEDIPROP(19) + #define DIPROP_KEYNAME MAKEDIPROP(20) #define DIPROP_CPOINTS MAKEDIPROP(21) #define DIPROP_APPDATA MAKEDIPROP(22)
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput8/tests/device.c | 21 +++++++ dlls/dinput8/tests/hid.c | 114 +++++++++++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 019f63ad825..8b34de276db 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -1329,6 +1329,8 @@ static void test_mouse_info(void) ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); prop_range.diph.dwHow = DIPH_BYOFFSET; prop_range.diph.dwObj = DIMOFS_X; hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); @@ -1407,12 +1409,23 @@ static void test_mouse_info(void) ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); prop_range.lMin = 0xdeadbeef; prop_range.lMax = 0xdeadbeef; hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); ok( hr == DI_OK, "GetProperty DIPROP_RANGE returned %#x\n", hr ); ok( prop_range.lMin == DIPROPRANGE_NOMIN, "got %d expected %d\n", prop_range.lMin, DIPROPRANGE_NOMIN ); ok( prop_range.lMax == DIPROPRANGE_NOMAX, "got %d expected %d\n", prop_range.lMax, DIPROPRANGE_NOMAX ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_PHYSICALRANGE, &prop_range.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr ); + + prop_string.diph.dwHow = DIPH_BYOFFSET; + prop_string.diph.dwObj = DIMOFS_X; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_KEYNAME, &prop_string.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_KEYNAME returned %#x\n", hr );
prop_range.diph.dwHow = DIPH_DEVICE; prop_range.diph.dwObj = 0; @@ -1660,10 +1673,16 @@ static void test_keyboard_info(void) ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); prop_range.diph.dwHow = DIPH_BYOFFSET; prop_range.diph.dwObj = 1; hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_RANGE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph ); + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_PHYSICALRANGE, &prop_range.diph ); + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr );
prop_dword.diph.dwHow = DIPH_DEVICE; prop_dword.diph.dwObj = 0; @@ -1736,6 +1755,8 @@ static void test_keyboard_info(void) ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); prop_range.diph.dwHow = DIPH_BYOFFSET; prop_range.diph.dwObj = 1; hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index ac4b8023611..355dc8ff855 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -4188,8 +4188,17 @@ static void test_simple_joystick(void) ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_RANGE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_KEYNAME, &prop_string.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "GetProperty DIPROP_KEYNAME returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_PHYSICALRANGE, &prop_range.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr );
prop_dword.diph.dwHow = DIPH_BYUSAGE; prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); @@ -4205,6 +4214,29 @@ static void test_simple_joystick(void) hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); ok( hr == DI_OK, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); ok( prop_dword.dwData == 10000, "got %u expected %u\n", prop_dword.dwData, 10000 ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == DIPROPCALIBRATIONMODE_COOKED, "got %u expected %u\n", prop_dword.dwData, DIPROPCALIBRATIONMODE_COOKED ); + + prop_string.diph.dwHow = DIPH_BYUSAGE; + prop_string.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_KEYNAME, &prop_string.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_KEYNAME returned %#x\n", hr ); + todo_wine + ok( !wcscmp( prop_string.wsz, expect_objects[4].tszName ), "got DIPROP_KEYNAME %s\n", + debugstr_w( prop_string.wsz ) ); + prop_string.diph.dwObj = MAKELONG( 0x1, HID_USAGE_PAGE_BUTTON ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_KEYNAME, &prop_string.diph ); + todo_wine + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_KEYNAME returned %#x\n", hr ); + prop_string.diph.dwHow = DIPH_BYUSAGE; + prop_string.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_KEYNAME, &prop_string.diph ); + ok( hr == DIERR_UNSUPPORTED, "SetProperty DIPROP_KEYNAME returned %#x\n", hr );
prop_range.diph.dwHow = DIPH_BYUSAGE; prop_range.diph.dwObj = MAKELONG( 0, 0 ); @@ -4225,6 +4257,20 @@ static void test_simple_joystick(void) ok( hr == DI_OK, "GetProperty DIPROP_RANGE returned %#x\n", hr ); ok( prop_range.lMin == 0, "got %d expected %d\n", prop_range.lMin, 0 ); ok( prop_range.lMax == 65535, "got %d expected %d\n", prop_range.lMax, 65535 ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr ); + todo_wine + ok( prop_range.lMin == -25, "got %d expected %d\n", prop_range.lMin, -25 ); + todo_wine + ok( prop_range.lMax == 56, "got %d expected %d\n", prop_range.lMax, 56 ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_PHYSICALRANGE, &prop_range.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr ); + todo_wine + ok( prop_range.lMin == -25, "got %d expected %d\n", prop_range.lMin, -25 ); + todo_wine + ok( prop_range.lMax == 56, "got %d expected %d\n", prop_range.lMax, 56 );
prop_pointer.diph.dwHow = DIPH_BYUSAGE; prop_pointer.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); @@ -4473,9 +4519,14 @@ static void test_simple_joystick(void)
hr = IDirectInputDevice8_Unacquire( device ); ok( hr == DI_OK, "Unacquire returned: %#x\n", hr ); + prop_dword.diph.dwHow = DIPH_BYUSAGE; + prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + prop_dword.dwData = 1; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr ); prop_dword.diph.dwHow = DIPH_DEVICE; prop_dword.diph.dwObj = 0; - prop_dword.dwData = 1; hr = IDirectInputDevice8_SetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph ); ok( hr == DI_OK, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr ); hr = IDirectInputDevice8_Acquire( device ); @@ -4764,6 +4815,21 @@ static void test_simple_joystick(void) prop_range.lMax = -4000; hr = IDirectInputDevice8_SetProperty( device, DIPROP_RANGE, &prop_range.diph ); ok( hr == DI_OK, "SetProperty DIPROP_RANGE returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph ); + todo_wine + ok( hr == DIERR_ACQUIRED, "SetProperty DIPROP_LOGICALRANGE returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_PHYSICALRANGE, &prop_range.diph ); + todo_wine + ok( hr == DIERR_ACQUIRED, "SetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr ); + + hr = IDirectInputDevice8_Unacquire( device ); + ok( hr == DI_OK, "Unacquire returned: %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph ); + ok( hr == DIERR_UNSUPPORTED, "SetProperty DIPROP_LOGICALRANGE returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_PHYSICALRANGE, &prop_range.diph ); + ok( hr == DIERR_UNSUPPORTED, "SetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr ); + hr = IDirectInputDevice8_Acquire( device ); + ok( hr == DI_OK, "Unacquire returned: %#x\n", hr );
prop_range.diph.dwHow = DIPH_DEVICE; prop_range.diph.dwObj = 0; @@ -4864,17 +4930,26 @@ static void test_simple_joystick(void) ok( hr == DIERR_INVALIDPARAM, "SetProperty DIPROP_DEADZONE returned %#x\n", hr ); hr = IDirectInputDevice8_SetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); ok( hr == DIERR_INVALIDPARAM, "SetProperty DIPROP_SATURATION returned %#x\n", hr ); + hr = IDirectInputDevice8_SetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_INVALIDPARAM, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); prop_dword.dwData = 1000; hr = IDirectInputDevice8_SetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); ok( hr == DI_OK, "SetProperty DIPROP_DEADZONE returned %#x\n", hr ); prop_dword.dwData = 6000; hr = IDirectInputDevice8_SetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); ok( hr == DI_OK, "SetProperty DIPROP_SATURATION returned %#x\n", hr ); + prop_dword.dwData = DIPROPCALIBRATIONMODE_COOKED; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr );
hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr );
prop_dword.diph.dwHow = DIPH_BYUSAGE; prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); @@ -4950,6 +5025,43 @@ static void test_simple_joystick(void) check_member( state, expect_state_abs[i], "%#x", rgbButtons[2] ); winetest_pop_context();
+ prop_dword.diph.dwHow = DIPH_BYUSAGE; + prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + prop_dword.dwData = DIPROPCALIBRATIONMODE_RAW; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == DIPROPCALIBRATIONMODE_RAW, "got %u expected %u\n", prop_dword.dwData, DIPROPCALIBRATIONMODE_RAW ); + + hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); + ok( hr == DI_OK, "GetDeviceState returned: %#x\n", hr ); + winetest_push_context( "state[%d]", i ); + todo_wine + ok( state.lX == 15, "got lX %d, expected %d\n" , state.lX, 15 ); + todo_wine + check_member( state, expect_state_abs[0], "%d", lY ); + check_member( state, expect_state_abs[0], "%d", lZ ); + check_member( state, expect_state_abs[0], "%d", lRx ); + todo_wine + check_member( state, expect_state_abs[0], "%d", rgdwPOV[0] ); + check_member( state, expect_state_abs[0], "%d", rgdwPOV[1] ); + winetest_pop_context(); + + prop_dword.dwData = DIPROPCALIBRATIONMODE_COOKED; + hr = IDirectInputDevice8_SetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); + + send_hid_input( file, &injected_input[ARRAY_SIZE(injected_input) - 1], sizeof(*injected_input) ); + res = WaitForSingleObject( event, 100 ); + todo_wine + ok( res == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); + hr = IDirectInputDevice8_Unacquire( device ); ok( hr == DI_OK, "Unacquire returned: %#x\n", hr );
As object properties.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 2 + dlls/dinput/device_private.h | 12 ++++ dlls/dinput/joystick_hid.c | 119 +++++++++++++++-------------------- 3 files changed, 66 insertions(+), 67 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index f21d951d268..a3dde86f8be 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -740,6 +740,7 @@ void dinput_device_destroy( IDirectInputDevice8W *iface )
TRACE( "iface %p.\n", iface );
+ free( This->object_properties ); free( This->data_queue );
/* Free data format */ @@ -1940,6 +1941,7 @@ HRESULT dinput_device_init( IDirectInputDevice8W *iface )
size = format->dwNumObjs * sizeof(*format->rgodf); if (!(format->rgodf = calloc( 1, size ))) return DIERR_OUTOFMEMORY; + format->dwSize = sizeof(*format); format->dwObjSize = sizeof(*format->rgodf); format->dwFlags = DIDF_ABSAXIS; diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index aeab89c840a..3e2942f71ef 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -57,6 +57,17 @@ struct dinput_device_vtbl
#define DEVICE_STATE_MAX_SIZE 1024
+struct object_properties +{ + LONG bit_size; + LONG logical_min; + LONG logical_max; + LONG range_min; + LONG range_max; + LONG deadzone; + LONG saturation; +}; + /* Device implementation */ struct dinput_device { @@ -100,6 +111,7 @@ struct dinput_device
BOOL autocenter; LONG device_gain; + struct object_properties *object_properties; };
extern HRESULT dinput_device_alloc( SIZE_T size, const struct dinput_device_vtbl *vtbl, const GUID *guid, diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 6cd537c5776..81b54ffe7a3 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -52,17 +52,6 @@ DEFINE_GUID( GUID_DEVINTERFACE_WINEXINPUT,0x6c53d5fd,0x6480,0x440f,0xb6,0x18,0x4 DEFINE_GUID( hid_joystick_guid, 0x9e573edb, 0x7734, 0x11d2, 0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7 ); DEFINE_DEVPROPKEY( DEVPROPKEY_HID_HANDLE, 0xbc62e415, 0xf4fe, 0x405c, 0x8e, 0xda, 0x63, 0x6f, 0xb5, 0x9f, 0x08, 0x98, 2 );
-struct extra_caps -{ - LONG bit_size; - LONG logical_min; - LONG logical_max; - LONG range_min; - LONG range_max; - LONG deadzone; - LONG saturation; -}; - struct pid_control_report { BYTE id; @@ -156,8 +145,6 @@ struct hid_joystick HIDD_ATTRIBUTES attrs; HIDP_CAPS caps;
- struct extra_caps *input_extra_caps; - char *input_report_buf; char *output_report_buf; USAGE_AND_PAGE *usages_buf; @@ -715,7 +702,6 @@ static void hid_joystick_release( IDirectInputDevice8W *iface ) free( impl->usages_buf ); free( impl->output_report_buf ); free( impl->input_report_buf ); - free( impl->input_extra_caps ); HidD_FreePreparsedData( impl->preparsed ); CloseHandle( impl->base.read_event ); CloseHandle( impl->device ); @@ -727,29 +713,29 @@ static HRESULT hid_joystick_get_property( IDirectInputDevice8W *iface, DWORD pro DIPROPHEADER *header, DIDEVICEOBJECTINSTANCEW *instance ) { struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); - struct extra_caps *extra = NULL; + struct object_properties *properties = NULL;
- if (instance) extra = impl->input_extra_caps + instance->dwOfs / sizeof(LONG); + if (instance) properties = impl->base.object_properties + instance->dwOfs / sizeof(LONG);
switch (property) { case (DWORD_PTR)DIPROP_RANGE: { DIPROPRANGE *value = (DIPROPRANGE *)header; - value->lMin = extra->range_min; - value->lMax = extra->range_max; + value->lMin = properties->range_min; + value->lMax = properties->range_max; return DI_OK; } case (DWORD_PTR)DIPROP_DEADZONE: { DIPROPDWORD *value = (DIPROPDWORD *)header; - value->dwData = extra->deadzone; + value->dwData = properties->deadzone; return DI_OK; } case (DWORD_PTR)DIPROP_SATURATION: { DIPROPDWORD *value = (DIPROPDWORD *)header; - value->dwData = extra->saturation; + value->dwData = properties->saturation; return DI_OK; } case (DWORD_PTR)DIPROP_GRANULARITY: @@ -797,22 +783,22 @@ static HRESULT hid_joystick_get_property( IDirectInputDevice8W *iface, DWORD pro static void set_extra_caps_range( struct hid_joystick *impl, const DIDEVICEOBJECTINSTANCEW *instance, LONG min, LONG max ) { - struct extra_caps *extra = impl->input_extra_caps + instance->dwOfs / sizeof(LONG); + struct object_properties *properties = impl->base.object_properties + instance->dwOfs / sizeof(LONG); LONG tmp;
- extra->range_min = min; - extra->range_max = max; + properties->range_min = min; + properties->range_max = max;
if (instance->dwType & DIDFT_AXIS) { - if (!extra->range_min) tmp = extra->range_max / 2; - else tmp = round( (extra->range_min + extra->range_max) / 2.0 ); + if (!properties->range_min) tmp = properties->range_max / 2; + else tmp = round( (properties->range_min + properties->range_max) / 2.0 ); *(LONG *)(impl->base.device_state + instance->dwOfs) = tmp; } else if (instance->dwType & DIDFT_POV) { - tmp = extra->logical_max - extra->logical_min; - if (tmp > 0) extra->range_max -= max / (tmp + 1); + tmp = properties->logical_max - properties->logical_min; + if (tmp > 0) properties->range_max -= max / (tmp + 1); *(LONG *)(impl->base.device_state + instance->dwOfs) = -1; } } @@ -842,9 +828,9 @@ static HRESULT hid_joystick_set_property( IDirectInputDevice8W *iface, DWORD pro const DIPROPHEADER *header, const DIDEVICEOBJECTINSTANCEW *instance ) { struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); - struct extra_caps *extra = NULL; + struct object_properties *properties = NULL;
- if (instance) extra = impl->input_extra_caps + instance->dwOfs / sizeof(LONG); + if (instance) properties = impl->base.object_properties + instance->dwOfs / sizeof(LONG);
switch (property) { @@ -857,13 +843,13 @@ static HRESULT hid_joystick_set_property( IDirectInputDevice8W *iface, DWORD pro case (DWORD_PTR)DIPROP_DEADZONE: { const DIPROPDWORD *value = (const DIPROPDWORD *)header; - extra->deadzone = value->dwData; + properties->deadzone = value->dwData; return DI_OK; } case (DWORD_PTR)DIPROP_SATURATION: { const DIPROPDWORD *value = (const DIPROPDWORD *)header; - extra->saturation = value->dwData; + properties->saturation = value->dwData; return DI_OK; } } @@ -1124,34 +1110,34 @@ static BOOL check_device_state_button( struct hid_joystick *impl, struct hid_val return DIENUM_CONTINUE; }
-static LONG sign_extend( ULONG value, struct extra_caps *caps ) +static LONG sign_extend( ULONG value, struct object_properties *properties ) { - UINT sign = 1 << (caps->bit_size - 1); - if (sign <= 1 || caps->logical_min >= 0) return value; + UINT sign = 1 << (properties->bit_size - 1); + if (sign <= 1 || properties->logical_min >= 0) return value; return value - ((value & sign) << 1); }
-static LONG scale_value( ULONG value, struct extra_caps *caps ) +static LONG scale_value( ULONG value, struct object_properties *properties ) { - LONG tmp = sign_extend( value, caps ), log_min, log_max, phy_min, phy_max; - log_min = caps->logical_min; - log_max = caps->logical_max; - phy_min = caps->range_min; - phy_max = caps->range_max; + LONG tmp = sign_extend( value, properties ), log_min, log_max, phy_min, phy_max; + log_min = properties->logical_min; + log_max = properties->logical_max; + phy_min = properties->range_min; + phy_max = properties->range_max;
if (log_min > tmp || log_max < tmp) return -1; /* invalid / null value */ return phy_min + MulDiv( tmp - log_min, phy_max - phy_min, log_max - log_min ); }
-static LONG scale_axis_value( ULONG value, struct extra_caps *caps ) +static LONG scale_axis_value( ULONG value, struct object_properties *properties ) { - LONG tmp = sign_extend( value, caps ), log_ctr, log_min, log_max, phy_ctr, phy_min, phy_max; - ULONG bit_max = (1 << caps->bit_size) - 1; + LONG tmp = sign_extend( value, properties ), log_ctr, log_min, log_max, phy_ctr, phy_min, phy_max; + ULONG bit_max = (1 << properties->bit_size) - 1;
- log_min = caps->logical_min; - log_max = caps->logical_max; - phy_min = caps->range_min; - phy_max = caps->range_max; + log_min = properties->logical_min; + log_max = properties->logical_max; + phy_min = properties->range_min; + phy_max = properties->range_max; /* xinput HID gamepad have bogus logical value range, let's use the bit range instead */ if (log_min == 0 && log_max == -1) log_max = bit_max;
@@ -1163,14 +1149,14 @@ static LONG scale_axis_value( ULONG value, struct extra_caps *caps ) tmp -= log_ctr; if (tmp <= 0) { - log_max = MulDiv( log_min - log_ctr, caps->deadzone, 10000 ); - log_min = MulDiv( log_min - log_ctr, caps->saturation, 10000 ); + log_max = MulDiv( log_min - log_ctr, properties->deadzone, 10000 ); + log_min = MulDiv( log_min - log_ctr, properties->saturation, 10000 ); phy_max = phy_ctr; } else { - log_min = MulDiv( log_max - log_ctr, caps->deadzone, 10000 ); - log_max = MulDiv( log_max - log_ctr, caps->saturation, 10000 ); + log_min = MulDiv( log_max - log_ctr, properties->deadzone, 10000 ); + log_max = MulDiv( log_max - log_ctr, properties->saturation, 10000 ); phy_min = phy_ctr; }
@@ -1182,7 +1168,7 @@ static LONG scale_axis_value( ULONG value, struct extra_caps *caps ) static BOOL read_device_state_value( struct hid_joystick *impl, struct hid_value_caps *caps, DIDEVICEOBJECTINSTANCEW *instance, void *data ) { - struct extra_caps *extra = impl->input_extra_caps + instance->dwOfs / sizeof(LONG); + struct object_properties *properties = impl->base.object_properties + instance->dwOfs / sizeof(LONG); IDirectInputDevice8W *iface = &impl->base.IDirectInputDevice8W_iface; ULONG logical_value, report_len = impl->caps.InputReportByteLength; struct parse_device_state_params *params = data; @@ -1196,8 +1182,8 @@ static BOOL read_device_state_value( struct hid_joystick *impl, struct hid_value &logical_value, impl->preparsed, report_buf, report_len ); if (status != HIDP_STATUS_SUCCESS) WARN( "HidP_GetUsageValue %04x:%04x returned %#x\n", instance->wUsagePage, instance->wUsage, status ); - if (instance->dwType & DIDFT_AXIS) value = scale_axis_value( logical_value, extra ); - else value = scale_value( logical_value, extra ); + if (instance->dwType & DIDFT_AXIS) value = scale_axis_value( logical_value, properties ); + else value = scale_value( logical_value, properties );
old_value = *(LONG *)(params->old_state + instance->dwOfs); *(LONG *)(impl->base.device_state + instance->dwOfs) = value; @@ -1578,16 +1564,16 @@ HRESULT hid_joystick_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *in return DI_OK; }
-static BOOL init_extra_caps( struct hid_joystick *impl, struct hid_value_caps *caps, - DIDEVICEOBJECTINSTANCEW *instance, void *data ) +static BOOL init_object_properties( struct hid_joystick *impl, struct hid_value_caps *caps, + DIDEVICEOBJECTINSTANCEW *instance, void *data ) { - struct extra_caps *extra = impl->input_extra_caps + instance->dwOfs / sizeof(LONG); + struct object_properties *properties = impl->base.object_properties + instance->dwOfs / sizeof(LONG); LONG range_max = (instance->dwType & DIDFT_AXIS) ? 65535 : 36000; - extra->bit_size = caps->bit_size; - extra->logical_min = caps->logical_min; - extra->logical_max = caps->logical_max; + properties->bit_size = caps->bit_size; + properties->logical_min = caps->logical_min; + properties->logical_max = caps->logical_max; set_extra_caps_range( impl, instance, 0, range_max ); - extra->saturation = 10000; + properties->saturation = 10000; return DIENUM_CONTINUE; }
@@ -1870,9 +1856,9 @@ HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID *guid, }, }; HIDD_ATTRIBUTES attrs = {.Size = sizeof(attrs)}; + struct object_properties *object_properties; struct hid_preparsed_data *preparsed; struct hid_joystick *impl = NULL; - struct extra_caps *extra; USAGE_AND_PAGE *usages; char *buffer; HRESULT hr; @@ -1907,11 +1893,10 @@ HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID *guid, list_init( &impl->effect_list );
preparsed = (struct hid_preparsed_data *)impl->preparsed; - - size = preparsed->input_caps_count * sizeof(struct extra_caps); - if (!(extra = calloc( 1, size ))) goto failed; - impl->input_extra_caps = extra; - enum_objects( impl, &filter, DIDFT_AXIS | DIDFT_POV, init_extra_caps, NULL ); + size = preparsed->input_caps_count * sizeof(struct object_properties); + if (!(object_properties = calloc( 1, size ))) goto failed; + impl->base.object_properties = object_properties; + enum_objects( impl, &filter, DIDFT_AXIS | DIDFT_POV, init_object_properties, NULL );
size = impl->caps.InputReportByteLength; if (!(buffer = malloc( size ))) goto failed;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 39 ++++++++++++++++++++++++++++++++++++++ dlls/dinput/joystick_hid.c | 9 +-------- 2 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index a3dde86f8be..c4d40e1278b 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -27,6 +27,7 @@
#include <stdarg.h> #include <string.h> +#include <math.h>
#include "windef.h" #include "winbase.h" @@ -1037,6 +1038,39 @@ static BOOL CALLBACK set_object_property( const DIDEVICEOBJECTINSTANCEW *instanc return DIENUM_CONTINUE; }
+static BOOL CALLBACK reset_object_value( const DIDEVICEOBJECTINSTANCEW *instance, void *context ) +{ + struct dinput_device *impl = context; + struct object_properties *properties; + LONG tmp = -1; + + if (!impl->object_properties) return DIENUM_STOP; + properties = impl->object_properties + instance->dwOfs / sizeof(LONG); + + if (instance->dwType & DIDFT_AXIS) + { + if (!properties->range_min) tmp = properties->range_max / 2; + else tmp = round( (properties->range_min + properties->range_max) / 2.0 ); + } + + *(LONG *)(impl->device_state + instance->dwOfs) = tmp; + return DIENUM_CONTINUE; +} + +static void reset_device_state( IDirectInputDevice8W *iface ) +{ + struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); + DIPROPHEADER filter = + { + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + .dwObj = 0, + }; + + impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS | DIDFT_POV, reset_object_value, impl ); +} + static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, const GUID *guid, const DIPROPHEADER *header ) { @@ -1065,6 +1099,7 @@ static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, co if (value->lMin > value->lMax) return DIERR_INVALIDPARAM; hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, set_object_property, ¶ms ); if (FAILED(hr)) return hr; + reset_device_state( iface ); return DI_OK; } case (DWORD_PTR)DIPROP_DEADZONE: @@ -1075,6 +1110,7 @@ static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, co if (value->dwData > 10000) return DIERR_INVALIDPARAM; hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, set_object_property, ¶ms ); if (FAILED(hr)) return hr; + reset_device_state( iface ); return DI_OK; } case (DWORD_PTR)DIPROP_AUTOCENTER: @@ -1922,6 +1958,9 @@ static BOOL CALLBACK enum_objects_init( const DIDEVICEOBJECTINSTANCEW *instance, obj_format->dwFlags = instance->dwFlags; }
+ if (impl->object_properties && (instance->dwType & (DIDFT_AXIS | DIDFT_POV))) + reset_object_value( instance, impl ); + format->dwNumObjs++; return DIENUM_CONTINUE; } diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 81b54ffe7a3..b252b9a13c9 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -789,17 +789,10 @@ static void set_extra_caps_range( struct hid_joystick *impl, const DIDEVICEOBJEC properties->range_min = min; properties->range_max = max;
- if (instance->dwType & DIDFT_AXIS) - { - if (!properties->range_min) tmp = properties->range_max / 2; - else tmp = round( (properties->range_min + properties->range_max) / 2.0 ); - *(LONG *)(impl->base.device_state + instance->dwOfs) = tmp; - } - else if (instance->dwType & DIDFT_POV) + if (instance->dwType & DIDFT_POV) { tmp = properties->logical_max - properties->logical_min; if (tmp > 0) properties->range_max -= max / (tmp + 1); - *(LONG *)(impl->base.device_state + instance->dwOfs) = -1; } }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 111 +++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 52 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index c4d40e1278b..9bf52cad2ec 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -911,7 +911,7 @@ static BOOL CALLBACK find_object( const DIDEVICEOBJECTINSTANCEW *instance, void return DIENUM_STOP; }
-static HRESULT WINAPI dinput_device_GetProperty( IDirectInputDevice8W *iface, const GUID *guid, DIPROPHEADER *header ) +static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GUID *guid, DIPROPHEADER *header ) { struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); DWORD object_mask = DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV; @@ -919,12 +919,6 @@ static HRESULT WINAPI dinput_device_GetProperty( IDirectInputDevice8W *iface, co DIPROPHEADER filter; HRESULT hr;
- TRACE( "iface %p, guid %s, header %p\n", iface, debugstr_guid( guid ), header ); - - if (!header) return DIERR_INVALIDPARAM; - if (header->dwHeaderSize != sizeof(DIPROPHEADER)) return DIERR_INVALIDPARAM; - if (!IS_DIPROP( guid )) return DI_OK; - filter = *header; if (FAILED(hr = enum_object_filter_init( impl, &filter ))) return hr;
@@ -1023,6 +1017,24 @@ static HRESULT WINAPI dinput_device_GetProperty( IDirectInputDevice8W *iface, co return DI_OK; }
+static HRESULT WINAPI dinput_device_GetProperty( IDirectInputDevice8W *iface, const GUID *guid, DIPROPHEADER *header ) +{ + struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); + HRESULT hr; + + TRACE( "iface %p, guid %s, header %p\n", iface, debugstr_guid( guid ), header ); + + if (!header) return DIERR_INVALIDPARAM; + if (header->dwHeaderSize != sizeof(DIPROPHEADER)) return DIERR_INVALIDPARAM; + if (!IS_DIPROP( guid )) return DI_OK; + + EnterCriticalSection( &impl->crit ); + hr = dinput_device_get_property( iface, guid, header ); + LeaveCriticalSection( &impl->crit ); + + return hr; +} + struct set_object_property_params { IDirectInputDevice8W *iface; @@ -1071,8 +1083,8 @@ static void reset_device_state( IDirectInputDevice8W *iface ) impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS | DIDFT_POV, reset_object_value, impl ); }
-static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, const GUID *guid, - const DIPROPHEADER *header ) +static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, const GUID *guid, + const DIPROPHEADER *header ) { struct set_object_property_params params = {.iface = iface, .header = header, .property = LOWORD( guid )}; struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); @@ -1081,12 +1093,6 @@ static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, co DIPROPHEADER filter; HRESULT hr;
- TRACE( "iface %p, guid %s, header %p\n", iface, debugstr_guid( guid ), header ); - - if (!header) return DIERR_INVALIDPARAM; - if (header->dwHeaderSize != sizeof(DIPROPHEADER)) return DIERR_INVALIDPARAM; - if (!IS_DIPROP( guid )) return DI_OK; - filter = *header; if (FAILED(hr = enum_object_filter_init( impl, &filter ))) return hr;
@@ -1118,18 +1124,13 @@ static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, co const DIPROPDWORD *value = (const DIPROPDWORD *)header; if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; - EnterCriticalSection( &impl->crit ); - if (impl->acquired) hr = DIERR_ACQUIRED; - else if (value->dwData > DIPROPAUTOCENTER_ON) hr = DIERR_INVALIDPARAM; - else if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) hr = DIERR_UNSUPPORTED; - else - { - FIXME( "DIPROP_AUTOCENTER stub!\n" ); - impl->autocenter = value->dwData; - hr = DI_OK; - } - LeaveCriticalSection( &impl->crit ); - return hr; + if (impl->acquired) return DIERR_ACQUIRED; + if (value->dwData > DIPROPAUTOCENTER_ON) return DIERR_INVALIDPARAM; + if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) return DIERR_UNSUPPORTED; + + FIXME( "DIPROP_AUTOCENTER stub!\n" ); + impl->autocenter = value->dwData; + return DI_OK; } case (DWORD_PTR)DIPROP_FFGAIN: { @@ -1138,12 +1139,9 @@ static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, co if (!impl->vtbl->send_device_gain) return DIERR_UNSUPPORTED; if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; if (value->dwData > 10000) return DIERR_INVALIDPARAM; - EnterCriticalSection( &impl->crit ); impl->device_gain = value->dwData; - if (!impl->acquired || !(impl->dwCoopLevel & DISCL_EXCLUSIVE)) hr = DI_OK; - else hr = impl->vtbl->send_device_gain( iface, impl->device_gain ); - LeaveCriticalSection( &impl->crit ); - return hr; + if (!impl->acquired || !(impl->dwCoopLevel & DISCL_EXCLUSIVE)) return DI_OK; + return impl->vtbl->send_device_gain( iface, impl->device_gain ); } case (DWORD_PTR)DIPROP_FFLOAD: case (DWORD_PTR)DIPROP_GRANULARITY: @@ -1163,41 +1161,31 @@ static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, co if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; if (header->dwHow == DIPH_DEVICE && header->dwObj) return DIERR_INVALIDPARAM; + if (impl->acquired) return DIERR_ACQUIRED;
TRACE( "Axis mode: %s\n", value->dwData == DIPROPAXISMODE_ABS ? "absolute" : "relative" ); - EnterCriticalSection( &impl->crit ); - if (impl->acquired) hr = DIERR_ACQUIRED; - else if (!impl->user_format) hr = DI_OK; - else + if (impl->user_format) { impl->user_format->dwFlags &= ~DIDFT_AXIS; impl->user_format->dwFlags |= value->dwData == DIPROPAXISMODE_ABS ? DIDF_ABSAXIS : DIDF_RELAXIS; - hr = DI_OK; } - LeaveCriticalSection( &impl->crit ); - return hr; + return DI_OK; } case (DWORD_PTR)DIPROP_BUFFERSIZE: { const DIPROPDWORD *value = (const DIPROPDWORD *)header; if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; + if (impl->acquired) return DIERR_ACQUIRED;
TRACE( "buffersize = %d\n", value->dwData );
- EnterCriticalSection( &impl->crit ); - if (impl->acquired) hr = DIERR_ACQUIRED; - else - { - impl->buffersize = value->dwData; - impl->queue_len = min( impl->buffersize, 1024 ); - free( impl->data_queue ); + impl->buffersize = value->dwData; + impl->queue_len = min( impl->buffersize, 1024 ); + free( impl->data_queue );
- impl->data_queue = impl->queue_len ? malloc( impl->queue_len * sizeof(DIDEVICEOBJECTDATA) ) : NULL; - impl->queue_head = impl->queue_tail = impl->overflow = 0; - hr = DI_OK; - } - LeaveCriticalSection( &impl->crit ); - return hr; + impl->data_queue = impl->queue_len ? malloc( impl->queue_len * sizeof(DIDEVICEOBJECTDATA) ) : NULL; + impl->queue_head = impl->queue_tail = impl->overflow = 0; + return DI_OK; } case (DWORD_PTR)DIPROP_APPDATA: { @@ -1220,6 +1208,25 @@ static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, co return DI_OK; }
+static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, const GUID *guid, + const DIPROPHEADER *header ) +{ + struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); + HRESULT hr; + + TRACE( "iface %p, guid %s, header %p\n", iface, debugstr_guid( guid ), header ); + + if (!header) return DIERR_INVALIDPARAM; + if (header->dwHeaderSize != sizeof(DIPROPHEADER)) return DIERR_INVALIDPARAM; + if (!IS_DIPROP( guid )) return DI_OK; + + EnterCriticalSection( &impl->crit ); + hr = dinput_device_set_property( iface, guid, header ); + LeaveCriticalSection( &impl->crit ); + + return hr; +} + static void dinput_device_set_username( struct dinput_device *impl, const DIPROPSTRING *value ) { struct DevicePlayer *device_player;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 189 ++++++++++++++++++++++++++------------- dlls/dinput8/tests/hid.c | 3 - 2 files changed, 125 insertions(+), 67 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 9bf52cad2ec..ee47ff60e4f 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -905,6 +905,127 @@ static HRESULT enum_object_filter_init( struct dinput_device *impl, DIPROPHEADER return DI_OK; }
+static HRESULT check_property( struct dinput_device *impl, const GUID *guid, const DIPROPHEADER *header, BOOL set ) +{ + switch (LOWORD( guid )) + { + case (DWORD_PTR)DIPROP_INSTANCENAME: + case (DWORD_PTR)DIPROP_KEYNAME: + case (DWORD_PTR)DIPROP_PRODUCTNAME: + case (DWORD_PTR)DIPROP_TYPENAME: + case (DWORD_PTR)DIPROP_USERNAME: + if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM; + break; + + case (DWORD_PTR)DIPROP_AUTOCENTER: + case (DWORD_PTR)DIPROP_AXISMODE: + case (DWORD_PTR)DIPROP_BUFFERSIZE: + case (DWORD_PTR)DIPROP_DEADZONE: + case (DWORD_PTR)DIPROP_FFGAIN: + case (DWORD_PTR)DIPROP_FFLOAD: + case (DWORD_PTR)DIPROP_GRANULARITY: + case (DWORD_PTR)DIPROP_JOYSTICKID: + case (DWORD_PTR)DIPROP_SATURATION: + case (DWORD_PTR)DIPROP_SCANCODE: + case (DWORD_PTR)DIPROP_VIDPID: + if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; + break; + + case (DWORD_PTR)DIPROP_APPDATA: + if (header->dwSize != sizeof(DIPROPPOINTER)) return DIERR_INVALIDPARAM; + break; + + case (DWORD_PTR)DIPROP_RANGE: + if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM; + break; + + case (DWORD_PTR)DIPROP_GUIDANDPATH: + if (header->dwSize != sizeof(DIPROPGUIDANDPATH)) return DIERR_INVALIDPARAM; + break; + } + + switch (LOWORD( guid )) + { + case (DWORD_PTR)DIPROP_PRODUCTNAME: + case (DWORD_PTR)DIPROP_INSTANCENAME: + case (DWORD_PTR)DIPROP_VIDPID: + case (DWORD_PTR)DIPROP_JOYSTICKID: + case (DWORD_PTR)DIPROP_GUIDANDPATH: + case (DWORD_PTR)DIPROP_BUFFERSIZE: + case (DWORD_PTR)DIPROP_FFGAIN: + case (DWORD_PTR)DIPROP_TYPENAME: + case (DWORD_PTR)DIPROP_USERNAME: + case (DWORD_PTR)DIPROP_AUTOCENTER: + case (DWORD_PTR)DIPROP_AXISMODE: + case (DWORD_PTR)DIPROP_FFLOAD: + if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; + if (header->dwObj) return DIERR_INVALIDPARAM; + break; + + case (DWORD_PTR)DIPROP_RANGE: + case (DWORD_PTR)DIPROP_DEADZONE: + case (DWORD_PTR)DIPROP_SATURATION: + case (DWORD_PTR)DIPROP_GRANULARITY: + if (header->dwHow == DIPH_DEVICE && !set) return DIERR_UNSUPPORTED; + break; + + case (DWORD_PTR)DIPROP_KEYNAME: + if (header->dwHow == DIPH_DEVICE) return DIERR_INVALIDPARAM; + break; + + case (DWORD_PTR)DIPROP_SCANCODE: + case (DWORD_PTR)DIPROP_APPDATA: + if (header->dwHow == DIPH_DEVICE) return DIERR_UNSUPPORTED; + break; + } + + if (set) + { + switch (LOWORD( guid )) + { + case (DWORD_PTR)DIPROP_AUTOCENTER: + case (DWORD_PTR)DIPROP_AXISMODE: + case (DWORD_PTR)DIPROP_BUFFERSIZE: + if (impl->acquired) return DIERR_ACQUIRED; + break; + case (DWORD_PTR)DIPROP_FFLOAD: + case (DWORD_PTR)DIPROP_GRANULARITY: + case (DWORD_PTR)DIPROP_VIDPID: + case (DWORD_PTR)DIPROP_TYPENAME: + case (DWORD_PTR)DIPROP_USERNAME: + case (DWORD_PTR)DIPROP_GUIDANDPATH: + return DIERR_READONLY; + } + + switch (LOWORD( guid )) + { + case (DWORD_PTR)DIPROP_RANGE: + { + const DIPROPRANGE *value = (const DIPROPRANGE *)header; + if (value->lMin > value->lMax) return DIERR_INVALIDPARAM; + break; + } + case (DWORD_PTR)DIPROP_DEADZONE: + case (DWORD_PTR)DIPROP_SATURATION: + case (DWORD_PTR)DIPROP_FFGAIN: + { + const DIPROPDWORD *value = (const DIPROPDWORD *)header; + if (value->dwData > 10000) return DIERR_INVALIDPARAM; + break; + } + case (DWORD_PTR)DIPROP_AUTOCENTER: + case (DWORD_PTR)DIPROP_AXISMODE: + { + const DIPROPDWORD *value = (const DIPROPDWORD *)header; + if (value->dwData > 1) return DIERR_INVALIDPARAM; + break; + } + } + } + + return DI_OK; +} + static BOOL CALLBACK find_object( const DIDEVICEOBJECTINSTANCEW *instance, void *context ) { *(DIDEVICEOBJECTINSTANCEW *)context = *instance; @@ -921,40 +1042,21 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU
filter = *header; if (FAILED(hr = enum_object_filter_init( impl, &filter ))) return hr; + if (FAILED(hr = check_property( impl, guid, header, FALSE ))) return hr;
switch (LOWORD( guid )) { case (DWORD_PTR)DIPROP_PRODUCTNAME: case (DWORD_PTR)DIPROP_INSTANCENAME: - if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM; - if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; - return impl->vtbl->get_property( iface, LOWORD( guid ), header, NULL ); - case (DWORD_PTR)DIPROP_VIDPID: case (DWORD_PTR)DIPROP_JOYSTICKID: - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; - if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; - return impl->vtbl->get_property( iface, LOWORD( guid ), header, NULL ); - case (DWORD_PTR)DIPROP_GUIDANDPATH: - if (header->dwSize != sizeof(DIPROPGUIDANDPATH)) return DIERR_INVALIDPARAM; - if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; return impl->vtbl->get_property( iface, LOWORD( guid ), header, NULL );
case (DWORD_PTR)DIPROP_RANGE: - if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM; - if (header->dwHow == DIPH_DEVICE) return DIERR_UNSUPPORTED; - hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance ); - if (FAILED(hr)) return hr; - if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; - if (!(instance.dwType & DIDFT_AXIS)) return DIERR_UNSUPPORTED; - return impl->vtbl->get_property( iface, LOWORD( guid ), header, &instance ); - case (DWORD_PTR)DIPROP_DEADZONE: case (DWORD_PTR)DIPROP_SATURATION: case (DWORD_PTR)DIPROP_GRANULARITY: - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; - if (header->dwHow == DIPH_DEVICE) return DIERR_UNSUPPORTED; hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance ); if (FAILED(hr)) return hr; if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; @@ -962,7 +1064,6 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU return impl->vtbl->get_property( iface, LOWORD( guid ), header, &instance );
case (DWORD_PTR)DIPROP_KEYNAME: - if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM; hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance ); if (FAILED(hr)) return hr; if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; @@ -972,7 +1073,6 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU case (DWORD_PTR)DIPROP_AUTOCENTER: { DIPROPDWORD *value = (DIPROPDWORD *)header; - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) return DIERR_UNSUPPORTED; value->dwData = impl->autocenter; return DI_OK; @@ -980,7 +1080,6 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU case (DWORD_PTR)DIPROP_BUFFERSIZE: { DIPROPDWORD *value = (DIPROPDWORD *)header; - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; value->dwData = impl->buffersize; return DI_OK; } @@ -988,7 +1087,6 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU { DIPROPSTRING *value = (DIPROPSTRING *)header; struct DevicePlayer *device_player; - if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM; LIST_FOR_EACH_ENTRY( device_player, &impl->dinput->device_players, struct DevicePlayer, entry ) { if (IsEqualGUID( &device_player->instance_guid, &impl->guid )) @@ -1003,7 +1101,6 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU case (DWORD_PTR)DIPROP_FFGAIN: { DIPROPDWORD *value = (DIPROPDWORD *)header; - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; value->dwData = impl->device_gain; return DI_OK; } @@ -1095,25 +1192,14 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c
filter = *header; if (FAILED(hr = enum_object_filter_init( impl, &filter ))) return hr; + if (FAILED(hr = check_property( impl, guid, header, TRUE ))) return hr;
switch (LOWORD( guid )) { case (DWORD_PTR)DIPROP_RANGE: - { - const DIPROPRANGE *value = (const DIPROPRANGE *)header; - if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM; - if (value->lMin > value->lMax) return DIERR_INVALIDPARAM; - hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, set_object_property, ¶ms ); - if (FAILED(hr)) return hr; - reset_device_state( iface ); - return DI_OK; - } case (DWORD_PTR)DIPROP_DEADZONE: case (DWORD_PTR)DIPROP_SATURATION: { - const DIPROPDWORD *value = (const DIPROPDWORD *)header; - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; - if (value->dwData > 10000) return DIERR_INVALIDPARAM; hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, set_object_property, ¶ms ); if (FAILED(hr)) return hr; reset_device_state( iface ); @@ -1122,10 +1208,6 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c case (DWORD_PTR)DIPROP_AUTOCENTER: { const DIPROPDWORD *value = (const DIPROPDWORD *)header; - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; - if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; - if (impl->acquired) return DIERR_ACQUIRED; - if (value->dwData > DIPROPAUTOCENTER_ON) return DIERR_INVALIDPARAM; if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) return DIERR_UNSUPPORTED;
FIXME( "DIPROP_AUTOCENTER stub!\n" ); @@ -1135,33 +1217,14 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c case (DWORD_PTR)DIPROP_FFGAIN: { const DIPROPDWORD *value = (const DIPROPDWORD *)header; - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; if (!impl->vtbl->send_device_gain) return DIERR_UNSUPPORTED; - if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; - if (value->dwData > 10000) return DIERR_INVALIDPARAM; impl->device_gain = value->dwData; if (!impl->acquired || !(impl->dwCoopLevel & DISCL_EXCLUSIVE)) return DI_OK; return impl->vtbl->send_device_gain( iface, impl->device_gain ); } - case (DWORD_PTR)DIPROP_FFLOAD: - case (DWORD_PTR)DIPROP_GRANULARITY: - case (DWORD_PTR)DIPROP_VIDPID: - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; - return DIERR_READONLY; - case (DWORD_PTR)DIPROP_TYPENAME: - case (DWORD_PTR)DIPROP_USERNAME: - if (header->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM; - return DIERR_READONLY; - case (DWORD_PTR)DIPROP_GUIDANDPATH: - if (header->dwSize != sizeof(DIPROPGUIDANDPATH)) return DIERR_INVALIDPARAM; - return DIERR_READONLY; case (DWORD_PTR)DIPROP_AXISMODE: { const DIPROPDWORD *value = (const DIPROPDWORD *)header; - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; - if (header->dwHow != DIPH_DEVICE) return DIERR_UNSUPPORTED; - if (header->dwHow == DIPH_DEVICE && header->dwObj) return DIERR_INVALIDPARAM; - if (impl->acquired) return DIERR_ACQUIRED;
TRACE( "Axis mode: %s\n", value->dwData == DIPROPAXISMODE_ABS ? "absolute" : "relative" ); if (impl->user_format) @@ -1174,8 +1237,6 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c case (DWORD_PTR)DIPROP_BUFFERSIZE: { const DIPROPDWORD *value = (const DIPROPDWORD *)header; - if (header->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; - if (impl->acquired) return DIERR_ACQUIRED;
TRACE( "buffersize = %d\n", value->dwData );
@@ -1191,8 +1252,6 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c { const DIPROPPOINTER *value = (const DIPROPPOINTER *)header; int user_offset; - if (header->dwSize != sizeof(DIPROPPOINTER)) return DIERR_INVALIDPARAM; - if (header->dwHow == DIPH_DEVICE) return DIERR_UNSUPPORTED; hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance ); if (FAILED(hr)) return hr; if (hr == DIENUM_CONTINUE) return DIERR_OBJECTNOTFOUND; @@ -1812,6 +1871,7 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D dpr.lMin = format->lAxisMin; dpr.lMax = format->lAxisMax; dpr.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dpr.diph.dwObj = 0; dpr.diph.dwHow = DIPH_DEVICE; IDirectInputDevice8_SetProperty( iface, DIPROP_RANGE, &dpr.diph );
@@ -1820,6 +1880,7 @@ static HRESULT WINAPI dinput_device_SetActionMap( IDirectInputDevice8W *iface, D dp.diph.dwSize = sizeof(DIPROPDWORD); dp.dwData = format->dwBufferSize; dp.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dp.diph.dwObj = 0; dp.diph.dwHow = DIPH_DEVICE; IDirectInputDevice8_SetProperty( iface, DIPROP_BUFFERSIZE, &dp.diph ); } diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 355dc8ff855..8c347dc009a 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -4193,7 +4193,6 @@ static void test_simple_joystick(void) hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_RANGE returned %#x\n", hr ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_KEYNAME, &prop_string.diph ); - todo_wine ok( hr == DIERR_INVALIDPARAM, "GetProperty DIPROP_KEYNAME returned %#x\n", hr ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph ); ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr ); @@ -4523,7 +4522,6 @@ static void test_simple_joystick(void) prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); prop_dword.dwData = 1; hr = IDirectInputDevice8_SetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph ); - todo_wine ok( hr == DIERR_UNSUPPORTED, "SetProperty DIPROP_BUFFERSIZE returned %#x\n", hr ); prop_dword.diph.dwHow = DIPH_DEVICE; prop_dword.diph.dwObj = 0; @@ -5086,7 +5084,6 @@ static void test_simple_joystick(void)
prop_dword.dwData = 0xdeadbeef; hr = IDirectInputDevice8_SetProperty( device, DIPROP_AXISMODE, &prop_dword.diph ); - todo_wine ok( hr == DIERR_INVALIDPARAM, "SetProperty DIPROP_AXISMODE returned %#x\n", hr ); prop_dword.dwData = DIPROPAXISMODE_REL; hr = IDirectInputDevice8_SetProperty( device, DIPROP_AXISMODE, &prop_dword.diph );
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 31 ++++++++++++++++-- dlls/dinput/device_private.h | 2 -- dlls/dinput/joystick_hid.c | 63 +++++++----------------------------- dlls/dinput/keyboard.c | 7 ---- dlls/dinput/mouse.c | 7 ---- 5 files changed, 40 insertions(+), 70 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index ee47ff60e4f..2367023175c 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1143,8 +1143,35 @@ static BOOL CALLBACK set_object_property( const DIDEVICEOBJECTINSTANCEW *instanc { struct set_object_property_params *params = context; struct dinput_device *impl = impl_from_IDirectInputDevice8W( params->iface ); - impl->vtbl->set_property( params->iface, params->property, params->header, instance ); - return DIENUM_CONTINUE; + struct object_properties *properties = NULL; + + if (!impl->object_properties) return DIENUM_STOP; + properties = impl->object_properties + instance->dwOfs / sizeof(LONG); + + switch (params->property) + { + case (DWORD_PTR)DIPROP_RANGE: + { + const DIPROPRANGE *value = (const DIPROPRANGE *)params->header; + properties->range_min = value->lMin; + properties->range_max = value->lMax; + return DIENUM_CONTINUE; + } + case (DWORD_PTR)DIPROP_DEADZONE: + { + const DIPROPDWORD *value = (const DIPROPDWORD *)params->header; + properties->deadzone = value->dwData; + return DIENUM_CONTINUE; + } + case (DWORD_PTR)DIPROP_SATURATION: + { + const DIPROPDWORD *value = (const DIPROPDWORD *)params->header; + properties->saturation = value->dwData; + return DIENUM_CONTINUE; + } + } + + return DIENUM_STOP; }
static BOOL CALLBACK reset_object_value( const DIDEVICEOBJECTINSTANCEW *instance, void *context ) diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index 3e2942f71ef..6d24e66bb54 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -45,8 +45,6 @@ struct dinput_device_vtbl LPDIENUMDEVICEOBJECTSCALLBACKW callback, void *context ); HRESULT (*get_property)( IDirectInputDevice8W *iface, DWORD property, DIPROPHEADER *header, DIDEVICEOBJECTINSTANCEW *instance ); - HRESULT (*set_property)( IDirectInputDevice8W *iface, DWORD property, const DIPROPHEADER *header, - const DIDEVICEOBJECTINSTANCEW *instance ); HRESULT (*get_effect_info)( IDirectInputDevice8W *iface, DIEFFECTINFOW *info, const GUID *guid ); HRESULT (*create_effect)( IDirectInputDevice8W *iface, IDirectInputEffect **out ); HRESULT (*send_force_feedback_command)( IDirectInputDevice8W *iface, DWORD command, BOOL unacquire ); diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index b252b9a13c9..56e4c38c31a 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -780,22 +780,6 @@ static HRESULT hid_joystick_get_property( IDirectInputDevice8W *iface, DWORD pro return DIERR_UNSUPPORTED; }
-static void set_extra_caps_range( struct hid_joystick *impl, const DIDEVICEOBJECTINSTANCEW *instance, - LONG min, LONG max ) -{ - struct object_properties *properties = impl->base.object_properties + instance->dwOfs / sizeof(LONG); - LONG tmp; - - properties->range_min = min; - properties->range_max = max; - - if (instance->dwType & DIDFT_POV) - { - tmp = properties->logical_max - properties->logical_min; - if (tmp > 0) properties->range_max -= max / (tmp + 1); - } -} - static HRESULT hid_joystick_send_device_gain( IDirectInputDevice8W *iface, LONG device_gain ) { struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); @@ -817,39 +801,6 @@ static HRESULT hid_joystick_send_device_gain( IDirectInputDevice8W *iface, LONG return DI_OK; }
-static HRESULT hid_joystick_set_property( IDirectInputDevice8W *iface, DWORD property, - const DIPROPHEADER *header, const DIDEVICEOBJECTINSTANCEW *instance ) -{ - struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); - struct object_properties *properties = NULL; - - if (instance) properties = impl->base.object_properties + instance->dwOfs / sizeof(LONG); - - switch (property) - { - case (DWORD_PTR)DIPROP_RANGE: - { - const DIPROPRANGE *value = (const DIPROPRANGE *)header; - set_extra_caps_range( impl, instance, value->lMin, value->lMax ); - return DI_OK; - } - case (DWORD_PTR)DIPROP_DEADZONE: - { - const DIPROPDWORD *value = (const DIPROPDWORD *)header; - properties->deadzone = value->dwData; - return DI_OK; - } - case (DWORD_PTR)DIPROP_SATURATION: - { - const DIPROPDWORD *value = (const DIPROPDWORD *)header; - properties->saturation = value->dwData; - return DI_OK; - } - } - - return DIERR_UNSUPPORTED; -} - static HRESULT hid_joystick_acquire( IDirectInputDevice8W *iface ) { struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); @@ -1301,7 +1252,6 @@ static const struct dinput_device_vtbl hid_joystick_vtbl = hid_joystick_unacquire, hid_joystick_enum_objects, hid_joystick_get_property, - hid_joystick_set_property, hid_joystick_get_effect_info, hid_joystick_create_effect, hid_joystick_send_force_feedback_command, @@ -1561,11 +1511,20 @@ static BOOL init_object_properties( struct hid_joystick *impl, struct hid_value_ DIDEVICEOBJECTINSTANCEW *instance, void *data ) { struct object_properties *properties = impl->base.object_properties + instance->dwOfs / sizeof(LONG); - LONG range_max = (instance->dwType & DIDFT_AXIS) ? 65535 : 36000; + LONG tmp; + properties->bit_size = caps->bit_size; properties->logical_min = caps->logical_min; properties->logical_max = caps->logical_max; - set_extra_caps_range( impl, instance, 0, range_max ); + + if (instance->dwType & DIDFT_AXIS) properties->range_max = 65535; + else + { + properties->range_max = 36000; + tmp = caps->logical_max - caps->logical_min; + if (tmp > 0) properties->range_max -= 36000 / (tmp + 1); + } + properties->saturation = 10000; return DIENUM_CONTINUE; } diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 916a1d43233..2afb744d520 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -274,12 +274,6 @@ static HRESULT keyboard_get_property( IDirectInputDevice8W *iface, DWORD propert return DIERR_UNSUPPORTED; }
-static HRESULT keyboard_set_property( IDirectInputDevice8W *iface, DWORD property, - const DIPROPHEADER *header, const DIDEVICEOBJECTINSTANCEW *instance ) -{ - return DIERR_UNSUPPORTED; -} - static const struct dinput_device_vtbl keyboard_vtbl = { NULL, @@ -289,7 +283,6 @@ static const struct dinput_device_vtbl keyboard_vtbl = keyboard_unacquire, keyboard_enum_objects, keyboard_get_property, - keyboard_set_property, NULL, NULL, NULL, diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 313ac070c86..94cca61a0d0 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -576,12 +576,6 @@ static HRESULT mouse_get_property( IDirectInputDevice8W *iface, DWORD property, return DIERR_UNSUPPORTED; }
-static HRESULT mouse_set_property( IDirectInputDevice8W *iface, DWORD property, - const DIPROPHEADER *header, const DIDEVICEOBJECTINSTANCEW *instance ) -{ - return DIERR_UNSUPPORTED; -} - static const struct dinput_device_vtbl mouse_vtbl = { NULL, @@ -591,7 +585,6 @@ static const struct dinput_device_vtbl mouse_vtbl = mouse_unacquire, mouse_enum_objects, mouse_get_property, - mouse_set_property, NULL, NULL, NULL,
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 100 +++++++++++++++++++++++++++++++---- dlls/dinput/device_private.h | 3 +- dlls/dinput/joystick_hid.c | 30 +---------- dlls/dinput/keyboard.c | 2 +- dlls/dinput/mouse.c | 25 +-------- dlls/dinput8/tests/hid.c | 2 - 6 files changed, 95 insertions(+), 67 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 2367023175c..ed2ae551e3e 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1022,6 +1022,34 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con } } } + else + { + switch (LOWORD( guid )) + { + case (DWORD_PTR)DIPROP_RANGE: + case (DWORD_PTR)DIPROP_GRANULARITY: + if (!impl->caps.dwAxes) return DIERR_UNSUPPORTED; + break; + + case (DWORD_PTR)DIPROP_KEYNAME: + /* not supported on the mouse */ + if (impl->caps.dwAxes && !(impl->caps.dwDevType & DIDEVTYPE_HID)) return DIERR_UNSUPPORTED; + break; + + case (DWORD_PTR)DIPROP_DEADZONE: + case (DWORD_PTR)DIPROP_SATURATION: + if (!impl->object_properties) return DIERR_UNSUPPORTED; + break; + + case (DWORD_PTR)DIPROP_PRODUCTNAME: + case (DWORD_PTR)DIPROP_INSTANCENAME: + case (DWORD_PTR)DIPROP_VIDPID: + case (DWORD_PTR)DIPROP_JOYSTICKID: + case (DWORD_PTR)DIPROP_GUIDANDPATH: + if (!impl->vtbl->get_property) return DIERR_UNSUPPORTED; + break; + } + }
return DI_OK; } @@ -1032,11 +1060,70 @@ static BOOL CALLBACK find_object( const DIDEVICEOBJECTINSTANCEW *instance, void return DIENUM_STOP; }
+struct get_object_property_params +{ + IDirectInputDevice8W *iface; + DIPROPHEADER *header; + DWORD property; +}; + +static BOOL CALLBACK get_object_property( const DIDEVICEOBJECTINSTANCEW *instance, void *context ) +{ + static const struct object_properties default_properties = + { + .range_min = DIPROPRANGE_NOMIN, + .range_max = DIPROPRANGE_NOMAX, + }; + struct get_object_property_params *params = context; + struct dinput_device *impl = impl_from_IDirectInputDevice8W( params->iface ); + const struct object_properties *properties = NULL; + + if (!impl->object_properties) properties = &default_properties; + else properties = impl->object_properties + instance->dwOfs / sizeof(LONG); + + switch (params->property) + { + case (DWORD_PTR)DIPROP_RANGE: + { + DIPROPRANGE *value = (DIPROPRANGE *)params->header; + value->lMin = properties->range_min; + value->lMax = properties->range_max; + return DIENUM_STOP; + } + case (DWORD_PTR)DIPROP_DEADZONE: + { + DIPROPDWORD *value = (DIPROPDWORD *)params->header; + value->dwData = properties->deadzone; + return DIENUM_STOP; + } + case (DWORD_PTR)DIPROP_SATURATION: + { + DIPROPDWORD *value = (DIPROPDWORD *)params->header; + value->dwData = properties->saturation; + return DIENUM_STOP; + } + case (DWORD_PTR)DIPROP_GRANULARITY: + { + DIPROPDWORD *value = (DIPROPDWORD *)params->header; + value->dwData = 1; + return DIENUM_STOP; + } + case (DWORD_PTR)DIPROP_KEYNAME: + { + DIPROPSTRING *value = (DIPROPSTRING *)params->header; + lstrcpynW( value->wsz, instance->tszName, ARRAY_SIZE(value->wsz) ); + return DIENUM_STOP; + } + } + + return DIENUM_STOP; +} + static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GUID *guid, DIPROPHEADER *header ) { + struct get_object_property_params params = {.iface = iface, .header = header, .property = LOWORD( guid )}; struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); DWORD object_mask = DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV; - DIDEVICEOBJECTINSTANCEW instance; DIPROPHEADER filter; HRESULT hr;
@@ -1057,18 +1144,11 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU case (DWORD_PTR)DIPROP_DEADZONE: case (DWORD_PTR)DIPROP_SATURATION: case (DWORD_PTR)DIPROP_GRANULARITY: - hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance ); - if (FAILED(hr)) return hr; - if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; - if (!(instance.dwType & DIDFT_AXIS)) return DIERR_UNSUPPORTED; - return impl->vtbl->get_property( iface, LOWORD( guid ), header, &instance ); - case (DWORD_PTR)DIPROP_KEYNAME: - hr = impl->vtbl->enum_objects( iface, &filter, object_mask, find_object, &instance ); + hr = impl->vtbl->enum_objects( iface, &filter, object_mask, get_object_property, ¶ms ); if (FAILED(hr)) return hr; if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; - if (!(instance.dwType & DIDFT_BUTTON)) return DIERR_UNSUPPORTED; - return impl->vtbl->get_property( iface, LOWORD( guid ), header, &instance ); + return DI_OK;
case (DWORD_PTR)DIPROP_AUTOCENTER: { diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index 6d24e66bb54..c12cc92bc70 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -44,7 +44,7 @@ struct dinput_device_vtbl HRESULT (*enum_objects)( IDirectInputDevice8W *iface, const DIPROPHEADER *filter, DWORD flags, LPDIENUMDEVICEOBJECTSCALLBACKW callback, void *context ); HRESULT (*get_property)( IDirectInputDevice8W *iface, DWORD property, DIPROPHEADER *header, - DIDEVICEOBJECTINSTANCEW *instance ); + const DIDEVICEOBJECTINSTANCEW *instance ); HRESULT (*get_effect_info)( IDirectInputDevice8W *iface, DIEFFECTINFOW *info, const GUID *guid ); HRESULT (*create_effect)( IDirectInputDevice8W *iface, IDirectInputEffect **out ); HRESULT (*send_force_feedback_command)( IDirectInputDevice8W *iface, DWORD command, BOOL unacquire ); @@ -64,6 +64,7 @@ struct object_properties LONG range_max; LONG deadzone; LONG saturation; + DWORD calibration_mode; };
/* Device implementation */ diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 56e4c38c31a..2ad3462ca42 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -710,40 +710,12 @@ static void hid_joystick_release( IDirectInputDevice8W *iface ) }
static HRESULT hid_joystick_get_property( IDirectInputDevice8W *iface, DWORD property, - DIPROPHEADER *header, DIDEVICEOBJECTINSTANCEW *instance ) + DIPROPHEADER *header, const DIDEVICEOBJECTINSTANCEW *instance ) { struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); - struct object_properties *properties = NULL; - - if (instance) properties = impl->base.object_properties + instance->dwOfs / sizeof(LONG);
switch (property) { - case (DWORD_PTR)DIPROP_RANGE: - { - DIPROPRANGE *value = (DIPROPRANGE *)header; - value->lMin = properties->range_min; - value->lMax = properties->range_max; - return DI_OK; - } - case (DWORD_PTR)DIPROP_DEADZONE: - { - DIPROPDWORD *value = (DIPROPDWORD *)header; - value->dwData = properties->deadzone; - return DI_OK; - } - case (DWORD_PTR)DIPROP_SATURATION: - { - DIPROPDWORD *value = (DIPROPDWORD *)header; - value->dwData = properties->saturation; - return DI_OK; - } - case (DWORD_PTR)DIPROP_GRANULARITY: - { - DIPROPDWORD *value = (DIPROPDWORD *)header; - value->dwData = 1; - return DI_OK; - } case (DWORD_PTR)DIPROP_PRODUCTNAME: { DIPROPSTRING *value = (DIPROPSTRING *)header; diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 2afb744d520..1421e56ac3a 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -260,7 +260,7 @@ static HRESULT keyboard_enum_objects( IDirectInputDevice8W *iface, const DIPROPH }
static HRESULT keyboard_get_property( IDirectInputDevice8W *iface, DWORD property, - DIPROPHEADER *header, DIDEVICEOBJECTINSTANCEW *instance ) + DIPROPHEADER *header, const DIDEVICEOBJECTINSTANCEW *instance ) { switch (property) { diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 94cca61a0d0..64b2c30008d 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -553,29 +553,6 @@ static HRESULT mouse_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEAD return DIENUM_CONTINUE; }
-static HRESULT mouse_get_property( IDirectInputDevice8W *iface, DWORD property, - DIPROPHEADER *header, DIDEVICEOBJECTINSTANCEW *instance ) -{ - switch (property) - { - case (DWORD_PTR)DIPROP_RANGE: - { - DIPROPRANGE *range = (DIPROPRANGE *)header; - range->lMin = DIPROPRANGE_NOMIN; - range->lMax = DIPROPRANGE_NOMAX; - return DI_OK; - } - case (DWORD_PTR)DIPROP_GRANULARITY: - { - DIPROPDWORD *value = (DIPROPDWORD *)header; - if (instance->dwType == DIMOFS_Z) value->dwData = WHEEL_DELTA; - else value->dwData = 1; - return DI_OK; - } - } - return DIERR_UNSUPPORTED; -} - static const struct dinput_device_vtbl mouse_vtbl = { NULL, @@ -584,7 +561,7 @@ static const struct dinput_device_vtbl mouse_vtbl = mouse_acquire, mouse_unacquire, mouse_enum_objects, - mouse_get_property, + NULL, NULL, NULL, NULL, diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 8c347dc009a..b3f696e09ee 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -4223,9 +4223,7 @@ static void test_simple_joystick(void) prop_string.diph.dwHow = DIPH_BYUSAGE; prop_string.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_KEYNAME, &prop_string.diph ); - todo_wine ok( hr == DI_OK, "GetProperty DIPROP_KEYNAME returned %#x\n", hr ); - todo_wine ok( !wcscmp( prop_string.wsz, expect_objects[4].tszName ), "got DIPROP_KEYNAME %s\n", debugstr_w( prop_string.wsz ) ); prop_string.diph.dwObj = MAKELONG( 0x1, HID_USAGE_PAGE_BUTTON );
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 26 ++++++++++++++++++++++++++ dlls/dinput8/tests/hid.c | 11 ----------- 2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index ed2ae551e3e..f70b7e549c0 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -920,6 +920,7 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con case (DWORD_PTR)DIPROP_AUTOCENTER: case (DWORD_PTR)DIPROP_AXISMODE: case (DWORD_PTR)DIPROP_BUFFERSIZE: + case (DWORD_PTR)DIPROP_CALIBRATIONMODE: case (DWORD_PTR)DIPROP_DEADZONE: case (DWORD_PTR)DIPROP_FFGAIN: case (DWORD_PTR)DIPROP_FFLOAD: @@ -966,6 +967,7 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con case (DWORD_PTR)DIPROP_DEADZONE: case (DWORD_PTR)DIPROP_SATURATION: case (DWORD_PTR)DIPROP_GRANULARITY: + case (DWORD_PTR)DIPROP_CALIBRATIONMODE: if (header->dwHow == DIPH_DEVICE && !set) return DIERR_UNSUPPORTED; break;
@@ -1015,6 +1017,7 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con } case (DWORD_PTR)DIPROP_AUTOCENTER: case (DWORD_PTR)DIPROP_AXISMODE: + case (DWORD_PTR)DIPROP_CALIBRATIONMODE: { const DIPROPDWORD *value = (const DIPROPDWORD *)header; if (value->dwData > 1) return DIERR_INVALIDPARAM; @@ -1038,6 +1041,7 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con
case (DWORD_PTR)DIPROP_DEADZONE: case (DWORD_PTR)DIPROP_SATURATION: + case (DWORD_PTR)DIPROP_CALIBRATIONMODE: if (!impl->object_properties) return DIERR_UNSUPPORTED; break;
@@ -1102,6 +1106,12 @@ static BOOL CALLBACK get_object_property( const DIDEVICEOBJECTINSTANCEW *instanc value->dwData = properties->saturation; return DIENUM_STOP; } + case (DWORD_PTR)DIPROP_CALIBRATIONMODE: + { + DIPROPDWORD *value = (DIPROPDWORD *)params->header; + value->dwData = properties->calibration_mode; + return DI_OK; + } case (DWORD_PTR)DIPROP_GRANULARITY: { DIPROPDWORD *value = (DIPROPDWORD *)params->header; @@ -1145,6 +1155,7 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU case (DWORD_PTR)DIPROP_SATURATION: case (DWORD_PTR)DIPROP_GRANULARITY: case (DWORD_PTR)DIPROP_KEYNAME: + case (DWORD_PTR)DIPROP_CALIBRATIONMODE: hr = impl->vtbl->enum_objects( iface, &filter, object_mask, get_object_property, ¶ms ); if (FAILED(hr)) return hr; if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; @@ -1249,6 +1260,12 @@ static BOOL CALLBACK set_object_property( const DIDEVICEOBJECTINSTANCEW *instanc properties->saturation = value->dwData; return DIENUM_CONTINUE; } + case (DWORD_PTR)DIPROP_CALIBRATIONMODE: + { + const DIPROPDWORD *value = (const DIPROPDWORD *)params->header; + properties->calibration_mode = value->dwData; + return DIENUM_CONTINUE; + } }
return DIENUM_STOP; @@ -1312,6 +1329,15 @@ static HRESULT WINAPI dinput_device_set_property( IDirectInputDevice8W *iface, c reset_device_state( iface ); return DI_OK; } + case (DWORD_PTR)DIPROP_CALIBRATIONMODE: + { + const DIPROPDWORD *value = (const DIPROPDWORD *)header; + if (value->dwData > DIPROPCALIBRATIONMODE_RAW) return DIERR_INVALIDPARAM; + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, set_object_property, ¶ms ); + if (FAILED(hr)) return hr; + reset_device_state( iface ); + return DI_OK; + } case (DWORD_PTR)DIPROP_AUTOCENTER: { const DIPROPDWORD *value = (const DIPROPDWORD *)header; diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index b3f696e09ee..3beabc4b03b 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -4215,9 +4215,7 @@ static void test_simple_joystick(void) ok( prop_dword.dwData == 10000, "got %u expected %u\n", prop_dword.dwData, 10000 ); prop_dword.dwData = 0xdeadbeef; hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); - todo_wine ok( hr == DI_OK, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); - todo_wine ok( prop_dword.dwData == DIPROPCALIBRATIONMODE_COOKED, "got %u expected %u\n", prop_dword.dwData, DIPROPCALIBRATIONMODE_COOKED );
prop_string.diph.dwHow = DIPH_BYUSAGE; @@ -4927,7 +4925,6 @@ static void test_simple_joystick(void) hr = IDirectInputDevice8_SetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); ok( hr == DIERR_INVALIDPARAM, "SetProperty DIPROP_SATURATION returned %#x\n", hr ); hr = IDirectInputDevice8_SetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); - todo_wine ok( hr == DIERR_INVALIDPARAM, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); prop_dword.dwData = 1000; hr = IDirectInputDevice8_SetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); @@ -4937,7 +4934,6 @@ static void test_simple_joystick(void) ok( hr == DI_OK, "SetProperty DIPROP_SATURATION returned %#x\n", hr ); prop_dword.dwData = DIPROPCALIBRATIONMODE_COOKED; hr = IDirectInputDevice8_SetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); - todo_wine ok( hr == DI_OK, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr );
hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); @@ -5025,13 +5021,10 @@ static void test_simple_joystick(void) prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); prop_dword.dwData = DIPROPCALIBRATIONMODE_RAW; hr = IDirectInputDevice8_SetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); - todo_wine ok( hr == DI_OK, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); prop_dword.dwData = 0xdeadbeef; hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); - todo_wine ok( hr == DI_OK, "GetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr ); - todo_wine ok( prop_dword.dwData == DIPROPCALIBRATIONMODE_RAW, "got %u expected %u\n", prop_dword.dwData, DIPROPCALIBRATIONMODE_RAW );
hr = IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE2), &state ); @@ -5039,23 +5032,19 @@ static void test_simple_joystick(void) winetest_push_context( "state[%d]", i ); todo_wine ok( state.lX == 15, "got lX %d, expected %d\n" , state.lX, 15 ); - todo_wine check_member( state, expect_state_abs[0], "%d", lY ); check_member( state, expect_state_abs[0], "%d", lZ ); check_member( state, expect_state_abs[0], "%d", lRx ); - todo_wine check_member( state, expect_state_abs[0], "%d", rgdwPOV[0] ); check_member( state, expect_state_abs[0], "%d", rgdwPOV[1] ); winetest_pop_context();
prop_dword.dwData = DIPROPCALIBRATIONMODE_COOKED; hr = IDirectInputDevice8_SetProperty( device, DIPROP_CALIBRATIONMODE, &prop_dword.diph ); - todo_wine ok( hr == DI_OK, "SetProperty DIPROP_CALIBRATIONMODE returned %#x\n", hr );
send_hid_input( file, &injected_input[ARRAY_SIZE(injected_input) - 1], sizeof(*injected_input) ); res = WaitForSingleObject( event, 100 ); - todo_wine ok( res == WAIT_OBJECT_0, "WaitForSingleObject failed\n" );
hr = IDirectInputDevice8_Unacquire( device );
Fixes apps like WheelCheck, which rely on some of these properties (DIPROP_PHYSICALRANGE) to correctly calculate the top center of the wheel against their permitted range.
In particular the constant force test now works just like in Windows, directing the wheel to the upper center and resisting any movement to the left or right. Before that it would pull the steering wheel hard to the left.
From: Ivo Ivanov logos128@gmail.com Signed-off-by: Ivo Ivanov logos128@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 27 +++++++++++++++++++++++++++ dlls/dinput/device_private.h | 2 ++ dlls/dinput/joystick_hid.c | 2 ++ dlls/dinput8/tests/hid.c | 8 -------- 4 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index f70b7e549c0..6240d640e0d 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -936,6 +936,8 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con if (header->dwSize != sizeof(DIPROPPOINTER)) return DIERR_INVALIDPARAM; break;
+ case (DWORD_PTR)DIPROP_PHYSICALRANGE: + case (DWORD_PTR)DIPROP_LOGICALRANGE: case (DWORD_PTR)DIPROP_RANGE: if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM; break; @@ -963,6 +965,8 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con if (header->dwObj) return DIERR_INVALIDPARAM; break;
+ case (DWORD_PTR)DIPROP_PHYSICALRANGE: + case (DWORD_PTR)DIPROP_LOGICALRANGE: case (DWORD_PTR)DIPROP_RANGE: case (DWORD_PTR)DIPROP_DEADZONE: case (DWORD_PTR)DIPROP_SATURATION: @@ -988,6 +992,8 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con case (DWORD_PTR)DIPROP_AUTOCENTER: case (DWORD_PTR)DIPROP_AXISMODE: case (DWORD_PTR)DIPROP_BUFFERSIZE: + case (DWORD_PTR)DIPROP_PHYSICALRANGE: + case (DWORD_PTR)DIPROP_LOGICALRANGE: if (impl->acquired) return DIERR_ACQUIRED; break; case (DWORD_PTR)DIPROP_FFLOAD: @@ -1023,6 +1029,9 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con if (value->dwData > 1) return DIERR_INVALIDPARAM; break; } + case (DWORD_PTR)DIPROP_PHYSICALRANGE: + case (DWORD_PTR)DIPROP_LOGICALRANGE: + return DIERR_UNSUPPORTED; } } else @@ -1039,6 +1048,8 @@ static HRESULT check_property( struct dinput_device *impl, const GUID *guid, con if (impl->caps.dwAxes && !(impl->caps.dwDevType & DIDEVTYPE_HID)) return DIERR_UNSUPPORTED; break;
+ case (DWORD_PTR)DIPROP_PHYSICALRANGE: + case (DWORD_PTR)DIPROP_LOGICALRANGE: case (DWORD_PTR)DIPROP_DEADZONE: case (DWORD_PTR)DIPROP_SATURATION: case (DWORD_PTR)DIPROP_CALIBRATIONMODE: @@ -1087,6 +1098,20 @@ static BOOL CALLBACK get_object_property( const DIDEVICEOBJECTINSTANCEW *instanc
switch (params->property) { + case (DWORD_PTR)DIPROP_PHYSICALRANGE: + { + DIPROPRANGE *value = (DIPROPRANGE *)params->header; + value->lMin = properties->physical_min; + value->lMax = properties->physical_max; + return DI_OK; + } + case (DWORD_PTR)DIPROP_LOGICALRANGE: + { + DIPROPRANGE *value = (DIPROPRANGE *)params->header; + value->lMin = properties->logical_min; + value->lMax = properties->logical_max; + return DI_OK; + } case (DWORD_PTR)DIPROP_RANGE: { DIPROPRANGE *value = (DIPROPRANGE *)params->header; @@ -1151,6 +1176,8 @@ static HRESULT dinput_device_get_property( IDirectInputDevice8W *iface, const GU return impl->vtbl->get_property( iface, LOWORD( guid ), header, NULL );
case (DWORD_PTR)DIPROP_RANGE: + case (DWORD_PTR)DIPROP_PHYSICALRANGE: + case (DWORD_PTR)DIPROP_LOGICALRANGE: case (DWORD_PTR)DIPROP_DEADZONE: case (DWORD_PTR)DIPROP_SATURATION: case (DWORD_PTR)DIPROP_GRANULARITY: diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index c12cc92bc70..e2cae26aea2 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -58,6 +58,8 @@ struct dinput_device_vtbl struct object_properties { LONG bit_size; + LONG physical_min; + LONG physical_max; LONG logical_min; LONG logical_max; LONG range_min; diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 2ad3462ca42..70c761267f7 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -1486,6 +1486,8 @@ static BOOL init_object_properties( struct hid_joystick *impl, struct hid_value_ LONG tmp;
properties->bit_size = caps->bit_size; + properties->physical_min = caps->physical_min; + properties->physical_max = caps->physical_max; properties->logical_min = caps->logical_min; properties->logical_max = caps->logical_max;
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index 3beabc4b03b..9e21ccdb713 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -4253,18 +4253,12 @@ static void test_simple_joystick(void) ok( prop_range.lMin == 0, "got %d expected %d\n", prop_range.lMin, 0 ); ok( prop_range.lMax == 65535, "got %d expected %d\n", prop_range.lMax, 65535 ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph ); - todo_wine ok( hr == DI_OK, "GetProperty DIPROP_LOGICALRANGE returned %#x\n", hr ); - todo_wine ok( prop_range.lMin == -25, "got %d expected %d\n", prop_range.lMin, -25 ); - todo_wine ok( prop_range.lMax == 56, "got %d expected %d\n", prop_range.lMax, 56 ); hr = IDirectInputDevice8_GetProperty( device, DIPROP_PHYSICALRANGE, &prop_range.diph ); - todo_wine ok( hr == DI_OK, "GetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr ); - todo_wine ok( prop_range.lMin == -25, "got %d expected %d\n", prop_range.lMin, -25 ); - todo_wine ok( prop_range.lMax == 56, "got %d expected %d\n", prop_range.lMax, 56 );
prop_pointer.diph.dwHow = DIPH_BYUSAGE; @@ -4810,10 +4804,8 @@ static void test_simple_joystick(void) hr = IDirectInputDevice8_SetProperty( device, DIPROP_RANGE, &prop_range.diph ); ok( hr == DI_OK, "SetProperty DIPROP_RANGE returned %#x\n", hr ); hr = IDirectInputDevice8_SetProperty( device, DIPROP_LOGICALRANGE, &prop_range.diph ); - todo_wine ok( hr == DIERR_ACQUIRED, "SetProperty DIPROP_LOGICALRANGE returned %#x\n", hr ); hr = IDirectInputDevice8_SetProperty( device, DIPROP_PHYSICALRANGE, &prop_range.diph ); - todo_wine ok( hr == DIERR_ACQUIRED, "SetProperty DIPROP_PHYSICALRANGE returned %#x\n", hr );
hr = IDirectInputDevice8_Unacquire( device );
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=102225
Your paranoid android.
=== w8 (32 bit report) ===
dinput8: hid.c:2213: Test failed: id 1 poll: expected identical reports