Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
7259346a
Commit
7259346a
authored
May 12, 2022
by
Rémi Bernon
Committed by
Alexandre Julliard
May 16, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
windows.gaming.input: Implement IForceFeedbackMotor_LoadEffectAsync.
Signed-off-by:
Rémi Bernon
<
rbernon@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7a82be5d
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
187 additions
and
6 deletions
+187
-6
force_feedback.c
dlls/dinput/tests/force_feedback.c
+0
-3
async.c
dlls/windows.gaming.input/async.c
+143
-0
force_feedback.c
dlls/windows.gaming.input/force_feedback.c
+42
-3
private.h
dlls/windows.gaming.input/private.h
+2
-0
No files found.
dlls/dinput/tests/force_feedback.c
View file @
7259346a
...
...
@@ -5666,9 +5666,7 @@ static void test_windows_gaming_input(void)
ok
(
hr
==
0x86854003
,
"Stop returned %#lx
\n
"
,
hr
);
hr
=
IForceFeedbackMotor_LoadEffectAsync
(
motor
,
effect
,
&
result_async
);
todo_wine
ok
(
hr
==
S_OK
,
"LoadEffectAsync returned %#lx
\n
"
,
hr
);
if
(
hr
!=
S_OK
)
goto
skip_tests
;
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
()
);
...
...
@@ -5696,7 +5694,6 @@ static void test_windows_gaming_input(void)
ok
(
ref
==
0
,
"Release returned %lu
\n
"
,
ref
);
skip_tests:
IForceFeedbackMotor_Release
(
motor
);
IRawGameController_Release
(
raw_controller
);
...
...
dlls/windows.gaming.input/async.c
View file @
7259346a
...
...
@@ -502,3 +502,146 @@ HRESULT async_operation_boolean_create( IUnknown *invoker, IUnknown *param, asyn
TRACE
(
"created IAsyncOperation_boolean %p
\n
"
,
*
out
);
return
S_OK
;
}
struct
async_result
{
IAsyncOperation_ForceFeedbackLoadEffectResult
IAsyncOperation_ForceFeedbackLoadEffectResult_iface
;
IWineAsyncInfoImpl
*
IWineAsyncInfoImpl_inner
;
LONG
ref
;
};
static
inline
struct
async_result
*
impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult
(
IAsyncOperation_ForceFeedbackLoadEffectResult
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
async_result
,
IAsyncOperation_ForceFeedbackLoadEffectResult_iface
);
}
static
HRESULT
WINAPI
async_result_QueryInterface
(
IAsyncOperation_ForceFeedbackLoadEffectResult
*
iface
,
REFIID
iid
,
void
**
out
)
{
struct
async_result
*
impl
=
impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult
(
iface
);
TRACE
(
"iface %p, iid %s, out %p.
\n
"
,
iface
,
debugstr_guid
(
iid
),
out
);
if
(
IsEqualGUID
(
iid
,
&
IID_IUnknown
)
||
IsEqualGUID
(
iid
,
&
IID_IInspectable
)
||
IsEqualGUID
(
iid
,
&
IID_IAgileObject
)
||
IsEqualGUID
(
iid
,
&
IID_IAsyncOperation_ForceFeedbackLoadEffectResult
))
{
IInspectable_AddRef
(
(
*
out
=
&
impl
->
IAsyncOperation_ForceFeedbackLoadEffectResult_iface
)
);
return
S_OK
;
}
return
IWineAsyncInfoImpl_QueryInterface
(
impl
->
IWineAsyncInfoImpl_inner
,
iid
,
out
);
}
static
ULONG
WINAPI
async_result_AddRef
(
IAsyncOperation_ForceFeedbackLoadEffectResult
*
iface
)
{
struct
async_result
*
impl
=
impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult
(
iface
);
ULONG
ref
=
InterlockedIncrement
(
&
impl
->
ref
);
TRACE
(
"iface %p, ref %lu.
\n
"
,
iface
,
ref
);
return
ref
;
}
static
ULONG
WINAPI
async_result_Release
(
IAsyncOperation_ForceFeedbackLoadEffectResult
*
iface
)
{
struct
async_result
*
impl
=
impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult
(
iface
);
ULONG
ref
=
InterlockedDecrement
(
&
impl
->
ref
);
TRACE
(
"iface %p, ref %lu.
\n
"
,
iface
,
ref
);
if
(
!
ref
)
{
/* guard against re-entry if inner releases an outer iface */
InterlockedIncrement
(
&
impl
->
ref
);
IWineAsyncInfoImpl_Release
(
impl
->
IWineAsyncInfoImpl_inner
);
free
(
impl
);
}
return
ref
;
}
static
HRESULT
WINAPI
async_result_GetIids
(
IAsyncOperation_ForceFeedbackLoadEffectResult
*
iface
,
ULONG
*
iid_count
,
IID
**
iids
)
{
FIXME
(
"iface %p, iid_count %p, iids %p stub!
\n
"
,
iface
,
iid_count
,
iids
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
async_result_GetRuntimeClassName
(
IAsyncOperation_ForceFeedbackLoadEffectResult
*
iface
,
HSTRING
*
class_name
)
{
return
WindowsCreateString
(
L"Windows.Foundation.IAsyncOperation`1<Windows.Gaming.Input.ForceFeedback.ForceFeedbackLoadEffectResult>"
,
ARRAY_SIZE
(
L"Windows.Foundation.IAsyncOperation`1<Windows.Gaming.Input.ForceFeedback.ForceFeedbackLoadEffectResult>"
),
class_name
);
}
static
HRESULT
WINAPI
async_result_GetTrustLevel
(
IAsyncOperation_ForceFeedbackLoadEffectResult
*
iface
,
TrustLevel
*
trust_level
)
{
FIXME
(
"iface %p, trust_level %p stub!
\n
"
,
iface
,
trust_level
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
async_result_put_Completed
(
IAsyncOperation_ForceFeedbackLoadEffectResult
*
iface
,
IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult
*
handler
)
{
struct
async_result
*
impl
=
impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult
(
iface
);
TRACE
(
"iface %p, handler %p.
\n
"
,
iface
,
handler
);
return
IWineAsyncInfoImpl_put_Completed
(
impl
->
IWineAsyncInfoImpl_inner
,
(
IWineAsyncOperationCompletedHandler
*
)
handler
);
}
static
HRESULT
WINAPI
async_result_get_Completed
(
IAsyncOperation_ForceFeedbackLoadEffectResult
*
iface
,
IAsyncOperationCompletedHandler_ForceFeedbackLoadEffectResult
**
handler
)
{
struct
async_result
*
impl
=
impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult
(
iface
);
TRACE
(
"iface %p, handler %p.
\n
"
,
iface
,
handler
);
return
IWineAsyncInfoImpl_get_Completed
(
impl
->
IWineAsyncInfoImpl_inner
,
(
IWineAsyncOperationCompletedHandler
**
)
handler
);
}
static
HRESULT
WINAPI
async_result_GetResults
(
IAsyncOperation_ForceFeedbackLoadEffectResult
*
iface
,
ForceFeedbackLoadEffectResult
*
results
)
{
struct
async_result
*
impl
=
impl_from_IAsyncOperation_ForceFeedbackLoadEffectResult
(
iface
);
PROPVARIANT
result
=
{.
vt
=
VT_UI4
};
HRESULT
hr
;
TRACE
(
"iface %p, results %p.
\n
"
,
iface
,
results
);
hr
=
IWineAsyncInfoImpl_get_Result
(
impl
->
IWineAsyncInfoImpl_inner
,
&
result
);
*
results
=
result
.
ulVal
;
PropVariantClear
(
&
result
);
return
hr
;
}
static
const
struct
IAsyncOperation_ForceFeedbackLoadEffectResultVtbl
async_result_vtbl
=
{
/* IUnknown methods */
async_result_QueryInterface
,
async_result_AddRef
,
async_result_Release
,
/* IInspectable methods */
async_result_GetIids
,
async_result_GetRuntimeClassName
,
async_result_GetTrustLevel
,
/* IAsyncOperation<ForceFeedbackLoadEffectResult> */
async_result_put_Completed
,
async_result_get_Completed
,
async_result_GetResults
,
};
HRESULT
async_operation_effect_result_create
(
IUnknown
*
invoker
,
IUnknown
*
param
,
async_operation_callback
callback
,
IAsyncOperation_ForceFeedbackLoadEffectResult
**
out
)
{
struct
async_result
*
impl
;
HRESULT
hr
;
*
out
=
NULL
;
if
(
!
(
impl
=
calloc
(
1
,
sizeof
(
*
impl
)
)))
return
E_OUTOFMEMORY
;
impl
->
IAsyncOperation_ForceFeedbackLoadEffectResult_iface
.
lpVtbl
=
&
async_result_vtbl
;
impl
->
ref
=
1
;
if
(
FAILED
(
hr
=
async_info_create
(
invoker
,
param
,
callback
,
(
IInspectable
*
)
&
impl
->
IAsyncOperation_ForceFeedbackLoadEffectResult_iface
,
&
impl
->
IWineAsyncInfoImpl_inner
))
||
FAILED
(
hr
=
IWineAsyncInfoImpl_Start
(
impl
->
IWineAsyncInfoImpl_inner
)))
{
if
(
impl
->
IWineAsyncInfoImpl_inner
)
IWineAsyncInfoImpl_Release
(
impl
->
IWineAsyncInfoImpl_inner
);
free
(
impl
);
return
hr
;
}
*
out
=
&
impl
->
IAsyncOperation_ForceFeedbackLoadEffectResult_iface
;
TRACE
(
"created IAsyncOperation_ForceFeedbackLoadEffectResult %p
\n
"
,
*
out
);
return
S_OK
;
}
dlls/windows.gaming.input/force_feedback.c
View file @
7259346a
...
...
@@ -34,6 +34,9 @@ struct effect
IInspectable
*
IInspectable_outer
;
LONG
ref
;
CRITICAL_SECTION
cs
;
IDirectInputEffect
*
effect
;
GUID
type
;
DWORD
axes
[
3
];
LONG
directions
[
3
];
...
...
@@ -87,7 +90,13 @@ static ULONG WINAPI effect_impl_Release( IWineForceFeedbackEffectImpl *iface )
TRACE
(
"iface %p decreasing refcount to %lu.
\n
"
,
iface
,
ref
);
if
(
!
ref
)
free
(
impl
);
if
(
!
ref
)
{
if
(
impl
->
effect
)
IDirectInputEffect_Release
(
impl
->
effect
);
impl
->
cs
.
DebugInfo
->
Spare
[
0
]
=
0
;
DeleteCriticalSection
(
&
impl
->
cs
);
free
(
impl
);
}
return
ref
;
}
...
...
@@ -181,6 +190,9 @@ HRESULT force_feedback_effect_create( enum WineForceFeedbackEffectType type, IIn
impl
->
axes
[
1
]
=
DIJOFS_Y
;
impl
->
axes
[
2
]
=
DIJOFS_Z
;
InitializeCriticalSection
(
&
impl
->
cs
);
impl
->
cs
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": effect.cs"
);
*
out
=
&
impl
->
IWineForceFeedbackEffectImpl_iface
;
TRACE
(
"created ForceFeedbackEffect %p
\n
"
,
*
out
);
return
S_OK
;
...
...
@@ -337,11 +349,38 @@ static HRESULT WINAPI motor_get_SupportedAxes( IForceFeedbackMotor *iface, enum
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
motor_load_effect_async
(
IUnknown
*
invoker
,
IUnknown
*
param
,
PROPVARIANT
*
result
)
{
struct
effect
*
effect
=
impl_from_IForceFeedbackEffect
(
(
IForceFeedbackEffect
*
)
param
);
struct
motor
*
impl
=
impl_from_IForceFeedbackMotor
(
(
IForceFeedbackMotor
*
)
invoker
);
IDirectInputEffect
*
dinput_effect
;
HRESULT
hr
;
if
(
SUCCEEDED
(
hr
=
IDirectInputDevice8_CreateEffect
(
impl
->
device
,
&
effect
->
type
,
&
effect
->
params
,
&
dinput_effect
,
NULL
)))
{
EnterCriticalSection
(
&
effect
->
cs
);
if
(
!
effect
->
effect
)
{
effect
->
effect
=
dinput_effect
;
IDirectInputEffect_AddRef
(
effect
->
effect
);
}
LeaveCriticalSection
(
&
effect
->
cs
);
IDirectInputEffect_Release
(
dinput_effect
);
}
result
->
vt
=
VT_UI4
;
if
(
SUCCEEDED
(
hr
))
result
->
ulVal
=
ForceFeedbackLoadEffectResult_Succeeded
;
else
if
(
hr
==
DIERR_DEVICEFULL
)
result
->
ulVal
=
ForceFeedbackLoadEffectResult_EffectStorageFull
;
else
result
->
ulVal
=
ForceFeedbackLoadEffectResult_EffectNotSupported
;
return
hr
;
}
static
HRESULT
WINAPI
motor_LoadEffectAsync
(
IForceFeedbackMotor
*
iface
,
IForceFeedbackEffect
*
effect
,
IAsyncOperation_ForceFeedbackLoadEffectResult
**
async_op
)
{
FIXME
(
"iface %p, effect %p, async_op %p stub!
\n
"
,
iface
,
effect
,
async_op
);
return
E_NOTIMPL
;
TRACE
(
"iface %p, effect %p, async_op %p.
\n
"
,
iface
,
effect
,
async_op
);
return
async_operation_effect_result_create
(
(
IUnknown
*
)
iface
,
(
IUnknown
*
)
effect
,
motor_load_effect_async
,
async_op
)
;
}
static
HRESULT
WINAPI
motor_PauseAllEffects
(
IForceFeedbackMotor
*
iface
)
...
...
dlls/windows.gaming.input/private.h
View file @
7259346a
...
...
@@ -76,6 +76,8 @@ extern HRESULT force_feedback_effect_create( enum WineForceFeedbackEffectType ty
typedef
HRESULT
(
WINAPI
*
async_operation_callback
)(
IUnknown
*
invoker
,
IUnknown
*
param
,
PROPVARIANT
*
result
);
extern
HRESULT
async_operation_boolean_create
(
IUnknown
*
invoker
,
IUnknown
*
param
,
async_operation_callback
callback
,
IAsyncOperation_boolean
**
out
);
extern
HRESULT
async_operation_effect_result_create
(
IUnknown
*
invoker
,
IUnknown
*
param
,
async_operation_callback
callback
,
IAsyncOperation_ForceFeedbackLoadEffectResult
**
out
);
#define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \
static inline impl_type *impl_from( iface_type *iface ) \
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment