From: Rémi Bernon rbernon@codeweavers.com
--- MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS index 721341266a9..276471287da 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -191,11 +191,12 @@ F: dlls/jscript/ Joystick input M: Rémi Bernon rbernon@codeweavers.com F: dlls/dinput*/ +F: dlls/joy.cpl/ F: dlls/windows.gaming.input/ F: dlls/winebus.sys/ F: dlls/winexinput.sys/ -F: dlls/xinput*/ F: dlls/winmm/joystick.c +F: dlls/xinput*/
Media format conversion P: Andrew Eikum coldpie@fastmail.com
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/joy.rc | 2 +- dlls/joy.cpl/main.c | 78 +++++++++++++++++++++++++++++- dlls/joy.cpl/{joy.h => resource.h} | 76 +---------------------------- 3 files changed, 79 insertions(+), 77 deletions(-) rename dlls/joy.cpl/{joy.h => resource.h} (52%)
diff --git a/dlls/joy.cpl/joy.rc b/dlls/joy.cpl/joy.rc index 6c4bb0053ae..8086ecec6e1 100644 --- a/dlls/joy.cpl/joy.rc +++ b/dlls/joy.cpl/joy.rc @@ -19,7 +19,7 @@ * */
-#include "joy.h" +#include "resource.h"
#pragma makedep po
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index c1f41fb0e56..e3ed1f8f155 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -28,15 +28,89 @@ #include <winbase.h> #include <winuser.h> #include <commctrl.h> +#include <dinput.h> #include <cpl.h> #include "ole2.h"
#include "wine/debug.h" -#include "joy.h" + +#include "resource.h"
WINE_DEFAULT_DEBUG_CHANNEL(joycpl);
-DECLSPEC_HIDDEN HMODULE hcpl; +#define TEST_MAX_BUTTONS 32 +#define TEST_MAX_AXES 4 +#define TEST_POLL_TIME 100 + +#define TEST_BUTTON_COL_MAX 8 +#define TEST_BUTTON_X 8 +#define TEST_BUTTON_Y 122 +#define TEST_NEXT_BUTTON_X 30 +#define TEST_NEXT_BUTTON_Y 25 +#define TEST_BUTTON_SIZE_X 20 +#define TEST_BUTTON_SIZE_Y 18 + +#define TEST_AXIS_X 43 +#define TEST_AXIS_Y 60 +#define TEST_NEXT_AXIS_X 77 +#define TEST_AXIS_SIZE_X 3 +#define TEST_AXIS_SIZE_Y 3 +#define TEST_AXIS_MIN -25 +#define TEST_AXIS_MAX 25 + +#define FF_AXIS_X 248 +#define FF_AXIS_Y 60 +#define FF_AXIS_SIZE_X 3 +#define FF_AXIS_SIZE_Y 3 + +#define FF_PLAY_TIME 2*DI_SECONDS +#define FF_PERIOD_TIME FF_PLAY_TIME/4 + +#define NUM_PROPERTY_PAGES 3 + +struct Effect +{ + IDirectInputEffect *effect; + DIEFFECT params; + DIEFFECTINFOW info; +}; + +struct Joystick +{ + IDirectInputDevice8W *device; + DIDEVICEINSTANCEW instance; + int num_buttons; + int num_axes; + BOOL forcefeedback; + BOOL is_xinput; + BOOL has_override; + int num_effects; + int cur_effect; + int chosen_effect; + struct Effect *effects; +}; + +struct Graphics +{ + HWND hwnd; + HWND buttons[TEST_MAX_BUTTONS]; + HWND axes[TEST_MAX_AXES]; + HWND ff_axis; +}; + +struct JoystickData +{ + IDirectInput8W *di; + struct Joystick *joysticks; + int num_joysticks; + int num_ff; + int cur_joystick; + int chosen_joystick; + struct Graphics graphics; + BOOL stop; +}; + +static HMODULE hcpl;
/********************************************************************* * DllMain diff --git a/dlls/joy.cpl/joy.h b/dlls/joy.cpl/resource.h similarity index 52% rename from dlls/joy.cpl/joy.h rename to dlls/joy.cpl/resource.h index 64df21963b9..671e9ad8c77 100644 --- a/dlls/joy.cpl/joy.h +++ b/dlls/joy.cpl/resource.h @@ -22,55 +22,10 @@ #ifndef __WINE_JOYSTICKCPL__ #define __WINE_JOYSTICKCPL__
-#include <winuser.h> #include <windef.h> +#include <winbase.h> +#include <winuser.h> #include <commctrl.h> -#include <dinput.h> - -extern HMODULE hcpl; - -struct Effect { - IDirectInputEffect *effect; - DIEFFECT params; - DIEFFECTINFOW info; -}; - -struct Joystick { - IDirectInputDevice8W *device; - DIDEVICEINSTANCEW instance; - int num_buttons; - int num_axes; - BOOL forcefeedback; - BOOL is_xinput; - BOOL has_override; - int num_effects; - int cur_effect; - int chosen_effect; - struct Effect *effects; -}; - -#define TEST_MAX_BUTTONS 32 -#define TEST_MAX_AXES 4 - -struct Graphics { - HWND hwnd; - HWND buttons[TEST_MAX_BUTTONS]; - HWND axes[TEST_MAX_AXES]; - HWND ff_axis; -}; - -struct JoystickData { - IDirectInput8W *di; - struct Joystick *joysticks; - int num_joysticks; - int num_ff; - int cur_joystick; - int chosen_joystick; - struct Graphics graphics; - BOOL stop; -}; - -#define NUM_PROPERTY_PAGES 3
/* strings */ #define IDS_CPL_NAME 1 @@ -102,31 +57,4 @@ struct JoystickData {
#define ICO_MAIN 100
-/* constants */ -#define TEST_POLL_TIME 100 - -#define TEST_BUTTON_COL_MAX 8 -#define TEST_BUTTON_X 8 -#define TEST_BUTTON_Y 122 -#define TEST_NEXT_BUTTON_X 30 -#define TEST_NEXT_BUTTON_Y 25 -#define TEST_BUTTON_SIZE_X 20 -#define TEST_BUTTON_SIZE_Y 18 - -#define TEST_AXIS_X 43 -#define TEST_AXIS_Y 60 -#define TEST_NEXT_AXIS_X 77 -#define TEST_AXIS_SIZE_X 3 -#define TEST_AXIS_SIZE_Y 3 -#define TEST_AXIS_MIN -25 -#define TEST_AXIS_MAX 25 - -#define FF_AXIS_X 248 -#define FF_AXIS_Y 60 -#define FF_AXIS_SIZE_X 3 -#define FF_AXIS_SIZE_Y 3 - -#define FF_PLAY_TIME 2*DI_SECONDS -#define FF_PERIOD_TIME FF_PLAY_TIME/4 - #endif
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 221 +++++++++++++++++++++----------------------- 1 file changed, 104 insertions(+), 117 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index e3ed1f8f155..81f32399d6a 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -128,13 +128,108 @@ BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason, LPVOID reserved) return TRUE; }
-/*********************************************************************** - * enum_callback [internal] - * Enumerates, creates and sets the common data format for all the joystick devices. - * First time it checks if space for the joysticks was already reserved - * and if not, just counts how many there are. - */ -static BOOL CALLBACK ff_effects_callback(const DIEFFECTINFOW *pdei, void *pvRef); +static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) +{ + HRESULT hr; + DIEFFECT dieffect; + DWORD axes[2] = {DIJOFS_X, DIJOFS_Y}; + LONG direction[2] = {0, 0}; + int num_axes = 2; + struct Joystick *joystick = context; + DIRAMPFORCE rforce; + DICONSTANTFORCE cforce; + DIPERIODIC pforce; + DICONDITION cdforce; + + if (joystick->effects == NULL) + { + joystick->num_effects += 1; + return DIENUM_CONTINUE; + } + + hr = IDirectInputDevice8_Acquire( joystick->device ); + + if (FAILED(hr)) return DIENUM_CONTINUE; + + ZeroMemory( &dieffect, sizeof(dieffect) ); + + dieffect.dwSize = sizeof(dieffect); + dieffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + dieffect.dwDuration = FF_PLAY_TIME; + dieffect.dwGain = DI_FFNOMINALMAX; + + dieffect.rgdwAxes = axes; + dieffect.rglDirection = direction; + + if (IsEqualGUID( &info->guid, &GUID_RampForce )) + { + rforce.lStart = 0; + rforce.lEnd = DI_FFNOMINALMAX; + + dieffect.cbTypeSpecificParams = sizeof(rforce); + dieffect.lpvTypeSpecificParams = &rforce; + dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; + } + else if (IsEqualGUID( &info->guid, &GUID_ConstantForce )) + { + cforce.lMagnitude = DI_FFNOMINALMAX; + + dieffect.cbTypeSpecificParams = sizeof(cforce); + dieffect.lpvTypeSpecificParams = &cforce; + dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; + } + else if (IsEqualGUID( &info->guid, &GUID_Sine ) || + IsEqualGUID( &info->guid, &GUID_Square ) || + IsEqualGUID( &info->guid, &GUID_Triangle ) || + IsEqualGUID( &info->guid, &GUID_SawtoothUp ) || + IsEqualGUID( &info->guid, &GUID_SawtoothDown )) + { + pforce.dwMagnitude = DI_FFNOMINALMAX; + pforce.lOffset = 0; + pforce.dwPhase = 0; + pforce.dwPeriod = FF_PERIOD_TIME; + + dieffect.cbTypeSpecificParams = sizeof(pforce); + dieffect.lpvTypeSpecificParams = &pforce; + dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; + } + else if (IsEqualGUID( &info->guid, &GUID_Spring ) || + IsEqualGUID( &info->guid, &GUID_Damper ) || + IsEqualGUID( &info->guid, &GUID_Inertia ) || + IsEqualGUID( &info->guid, &GUID_Friction )) + { + cdforce.dwPositiveSaturation = 10000; + cdforce.dwNegativeSaturation = 10000; + cdforce.lPositiveCoefficient = 10000; + cdforce.lNegativeCoefficient = 10000; + cdforce.lDeadBand = 0; + cdforce.lOffset = 0; + + dieffect.cbTypeSpecificParams = sizeof(cdforce); + dieffect.lpvTypeSpecificParams = &cdforce; + dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; + } + + do + { + dieffect.cAxes = num_axes--; + hr = IDirectInputDevice2_CreateEffect( joystick->device, &info->guid, &dieffect, + &joystick->effects[joystick->cur_effect].effect, NULL ); + } while (FAILED(hr) && num_axes); + + if (FAILED(hr)) + { + FIXME( "Failed to create effect with type %s, hr %#lx\n", debugstr_guid( &info->guid ), hr ); + return DIENUM_CONTINUE; + } + + joystick->effects[joystick->cur_effect].params = dieffect; + joystick->effects[joystick->cur_effect].info = *info; + joystick->cur_effect += 1; + + return DIENUM_CONTINUE; +} + static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *context) { DIPROPGUIDANDPATH prop_guid_path = @@ -193,11 +288,11 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont /* Count device effects and then store them */ joystick->num_effects = 0; joystick->effects = NULL; - IDirectInputDevice8_EnumEffects(joystick->device, ff_effects_callback, (void *)joystick, 0); + IDirectInputDevice8_EnumEffects( joystick->device, enum_effects, (void *)joystick, 0 ); joystick->effects = malloc(sizeof(struct Effect) * joystick->num_effects);
joystick->cur_effect = 0; - IDirectInputDevice8_EnumEffects(joystick->device, ff_effects_callback, (void*)joystick, 0); + IDirectInputDevice8_EnumEffects( joystick->device, enum_effects, (void *)joystick, 0 ); joystick->num_effects = joystick->cur_effect;
return DIENUM_CONTINUE; @@ -852,114 +947,6 @@ static DWORD WINAPI ff_input_thread(void *param) return 0; }
-/*********************************************************************** - * ff_effects_callback [internal] - * Enumerates, creates, sets the some parameters and stores all ff effects - * supported by the joystick. Works like enum_callback, counting the effects - * first and then storing them. - */ -static BOOL CALLBACK ff_effects_callback(const DIEFFECTINFOW *pdei, void *pvRef) -{ - HRESULT hr; - DIEFFECT dieffect; - DWORD axes[2] = {DIJOFS_X, DIJOFS_Y}; - LONG direction[2] = {0, 0}; - int num_axes = 2; - struct Joystick *joystick = pvRef; - DIRAMPFORCE rforce; - DICONSTANTFORCE cforce; - DIPERIODIC pforce; - DICONDITION cdforce; - - if (joystick->effects == NULL) - { - joystick->num_effects += 1; - return DIENUM_CONTINUE; - } - - hr = IDirectInputDevice8_Acquire(joystick->device); - - if (FAILED(hr)) return DIENUM_CONTINUE; - - ZeroMemory(&dieffect, sizeof(dieffect)); - - dieffect.dwSize = sizeof(dieffect); - dieffect.dwFlags = DIEFF_CARTESIAN|DIEFF_OBJECTOFFSETS; - dieffect.dwDuration = FF_PLAY_TIME; - dieffect.dwGain = DI_FFNOMINALMAX; - - dieffect.rgdwAxes = axes; - dieffect.rglDirection = direction; - - if (IsEqualGUID(&pdei->guid, &GUID_RampForce)) - { - rforce.lStart = 0; - rforce.lEnd = DI_FFNOMINALMAX; - - dieffect.cbTypeSpecificParams = sizeof(rforce); - dieffect.lpvTypeSpecificParams = &rforce; - dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; - } - else if (IsEqualGUID(&pdei->guid, &GUID_ConstantForce)) - { - cforce.lMagnitude = DI_FFNOMINALMAX; - - dieffect.cbTypeSpecificParams = sizeof(cforce); - dieffect.lpvTypeSpecificParams = &cforce; - dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; - } - else if (IsEqualGUID(&pdei->guid, &GUID_Sine) || - IsEqualGUID(&pdei->guid, &GUID_Square) || - IsEqualGUID(&pdei->guid, &GUID_Triangle) || - IsEqualGUID(&pdei->guid, &GUID_SawtoothUp) || - IsEqualGUID(&pdei->guid, &GUID_SawtoothDown)) - { - pforce.dwMagnitude = DI_FFNOMINALMAX; - pforce.lOffset = 0; - pforce.dwPhase = 0; - pforce.dwPeriod = FF_PERIOD_TIME; - - dieffect.cbTypeSpecificParams = sizeof(pforce); - dieffect.lpvTypeSpecificParams = &pforce; - dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; - } - else if (IsEqualGUID(&pdei->guid, &GUID_Spring) || - IsEqualGUID(&pdei->guid, &GUID_Damper) || - IsEqualGUID(&pdei->guid, &GUID_Inertia) || - IsEqualGUID(&pdei->guid, &GUID_Friction)) - { - cdforce.dwPositiveSaturation = 10000; - cdforce.dwNegativeSaturation = 10000; - cdforce.lPositiveCoefficient = 10000; - cdforce.lNegativeCoefficient = 10000; - cdforce.lDeadBand = 0; - cdforce.lOffset = 0; - - dieffect.cbTypeSpecificParams = sizeof(cdforce); - dieffect.lpvTypeSpecificParams = &cdforce; - dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; - } - - do - { - dieffect.cAxes = num_axes--; - hr = IDirectInputDevice2_CreateEffect( - joystick->device, &pdei->guid, &dieffect, &joystick->effects[joystick->cur_effect].effect, NULL); - } - while (FAILED(hr) && num_axes); - - if (FAILED(hr)) - { - FIXME("Failed to create effect with type %s, hr %#lx\n", debugstr_guid(&pdei->guid), hr); - return DIENUM_CONTINUE; - } - - joystick->effects[joystick->cur_effect].params = dieffect; - joystick->effects[joystick->cur_effect].info = *pdei; - joystick->cur_effect += 1; - - return DIENUM_CONTINUE; -}
/********************************************************************* * ff_dlgproc [internal]
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 106 +++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 56 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index 81f32399d6a..40139b51572 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -130,16 +130,41 @@ BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason, LPVOID reserved)
static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) { - HRESULT hr; - DIEFFECT dieffect; - DWORD axes[2] = {DIJOFS_X, DIJOFS_Y}; - LONG direction[2] = {0, 0}; - int num_axes = 2; struct Joystick *joystick = context; - DIRAMPFORCE rforce; - DICONSTANTFORCE cforce; - DIPERIODIC pforce; - DICONDITION cdforce; + DWORD axes[2] = {DIJOFS_X, DIJOFS_Y}; + LONG direction[2] = {0}; + DIEFFECT params = + { + .dwSize = sizeof(DIEFFECT), + .dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS, + .dwDuration = FF_PLAY_TIME, + .dwGain = DI_FFNOMINALMAX, + .rglDirection = direction, + .rgdwAxes = axes, + .cAxes = 2, + }; + DICONSTANTFORCE constant = + { + .lMagnitude = DI_FFNOMINALMAX, + }; + DIPERIODIC periodic = + { + .dwMagnitude = DI_FFNOMINALMAX, + .dwPeriod = FF_PERIOD_TIME, + }; + DICONDITION condition = + { + .dwPositiveSaturation = 10000, + .dwNegativeSaturation = 10000, + .lPositiveCoefficient = 10000, + .lNegativeCoefficient = 10000, + }; + DIRAMPFORCE ramp = + { + .lEnd = DI_FFNOMINALMAX, + }; + IDirectInputEffect *effect; + HRESULT hr;
if (joystick->effects == NULL) { @@ -148,35 +173,19 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) }
hr = IDirectInputDevice8_Acquire( joystick->device ); - if (FAILED(hr)) return DIENUM_CONTINUE;
- ZeroMemory( &dieffect, sizeof(dieffect) ); - - dieffect.dwSize = sizeof(dieffect); - dieffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; - dieffect.dwDuration = FF_PLAY_TIME; - dieffect.dwGain = DI_FFNOMINALMAX; - - dieffect.rgdwAxes = axes; - dieffect.rglDirection = direction; - if (IsEqualGUID( &info->guid, &GUID_RampForce )) { - rforce.lStart = 0; - rforce.lEnd = DI_FFNOMINALMAX; - - dieffect.cbTypeSpecificParams = sizeof(rforce); - dieffect.lpvTypeSpecificParams = &rforce; - dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; + params.cbTypeSpecificParams = sizeof(ramp); + params.lpvTypeSpecificParams = &ramp; + params.dwFlags |= DIEP_TYPESPECIFICPARAMS; } else if (IsEqualGUID( &info->guid, &GUID_ConstantForce )) { - cforce.lMagnitude = DI_FFNOMINALMAX; - - dieffect.cbTypeSpecificParams = sizeof(cforce); - dieffect.lpvTypeSpecificParams = &cforce; - dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; + params.cbTypeSpecificParams = sizeof(constant); + params.lpvTypeSpecificParams = &constant; + params.dwFlags |= DIEP_TYPESPECIFICPARAMS; } else if (IsEqualGUID( &info->guid, &GUID_Sine ) || IsEqualGUID( &info->guid, &GUID_Square ) || @@ -184,38 +193,22 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) IsEqualGUID( &info->guid, &GUID_SawtoothUp ) || IsEqualGUID( &info->guid, &GUID_SawtoothDown )) { - pforce.dwMagnitude = DI_FFNOMINALMAX; - pforce.lOffset = 0; - pforce.dwPhase = 0; - pforce.dwPeriod = FF_PERIOD_TIME; - - dieffect.cbTypeSpecificParams = sizeof(pforce); - dieffect.lpvTypeSpecificParams = &pforce; - dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; + params.cbTypeSpecificParams = sizeof(periodic); + params.lpvTypeSpecificParams = &periodic; + params.dwFlags |= DIEP_TYPESPECIFICPARAMS; } else if (IsEqualGUID( &info->guid, &GUID_Spring ) || IsEqualGUID( &info->guid, &GUID_Damper ) || IsEqualGUID( &info->guid, &GUID_Inertia ) || IsEqualGUID( &info->guid, &GUID_Friction )) { - cdforce.dwPositiveSaturation = 10000; - cdforce.dwNegativeSaturation = 10000; - cdforce.lPositiveCoefficient = 10000; - cdforce.lNegativeCoefficient = 10000; - cdforce.lDeadBand = 0; - cdforce.lOffset = 0; - - dieffect.cbTypeSpecificParams = sizeof(cdforce); - dieffect.lpvTypeSpecificParams = &cdforce; - dieffect.dwFlags |= DIEP_TYPESPECIFICPARAMS; + params.cbTypeSpecificParams = sizeof(condition); + params.lpvTypeSpecificParams = &condition; + params.dwFlags |= DIEP_TYPESPECIFICPARAMS; }
- do - { - dieffect.cAxes = num_axes--; - hr = IDirectInputDevice2_CreateEffect( joystick->device, &info->guid, &dieffect, - &joystick->effects[joystick->cur_effect].effect, NULL ); - } while (FAILED(hr) && num_axes); + do hr = IDirectInputDevice2_CreateEffect( joystick->device, &info->guid, ¶ms, &effect, NULL ); + while (FAILED(hr) && --params.cAxes);
if (FAILED(hr)) { @@ -223,7 +216,8 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) return DIENUM_CONTINUE; }
- joystick->effects[joystick->cur_effect].params = dieffect; + joystick->effects[joystick->cur_effect].effect = effect; + joystick->effects[joystick->cur_effect].params = params; joystick->effects[joystick->cur_effect].info = *info; joystick->cur_effect += 1;
From: Rémi Bernon rbernon@codeweavers.com
The direction and axis arrays are also not pointing to valid memory anymore. --- dlls/joy.cpl/main.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index 40139b51572..53cfff1baf3 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -71,7 +71,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(joycpl); struct Effect { IDirectInputEffect *effect; - DIEFFECT params; DIEFFECTINFOW info; };
@@ -217,7 +216,6 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) }
joystick->effects[joystick->cur_effect].effect = effect; - joystick->effects[joystick->cur_effect].params = params; joystick->effects[joystick->cur_effect].info = *info; joystick->cur_effect += 1;
@@ -906,21 +904,29 @@ static DWORD WINAPI ff_input_thread(void *param) int i; struct Joystick *joy = &data->joysticks[data->chosen_joystick]; int chosen_effect = joy->chosen_effect; - DIEFFECT *dieffect; DWORD flags = DIEP_AXES | DIEP_DIRECTION | DIEP_NORESTART; + LONG direction[3] = {0}; + DWORD axes[3] = {0}; + DIEFFECT params = + { + .dwSize = sizeof(DIEFFECT), + .dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS, + .rglDirection = direction, + .rgdwAxes = axes, + .cAxes = 3, + }; RECT r;
Sleep(TEST_POLL_TIME);
/* Skip this if we have no effects */ - if (joy->num_effects == 0 || chosen_effect < 0) continue; + if (joy->num_effects == 0 || chosen_effect < 0 || !joy->effects[chosen_effect].effect) continue;
poll_input(joy, &state);
- /* Set ff parameters and draw the axis */ - dieffect = &joy->effects[chosen_effect].params; - dieffect->rgdwAxes[0] = state.lX; - dieffect->rgdwAxes[1] = state.lY; + IDirectInputEffect_GetParameters( joy->effects[chosen_effect].effect, ¶ms, flags ); + params.rgdwAxes[0] = state.lX; + params.rgdwAxes[1] = state.lY;
r.left = FF_AXIS_X + state.lX; r.top = FF_AXIS_Y + state.lY; @@ -932,7 +938,7 @@ static DWORD WINAPI ff_input_thread(void *param) for (i=0; i < TEST_MAX_BUTTONS; i++) if (state.rgbButtons[i]) { - IDirectInputEffect_SetParameters(joy->effects[chosen_effect].effect, dieffect, flags); + IDirectInputEffect_SetParameters( joy->effects[chosen_effect].effect, ¶ms, flags ); IDirectInputEffect_Start(joy->effects[chosen_effect].effect, 1, 0); break; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index 53cfff1baf3..b32e1f18152 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -71,7 +71,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(joycpl); struct Effect { IDirectInputEffect *effect; - DIEFFECTINFOW info; };
struct Joystick @@ -216,7 +215,6 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) }
joystick->effects[joystick->cur_effect].effect = effect; - joystick->effects[joystick->cur_effect].info = *info; joystick->cur_effect += 1;
return DIENUM_CONTINUE; @@ -866,9 +864,12 @@ static void initialize_effects_list(HWND hwnd, struct Joystick* joy)
for (i=0; i < joy->num_effects; i++) { - /* Effect names start with GUID_, so we'll skip this part */ - WCHAR *name = joy->effects[i].info.tszName + 5; - SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_ADDSTRING, 0, (LPARAM) name); + DIEFFECTINFOW info = {.dwSize = sizeof(DIEFFECTINFOW)}; + GUID guid; + + if (FAILED(IDirectInputEffect_GetEffectGuid( joy->effects[i].effect, &guid ))) continue; + if (FAILED(IDirectInputDevice8_GetEffectInfo( joy->device, &info, &guid ))) continue; + SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_ADDSTRING, 0, (LPARAM)(info.tszName + 5)); } }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 78 ++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 40 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index b32e1f18152..43ffec51461 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -33,6 +33,7 @@ #include "ole2.h"
#include "wine/debug.h" +#include "wine/list.h"
#include "resource.h"
@@ -68,8 +69,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(joycpl);
#define NUM_PROPERTY_PAGES 3
-struct Effect +struct effect { + struct list entry; IDirectInputEffect *effect; };
@@ -82,10 +84,9 @@ struct Joystick BOOL forcefeedback; BOOL is_xinput; BOOL has_override; - int num_effects; - int cur_effect; - int chosen_effect; - struct Effect *effects; + + struct list effects; + IDirectInputEffect *effect_selected; };
struct Graphics @@ -162,17 +163,14 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) .lEnd = DI_FFNOMINALMAX, }; IDirectInputEffect *effect; + struct effect *entry; HRESULT hr;
- if (joystick->effects == NULL) - { - joystick->num_effects += 1; - return DIENUM_CONTINUE; - } - hr = IDirectInputDevice8_Acquire( joystick->device ); if (FAILED(hr)) return DIENUM_CONTINUE;
+ if (!(entry = calloc( 1, sizeof(*entry) ))) return DIENUM_STOP; + if (IsEqualGUID( &info->guid, &GUID_RampForce )) { params.cbTypeSpecificParams = sizeof(ramp); @@ -211,11 +209,12 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) if (FAILED(hr)) { FIXME( "Failed to create effect with type %s, hr %#lx\n", debugstr_guid( &info->guid ), hr ); + free( entry ); return DIENUM_CONTINUE; }
- joystick->effects[joystick->cur_effect].effect = effect; - joystick->cur_effect += 1; + entry->effect = effect; + list_add_tail( &joystick->effects, &entry->entry );
return DIENUM_CONTINUE; } @@ -256,11 +255,13 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont joystick->num_buttons = caps.dwButtons; joystick->num_axes = caps.dwAxes; joystick->forcefeedback = caps.dwFlags & DIDC_FORCEFEEDBACK; - joystick->num_effects = 0;
IDirectInputDevice8_GetProperty(joystick->device, DIPROP_GUIDANDPATH, &prop_guid_path.diph); joystick->is_xinput = wcsstr(prop_guid_path.wszPath, L"&ig_") != NULL;
+ list_init( &joystick->effects ); + joystick->effect_selected = NULL; + if (joystick->forcefeedback) data->num_ff++;
/* Set axis range to ease the GUI visualization */ @@ -275,15 +276,7 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont
if (!joystick->forcefeedback) return DIENUM_CONTINUE;
- /* Count device effects and then store them */ - joystick->num_effects = 0; - joystick->effects = NULL; IDirectInputDevice8_EnumEffects( joystick->device, enum_effects, (void *)joystick, 0 ); - joystick->effects = malloc(sizeof(struct Effect) * joystick->num_effects); - - joystick->cur_effect = 0; - IDirectInputDevice8_EnumEffects( joystick->device, enum_effects, (void *)joystick, 0 ); - joystick->num_effects = joystick->cur_effect;
return DIENUM_CONTINUE; } @@ -307,18 +300,17 @@ static void initialize_joysticks(struct JoystickData *data) */ static void destroy_joysticks(struct JoystickData *data) { - int i, j; + int i;
for (i = 0; i < data->num_joysticks; i++) { + struct effect *effect, *next_effect;
- if (data->joysticks[i].forcefeedback && data->joysticks[i].num_effects > 0) + LIST_FOR_EACH_ENTRY_SAFE( effect, next_effect, &data->joysticks[i].effects, struct effect, entry ) { - for (j = 0; j < data->joysticks[i].num_effects; j++) - if (data->joysticks[i].effects[j].effect) - IDirectInputEffect_Release(data->joysticks[i].effects[j].effect); - - free(data->joysticks[i].effects); + list_remove( &effect->entry ); + IDirectInputEffect_Release( effect->effect ); + free( effect ); }
IDirectInputDevice8_Unacquire(data->joysticks[i].device); @@ -858,16 +850,16 @@ static void draw_ff_axis(HWND hwnd, struct JoystickData *data)
static void initialize_effects_list(HWND hwnd, struct Joystick* joy) { - int i; + struct effect *effect;
SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_RESETCONTENT, 0, 0);
- for (i=0; i < joy->num_effects; i++) + LIST_FOR_EACH_ENTRY( effect, &joy->effects, struct effect, entry ) { DIEFFECTINFOW info = {.dwSize = sizeof(DIEFFECTINFOW)}; GUID guid;
- if (FAILED(IDirectInputEffect_GetEffectGuid( joy->effects[i].effect, &guid ))) continue; + if (FAILED(IDirectInputEffect_GetEffectGuid( effect->effect, &guid ))) continue; if (FAILED(IDirectInputDevice8_GetEffectInfo( joy->device, &info, &guid ))) continue; SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_ADDSTRING, 0, (LPARAM)(info.tszName + 5)); } @@ -883,11 +875,18 @@ static void ff_handle_joychange(HWND hwnd, struct JoystickData *data)
static void ff_handle_effectchange(HWND hwnd, struct Joystick *joy) { - int sel = SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_GETCURSEL, 0, 0); + struct list *entry; + int sel;
+ sel = SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_GETCURSEL, 0, 0); if (sel < 0) return;
- joy->chosen_effect = sel; + entry = list_head( &joy->effects ); + while (sel-- && entry) entry = list_next( &joy->effects, entry ); + if (!entry) return; + + joy->effect_selected = LIST_ENTRY( entry, struct effect, entry )->effect; + IDirectInputDevice8_Unacquire(joy->device); IDirectInputDevice8_SetCooperativeLevel(joy->device, GetAncestor(hwnd, GA_ROOT), DISCL_BACKGROUND|DISCL_EXCLUSIVE); IDirectInputDevice8_Acquire(joy->device); @@ -904,8 +903,8 @@ static DWORD WINAPI ff_input_thread(void *param) { int i; struct Joystick *joy = &data->joysticks[data->chosen_joystick]; - int chosen_effect = joy->chosen_effect; DWORD flags = DIEP_AXES | DIEP_DIRECTION | DIEP_NORESTART; + IDirectInputEffect *effect; LONG direction[3] = {0}; DWORD axes[3] = {0}; DIEFFECT params = @@ -920,12 +919,11 @@ static DWORD WINAPI ff_input_thread(void *param)
Sleep(TEST_POLL_TIME);
- /* Skip this if we have no effects */ - if (joy->num_effects == 0 || chosen_effect < 0 || !joy->effects[chosen_effect].effect) continue; + if (!(effect = joy->effect_selected)) continue;
poll_input(joy, &state);
- IDirectInputEffect_GetParameters( joy->effects[chosen_effect].effect, ¶ms, flags ); + IDirectInputEffect_GetParameters( effect, ¶ms, flags ); params.rgdwAxes[0] = state.lX; params.rgdwAxes[1] = state.lY;
@@ -939,8 +937,8 @@ static DWORD WINAPI ff_input_thread(void *param) for (i=0; i < TEST_MAX_BUTTONS; i++) if (state.rgbButtons[i]) { - IDirectInputEffect_SetParameters( joy->effects[chosen_effect].effect, ¶ms, flags ); - IDirectInputEffect_Start(joy->effects[chosen_effect].effect, 1, 0); + IDirectInputEffect_SetParameters( effect, ¶ms, flags ); + IDirectInputEffect_Start( effect, 1, 0 ); break; } }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index 43ffec51461..1a4286a6b92 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -78,7 +78,6 @@ struct effect struct Joystick { IDirectInputDevice8W *device; - DIDEVICEINSTANCEW instance; int num_buttons; int num_axes; BOOL forcefeedback; @@ -247,8 +246,6 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont IDirectInput8_CreateDevice(data->di, &instance->guidInstance, &joystick->device, NULL); IDirectInputDevice8_SetDataFormat(joystick->device, &c_dfDIJoystick);
- joystick->instance = *instance; - caps.dwSize = sizeof(caps); IDirectInputDevice8_GetCapabilities(joystick->device, &caps);
@@ -400,8 +397,10 @@ static void refresh_joystick_list(HWND hwnd, struct JoystickData *data)
for (joy = data->joysticks, joy_end = joy + data->num_joysticks; joy != joy_end; ++joy) { - if (joy->is_xinput) SendDlgItemMessageW(hwnd, IDC_XINPUTLIST, LB_ADDSTRING, 0, (LPARAM) joy->instance.tszInstanceName); - else SendDlgItemMessageW(hwnd, IDC_JOYSTICKLIST, LB_ADDSTRING, 0, (LPARAM) joy->instance.tszInstanceName); + DIDEVICEINSTANCEW info = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; + if (FAILED(IDirectInputDevice8_GetDeviceInfo( joy->device, &info ))) continue; + if (joy->is_xinput) SendDlgItemMessageW( hwnd, IDC_XINPUTLIST, LB_ADDSTRING, 0, (LPARAM)info.tszInstanceName ); + else SendDlgItemMessageW( hwnd, IDC_JOYSTICKLIST, LB_ADDSTRING, 0, (LPARAM)info.tszInstanceName ); }
/* Search for disabled joysticks */ @@ -760,7 +759,11 @@ static void refresh_test_joystick_list(HWND hwnd, struct JoystickData *data) struct Joystick *joy, *joy_end; SendDlgItemMessageW(hwnd, IDC_TESTSELECTCOMBO, CB_RESETCONTENT, 0, 0); for (joy = data->joysticks, joy_end = joy + data->num_joysticks; joy != joy_end; ++joy) - SendDlgItemMessageW(hwnd, IDC_TESTSELECTCOMBO, CB_ADDSTRING, 0, (LPARAM)joy->instance.tszInstanceName); + { + DIDEVICEINSTANCEW info = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; + if (FAILED(IDirectInputDevice8_GetDeviceInfo( joy->device, &info ))) continue; + SendDlgItemMessageW( hwnd, IDC_TESTSELECTCOMBO, CB_ADDSTRING, 0, (LPARAM)info.tszInstanceName ); + } }
static INT_PTR CALLBACK test_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) @@ -956,7 +959,11 @@ static void refresh_ff_joystick_list(HWND hwnd, struct JoystickData *data) struct Joystick *joy, *joy_end; SendDlgItemMessageW(hwnd, IDC_FFSELECTCOMBO, CB_RESETCONTENT, 0, 0); for (joy = data->joysticks, joy_end = joy + data->num_joysticks; joy != joy_end; ++joy) - SendDlgItemMessageW(hwnd, IDC_FFSELECTCOMBO, CB_ADDSTRING, 0, (LPARAM)joy->instance.tszInstanceName); + { + DIDEVICEINSTANCEW info = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; + if (FAILED(IDirectInputDevice8_GetDeviceInfo( joy->device, &info ))) continue; + SendDlgItemMessageW( hwnd, IDC_FFSELECTCOMBO, CB_ADDSTRING, 0, (LPARAM)info.tszInstanceName ); + } }
static INT_PTR CALLBACK ff_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index 1a4286a6b92..d258dee7d01 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -78,8 +78,6 @@ struct effect struct Joystick { IDirectInputDevice8W *device; - int num_buttons; - int num_axes; BOOL forcefeedback; BOOL is_xinput; BOOL has_override; @@ -249,8 +247,6 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont caps.dwSize = sizeof(caps); IDirectInputDevice8_GetCapabilities(joystick->device, &caps);
- joystick->num_buttons = caps.dwButtons; - joystick->num_axes = caps.dwAxes; joystick->forcefeedback = caps.dwFlags & DIDC_FORCEFEEDBACK;
IDirectInputDevice8_GetProperty(joystick->device, DIPROP_GUIDANDPATH, &prop_guid_path.diph); @@ -668,15 +664,15 @@ static DWORD WINAPI input_thread(void *param)
static void test_handle_joychange(HWND hwnd, struct JoystickData *data) { + DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; int i;
if (data->num_joysticks == 0) return;
data->chosen_joystick = SendDlgItemMessageW(hwnd, IDC_TESTSELECTCOMBO, CB_GETCURSEL, 0, 0); + if (FAILED(IDirectInputDevice8_GetCapabilities( data->joysticks[data->chosen_joystick].device, &caps ))) return;
- /* Enable only buttons present in the device */ - for (i = 0; i < TEST_MAX_BUTTONS; i++) - ShowWindow(data->graphics.buttons[i], i < data->joysticks[data->chosen_joystick].num_buttons); + for (i = 0; i < TEST_MAX_BUTTONS; i++) ShowWindow( data->graphics.buttons[i], i < caps.dwButtons ); }
/*********************************************************************
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index d258dee7d01..59e5facb76f 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -79,8 +79,6 @@ struct Joystick { IDirectInputDevice8W *device; BOOL forcefeedback; - BOOL is_xinput; - BOOL has_override;
struct list effects; IDirectInputEffect *effect_selected; @@ -218,15 +216,6 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context )
static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *context) { - DIPROPGUIDANDPATH prop_guid_path = - { - .diph = - { - .dwSize = sizeof(DIPROPGUIDANDPATH), - .dwHeaderSize = sizeof(DIPROPHEADER), - .dwHow = DIPH_DEVICE, - }, - }; struct JoystickData *data = context; struct Joystick *joystick; DIPROPRANGE proprange; @@ -249,9 +238,6 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont
joystick->forcefeedback = caps.dwFlags & DIDC_FORCEFEEDBACK;
- IDirectInputDevice8_GetProperty(joystick->device, DIPROP_GUIDANDPATH, &prop_guid_path.diph); - joystick->is_xinput = wcsstr(prop_guid_path.wszPath, L"&ig_") != NULL; - list_init( &joystick->effects ); joystick->effect_selected = NULL;
@@ -394,8 +380,20 @@ static void refresh_joystick_list(HWND hwnd, struct JoystickData *data) for (joy = data->joysticks, joy_end = joy + data->num_joysticks; joy != joy_end; ++joy) { DIDEVICEINSTANCEW info = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; + DIPROPGUIDANDPATH prop = + { + .diph = + { + .dwSize = sizeof(DIPROPGUIDANDPATH), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + if (FAILED(IDirectInputDevice8_GetDeviceInfo( joy->device, &info ))) continue; - if (joy->is_xinput) SendDlgItemMessageW( hwnd, IDC_XINPUTLIST, LB_ADDSTRING, 0, (LPARAM)info.tszInstanceName ); + if (FAILED(IDirectInputDevice8_GetProperty( joy->device, DIPROP_GUIDANDPATH, &prop.diph ))) continue; + + if (wcsstr( prop.wszPath, L"&ig_" )) SendDlgItemMessageW( hwnd, IDC_XINPUTLIST, LB_ADDSTRING, 0, (LPARAM)info.tszInstanceName ); else SendDlgItemMessageW( hwnd, IDC_JOYSTICKLIST, LB_ADDSTRING, 0, (LPARAM)info.tszInstanceName ); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index 59e5facb76f..bee38fe3553 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -78,7 +78,6 @@ struct effect struct Joystick { IDirectInputDevice8W *device; - BOOL forcefeedback;
struct list effects; IDirectInputEffect *effect_selected; @@ -216,10 +215,10 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context )
static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *context) { + DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; struct JoystickData *data = context; struct Joystick *joystick; DIPROPRANGE proprange; - DIDEVCAPS caps;
if (data->joysticks == NULL) { @@ -233,15 +232,11 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont IDirectInput8_CreateDevice(data->di, &instance->guidInstance, &joystick->device, NULL); IDirectInputDevice8_SetDataFormat(joystick->device, &c_dfDIJoystick);
- caps.dwSize = sizeof(caps); - IDirectInputDevice8_GetCapabilities(joystick->device, &caps); - - joystick->forcefeedback = caps.dwFlags & DIDC_FORCEFEEDBACK; - list_init( &joystick->effects ); joystick->effect_selected = NULL;
- if (joystick->forcefeedback) data->num_ff++; + IDirectInputDevice8_GetCapabilities(joystick->device, &caps); + if (caps.dwFlags & DIDC_FORCEFEEDBACK) data->num_ff++;
/* Set axis range to ease the GUI visualization */ proprange.diph.dwSize = sizeof(DIPROPRANGE); @@ -252,9 +247,6 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont proprange.lMax = TEST_AXIS_MAX;
IDirectInputDevice_SetProperty(joystick->device, DIPROP_RANGE, &proprange.diph); - - if (!joystick->forcefeedback) return DIENUM_CONTINUE; - IDirectInputDevice8_EnumEffects( joystick->device, enum_effects, (void *)joystick, 0 );
return DIENUM_CONTINUE;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index bee38fe3553..ec8299753f1 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -105,6 +105,15 @@ struct JoystickData
static HMODULE hcpl;
+static CRITICAL_SECTION joy_cs; +static CRITICAL_SECTION_DEBUG joy_cs_debug = +{ + 0, 0, &joy_cs, + { &joy_cs_debug.ProcessLocksList, &joy_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": joy_cs") } +}; +static CRITICAL_SECTION joy_cs = { &joy_cs_debug, -1, 0, 0, 0, 0 }; + /********************************************************************* * DllMain */ @@ -213,6 +222,27 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) return DIENUM_CONTINUE; }
+static void set_selected_effect( struct Joystick *joystick, IDirectInputEffect *effect ) +{ + IDirectInputEffect *previous; + + EnterCriticalSection( &joy_cs ); + if ((previous = joystick->effect_selected)) IDirectInputEffect_Release( previous ); + if ((joystick->effect_selected = effect)) IDirectInput_AddRef( effect ); + LeaveCriticalSection( &joy_cs ); +} + +static IDirectInputEffect *get_selected_effect( struct Joystick *joystick ) +{ + IDirectInputEffect *effect; + + EnterCriticalSection( &joy_cs ); + if ((effect = joystick->effect_selected)) IDirectInputEffect_AddRef( effect ); + LeaveCriticalSection( &joy_cs ); + + return effect; +} + static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *context) { DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; @@ -277,6 +307,8 @@ static void destroy_joysticks(struct JoystickData *data) { struct effect *effect, *next_effect;
+ set_selected_effect( &data->joysticks[i], NULL ); + LIST_FOR_EACH_ENTRY_SAFE( effect, next_effect, &data->joysticks[i].effects, struct effect, entry ) { list_remove( &effect->entry ); @@ -867,6 +899,8 @@ static void ff_handle_effectchange(HWND hwnd, struct Joystick *joy) struct list *entry; int sel;
+ set_selected_effect( joy, NULL ); + sel = SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_GETCURSEL, 0, 0); if (sel < 0) return;
@@ -874,7 +908,7 @@ static void ff_handle_effectchange(HWND hwnd, struct Joystick *joy) while (sel-- && entry) entry = list_next( &joy->effects, entry ); if (!entry) return;
- joy->effect_selected = LIST_ENTRY( entry, struct effect, entry )->effect; + set_selected_effect( joy, LIST_ENTRY( entry, struct effect, entry )->effect );
IDirectInputDevice8_Unacquire(joy->device); IDirectInputDevice8_SetCooperativeLevel(joy->device, GetAncestor(hwnd, GA_ROOT), DISCL_BACKGROUND|DISCL_EXCLUSIVE); @@ -908,7 +942,7 @@ static DWORD WINAPI ff_input_thread(void *param)
Sleep(TEST_POLL_TIME);
- if (!(effect = joy->effect_selected)) continue; + if (!(effect = get_selected_effect( joy ))) continue;
poll_input(joy, &state);
@@ -930,6 +964,8 @@ static DWORD WINAPI ff_input_thread(void *param) IDirectInputEffect_Start( effect, 1, 0 ); break; } + + IDirectInputEffect_Release( effect ); }
return 0;