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>
This commit is contained in:
parent
5b78cc992c
commit
967399eba0
|
@ -1308,11 +1308,24 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface,
|
||||||
case (DWORD_PTR) DIPROP_USERNAME:
|
case (DWORD_PTR) DIPROP_USERNAME:
|
||||||
{
|
{
|
||||||
LPDIPROPSTRING ps = (LPDIPROPSTRING)pdiph;
|
LPDIPROPSTRING ps = (LPDIPROPSTRING)pdiph;
|
||||||
|
struct DevicePlayer *device_player;
|
||||||
|
|
||||||
if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
|
if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
|
||||||
|
|
||||||
lstrcpynW(ps->wsz, This->username, sizeof(ps->wsz)/sizeof(WCHAR));
|
LIST_FOR_EACH_ENTRY(device_player, &This->dinput->device_players,
|
||||||
break;
|
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:
|
case (DWORD_PTR) DIPROP_VIDPID:
|
||||||
FIXME("DIPROP_VIDPID not implemented\n");
|
FIXME("DIPROP_VIDPID not implemented\n");
|
||||||
|
@ -1390,10 +1403,29 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty(
|
||||||
case (DWORD_PTR) DIPROP_USERNAME:
|
case (DWORD_PTR) DIPROP_USERNAME:
|
||||||
{
|
{
|
||||||
LPCDIPROPSTRING ps = (LPCDIPROPSTRING)pdiph;
|
LPCDIPROPSTRING ps = (LPCDIPROPSTRING)pdiph;
|
||||||
|
struct DevicePlayer *device_player;
|
||||||
|
BOOL found = FALSE;
|
||||||
|
|
||||||
if (pdiph->dwSize != sizeof(DIPROPSTRING)) return DIERR_INVALIDPARAM;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -81,7 +81,6 @@ struct IDirectInputDeviceImpl
|
||||||
/* Action mapping */
|
/* Action mapping */
|
||||||
int num_actions; /* number of actions mapped */
|
int num_actions; /* number of actions mapped */
|
||||||
ActionMap *action_map; /* array of mappings */
|
ActionMap *action_map; /* array of mappings */
|
||||||
WCHAR username[MAX_PATH];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN;
|
extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -577,6 +577,7 @@ static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwV
|
||||||
This->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectInputImpl*->crit");
|
This->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectInputImpl*->crit");
|
||||||
|
|
||||||
list_init( &This->devices_list );
|
list_init( &This->devices_list );
|
||||||
|
list_init( &This->device_players );
|
||||||
|
|
||||||
/* Add self to the list of the IDirectInputs */
|
/* Add self to the list of the IDirectInputs */
|
||||||
EnterCriticalSection( &dinput_hook_crit );
|
EnterCriticalSection( &dinput_hook_crit );
|
||||||
|
@ -599,11 +600,16 @@ static void uninitialize_directinput_instance(IDirectInputImpl *This)
|
||||||
{
|
{
|
||||||
if (This->initialized)
|
if (This->initialized)
|
||||||
{
|
{
|
||||||
|
struct DevicePlayer *device_player, *device_player2;
|
||||||
/* Remove self from the list of the IDirectInputs */
|
/* Remove self from the list of the IDirectInputs */
|
||||||
EnterCriticalSection( &dinput_hook_crit );
|
EnterCriticalSection( &dinput_hook_crit );
|
||||||
list_remove( &This->entry );
|
list_remove( &This->entry );
|
||||||
LeaveCriticalSection( &dinput_hook_crit );
|
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();
|
check_hook_thread();
|
||||||
|
|
||||||
This->crit.DebugInfo->Spare[0] = 0;
|
This->crit.DebugInfo->Spare[0] = 0;
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct IDirectInputImpl
|
||||||
DWORD evsequence; /* unique sequence number for events */
|
DWORD evsequence; /* unique sequence number for events */
|
||||||
DWORD dwVersion; /* direct input version number */
|
DWORD dwVersion; /* direct input version number */
|
||||||
struct list devices_list; /* list of all created dinput devices */
|
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 */
|
/* 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);
|
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 mouse_device DECLSPEC_HIDDEN;
|
||||||
extern const struct dinput_device keyboard_device DECLSPEC_HIDDEN;
|
extern const struct dinput_device keyboard_device DECLSPEC_HIDDEN;
|
||||||
extern const struct dinput_device joystick_linux_device DECLSPEC_HIDDEN;
|
extern const struct dinput_device joystick_linux_device DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -174,6 +174,7 @@ static BOOL CALLBACK enumeration_callback(const DIDEVICEINSTANCEA *lpddi, IDirec
|
||||||
struct enum_data *data = pvRef;
|
struct enum_data *data = pvRef;
|
||||||
DWORD cnt;
|
DWORD cnt;
|
||||||
DIDEVICEOBJECTDATA buffer[5];
|
DIDEVICEOBJECTDATA buffer[5];
|
||||||
|
IDirectInputDevice8A *lpdid2;
|
||||||
|
|
||||||
if (!data) return DIENUM_CONTINUE;
|
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);
|
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 */
|
/* Building and setting an action map */
|
||||||
/* It should not use any pre-stored mappings so we use DIDBAM_HWDEFAULTS */
|
/* It should not use any pre-stored mappings so we use DIDBAM_HWDEFAULTS */
|
||||||
hr = IDirectInputDevice8_BuildActionMap(lpdid, data->lpdiaf, NULL, 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 (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));
|
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 */
|
/* Test buffer size */
|
||||||
memset(&dp, 0, sizeof(dp));
|
memset(&dp, 0, sizeof(dp));
|
||||||
dp.diph.dwSize = sizeof(dp);
|
dp.diph.dwSize = sizeof(dp);
|
||||||
|
@ -315,6 +325,7 @@ static void test_action_mapping(void)
|
||||||
af.dwBufferSize = 32;
|
af.dwBufferSize = 32;
|
||||||
|
|
||||||
/* This enumeration builds and sets the action map for all devices */
|
/* 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);
|
hr = IDirectInput8_EnumDevicesBySemantics(pDI, 0, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY);
|
||||||
ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);
|
ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue