Commit 26c11312 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dinput: Use a single list for all acquired devices.

Instead of going through devices list of dinputs list, and checking their acquired field, which is not CPU friendly. This also removes the now unused IDirectInputImpl critical section and devices list. Signed-off-by: 's avatarRémi Bernon <rbernon@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 9463684d
......@@ -1001,7 +1001,9 @@ HRESULT WINAPI IDirectInputDevice2WImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
res = This->acquired ? S_FALSE : DI_OK;
This->acquired = 1;
LeaveCriticalSection(&This->crit);
if (res == DI_OK)
if (res != DI_OK) return res;
dinput_hooks_acquire_device(iface);
check_dinput_hooks(iface, TRUE);
return res;
......@@ -1029,7 +1031,9 @@ HRESULT WINAPI IDirectInputDevice2WImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
res = !This->acquired ? DI_NOEFFECT : DI_OK;
This->acquired = 0;
LeaveCriticalSection(&This->crit);
if (res == DI_OK)
if (res != DI_OK) return res;
dinput_hooks_unacquire_device(iface);
check_dinput_hooks(iface, FALSE);
return res;
......@@ -1164,10 +1168,6 @@ ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface)
/* Free action mapping */
HeapFree(GetProcessHeap(), 0, This->action_map);
EnterCriticalSection( &This->dinput->crit );
list_remove( &This->entry );
LeaveCriticalSection( &This->dinput->crit );
IDirectInput_Release(&This->dinput->IDirectInput7A_iface);
This->crit.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->crit);
......
......@@ -63,7 +63,7 @@ struct IDirectInputDeviceImpl
GUID guid;
CRITICAL_SECTION crit;
IDirectInputImpl *dinput;
struct list entry; /* entry into IDirectInput devices list */
struct list entry; /* entry into acquired device list */
HANDLE hEvent;
DWORD dwCoopLevel;
HWND win;
......
......@@ -100,10 +100,29 @@ HINSTANCE DINPUT_instance;
static BOOL check_hook_thread(void);
static CRITICAL_SECTION dinput_hook_crit;
static struct list direct_input_list = LIST_INIT( direct_input_list );
static struct list acquired_device_list = LIST_INIT( acquired_device_list );
static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwVersion);
static void uninitialize_directinput_instance(IDirectInputImpl *This);
void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface)
{
IDirectInputDeviceImpl *dev = impl_from_IDirectInputDevice8W(iface);
EnterCriticalSection( &dinput_hook_crit );
list_add_tail( &acquired_device_list, &dev->entry );
LeaveCriticalSection( &dinput_hook_crit );
}
void dinput_hooks_unacquire_device(LPDIRECTINPUTDEVICE8W iface)
{
IDirectInputDeviceImpl *dev = impl_from_IDirectInputDevice8W(iface);
EnterCriticalSection( &dinput_hook_crit );
list_remove( &dev->entry );
LeaveCriticalSection( &dinput_hook_crit );
}
static HRESULT create_directinput_instance(REFIID riid, LPVOID *ppDI, IDirectInputImpl **out)
{
IDirectInputImpl *This = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectInputImpl) );
......@@ -618,10 +637,6 @@ static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwV
This->dwVersion = dwVersion;
This->evsequence = 1;
InitializeCriticalSection( &This->crit );
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 */
......@@ -657,9 +672,6 @@ static void uninitialize_directinput_instance(IDirectInputImpl *This)
check_hook_thread();
This->crit.DebugInfo->Spare[0] = 0;
DeleteCriticalSection( &This->crit );
This->initialized = FALSE;
}
}
......@@ -1641,24 +1653,19 @@ HRESULT WINAPI DllUnregisterServer(void)
static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
{
IDirectInputImpl *dinput;
IDirectInputDeviceImpl *dev;
int skip = 0;
if (code != HC_ACTION) return CallNextHookEx( 0, code, wparam, lparam );
EnterCriticalSection( &dinput_hook_crit );
LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
LIST_FOR_EACH_ENTRY( dev, &acquired_device_list, IDirectInputDeviceImpl, entry )
{
IDirectInputDeviceImpl *dev;
EnterCriticalSection( &dinput->crit );
LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
if (dev->acquired && dev->event_proc)
if (dev->event_proc)
{
TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam);
skip |= dev->event_proc( &dev->IDirectInputDevice8A_iface, wparam, lparam );
}
LeaveCriticalSection( &dinput->crit );
}
LeaveCriticalSection( &dinput_hook_crit );
......@@ -1667,8 +1674,8 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam )
{
IDirectInputDeviceImpl *dev, *next;
CWPSTRUCT *msg = (CWPSTRUCT *)lparam;
IDirectInputImpl *dinput;
HWND foreground;
if (code != HC_ACTION || (msg->message != WM_KILLFOCUS &&
......@@ -1678,24 +1685,14 @@ static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam
foreground = GetForegroundWindow();
EnterCriticalSection( &dinput_hook_crit );
LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
{
IDirectInputDeviceImpl *dev;
EnterCriticalSection( &dinput->crit );
LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
LIST_FOR_EACH_ENTRY_SAFE( dev, next, &acquired_device_list, IDirectInputDeviceImpl, entry )
{
if (!dev->acquired) continue;
if (msg->hwnd == dev->win && msg->hwnd != foreground)
{
TRACE( "%p window is not foreground - unacquiring %p\n", dev->win, dev );
IDirectInputDevice_Unacquire( &dev->IDirectInputDevice8A_iface );
}
}
LeaveCriticalSection( &dinput->crit );
}
LeaveCriticalSection( &dinput_hook_crit );
return CallNextHookEx( 0, code, wparam, lparam );
......@@ -1716,7 +1713,7 @@ static DWORD WINAPI hook_thread_proc(void *param)
if (msg.message == WM_USER+0x10)
{
IDirectInputImpl *dinput;
IDirectInputDeviceImpl *dev;
HANDLE finished_event = (HANDLE)msg.lParam;
TRACE( "Processing hook change notification wp:%ld lp:%#lx\n", msg.wParam, msg.lParam );
......@@ -1732,14 +1729,9 @@ static DWORD WINAPI hook_thread_proc(void *param)
EnterCriticalSection( &dinput_hook_crit );
/* Count acquired keyboards and mice*/
LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
LIST_FOR_EACH_ENTRY( dev, &acquired_device_list, IDirectInputDeviceImpl, entry )
{
IDirectInputDeviceImpl *dev;
EnterCriticalSection( &dinput->crit );
LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
{
if (!dev->acquired || !dev->event_proc) continue;
if (!dev->event_proc) continue;
if (IsEqualGUID( &dev->guid, &GUID_SysKeyboard ))
kbd_cnt++;
......@@ -1747,8 +1739,6 @@ static DWORD WINAPI hook_thread_proc(void *param)
if (IsEqualGUID( &dev->guid, &GUID_SysMouse ))
mice_cnt++;
}
LeaveCriticalSection( &dinput->crit );
}
LeaveCriticalSection( &dinput_hook_crit );
if (kbd_cnt && !kbd_hook)
......
......@@ -42,12 +42,10 @@ struct IDirectInputImpl
LONG ref;
BOOL initialized;
CRITICAL_SECTION crit;
struct list entry; /* entry into list of all IDirectInputs */
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 */
};
......@@ -71,6 +69,9 @@ extern const struct dinput_device joystick_linux_device DECLSPEC_HIDDEN;
extern const struct dinput_device joystick_linuxinput_device DECLSPEC_HIDDEN;
extern const struct dinput_device joystick_osx_device DECLSPEC_HIDDEN;
extern void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface);
extern void dinput_hooks_unacquire_device(LPDIRECTINPUTDEVICE8W iface);
extern void check_dinput_hooks(LPDIRECTINPUTDEVICE8W, BOOL) DECLSPEC_HIDDEN;
extern void check_dinput_events(void) DECLSPEC_HIDDEN;
typedef int (*DI_EVENT_PROC)(LPDIRECTINPUTDEVICE8A, WPARAM, LPARAM);
......
......@@ -554,10 +554,6 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
EnterCriticalSection(&dinput->crit);
list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
LeaveCriticalSection(&dinput->crit);
newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
......
......@@ -595,10 +595,6 @@ static JoystickImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput, unsig
IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
EnterCriticalSection(&dinput->crit);
list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
LeaveCriticalSection(&dinput->crit);
return newDevice;
failed:
......
......@@ -1242,10 +1242,6 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
EnterCriticalSection(&dinput->crit);
list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
LeaveCriticalSection(&dinput->crit);
newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
newDevice->generic.devcaps.dwFlags |= DIDC_ATTACHED;
if (newDevice->generic.base.dinput->dwVersion >= 0x0800)
......
......@@ -291,10 +291,6 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
newDevice->base.data_format.wine_df = df;
IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface);
EnterCriticalSection(&dinput->crit);
list_add_tail(&dinput->devices_list, &newDevice->base.entry);
LeaveCriticalSection(&dinput->crit);
return newDevice;
failed:
......
......@@ -242,10 +242,6 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
newDevice->base.data_format.wine_df = df;
IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface);
EnterCriticalSection(&dinput->crit);
list_add_tail(&dinput->devices_list, &newDevice->base.entry);
LeaveCriticalSection(&dinput->crit);
return newDevice;
failed:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment