dinput: Implement EnumObjects through the internal vtable.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-10-18 10:21:53 +02:00 committed by Alexandre Julliard
parent be9a36c4ff
commit 34f66a0cec
5 changed files with 90 additions and 87 deletions

View File

@ -1140,33 +1140,70 @@ ULONG WINAPI IDirectInputDevice2WImpl_AddRef(LPDIRECTINPUTDEVICE8W iface)
return ref;
}
HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface,
LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID lpvRef, DWORD dwFlags)
HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects( IDirectInputDevice8W *iface, LPDIENUMDEVICEOBJECTSCALLBACKW callback,
void *context, DWORD flags )
{
IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
DIDEVICEOBJECTINSTANCEW ddoi;
int i;
TRACE("(%p)->(%p,%p flags:%08x)\n", This, lpCallback, lpvRef, dwFlags);
TRACE(" - flags = ");
_dump_EnumObjects_flags(dwFlags);
TRACE("\n");
if (!lpCallback) return DIERR_INVALIDPARAM;
/* Only the fields till dwFFMaxForce are relevant */
memset(&ddoi, 0, sizeof(ddoi));
ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEW, dwFFMaxForce);
for (i = 0; i < This->data_format.wine_df->dwNumObjs; i++)
static const DIPROPHEADER filter =
{
LPDIOBJECTDATAFORMAT odf = dataformat_to_odf(This->data_format.wine_df, i);
.dwSize = sizeof(filter),
.dwHeaderSize = sizeof(filter),
.dwHow = DIPH_DEVICE,
};
struct IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface );
HRESULT hr;
if (dwFlags != DIDFT_ALL && !(dwFlags & DIDFT_GETTYPE(odf->dwType))) continue;
if (IDirectInputDevice_GetObjectInfo(iface, &ddoi, odf->dwType, DIPH_BYID) != DI_OK)
continue;
TRACE( "iface %p, callback %p, context %p, flags %#x.\n", iface, callback, context, flags );
if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) break;
if (!callback) return DIERR_INVALIDPARAM;
if (flags & ~(DIDFT_AXIS | DIDFT_POV | DIDFT_BUTTON | DIDFT_NODATA | DIDFT_COLLECTION))
return DIERR_INVALIDPARAM;
if (!impl->vtbl->enum_objects)
{
DIDEVICEOBJECTINSTANCEW ddoi;
DWORD i;
/* Only the fields till dwFFMaxForce are relevant */
memset( &ddoi, 0, sizeof(ddoi) );
ddoi.dwSize = FIELD_OFFSET( DIDEVICEOBJECTINSTANCEW, dwFFMaxForce );
for (i = 0; i < impl->data_format.wine_df->dwNumObjs; i++)
{
LPDIOBJECTDATAFORMAT odf = dataformat_to_odf( impl->data_format.wine_df, i );
if (flags != DIDFT_ALL && !(flags & DIDFT_GETTYPE( odf->dwType ))) continue;
if (IDirectInputDevice_GetObjectInfo( iface, &ddoi, odf->dwType, DIPH_BYID ) != DI_OK)
continue;
if (callback( &ddoi, context ) != DIENUM_CONTINUE) break;
}
return DI_OK;
}
if (flags == DIDFT_ALL || (flags & DIDFT_AXIS))
{
hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, callback, context );
if (FAILED(hr)) return hr;
if (hr != DIENUM_CONTINUE) return DI_OK;
}
if (flags == DIDFT_ALL || (flags & DIDFT_POV))
{
hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_POV, callback, context );
if (FAILED(hr)) return hr;
if (hr != DIENUM_CONTINUE) return DI_OK;
}
if (flags == DIDFT_ALL || (flags & DIDFT_BUTTON))
{
hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_BUTTON, callback, context );
if (FAILED(hr)) return hr;
if (hr != DIENUM_CONTINUE) return DI_OK;
}
if (flags == DIDFT_ALL || (flags & (DIDFT_NODATA | DIDFT_COLLECTION)))
{
hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_NODATA, callback, context );
if (FAILED(hr)) return hr;
if (hr != DIENUM_CONTINUE) return DI_OK;
}
return DI_OK;

View File

@ -57,9 +57,11 @@ typedef HRESULT dinput_device_read_state( IDirectInputDevice8W *iface );
struct dinput_device_vtbl
{
HRESULT (*read)(IDirectInputDevice8W *);
HRESULT (*acquire)(IDirectInputDevice8W *);
HRESULT (*unacquire)(IDirectInputDevice8W *);
HRESULT (*read)( IDirectInputDevice8W *iface );
HRESULT (*acquire)( IDirectInputDevice8W *iface );
HRESULT (*unacquire)( IDirectInputDevice8W *iface );
HRESULT (*enum_objects)( IDirectInputDevice8W *iface, const DIPROPHEADER *filter, DWORD flags,
LPDIENUMDEVICEOBJECTSCALLBACKW callback, void *context );
};
#define DEVICE_STATE_MAX_SIZE 1024

View File

@ -656,66 +656,6 @@ static ULONG WINAPI hid_joystick_Release( IDirectInputDevice8W *iface )
return ref;
}
struct enum_objects_params
{
LPDIENUMDEVICEOBJECTSCALLBACKW callback;
void *context;
};
static BOOL enum_objects_callback( struct hid_joystick *impl, struct hid_value_caps *caps,
DIDEVICEOBJECTINSTANCEW *instance, void *data )
{
struct enum_objects_params *params = data;
return params->callback( instance, params->context );
}
static HRESULT WINAPI hid_joystick_EnumObjects( IDirectInputDevice8W *iface, LPDIENUMDEVICEOBJECTSCALLBACKW callback,
void *context, DWORD flags )
{
static const DIPROPHEADER filter =
{
.dwSize = sizeof(filter),
.dwHeaderSize = sizeof(filter),
.dwHow = DIPH_DEVICE,
};
struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
struct enum_objects_params params =
{
.callback = callback,
.context = context,
};
BOOL ret;
TRACE( "iface %p, callback %p, context %p, flags %#x.\n", iface, callback, context, flags );
if (!callback) return DIERR_INVALIDPARAM;
if (flags & ~(DIDFT_AXIS | DIDFT_POV | DIDFT_BUTTON | DIDFT_NODATA | DIDFT_COLLECTION))
return DIERR_INVALIDPARAM;
if (flags == DIDFT_ALL || (flags & DIDFT_AXIS))
{
ret = enum_objects( impl, &filter, DIDFT_AXIS, enum_objects_callback, &params );
if (ret != DIENUM_CONTINUE) return DI_OK;
}
if (flags == DIDFT_ALL || (flags & DIDFT_POV))
{
ret = enum_objects( impl, &filter, DIDFT_POV, enum_objects_callback, &params );
if (ret != DIENUM_CONTINUE) return DI_OK;
}
if (flags == DIDFT_ALL || (flags & DIDFT_BUTTON))
{
ret = enum_objects( impl, &filter, DIDFT_BUTTON, enum_objects_callback, &params );
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, &params );
if (ret != DIENUM_CONTINUE) return DI_OK;
}
return DI_OK;
}
static BOOL get_property_prop_range( struct hid_joystick *impl, struct hid_value_caps *caps,
DIDEVICEOBJECTINSTANCEW *instance, void *data )
{
@ -1392,7 +1332,7 @@ static const IDirectInputDevice8WVtbl hid_joystick_vtbl =
hid_joystick_Release,
/*** IDirectInputDevice methods ***/
IDirectInputDevice2WImpl_GetCapabilities,
hid_joystick_EnumObjects,
IDirectInputDevice2WImpl_EnumObjects,
hid_joystick_GetProperty,
hid_joystick_SetProperty,
IDirectInputDevice2WImpl_Acquire,
@ -1616,11 +1556,33 @@ static HRESULT hid_joystick_internal_read( IDirectInputDevice8W *iface )
return hr;
}
struct enum_objects_params
{
LPDIENUMDEVICEOBJECTSCALLBACKW callback;
void *context;
};
static BOOL enum_objects_callback( struct hid_joystick *impl, struct hid_value_caps *caps,
DIDEVICEOBJECTINSTANCEW *instance, void *data )
{
struct enum_objects_params *params = data;
return params->callback( instance, params->context );
}
static HRESULT hid_joystick_internal_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *filter, DWORD flags,
LPDIENUMDEVICEOBJECTSCALLBACKW callback, void *context )
{
struct enum_objects_params params = {.callback = callback, .context = context};
struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
return enum_objects( impl, filter, flags, enum_objects_callback, &params );
}
static const struct dinput_device_vtbl hid_joystick_internal_vtbl =
{
hid_joystick_internal_read,
hid_joystick_internal_acquire,
hid_joystick_internal_unacquire,
hid_joystick_internal_enum_objects,
};
static DWORD device_type_for_version( DWORD type, DWORD version )

View File

@ -412,6 +412,7 @@ static const struct dinput_device_vtbl keyboard_internal_vtbl =
NULL,
keyboard_internal_acquire,
keyboard_internal_unacquire,
NULL,
};
static const IDirectInputDevice8WVtbl SysKeyboardWvt =

View File

@ -668,6 +668,7 @@ static const struct dinput_device_vtbl mouse_internal_vtbl =
NULL,
mouse_internal_acquire,
mouse_internal_unacquire,
NULL,
};
static const IDirectInputDevice8WVtbl SysMouseWvt =