dinput: Add a release callback for internal refcount handling.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-10-20 11:29:33 +02:00 committed by Alexandre Julliard
parent 89c59e77c1
commit 7ccf07ae8f
5 changed files with 48 additions and 48 deletions

View file

@ -1049,15 +1049,11 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetEventNotification(LPDIRECTINPUTDEVICE
return DI_OK; return DI_OK;
} }
void direct_input_device_destroy( IDirectInputDevice8W *iface )
ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface)
{ {
IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
ULONG ref = InterlockedDecrement(&(This->ref));
TRACE("(%p) ref %d\n", This, ref); TRACE( "iface %p.\n", iface );
if (ref) return ref;
IDirectInputDevice_Unacquire(iface); IDirectInputDevice_Unacquire(iface);
/* Reset the FF state, free all effects, etc */ /* Reset the FF state, free all effects, etc */
@ -1078,6 +1074,20 @@ ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface)
DeleteCriticalSection(&This->crit); DeleteCriticalSection(&This->crit);
free( This ); free( This );
}
ULONG WINAPI IDirectInputDevice2WImpl_Release( IDirectInputDevice8W *iface )
{
IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface );
ULONG ref = InterlockedDecrement( &impl->ref );
TRACE( "iface %p, ref %u.\n", iface, ref );
if (!ref)
{
if (impl->vtbl->release) impl->vtbl->release( iface );
else direct_input_device_destroy( iface );
}
return ref; return ref;
} }
@ -1132,11 +1142,11 @@ HRESULT WINAPI IDirectInputDevice2WImpl_QueryInterface(LPDIRECTINPUTDEVICE8W ifa
return E_NOINTERFACE; return E_NOINTERFACE;
} }
ULONG WINAPI IDirectInputDevice2WImpl_AddRef(LPDIRECTINPUTDEVICE8W iface) ULONG WINAPI IDirectInputDevice2WImpl_AddRef( IDirectInputDevice8W *iface )
{ {
IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface );
ULONG ref = InterlockedIncrement(&This->ref); ULONG ref = InterlockedIncrement( &impl->ref );
TRACE( "(%p) ref %d\n", This, ref ); TRACE( "iface %p, ref %u.\n", iface, ref );
return ref; return ref;
} }

View file

@ -57,6 +57,7 @@ typedef HRESULT dinput_device_read_state( IDirectInputDevice8W *iface );
struct dinput_device_vtbl struct dinput_device_vtbl
{ {
void (*release)( IDirectInputDevice8W *iface );
HRESULT (*poll)( IDirectInputDevice8W *iface ); HRESULT (*poll)( IDirectInputDevice8W *iface );
HRESULT (*read)( IDirectInputDevice8W *iface ); HRESULT (*read)( IDirectInputDevice8W *iface );
HRESULT (*acquire)( IDirectInputDevice8W *iface ); HRESULT (*acquire)( IDirectInputDevice8W *iface );
@ -116,6 +117,7 @@ struct IDirectInputDeviceImpl
extern HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl *vtbl, const struct dinput_device_vtbl *internal_vtbl, extern HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl *vtbl, const struct dinput_device_vtbl *internal_vtbl,
const GUID *guid, IDirectInputImpl *dinput, void **out ) DECLSPEC_HIDDEN; const GUID *guid, IDirectInputImpl *dinput, void **out ) DECLSPEC_HIDDEN;
extern HRESULT direct_input_device_init( IDirectInputDevice8W *iface ); extern HRESULT direct_input_device_init( IDirectInputDevice8W *iface );
extern void direct_input_device_destroy( IDirectInputDevice8W *iface );
extern const IDirectInputDevice8AVtbl dinput_device_a_vtbl DECLSPEC_HIDDEN; extern const IDirectInputDevice8AVtbl dinput_device_a_vtbl DECLSPEC_HIDDEN;
extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN; extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN;

View file

@ -158,7 +158,7 @@ struct pid_set_ramp_force
struct hid_joystick struct hid_joystick
{ {
IDirectInputDeviceImpl base; IDirectInputDeviceImpl base;
LONG ref; LONG internal_ref;
HANDLE device; HANDLE device;
OVERLAPPED read_ovl; OVERLAPPED read_ovl;
@ -608,45 +608,30 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter,
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
static ULONG hid_joystick_private_incref( struct hid_joystick *impl ) static void hid_joystick_internal_addref( IDirectInputDevice8W *iface )
{ {
return IDirectInputDevice2WImpl_AddRef( &impl->base.IDirectInputDevice8W_iface ); struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
ULONG ref = InterlockedIncrement( &impl->internal_ref );
TRACE( "iface %p, internal ref %u.\n", iface, ref );
} }
static ULONG hid_joystick_private_decref( struct hid_joystick *impl ) static void hid_joystick_internal_release( IDirectInputDevice8W *iface )
{ {
struct hid_joystick tmp = *impl; struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
ULONG ref; ULONG ref = InterlockedDecrement( &impl->internal_ref );
TRACE( "iface %p, internal ref %u.\n", iface, ref );
if (!(ref = IDirectInputDevice2WImpl_Release( &impl->base.IDirectInputDevice8W_iface ))) if (!ref)
{ {
free( tmp.usages_buf ); free( impl->usages_buf );
free( tmp.output_report_buf ); free( impl->output_report_buf );
free( tmp.input_report_buf ); free( impl->input_report_buf );
free( tmp.input_extra_caps ); free( impl->input_extra_caps );
HidD_FreePreparsedData( tmp.preparsed ); HidD_FreePreparsedData( impl->preparsed );
CloseHandle( tmp.base.read_event ); CloseHandle( impl->base.read_event );
CloseHandle( tmp.device ); CloseHandle( impl->device );
direct_input_device_destroy( iface );
} }
return ref;
}
static ULONG WINAPI hid_joystick_AddRef( IDirectInputDevice8W *iface )
{
struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
ULONG ref = InterlockedIncrement( &impl->ref );
TRACE( "iface %p, ref %u.\n", iface, ref );
return ref;
}
static ULONG WINAPI hid_joystick_Release( IDirectInputDevice8W *iface )
{
struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
ULONG ref = InterlockedDecrement( &impl->ref );
TRACE( "iface %p, ref %u.\n", iface, ref );
if (!ref) hid_joystick_private_decref( impl );
return ref;
} }
static HRESULT hid_joystick_internal_get_property( IDirectInputDevice8W *iface, DWORD property, DIPROPHEADER *header, static HRESULT hid_joystick_internal_get_property( IDirectInputDevice8W *iface, DWORD property, DIPROPHEADER *header,
@ -1150,8 +1135,8 @@ static const IDirectInputDevice8WVtbl hid_joystick_vtbl =
{ {
/*** IUnknown methods ***/ /*** IUnknown methods ***/
IDirectInputDevice2WImpl_QueryInterface, IDirectInputDevice2WImpl_QueryInterface,
hid_joystick_AddRef, IDirectInputDevice2WImpl_AddRef,
hid_joystick_Release, IDirectInputDevice2WImpl_Release,
/*** IDirectInputDevice methods ***/ /*** IDirectInputDevice methods ***/
IDirectInputDevice2WImpl_GetCapabilities, IDirectInputDevice2WImpl_GetCapabilities,
IDirectInputDevice2WImpl_EnumObjects, IDirectInputDevice2WImpl_EnumObjects,
@ -1404,6 +1389,7 @@ static HRESULT hid_joystick_internal_enum_objects( IDirectInputDevice8W *iface,
static const struct dinput_device_vtbl hid_joystick_internal_vtbl = static const struct dinput_device_vtbl hid_joystick_internal_vtbl =
{ {
hid_joystick_internal_release,
NULL, NULL,
hid_joystick_internal_read, hid_joystick_internal_read,
hid_joystick_internal_acquire, hid_joystick_internal_acquire,
@ -1979,7 +1965,7 @@ static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID
&attrs, &impl->caps, dinput->dwVersion ); &attrs, &impl->caps, dinput->dwVersion );
if (hr != DI_OK) goto failed; if (hr != DI_OK) goto failed;
impl->ref = 1; impl->internal_ref = 1;
impl->base.instance = instance; impl->base.instance = instance;
impl->base.caps.dwDevType = instance.dwDevType; impl->base.caps.dwDevType = instance.dwDevType;
impl->attrs = attrs; impl->attrs = attrs;
@ -2097,7 +2083,7 @@ static ULONG WINAPI hid_joystick_effect_Release( IDirectInputEffect *iface )
EnterCriticalSection( &impl->joystick->base.crit ); EnterCriticalSection( &impl->joystick->base.crit );
list_remove( &impl->entry ); list_remove( &impl->entry );
LeaveCriticalSection( &impl->joystick->base.crit ); LeaveCriticalSection( &impl->joystick->base.crit );
hid_joystick_private_decref( impl->joystick ); hid_joystick_internal_release( &impl->joystick->base.IDirectInputDevice8W_iface );
free( impl->type_specific_buf[1] ); free( impl->type_specific_buf[1] );
free( impl->type_specific_buf[0] ); free( impl->type_specific_buf[0] );
free( impl->effect_update_buf ); free( impl->effect_update_buf );
@ -2934,7 +2920,7 @@ static HRESULT hid_joystick_effect_create( struct hid_joystick *joystick, IDirec
impl->IDirectInputEffect_iface.lpVtbl = &hid_joystick_effect_vtbl; impl->IDirectInputEffect_iface.lpVtbl = &hid_joystick_effect_vtbl;
impl->ref = 1; impl->ref = 1;
impl->joystick = joystick; impl->joystick = joystick;
hid_joystick_private_incref( joystick ); hid_joystick_internal_addref( &joystick->base.IDirectInputDevice8W_iface );
EnterCriticalSection( &joystick->base.crit ); EnterCriticalSection( &joystick->base.crit );
list_add_tail( &joystick->effect_list, &impl->entry ); list_add_tail( &joystick->effect_list, &impl->entry );

View file

@ -330,6 +330,7 @@ static HRESULT keyboard_internal_set_property( IDirectInputDevice8W *iface, DWOR
static const struct dinput_device_vtbl keyboard_internal_vtbl = static const struct dinput_device_vtbl keyboard_internal_vtbl =
{ {
NULL,
keyboard_internal_poll, keyboard_internal_poll,
NULL, NULL,
keyboard_internal_acquire, keyboard_internal_acquire,

View file

@ -643,6 +643,7 @@ static HRESULT mouse_internal_set_property( IDirectInputDevice8W *iface, DWORD p
static const struct dinput_device_vtbl mouse_internal_vtbl = static const struct dinput_device_vtbl mouse_internal_vtbl =
{ {
NULL,
mouse_internal_poll, mouse_internal_poll,
NULL, NULL,
mouse_internal_acquire, mouse_internal_acquire,