[PATCH 2/5] dinput: Enumerate all HID joystick objects at once.
Rémi Bernon
rbernon at codeweavers.com
Mon Sep 27 02:43:04 CDT 2021
Instead of using individual helpers.
The force-feedback EnumObjects test shows that we should enumerate the
output objects in their original order in the HID report descriptor, not
depending on their button/value nature.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/dinput/joystick_hid.c | 128 +++++++++++++++----------------------
dlls/dinput8/tests/hid.c | 1 -
2 files changed, 51 insertions(+), 78 deletions(-)
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index 6eb1a98c13b..06537e9fd25 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -231,13 +231,13 @@ static void set_axis_type( DIDEVICEOBJECTINSTANCEW *instance, BOOL *seen, DWORD
seen[i] = TRUE;
}
-static BOOL enum_value_objects( struct hid_joystick *impl, const DIPROPHEADER *filter,
- DWORD flags, enum_object_callback callback, void *data )
+static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter, DWORD flags,
+ enum_object_callback callback, void *data )
{
DIDEVICEOBJECTINSTANCEW instance = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)};
- struct hid_caps caps = {.type = VALUE_CAPS};
+ DWORD collection = 0, axis = 0, button = 0, pov = 0, i, j;
BOOL ret, seen_axis[6] = {0};
- DWORD axis = 0, pov = 0, i;
+ struct hid_caps caps = {0};
for (i = 0; i < impl->caps.NumberInputValueCaps; ++i)
{
@@ -328,17 +328,6 @@ static BOOL enum_value_objects( struct hid_joystick *impl, const DIPROPHEADER *f
}
}
- return DIENUM_CONTINUE;
-}
-
-static BOOL enum_button_objects( struct hid_joystick *impl, const DIPROPHEADER *filter,
- DWORD flags, enum_object_callback callback, void *data )
-{
- DIDEVICEOBJECTINSTANCEW instance = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)};
- struct hid_caps caps = {.type = BUTTON_CAPS};
- DWORD button = 0, i, j;
- BOOL ret;
-
for (i = 0; i < impl->caps.NumberInputButtonCaps; ++i)
{
caps.button = impl->input_button_caps + i;
@@ -384,17 +373,6 @@ static BOOL enum_button_objects( struct hid_joystick *impl, const DIPROPHEADER *
}
}
- return DIENUM_CONTINUE;
-}
-
-static BOOL enum_collections_objects( struct hid_joystick *impl, const DIPROPHEADER *filter, DWORD flags,
- enum_object_callback callback, void *data )
-{
- DIDEVICEOBJECTINSTANCEW instance = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)};
- struct hid_caps caps = {.type = LINK_COLLECTION_NODE};
- DWORD collection = 0, i;
- BOOL ret;
-
for (i = 0; i < impl->caps.NumberLinkCollectionNodes; ++i)
{
caps.node = impl->collection_nodes + i;
@@ -489,14 +467,31 @@ static HRESULT WINAPI hid_joystick_EnumObjects( IDirectInputDevice8W *iface, LPD
TRACE( "iface %p, callback %p, context %p, flags %#x.\n", iface, callback, context, flags );
if (!callback) return DIERR_INVALIDPARAM;
+ if (flags & ~(DIDFT_AXIS | DIDFT_AXIS | DIDFT_BUTTON | DIDFT_NODATA | DIDFT_COLLECTION))
+ return DIERR_INVALIDPARAM;
- ret = enum_value_objects( impl, &filter, flags, enum_objects_callback, ¶ms );
- if (ret != DIENUM_CONTINUE) return S_OK;
- ret = enum_button_objects( impl, &filter, flags, enum_objects_callback, ¶ms );
- if (ret != DIENUM_CONTINUE) return S_OK;
- enum_collections_objects( impl, &filter, flags, enum_objects_callback, ¶ms );
+ if (flags == DIDFT_ALL || (flags & DIDFT_AXIS))
+ {
+ ret = enum_objects( impl, &filter, DIDFT_AXIS, enum_objects_callback, ¶ms );
+ if (ret != DIENUM_CONTINUE) return DI_OK;
+ }
+ if (flags == DIDFT_ALL || (flags & DIDFT_POV))
+ {
+ ret = enum_objects( impl, &filter, DIDFT_POV, enum_objects_callback, ¶ms );
+ if (ret != DIENUM_CONTINUE) return DI_OK;
+ }
+ if (flags == DIDFT_ALL || (flags & DIDFT_BUTTON))
+ {
+ ret = enum_objects( impl, &filter, DIDFT_BUTTON, enum_objects_callback, ¶ms );
+ if (ret != DIENUM_CONTINUE) return DI_OK;
+ }
+ if (flags == DIDFT_ALL || (flags & (DIDFT_NODATA | DIDFT_COLLECTION)))
+ {
+ ret = enum_objects( impl, &filter, DIDFT_NODATA, enum_objects_callback, ¶ms );
+ if (ret != DIENUM_CONTINUE) return DI_OK;
+ }
- return S_OK;
+ return DI_OK;
}
static BOOL get_property_prop_range( struct hid_joystick *impl, struct hid_caps *caps,
@@ -524,7 +519,7 @@ static HRESULT WINAPI hid_joystick_GetProperty( IDirectInputDevice8W *iface, con
{
case (DWORD_PTR)DIPROP_RANGE:
if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM;
- enum_value_objects( impl, header, DIDFT_AXIS, get_property_prop_range, header );
+ enum_objects( impl, header, DIDFT_AXIS, get_property_prop_range, header );
return DI_OK;
case (DWORD_PTR)DIPROP_PRODUCTNAME:
{
@@ -597,7 +592,7 @@ static HRESULT WINAPI hid_joystick_SetProperty( IDirectInputDevice8W *iface, con
{
case (DWORD_PTR)DIPROP_RANGE:
if (header->dwSize != sizeof(DIPROPRANGE)) return DIERR_INVALIDPARAM;
- enum_value_objects( impl, header, DIDFT_AXIS, set_property_prop_range, (void *)header );
+ enum_objects( impl, header, DIDFT_AXIS, set_property_prop_range, (void *)header );
return DI_OK;
case (DWORD_PTR)DIPROP_FFLOAD:
case (DWORD_PTR)DIPROP_GRANULARITY:
@@ -687,7 +682,6 @@ static HRESULT WINAPI hid_joystick_GetObjectInfo( IDirectInputDevice8W *iface, D
.dwHow = how,
.dwObj = obj
};
- BOOL ret;
TRACE( "iface %p, instance %p, obj %#x, how %#x.\n", iface, instance, obj, how );
@@ -696,12 +690,7 @@ static HRESULT WINAPI hid_joystick_GetObjectInfo( IDirectInputDevice8W *iface, D
instance->dwSize != sizeof(DIDEVICEOBJECTINSTANCEW))
return DIERR_INVALIDPARAM;
- ret = enum_value_objects( impl, &filter, DIDFT_ALL, get_object_info, instance );
- if (ret != DIENUM_CONTINUE) return S_OK;
- ret = enum_button_objects( impl, &filter, DIDFT_ALL, get_object_info, instance );
- if (ret != DIENUM_CONTINUE) return S_OK;
- enum_collections_objects( impl, &filter, DIDFT_ALL, get_object_info, instance );
-
+ enum_objects( impl, &filter, DIDFT_ALL, get_object_info, instance );
return S_OK;
}
@@ -811,16 +800,11 @@ static BOOL check_device_state_button( struct hid_joystick *impl, struct hid_cap
struct parse_device_state_params *params = data;
BYTE old_value, value;
- if (!(instance->dwType & DIDFT_BUTTON))
- FIXME( "unexpected object type %#x, expected DIDFT_BUTTON\n", instance->dwType );
- else
- {
- value = params->buttons[instance->wUsage - 1];
- old_value = params->old_state[instance->dwOfs];
- impl->device_state[instance->dwOfs] = value;
- if (old_value != value)
- queue_event( iface, instance->dwType, value, params->time, params->seq );
- }
+ value = params->buttons[instance->wUsage - 1];
+ old_value = params->old_state[instance->dwOfs];
+ impl->device_state[instance->dwOfs] = value;
+ if (old_value != value)
+ queue_event( iface, instance->dwType, value, params->time, params->seq );
return DIENUM_CONTINUE;
}
@@ -854,21 +838,16 @@ static BOOL read_device_state_value( struct hid_joystick *impl, struct hid_caps
LONG old_value, value;
NTSTATUS status;
- if (!(instance->dwType & (DIDFT_POV | DIDFT_AXIS)))
- FIXME( "unexpected object type %#x, expected DIDFT_POV | DIDFT_AXIS\n", instance->dwType );
- else
- {
- status = HidP_GetUsageValue( HidP_Input, instance->wUsagePage, 0, instance->wUsage,
- &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 );
- value = scale_value( logical_value, value_caps, value_caps->PhysicalMin, value_caps->PhysicalMax );
-
- old_value = *(LONG *)(params->old_state + instance->dwOfs);
- *(LONG *)(impl->device_state + instance->dwOfs) = value;
- if (old_value != value)
- queue_event( iface, instance->dwType, value, params->time, params->seq );
- }
+ status = HidP_GetUsageValue( HidP_Input, instance->wUsagePage, 0, instance->wUsage,
+ &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 );
+ value = scale_value( logical_value, value_caps, value_caps->PhysicalMin, value_caps->PhysicalMax );
+
+ old_value = *(LONG *)(params->old_state + instance->dwOfs);
+ *(LONG *)(impl->device_state + instance->dwOfs) = value;
+ if (old_value != value)
+ queue_event( iface, instance->dwType, value, params->time, params->seq );
return DIENUM_CONTINUE;
}
@@ -933,8 +912,8 @@ static HRESULT hid_joystick_read_state( IDirectInputDevice8W *iface )
params.buttons[usages->Usage - 1] = 0x80;
}
- enum_value_objects( impl, &filter, DIDFT_ALL, read_device_state_value, ¶ms );
- enum_button_objects( impl, &filter, DIDFT_ALL, check_device_state_button, ¶ms );
+ enum_objects( impl, &filter, DIDFT_AXIS | DIDFT_POV, read_device_state_value, ¶ms );
+ enum_objects( impl, &filter, DIDFT_BUTTON, check_device_state_button, ¶ms );
if (impl->base.hEvent && memcmp( ¶ms.old_state, impl->device_state, format->dwDataSize ))
SetEvent( impl->base.hEvent );
}
@@ -1328,10 +1307,7 @@ static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID
&impl->caps.NumberInputValueCaps, impl->preparsed );
if (status != HIDP_STATUS_SUCCESS && status != HIDP_STATUS_USAGE_NOT_FOUND) goto failed;
- /* enumerate collections first, so we can find report collections */
- enum_collections_objects( impl, &filter, DIDFT_ALL, init_objects, NULL );
- enum_value_objects( impl, &filter, DIDFT_ALL, init_objects, NULL );
- enum_button_objects( impl, &filter, DIDFT_ALL, init_objects, NULL );
+ enum_objects( impl, &filter, DIDFT_ALL, init_objects, NULL );
format = impl->base.data_format.wine_df;
if (format->dwDataSize > DEVICE_STATE_MAX_SIZE)
@@ -1347,16 +1323,14 @@ static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID
format->dwFlags = DIDF_ABSAXIS;
index = 0;
- enum_value_objects( impl, &filter, DIDFT_ALL, init_data_format, &index );
- enum_button_objects( impl, &filter, DIDFT_ALL, init_data_format, &index );
- enum_collections_objects( impl, &filter, DIDFT_ALL, init_data_format, &index );
+ enum_objects( impl, &filter, DIDFT_ALL, init_data_format, &index );
_dump_DIDATAFORMAT( impl->base.data_format.wine_df );
range.lMax = 65535;
- enum_value_objects( impl, &range.diph, DIDFT_AXIS, set_property_prop_range, &range );
+ enum_objects( impl, &range.diph, DIDFT_AXIS, set_property_prop_range, &range );
range.lMax = 36000;
- enum_value_objects( impl, &range.diph, DIDFT_POV, set_property_prop_range, &range );
+ enum_objects( impl, &range.diph, DIDFT_POV, set_property_prop_range, &range );
*out = &impl->base.IDirectInputDevice8W_iface;
return DI_OK;
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index 14198f2d876..d73d4dabfff 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -3943,7 +3943,6 @@ static void test_simple_joystick(void)
hr = IDirectInputDevice8_EnumObjects( device, NULL, NULL, DIDFT_ALL );
ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_EnumObjects returned %#x\n", hr );
hr = IDirectInputDevice8_EnumObjects( device, check_object_count, &res, 0x20 );
- todo_wine
ok( hr == DIERR_INVALIDPARAM, "IDirectInputDevice8_EnumObjects returned %#x\n", hr );
res = 0;
hr = IDirectInputDevice8_EnumObjects( device, check_object_count, &res, DIDFT_AXIS | DIDFT_PSHBUTTON );
--
2.33.0
More information about the wine-devel
mailing list