Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
d62e2268
Commit
d62e2268
authored
Mar 27, 2023
by
Rémi Bernon
Committed by
Alexandre Julliard
Mar 27, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dinput: Rewrite IDirectInput8_EnumDevicesBySemantics.
Simplifying and fixing it.
parent
cb987646
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
90 additions
and
118 deletions
+90
-118
device.c
dlls/dinput/device.c
+3
-3
device_private.h
dlls/dinput/device_private.h
+2
-0
dinput.c
dlls/dinput/dinput.c
+84
-114
joystick8.c
dlls/dinput/tests/joystick8.c
+1
-1
No files found.
dlls/dinput/device.c
View file @
d62e2268
...
...
@@ -1785,7 +1785,7 @@ static HRESULT WINAPI dinput_device_WriteEffectToFile( IDirectInputDevice8W *ifa
return
DI_OK
;
}
static
BOOL
object_matches_semantic
(
const
DIDEVICEINSTANCEW
*
instance
,
const
DIOBJECTDATAFORMAT
*
object
,
BOOL
device_
object_matches_semantic
(
const
DIDEVICEINSTANCEW
*
instance
,
const
DIOBJECTDATAFORMAT
*
object
,
DWORD
semantic
,
BOOL
exact
)
{
DWORD
value
=
semantic
&
0xff
,
axis
=
(
semantic
>>
15
)
&
3
,
type
;
...
...
@@ -1885,7 +1885,7 @@ static HRESULT WINAPI dinput_device_BuildActionMap( IDirectInputDevice8W *iface,
for
(
object
=
impl
->
device_format
.
rgodf
;
object
<
object_end
;
object
++
)
{
if
(
mapped
[
object
-
impl
->
device_format
.
rgodf
])
continue
;
if
(
!
object_matches_semantic
(
&
impl
->
instance
,
object
,
action
->
dwSemantic
,
TRUE
))
continue
;
if
(
!
device_
object_matches_semantic
(
&
impl
->
instance
,
object
,
action
->
dwSemantic
,
TRUE
))
continue
;
if
((
action
->
dwFlags
&
DIA_FORCEFEEDBACK
)
&&
!
(
object
->
dwType
&
DIDFT_FFACTUATOR
))
continue
;
action
->
dwObjID
=
object
->
dwType
;
action
->
guidInstance
=
impl
->
guid
;
...
...
@@ -1904,7 +1904,7 @@ static HRESULT WINAPI dinput_device_BuildActionMap( IDirectInputDevice8W *iface,
for
(
object
=
impl
->
device_format
.
rgodf
;
object
<
object_end
;
object
++
)
{
if
(
mapped
[
object
-
impl
->
device_format
.
rgodf
])
continue
;
if
(
!
object_matches_semantic
(
&
impl
->
instance
,
object
,
action
->
dwSemantic
,
FALSE
))
continue
;
if
(
!
device_
object_matches_semantic
(
&
impl
->
instance
,
object
,
action
->
dwSemantic
,
FALSE
))
continue
;
if
((
action
->
dwFlags
&
DIA_FORCEFEEDBACK
)
&&
!
(
object
->
dwType
&
DIDFT_FFACTUATOR
))
continue
;
action
->
dwObjID
=
object
->
dwType
;
action
->
guidInstance
=
impl
->
guid
;
...
...
dlls/dinput/device_private.h
View file @
d62e2268
...
...
@@ -128,6 +128,8 @@ extern void dinput_device_internal_release( struct dinput_device *device );
extern
HRESULT
dinput_device_init_device_format
(
IDirectInputDevice8W
*
iface
);
extern
int
dinput_device_object_index_from_id
(
IDirectInputDevice8W
*
iface
,
DWORD
id
);
extern
BOOL
device_object_matches_semantic
(
const
DIDEVICEINSTANCEW
*
instance
,
const
DIOBJECTDATAFORMAT
*
object
,
DWORD
semantic
,
BOOL
exact
);
extern
BOOL
get_app_key
(
HKEY
*
,
HKEY
*
)
DECLSPEC_HIDDEN
;
extern
DWORD
get_config_key
(
HKEY
,
HKEY
,
const
WCHAR
*
,
WCHAR
*
,
DWORD
)
DECLSPEC_HIDDEN
;
...
...
dlls/dinput/dinput.c
View file @
d62e2268
...
...
@@ -45,19 +45,6 @@ static inline struct dinput *impl_from_IDirectInput8W( IDirectInput8W *iface )
return
CONTAINING_RECORD
(
iface
,
struct
dinput
,
IDirectInput8W_iface
);
}
static
DWORD
diactionformat_priorityW
(
DIACTIONFORMATW
*
action_format
,
DWORD
genre
)
{
int
i
;
DWORD
priorityFlags
=
0
;
/* If there's at least one action for the device it's priority 1 */
for
(
i
=
0
;
i
<
action_format
->
dwNumActions
;
i
++
)
if
((
action_format
->
rgoAction
[
i
].
dwSemantic
&
genre
)
==
genre
)
priorityFlags
|=
DIEDBS_MAPPEDPRI1
;
return
priorityFlags
;
}
#if defined __i386__ && defined _MSC_VER
__declspec
(
naked
)
BOOL
enum_callback_wrapper
(
void
*
callback
,
const
void
*
instance
,
void
*
ref
)
{
...
...
@@ -438,65 +425,82 @@ static HRESULT WINAPI dinput8_FindDevice( IDirectInput8W *iface, const GUID *gui
return
IDirectInput7_FindDevice
(
&
impl
->
IDirectInput7W_iface
,
guid
,
name
,
instance_guid
);
}
st
atic
BOOL
should_enumerate_device
(
const
WCHAR
*
username
,
DWORD
flags
,
struct
list
*
device_players
,
const
GUID
*
guid
)
st
ruct
enum_device_by_semantics_params
{
BOOL
should_enumerate
=
TRUE
;
struct
DevicePlayer
*
device_player
;
IDirectInput8W
*
iface
;
const
WCHAR
*
username
;
DWORD
flags
;
/* Check if user owns impl device */
if
(
flags
&
DIEDBSFL_THISUSER
&&
username
&&
*
username
)
IDirectInputDevice8W
*
devices
[
128
];
DWORD
device_count
;
};
static
BOOL
CALLBACK
enum_device_by_semantics
(
const
DIDEVICEINSTANCEW
*
instance
,
void
*
context
)
{
struct
enum_device_by_semantics_params
*
params
=
context
;
DIDEVCAPS
caps
=
{.
dwSize
=
sizeof
(
caps
)};
DIPROPSTRING
prop_username
=
{
should_enumerate
=
FALSE
;
LIST_FOR_EACH_ENTRY
(
device_player
,
device_players
,
struct
DevicePlayer
,
entry
)
.
diph
=
{
if
(
IsEqualGUID
(
&
device_player
->
instance_guid
,
guid
))
{
if
(
*
device_player
->
username
&&
!
wcscmp
(
username
,
device_player
->
username
))
return
TRUE
;
/* Device username matches */
break
;
}
}
}
.
dwSize
=
sizeof
(
DIPROPSTRING
),
.
dwHeaderSize
=
sizeof
(
DIPROPHEADER
),
.
dwHow
=
DIPH_DEVICE
,
},
}
;
IDirectInputDevice8W
*
device
;
BOOL
ret
=
DIENUM_CONTINUE
;
HRESULT
hr
;
/* Check if impl device is not owned by anyone */
if
(
flags
&
DIEDBSFL_AVAILABLEDEVICES
)
if
(
params
->
device_count
>=
ARRAY_SIZE
(
params
->
devices
))
return
DIENUM_STOP
;
if
(
FAILED
(
hr
=
IDirectInput8_CreateDevice
(
params
->
iface
,
&
instance
->
guidInstance
,
&
device
,
NULL
)))
{
BOOL
found
=
FALSE
;
should_enumerate
=
FALSE
;
LIST_FOR_EACH_ENTRY
(
device_player
,
device_players
,
struct
DevicePlayer
,
entry
)
{
if
(
IsEqualGUID
(
&
device_player
->
instance_guid
,
guid
))
{
if
(
*
device_player
->
username
)
found
=
TRUE
;
break
;
}
}
if
(
!
found
)
return
TRUE
;
/* Device does not have a username */
WARN
(
"Failed to create device, hr %#lx
\n
"
,
hr
);
return
DIENUM_CONTINUE
;
}
return
should_enumerate
;
if
(
FAILED
(
hr
=
IDirectInputDevice8_GetCapabilities
(
device
,
&
caps
)))
WARN
(
"Failed to get device capabilities, hr %#lx
\n
"
,
hr
);
if
((
params
->
flags
&
DIEDBSFL_FORCEFEEDBACK
)
&&
!
caps
.
dwFFDriverVersion
)
goto
done
;
if
(
FAILED
(
hr
=
IDirectInputDevice8_GetProperty
(
device
,
DIPROP_USERNAME
,
&
prop_username
.
diph
)))
WARN
(
"Failed to get device capabilities, hr %#lx
\n
"
,
hr
);
else
if
((
params
->
flags
&
DIEDBSFL_THISUSER
)
&&
*
params
->
username
&&
wcscmp
(
params
->
username
,
prop_username
.
wsz
))
goto
done
;
else
if
((
params
->
flags
&
DIEDBSFL_AVAILABLEDEVICES
)
&&
*
prop_username
.
wsz
)
goto
done
;
IDirectInputDevice_AddRef
(
device
);
params
->
devices
[
params
->
device_count
++
]
=
device
;
done:
IDirectInputDevice8_Release
(
device
);
return
ret
;
}
struct
enum_device_
by
_semantics_params
struct
enum_device_
object
_semantics_params
{
IDirectInput8W
*
ifa
ce
;
const
WCHAR
*
username
;
DIDEVICEINSTANCEW
instan
ce
;
DIACTIONFORMATW
*
format
;
DWORD
flags
;
DIDEVICEINSTANCEW
*
instances
;
DWORD
instance_count
;
};
static
BOOL
CALLBACK
enum_device_
by_semantics
(
const
DIDEVICEINSTANCEW
*
instance
,
void
*
context
)
static
BOOL
CALLBACK
enum_device_
object_semantics
(
const
DIDEVICEOBJECTINSTANCEW
*
obj
,
void
*
args
)
{
struct
enum_device_by_semantics_params
*
params
=
context
;
struct
dinput
*
impl
=
impl_from_IDirectInput8W
(
params
->
iface
);
struct
enum_device_object_semantics_params
*
params
=
args
;
DIACTIONFORMATW
*
format
=
params
->
format
;
UINT
i
;
if
(
should_enumerate_device
(
params
->
username
,
params
->
flags
,
&
impl
->
device_players
,
&
instance
->
guidInstance
)
)
for
(
i
=
0
;
format
&&
i
<
format
->
dwNumActions
;
i
++
)
{
params
->
instance_count
++
;
params
->
instances
=
realloc
(
params
->
instances
,
sizeof
(
DIDEVICEINSTANCEW
)
*
params
->
instance_count
);
params
->
instances
[
params
->
instance_count
-
1
]
=
*
instance
;
DIOBJECTDATAFORMAT
object_format
=
{.
dwType
=
obj
->
dwType
,
.
dwOfs
=
obj
->
dwOfs
};
BYTE
dev_type
=
params
->
instance
.
dwDevType
&
0xf
;
DIACTIONW
*
action
=
format
->
rgoAction
+
i
;
if
(
!
device_object_matches_semantic
(
&
params
->
instance
,
&
object_format
,
action
->
dwSemantic
,
FALSE
))
continue
;
if
(
!
(
action
->
dwSemantic
&
0x4000
))
params
->
flags
|=
DIEDBS_MAPPEDPRI1
;
else
if
(
dev_type
!=
DIDEVTYPE_KEYBOARD
&&
dev_type
!=
DIDEVTYPE_MOUSE
)
params
->
flags
|=
DIEDBS_MAPPEDPRI2
;
}
return
DIENUM_CONTINUE
;
...
...
@@ -505,18 +509,13 @@ static BOOL CALLBACK enum_device_by_semantics( const DIDEVICEINSTANCEW *instance
static
HRESULT
WINAPI
dinput8_EnumDevicesBySemantics
(
IDirectInput8W
*
iface
,
const
WCHAR
*
username
,
DIACTIONFORMATW
*
action_format
,
LPDIENUMDEVICESBYSEMANTICSCBW
callback
,
void
*
context
,
DWORD
flags
)
{
struct
enum_device_by_semantics_params
params
=
{.
iface
=
iface
,
.
username
=
username
,
.
flags
=
flags
};
DWORD
callbackFlags
,
enum_flags
=
DIEDFL_ATTACHEDONLY
|
(
flags
&
DIEDFL_FORCEFEEDBACK
);
static
const
GUID
*
guids
[
2
]
=
{
&
GUID_SysKeyboard
,
&
GUID_SysMouse
};
static
const
DWORD
actionMasks
[]
=
{
DIKEYBOARD_MASK
,
DIMOUSE_MASK
};
struct
enum_device_by_semantics_params
params
=
{.
iface
=
iface
,
.
username
=
username
?
username
:
L""
,
.
flags
=
flags
};
DWORD
enum_flags
=
DIEDFL_ATTACHEDONLY
|
(
flags
&
DIEDFL_FORCEFEEDBACK
);
struct
dinput
*
impl
=
impl_from_IDirectInput8W
(
iface
);
IDirectInputDevice8W
*
device
;
DIDEVICEINSTANCEW
didevi
;
unsigned
int
i
=
0
;
HRESULT
hr
;
int
remain
;
FIXME
(
"iface %p, username %s, action_format %p, callback %p, context %p, flags %#lx stub!
\n
"
,
TRACE
(
"iface %p, username %s, action_format %p, callback %p, context %p, flags %#lx
\n
"
,
iface
,
debugstr_w
(
username
),
action_format
,
callback
,
context
,
flags
);
if
(
!
action_format
)
return
DIERR_INVALIDPARAM
;
...
...
@@ -531,64 +530,35 @@ static HRESULT WINAPI dinput8_EnumDevicesBySemantics( IDirectInput8W *iface, con
action
->
dwObjID
,
action
->
dwHow
,
debugstr_w
(
action
->
lptszActionName
)
);
}
didevi
.
dwSize
=
sizeof
(
didevi
);
hr
=
IDirectInput8_EnumDevices
(
&
impl
->
IDirectInput8W_iface
,
DI8DEVCLASS_GAMECTRL
,
enum_device_by_semantics
,
&
params
,
enum_flags
);
if
(
FAILED
(
hr
))
if
(
FAILED
(
hr
=
IDirectInput8_EnumDevices
(
&
impl
->
IDirectInput8W_iface
,
DI8DEVCLASS_ALL
,
enum_device_by_semantics
,
&
params
,
enum_flags
)))
{
free
(
params
.
instances
);
return
hr
;
WARN
(
"Failed to enumerate devices, hr %#lx
\n
"
,
hr
);
goto
cleanup
;
}
remain
=
params
.
instance_count
;
/* Add keyboard and mouse to remaining device count */
if
(
!
(
flags
&
DIEDBSFL_FORCEFEEDBACK
))
while
(
params
.
device_count
--
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
guids
);
i
++
)
{
if
(
should_enumerate_device
(
username
,
flags
,
&
impl
->
device_players
,
guids
[
i
]
))
remain
++
;
}
}
for
(
i
=
0
;
i
<
params
.
instance_count
;
i
++
)
{
callbackFlags
=
diactionformat_priorityW
(
action_format
,
action_format
->
dwGenre
);
IDirectInput_CreateDevice
(
iface
,
&
params
.
instances
[
i
].
guidInstance
,
&
device
,
NULL
);
if
(
callback
(
&
params
.
instances
[
i
],
device
,
callbackFlags
,
--
remain
,
context
)
==
DIENUM_STOP
)
{
free
(
params
.
instances
);
IDirectInputDevice_Release
(
device
);
return
DI_OK
;
}
IDirectInputDevice_Release
(
device
);
}
free
(
params
.
instances
);
if
(
flags
&
DIEDBSFL_FORCEFEEDBACK
)
return
DI_OK
;
/* Enumerate keyboard and mouse */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
guids
);
i
++
)
{
if
(
should_enumerate_device
(
username
,
flags
,
&
impl
->
device_players
,
guids
[
i
]
))
{
callbackFlags
=
diactionformat_priorityW
(
action_format
,
actionMasks
[
i
]
);
IDirectInput_CreateDevice
(
iface
,
guids
[
i
],
&
device
,
NULL
);
IDirectInputDevice_GetDeviceInfo
(
device
,
&
didevi
);
if
(
callback
(
&
didevi
,
device
,
callbackFlags
,
--
remain
,
context
)
==
DIENUM_STOP
)
{
IDirectInputDevice_Release
(
device
);
return
DI_OK
;
}
IDirectInputDevice_Release
(
device
);
}
struct
enum_device_object_semantics_params
object_params
=
{.
instance
=
{.
dwSize
=
sizeof
(
DIDEVICEINSTANCEW
)},
.
format
=
action_format
};
IDirectInputDevice8W
*
device
=
params
.
devices
[
params
.
device_count
];
BOOL
ret
=
DIENUM_STOP
;
if
(
FAILED
(
hr
=
IDirectInputDevice8_GetDeviceInfo
(
device
,
&
object_params
.
instance
)))
WARN
(
"Failed to get device %p info, hr %#lx
\n
"
,
device
,
hr
);
else
if
(
FAILED
(
hr
=
IDirectInputDevice8_EnumObjects
(
device
,
enum_device_object_semantics
,
&
object_params
,
DIDFT_ALL
)))
WARN
(
"Failed to enumerate device %p objects, hr %#lx
\n
"
,
device
,
hr
);
else
ret
=
callback
(
&
object_params
.
instance
,
device
,
object_params
.
flags
,
params
.
device_count
,
context
);
IDirectInputDevice8_Release
(
device
);
if
(
ret
==
DIENUM_STOP
)
goto
cleanup
;
}
return
DI_OK
;
cleanup:
while
(
params
.
device_count
--
)
IDirectInputDevice8_Release
(
params
.
devices
[
params
.
device_count
]
);
return
hr
;
}
static
HRESULT
WINAPI
dinput8_ConfigureDevices
(
IDirectInput8W
*
iface
,
LPDICONFIGUREDEVICESCALLBACK
callback
,
...
...
dlls/dinput/tests/joystick8.c
View file @
d62e2268
...
...
@@ -445,7 +445,7 @@ static BOOL CALLBACK enum_devices_by_semantic( const DIDEVICEINSTANCEW *instance
if
(
remaining
==
2
)
{
expect_instance
=
&
expect_joystick
;
todo_wine
ok
(
flags
==
(
context
?
3
:
0
),
"got flags %#lx
\n
"
,
flags
);
ok
(
flags
==
(
context
?
3
:
0
),
"got flags %#lx
\n
"
,
flags
);
}
else
if
(
remaining
==
1
)
{
...
...
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