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
af1dcde2
Commit
af1dcde2
authored
Aug 24, 2012
by
Lucas Zawacki
Committed by
Alexandre Julliard
Aug 27, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dinput: SetActionMap saving mappings.
parent
77cab1ce
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
149 additions
and
4 deletions
+149
-4
device.c
dlls/dinput/device.c
+143
-0
dinput_private.h
dlls/dinput/dinput_private.h
+2
-0
device.c
dlls/dinput8/tests/device.c
+4
-4
No files found.
dlls/dinput/device.c
View file @
af1dcde2
...
...
@@ -598,10 +598,142 @@ static DWORD semantic_to_obj_id(IDirectInputDeviceImpl* This, DWORD dwSemantic)
return
type
|
(
0x0000ff00
&
(
obj_instance
<<
8
));
}
/*
* get_mapping_key
* Retrieves an open registry key to save the mapping, parametrized for an username,
* specific device and specific action mapping guid.
*/
static
HKEY
get_mapping_key
(
const
WCHAR
*
device
,
const
WCHAR
*
username
,
const
WCHAR
*
guid
)
{
static
const
WCHAR
subkey
[]
=
{
'S'
,
'o'
,
'f'
,
't'
,
'w'
,
'a'
,
'r'
,
'e'
,
'\\'
,
'W'
,
'i'
,
'n'
,
'e'
,
'\\'
,
'D'
,
'i'
,
'r'
,
'e'
,
'c'
,
't'
,
'I'
,
'n'
,
'p'
,
'u'
,
't'
,
'\\'
,
'M'
,
'a'
,
'p'
,
'p'
,
'i'
,
'n'
,
'g'
,
's'
,
'\\'
,
'%'
,
's'
,
'\\'
,
'%'
,
's'
,
'\\'
,
'%'
,
's'
,
'\0'
};
HKEY
hkey
;
WCHAR
*
keyname
;
keyname
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WCHAR
)
*
(
lstrlenW
(
subkey
)
+
strlenW
(
username
)
+
strlenW
(
device
)
+
strlenW
(
guid
)));
sprintfW
(
keyname
,
subkey
,
username
,
device
,
guid
);
/* The key used is HKCU\Software\Wine\DirectInput\Mappings\[username]\[device]\[mapping_guid] */
if
(
RegCreateKeyW
(
HKEY_CURRENT_USER
,
keyname
,
&
hkey
))
hkey
=
0
;
HeapFree
(
GetProcessHeap
(),
0
,
keyname
);
return
hkey
;
}
static
HRESULT
save_mapping_settings
(
IDirectInputDevice8W
*
iface
,
LPDIACTIONFORMATW
lpdiaf
,
LPCWSTR
lpszUsername
)
{
WCHAR
*
guid_str
=
NULL
;
DIDEVICEINSTANCEW
didev
;
HKEY
hkey
;
int
i
;
didev
.
dwSize
=
sizeof
(
didev
);
IDirectInputDevice8_GetDeviceInfo
(
iface
,
&
didev
);
if
(
StringFromCLSID
(
&
lpdiaf
->
guidActionMap
,
&
guid_str
)
!=
S_OK
)
return
DI_SETTINGSNOTSAVED
;
hkey
=
get_mapping_key
(
didev
.
tszInstanceName
,
lpszUsername
,
guid_str
);
if
(
!
hkey
)
{
CoTaskMemFree
(
guid_str
);
return
DI_SETTINGSNOTSAVED
;
}
/* Write each of the actions mapped for this device.
Format is "dwSemantic"="dwObjID" and key is of type REG_DWORD
*/
for
(
i
=
0
;
i
<
lpdiaf
->
dwNumActions
;
i
++
)
{
static
const
WCHAR
format
[]
=
{
'%'
,
'x'
,
'\0'
};
WCHAR
label
[
9
];
if
(
IsEqualGUID
(
&
didev
.
guidInstance
,
&
lpdiaf
->
rgoAction
[
i
].
guidInstance
)
&&
lpdiaf
->
rgoAction
[
i
].
dwHow
!=
DIAH_UNMAPPED
)
{
sprintfW
(
label
,
format
,
lpdiaf
->
rgoAction
[
i
].
dwSemantic
);
RegSetValueExW
(
hkey
,
label
,
0
,
REG_DWORD
,
(
const
BYTE
*
)
&
lpdiaf
->
rgoAction
[
i
].
dwObjID
,
sizeof
(
DWORD
));
}
}
RegCloseKey
(
hkey
);
CoTaskMemFree
(
guid_str
);
return
DI_OK
;
}
static
BOOL
load_mapping_settings
(
IDirectInputDeviceImpl
*
This
,
LPDIACTIONFORMATW
lpdiaf
,
const
WCHAR
*
username
)
{
HKEY
hkey
;
WCHAR
*
guid_str
;
DIDEVICEINSTANCEW
didev
;
int
i
;
didev
.
dwSize
=
sizeof
(
didev
);
IDirectInputDevice8_GetDeviceInfo
(
&
This
->
IDirectInputDevice8W_iface
,
&
didev
);
if
(
StringFromCLSID
(
&
lpdiaf
->
guidActionMap
,
&
guid_str
)
!=
S_OK
)
return
FALSE
;
hkey
=
get_mapping_key
(
didev
.
tszInstanceName
,
username
,
guid_str
);
if
(
!
hkey
)
{
CoTaskMemFree
(
guid_str
);
return
FALSE
;
}
/* Try to read each action in the DIACTIONFORMAT from registry */
for
(
i
=
0
;
i
<
lpdiaf
->
dwNumActions
;
i
++
)
{
static
const
WCHAR
format
[]
=
{
'%'
,
'x'
,
'\0'
};
DWORD
id
,
size
=
sizeof
(
DWORD
);
WCHAR
label
[
9
];
sprintfW
(
label
,
format
,
lpdiaf
->
rgoAction
[
i
].
dwSemantic
);
if
(
!
RegQueryValueExW
(
hkey
,
label
,
0
,
NULL
,
(
LPBYTE
)
&
id
,
&
size
))
{
lpdiaf
->
rgoAction
[
i
].
dwObjID
=
id
;
lpdiaf
->
rgoAction
[
i
].
guidInstance
=
didev
.
guidInstance
;
lpdiaf
->
rgoAction
[
i
].
dwHow
=
DIAH_USERCONFIG
;
}
}
RegCloseKey
(
hkey
);
CoTaskMemFree
(
guid_str
);
return
TRUE
;
}
HRESULT
_build_action_map
(
LPDIRECTINPUTDEVICE8W
iface
,
LPDIACTIONFORMATW
lpdiaf
,
LPCWSTR
lpszUserName
,
DWORD
dwFlags
,
DWORD
devMask
,
LPCDIDATAFORMAT
df
)
{
IDirectInputDeviceImpl
*
This
=
impl_from_IDirectInputDevice8W
(
iface
);
WCHAR
username
[
MAX_PATH
];
DWORD
username_size
=
MAX_PATH
;
int
i
,
has_actions
=
0
;
BOOL
load_success
=
FALSE
;
/* Unless asked the contrary by these flags, try to load a previous mapping */
if
(
!
(
dwFlags
&
DIDBAM_HWDEFAULTS
))
{
/* Retrieve logged user name if necessary */
if
(
lpszUserName
==
NULL
)
GetUserNameW
(
username
,
&
username_size
);
else
lstrcpynW
(
username
,
lpszUserName
,
MAX_PATH
);
load_success
=
load_mapping_settings
(
This
,
lpdiaf
,
username
);
}
if
(
load_success
)
return
DI_OK
;
for
(
i
=
0
;
i
<
lpdiaf
->
dwNumActions
;
i
++
)
{
...
...
@@ -650,6 +782,8 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L
DIOBJECTDATAFORMAT
*
obj_df
=
NULL
;
DIPROPDWORD
dp
;
DIPROPRANGE
dpr
;
WCHAR
username
[
MAX_PATH
];
DWORD
username_size
=
MAX_PATH
;
int
i
,
action
=
0
,
num_actions
=
0
;
unsigned
int
offset
=
0
;
...
...
@@ -722,6 +856,15 @@ HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, L
IDirectInputDevice8_SetProperty
(
iface
,
DIPROP_BUFFERSIZE
,
&
dp
.
diph
);
}
/* Retrieve logged user name if necessary */
if
(
lpszUserName
==
NULL
)
GetUserNameW
(
username
,
&
username_size
);
else
lstrcpynW
(
username
,
lpszUserName
,
MAX_PATH
);
/* Save the settings to disk */
save_mapping_settings
(
iface
,
lpdiaf
,
username
);
return
IDirectInputDevice8WImpl_SetActionMap
(
iface
,
lpdiaf
,
lpszUserName
,
dwFlags
);
}
...
...
dlls/dinput/dinput_private.h
View file @
af1dcde2
...
...
@@ -70,6 +70,8 @@ extern void _copy_diactionformatWtoA(LPDIACTIONFORMATA, LPDIACTIONFORMATW) DECLS
extern
HRESULT
_configure_devices
(
IDirectInput8W
*
iface
,
LPDICONFIGUREDEVICESCALLBACK
lpdiCallback
,
LPDICONFIGUREDEVICESPARAMSW
lpdiCDParams
,
DWORD
dwFlags
,
LPVOID
pvRefData
)
DECLSPEC_HIDDEN
;
extern
WCHAR
*
get_mapping_path
(
const
WCHAR
*
device
,
const
WCHAR
*
username
)
DECLSPEC_HIDDEN
;
#define IS_DIPROP(x) (((ULONG_PTR)(x) >> 16) == 0)
#define DIKEYBOARD_MASK 0x81000000
...
...
dlls/dinput8/tests/device.c
View file @
af1dcde2
...
...
@@ -458,13 +458,13 @@ static void test_save_settings(void)
hr
=
IDirectInputDevice8_BuildActionMap
(
pKey
,
&
af
,
NULL
,
0
);
ok
(
SUCCEEDED
(
hr
),
"BuildActionMap failed hr=%08x
\n
"
,
hr
);
todo_wine
ok
(
other_results
[
0
]
==
af
.
rgoAction
[
0
].
dwObjID
,
ok
(
other_results
[
0
]
==
af
.
rgoAction
[
0
].
dwObjID
,
"Mapped incorrectly expected: 0x%08x got: 0x%08x
\n
"
,
other_results
[
0
],
af
.
rgoAction
[
0
].
dwObjID
);
todo_wine
ok
(
IsEqualGUID
(
&
GUID_SysKeyboard
,
&
af
.
rgoAction
[
0
].
guidInstance
),
"Action should be mapped to keyboard
\n
"
);
ok
(
IsEqualGUID
(
&
GUID_SysKeyboard
,
&
af
.
rgoAction
[
0
].
guidInstance
),
"Action should be mapped to keyboard
\n
"
);
todo_wine
ok
(
other_results
[
1
]
==
af
.
rgoAction
[
1
].
dwObjID
,
ok
(
other_results
[
1
]
==
af
.
rgoAction
[
1
].
dwObjID
,
"Mapped incorrectly expected: 0x%08x got: 0x%08x
\n
"
,
other_results
[
1
],
af
.
rgoAction
[
1
].
dwObjID
);
todo_wine
ok
(
IsEqualGUID
(
&
GUID_SysKeyboard
,
&
af
.
rgoAction
[
1
].
guidInstance
),
"Action should be mapped to keyboard
\n
"
);
ok
(
IsEqualGUID
(
&
GUID_SysKeyboard
,
&
af
.
rgoAction
[
1
].
guidInstance
),
"Action should be mapped to keyboard
\n
"
);
}
START_TEST
(
device
)
...
...
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