mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 02:34:53 +00:00
[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:
parent
e1aaa10312
commit
6ab32d28bf
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue