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:
parent
ff7685dea4
commit
a382646e38
|
@ -104,6 +104,7 @@ struct hid_joystick
|
||||||
struct extra_caps *input_extra_caps;
|
struct extra_caps *input_extra_caps;
|
||||||
|
|
||||||
char *input_report_buf;
|
char *input_report_buf;
|
||||||
|
char *output_report_buf;
|
||||||
USAGE_AND_PAGE *usages_buf;
|
USAGE_AND_PAGE *usages_buf;
|
||||||
ULONG usages_count;
|
ULONG usages_count;
|
||||||
|
|
||||||
|
@ -369,6 +370,7 @@ static ULONG WINAPI hid_joystick_Release( IDirectInputDevice8W *iface )
|
||||||
if (!(ref = IDirectInputDevice2WImpl_Release( iface )))
|
if (!(ref = IDirectInputDevice2WImpl_Release( iface )))
|
||||||
{
|
{
|
||||||
HeapFree( GetProcessHeap(), 0, tmp.usages_buf );
|
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_report_buf );
|
||||||
HeapFree( GetProcessHeap(), 0, tmp.input_extra_caps );
|
HeapFree( GetProcessHeap(), 0, tmp.input_extra_caps );
|
||||||
HidD_FreePreparsedData( tmp.preparsed );
|
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 )
|
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)
|
switch (command)
|
||||||
{
|
{
|
||||||
case DISFFC_RESET:
|
case DISFFC_RESET: usage = PID_USAGE_DC_DEVICE_RESET; break;
|
||||||
case DISFFC_STOPALL:
|
case DISFFC_STOPALL: usage = PID_USAGE_DC_STOP_ALL_EFFECTS; break;
|
||||||
case DISFFC_PAUSE:
|
case DISFFC_PAUSE: usage = PID_USAGE_DC_DEVICE_PAUSE; break;
|
||||||
case DISFFC_CONTINUE:
|
case DISFFC_CONTINUE: usage = PID_USAGE_DC_DEVICE_CONTINUE; break;
|
||||||
case DISFFC_SETACTUATORSON:
|
case DISFFC_SETACTUATORSON: usage = PID_USAGE_DC_ENABLE_ACTUATORS; break;
|
||||||
case DISFFC_SETACTUATORSOFF:
|
case DISFFC_SETACTUATORSOFF: usage = PID_USAGE_DC_DISABLE_ACTUATORS; break;
|
||||||
return DIERR_UNSUPPORTED;
|
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,
|
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;
|
size = impl->caps.InputReportByteLength;
|
||||||
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size ))) goto failed;
|
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size ))) goto failed;
|
||||||
impl->input_report_buf = buffer;
|
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 );
|
impl->usages_count = HidP_MaxUsageListLength( HidP_Input, 0, impl->preparsed );
|
||||||
size = impl->usages_count * sizeof(USAGE_AND_PAGE);
|
size = impl->usages_count * sizeof(USAGE_AND_PAGE);
|
||||||
if (!(usages = HeapAlloc( GetProcessHeap(), 0, size ))) goto failed;
|
if (!(usages = HeapAlloc( GetProcessHeap(), 0, size ))) goto failed;
|
||||||
|
|
|
@ -5253,6 +5253,13 @@ static void test_force_feedback_joystick( void )
|
||||||
.dwFFDriverVersion = 1,
|
.dwFFDriverVersion = 1,
|
||||||
};
|
};
|
||||||
struct hid_expect expect_dc_reset =
|
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,
|
.code = IOCTL_HID_WRITE_REPORT,
|
||||||
.todo = TRUE,
|
.todo = TRUE,
|
||||||
|
@ -5751,7 +5758,6 @@ static void test_force_feedback_joystick( void )
|
||||||
todo_wine
|
todo_wine
|
||||||
ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "IDirectInputDevice8_GetForceFeedbackState returned %#x\n", hr );
|
ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "IDirectInputDevice8_GetForceFeedbackState returned %#x\n", hr );
|
||||||
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_RESET );
|
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_RESET );
|
||||||
todo_wine
|
|
||||||
ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
ok( hr == DIERR_NOTEXCLUSIVEACQUIRED, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
||||||
|
|
||||||
escape.dwSize = sizeof(DIEFFESCAPE);
|
escape.dwSize = sizeof(DIEFFESCAPE);
|
||||||
|
@ -5769,7 +5775,7 @@ static void test_force_feedback_joystick( void )
|
||||||
hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE );
|
hr = IDirectInputDevice8_SetCooperativeLevel( device, hwnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE );
|
||||||
ok( hr == DI_OK, "IDirectInputDevice8_SetCooperativeLevel returned: %#x\n", hr );
|
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 );
|
hr = IDirectInputDevice8_Acquire( device );
|
||||||
ok( hr == DI_OK, "IDirectInputDevice8_Acquire returned: %#x\n", hr );
|
ok( hr == DI_OK, "IDirectInputDevice8_Acquire returned: %#x\n", hr );
|
||||||
set_hid_expect( file, NULL, 0 );
|
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) );
|
set_hid_expect( file, &expect_dc_reset, sizeof(expect_dc_reset) );
|
||||||
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_RESET );
|
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_RESET );
|
||||||
todo_wine
|
|
||||||
ok( hr == DI_OK, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
ok( hr == DI_OK, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
||||||
set_hid_expect( file, NULL, 0 );
|
set_hid_expect( file, NULL, 0 );
|
||||||
|
|
||||||
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_STOPALL );
|
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_STOPALL );
|
||||||
todo_wine
|
|
||||||
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
||||||
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_PAUSE );
|
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_PAUSE );
|
||||||
todo_wine
|
|
||||||
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
||||||
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_CONTINUE );
|
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_CONTINUE );
|
||||||
todo_wine
|
|
||||||
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
||||||
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSON );
|
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSON );
|
||||||
todo_wine
|
|
||||||
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
||||||
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSOFF );
|
hr = IDirectInputDevice8_SendForceFeedbackCommand( device, DISFFC_SETACTUATORSOFF );
|
||||||
todo_wine
|
|
||||||
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
ok( hr == HIDP_STATUS_USAGE_NOT_FOUND, "IDirectInputDevice8_SendForceFeedbackCommand returned %#x\n", hr );
|
||||||
|
|
||||||
objdata.dwOfs = 0x1e;
|
objdata.dwOfs = 0x1e;
|
||||||
|
@ -5821,7 +5821,7 @@ static void test_force_feedback_joystick( void )
|
||||||
|
|
||||||
test_periodic_effect( device, file );
|
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 );
|
hr = IDirectInputDevice8_Unacquire( device );
|
||||||
ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr );
|
ok( hr == DI_OK, "IDirectInputDevice8_Unacquire returned: %#x\n", hr );
|
||||||
set_hid_expect( file, NULL, 0 );
|
set_hid_expect( file, NULL, 0 );
|
||||||
|
|
Loading…
Reference in New Issue