From a478c4fe251daba7080f9e6dc934be5168eec1c8 Mon Sep 17 00:00:00 2001 From: Vitaliy Margolen Date: Sat, 5 Jul 2008 22:24:57 -0600 Subject: [PATCH] dinput: Freed effect should remove itself from the parent's list of effects. Add tests. --- dlls/dinput/effect_linuxinput.c | 13 ++++++----- dlls/dinput/joystick_linuxinput.c | 4 ++-- dlls/dinput/tests/joystick.c | 46 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/dlls/dinput/effect_linuxinput.c b/dlls/dinput/effect_linuxinput.c index ab72d2c4d8c..1fef4cd375a 100644 --- a/dlls/dinput/effect_linuxinput.c +++ b/dlls/dinput/effect_linuxinput.c @@ -53,11 +53,9 @@ struct LinuxInputEffectImpl LONG ref; GUID guid; - /* Effect data */ - struct ff_effect effect; - - /* Parent device */ - int* fd; + struct ff_effect effect; /* Effect data */ + int* fd; /* Parent device */ + struct list *entry; /* Entry into the parent's list of effects */ }; @@ -766,6 +764,8 @@ static ULONG WINAPI LinuxInputEffectImpl_Release(LPDIRECTINPUTEFFECT iface) { LinuxInputEffectImpl_Stop(iface); LinuxInputEffectImpl_Unload(iface); + list_remove(This->entry); + HeapFree(GetProcessHeap(), 0, LIST_ENTRY(This->entry, effect_list_item, entry)); HeapFree(GetProcessHeap(), 0, This); } return ref; @@ -778,6 +778,7 @@ static ULONG WINAPI LinuxInputEffectImpl_Release(LPDIRECTINPUTEFFECT iface) HRESULT linuxinput_create_effect( int* fd, REFGUID rguid, + struct list *parent_list_entry, LPDIRECTINPUTEFFECT* peff) { LinuxInputEffectImpl* newEffect = HeapAlloc(GetProcessHeap(), @@ -835,6 +836,8 @@ HRESULT linuxinput_create_effect( /* mark as non-uploaded */ newEffect->effect.id = -1; + newEffect->entry = parent_list_entry; + *peff = (LPDIRECTINPUTEFFECT)newEffect; TRACE("Creating linux input system effect (%p) with guid %s\n", diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c index d3185d306db..0ef90a16596 100644 --- a/dlls/dinput/joystick_linuxinput.c +++ b/dlls/dinput/joystick_linuxinput.c @@ -141,7 +141,7 @@ struct wine_input_absinfo { }; /* implemented in effect_linuxinput.c */ -HRESULT linuxinput_create_effect(int* fd, REFGUID rguid, LPDIRECTINPUTEFFECT* peff); +HRESULT linuxinput_create_effect(int* fd, REFGUID rguid, struct list *parent_list_entry, LPDIRECTINPUTEFFECT* peff); HRESULT linuxinput_get_info_A(int fd, REFGUID rguid, LPDIEFFECTINFOA info); HRESULT linuxinput_get_info_W(int fd, REFGUID rguid, LPDIEFFECTINFOW info); @@ -1053,7 +1053,7 @@ static HRESULT WINAPI JoystickAImpl_CreateEffect(LPDIRECTINPUTDEVICE8A iface, if (!(new_effect = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_effect)))) return DIERR_OUTOFMEMORY; - retval = linuxinput_create_effect(&This->joyfd, rguid, &new_effect->ref); + retval = linuxinput_create_effect(&This->joyfd, rguid, &new_effect->entry, &new_effect->ref); if (retval != DI_OK) { HeapFree(GetProcessHeap(), 0, new_effect); diff --git a/dlls/dinput/tests/joystick.c b/dlls/dinput/tests/joystick.c index 4727a5ad441..567dad076d1 100644 --- a/dlls/dinput/tests/joystick.c +++ b/dlls/dinput/tests/joystick.c @@ -18,6 +18,7 @@ #define DIRECTINPUT_VERSION 0x0700 +#define COBJMACROS #include #include @@ -85,6 +86,12 @@ typedef struct tagJoystickInfo DWORD dZone; } JoystickInfo; +static int get_refcount(IUnknown *object) +{ + IUnknown_AddRef( object ); + return IUnknown_Release( object ); +} + static BOOL CALLBACK EnumAxes( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext) @@ -331,6 +338,45 @@ static BOOL CALLBACK EnumJoysticks( ok(js.rgdwPOV[3] == -1, "Default for unassigned POV should be -1 not: %d\n", js.rgdwPOV[3]); } + if (caps.dwFlags & DIDC_FORCEFEEDBACK) + { + DWORD axes[2] = {DIJOFS_X, DIJOFS_Y}; + LONG direction[2] = {0, 0}; + DICONSTANTFORCE force = {0}; + DIEFFECT eff; + LPDIRECTINPUTEFFECT effect = NULL; + LONG cnt1, cnt2; + + trace("Testing force-feedback\n"); + memset(&eff, 0, sizeof(eff)); + eff.dwSize = sizeof(eff); + eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + eff.dwDuration = INFINITE; + eff.dwGain = DI_FFNOMINALMAX; + eff.dwTriggerButton = DIEB_NOTRIGGER; + eff.cAxes = sizeof(axes) / sizeof(axes[0]); + eff.rgdwAxes = axes; + eff.rglDirection = direction; + eff.cbTypeSpecificParams = sizeof(force); + eff.lpvTypeSpecificParams = &force; + + cnt1 = get_refcount((IUnknown*)pJoystick); + + hr = IDirectInputDevice2_CreateEffect((LPDIRECTINPUTDEVICE2)pJoystick, &GUID_ConstantForce, + &eff, &effect, NULL); + ok(hr == DI_OK, "IDirectInputDevice_CreateEffect() failed: %s\n", DXGetErrorString8(hr)); + cnt2 = get_refcount((IUnknown*)pJoystick); + ok(cnt1 == cnt2, "Ref count is wrong %d != %d\n", cnt1, cnt2); + + if (effect) + { + ref = IUnknown_Release(effect); + ok(ref == 0, "IDirectInputDevice_Release() reference count = %d\n", ref); + } + cnt1 = get_refcount((IUnknown*)pJoystick); + ok(cnt1 == cnt2, "Ref count is wrong %d != %d\n", cnt1, cnt2); + } + if (winetest_interactive) { trace("You have 30 seconds to test all axes, sliders, POVs and buttons\n"); count = 300; -- 2.11.4.GIT