From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dinput/device.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index df19f615a55..407e4f52a38 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -2183,11 +2183,15 @@ static const GUID *object_instance_guid( const DIDEVICEOBJECTINSTANCEW *instance return &GUID_Unknown; }
-static BOOL CALLBACK enum_objects_count( const DIDEVICEOBJECTINSTANCEW *instance, void *data ) +static BOOL enum_objects_count( struct dinput_device *impl, UINT index, struct hid_value_caps *caps, + const DIDEVICEOBJECTINSTANCEW *instance, void *data ) { - struct dinput_device *impl = impl_from_IDirectInputDevice8W( data ); DIDATAFORMAT *format = &impl->device_format;
+ if (index == -1) return DIENUM_STOP; + format->dwNumObjs++; + if (instance->wUsagePage == HID_USAGE_PAGE_PID) return DIENUM_CONTINUE; + format->dwDataSize = max( format->dwDataSize, instance->dwOfs + sizeof(LONG) ); if (instance->dwType & DIDFT_BUTTON) impl->caps.dwButtons++; if (instance->dwType & DIDFT_AXIS) impl->caps.dwAxes++; @@ -2200,36 +2204,46 @@ static BOOL CALLBACK enum_objects_count( const DIDEVICEOBJECTINSTANCEW *instance FIXME( "multiple device state reports found!\n" ); }
- format->dwNumObjs++; return DIENUM_CONTINUE; }
-static BOOL CALLBACK enum_objects_init( const DIDEVICEOBJECTINSTANCEW *instance, void *data ) +static BOOL enum_objects_init( struct dinput_device *impl, UINT index, struct hid_value_caps *caps, + const DIDEVICEOBJECTINSTANCEW *instance, void *data ) { - struct dinput_device *impl = impl_from_IDirectInputDevice8W( data ); DIDATAFORMAT *format = &impl->device_format; DIOBJECTDATAFORMAT *object_format;
- object_format = format->rgodf + format->dwNumObjs; + if (index == -1) return DIENUM_STOP; + if (instance->wUsagePage == HID_USAGE_PAGE_PID) return DIENUM_CONTINUE; + + object_format = format->rgodf + index; object_format->pguid = object_instance_guid( instance ); object_format->dwOfs = instance->dwOfs; object_format->dwType = instance->dwType; object_format->dwFlags = instance->dwFlags;
if (impl->object_properties && (instance->dwType & (DIDFT_AXIS | DIDFT_POV))) - reset_object_value( impl, format->dwNumObjs, NULL, instance, NULL ); + reset_object_value( impl, index, caps, instance, NULL );
- format->dwNumObjs++; return DIENUM_CONTINUE; }
HRESULT dinput_device_init_device_format( IDirectInputDevice8W *iface ) { + static const DIPROPHEADER filter = + { + .dwSize = sizeof(filter), + .dwHeaderSize = sizeof(filter), + .dwHow = DIPH_DEVICE, + }; struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface ); DIDATAFORMAT *format = &impl->device_format; ULONG i, size; + HRESULT hr; + + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_ALL, enum_objects_count, NULL ); + if (FAILED(hr)) return hr;
- IDirectInputDevice8_EnumObjects( iface, enum_objects_count, iface, DIDFT_ALL ); if (format->dwDataSize > DEVICE_STATE_MAX_SIZE) { FIXME( "unable to create device, state is too large\n" ); @@ -2242,8 +2256,15 @@ HRESULT dinput_device_init_device_format( IDirectInputDevice8W *iface ) format->dwSize = sizeof(*format); format->dwObjSize = sizeof(*format->rgodf); format->dwFlags = DIDF_ABSAXIS; - format->dwNumObjs = 0; - IDirectInputDevice8_EnumObjects( iface, enum_objects_init, iface, DIDFT_ALL ); + + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, enum_objects_init, NULL ); + if (FAILED(hr)) return hr; + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_POV, enum_objects_init, NULL ); + if (FAILED(hr)) return hr; + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_BUTTON, enum_objects_init, NULL ); + if (FAILED(hr)) return hr; + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_NODATA, enum_objects_init, NULL ); + if (FAILED(hr)) return hr;
if (TRACE_ON( dinput )) {