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
d57b7ac4
Commit
d57b7ac4
authored
Sep 03, 2005
by
Daniel Remenak
Committed by
Alexandre Julliard
Sep 03, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement EnumEffects, CreateEffect, EnumCreatedEffects,
SendForceFeedbackCommand, and GetForceFeedbackStatus for linux input joysticks.
parent
f3719a88
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
377 additions
and
12 deletions
+377
-12
joystick_linuxinput.c
dlls/dinput/joystick_linuxinput.c
+377
-12
No files found.
dlls/dinput/joystick_linuxinput.c
View file @
d57b7ac4
...
...
@@ -69,6 +69,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(dinput);
#define WINE_JOYSTICK_AXIS_BASE 0
#define WINE_JOYSTICK_BUTTON_BASE 8
typedef
struct
EffectListItem
EffectListItem
;
struct
EffectListItem
{
LPDIRECTINPUTEFFECT
ref
;
struct
EffectListItem
*
next
;
};
/* implemented in effect_linuxinput.c */
HRESULT
linuxinput_create_effect
(
int
fd
,
REFGUID
rguid
,
LPDIRECTINPUTEFFECT
*
peff
);
HRESULT
linuxinput_get_info_A
(
int
fd
,
REFGUID
rguid
,
LPDIEFFECTINFOA
info
);
HRESULT
linuxinput_get_info_W
(
int
fd
,
REFGUID
rguid
,
LPDIEFFECTINFOW
info
);
typedef
struct
JoystickImpl
JoystickImpl
;
static
const
IDirectInputDevice8AVtbl
JoystickAvt
;
static
const
IDirectInputDevice8WVtbl
JoystickWvt
;
...
...
@@ -104,6 +116,8 @@ struct JoystickImpl
/* Force feedback variables */
BOOL
has_ff
;
int
num_effects
;
EffectListItem
*
top_effect
;
int
ff_state
;
/* data returned by the EVIOCGABS() ioctl */
int
axes
[
ABS_MAX
+
1
][
5
];
...
...
@@ -288,6 +302,7 @@ static JoystickImpl *alloc_device(REFGUID rguid, const void *jvt, IDirectInputIm
newDevice
->
ref
=
1
;
newDevice
->
joyfd
=
-
1
;
newDevice
->
dinput
=
dinput
;
newDevice
->
ff_state
=
FF_STATUS_STOPPED
;
memcpy
(
&
(
newDevice
->
guid
),
rguid
,
sizeof
(
*
rguid
));
for
(
i
=
0
;
i
<
ABS_MAX
;
i
++
)
{
newDevice
->
wantmin
[
i
]
=
-
32768
;
...
...
@@ -376,6 +391,9 @@ static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
if
(
ref
)
return
ref
;
/* Reset the FF state, free all effects, etc */
iface
->
lpVtbl
->
SendForceFeedbackCommand
(
iface
,
DISFFC_RESET
);
/* Free the data queue */
HeapFree
(
GetProcessHeap
(),
0
,
This
->
data_queue
);
...
...
@@ -705,6 +723,9 @@ static void joy_polldev(JoystickImpl *This) {
break
;
}
break
;
case
EV_FF_STATUS
:
This
->
ff_state
=
ie
.
value
;
break
;
default:
FIXME
(
"joystick cannot handle type %d event (code %d)
\n
"
,
ie
.
type
,
ie
.
code
);
break
;
...
...
@@ -1104,6 +1125,350 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
return
DI_OK
;
}
/******************************************************************************
* CreateEffect - Create a new FF effect with the specified params
*/
static
HRESULT
WINAPI
JoystickAImpl_CreateEffect
(
LPDIRECTINPUTDEVICE8A
iface
,
REFGUID
rguid
,
LPCDIEFFECT
lpeff
,
LPDIRECTINPUTEFFECT
*
ppdef
,
LPUNKNOWN
pUnkOuter
)
{
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
EffectListItem
*
new
=
NULL
;
HRESULT
retval
=
DI_OK
;
#endif
JoystickImpl
*
This
=
(
JoystickImpl
*
)
iface
;
TRACE
(
"(this=%p,%p,%p,%p,%p)
\n
"
,
This
,
rguid
,
lpeff
,
ppdef
,
pUnkOuter
);
#ifndef HAVE_STRUCT_FF_EFFECT_DIRECTION
TRACE
(
"not available (compiled w/o ff support)
\n
"
);
*
ppdef
=
NULL
;
return
DI_OK
;
#else
new
=
malloc
(
sizeof
(
EffectListItem
));
new
->
next
=
This
->
top_effect
;
This
->
top_effect
=
new
;
retval
=
linuxinput_create_effect
(
This
->
joyfd
,
rguid
,
&
(
new
->
ref
));
if
(
retval
!=
DI_OK
)
return
retval
;
if
(
lpeff
!=
NULL
)
retval
=
new
->
ref
->
lpVtbl
->
SetParameters
(
new
->
ref
,
lpeff
,
0
);
if
(
retval
!=
DI_OK
)
return
retval
;
*
ppdef
=
new
->
ref
;
if
(
pUnkOuter
!=
NULL
)
FIXME
(
"Interface aggregation not implemented.
\n
"
);
return
DI_OK
;
#endif
/* HAVE_STRUCT_FF_EFFECT_DIRECTION */
}
/*******************************************************************************
* EnumEffects - Enumerate available FF effects
*/
static
HRESULT
WINAPI
JoystickAImpl_EnumEffects
(
LPDIRECTINPUTDEVICE8A
iface
,
LPDIENUMEFFECTSCALLBACKA
lpCallback
,
LPVOID
pvRef
,
DWORD
dwEffType
)
{
DIEFFECTINFOA
dei
;
/* feif */
DWORD
type
=
DIEFT_GETTYPE
(
dwEffType
);
JoystickImpl
*
This
=
(
JoystickImpl
*
)
iface
;
int
xfd
=
This
->
joyfd
;
TRACE
(
"(this=%p,%p,%ld) type=%ld fd=%d
\n
"
,
This
,
pvRef
,
dwEffType
,
type
,
xfd
);
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
dei
.
dwSize
=
sizeof
(
DIEFFECTINFOA
);
/* We need to return something even if we're not yet acquired */
if
(
xfd
==
-
1
)
iface
->
lpVtbl
->
Acquire
(
iface
);
if
((
type
==
DIEFT_ALL
||
type
==
DIEFT_CONSTANTFORCE
)
&&
test_bit
(
This
->
ffbits
,
FF_CONSTANT
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_ConstantForce
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
((
type
==
DIEFT_ALL
||
type
==
DIEFT_PERIODIC
)
&&
test_bit
(
This
->
ffbits
,
FF_PERIODIC
))
{
if
(
test_bit
(
This
->
ffbits
,
FF_SQUARE
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Square
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_SINE
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Sine
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_TRIANGLE
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Triangle
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_SAW_UP
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_SawtoothUp
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_SAW_DOWN
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_SawtoothDown
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
}
if
((
type
==
DIEFT_ALL
||
type
==
DIEFT_RAMPFORCE
)
&&
test_bit
(
This
->
ffbits
,
FF_RAMP
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_RampForce
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
type
==
DIEFT_ALL
||
type
==
DIEFT_CONDITION
)
{
if
(
test_bit
(
This
->
ffbits
,
FF_SPRING
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Spring
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_DAMPER
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Damper
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_INERTIA
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Inertia
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_FRICTION
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Friction
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
}
/* return to unaquired state if that's where it was */
if
(
xfd
==
-
1
)
iface
->
lpVtbl
->
Unacquire
(
iface
);
#endif
return
DI_OK
;
}
static
HRESULT
WINAPI
JoystickWImpl_EnumEffects
(
LPDIRECTINPUTDEVICE8W
iface
,
LPDIENUMEFFECTSCALLBACKW
lpCallback
,
LPVOID
pvRef
,
DWORD
dwEffType
)
{
/* seems silly to duplicate all this code but all the structures and functions
* are actually different (A/W) */
DIEFFECTINFOW
dei
;
/* feif */
DWORD
type
=
DIEFT_GETTYPE
(
dwEffType
);
JoystickImpl
*
This
=
(
JoystickImpl
*
)
iface
;
int
xfd
=
This
->
joyfd
;
TRACE
(
"(this=%p,%p,%ld) type=%ld fd=%d
\n
"
,
This
,
pvRef
,
dwEffType
,
type
,
xfd
);
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
dei
.
dwSize
=
sizeof
(
DIEFFECTINFOW
);
/* We need to return something even if we're not yet acquired */
if
(
xfd
==
-
1
)
iface
->
lpVtbl
->
Acquire
(
iface
);
if
((
type
==
DIEFT_ALL
||
type
==
DIEFT_CONSTANTFORCE
)
&&
test_bit
(
This
->
ffbits
,
FF_CONSTANT
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_ConstantForce
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
((
type
==
DIEFT_ALL
||
type
==
DIEFT_PERIODIC
)
&&
test_bit
(
This
->
ffbits
,
FF_PERIODIC
))
{
if
(
test_bit
(
This
->
ffbits
,
FF_SQUARE
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Square
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_SINE
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Sine
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_TRIANGLE
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Triangle
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_SAW_UP
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_SawtoothUp
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_SAW_DOWN
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_SawtoothDown
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
}
if
((
type
==
DIEFT_ALL
||
type
==
DIEFT_RAMPFORCE
)
&&
test_bit
(
This
->
ffbits
,
FF_RAMP
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_RampForce
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
type
==
DIEFT_ALL
||
type
==
DIEFT_CONDITION
)
{
if
(
test_bit
(
This
->
ffbits
,
FF_SPRING
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Spring
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_DAMPER
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Damper
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_INERTIA
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Inertia
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
if
(
test_bit
(
This
->
ffbits
,
FF_FRICTION
))
{
iface
->
lpVtbl
->
GetEffectInfo
(
iface
,
&
dei
,
&
GUID_Friction
);
(
*
lpCallback
)(
&
dei
,
pvRef
);
}
}
/* return to unaquired state if that's where it was */
if
(
xfd
==
-
1
)
iface
->
lpVtbl
->
Unacquire
(
iface
);
#endif
return
DI_OK
;
}
/*******************************************************************************
* GetEffectInfo - Get information about a particular effect
*/
static
HRESULT
WINAPI
JoystickAImpl_GetEffectInfo
(
LPDIRECTINPUTDEVICE8A
iface
,
LPDIEFFECTINFOA
pdei
,
REFGUID
guid
)
{
JoystickImpl
*
This
=
(
JoystickImpl
*
)
iface
;
TRACE
(
"(this=%p,%p,%s)
\n
"
,
This
,
pdei
,
_dump_dinput_GUID
(
guid
));
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
return
linuxinput_get_info_A
(
This
->
joyfd
,
guid
,
pdei
);
#else
return
DI_OK
;
#endif
}
static
HRESULT
WINAPI
JoystickWImpl_GetEffectInfo
(
LPDIRECTINPUTDEVICE8W
iface
,
LPDIEFFECTINFOW
pdei
,
REFGUID
guid
)
{
JoystickImpl
*
This
=
(
JoystickImpl
*
)
iface
;
TRACE
(
"(this=%p,%p,%s)
\n
"
,
This
,
pdei
,
_dump_dinput_GUID
(
guid
));
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
return
linuxinput_get_info_W
(
This
->
joyfd
,
guid
,
pdei
);
#else
return
DI_OK
;
#endif
}
/*******************************************************************************
* GetForceFeedbackState - Get information about the device's FF state
*/
static
HRESULT
WINAPI
JoystickAImpl_GetForceFeedbackState
(
LPDIRECTINPUTDEVICE8A
iface
,
LPDWORD
pdwOut
)
{
JoystickImpl
*
This
=
(
JoystickImpl
*
)
iface
;
TRACE
(
"(this=%p,%p)
\n
"
,
This
,
pdwOut
);
(
*
pdwOut
)
=
0
;
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
/* DIGFFS_STOPPED is the only mandatory flag to report */
if
(
This
->
ff_state
==
FF_STATUS_STOPPED
)
(
*
pdwOut
)
|=
DIGFFS_STOPPED
;
#endif
return
DI_OK
;
}
/*******************************************************************************
* SendForceFeedbackCommand - Send a command to the device's FF system
*/
static
HRESULT
WINAPI
JoystickAImpl_SendForceFeedbackCommand
(
LPDIRECTINPUTDEVICE8A
iface
,
DWORD
dwFlags
)
{
JoystickImpl
*
This
=
(
JoystickImpl
*
)
iface
;
TRACE
(
"(this=%p,%ld)
\n
"
,
This
,
dwFlags
);
#ifdef HAVE_STRUCT_FF_EFFECT_DIRECTION
if
(
dwFlags
==
DISFFC_STOPALL
)
{
/* Stop all effects */
EffectListItem
*
itr
=
This
->
top_effect
;
while
(
itr
)
{
itr
->
ref
->
lpVtbl
->
Stop
(
itr
->
ref
);
itr
=
itr
->
next
;
}
}
else
if
(
dwFlags
==
DISFFC_RESET
)
{
/* Stop, unload, release and free all effects */
/* This returns the device to its "bare" state */
while
(
This
->
top_effect
)
{
EffectListItem
*
temp
=
This
->
top_effect
;
temp
->
ref
->
lpVtbl
->
Stop
(
temp
->
ref
);
temp
->
ref
->
lpVtbl
->
Unload
(
temp
->
ref
);
temp
->
ref
->
lpVtbl
->
Release
(
temp
->
ref
);
This
->
top_effect
=
temp
->
next
;
free
(
temp
);
}
}
else
if
(
dwFlags
==
DISFFC_PAUSE
||
dwFlags
==
DISFFC_CONTINUE
)
{
FIXME
(
"No support for Pause or Continue in linux
\n
"
);
}
else
if
(
dwFlags
==
DISFFC_SETACTUATORSOFF
||
dwFlags
==
DISFFC_SETACTUATORSON
)
{
FIXME
(
"No direct actuator control in linux
\n
"
);
}
else
{
FIXME
(
"Unknown Force Feedback Command!
\n
"
);
return
DIERR_INVALIDPARAM
;
}
return
DI_OK
;
#else
return
DIERR_UNSUPPORTED
;
#endif
}
/*******************************************************************************
* EnumCreatedEffectObjects - Enumerate all the effects that have been
* created for this device.
*/
static
HRESULT
WINAPI
JoystickAImpl_EnumCreatedEffectObjects
(
LPDIRECTINPUTDEVICE8A
iface
,
LPDIENUMCREATEDEFFECTOBJECTSCALLBACK
lpCallback
,
LPVOID
pvRef
,
DWORD
dwFlags
)
{
/* this function is safe to call on non-ff-enabled builds */
JoystickImpl
*
This
=
(
JoystickImpl
*
)
iface
;
EffectListItem
*
itr
=
This
->
top_effect
;
TRACE
(
"(this=%p,%p,%p,%ld)
\n
"
,
This
,
lpCallback
,
pvRef
,
dwFlags
);
if
(
!
lpCallback
)
return
DIERR_INVALIDPARAM
;
if
(
dwFlags
!=
0
)
FIXME
(
"Flags specified, but no flags exist yet (DX9)!"
);
while
(
itr
)
{
(
*
lpCallback
)(
itr
->
ref
,
pvRef
);
itr
=
itr
->
next
;
}
return
DI_OK
;
}
static
const
IDirectInputDevice8AVtbl
JoystickAvt
=
{
IDirectInputDevice2AImpl_QueryInterface
,
...
...
@@ -1124,12 +1489,12 @@ static const IDirectInputDevice8AVtbl JoystickAvt =
IDirectInputDevice2AImpl_GetDeviceInfo
,
IDirectInputDevice2AImpl_RunControlPanel
,
IDirectInputDevice2AImpl_Initialize
,
IDirectInputDevice2
AImpl_CreateEffect
,
IDirectInputDevice2
AImpl_EnumEffects
,
IDirectInputDevice2
AImpl_GetEffectInfo
,
IDirectInputDevice2
AImpl_GetForceFeedbackState
,
IDirectInputDevice2
AImpl_SendForceFeedbackCommand
,
IDirectInputDevice2
AImpl_EnumCreatedEffectObjects
,
Joystick
AImpl_CreateEffect
,
Joystick
AImpl_EnumEffects
,
Joystick
AImpl_GetEffectInfo
,
Joystick
AImpl_GetForceFeedbackState
,
Joystick
AImpl_SendForceFeedbackCommand
,
Joystick
AImpl_EnumCreatedEffectObjects
,
IDirectInputDevice2AImpl_Escape
,
JoystickAImpl_Poll
,
IDirectInputDevice2AImpl_SendDeviceData
,
...
...
@@ -1166,12 +1531,12 @@ static const IDirectInputDevice8WVtbl JoystickWvt =
IDirectInputDevice2WImpl_GetDeviceInfo
,
XCAST
(
RunControlPanel
)
IDirectInputDevice2AImpl_RunControlPanel
,
XCAST
(
Initialize
)
IDirectInputDevice2AImpl_Initialize
,
XCAST
(
CreateEffect
)
IDirectInputDevice2
AImpl_CreateEffect
,
IDirectInputDevice2
WImpl_EnumEffects
,
IDirectInputDevice2
WImpl_GetEffectInfo
,
XCAST
(
GetForceFeedbackState
)
IDirectInputDevice2
AImpl_GetForceFeedbackState
,
XCAST
(
SendForceFeedbackCommand
)
IDirectInputDevice2
AImpl_SendForceFeedbackCommand
,
XCAST
(
EnumCreatedEffectObjects
)
IDirectInputDevice2
AImpl_EnumCreatedEffectObjects
,
XCAST
(
CreateEffect
)
Joystick
AImpl_CreateEffect
,
Joystick
WImpl_EnumEffects
,
Joystick
WImpl_GetEffectInfo
,
XCAST
(
GetForceFeedbackState
)
Joystick
AImpl_GetForceFeedbackState
,
XCAST
(
SendForceFeedbackCommand
)
Joystick
AImpl_SendForceFeedbackCommand
,
XCAST
(
EnumCreatedEffectObjects
)
Joystick
AImpl_EnumCreatedEffectObjects
,
XCAST
(
Escape
)
IDirectInputDevice2AImpl_Escape
,
XCAST
(
Poll
)
JoystickAImpl_Poll
,
XCAST
(
SendDeviceData
)
IDirectInputDevice2AImpl_SendDeviceData
,
...
...
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