Module: wine Branch: master Commit: 448dde9be8e1334d20b404288367e1c47edb485c URL: http://source.winehq.org/git/wine.git/?a=commit;h=448dde9be8e1334d20b4042883...
Author: Vitaliy Margolen wine-patches@kievinfo.com Date: Fri Jul 6 23:36:09 2007 -0600
dinput: Keep the list of all the dinput devices created for each IDIrectInput object.
---
dlls/dinput/device.c | 4 ++++ dlls/dinput/device_private.h | 2 ++ dlls/dinput/dinput_main.c | 40 +++++++++++++++++++++++++++++++--------- dlls/dinput/dinput_private.h | 12 +++++++----- 4 files changed, 44 insertions(+), 14 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 35bf117..618665f 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -688,6 +688,10 @@ ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface) HeapFree(GetProcessHeap(), 0, This->data_format.wine_df); release_DataFormat(&This->data_format);
+ EnterCriticalSection( &This->dinput->crit ); + list_remove( &This->entry ); + LeaveCriticalSection( &This->dinput->crit ); + IDirectInput_Release((LPDIRECTINPUTDEVICE8A)This->dinput); This->crit.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->crit); diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index 6295d6c..2ac609b 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -25,6 +25,7 @@ #include "windef.h" #include "winbase.h" #include "dinput.h" +#include "wine/list.h" #include "dinput_private.h"
typedef struct @@ -55,6 +56,7 @@ struct IDirectInputDevice2AImpl GUID guid; CRITICAL_SECTION crit; IDirectInputImpl *dinput; + struct list entry; /* entry into IDirectInput devices list */ HANDLE hEvent; DWORD dwCoopLevel; HWND win; diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 28718fa..52be7f3 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -43,6 +43,7 @@ #include "winuser.h" #include "winerror.h" #include "dinput_private.h" +#include "device_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
@@ -129,6 +130,11 @@ HRESULT WINAPI DirectInputCreateEx( This->dwVersion = dwVersion; This->evsequence = 1; *ppDI = This; + + InitializeCriticalSection(&This->crit); + This->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectInputImpl*->crit"); + + list_init( &This->devices_list ); } return res; } @@ -254,15 +260,19 @@ static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUT7A iface)
static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface) { - IDirectInputImpl *This = (IDirectInputImpl *)iface; - ULONG ref; - ref = InterlockedDecrement(&(This->ref)); - if (ref == 0) - { - HeapFree(GetProcessHeap(), 0, This); - release_hook_thread(); - } - return ref; + IDirectInputImpl *This = (IDirectInputImpl *)iface; + ULONG ref; + + ref = InterlockedDecrement( &This->ref ); + if (ref) return ref; + + release_hook_thread(); + + This->crit.DebugInfo->Spare[0] = 0; + DeleteCriticalSection( &This->crit ); + HeapFree( GetProcessHeap(), 0, This ); + + return 0; }
static HRESULT WINAPI IDirectInputAImpl_QueryInterface(LPDIRECTINPUT7A iface, REFIID riid, LPVOID *ppobj) { @@ -355,9 +365,15 @@ static HRESULT WINAPI IDirectInput7AImpl_CreateDeviceEx(LPDIRECTINPUT7A iface, R /* Loop on all the devices to see if anyone matches the given GUID */ for (i = 0; i < NB_DINPUT_DEVICES; i++) { HRESULT ret; + if (!dinput_devices[i]->create_deviceA) continue; if ((ret = dinput_devices[i]->create_deviceA(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK) + { + EnterCriticalSection( &This->crit ); + list_add_tail( &This->devices_list, &(*(IDirectInputDevice2AImpl**)pvOut)->entry ); + LeaveCriticalSection( &This->crit ); return DI_OK; + }
if (ret == DIERR_NOINTERFACE) ret_value = DIERR_NOINTERFACE; @@ -380,9 +396,15 @@ static HRESULT WINAPI IDirectInput7WImpl_CreateDeviceEx(LPDIRECTINPUT7W iface, R /* Loop on all the devices to see if anyone matches the given GUID */ for (i = 0; i < NB_DINPUT_DEVICES; i++) { HRESULT ret; + if (!dinput_devices[i]->create_deviceW) continue; if ((ret = dinput_devices[i]->create_deviceW(This, rguid, riid, (LPDIRECTINPUTDEVICEW*) pvOut)) == DI_OK) + { + EnterCriticalSection( &This->crit ); + list_add_tail( &This->devices_list, &(*(IDirectInputDevice2AImpl**)pvOut)->entry ); + LeaveCriticalSection( &This->crit ); return DI_OK; + }
if (ret == DIERR_NOINTERFACE) ret_value = DIERR_NOINTERFACE; diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h index d3f58a3..b29f61e 100644 --- a/dlls/dinput/dinput_private.h +++ b/dlls/dinput/dinput_private.h @@ -24,18 +24,20 @@ #include "windef.h" #include "winbase.h" #include "dinput.h" +#include "wine/list.h"
/* Implementation specification */ typedef struct IDirectInputImpl IDirectInputImpl; struct IDirectInputImpl { - const void *lpVtbl; - LONG ref; + const void *lpVtbl; + LONG ref;
- /* Used to have an unique sequence number for all the events */ - DWORD evsequence; + CRITICAL_SECTION crit;
- DWORD dwVersion; + DWORD evsequence; /* unique sequence number for events */ + DWORD dwVersion; /* direct input version number */ + struct list devices_list; /* list of all created dinput devices */ };
/* Function called by all devices that Wine supports */