dinput: Implement hid_joystick_SendForceFeedbackCommand.

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-01 09:31:02 +02:00 committed by Alexandre Julliard
parent ff7685dea4
commit a382646e38
2 changed files with 51 additions and 18 deletions

View File

@ -104,6 +104,7 @@ struct hid_joystick
struct extra_caps *input_extra_caps;
char *input_report_buf;
char *output_report_buf;
USAGE_AND_PAGE *usages_buf;
ULONG usages_count;
@ -369,6 +370,7 @@ static ULONG WINAPI hid_joystick_Release( IDirectInputDevice8W *iface )
if (!(ref = IDirectInputDevice2WImpl_Release( iface )))
{
HeapFree( GetProcessHeap(), 0, tmp.usages_buf );
HeapFree( GetProcessHeap(), 0, tmp.output_report_buf );
HeapFree( GetProcessHeap(), 0, tmp.input_report_buf );
HeapFree( GetProcessHeap(), 0, tmp.input_extra_caps );
HidD_FreePreparsedData( tmp.preparsed );
@ -833,20 +835,48 @@ static HRESULT WINAPI hid_joystick_GetForceFeedbackState( IDirectInputDevice8W *
static HRESULT WINAPI hid_joystick_SendForceFeedbackCommand( IDirectInputDevice8W *iface, DWORD command )
{
FIXME( "iface %p, command %x stub!\n", iface, command );
struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
struct pid_control_report *report = &impl->pid_device_control;
ULONG report_len = impl->caps.OutputReportByteLength;
char *report_buf = impl->output_report_buf;
NTSTATUS status;
USAGE usage;
ULONG count;
HRESULT hr;
TRACE( "iface %p, flags %x.\n", iface, command );
switch (command)
{
case DISFFC_RESET:
case DISFFC_STOPALL:
case DISFFC_PAUSE:
case DISFFC_CONTINUE:
case DISFFC_SETACTUATORSON:
case DISFFC_SETACTUATORSOFF:
return DIERR_UNSUPPORTED;
case DISFFC_RESET: usage = PID_USAGE_DC_DEVICE_RESET; break;
case DISFFC_STOPALL: usage = PID_USAGE_DC_STOP_ALL_EFFECTS; break;
case DISFFC_PAUSE: usage = PID_USAGE_DC_DEVICE_PAUSE; break;
case DISFFC_CONTINUE: usage = PID_USAGE_DC_DEVICE_CONTINUE; break;
case DISFFC_SETACTUATORSON: usage = PID_USAGE_DC_ENABLE_ACTUATORS; break;
case DISFFC_SETACTUATORSOFF: usage = PID_USAGE_DC_DISABLE_ACTUATORS; break;
default: return DIERR_INVALIDPARAM;
}
return DIERR_INVALIDPARAM;
if (!(impl->dev_caps.dwFlags & DIDC_FORCEFEEDBACK)) return DIERR_UNSUPPORTED;
EnterCriticalSection( &impl->base.crit );
if (!impl->base.acquired || !(impl->base.dwCoopLevel & DISCL_EXCLUSIVE))
hr = DIERR_NOTEXCLUSIVEACQUIRED;
else
{
count = 1;
status = HidP_InitializeReportForID( HidP_Output, report->id, impl->preparsed, report_buf, report_len );
if (status != HIDP_STATUS_SUCCESS) hr = status;
else status = HidP_SetUsages( HidP_Output, HID_USAGE_PAGE_PID, report->control_coll, &usage,
&count, impl->preparsed, report_buf, report_len );
if (status != HIDP_STATUS_SUCCESS) hr = status;
else if (WriteFile( impl->device, report_buf, report_len, NULL, NULL )) hr = DI_OK;
else hr = DIERR_GENERIC;
}
LeaveCriticalSection( &impl->base.crit );
return hr;
}
static HRESULT WINAPI hid_joystick_EnumCreatedEffectObjects( IDirectInputDevice8W *iface,
@ -1555,6 +1585,9 @@ static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID
size = impl->caps.InputReportByteLength;
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size ))) goto failed;
impl->input_report_buf = buffer;
size = impl->caps.OutputReportByteLength;
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size ))) goto failed;
impl->output_report_buf = buffer;
impl->usages_count = HidP_MaxUsageListLength( HidP_Input, 0, impl->preparsed );
size = impl->usages_count * sizeof(USAGE_AND_PAGE);
if (!(usages = HeapAlloc( GetProcessHeap(), 0, size ))) goto failed;

View File

@ -5253,6 +5253,13 @@ static void test_force_feedback_joystick( void )
.dwFFDriverVersion = 1,
};
struct hid_expect expect_dc_reset =
{
.code = IOCTL_HID_WRITE_REPORT,
.report_id = 1,
.report_len = 2,
.report_buf = {1, 0x01},
};
struct hid_expect expect_dc_reset_todo =
{
.code = IOCTL_HID_WRITE_REPORT,
.todo = TRUE,
@ -5751,7 +5758,6 @@ static void test_force_feedback_joystick( void )
todo_wine
ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "IDirectInputDevice8_GetForceFeedbackState returned %#x\n", hr );
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_RESET );
todo_wine
ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
escape.dwSize = sizeof(DIEFFESCAPE);
@ -5769,7 +5775,7 @@ static void test_force_feedback_joystick( void )
hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE );
ok( hr == DI_OK, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr );
set_hid_expect( file, &expect_dc_reset, sizeof(expect_dc_reset) );
set_hid_expect( file, &expect_dc_reset_todo, sizeof(expect_dc_reset_todo) );
hr = IDirectInputDevice8_Acquire( device );
ok( hr == DI_OK, "IDirectInputDevice8_Acquire returned: %#x\n", hr );
set_hid_expect( file, NULL, 0 );
@ -5792,24 +5798,18 @@ static void test_force_feedback_joystick( void )
set_hid_expect( file, &expect_dc_reset, sizeof(expect_dc_reset) );
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_RESET );
todo_wine
ok( hr == DI_OK, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
set_hid_expect( file, NULL, 0 );
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_STOPALL );
todo_wine
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_PAUSE );
todo_wine
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_CONTINUE );
todo_wine
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSON );
todo_wine
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSOFF );
todo_wine
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
objdata.dwOfs = 0x1e;
@ -5821,7 +5821,7 @@ static void test_force_feedback_joystick( void )
test_periodic_effect( device, file );
set_hid_expect( file, &expect_dc_reset, sizeof(expect_dc_reset) );
set_hid_expect( file, &expect_dc_reset_todo, sizeof(expect_dc_reset_todo) );
hr = IDirectInputDevice8_Unacquire( device );
ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr );
set_hid_expect( file, NULL, 0 );