Rémi Bernon : dinput: Write PID device gain reports when necessary.
Alexandre Julliard
julliard at winehq.org
Wed Nov 17 16:27:57 CST 2021
Module: wine
Branch: master
Commit: 45986545f82aef8ad7c56ec77a449c45fda8a4fd
URL: https://source.winehq.org/git/wine.git/?a=commit;h=45986545f82aef8ad7c56ec77a449c45fda8a4fd
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Wed Nov 17 11:51:53 2021 +0100
dinput: Write PID device gain reports when necessary.
Based on a patch from Ivo Ivanov <logos128 at gmail.com>.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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 =
More information about the wine-cvs
mailing list