In preparation for the addition of more tabs to test for other APIs.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 65 ++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 30 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index ec8299753f1..33af6202445 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -78,9 +78,6 @@ struct effect struct Joystick { IDirectInputDevice8W *device; - - struct list effects; - IDirectInputEffect *effect_selected; };
struct Graphics @@ -114,6 +111,9 @@ static CRITICAL_SECTION_DEBUG joy_cs_debug = }; static CRITICAL_SECTION joy_cs = { &joy_cs_debug, -1, 0, 0, 0, 0 };
+static struct list effects = LIST_INIT( effects ); +static IDirectInputEffect *effect_selected; + /********************************************************************* * DllMain */ @@ -217,32 +217,46 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) }
entry->effect = effect; - list_add_tail( &joystick->effects, &entry->entry ); + list_add_tail( &effects, &entry->entry );
return DIENUM_CONTINUE; }
-static void set_selected_effect( struct Joystick *joystick, IDirectInputEffect *effect ) +static void set_selected_effect( IDirectInputEffect *effect ) { IDirectInputEffect *previous;
EnterCriticalSection( &joy_cs ); - if ((previous = joystick->effect_selected)) IDirectInputEffect_Release( previous ); - if ((joystick->effect_selected = effect)) IDirectInput_AddRef( effect ); + if ((previous = effect_selected)) IDirectInputEffect_Release( previous ); + if ((effect_selected = effect)) IDirectInput_AddRef( effect ); LeaveCriticalSection( &joy_cs ); }
-static IDirectInputEffect *get_selected_effect( struct Joystick *joystick ) +static IDirectInputEffect *get_selected_effect(void) { IDirectInputEffect *effect;
EnterCriticalSection( &joy_cs ); - if ((effect = joystick->effect_selected)) IDirectInputEffect_AddRef( effect ); + if ((effect = effect_selected)) IDirectInputEffect_AddRef( effect ); LeaveCriticalSection( &joy_cs );
return effect; }
+static void clear_effects(void) +{ + struct effect *effect, *next; + + set_selected_effect( NULL ); + + LIST_FOR_EACH_ENTRY_SAFE( effect, next, &effects, struct effect, entry ) + { + list_remove( &effect->entry ); + IDirectInputEffect_Release( effect->effect ); + free( effect ); + } +} + static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *context) { DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; @@ -262,9 +276,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);
- list_init( &joystick->effects ); - joystick->effect_selected = NULL; - IDirectInputDevice8_GetCapabilities(joystick->device, &caps); if (caps.dwFlags & DIDC_FORCEFEEDBACK) data->num_ff++;
@@ -277,7 +288,6 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont proprange.lMax = TEST_AXIS_MAX;
IDirectInputDevice_SetProperty(joystick->device, DIPROP_RANGE, &proprange.diph); - IDirectInputDevice8_EnumEffects( joystick->device, enum_effects, (void *)joystick, 0 );
return DIENUM_CONTINUE; } @@ -305,17 +315,6 @@ static void destroy_joysticks(struct JoystickData *data)
for (i = 0; i < data->num_joysticks; i++) { - 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 ); - IDirectInputEffect_Release( effect->effect ); - free( effect ); - } - IDirectInputDevice8_Unacquire(data->joysticks[i].device); IDirectInputDevice8_Release(data->joysticks[i].device); } @@ -394,6 +393,7 @@ static void refresh_joystick_list(HWND hwnd, struct JoystickData *data) LSTATUS status; DWORD i;
+ clear_effects(); destroy_joysticks(data); initialize_joysticks(data);
@@ -873,9 +873,13 @@ static void initialize_effects_list(HWND hwnd, struct Joystick* joy) { struct effect *effect;
+ clear_effects(); + + IDirectInputDevice8_EnumEffects( joy->device, enum_effects, (void *)joy, 0 ); + SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_RESETCONTENT, 0, 0);
- LIST_FOR_EACH_ENTRY( effect, &joy->effects, struct effect, entry ) + LIST_FOR_EACH_ENTRY( effect, &effects, struct effect, entry ) { DIEFFECTINFOW info = {.dwSize = sizeof(DIEFFECTINFOW)}; GUID guid; @@ -899,16 +903,16 @@ static void ff_handle_effectchange(HWND hwnd, struct Joystick *joy) struct list *entry; int sel;
- set_selected_effect( joy, NULL ); + set_selected_effect( NULL );
sel = SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_GETCURSEL, 0, 0); if (sel < 0) return;
- entry = list_head( &joy->effects ); - while (sel-- && entry) entry = list_next( &joy->effects, entry ); + entry = list_head( &effects ); + while (sel-- && entry) entry = list_next( &effects, entry ); if (!entry) return;
- set_selected_effect( joy, LIST_ENTRY( entry, struct effect, entry )->effect ); + set_selected_effect( LIST_ENTRY( entry, struct effect, entry )->effect );
IDirectInputDevice8_Unacquire(joy->device); IDirectInputDevice8_SetCooperativeLevel(joy->device, GetAncestor(hwnd, GA_ROOT), DISCL_BACKGROUND|DISCL_EXCLUSIVE); @@ -942,7 +946,7 @@ static DWORD WINAPI ff_input_thread(void *param)
Sleep(TEST_POLL_TIME);
- if (!(effect = get_selected_effect( joy ))) continue; + if (!(effect = get_selected_effect())) continue;
poll_input(joy, &state);
@@ -1207,6 +1211,7 @@ LONG CALLBACK CPlApplet(HWND hwnd, UINT command, LPARAM lParam1, LPARAM lParam2) break;
case CPL_STOP: + clear_effects(); destroy_joysticks(&data);
/* And destroy dinput too */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 228 ++++++++++++++++++++++++++------------------ 1 file changed, 137 insertions(+), 91 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index 33af6202445..f2d4212b0aa 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -75,8 +75,9 @@ struct effect IDirectInputEffect *effect; };
-struct Joystick +struct device { + struct list entry; IDirectInputDevice8W *device; };
@@ -91,11 +92,7 @@ struct Graphics struct JoystickData { IDirectInput8W *di; - struct Joystick *joysticks; - int num_joysticks; int num_ff; - int cur_joystick; - int chosen_joystick; struct Graphics graphics; BOOL stop; }; @@ -114,6 +111,9 @@ static CRITICAL_SECTION joy_cs = { &joy_cs_debug, -1, 0, 0, 0, 0 }; static struct list effects = LIST_INIT( effects ); static IDirectInputEffect *effect_selected;
+static struct list devices = LIST_INIT( devices ); +static IDirectInputDevice8W *device_selected; + /********************************************************************* * DllMain */ @@ -132,7 +132,7 @@ BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason, LPVOID reserved)
static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) { - struct Joystick *joystick = context; + IDirectInputDevice8W *device = context; DWORD axes[2] = {DIJOFS_X, DIJOFS_Y}; LONG direction[2] = {0}; DIEFFECT params = @@ -169,7 +169,7 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) struct effect *entry; HRESULT hr;
- hr = IDirectInputDevice8_Acquire( joystick->device ); + hr = IDirectInputDevice8_Acquire( device ); if (FAILED(hr)) return DIENUM_CONTINUE;
if (!(entry = calloc( 1, sizeof(*entry) ))) return DIENUM_STOP; @@ -206,7 +206,7 @@ static BOOL CALLBACK enum_effects( const DIEFFECTINFOW *info, void *context ) params.dwFlags |= DIEP_TYPESPECIFICPARAMS; }
- do hr = IDirectInputDevice2_CreateEffect( joystick->device, &info->guid, ¶ms, &effect, NULL ); + do hr = IDirectInputDevice2_CreateEffect( device, &info->guid, ¶ms, &effect, NULL ); while (FAILED(hr) && --params.cAxes);
if (FAILED(hr)) @@ -257,26 +257,19 @@ static void clear_effects(void) } }
-static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *context) +static BOOL CALLBACK enum_devices( const DIDEVICEINSTANCEW *instance, void *context ) { DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; struct JoystickData *data = context; - struct Joystick *joystick; DIPROPRANGE proprange; + struct device *entry;
- if (data->joysticks == NULL) - { - data->num_joysticks += 1; - return DIENUM_CONTINUE; - } - - joystick = &data->joysticks[data->cur_joystick]; - data->cur_joystick += 1; + if (!(entry = calloc( 1, sizeof(*entry) ))) return DIENUM_STOP;
- IDirectInput8_CreateDevice(data->di, &instance->guidInstance, &joystick->device, NULL); - IDirectInputDevice8_SetDataFormat(joystick->device, &c_dfDIJoystick); + IDirectInput8_CreateDevice( data->di, &instance->guidInstance, &entry->device, NULL ); + IDirectInputDevice8_SetDataFormat( entry->device, &c_dfDIJoystick );
- IDirectInputDevice8_GetCapabilities(joystick->device, &caps); + IDirectInputDevice8_GetCapabilities( entry->device, &caps ); if (caps.dwFlags & DIDC_FORCEFEEDBACK) data->num_ff++;
/* Set axis range to ease the GUI visualization */ @@ -287,40 +280,53 @@ static BOOL CALLBACK enum_callback(const DIDEVICEINSTANCEW *instance, void *cont proprange.lMin = TEST_AXIS_MIN; proprange.lMax = TEST_AXIS_MAX;
- IDirectInputDevice_SetProperty(joystick->device, DIPROP_RANGE, &proprange.diph); + IDirectInputDevice_SetProperty( entry->device, DIPROP_RANGE, &proprange.diph ); + list_add_tail( &devices, &entry->entry );
return DIENUM_CONTINUE; }
-/*********************************************************************** - * initialize_joysticks [internal] - */ -static void initialize_joysticks(struct JoystickData *data) +static void set_selected_device( IDirectInputDevice8W *device ) +{ + IDirectInputDevice8W *previous; + + EnterCriticalSection( &joy_cs ); + + set_selected_effect( NULL ); + + if (device) IDirectInputDevice8_AddRef( device ); + previous = device_selected; + device_selected = device; + if (previous) IDirectInputEffect_Release( previous ); + + LeaveCriticalSection( &joy_cs ); +} + +static IDirectInputDevice8W *get_selected_device(void) { - data->num_joysticks = 0; - data->cur_joystick = 0; - IDirectInput8_EnumDevices(data->di, DI8DEVCLASS_GAMECTRL, enum_callback, data, DIEDFL_ATTACHEDONLY); - data->joysticks = malloc(sizeof(struct Joystick) * data->num_joysticks); + IDirectInputDevice8W *device; + + EnterCriticalSection( &joy_cs ); + device = device_selected; + if (device) IDirectInputDevice8_AddRef( device ); + LeaveCriticalSection( &joy_cs );
- /* Get all the joysticks */ - IDirectInput8_EnumDevices(data->di, DI8DEVCLASS_GAMECTRL, enum_callback, data, DIEDFL_ATTACHEDONLY); + return device; }
-/*********************************************************************** - * destroy_joysticks [internal] - */ -static void destroy_joysticks(struct JoystickData *data) +static void clear_devices(void) { - int i; + struct device *entry, *next; + + set_selected_device( NULL );
- for (i = 0; i < data->num_joysticks; i++) + LIST_FOR_EACH_ENTRY_SAFE( entry, next, &devices, struct device, entry ) { - IDirectInputDevice8_Unacquire(data->joysticks[i].device); - IDirectInputDevice8_Release(data->joysticks[i].device); + list_remove( &entry->entry ); + IDirectInputDevice8_Unacquire( entry->device ); + IDirectInputDevice8_Release( entry->device ); + free( entry ); } - - free(data->joysticks); - data->joysticks = NULL; }
/****************************************************************************** @@ -387,21 +393,22 @@ static void enable_joystick(WCHAR *joy_name, BOOL enable)
static void refresh_joystick_list(HWND hwnd, struct JoystickData *data) { - struct Joystick *joy, *joy_end; + struct device *entry; HKEY hkey, appkey; DWORD values = 0; LSTATUS status; DWORD i;
clear_effects(); - destroy_joysticks(data); - initialize_joysticks(data); + clear_devices(); + + IDirectInput8_EnumDevices( data->di, DI8DEVCLASS_GAMECTRL, enum_devices, data, DIEDFL_ATTACHEDONLY );
SendDlgItemMessageW(hwnd, IDC_JOYSTICKLIST, LB_RESETCONTENT, 0, 0); SendDlgItemMessageW(hwnd, IDC_DISABLEDLIST, LB_RESETCONTENT, 0, 0); SendDlgItemMessageW(hwnd, IDC_XINPUTLIST, LB_RESETCONTENT, 0, 0);
- for (joy = data->joysticks, joy_end = joy + data->num_joysticks; joy != joy_end; ++joy) + LIST_FOR_EACH_ENTRY( entry, &devices, struct device, entry ) { DIDEVICEINSTANCEW info = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; DIPROPGUIDANDPATH prop = @@ -414,8 +421,8 @@ static void refresh_joystick_list(HWND hwnd, struct JoystickData *data) }, };
- if (FAILED(IDirectInputDevice8_GetDeviceInfo( joy->device, &info ))) continue; - if (FAILED(IDirectInputDevice8_GetProperty( joy->device, DIPROP_GUIDANDPATH, &prop.diph ))) continue; + if (FAILED(IDirectInputDevice8_GetDeviceInfo( entry->device, &info ))) continue; + if (FAILED(IDirectInputDevice8_GetProperty( entry->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 ); @@ -596,22 +603,22 @@ static void dump_joy_state(DIJOYSTATE* st) TRACE("\n"); }
-static void poll_input(const struct Joystick *joy, DIJOYSTATE *state) +static void poll_input( IDirectInputDevice8W *device, DIJOYSTATE *state ) { HRESULT hr;
- hr = IDirectInputDevice8_Poll(joy->device); + hr = IDirectInputDevice8_Poll( device );
/* If it failed, try to acquire the joystick */ if (FAILED(hr)) { - hr = IDirectInputDevice8_Acquire(joy->device); - while (hr == DIERR_INPUTLOST) hr = IDirectInputDevice8_Acquire(joy->device); + hr = IDirectInputDevice8_Acquire( device ); + while (hr == DIERR_INPUTLOST) hr = IDirectInputDevice8_Acquire( device ); }
if (hr == DIERR_OTHERAPPHASPRIO) return;
- IDirectInputDevice8_GetDeviceState(joy->device, sizeof(DIJOYSTATE), state); + IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE), state ); }
static DWORD WINAPI input_thread(void *param) @@ -637,10 +644,16 @@ static DWORD WINAPI input_thread(void *param)
while (!data->stop) { - int i; - unsigned int j; + IDirectInputDevice8W *device; + unsigned int i, j; + + memset( &state, 0, sizeof(state) );
- poll_input(&data->joysticks[data->chosen_joystick], &state); + if ((device = get_selected_device())) + { + poll_input( device, &state ); + IDirectInputDevice8_Release( device ); + }
dump_joy_state(&state);
@@ -687,13 +700,23 @@ static DWORD WINAPI input_thread(void *param) static void test_handle_joychange(HWND hwnd, struct JoystickData *data) { DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; + IDirectInputDevice8W *device; + struct list *entry; int i;
- if (data->num_joysticks == 0) return; + set_selected_device( NULL ); + + i = SendDlgItemMessageW( hwnd, IDC_TESTSELECTCOMBO, CB_GETCURSEL, 0, 0 ); + if (i < 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; + entry = list_head( &devices ); + while (i-- && entry) entry = list_next( &devices, entry ); + if (!entry) return; + + device = LIST_ENTRY( entry, struct device, entry )->device; + if (FAILED(IDirectInputDevice8_GetCapabilities( device, &caps ))) return;
+ set_selected_device( device ); for (i = 0; i < TEST_MAX_BUTTONS; i++) ShowWindow( data->graphics.buttons[i], i < caps.dwButtons ); }
@@ -774,12 +797,14 @@ static void draw_joystick_axes(HWND hwnd, struct JoystickData* data) */ static void refresh_test_joystick_list(HWND hwnd, struct JoystickData *data) { - struct Joystick *joy, *joy_end; + struct device *entry; + SendDlgItemMessageW(hwnd, IDC_TESTSELECTCOMBO, CB_RESETCONTENT, 0, 0); - for (joy = data->joysticks, joy_end = joy + data->num_joysticks; joy != joy_end; ++joy) + + LIST_FOR_EACH_ENTRY( entry, &devices, struct device, entry ) { DIDEVICEINSTANCEW info = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; - if (FAILED(IDirectInputDevice8_GetDeviceInfo( joy->device, &info ))) continue; + if (FAILED(IDirectInputDevice8_GetDeviceInfo( entry->device, &info ))) continue; SendDlgItemMessageW( hwnd, IDC_TESTSELECTCOMBO, CB_ADDSTRING, 0, (LPARAM)info.tszInstanceName ); } } @@ -822,7 +847,7 @@ static INT_PTR CALLBACK test_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM refresh_test_joystick_list(hwnd, data);
/* Initialize input thread */ - if (data->num_joysticks > 0) + if (!list_empty( &devices )) { data->stop = FALSE;
@@ -869,13 +894,13 @@ static void draw_ff_axis(HWND hwnd, struct JoystickData *data) hwnd, NULL, NULL, hinst); }
-static void initialize_effects_list(HWND hwnd, struct Joystick* joy) +static void initialize_effects_list( HWND hwnd, IDirectInputDevice8W *device ) { struct effect *effect;
clear_effects();
- IDirectInputDevice8_EnumEffects( joy->device, enum_effects, (void *)joy, 0 ); + IDirectInputDevice8_EnumEffects( device, enum_effects, device, 0 );
SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_RESETCONTENT, 0, 0);
@@ -885,21 +910,35 @@ static void initialize_effects_list(HWND hwnd, struct Joystick* joy) GUID guid;
if (FAILED(IDirectInputEffect_GetEffectGuid( effect->effect, &guid ))) continue; - if (FAILED(IDirectInputDevice8_GetEffectInfo( joy->device, &info, &guid ))) continue; + if (FAILED(IDirectInputDevice8_GetEffectInfo( device, &info, &guid ))) continue; SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_ADDSTRING, 0, (LPARAM)(info.tszName + 5)); } }
-static void ff_handle_joychange(HWND hwnd, struct JoystickData *data) +static void ff_handle_joychange( HWND hwnd ) { - if (data->num_ff == 0) return; + DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; + IDirectInputDevice8W *device; + struct list *entry; + int i; + + i = SendDlgItemMessageW( hwnd, IDC_FFSELECTCOMBO, CB_GETCURSEL, 0, 0 ); + if (i < 0) return; + + entry = list_head( &devices ); + while (i-- && entry) entry = list_next( &devices, entry ); + if (!entry) return;
- data->chosen_joystick = SendDlgItemMessageW(hwnd, IDC_FFSELECTCOMBO, CB_GETCURSEL, 0, 0); - initialize_effects_list(hwnd, &data->joysticks[data->chosen_joystick]); + device = LIST_ENTRY( entry, struct device, entry )->device; + if (FAILED(IDirectInputDevice8_GetCapabilities( device, &caps ))) return; + + set_selected_device( device ); + initialize_effects_list( hwnd, device ); }
-static void ff_handle_effectchange(HWND hwnd, struct Joystick *joy) +static void ff_handle_effectchange( HWND hwnd ) { + IDirectInputDevice8W *device; struct list *entry; int sel;
@@ -914,9 +953,13 @@ static void ff_handle_effectchange(HWND hwnd, struct Joystick *joy)
set_selected_effect( 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); + if ((device = get_selected_device())) + { + IDirectInputDevice8_Unacquire( device ); + IDirectInputDevice8_SetCooperativeLevel( device, GetAncestor( hwnd, GA_ROOT ), DISCL_BACKGROUND | DISCL_EXCLUSIVE ); + IDirectInputDevice8_Acquire( device ); + IDirectInputDevice8_Release( device ); + } }
static DWORD WINAPI ff_input_thread(void *param) @@ -929,8 +972,8 @@ static DWORD WINAPI ff_input_thread(void *param) while (!data->stop) { int i; - struct Joystick *joy = &data->joysticks[data->chosen_joystick]; DWORD flags = DIEP_AXES | DIEP_DIRECTION | DIEP_NORESTART; + IDirectInputDevice8W *device; IDirectInputEffect *effect; LONG direction[3] = {0}; DWORD axes[3] = {0}; @@ -946,9 +989,11 @@ static DWORD WINAPI ff_input_thread(void *param)
Sleep(TEST_POLL_TIME);
- if (!(effect = get_selected_effect())) continue; + if (!(device = get_selected_device())) continue; + poll_input( device, &state ); + IDirectInputDevice8_Release( device );
- poll_input(joy, &state); + if (!(effect = get_selected_effect())) continue;
IDirectInputEffect_GetParameters( effect, ¶ms, flags ); params.rgdwAxes[0] = state.lX; @@ -982,12 +1027,14 @@ static DWORD WINAPI ff_input_thread(void *param) */ static void refresh_ff_joystick_list(HWND hwnd, struct JoystickData *data) { - struct Joystick *joy, *joy_end; + struct device *entry; + SendDlgItemMessageW(hwnd, IDC_FFSELECTCOMBO, CB_RESETCONTENT, 0, 0); - for (joy = data->joysticks, joy_end = joy + data->num_joysticks; joy != joy_end; ++joy) + + LIST_FOR_EACH_ENTRY( entry, &devices, struct device, entry ) { DIDEVICEINSTANCEW info = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; - if (FAILED(IDirectInputDevice8_GetDeviceInfo( joy->device, &info ))) continue; + if (FAILED(IDirectInputDevice8_GetDeviceInfo( entry->device, &info ))) continue; SendDlgItemMessageW( hwnd, IDC_FFSELECTCOMBO, CB_ADDSTRING, 0, (LPARAM)info.tszInstanceName ); } } @@ -1014,15 +1061,15 @@ static INT_PTR CALLBACK ff_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp switch(wparam) { case MAKEWPARAM(IDC_FFSELECTCOMBO, CBN_SELCHANGE): - ff_handle_joychange(hwnd, data); + ff_handle_joychange( hwnd );
SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_SETCURSEL, 0, 0); - ff_handle_effectchange(hwnd, &data->joysticks[data->chosen_joystick]); - break; + ff_handle_effectchange( hwnd ); + break;
case MAKEWPARAM(IDC_FFEFFECTLIST, LBN_SELCHANGE): - ff_handle_effectchange(hwnd, &data->joysticks[data->chosen_joystick]); - break; + ff_handle_effectchange( hwnd ); + break; } return TRUE;
@@ -1039,10 +1086,10 @@ static INT_PTR CALLBACK ff_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp data->stop = FALSE; /* Set the first joystick as default */ SendDlgItemMessageW(hwnd, IDC_FFSELECTCOMBO, CB_SETCURSEL, 0, 0); - ff_handle_joychange(hwnd, data); + ff_handle_joychange( hwnd );
SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_SETCURSEL, 0, 0); - ff_handle_effectchange(hwnd, &data->joysticks[data->chosen_joystick]); + ff_handle_effectchange( hwnd );
thread = CreateThread(NULL, 0, ff_input_thread, (void*) data, 0, &tid); } @@ -1187,8 +1234,7 @@ LONG CALLBACK CPlApplet(HWND hwnd, UINT command, LPARAM lParam1, LPARAM lParam2) return FALSE; }
- /* Then get all the connected joysticks */ - initialize_joysticks(&data); + IDirectInput8_EnumDevices( data.di, DI8DEVCLASS_GAMECTRL, enum_devices, &data, DIEDFL_ATTACHEDONLY );
return TRUE; } @@ -1212,7 +1258,7 @@ LONG CALLBACK CPlApplet(HWND hwnd, UINT command, LPARAM lParam1, LPARAM lParam2)
case CPL_STOP: clear_effects(); - destroy_joysticks(&data); + clear_devices();
/* And destroy dinput too */ IDirectInput8_Release(data.di);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index f2d4212b0aa..ab2314bad5f 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -92,7 +92,6 @@ struct Graphics struct JoystickData { IDirectInput8W *di; - int num_ff; struct Graphics graphics; BOOL stop; }; @@ -270,7 +269,6 @@ static BOOL CALLBACK enum_devices( const DIDEVICEINSTANCEW *instance, void *cont IDirectInputDevice8_SetDataFormat( entry->device, &c_dfDIJoystick );
IDirectInputDevice8_GetCapabilities( entry->device, &caps ); - if (caps.dwFlags & DIDC_FORCEFEEDBACK) data->num_ff++;
/* Set axis range to ease the GUI visualization */ proprange.diph.dwSize = sizeof(DIPROPRANGE); @@ -846,17 +844,13 @@ static INT_PTR CALLBACK test_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
refresh_test_joystick_list(hwnd, data);
- /* Initialize input thread */ - if (!list_empty( &devices )) - { - data->stop = FALSE; + data->stop = FALSE;
- /* Set the first joystick as default */ - SendDlgItemMessageW(hwnd, IDC_TESTSELECTCOMBO, CB_SETCURSEL, 0, 0); - test_handle_joychange(hwnd, data); + /* Set the first joystick as default */ + SendDlgItemMessageW(hwnd, IDC_TESTSELECTCOMBO, CB_SETCURSEL, 0, 0); + test_handle_joychange(hwnd, data);
- thread = CreateThread(NULL, 0, input_thread, (void*) data, 0, &tid); - } + thread = CreateThread(NULL, 0, input_thread, (void*) data, 0, &tid); } break;
@@ -1079,20 +1073,15 @@ static INT_PTR CALLBACK ff_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp case PSN_SETACTIVE: refresh_ff_joystick_list(hwnd, data);
- if (data->num_ff > 0) - { - DWORD tid; - - data->stop = FALSE; - /* Set the first joystick as default */ - SendDlgItemMessageW(hwnd, IDC_FFSELECTCOMBO, CB_SETCURSEL, 0, 0); - ff_handle_joychange( hwnd ); + data->stop = FALSE; + /* Set the first joystick as default */ + SendDlgItemMessageW(hwnd, IDC_FFSELECTCOMBO, CB_SETCURSEL, 0, 0); + ff_handle_joychange( hwnd );
- SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_SETCURSEL, 0, 0); - ff_handle_effectchange( hwnd ); + SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_SETCURSEL, 0, 0); + ff_handle_effectchange( hwnd );
- thread = CreateThread(NULL, 0, ff_input_thread, (void*) data, 0, &tid); - } + thread = CreateThread(NULL, 0, ff_input_thread, (void*) data, 0, NULL); break;
case PSN_RESET: /* intentional fall-through */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/main.c | 55 +++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 29 deletions(-)
diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index ab2314bad5f..cc1ce800445 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -113,6 +113,8 @@ static IDirectInputEffect *effect_selected; static struct list devices = LIST_INIT( devices ); static IDirectInputDevice8W *device_selected;
+static HANDLE device_state_event; + /********************************************************************* * DllMain */ @@ -292,10 +294,17 @@ static void set_selected_device( IDirectInputDevice8W *device )
set_selected_effect( NULL );
- if (device) IDirectInputDevice8_AddRef( device ); - previous = device_selected; - device_selected = device; - if (previous) IDirectInputEffect_Release( previous ); + if ((previous = device_selected)) + { + IDirectInputDevice8_SetEventNotification( previous, NULL ); + IDirectInputDevice8_Release( previous ); + } + if ((device_selected = device)) + { + IDirectInputDevice8_AddRef( device ); + IDirectInputDevice8_SetEventNotification( device, device_state_event ); + IDirectInputDevice8_Acquire( device ); + }
LeaveCriticalSection( &joy_cs ); } @@ -601,24 +610,6 @@ static void dump_joy_state(DIJOYSTATE* st) TRACE("\n"); }
-static void poll_input( IDirectInputDevice8W *device, DIJOYSTATE *state ) -{ - HRESULT hr; - - hr = IDirectInputDevice8_Poll( device ); - - /* If it failed, try to acquire the joystick */ - if (FAILED(hr)) - { - hr = IDirectInputDevice8_Acquire( device ); - while (hr == DIERR_INPUTLOST) hr = IDirectInputDevice8_Acquire( device ); - } - - if (hr == DIERR_OTHERAPPHASPRIO) return; - - IDirectInputDevice8_GetDeviceState( device, sizeof(DIJOYSTATE), state ); -} - static DWORD WINAPI input_thread(void *param) { int axes_pos[TEST_MAX_AXES][2]; @@ -647,9 +638,11 @@ static DWORD WINAPI input_thread(void *param)
memset( &state, 0, sizeof(state) );
+ if (WaitForSingleObject( device_state_event, TEST_POLL_TIME ) == WAIT_TIMEOUT) continue; + if ((device = get_selected_device())) { - poll_input( device, &state ); + IDirectInputDevice8_GetDeviceState( device, sizeof(state), &state ); IDirectInputDevice8_Release( device ); }
@@ -688,8 +681,6 @@ static DWORD WINAPI input_thread(void *param)
SetWindowPos(data->graphics.axes[i], 0, r.left, r.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); } - - Sleep(TEST_POLL_TIME); }
return 0; @@ -981,11 +972,13 @@ static DWORD WINAPI ff_input_thread(void *param) }; RECT r;
- Sleep(TEST_POLL_TIME); + if (WaitForSingleObject( device_state_event, TEST_POLL_TIME ) == WAIT_TIMEOUT) continue;
- if (!(device = get_selected_device())) continue; - poll_input( device, &state ); - IDirectInputDevice8_Release( device ); + if ((device = get_selected_device())) + { + IDirectInputDevice8_GetDeviceState( device, sizeof(state), &state ); + IDirectInputDevice8_Release( device ); + }
if (!(effect = get_selected_effect())) continue;
@@ -1214,6 +1207,8 @@ LONG CALLBACK CPlApplet(HWND hwnd, UINT command, LPARAM lParam1, LPARAM lParam2) { HRESULT hr;
+ device_state_event = CreateEventW( NULL, FALSE, FALSE, NULL ); + /* Initialize dinput */ hr = DirectInput8Create(GetModuleHandleW(NULL), DIRECTINPUT_VERSION, &IID_IDirectInput8W, (void**)&data.di, NULL);
@@ -1251,6 +1246,8 @@ LONG CALLBACK CPlApplet(HWND hwnd, UINT command, LPARAM lParam1, LPARAM lParam2)
/* And destroy dinput too */ IDirectInput8_Release(data.di); + + CloseHandle( device_state_event ); break; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/joy.rc | 4 ++-- dlls/joy.cpl/main.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/dlls/joy.cpl/joy.rc b/dlls/joy.cpl/joy.rc index 8086ecec6e1..d1c179d2ef3 100644 --- a/dlls/joy.cpl/joy.rc +++ b/dlls/joy.cpl/joy.rc @@ -55,8 +55,8 @@ CAPTION "Test Joystick" FONT 8, "Ms Shell Dlg" { COMBOBOX IDC_TESTSELECTCOMBO, 5, 5, 200, 60, CBS_DROPDOWNLIST | CBS_HASSTRINGS - GROUPBOX "Buttons", IDC_STATIC, 0, 110, 250, 110 - GROUPBOX "", IDC_TESTGROUPXY, 15, 30, 60, 60 + GROUPBOX "Buttons", IDC_STATIC, 15, 100, 291, 70 + GROUPBOX "", IDC_TESTGROUPXY, 15, 30, 60, 60 GROUPBOX "", IDC_TESTGROUPRXRY, 92, 30, 60, 60 GROUPBOX "", IDC_TESTGROUPZRZ, 169, 30, 60, 60 GROUPBOX "", IDC_TESTGROUPPOV, 246, 30, 60, 60 diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index cc1ce800445..e48762d18f1 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -43,13 +43,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(joycpl); #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_BUTTON_COL_MAX 16 +#define TEST_BUTTON_X 24 +#define TEST_BUTTON_Y 112 +#define TEST_NEXT_BUTTON_X 17 +#define TEST_NEXT_BUTTON_Y 15 +#define TEST_BUTTON_SIZE_X 16 +#define TEST_BUTTON_SIZE_Y 14
#define TEST_AXIS_X 43 #define TEST_AXIS_Y 60
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/joy.rc | 17 +- dlls/joy.cpl/main.c | 398 ++++++++++++---------------------------- dlls/joy.cpl/resource.h | 5 +- 3 files changed, 124 insertions(+), 296 deletions(-)
diff --git a/dlls/joy.cpl/joy.rc b/dlls/joy.cpl/joy.rc index d1c179d2ef3..0d4c719166d 100644 --- a/dlls/joy.cpl/joy.rc +++ b/dlls/joy.cpl/joy.rc @@ -54,25 +54,16 @@ STYLE WS_CAPTION | WS_CHILD | WS_DISABLED CAPTION "Test Joystick" FONT 8, "Ms Shell Dlg" { - COMBOBOX IDC_TESTSELECTCOMBO, 5, 5, 200, 60, CBS_DROPDOWNLIST | CBS_HASSTRINGS + COMBOBOX IDC_TESTSELECTCOMBO, 15, 10, 291, 60, CBS_DROPDOWNLIST | CBS_HASSTRINGS GROUPBOX "Buttons", IDC_STATIC, 15, 100, 291, 70 GROUPBOX "", IDC_TESTGROUPXY, 15, 30, 60, 60 GROUPBOX "", IDC_TESTGROUPRXRY, 92, 30, 60, 60 GROUPBOX "", IDC_TESTGROUPZRZ, 169, 30, 60, 60 GROUPBOX "", IDC_TESTGROUPPOV, 246, 30, 60, 60 -} - -IDD_FORCEFEEDBACK DIALOG 0, 0, 320, 300 -STYLE WS_CAPTION | WS_CHILD | WS_DISABLED -CAPTION "Test Force Feedback" -FONT 8, "Ms Shell Dlg" -{ - COMBOBOX IDC_FFSELECTCOMBO, 5, 5, 200, 60, CBS_DROPDOWNLIST | CBS_HASSTRINGS - LTEXT "Available Effects", IDC_STATIC, 10, 30, 100, 10 - LISTBOX IDC_FFEFFECTLIST, 10, 40, 180, 70, WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY + LTEXT "Force Feedback Effect", IDC_STATIC, 15, 180, 291, 10 + LISTBOX IDC_FFEFFECTLIST, 15, 190, 291, 70, WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY LTEXT "Press any button in the controller to activate the chosen effect. The effect direction can be changed with the controller axis.", - IDC_STATIC, 10, 110, 210, 25 - GROUPBOX "Direction", IDC_STATIC, 220, 30, 60, 60 + IDC_STATIC, 15, 260, 291, 25 }
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index e48762d18f1..e5377a71aa9 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -59,16 +59,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(joycpl); #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 { struct list entry; @@ -86,7 +79,6 @@ struct Graphics HWND hwnd; HWND buttons[TEST_MAX_BUTTONS]; HWND axes[TEST_MAX_AXES]; - HWND ff_axis; };
struct JoystickData @@ -613,7 +605,6 @@ static void dump_joy_state(DIJOYSTATE* st) static DWORD WINAPI input_thread(void *param) { int axes_pos[TEST_MAX_AXES][2]; - DIJOYSTATE state; struct JoystickData *data = param;
/* Setup POV as clock positions @@ -629,63 +620,114 @@ static DWORD WINAPI input_thread(void *param) int pov_pos[9][2] = { {0, -ma}, {ma/2, -ma/2}, {ma, 0}, {ma/2, ma/2}, {0, ma}, {-ma/2, ma/2}, {-ma, 0}, {-ma/2, -ma/2}, {0, 0} };
- ZeroMemory(&state, sizeof(state)); - while (!data->stop) { IDirectInputDevice8W *device; + IDirectInputEffect *effect; + DIJOYSTATE state = {0}; unsigned int i, j;
- memset( &state, 0, sizeof(state) ); - if (WaitForSingleObject( device_state_event, TEST_POLL_TIME ) == WAIT_TIMEOUT) continue;
if ((device = get_selected_device())) { IDirectInputDevice8_GetDeviceState( device, sizeof(state), &state ); IDirectInputDevice8_Release( device ); - }
- dump_joy_state(&state); + dump_joy_state(&state);
- /* Indicate pressed buttons */ - for (i = 0; i < TEST_MAX_BUTTONS; i++) - SendMessageW(data->graphics.buttons[i], BM_SETSTATE, !!state.rgbButtons[i], 0); + /* Indicate pressed buttons */ + for (i = 0; i < TEST_MAX_BUTTONS; i++) + SendMessageW(data->graphics.buttons[i], BM_SETSTATE, !!state.rgbButtons[i], 0);
- /* Indicate axis positions, axes showing are hardcoded for now */ - axes_pos[0][0] = state.lX; - axes_pos[0][1] = state.lY; - axes_pos[1][0] = state.lRx; - axes_pos[1][1] = state.lRy; - axes_pos[2][0] = state.lZ; - axes_pos[2][1] = state.lRz; + /* Indicate axis positions, axes showing are hardcoded for now */ + axes_pos[0][0] = state.lX; + axes_pos[0][1] = state.lY; + axes_pos[1][0] = state.lRx; + axes_pos[1][1] = state.lRy; + axes_pos[2][0] = state.lZ; + axes_pos[2][1] = state.lRz;
- /* Set pov values */ - for (j = 0; j < ARRAY_SIZE(pov_val); j++) - { - if (state.rgdwPOV[0] == pov_val[j]) + /* Set pov values */ + for (j = 0; j < ARRAY_SIZE(pov_val); j++) { - axes_pos[3][0] = pov_pos[j][0]; - axes_pos[3][1] = pov_pos[j][1]; + if (state.rgdwPOV[0] == pov_val[j]) + { + axes_pos[3][0] = pov_pos[j][0]; + axes_pos[3][1] = pov_pos[j][1]; + } + } + + for (i = 0; i < TEST_MAX_AXES; i++) + { + RECT r; + + r.left = (TEST_AXIS_X + TEST_NEXT_AXIS_X*i + axes_pos[i][0]); + r.top = (TEST_AXIS_Y + axes_pos[i][1]); + r.bottom = r.right = 0; /* unused */ + MapDialogRect(data->graphics.hwnd, &r); + + SetWindowPos(data->graphics.axes[i], 0, r.left, r.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); } }
- for (i = 0; i < TEST_MAX_AXES; i++) + if ((effect = get_selected_effect())) { - RECT r; - - r.left = (TEST_AXIS_X + TEST_NEXT_AXIS_X*i + axes_pos[i][0]); - r.top = (TEST_AXIS_Y + axes_pos[i][1]); - r.bottom = r.right = 0; /* unused */ - MapDialogRect(data->graphics.hwnd, &r); + 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, + }; + + IDirectInputEffect_GetParameters( effect, ¶ms, flags ); + params.rgdwAxes[0] = state.lX; + params.rgdwAxes[1] = state.lY; + + for (i=0; i < TEST_MAX_BUTTONS; i++) + { + if (state.rgbButtons[i]) + { + IDirectInputEffect_SetParameters( effect, ¶ms, flags ); + IDirectInputEffect_Start( effect, 1, 0 ); + break; + } + }
- SetWindowPos(data->graphics.axes[i], 0, r.left, r.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); + IDirectInputEffect_Release( effect ); } }
return 0; }
+static void initialize_effects_list( HWND hwnd, IDirectInputDevice8W *device ) +{ + struct effect *effect; + + clear_effects(); + + IDirectInputDevice8_EnumEffects( device, enum_effects, device, 0 ); + + SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_RESETCONTENT, 0, 0); + SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_ADDSTRING, 0, (LPARAM)L"None"); + + LIST_FOR_EACH_ENTRY( effect, &effects, struct effect, entry ) + { + DIEFFECTINFOW info = {.dwSize = sizeof(DIEFFECTINFOW)}; + GUID guid; + + if (FAILED(IDirectInputEffect_GetEffectGuid( effect->effect, &guid ))) continue; + if (FAILED(IDirectInputDevice8_GetEffectInfo( device, &info, &guid ))) continue; + SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_ADDSTRING, 0, (LPARAM)(info.tszName + 5)); + } +} + static void test_handle_joychange(HWND hwnd, struct JoystickData *data) { DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; @@ -706,9 +748,36 @@ static void test_handle_joychange(HWND hwnd, struct JoystickData *data) if (FAILED(IDirectInputDevice8_GetCapabilities( device, &caps ))) return;
set_selected_device( device ); + initialize_effects_list( hwnd, device ); for (i = 0; i < TEST_MAX_BUTTONS; i++) ShowWindow( data->graphics.buttons[i], i < caps.dwButtons ); }
+static void ff_handle_effectchange( HWND hwnd ) +{ + IDirectInputDevice8W *device; + struct list *entry; + int sel; + + set_selected_effect( NULL ); + + sel = SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_GETCURSEL, 0, 0) - 1; + if (sel < 0) return; + + entry = list_head( &effects ); + while (sel-- && entry) entry = list_next( &effects, entry ); + if (!entry) return; + + set_selected_effect( LIST_ENTRY( entry, struct effect, entry )->effect ); + + if ((device = get_selected_device())) + { + IDirectInputDevice8_Unacquire( device ); + IDirectInputDevice8_SetCooperativeLevel( device, GetAncestor( hwnd, GA_ROOT ), DISCL_BACKGROUND | DISCL_EXCLUSIVE ); + IDirectInputDevice8_Acquire( device ); + IDirectInputDevice8_Release( device ); + } +} + /********************************************************************* * button_number_to_wchar [internal] * Transforms an integer in the interval [0,99] into a 2 character WCHAR string @@ -822,233 +891,6 @@ static INT_PTR CALLBACK test_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM { case MAKEWPARAM(IDC_TESTSELECTCOMBO, CBN_SELCHANGE): test_handle_joychange(hwnd, data); - break; - } - return TRUE; - - case WM_NOTIFY: - switch(((LPNMHDR)lparam)->code) - { - case PSN_SETACTIVE: - { - DWORD tid; - - refresh_test_joystick_list(hwnd, data); - - data->stop = FALSE; - - /* Set the first joystick as default */ - SendDlgItemMessageW(hwnd, IDC_TESTSELECTCOMBO, CB_SETCURSEL, 0, 0); - test_handle_joychange(hwnd, data); - - thread = CreateThread(NULL, 0, input_thread, (void*) data, 0, &tid); - } - break; - - case PSN_RESET: /* intentional fall-through */ - case PSN_KILLACTIVE: - /* Stop input thread */ - data->stop = TRUE; - MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, 0); - CloseHandle(thread); - break; - } - return TRUE; - } - return FALSE; -} - -/********************************************************************* - * Joystick force feedback testing functions - * - */ -static void draw_ff_axis(HWND hwnd, struct JoystickData *data) -{ - HINSTANCE hinst = (HINSTANCE) GetWindowLongPtrW(hwnd, GWLP_HINSTANCE); - RECT r; - - r.left = FF_AXIS_X; - r.top = FF_AXIS_Y; - r.right = r.left + FF_AXIS_SIZE_X; - r.bottom = r.top + FF_AXIS_SIZE_Y; - MapDialogRect(hwnd, &r); - - /* Draw direction axis */ - data->graphics.ff_axis = CreateWindowW(L"Button", NULL, WS_CHILD | WS_VISIBLE, - r.left, r.top, r.right - r.left, r.bottom - r.top, - hwnd, NULL, NULL, hinst); -} - -static void initialize_effects_list( HWND hwnd, IDirectInputDevice8W *device ) -{ - struct effect *effect; - - clear_effects(); - - IDirectInputDevice8_EnumEffects( device, enum_effects, device, 0 ); - - SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_RESETCONTENT, 0, 0); - - LIST_FOR_EACH_ENTRY( effect, &effects, struct effect, entry ) - { - DIEFFECTINFOW info = {.dwSize = sizeof(DIEFFECTINFOW)}; - GUID guid; - - if (FAILED(IDirectInputEffect_GetEffectGuid( effect->effect, &guid ))) continue; - if (FAILED(IDirectInputDevice8_GetEffectInfo( device, &info, &guid ))) continue; - SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_ADDSTRING, 0, (LPARAM)(info.tszName + 5)); - } -} - -static void ff_handle_joychange( HWND hwnd ) -{ - DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; - IDirectInputDevice8W *device; - struct list *entry; - int i; - - i = SendDlgItemMessageW( hwnd, IDC_FFSELECTCOMBO, CB_GETCURSEL, 0, 0 ); - if (i < 0) return; - - entry = list_head( &devices ); - while (i-- && entry) entry = list_next( &devices, entry ); - if (!entry) return; - - device = LIST_ENTRY( entry, struct device, entry )->device; - if (FAILED(IDirectInputDevice8_GetCapabilities( device, &caps ))) return; - - set_selected_device( device ); - initialize_effects_list( hwnd, device ); -} - -static void ff_handle_effectchange( HWND hwnd ) -{ - IDirectInputDevice8W *device; - struct list *entry; - int sel; - - set_selected_effect( NULL ); - - sel = SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_GETCURSEL, 0, 0); - if (sel < 0) return; - - entry = list_head( &effects ); - while (sel-- && entry) entry = list_next( &effects, entry ); - if (!entry) return; - - set_selected_effect( LIST_ENTRY( entry, struct effect, entry )->effect ); - - if ((device = get_selected_device())) - { - IDirectInputDevice8_Unacquire( device ); - IDirectInputDevice8_SetCooperativeLevel( device, GetAncestor( hwnd, GA_ROOT ), DISCL_BACKGROUND | DISCL_EXCLUSIVE ); - IDirectInputDevice8_Acquire( device ); - IDirectInputDevice8_Release( device ); - } -} - -static DWORD WINAPI ff_input_thread(void *param) -{ - struct JoystickData *data = param; - DIJOYSTATE state; - - ZeroMemory(&state, sizeof(state)); - - while (!data->stop) - { - int i; - DWORD flags = DIEP_AXES | DIEP_DIRECTION | DIEP_NORESTART; - IDirectInputDevice8W *device; - IDirectInputEffect *effect; - 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; - - if (WaitForSingleObject( device_state_event, TEST_POLL_TIME ) == WAIT_TIMEOUT) continue; - - if ((device = get_selected_device())) - { - IDirectInputDevice8_GetDeviceState( device, sizeof(state), &state ); - IDirectInputDevice8_Release( device ); - } - - if (!(effect = get_selected_effect())) continue; - - IDirectInputEffect_GetParameters( 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; - r.right = r.bottom = 0; /* unused */ - MapDialogRect(data->graphics.hwnd, &r); - - SetWindowPos(data->graphics.ff_axis, 0, r.left, r.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - - for (i=0; i < TEST_MAX_BUTTONS; i++) - if (state.rgbButtons[i]) - { - IDirectInputEffect_SetParameters( effect, ¶ms, flags ); - IDirectInputEffect_Start( effect, 1, 0 ); - break; - } - - IDirectInputEffect_Release( effect ); - } - - return 0; -} - - -/********************************************************************* - * ff_dlgproc [internal] - * - */ -static void refresh_ff_joystick_list(HWND hwnd, struct JoystickData *data) -{ - struct device *entry; - - SendDlgItemMessageW(hwnd, IDC_FFSELECTCOMBO, CB_RESETCONTENT, 0, 0); - - LIST_FOR_EACH_ENTRY( entry, &devices, struct device, entry ) - { - DIDEVICEINSTANCEW info = {.dwSize = sizeof(DIDEVICEINSTANCEW)}; - if (FAILED(IDirectInputDevice8_GetDeviceInfo( entry->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) -{ - static HANDLE thread; - static struct JoystickData *data; - TRACE("(%p, 0x%08x/%d, 0x%Ix)\n", hwnd, msg, msg, lparam); - - switch (msg) - { - case WM_INITDIALOG: - { - data = (struct JoystickData*) ((PROPSHEETPAGEW*)lparam)->lParam; - - refresh_ff_joystick_list(hwnd, data); - draw_ff_axis(hwnd, data); - - return TRUE; - } - - case WM_COMMAND: - switch(wparam) - { - case MAKEWPARAM(IDC_FFSELECTCOMBO, CBN_SELCHANGE): - ff_handle_joychange( hwnd );
SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_SETCURSEL, 0, 0); ff_handle_effectchange( hwnd ); @@ -1064,22 +906,27 @@ static INT_PTR CALLBACK ff_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp switch(((LPNMHDR)lparam)->code) { case PSN_SETACTIVE: - refresh_ff_joystick_list(hwnd, data); + { + DWORD tid; + + refresh_test_joystick_list(hwnd, data);
data->stop = FALSE; + /* Set the first joystick as default */ - SendDlgItemMessageW(hwnd, IDC_FFSELECTCOMBO, CB_SETCURSEL, 0, 0); - ff_handle_joychange( hwnd ); + SendDlgItemMessageW(hwnd, IDC_TESTSELECTCOMBO, CB_SETCURSEL, 0, 0); + test_handle_joychange(hwnd, data);
SendDlgItemMessageW(hwnd, IDC_FFEFFECTLIST, LB_SETCURSEL, 0, 0); ff_handle_effectchange( hwnd );
- thread = CreateThread(NULL, 0, ff_input_thread, (void*) data, 0, NULL); + thread = CreateThread(NULL, 0, input_thread, (void*) data, 0, &tid); + } break;
case PSN_RESET: /* intentional fall-through */ case PSN_KILLACTIVE: - /* Stop ff thread */ + /* Stop input thread */ data->stop = TRUE; MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, 0); CloseHandle(thread); @@ -1113,8 +960,8 @@ static int CALLBACK propsheet_callback(HWND hwnd, UINT msg, LPARAM lparam) static void display_cpl_sheets(HWND parent, struct JoystickData *data) { INITCOMMONCONTROLSEX icex; - PROPSHEETPAGEW psp[NUM_PROPERTY_PAGES]; BOOL activated = FALSE; + PROPSHEETPAGEW psp[2]; PROPSHEETHEADERW psh; ULONG_PTR cookie; ACTCTXW actctx; @@ -1155,13 +1002,6 @@ static void display_cpl_sheets(HWND parent, struct JoystickData *data) psp[id].lParam = (INT_PTR) data; id++;
- psp[id].dwSize = sizeof (PROPSHEETPAGEW); - psp[id].hInstance = hcpl; - psp[id].u.pszTemplate = MAKEINTRESOURCEW(IDD_FORCEFEEDBACK); - psp[id].pfnDlgProc = ff_dlgproc; - psp[id].lParam = (INT_PTR) data; - id++; - /* Fill out the PROPSHEETHEADER */ psh.dwSize = sizeof (PROPSHEETHEADERW); psh.dwFlags = PSH_PROPSHEETPAGE | PSH_USEICONID | PSH_USECALLBACK; diff --git a/dlls/joy.cpl/resource.h b/dlls/joy.cpl/resource.h index 671e9ad8c77..c15f8dfbdeb 100644 --- a/dlls/joy.cpl/resource.h +++ b/dlls/joy.cpl/resource.h @@ -36,7 +36,6 @@
#define IDD_LIST 1000 #define IDD_TEST 1001 -#define IDD_FORCEFEEDBACK 1002
#define IDC_JOYSTICKLIST 2000 #define IDC_DISABLEDLIST 2001 @@ -51,9 +50,7 @@ #define IDC_TESTGROUPRXRY 2102 #define IDC_TESTGROUPZRZ 2103 #define IDC_TESTGROUPPOV 2104 - -#define IDC_FFSELECTCOMBO 2200 -#define IDC_FFEFFECTLIST 2201 +#define IDC_FFEFFECTLIST 2105
#define ICO_MAIN 100
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=126937
Your paranoid android.
=== debian11 (32 bit report) ===
Report validation errors: advapi32:security has no test summary line (early exit of the main process?) advapi32:security has unaccounted for todo messages