[DINPUT] Sync with Wine Staging 2.9. CORE-13362

e87ccb8 dinput: Assume a 1-to-1 axes map when no axes match.
41b126b dinput: Handle username in EnumDevicesBySemantics.
967399e dinput: Keep username same between device objects.

svn path=/trunk/; revision=74776
This commit is contained in:
Amine Khaldi 2017-06-03 18:05:46 +00:00
parent e1aaa10312
commit 6ab32d28bf
6 changed files with 163 additions and 21 deletions

View file

@ -1294,11 +1294,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");
@ -1376,10 +1389,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:

View file

@ -73,7 +73,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;

View file

@ -558,6 +558,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 );
@ -580,11 +581,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;
@ -898,6 +904,47 @@ static HRESULT WINAPI IDirectInput8WImpl_FindDevice(LPDIRECTINPUT8W iface, REFGU
return IDirectInput2WImpl_FindDevice( &This->IDirectInput7W_iface, rguid, pszName, pguidInstance );
}
static BOOL should_enumerate_device(const WCHAR *username, DWORD dwFlags,
struct list *device_players, REFGUID guid)
{
BOOL should_enumerate = TRUE;
struct DevicePlayer *device_player;
/* Check if user owns this device */
if (dwFlags & DIEDBSFL_THISUSER && username && *username)
{
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 && !lstrcmpW(username, device_player->username))
return TRUE; /* Device username matches */
break;
}
}
}
/* Check if this device is not owned by anyone */
if (dwFlags & DIEDBSFL_AVAILABLEDEVICES) {
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 */
}
return should_enumerate;
}
static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
LPDIRECTINPUT8A iface, LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat,
LPDIENUMDEVICESBYSEMANTICSCBA lpCallback,
@ -914,6 +961,7 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
int device_count = 0;
int remain;
DIDEVICEINSTANCEA *didevis = 0;
WCHAR *username_w = 0;
FIXME("(this=%p,%s,%p,%p,%p,%04x): semi-stub\n", This, debugstr_a(ptszUserName), lpdiActionFormat,
lpCallback, pvRef, dwFlags);
@ -930,6 +978,14 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
didevi.dwSize = sizeof(didevi);
if (ptszUserName)
{
int len = MultiByteToWideChar(CP_ACP, 0, ptszUserName, -1, 0, 0);
username_w = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
MultiByteToWideChar(CP_ACP, 0, ptszUserName, -1, username_w, len);
}
/* Enumerate all the joysticks */
for (i = 0; i < NB_DINPUT_DEVICES; i++)
{
@ -943,7 +999,8 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
/* Default behavior is to enumerate attached game controllers */
enumSuccess = dinput_devices[i]->enum_deviceA(DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY | dwFlags, &didevi, This->dwVersion, j);
if (enumSuccess == S_OK)
if (enumSuccess == S_OK &&
should_enumerate_device(username_w, dwFlags, &This->device_players, &didevi.guidInstance))
{
if (device_count++)
didevis = HeapReAlloc(GetProcessHeap(), 0, didevis, sizeof(DIDEVICEINSTANCEA)*device_count);
@ -955,8 +1012,15 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
}
remain = device_count;
/* Add keyboard and mouse to remaining device count */
if (!(dwFlags & DIEDBSFL_FORCEFEEDBACK))
remain += sizeof(guids)/sizeof(guids[0]);
{
for (i = 0; i < sizeof(guids) / sizeof(guids[0]); i++)
{
if (should_enumerate_device(username_w, dwFlags, &This->device_players, guids[i]))
remain++;
}
}
for (i = 0; i < device_count; i++)
{
@ -966,26 +1030,38 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
if (lpCallback(&didevis[i], lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP)
{
HeapFree(GetProcessHeap(), 0, didevis);
HeapFree(GetProcessHeap(), 0, username_w);
return DI_OK;
}
}
HeapFree(GetProcessHeap(), 0, didevis);
if (dwFlags & DIEDBSFL_FORCEFEEDBACK) return DI_OK;
if (dwFlags & DIEDBSFL_FORCEFEEDBACK)
{
HeapFree(GetProcessHeap(), 0, username_w);
return DI_OK;
}
/* Enumerate keyboard and mouse */
for(i=0; i < sizeof(guids)/sizeof(guids[0]); i++)
{
callbackFlags = diactionformat_priorityA(lpdiActionFormat, actionMasks[i]);
if (should_enumerate_device(username_w, dwFlags, &This->device_players, guids[i]))
{
callbackFlags = diactionformat_priorityA(lpdiActionFormat, actionMasks[i]);
IDirectInput_CreateDevice(iface, guids[i], &lpdid, NULL);
IDirectInputDevice_GetDeviceInfo(lpdid, &didevi);
IDirectInput_CreateDevice(iface, guids[i], &lpdid, NULL);
IDirectInputDevice_GetDeviceInfo(lpdid, &didevi);
if (lpCallback(&didevi, lpdid, callbackFlags, sizeof(guids)/sizeof(guids[0]) - (i+1), pvRef) == DIENUM_STOP)
return DI_OK;
if (lpCallback(&didevi, lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP)
{
HeapFree(GetProcessHeap(), 0, username_w);
return DI_OK;
}
}
}
HeapFree(GetProcessHeap(), 0, username_w);
return DI_OK;
}
@ -1024,7 +1100,8 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
/* Default behavior is to enumerate attached game controllers */
enumSuccess = dinput_devices[i]->enum_deviceW(DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY | dwFlags, &didevi, This->dwVersion, j);
if (enumSuccess == S_OK)
if (enumSuccess == S_OK &&
should_enumerate_device(ptszUserName, dwFlags, &This->device_players, &didevi.guidInstance))
{
if (device_count++)
didevis = HeapReAlloc(GetProcessHeap(), 0, didevis, sizeof(DIDEVICEINSTANCEW)*device_count);
@ -1036,8 +1113,15 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
}
remain = device_count;
/* Add keyboard and mouse to remaining device count */
if (!(dwFlags & DIEDBSFL_FORCEFEEDBACK))
remain += sizeof(guids)/sizeof(guids[0]);
{
for (i = 0; i < sizeof(guids) / sizeof(guids[0]); i++)
{
if (should_enumerate_device(ptszUserName, dwFlags, &This->device_players, guids[i]))
remain++;
}
}
for (i = 0; i < device_count; i++)
{
@ -1058,13 +1142,16 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
/* Enumerate keyboard and mouse */
for(i=0; i < sizeof(guids)/sizeof(guids[0]); i++)
{
callbackFlags = diactionformat_priorityW(lpdiActionFormat, actionMasks[i]);
if (should_enumerate_device(ptszUserName, dwFlags, &This->device_players, guids[i]))
{
callbackFlags = diactionformat_priorityW(lpdiActionFormat, actionMasks[i]);
IDirectInput_CreateDevice(iface, guids[i], &lpdid, NULL);
IDirectInputDevice_GetDeviceInfo(lpdid, &didevi);
IDirectInput_CreateDevice(iface, guids[i], &lpdid, NULL);
IDirectInputDevice_GetDeviceInfo(lpdid, &didevi);
if (lpCallback(&didevi, lpdid, callbackFlags, sizeof(guids)/sizeof(guids[0]) - (i+1), pvRef) == DIENUM_STOP)
return DI_OK;
if (lpCallback(&didevi, lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP)
return DI_OK;
}
}
return DI_OK;

View file

@ -62,6 +62,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 */
@ -72,6 +73,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;

View file

@ -208,19 +208,36 @@ static INT find_joystick_devices(void)
else
if ((joydev.dev_axes_map = HeapAlloc(GetProcessHeap(), 0, joydev.axis_count * sizeof(int))))
{
INT j;
INT j, found_axes = 0;
/* Remap to DI numbers */
for (j = 0; j < joydev.axis_count; j++)
{
if (axes_map[j] < 8)
{
/* Axis match 1-to-1 */
joydev.dev_axes_map[j] = j;
found_axes++;
}
else if (axes_map[j] == 16 ||
axes_map[j] == 17)
{
/* POV axis */
joydev.dev_axes_map[j] = 8;
found_axes++;
}
else
joydev.dev_axes_map[j] = -1;
}
/* If no axes were configured but there are axes assume a 1-to-1 (wii controller) */
if (joydev.axis_count && !found_axes)
{
ERR("Incoherent joystick data, advertised %d axes, detected 0. Assuming 1-to-1.\n",
joydev.axis_count);
for (j = 0; j < joydev.axis_count; j++)
joydev.dev_axes_map[j] = j;
}
}
/* Find vendor_id and product_id in sysfs */

View file

@ -30,7 +30,7 @@ reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-1.9.4
reactos/dll/directx/wine/d3dxof # Synced to WineStaging-1.9.23
reactos/dll/directx/wine/ddraw # Synced to WineStaging-1.9.4
reactos/dll/directx/wine/devenum # Synced to WineStaging-2.9
reactos/dll/directx/wine/dinput # Synced to WineStaging-2.2
reactos/dll/directx/wine/dinput # Synced to WineStaging-2.9
reactos/dll/directx/wine/dinput8 # Synced to WineStaging-1.9.23
reactos/dll/directx/wine/dmusic # Synced to WineStaging-1.9.23
reactos/dll/directx/wine/dplay # Synced to WineStaging-1.9.23