dinput/tests: Add some Windows.Gaming.Input.ForceFeedback.ConditionForceEffect tests.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e9f430d955
commit
ea71b9f81b
|
@ -4985,21 +4985,21 @@ static void test_windows_gaming_input(void)
|
||||||
END_COLLECTION,
|
END_COLLECTION,
|
||||||
|
|
||||||
USAGE(1, PID_USAGE_CP_OFFSET),
|
USAGE(1, PID_USAGE_CP_OFFSET),
|
||||||
LOGICAL_MINIMUM(1, 0x80),
|
LOGICAL_MINIMUM(2, -10000),
|
||||||
LOGICAL_MAXIMUM(1, 0x7f),
|
LOGICAL_MAXIMUM(2, +10000),
|
||||||
PHYSICAL_MINIMUM(2, 0xd8f0),
|
PHYSICAL_MINIMUM(2, -10000),
|
||||||
PHYSICAL_MAXIMUM(2, 0x2710),
|
PHYSICAL_MAXIMUM(2, +10000),
|
||||||
REPORT_SIZE(1, 8),
|
REPORT_SIZE(1, 16),
|
||||||
REPORT_COUNT(1, 1),
|
REPORT_COUNT(1, 1),
|
||||||
OUTPUT(1, Data|Var|Abs),
|
OUTPUT(1, Data|Var|Abs),
|
||||||
|
|
||||||
USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT),
|
USAGE(1, PID_USAGE_POSITIVE_COEFFICIENT),
|
||||||
USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT),
|
USAGE(1, PID_USAGE_NEGATIVE_COEFFICIENT),
|
||||||
LOGICAL_MINIMUM(1, 0x80),
|
LOGICAL_MINIMUM(2, -10000),
|
||||||
LOGICAL_MAXIMUM(1, 0x7f),
|
LOGICAL_MAXIMUM(2, +10000),
|
||||||
PHYSICAL_MINIMUM(2, 0xd8f0),
|
PHYSICAL_MINIMUM(2, -10000),
|
||||||
PHYSICAL_MAXIMUM(2, 0x2710),
|
PHYSICAL_MAXIMUM(2, +10000),
|
||||||
REPORT_SIZE(1, 8),
|
REPORT_SIZE(1, 16),
|
||||||
REPORT_COUNT(1, 2),
|
REPORT_COUNT(1, 2),
|
||||||
OUTPUT(1, Data|Var|Abs),
|
OUTPUT(1, Data|Var|Abs),
|
||||||
|
|
||||||
|
@ -5008,7 +5008,7 @@ static void test_windows_gaming_input(void)
|
||||||
LOGICAL_MINIMUM(1, 0),
|
LOGICAL_MINIMUM(1, 0),
|
||||||
LOGICAL_MAXIMUM(2, 0x00ff),
|
LOGICAL_MAXIMUM(2, 0x00ff),
|
||||||
PHYSICAL_MINIMUM(1, 0),
|
PHYSICAL_MINIMUM(1, 0),
|
||||||
PHYSICAL_MAXIMUM(2, 0x2710),
|
PHYSICAL_MAXIMUM(2, 10000),
|
||||||
REPORT_SIZE(1, 8),
|
REPORT_SIZE(1, 8),
|
||||||
REPORT_COUNT(1, 2),
|
REPORT_COUNT(1, 2),
|
||||||
OUTPUT(1, Data|Var|Abs),
|
OUTPUT(1, Data|Var|Abs),
|
||||||
|
@ -5017,7 +5017,7 @@ static void test_windows_gaming_input(void)
|
||||||
LOGICAL_MINIMUM(1, 0),
|
LOGICAL_MINIMUM(1, 0),
|
||||||
LOGICAL_MAXIMUM(2, 0x00ff),
|
LOGICAL_MAXIMUM(2, 0x00ff),
|
||||||
PHYSICAL_MINIMUM(1, 0),
|
PHYSICAL_MINIMUM(1, 0),
|
||||||
PHYSICAL_MAXIMUM(2, 0x2710),
|
PHYSICAL_MAXIMUM(2, 10000),
|
||||||
REPORT_SIZE(1, 8),
|
REPORT_SIZE(1, 8),
|
||||||
REPORT_COUNT(1, 1),
|
REPORT_COUNT(1, 1),
|
||||||
OUTPUT(1, Data|Var|Abs),
|
OUTPUT(1, Data|Var|Abs),
|
||||||
|
@ -5494,6 +5494,47 @@ static void test_windows_gaming_input(void)
|
||||||
.todo = TRUE,
|
.todo = TRUE,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
struct hid_expect expect_create_condition[] =
|
||||||
|
{
|
||||||
|
/* create new effect */
|
||||||
|
{
|
||||||
|
.code = IOCTL_HID_SET_FEATURE,
|
||||||
|
.report_id = 2,
|
||||||
|
.report_len = 3,
|
||||||
|
.report_buf = {2,0x03,0x00},
|
||||||
|
},
|
||||||
|
/* block load */
|
||||||
|
{
|
||||||
|
.code = IOCTL_HID_GET_FEATURE,
|
||||||
|
.report_id = 3,
|
||||||
|
.report_len = 5,
|
||||||
|
.report_buf = {3,0x01,0x01,0x00,0x00},
|
||||||
|
},
|
||||||
|
/* set condition */
|
||||||
|
{
|
||||||
|
.code = IOCTL_HID_WRITE_REPORT,
|
||||||
|
.report_id = 4,
|
||||||
|
.report_len = 12,
|
||||||
|
.report_buf = {4,0x01,0x00,0x70,0x17,0x7b,0x02,0xe9,0x04,0x4c,0x66,0x7f},
|
||||||
|
.todo = TRUE,
|
||||||
|
},
|
||||||
|
/* update effect */
|
||||||
|
{
|
||||||
|
.code = IOCTL_HID_WRITE_REPORT,
|
||||||
|
.report_id = 3,
|
||||||
|
.report_len = 18,
|
||||||
|
.report_buf = {3,0x01,0x03,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00},
|
||||||
|
.wine_only = TRUE,
|
||||||
|
.todo = TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.code = IOCTL_HID_WRITE_REPORT,
|
||||||
|
.report_id = 3,
|
||||||
|
.report_len = 18,
|
||||||
|
.report_buf = {3,0x01,0x03,0x08,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x00,0x00,0x00},
|
||||||
|
.todo = TRUE,
|
||||||
|
},
|
||||||
|
};
|
||||||
struct hid_expect expect_create_constant[] =
|
struct hid_expect expect_create_constant[] =
|
||||||
{
|
{
|
||||||
/* create new effect */
|
/* create new effect */
|
||||||
|
@ -5625,6 +5666,7 @@ static void test_windows_gaming_input(void)
|
||||||
.report_buf = {5,0x01},
|
.report_buf = {5,0x01},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
static const WCHAR *condition_effect_class_name = RuntimeClass_Windows_Gaming_Input_ForceFeedback_ConditionForceEffect;
|
||||||
static const WCHAR *periodic_effect_class_name = RuntimeClass_Windows_Gaming_Input_ForceFeedback_PeriodicForceEffect;
|
static const WCHAR *periodic_effect_class_name = RuntimeClass_Windows_Gaming_Input_ForceFeedback_PeriodicForceEffect;
|
||||||
static const WCHAR *constant_effect_class_name = RuntimeClass_Windows_Gaming_Input_ForceFeedback_ConstantForceEffect;
|
static const WCHAR *constant_effect_class_name = RuntimeClass_Windows_Gaming_Input_ForceFeedback_ConstantForceEffect;
|
||||||
static const WCHAR *force_feedback_motor = RuntimeClass_Windows_Gaming_Input_ForceFeedback_ForceFeedbackMotor;
|
static const WCHAR *force_feedback_motor = RuntimeClass_Windows_Gaming_Input_ForceFeedback_ForceFeedbackMotor;
|
||||||
|
@ -5647,11 +5689,14 @@ static void test_windows_gaming_input(void)
|
||||||
IAsyncOperationCompletedHandler_boolean *tmp_handler;
|
IAsyncOperationCompletedHandler_boolean *tmp_handler;
|
||||||
struct result_async_handler result_async_handler;
|
struct result_async_handler result_async_handler;
|
||||||
IVectorView_RawGameController *controllers_view;
|
IVectorView_RawGameController *controllers_view;
|
||||||
|
IConditionForceEffectFactory *condition_factory;
|
||||||
IRawGameControllerStatics *controller_statics;
|
IRawGameControllerStatics *controller_statics;
|
||||||
EventRegistrationToken controller_added_token;
|
EventRegistrationToken controller_added_token;
|
||||||
IPeriodicForceEffectFactory *periodic_factory;
|
IPeriodicForceEffectFactory *periodic_factory;
|
||||||
struct bool_async_handler bool_async_handler;
|
struct bool_async_handler bool_async_handler;
|
||||||
IVectorView_ForceFeedbackMotor *motors_view;
|
IVectorView_ForceFeedbackMotor *motors_view;
|
||||||
|
IConditionForceEffect *condition_effect;
|
||||||
|
ConditionForceEffectKind condition_kind;
|
||||||
ForceFeedbackEffectAxes supported_axes;
|
ForceFeedbackEffectAxes supported_axes;
|
||||||
IActivationFactory *activation_factory;
|
IActivationFactory *activation_factory;
|
||||||
IPeriodicForceEffect *periodic_effect;
|
IPeriodicForceEffect *periodic_effect;
|
||||||
|
@ -6152,6 +6197,109 @@ static void test_windows_gaming_input(void)
|
||||||
|
|
||||||
|
|
||||||
skip_periodic:
|
skip_periodic:
|
||||||
|
hr = pWindowsCreateString( condition_effect_class_name, wcslen( condition_effect_class_name ), &str );
|
||||||
|
ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr );
|
||||||
|
hr = pRoGetActivationFactory( str, &IID_IConditionForceEffectFactory, (void **)&condition_factory );
|
||||||
|
todo_wine
|
||||||
|
ok( hr == S_OK, "RoGetActivationFactory returned %#lx\n", hr );
|
||||||
|
pWindowsDeleteString( str );
|
||||||
|
if (hr != S_OK) goto skip_condition;
|
||||||
|
|
||||||
|
check_interface( condition_factory, &IID_IUnknown, TRUE );
|
||||||
|
check_interface( condition_factory, &IID_IInspectable, TRUE );
|
||||||
|
check_interface( condition_factory, &IID_IAgileObject, TRUE );
|
||||||
|
check_interface( condition_factory, &IID_IActivationFactory, TRUE );
|
||||||
|
check_interface( condition_factory, &IID_IConditionForceEffectFactory, TRUE );
|
||||||
|
check_interface( condition_factory, &IID_IPeriodicForceEffectFactory, FALSE );
|
||||||
|
|
||||||
|
hr = IConditionForceEffectFactory_QueryInterface( condition_factory, &IID_IActivationFactory, (void **)&activation_factory );
|
||||||
|
ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
|
||||||
|
hr = IActivationFactory_ActivateInstance( activation_factory, &tmp_inspectable );
|
||||||
|
ok( hr == E_NOTIMPL, "ActivateInstance returned %#lx\n", hr );
|
||||||
|
IActivationFactory_Release( activation_factory );
|
||||||
|
|
||||||
|
|
||||||
|
hr = IConditionForceEffectFactory_CreateInstance( condition_factory, ConditionForceEffectKind_Spring, &effect );
|
||||||
|
ok( hr == S_OK, "CreateInstance returned %#lx\n", hr );
|
||||||
|
|
||||||
|
check_interface( effect, &IID_IUnknown, TRUE );
|
||||||
|
check_interface( effect, &IID_IInspectable, TRUE );
|
||||||
|
check_interface( effect, &IID_IAgileObject, TRUE );
|
||||||
|
check_interface( effect, &IID_IForceFeedbackEffect, TRUE );
|
||||||
|
check_interface( effect, &IID_IConditionForceEffect, TRUE );
|
||||||
|
check_interface( effect, &IID_IPeriodicForceEffect, FALSE );
|
||||||
|
check_runtimeclass( effect, condition_effect_class_name );
|
||||||
|
|
||||||
|
hr = IForceFeedbackEffect_QueryInterface( effect, &IID_IConditionForceEffect, (void **)&condition_effect );
|
||||||
|
ok( hr == S_OK, "QueryInterface returned %#lx\n", hr );
|
||||||
|
|
||||||
|
hr = IConditionForceEffect_get_Kind( condition_effect, &condition_kind );
|
||||||
|
ok( hr == S_OK, "get_Kind returned %#lx\n", hr );
|
||||||
|
ok( condition_kind == ConditionForceEffectKind_Spring, "got kind %u\n", condition_kind );
|
||||||
|
hr = IConditionForceEffect_SetParameters( condition_effect, direction, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6 );
|
||||||
|
todo_wine
|
||||||
|
ok( hr == S_OK, "SetParameters returned %#lx\n", hr );
|
||||||
|
IConditionForceEffect_Release( condition_effect );
|
||||||
|
|
||||||
|
set_hid_expect( file, expect_create_condition, sizeof(expect_create_condition) );
|
||||||
|
hr = IForceFeedbackMotor_LoadEffectAsync( motor, effect, &result_async );
|
||||||
|
ok( hr == S_OK, "LoadEffectAsync returned %#lx\n", hr );
|
||||||
|
result_async_handler = default_result_async_handler;
|
||||||
|
result_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL );
|
||||||
|
ok( !!result_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() );
|
||||||
|
hr = IAsyncOperation_ForceFeedbackLoadEffectResult_put_Completed( result_async, &result_async_handler.IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult_iface );
|
||||||
|
ok( hr == S_OK, "put_Completed returned %#lx\n", hr );
|
||||||
|
ret = WaitForSingleObject( result_async_handler.event, 5000 );
|
||||||
|
ok( !ret, "WaitForSingleObject returned %#lx\n", ret );
|
||||||
|
ret = CloseHandle( result_async_handler.event );
|
||||||
|
ok( ret, "CloseHandle failed, error %lu\n", GetLastError() );
|
||||||
|
check_result_async( result_async, 1, Completed, S_OK, ForceFeedbackLoadEffectResult_Succeeded );
|
||||||
|
ref = IAsyncOperation_ForceFeedbackLoadEffectResult_Release( result_async );
|
||||||
|
ok( ref == 0, "Release returned %lu\n", ref );
|
||||||
|
set_hid_expect( file, NULL, 0 );
|
||||||
|
|
||||||
|
set_hid_expect( file, &expect_effect_start, sizeof(expect_effect_start) );
|
||||||
|
hr = IForceFeedbackEffect_Start( effect );
|
||||||
|
todo_wine
|
||||||
|
ok( hr == S_OK, "Start returned %#lx\n", hr );
|
||||||
|
set_hid_expect( file, &expect_effect_start, sizeof(expect_effect_start) );
|
||||||
|
hr = IForceFeedbackEffect_Start( effect );
|
||||||
|
todo_wine
|
||||||
|
ok( hr == S_OK, "Start returned %#lx\n", hr );
|
||||||
|
|
||||||
|
set_hid_expect( file, &expect_effect_stop, sizeof(expect_effect_stop) );
|
||||||
|
hr = IForceFeedbackEffect_Stop( effect );
|
||||||
|
todo_wine
|
||||||
|
ok( hr == S_OK, "Stop returned %#lx\n", hr );
|
||||||
|
set_hid_expect( file, &expect_effect_stop, sizeof(expect_effect_stop) );
|
||||||
|
hr = IForceFeedbackEffect_Stop( effect );
|
||||||
|
todo_wine
|
||||||
|
ok( hr == S_OK, "Stop returned %#lx\n", hr );
|
||||||
|
|
||||||
|
set_hid_expect( file, expect_unload, sizeof(expect_unload) );
|
||||||
|
hr = IForceFeedbackMotor_TryUnloadEffectAsync( motor, effect, &bool_async );
|
||||||
|
ok( hr == S_OK, "TryUnloadEffectAsync returned %#lx\n", hr );
|
||||||
|
bool_async_handler = default_bool_async_handler;
|
||||||
|
bool_async_handler.event = CreateEventW( NULL, FALSE, FALSE, NULL );
|
||||||
|
ok( !!bool_async_handler.event, "CreateEventW failed, error %lu\n", GetLastError() );
|
||||||
|
hr = IAsyncOperation_boolean_put_Completed( bool_async, &bool_async_handler.IAsyncOperationCompletedHandler_boolean_iface );
|
||||||
|
ok( hr == S_OK, "put_Completed returned %#lx\n", hr );
|
||||||
|
ret = WaitForSingleObject( bool_async_handler.event, 5000 );
|
||||||
|
ok( !ret, "WaitForSingleObject returned %#lx\n", ret );
|
||||||
|
ret = CloseHandle( bool_async_handler.event );
|
||||||
|
ok( ret, "CloseHandle failed, error %lu\n", GetLastError() );
|
||||||
|
check_bool_async( bool_async, 1, Completed, S_OK, TRUE );
|
||||||
|
ref = IAsyncOperation_boolean_Release( bool_async );
|
||||||
|
ok( ref == 0, "Release returned %lu\n", ref );
|
||||||
|
set_hid_expect( file, NULL, 0 );
|
||||||
|
|
||||||
|
ref = IForceFeedbackEffect_Release( effect );
|
||||||
|
ok( ref == 0, "Release returned %lu\n", ref );
|
||||||
|
|
||||||
|
IConditionForceEffectFactory_Release( condition_factory );
|
||||||
|
|
||||||
|
|
||||||
|
skip_condition:
|
||||||
hr = pWindowsCreateString( constant_effect_class_name, wcslen( constant_effect_class_name ), &str );
|
hr = pWindowsCreateString( constant_effect_class_name, wcslen( constant_effect_class_name ), &str );
|
||||||
ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr );
|
ok( hr == S_OK, "WindowsCreateString returned %#lx\n", hr );
|
||||||
hr = pRoGetActivationFactory( str, &IID_IActivationFactory, (void **)&activation_factory );
|
hr = pRoGetActivationFactory( str, &IID_IActivationFactory, (void **)&activation_factory );
|
||||||
|
|
Loading…
Reference in New Issue