Based on a patch from Ivo Ivanov logos128@gmail.com.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 4 +++- dlls/dinput/device_private.h | 2 +- dlls/dinput/joystick_hid.c | 42 +++++++++++++++++++++++++++++------- dlls/dinput8/tests/hid.c | 13 ----------- 4 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 449adaffde2..f21d951d268 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1103,6 +1103,8 @@ static HRESULT WINAPI dinput_device_SetProperty( IDirectInputDevice8W *iface, co if (value->dwData > 10000) return DIERR_INVALIDPARAM; EnterCriticalSection( &impl->crit ); impl->device_gain = value->dwData; + if (!impl->acquired || !(impl->dwCoopLevel & DISCL_EXCLUSIVE)) hr = DI_OK; + else hr = impl->vtbl->send_device_gain( iface, impl->device_gain ); LeaveCriticalSection( &impl->crit ); return hr; } @@ -1520,7 +1522,7 @@ static HRESULT WINAPI dinput_device_SendForceFeedbackCommand( IDirectInputDevice
EnterCriticalSection( &impl->crit ); if (!impl->acquired || !(impl->dwCoopLevel & DISCL_EXCLUSIVE)) hr = DIERR_NOTEXCLUSIVEACQUIRED; - else hr = impl->vtbl->send_force_feedback_command( iface, command ); + else hr = impl->vtbl->send_force_feedback_command( iface, command, FALSE ); LeaveCriticalSection( &impl->crit );
return hr; diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index a2110942583..aeab89c840a 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -49,7 +49,7 @@ struct dinput_device_vtbl 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 ); + HRESULT (*send_force_feedback_command)( IDirectInputDevice8W *iface, DWORD command, BOOL unacquire ); HRESULT (*send_device_gain)( IDirectInputDevice8W *iface, LONG device_gain ); HRESULT (*enum_created_effect_objects)( IDirectInputDevice8W *iface, LPDIENUMCREATEDEFFECTOBJECTSCALLBACK callback, void *context, DWORD flags ); diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 0502362de2f..6cd537c5776 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -674,11 +674,11 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter, return DIENUM_CONTINUE; }
-static void set_parameter_value( struct hid_joystick_effect *impl, char *report_buf, - struct hid_value_caps *caps, LONG value ) +static void set_report_value( struct hid_joystick *impl, char *report_buf, + struct hid_value_caps *caps, LONG value ) { - ULONG report_len = impl->joystick->caps.OutputReportByteLength; - PHIDP_PREPARSED_DATA preparsed = impl->joystick->preparsed; + ULONG report_len = impl->caps.OutputReportByteLength; + PHIDP_PREPARSED_DATA preparsed = impl->preparsed; LONG log_min, log_max, phy_min, phy_max; NTSTATUS status;
@@ -819,9 +819,23 @@ static void set_extra_caps_range( struct hid_joystick *impl, const DIDEVICEOBJEC
static HRESULT hid_joystick_send_device_gain( IDirectInputDevice8W *iface, LONG device_gain ) { - FIXME( "iface %p stub!\n", iface ); + struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); + struct pid_device_gain *report = &impl->pid_device_gain; + ULONG report_len = impl->caps.OutputReportByteLength; + char *report_buf = impl->output_report_buf; + NTSTATUS status;
- return DIERR_UNSUPPORTED; + TRACE( "iface %p.\n", iface ); + + if (!report->id || !report->device_gain_caps) return DI_OK; + + status = HidP_InitializeReportForID( HidP_Output, report->id, impl->preparsed, report_buf, report_len ); + if (status != HIDP_STATUS_SUCCESS) return status; + + set_report_value( impl, report_buf, report->device_gain_caps, device_gain ); + + if (!WriteFile( impl->device, report_buf, report_len, NULL, NULL )) return DIERR_INPUTLOST; + return DI_OK; }
static HRESULT hid_joystick_set_property( IDirectInputDevice8W *iface, DWORD property, @@ -884,6 +898,8 @@ static HRESULT hid_joystick_acquire( IDirectInputDevice8W *iface ) return DI_OK; }
+static HRESULT hid_joystick_send_force_feedback_command( IDirectInputDevice8W *iface, DWORD command, BOOL unacquire ); + static HRESULT hid_joystick_unacquire( IDirectInputDevice8W *iface ) { struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); @@ -895,7 +911,9 @@ static HRESULT hid_joystick_unacquire( IDirectInputDevice8W *iface ) if (!ret) WARN( "CancelIoEx failed, last error %u\n", GetLastError() ); else WaitForSingleObject( impl->base.read_event, INFINITE );
- IDirectInputDevice8_SendForceFeedbackCommand( iface, DISFFC_RESET ); + if (!(impl->base.caps.dwFlags & DIDC_FORCEFEEDBACK)) return DI_OK; + if (!impl->base.acquired || !(impl->base.dwCoopLevel & DISCL_EXCLUSIVE)) return DI_OK; + hid_joystick_send_force_feedback_command( iface, DISFFC_RESET, TRUE ); return DI_OK; }
@@ -1027,7 +1045,7 @@ static BOOL CALLBACK unload_effect_object( IDirectInputEffect *effect, void *con return DIENUM_CONTINUE; }
-static HRESULT hid_joystick_send_force_feedback_command( IDirectInputDevice8W *iface, DWORD command ) +static HRESULT hid_joystick_send_force_feedback_command( IDirectInputDevice8W *iface, DWORD command, BOOL unacquire ) { struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); struct pid_control_report *report = &impl->pid_device_control; @@ -1060,6 +1078,8 @@ static HRESULT hid_joystick_send_force_feedback_command( IDirectInputDevice8W *i if (status != HIDP_STATUS_SUCCESS) return status;
if (!WriteFile( impl->device, report_buf, report_len, NULL, NULL )) return DIERR_INPUTLOST; + if (!unacquire) hid_joystick_send_device_gain( iface, impl->base.device_gain ); + return DI_OK; }
@@ -2655,6 +2675,12 @@ static HRESULT WINAPI hid_joystick_effect_GetEffectStatus( IDirectInputEffect *i return DIERR_UNSUPPORTED; }
+static void set_parameter_value( struct hid_joystick_effect *impl, char *report_buf, + struct hid_value_caps *caps, LONG value ) +{ + return set_report_value( impl->joystick, report_buf, caps, value ); +} + static void set_parameter_value_us( struct hid_joystick_effect *impl, char *report_buf, struct hid_value_caps *caps, LONG value ) { diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index ba5a26b3945..ac4b8023611 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -754,15 +754,7 @@ static BOOL sync_ioctl( HANDLE file, DWORD code, void *in_buf, DWORD in_len, voi if (!ret && GetLastError() == ERROR_IO_PENDING) { ret = GetOverlappedResultEx( file, &ovl, &out_len, timeout, TRUE ); - todo_wine_if( timeout != INFINITE ) ok( ret, "GetOverlappedResultEx returned %u\n", GetLastError() ); - if (!ret) - { - ret = CancelIoEx( file, &ovl ); - ok( ret, "CancelIoEx returned %u\n", GetLastError() ); - ret = WaitForSingleObject( ovl.hEvent, INFINITE ); - ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n" ); - } } CloseHandle( ovl.hEvent );
@@ -793,7 +785,6 @@ static void set_hid_expect_( int line, HANDLE file, struct hid_expect *expect, D static void wait_hid_expect_( int line, HANDLE file, DWORD timeout ) { BOOL ret = sync_ioctl( file, IOCTL_WINETEST_HID_WAIT_EXPECT, NULL, 0, NULL, 0, timeout ); - todo_wine ok( ret, "IOCTL_WINETEST_HID_WAIT_EXPECT failed, last error %u\n", GetLastError() );
set_hid_expect( file, NULL, 0 ); @@ -5584,7 +5575,6 @@ static void test_periodic_effect( IDirectInputDevice8W *device, HANDLE file, DWO .report_id = 8, .report_len = 2, .report_buf = {8, 0x19}, - .todo = TRUE, }, }; struct hid_expect expect_reset[] = @@ -6947,7 +6937,6 @@ static void test_force_feedback_joystick( DWORD version ) .report_id = 8, .report_len = 2, .report_buf = {8, 0x19}, - .todo = TRUE, }, }; struct hid_expect expect_reset[] = @@ -6965,7 +6954,6 @@ static void test_force_feedback_joystick( DWORD version ) .report_id = 8, .report_len = 2, .report_buf = {8, 0x19}, - .todo = TRUE, }; struct hid_expect expect_set_device_gain_2 = { @@ -6973,7 +6961,6 @@ static void test_force_feedback_joystick( DWORD version ) .report_id = 8, .report_len = 2, .report_buf = {8, 0x33}, - .todo = TRUE, };
const DIDEVICEINSTANCEW expect_devinst =