Commit 15c12fd7 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dinput: Use an internal refcount on all dinput devices.

parent e82e74bf
......@@ -693,25 +693,35 @@ static HRESULT WINAPI dinput_device_SetEventNotification( IDirectInputDevice8W *
return DI_OK;
}
void dinput_device_destroy( IDirectInputDevice8W *iface )
void dinput_device_internal_addref( struct dinput_device *impl )
{
struct dinput_device *This = impl_from_IDirectInputDevice8W( iface );
ULONG ref = InterlockedIncrement( &impl->internal_ref );
TRACE( "impl %p, internal ref %lu.\n", impl, ref );
}
TRACE( "iface %p.\n", iface );
void dinput_device_internal_release( struct dinput_device *impl )
{
ULONG ref = InterlockedDecrement( &impl->internal_ref );
TRACE( "impl %p, internal ref %lu.\n", impl, ref );
free( This->object_properties );
free( This->data_queue );
if (!ref)
{
if (impl->vtbl->destroy) impl->vtbl->destroy( &impl->IDirectInputDevice8W_iface );
free( This->device_format.rgodf );
dinput_device_release_user_format( This );
free( impl->object_properties );
free( impl->data_queue );
free( This->action_map );
free( impl->device_format.rgodf );
dinput_device_release_user_format( impl );
IDirectInput_Release(&This->dinput->IDirectInput7A_iface);
This->crit.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->crit);
free( impl->action_map );
free( This );
IDirectInput_Release( &impl->dinput->IDirectInput7A_iface );
impl->crit.DebugInfo->Spare[0] = 0;
DeleteCriticalSection( &impl->crit );
free( impl );
}
}
static ULONG WINAPI dinput_device_Release( IDirectInputDevice8W *iface )
......@@ -724,8 +734,7 @@ static ULONG WINAPI dinput_device_Release( IDirectInputDevice8W *iface )
if (!ref)
{
IDirectInputDevice_Unacquire( iface );
if (impl->vtbl->release) impl->vtbl->release( iface );
else dinput_device_destroy( iface );
dinput_device_internal_release( impl );
}
return ref;
......@@ -2107,6 +2116,7 @@ void dinput_device_init( struct dinput_device *device, const struct dinput_devic
{
device->IDirectInputDevice8A_iface.lpVtbl = &dinput_device_a_vtbl;
device->IDirectInputDevice8W_iface.lpVtbl = &dinput_device_w_vtbl;
device->internal_ref = 1;
device->ref = 1;
device->guid = *guid;
device->instance.dwSize = sizeof(DIDEVICEINSTANCEW);
......
......@@ -36,7 +36,7 @@ typedef struct
struct dinput_device_vtbl
{
void (*release)( IDirectInputDevice8W *iface );
void (*destroy)( IDirectInputDevice8W *iface );
HRESULT (*poll)( IDirectInputDevice8W *iface );
HRESULT (*read)( IDirectInputDevice8W *iface );
HRESULT (*acquire)( IDirectInputDevice8W *iface );
......@@ -81,7 +81,9 @@ struct dinput_device
{
IDirectInputDevice8W IDirectInputDevice8W_iface;
IDirectInputDevice8A IDirectInputDevice8A_iface;
LONG internal_ref;
LONG ref;
GUID guid;
CRITICAL_SECTION crit;
struct dinput *dinput;
......@@ -125,8 +127,10 @@ struct dinput_device
extern void dinput_device_init( struct dinput_device *device, const struct dinput_device_vtbl *vtbl,
const GUID *guid, struct dinput *dinput );
extern void dinput_device_internal_addref( struct dinput_device *device );
extern void dinput_device_internal_release( struct dinput_device *device );
extern HRESULT dinput_device_init_device_format( IDirectInputDevice8W *iface );
extern void dinput_device_destroy( IDirectInputDevice8W *iface );
extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN;
extern DWORD get_config_key( HKEY, HKEY, const WCHAR *, WCHAR *, DWORD ) DECLSPEC_HIDDEN;
......
......@@ -172,7 +172,6 @@ struct pid_effect_state
struct hid_joystick
{
struct dinput_device base;
LONG internal_ref;
HANDLE device;
OVERLAPPED read_ovl;
......@@ -775,21 +774,11 @@ static void set_report_value( struct hid_joystick *impl, char *report_buf,
caps->usage_page, caps->usage_min, status );
}
static void hid_joystick_addref( IDirectInputDevice8W *iface )
static void hid_joystick_destroy( IDirectInputDevice8W *iface )
{
struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
ULONG ref = InterlockedIncrement( &impl->internal_ref );
TRACE( "iface %p, internal ref %lu.\n", iface, ref );
}
static void hid_joystick_release( IDirectInputDevice8W *iface )
{
struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
ULONG ref = InterlockedDecrement( &impl->internal_ref );
TRACE( "iface %p, internal ref %lu.\n", iface, ref );
TRACE( "iface %p.\n", iface );
if (!ref)
{
free( impl->usages_buf );
free( impl->feature_report_buf );
free( impl->output_report_buf );
......@@ -797,8 +786,6 @@ static void hid_joystick_release( IDirectInputDevice8W *iface )
HidD_FreePreparsedData( impl->preparsed );
CloseHandle( impl->base.read_event );
CloseHandle( impl->device );
dinput_device_destroy( iface );
}
}
static HRESULT hid_joystick_get_property( IDirectInputDevice8W *iface, DWORD property,
......@@ -1367,7 +1354,7 @@ static HRESULT hid_joystick_enum_objects( IDirectInputDevice8W *iface, const DIP
static const struct dinput_device_vtbl hid_joystick_vtbl =
{
hid_joystick_release,
hid_joystick_destroy,
NULL,
hid_joystick_read,
hid_joystick_acquire,
......@@ -2036,7 +2023,6 @@ HRESULT hid_joystick_create_device( struct dinput *dinput, const GUID *guid, IDi
impl->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": hid_joystick.base.crit");
impl->base.dwCoopLevel = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND;
impl->base.read_event = CreateEventW( NULL, TRUE, FALSE, NULL );
impl->internal_ref = 1;
if (memcmp( device_path_guid.Data4, guid->Data4, sizeof(device_path_guid.Data4) ))
hr = hid_joystick_device_open( -1, guid, &impl->base.instance, impl->device_path, &impl->device, &impl->preparsed,
......@@ -2163,7 +2149,7 @@ static ULONG WINAPI hid_joystick_effect_Release( IDirectInputEffect *iface )
EnterCriticalSection( &impl->joystick->base.crit );
list_remove( &impl->entry );
LeaveCriticalSection( &impl->joystick->base.crit );
hid_joystick_release( &impl->joystick->base.IDirectInputDevice8W_iface );
dinput_device_internal_release( &impl->joystick->base );
free( impl->set_envelope_buf );
free( impl->type_specific_buf );
free( impl->effect_update_buf );
......@@ -3155,7 +3141,7 @@ static HRESULT hid_joystick_create_effect( IDirectInputDevice8W *iface, IDirectI
impl->IDirectInputEffect_iface.lpVtbl = &hid_joystick_effect_vtbl;
impl->ref = 1;
impl->joystick = joystick;
hid_joystick_addref( &joystick->base.IDirectInputDevice8W_iface );
dinput_device_internal_addref( &joystick->base );
EnterCriticalSection( &joystick->base.crit );
list_add_tail( &joystick->effect_list, &impl->entry );
......
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