mirror of
https://github.com/reactos/wine.git
synced 2024-11-28 14:10:32 +00:00
dinput: SetActionMap saving mappings.
This commit is contained in:
parent
77cab1ce98
commit
af1dcde288
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user