dinput: Look for the PID device control output report.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
903c7ea75d
commit
ff7685dea4
|
@ -78,6 +78,13 @@ struct extra_caps
|
||||||
LONG saturation;
|
LONG saturation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct pid_control_report
|
||||||
|
{
|
||||||
|
BYTE id;
|
||||||
|
ULONG collection;
|
||||||
|
ULONG control_coll;
|
||||||
|
};
|
||||||
|
|
||||||
#define DEVICE_STATE_MAX_SIZE 1024
|
#define DEVICE_STATE_MAX_SIZE 1024
|
||||||
|
|
||||||
struct hid_joystick
|
struct hid_joystick
|
||||||
|
@ -102,6 +109,8 @@ struct hid_joystick
|
||||||
|
|
||||||
BYTE device_state_report_id;
|
BYTE device_state_report_id;
|
||||||
BYTE device_state[DEVICE_STATE_MAX_SIZE];
|
BYTE device_state[DEVICE_STATE_MAX_SIZE];
|
||||||
|
|
||||||
|
struct pid_control_report pid_device_control;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct hid_joystick *impl_from_IDirectInputDevice8W( IDirectInputDevice8W *iface )
|
static inline struct hid_joystick *impl_from_IDirectInputDevice8W( IDirectInputDevice8W *iface )
|
||||||
|
@ -1176,6 +1185,12 @@ static BOOL hid_joystick_device_try_open( UINT32 handle, const WCHAR *path, HAND
|
||||||
instance->wUsagePage = caps->UsagePage;
|
instance->wUsagePage = caps->UsagePage;
|
||||||
instance->wUsage = caps->Usage;
|
instance->wUsage = caps->Usage;
|
||||||
|
|
||||||
|
count = ARRAY_SIZE(buttons);
|
||||||
|
status = HidP_GetSpecificButtonCaps( HidP_Output, HID_USAGE_PAGE_PID, 0,
|
||||||
|
PID_USAGE_DC_DEVICE_RESET, buttons, &count, preparsed_data );
|
||||||
|
if (status == HIDP_STATUS_SUCCESS && count > 0)
|
||||||
|
instance->guidFFDriver = IID_IDirectInputPIDDriver;
|
||||||
|
|
||||||
count = ARRAY_SIZE(buttons);
|
count = ARRAY_SIZE(buttons);
|
||||||
status = HidP_GetSpecificButtonCaps( HidP_Input, HID_USAGE_PAGE_BUTTON, 0, 0, buttons, &count, preparsed_data );
|
status = HidP_GetSpecificButtonCaps( HidP_Input, HID_USAGE_PAGE_BUTTON, 0, 0, buttons, &count, preparsed_data );
|
||||||
if (status != HIDP_STATUS_SUCCESS) count = button_count = 0;
|
if (status != HIDP_STATUS_SUCCESS) count = button_count = 0;
|
||||||
|
@ -1398,6 +1413,67 @@ static BOOL init_data_format( struct hid_joystick *impl, struct hid_value_caps *
|
||||||
return DIENUM_CONTINUE;
|
return DIENUM_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL init_pid_reports( struct hid_joystick *impl, struct hid_value_caps *caps,
|
||||||
|
DIDEVICEOBJECTINSTANCEW *instance, void *data )
|
||||||
|
{
|
||||||
|
struct pid_control_report *device_control = &impl->pid_device_control;
|
||||||
|
|
||||||
|
#define SET_COLLECTION( rep ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (rep->collection) FIXME( "duplicate " #rep " report!\n" ); \
|
||||||
|
else rep->collection = DIDFT_GETINSTANCE( instance->dwType ); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SET_SUB_COLLECTION( rep, sub ) \
|
||||||
|
do { \
|
||||||
|
if (instance->wCollectionNumber != rep->collection) \
|
||||||
|
FIXME( "unexpected " #rep "." #sub " parent!\n" ); \
|
||||||
|
else if (rep->sub) \
|
||||||
|
FIXME( "duplicate " #rep "." #sub " collection!\n" ); \
|
||||||
|
else \
|
||||||
|
rep->sub = DIDFT_GETINSTANCE( instance->dwType ); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
if (instance->wUsagePage == HID_USAGE_PAGE_PID)
|
||||||
|
{
|
||||||
|
switch (instance->wUsage)
|
||||||
|
{
|
||||||
|
case PID_USAGE_DEVICE_CONTROL_REPORT: SET_COLLECTION( device_control ); break;
|
||||||
|
case PID_USAGE_DEVICE_CONTROL: SET_SUB_COLLECTION( device_control, control_coll ); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef SET_SUB_COLLECTION
|
||||||
|
#undef SET_COLLECTION
|
||||||
|
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL init_pid_caps( struct hid_joystick *impl, struct hid_value_caps *caps,
|
||||||
|
DIDEVICEOBJECTINSTANCEW *instance, void *data )
|
||||||
|
{
|
||||||
|
struct pid_control_report *device_control = &impl->pid_device_control;
|
||||||
|
|
||||||
|
if (!(instance->dwType & DIDFT_OUTPUT)) return DIENUM_CONTINUE;
|
||||||
|
|
||||||
|
#define SET_REPORT_ID( rep ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (!rep->id) \
|
||||||
|
rep->id = instance->wReportId; \
|
||||||
|
else if (rep->id != instance->wReportId) \
|
||||||
|
FIXME( "multiple " #rep " report ids!\n" ); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
if (instance->wCollectionNumber == device_control->control_coll)
|
||||||
|
SET_REPORT_ID( device_control );
|
||||||
|
|
||||||
|
#undef SET_REPORT_ID
|
||||||
|
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID *guid, IDirectInputDevice8W **out )
|
static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID *guid, IDirectInputDevice8W **out )
|
||||||
{
|
{
|
||||||
static const DIPROPHEADER filter =
|
static const DIPROPHEADER filter =
|
||||||
|
@ -1485,6 +1561,20 @@ static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID
|
||||||
impl->usages_buf = usages;
|
impl->usages_buf = usages;
|
||||||
|
|
||||||
enum_objects( impl, &filter, DIDFT_ALL, init_objects, NULL );
|
enum_objects( impl, &filter, DIDFT_ALL, init_objects, NULL );
|
||||||
|
enum_objects( impl, &filter, DIDFT_COLLECTION, init_pid_reports, NULL );
|
||||||
|
enum_objects( impl, &filter, DIDFT_NODATA, init_pid_caps, NULL );
|
||||||
|
|
||||||
|
TRACE( "device control id %u, coll %u, control coll %u\n", impl->pid_device_control.id,
|
||||||
|
impl->pid_device_control.collection, impl->pid_device_control.control_coll );
|
||||||
|
|
||||||
|
if (impl->pid_device_control.id)
|
||||||
|
{
|
||||||
|
impl->dev_caps.dwFlags |= DIDC_FORCEFEEDBACK;
|
||||||
|
impl->dev_caps.dwFFSamplePeriod = 1000000;
|
||||||
|
impl->dev_caps.dwFFMinTimeResolution = 1000000;
|
||||||
|
impl->dev_caps.dwHardwareRevision = 1;
|
||||||
|
impl->dev_caps.dwFFDriverVersion = 1;
|
||||||
|
}
|
||||||
|
|
||||||
format = impl->base.data_format.wine_df;
|
format = impl->base.data_format.wine_df;
|
||||||
if (format->dwDataSize > DEVICE_STATE_MAX_SIZE)
|
if (format->dwDataSize > DEVICE_STATE_MAX_SIZE)
|
||||||
|
|
|
@ -5646,7 +5646,6 @@ static void test_force_feedback_joystick( void )
|
||||||
check_member_wstr( devinst, expect_devinst, tszInstanceName );
|
check_member_wstr( devinst, expect_devinst, tszInstanceName );
|
||||||
todo_wine
|
todo_wine
|
||||||
check_member_wstr( devinst, expect_devinst, tszProductName );
|
check_member_wstr( devinst, expect_devinst, tszProductName );
|
||||||
todo_wine
|
|
||||||
check_member_guid( devinst, expect_devinst, guidFFDriver );
|
check_member_guid( devinst, expect_devinst, guidFFDriver );
|
||||||
check_member( devinst, expect_devinst, "%04x", wUsagePage );
|
check_member( devinst, expect_devinst, "%04x", wUsagePage );
|
||||||
check_member( devinst, expect_devinst, "%04x", wUsage );
|
check_member( devinst, expect_devinst, "%04x", wUsage );
|
||||||
|
@ -5655,20 +5654,15 @@ static void test_force_feedback_joystick( void )
|
||||||
hr = IDirectInputDevice8_GetCapabilities( device, &caps );
|
hr = IDirectInputDevice8_GetCapabilities( device, &caps );
|
||||||
ok( hr == DI_OK, "IDirectInputDevice8_GetCapabilities returned %#x\n", hr );
|
ok( hr == DI_OK, "IDirectInputDevice8_GetCapabilities returned %#x\n", hr );
|
||||||
check_member( caps, expect_caps, "%d", dwSize );
|
check_member( caps, expect_caps, "%d", dwSize );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", dwFlags );
|
check_member( caps, expect_caps, "%#x", dwFlags );
|
||||||
check_member( caps, expect_caps, "%#x", dwDevType );
|
check_member( caps, expect_caps, "%#x", dwDevType );
|
||||||
check_member( caps, expect_caps, "%d", dwAxes );
|
check_member( caps, expect_caps, "%d", dwAxes );
|
||||||
check_member( caps, expect_caps, "%d", dwButtons );
|
check_member( caps, expect_caps, "%d", dwButtons );
|
||||||
check_member( caps, expect_caps, "%d", dwPOVs );
|
check_member( caps, expect_caps, "%d", dwPOVs );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%d", dwFFSamplePeriod );
|
check_member( caps, expect_caps, "%d", dwFFSamplePeriod );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%d", dwFFMinTimeResolution );
|
check_member( caps, expect_caps, "%d", dwFFMinTimeResolution );
|
||||||
check_member( caps, expect_caps, "%d", dwFirmwareRevision );
|
check_member( caps, expect_caps, "%d", dwFirmwareRevision );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%d", dwHardwareRevision );
|
check_member( caps, expect_caps, "%d", dwHardwareRevision );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%d", dwFFDriverVersion );
|
check_member( caps, expect_caps, "%d", dwFFDriverVersion );
|
||||||
|
|
||||||
prop_dword.dwData = 0xdeadbeef;
|
prop_dword.dwData = 0xdeadbeef;
|
||||||
|
|
Loading…
Reference in New Issue