Author: akhaldi Date: Sat Jun 3 18:05:46 2017 New Revision: 74776
URL: http://svn.reactos.org/svn/reactos?rev=74776&view=rev Log: [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.
Modified: trunk/reactos/dll/directx/wine/dinput/device.c trunk/reactos/dll/directx/wine/dinput/device_private.h trunk/reactos/dll/directx/wine/dinput/dinput_main.c trunk/reactos/dll/directx/wine/dinput/dinput_private.h trunk/reactos/dll/directx/wine/dinput/joystick_linux.c trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/directx/wine/dinput/device.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/dev... ============================================================================== --- trunk/reactos/dll/directx/wine/dinput/device.c [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dinput/device.c [iso-8859-1] Sat Jun 3 18:05:46 2017 @@ -1294,11 +1294,24 @@ 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 @@ 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:
Modified: trunk/reactos/dll/directx/wine/dinput/device_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/dev... ============================================================================== --- trunk/reactos/dll/directx/wine/dinput/device_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dinput/device_private.h [iso-8859-1] Sat Jun 3 18:05:46 2017 @@ -73,7 +73,6 @@ /* 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;
Modified: trunk/reactos/dll/directx/wine/dinput/dinput_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/din... ============================================================================== --- trunk/reactos/dll/directx/wine/dinput/dinput_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dinput/dinput_main.c [iso-8859-1] Sat Jun 3 18:05:46 2017 @@ -558,6 +558,7 @@ 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,10 +581,15 @@ { 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();
@@ -898,6 +904,47 @@ 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 @@ 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 @@
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 @@
/* 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 @@ }
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 @@ 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]); - - 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 (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); + + 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 @@
/* 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 @@ }
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 @@ /* Enumerate keyboard and mouse */ for(i=0; i < sizeof(guids)/sizeof(guids[0]); i++) { - callbackFlags = diactionformat_priorityW(lpdiActionFormat, actionMasks[i]); - - 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 (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); + + if (lpCallback(&didevi, lpdid, callbackFlags, --remain, pvRef) == DIENUM_STOP) + return DI_OK; + } }
return DI_OK;
Modified: trunk/reactos/dll/directx/wine/dinput/dinput_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/din... ============================================================================== --- trunk/reactos/dll/directx/wine/dinput/dinput_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dinput/dinput_private.h [iso-8859-1] Sat Jun 3 18:05:46 2017 @@ -62,6 +62,7 @@ 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 */ @@ -70,6 +71,12 @@ HRESULT (*enum_deviceA)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id); HRESULT (*enum_deviceW)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id); 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;
Modified: trunk/reactos/dll/directx/wine/dinput/joystick_linux.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/joy... ============================================================================== --- trunk/reactos/dll/directx/wine/dinput/joystick_linux.c [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dinput/joystick_linux.c [iso-8859-1] Sat Jun 3 18:05:46 2017 @@ -208,19 +208,36 @@ 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 */
Modified: trunk/reactos/media/doc/README.WINE URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=7... ============================================================================== --- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original) +++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Sat Jun 3 18:05:46 2017 @@ -30,7 +30,7 @@ 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