dinput: Move GetProperty implementation for objects to generic device.

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-11-18 09:53:17 +01:00 committed by Alexandre Julliard
parent 3834eaf9bd
commit 0c9cac9547
6 changed files with 95 additions and 67 deletions

View file

@ -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, &params );
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:
{

View file

@ -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 */

View file

@ -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;

View file

@ -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)
{

View file

@ -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,

View file

@ -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 );