Module: wine Branch: master Commit: 967399eba07c33548c7bb941371d03c18547517c URL: http://source.winehq.org/git/wine.git/?a=commit;h=967399eba07c33548c7bb94137...
Author: Jetro Jormalainen jje-wine@jv.jetro.fi Date: Thu Mar 2 20:51:40 2017 +0200
dinput: Keep username same between device objects.
Signed-off-by: Jetro Jormalainen jje-wine@jv.jetro.fi Signed-off-by: Andrew Eikum aeikum@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/dinput/device.c | 38 +++++++++++++++++++++++++++++++++++--- dlls/dinput/device_private.h | 1 - dlls/dinput/dinput_main.c | 6 ++++++ dlls/dinput/dinput_private.h | 7 +++++++ dlls/dinput8/tests/device.c | 11 +++++++++++ 5 files changed, 59 insertions(+), 4 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index a9ef2d4..7b83a39 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1308,11 +1308,24 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, case (DWORD_PTR) DIPROP_USERNAME: { LPDIPROPSTRING ps = (LPDIPROPSTRING)pdiph; + struct DevicePlayer *device_player;
if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
- lstrcpynW(ps->wsz, This->username, sizeof(ps->wsz)/sizeof(WCHAR)); - break; + LIST_FOR_EACH_ENTRY(device_player, &This->dinput->device_players, + struct DevicePlayer, entry) + { + if (IsEqualGUID(&device_player->instance_guid, &This->guid)) + { + if (*device_player->username) + { + lstrcpynW(ps->wsz, device_player->username, sizeof(ps->wsz)/sizeof(WCHAR)); + return DI_OK; + } + else break; + } + } + return S_FALSE; } case (DWORD_PTR) DIPROP_VIDPID: FIXME("DIPROP_VIDPID not implemented\n"); @@ -1390,10 +1403,29 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty( case (DWORD_PTR) DIPROP_USERNAME: { LPCDIPROPSTRING ps = (LPCDIPROPSTRING)pdiph; + struct DevicePlayer *device_player; + BOOL found = FALSE;
if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
- lstrcpynW(This->username, ps->wsz, sizeof(This->username)/sizeof(WCHAR)); + LIST_FOR_EACH_ENTRY(device_player, &This->dinput->device_players, + struct DevicePlayer, entry) + { + if (IsEqualGUID(&device_player->instance_guid, &This->guid)) + { + found = TRUE; + break; + } + } + if (!found && (device_player = + HeapAlloc(GetProcessHeap(), 0, sizeof(struct DevicePlayer)))) + { + list_add_tail(&This->dinput->device_players, &device_player->entry); + device_player->instance_guid = This->guid; + } + if (device_player) + lstrcpynW(device_player->username, ps->wsz, + sizeof(device_player->username)/sizeof(WCHAR)); break; } default: diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index c4fbe85..52bbec4 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -81,7 +81,6 @@ struct IDirectInputDeviceImpl /* Action mapping */ int num_actions; /* number of actions mapped */ ActionMap *action_map; /* array of mappings */ - WCHAR username[MAX_PATH]; };
extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN; diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index ab6a2e8..2bf9f38 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -577,6 +577,7 @@ static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwV This->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectInputImpl*->crit");
list_init( &This->devices_list ); + list_init( &This->device_players );
/* Add self to the list of the IDirectInputs */ EnterCriticalSection( &dinput_hook_crit ); @@ -599,11 +600,16 @@ static void uninitialize_directinput_instance(IDirectInputImpl *This) { if (This->initialized) { + struct DevicePlayer *device_player, *device_player2; /* Remove self from the list of the IDirectInputs */ EnterCriticalSection( &dinput_hook_crit ); list_remove( &This->entry ); LeaveCriticalSection( &dinput_hook_crit );
+ LIST_FOR_EACH_ENTRY_SAFE( device_player, device_player2, + &This->device_players, struct DevicePlayer, entry ) + HeapFree(GetProcessHeap(), 0, device_player); + check_hook_thread();
This->crit.DebugInfo->Spare[0] = 0; diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h index 176c0e0..6c93e16 100644 --- a/dlls/dinput/dinput_private.h +++ b/dlls/dinput/dinput_private.h @@ -46,6 +46,7 @@ struct IDirectInputImpl DWORD evsequence; /* unique sequence number for events */ DWORD dwVersion; /* direct input version number */ struct list devices_list; /* list of all created dinput devices */ + struct list device_players; /* device instance guid to player name */ };
/* Function called by all devices that Wine supports */ @@ -56,6 +57,12 @@ struct dinput_device { HRESULT (*create_device)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode); };
+struct DevicePlayer { + GUID instance_guid; + WCHAR username[MAX_PATH]; + struct list entry; +}; + extern const struct dinput_device mouse_device DECLSPEC_HIDDEN; extern const struct dinput_device keyboard_device DECLSPEC_HIDDEN; extern const struct dinput_device joystick_linux_device DECLSPEC_HIDDEN; diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 6753b73..2b06f62 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -174,6 +174,7 @@ static BOOL CALLBACK enumeration_callback(const DIDEVICEINSTANCEA *lpddi, IDirec struct enum_data *data = pvRef; DWORD cnt; DIDEVICEOBJECTDATA buffer[5]; + IDirectInputDevice8A *lpdid2;
if (!data) return DIENUM_CONTINUE;
@@ -205,6 +206,10 @@ static BOOL CALLBACK enumeration_callback(const DIDEVICEINSTANCEA *lpddi, IDirec ok (dwFlags & DIEDBS_MAPPEDPRI1, "Mouse should be mapped as pri1 dwFlags=%08x\n", dwFlags); }
+ /* Creating second device object to check if it has the same username */ + hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, &lpdid2, NULL); + ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr); + /* Building and setting an action map */ /* It should not use any pre-stored mappings so we use DIDBAM_HWDEFAULTS */ hr = IDirectInputDevice8_BuildActionMap(lpdid, data->lpdiaf, NULL, DIDBAM_HWDEFAULTS); @@ -231,6 +236,11 @@ static BOOL CALLBACK enumeration_callback(const DIDEVICEINSTANCEA *lpddi, IDirec ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr); ok (!lstrcmpW(usernameW, dps.wsz), "Username not set correctly expected=%s, got=%s\n", wine_dbgstr_w(usernameW), wine_dbgstr_w(dps.wsz));
+ dps.wsz[0] = '\0'; + hr = IDirectInputDevice_GetProperty(lpdid2, DIPROP_USERNAME, &dps.diph); + ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr); + ok (!lstrcmpW(usernameW, dps.wsz), "Username not set correctly expected=%s, got=%s\n", wine_dbgstr_w(usernameW), wine_dbgstr_w(dps.wsz)); + /* Test buffer size */ memset(&dp, 0, sizeof(dp)); dp.diph.dwSize = sizeof(dp); @@ -315,6 +325,7 @@ static void test_action_mapping(void) af.dwBufferSize = 32;
/* This enumeration builds and sets the action map for all devices */ + data.pDI = pDI; hr = IDirectInput8_EnumDevicesBySemantics(pDI, 0, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY); ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);