From: Tyson Whitehead twhitehead@gmail.com
--- dlls/joy.cpl/dinput.c | 71 ++++++++++++++++++++++++++++++++++++++ dlls/joy.cpl/joy.rc | 31 +++++++++-------- dlls/joy.cpl/joy_private.h | 3 ++ dlls/joy.cpl/main.c | 22 ++++++++---- dlls/joy.cpl/resource.h | 1 + 5 files changed, 107 insertions(+), 21 deletions(-)
diff --git a/dlls/joy.cpl/dinput.c b/dlls/joy.cpl/dinput.c index 68268cbb72c..cce3db3dbb8 100644 --- a/dlls/joy.cpl/dinput.c +++ b/dlls/joy.cpl/dinput.c @@ -198,6 +198,15 @@ static void clear_effects(void) static void set_selected_device( IDirectInputDevice8W *device ) { IDirectInputDevice8W *previous; + DIPROPDWORD ac_prop = { + .diph = { + .dwSize = sizeof(DIPROPDWORD), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + HANDLE ac_button = GetDlgItem( dialog_hwnd, IDC_DI_AUTOCENTER ); + HRESULT hr;
EnterCriticalSection( &state_cs );
@@ -212,6 +221,16 @@ static void set_selected_device( IDirectInputDevice8W *device ) { IDirectInputDevice8_AddRef( device ); IDirectInputDevice8_SetEventNotification( device, state_event ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_AUTOCENTER, &ac_prop.diph); + if ( SUCCEEDED(hr) ) + { + EnableWindow( ac_button, TRUE); + SendMessageW( ac_button, BM_SETCHECK, ac_prop.dwData == DIPROPAUTOCENTER_ON, 0 ); + } + else + { + EnableWindow( ac_button, FALSE); + } IDirectInputDevice8_Acquire( device ); }
@@ -262,6 +281,52 @@ static void clear_devices(void) } }
+static void set_autocenter_initial( BOOL enabled ) +{ + IDirectInputDevice8W *device; + + if ( (device = get_selected_device()) ) + { + DIDEVICEINSTANCEW instance = { .dwSize = sizeof(DIDEVICEINSTANCEW) }; + HRESULT hr; + + if ( FAILED(hr = IDirectInputDevice8_GetDeviceInfo( device, &instance )) ) + { + WARN( "Unable to set autocenter default as get device info failed, hr %#lx\n", hr ); + } + else + { + DIPROPDWORD autocenter = { + .diph = { + .dwSize = sizeof(DIPROPDWORD), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + HKEY defkey, appkey; + + get_app_key(L"Autocenter", &defkey, &appkey); + + if (!enabled) + set_config_key(defkey, appkey, instance.tszInstanceName, L"off"); + else + set_config_key(defkey, appkey, instance.tszInstanceName, L"on"); + + if (defkey) RegCloseKey(defkey); + if (appkey) RegCloseKey(appkey); + + IDirectInputDevice8_Unacquire( device ); + autocenter.dwData = enabled ? DIPROPAUTOCENTER_ON : DIPROPAUTOCENTER_OFF; + if ( FAILED(hr = IDirectInputDevice8_SetProperty(device, DIPROP_AUTOCENTER, &autocenter.diph)) ) + { + WARN( "Unable to set autocenter on device as set property failed, hr %#lx\n", hr ); + } + IDirectInputDevice8_Acquire( device ); + IDirectInputDevice8_Release( device ); + } + } +} + static DWORD WINAPI input_thread( void *param ) { HANDLE events[2] = {param, state_event}; @@ -783,6 +848,7 @@ INT_PTR CALLBACK test_di_dialog_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM .dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE, .dbcc_classguid = GUID_DEVINTERFACE_HID, }; + DWORD sel;
TRACE( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam );
@@ -807,6 +873,11 @@ INT_PTR CALLBACK test_di_dialog_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM case MAKEWPARAM( IDC_DI_EFFECTS, LBN_SELCHANGE ): handle_di_effects_change( hwnd ); break; + + case MAKEWPARAM( IDC_DI_AUTOCENTER, BN_CLICKED ): + sel = SendMessageW( GetDlgItem( hwnd, IDC_DI_AUTOCENTER ), BM_GETCHECK, 0, 0 ); + set_autocenter_initial( sel ); + break; } return TRUE;
diff --git a/dlls/joy.cpl/joy.rc b/dlls/joy.cpl/joy.rc index 1eb62d86ab3..7ac6221ed1b 100644 --- a/dlls/joy.cpl/joy.rc +++ b/dlls/joy.cpl/joy.rc @@ -31,28 +31,28 @@ BEGIN IDS_CPL_INFO "Test and configure game controllers." END
-IDD_LIST DIALOG 0, 0, 320, 300 +IDD_LIST DIALOG 0, 0, 320, 310 STYLE WS_CAPTION | WS_CHILD | WS_DISABLED CAPTION "Joysticks" FONT 8, "Ms Shell Dlg" { PUSHBUTTON "&Disable", IDC_BUTTON_DI_DISABLE, 200, 20, 60, 15 PUSHBUTTON "&Reset", IDC_BUTTON_DI_RESET, 200, 40, 60, 15 - PUSHBUTTON "&Override", IDC_BUTTON_XI_OVERRIDE, 200, 90, 60, 15 - PUSHBUTTON "&Enable", IDC_BUTTON_ENABLE, 200, 160, 60, 15 + PUSHBUTTON "&Override", IDC_BUTTON_XI_OVERRIDE, 200, 95, 60, 15 + PUSHBUTTON "&Enable", IDC_BUTTON_ENABLE, 200, 170, 60, 15 LTEXT "Connected (DirectInput devices)", IDC_STATIC, 10, 10, 180, 10 - LISTBOX IDC_DI_ENABLED_LIST, 10, 20, 180, 60, WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY - LTEXT "Connected (XInput devices)", IDC_STATIC, 10, 80, 180, 10 - LISTBOX IDC_XI_ENABLED_LIST, 10, 90, 180, 60, WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY - LTEXT "Disabled", IDC_STATIC, 10, 150, 180, 10 - LISTBOX IDC_DISABLED_LIST, 10, 160, 180, 60, WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY - - GROUPBOX "Advanced settings (restart prefix required to take effect)", IDC_ADVANCED, 10, 220, 300, 70 - AUTOCHECKBOX "Enable SDL", IDC_ENABLE_SDL, 20, 235, 100, 10 - AUTOCHECKBOX "Disable hidraw", IDC_DISABLE_HIDRAW, 20, 245, 100, 10 + LISTBOX IDC_DI_ENABLED_LIST, 10, 20, 180, 65, WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY + LTEXT "Connected (XInput devices)", IDC_STATIC, 10, 85, 180, 10 + LISTBOX IDC_XI_ENABLED_LIST, 10, 95, 180, 65, WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY + LTEXT "Disabled", IDC_STATIC, 10, 160, 180, 10 + LISTBOX IDC_DISABLED_LIST, 10, 170, 180, 65, WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY + + GROUPBOX "Advanced settings (restart prefix required to take effect)", IDC_ADVANCED, 10, 235, 300, 65 + AUTOCHECKBOX "Enable SDL", IDC_ENABLE_SDL, 20, 250, 100, 10 + AUTOCHECKBOX "Disable hidraw", IDC_DISABLE_HIDRAW, 20, 260, 100, 10 }
-IDD_TEST_DI DIALOG 0, 0, 320, 300 +IDD_TEST_DI DIALOG 0, 0, 320, 310 STYLE WS_CAPTION | WS_CHILD | WS_DISABLED CAPTION "DInput" FONT 8, "Ms Shell Dlg" @@ -65,9 +65,10 @@ FONT 8, "Ms Shell Dlg" LISTBOX IDC_DI_EFFECTS, 15, 206, 291, 54, 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, 15, 260, 291, 25 + AUTOCHECKBOX "Autocenter on for applications that don't set it", IDC_DI_AUTOCENTER, 15, 290, 291, 10 }
-IDD_TEST_XI DIALOG 0, 0, 320, 300 +IDD_TEST_XI DIALOG 0, 0, 320, 310 STYLE WS_CAPTION | WS_CHILD | WS_DISABLED CAPTION "XInput" FONT 8, "Ms Shell Dlg" @@ -100,7 +101,7 @@ FONT 8, "Ms Shell Dlg" AUTOCHECKBOX "Rumble", IDC_XI_RUMBLE_3, 260, 220, 40, 10 }
-IDD_TEST_WGI DIALOG 0, 0, 320, 300 +IDD_TEST_WGI DIALOG 0, 0, 320, 310 STYLE WS_CAPTION | WS_CHILD | WS_DISABLED CAPTION "Windows.Gaming.Input" FONT 8, "Ms Shell Dlg" diff --git a/dlls/joy.cpl/joy_private.h b/dlls/joy.cpl/joy_private.h index 7c02096dd55..0ae690b5944 100644 --- a/dlls/joy.cpl/joy_private.h +++ b/dlls/joy.cpl/joy_private.h @@ -31,6 +31,9 @@
#include "resource.h"
+extern BOOL get_app_key(const WCHAR *subkey_name, HKEY *defkey, HKEY *appkey); +extern DWORD set_config_key(HKEY defkey, HKEY appkey, const WCHAR *name, const WCHAR *value); + extern void paint_axes_view( HWND hwnd, UINT32 count, double *axes, const WCHAR **names ); extern void paint_povs_view( HWND hwnd, UINT32 count, UINT32 *povs ); extern void paint_buttons_view( HWND hwnd, UINT32 count, BYTE *buttons ); diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index d667ae6b5b0..baf0705b893 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -112,15 +112,25 @@ static void clear_devices(void) * get_app_key [internal] * Get the default DirectInput key and the selected app config key. */ -static BOOL get_app_key(HKEY *defkey, HKEY *appkey) +BOOL get_app_key(const WCHAR *subkey_name, HKEY *defkey, HKEY *appkey) { + HKEY tempkey; *appkey = 0;
/* Registry key can be found in HKCU\Software\Wine\DirectInput */ - if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\Wine\DirectInput\Joysticks", 0, NULL, 0, + if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\Wine\DirectInput", 0, NULL, 0, KEY_SET_VALUE | KEY_READ, NULL, defkey, NULL)) *defkey = 0;
+ if ( *defkey && subkey_name ) + { + if ( RegCreateKeyExW( *defkey, subkey_name, 0, NULL, 0, + KEY_SET_VALUE | KEY_READ, NULL, &tempkey, NULL) ) + tempkey = 0; + RegCloseKey( *defkey ); + *defkey = tempkey; + } + return *defkey || *appkey; }
@@ -135,7 +145,7 @@ static BOOL get_advanced_key(HKEY *key) * set_config_key [internal] * Writes a string value to a registry key, deletes the key if value == NULL */ -static DWORD set_config_key(HKEY defkey, HKEY appkey, const WCHAR *name, const WCHAR *value) +DWORD set_config_key(HKEY defkey, HKEY appkey, const WCHAR *name, const WCHAR *value) { if (value == NULL) { @@ -168,7 +178,7 @@ static void enable_joystick(WCHAR *joy_name, BOOL enable) { HKEY hkey, appkey;
- get_app_key(&hkey, &appkey); + get_app_key(L"Joysticks", &hkey, &appkey);
if (!enable) set_config_key(hkey, appkey, joy_name, L"disabled"); @@ -238,7 +248,7 @@ static void refresh_joystick_list( HWND hwnd ) }
/* Search for disabled joysticks */ - get_app_key(&hkey, &appkey); + get_app_key(L"Joysticks", &hkey, &appkey); RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, &values, NULL, NULL, NULL, NULL);
for (i=0; i < values; i++) @@ -260,7 +270,7 @@ static void override_joystick(WCHAR *joy_name, BOOL override) { HKEY hkey, appkey;
- get_app_key(&hkey, &appkey); + get_app_key(L"Joysticks", &hkey, &appkey);
if (override) set_config_key(hkey, appkey, joy_name, L"override"); diff --git a/dlls/joy.cpl/resource.h b/dlls/joy.cpl/resource.h index 894fa016b66..9d7743249df 100644 --- a/dlls/joy.cpl/resource.h +++ b/dlls/joy.cpl/resource.h @@ -56,6 +56,7 @@ #define IDC_DI_POVS 2102 #define IDC_DI_BUTTONS 2103 #define IDC_DI_EFFECTS 2104 +#define IDC_DI_AUTOCENTER 2105
#define IDC_XI_USER_0 2200 #define IDC_XI_USER_1 2201