[PATCH 4/5] xinput1_3: Enable controller on init, disable on remove.
Rémi Bernon
rbernon at codeweavers.com
Fri Aug 6 10:08:58 CDT 2021
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/xinput1_3/main.c | 115 ++++++++++++++++++++++--------------------
1 file changed, 59 insertions(+), 56 deletions(-)
diff --git a/dlls/xinput1_3/main.c b/dlls/xinput1_3/main.c
index 7f4bb329c75..d5ddc1f38c8 100644
--- a/dlls/xinput1_3/main.c
+++ b/dlls/xinput1_3/main.c
@@ -240,6 +240,58 @@ static BOOL VerifyGamepad(PHIDP_PREPARSED_DATA preparsed, XINPUT_CAPABILITIES *x
return TRUE;
}
+static DWORD HID_set_state(struct xinput_controller *device, XINPUT_VIBRATION *state)
+{
+ struct hid_platform_private *private = device->platform_private;
+ char *output_report_buf = private->output_report_buf;
+ ULONG output_report_len = private->caps.OutputReportByteLength;
+
+ if (device->caps.Flags & XINPUT_CAPS_FFB_SUPPORTED)
+ {
+ device->vibration.wLeftMotorSpeed = state->wLeftMotorSpeed;
+ device->vibration.wRightMotorSpeed = state->wRightMotorSpeed;
+
+ if (private->enabled)
+ {
+ memset(output_report_buf, 0, output_report_len);
+ output_report_buf[0] = /* report id */ 0;
+ output_report_buf[1] = 0x8;
+ output_report_buf[3] = (BYTE)(state->wLeftMotorSpeed / 256);
+ output_report_buf[4] = (BYTE)(state->wRightMotorSpeed / 256);
+
+ if (!HidD_SetOutputReport(private->device, output_report_buf, output_report_len))
+ {
+ WARN("unable to set output report, HidD_SetOutputReport failed with error %u\n", GetLastError());
+ return GetLastError();
+ }
+
+ return ERROR_SUCCESS;
+ }
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static void controller_enable(struct xinput_controller *controller)
+{
+ struct hid_platform_private *private = controller->platform_private;
+ XINPUT_VIBRATION state = controller->vibration;
+
+ if (private->enabled) return;
+ if (controller->caps.Flags & XINPUT_CAPS_FFB_SUPPORTED) HID_set_state(controller, &state);
+ private->enabled = TRUE;
+}
+
+static void controller_disable(struct xinput_controller *controller)
+{
+ struct hid_platform_private *private = controller->platform_private;
+ XINPUT_VIBRATION state = {0};
+
+ if (!private->enabled) return;
+ if (controller->caps.Flags & XINPUT_CAPS_FFB_SUPPORTED) HID_set_state(controller, &state);
+ private->enabled = FALSE;
+}
+
static BOOL init_controller(struct xinput_controller *controller, PHIDP_PREPARSED_DATA preparsed,
HIDP_CAPS *caps, HANDLE device, WCHAR *device_path)
{
@@ -257,12 +309,15 @@ static BOOL init_controller(struct xinput_controller *controller, PHIDP_PREPARSE
if (!(private->input_report_buf[1] = calloc(1, private->caps.InputReportByteLength))) goto failed;
if (!(private->output_report_buf = calloc(1, private->caps.OutputReportByteLength))) goto failed;
lstrcpynW(private->device_path, device_path, MAX_PATH);
- private->enabled = TRUE;
+ private->enabled = FALSE;
memset(&controller->state, 0, sizeof(controller->state));
memset(&controller->vibration, 0, sizeof(controller->vibration));
+ EnterCriticalSection(&controller->crit);
controller->platform_private = private;
+ controller_enable(controller);
+ LeaveCriticalSection(&controller->crit);
return TRUE;
failed:
@@ -350,6 +405,7 @@ static void remove_gamepad(struct xinput_controller *device)
{
struct hid_platform_private *private = device->platform_private;
+ controller_disable(device);
device->platform_private = NULL;
CloseHandle(private->device);
@@ -499,60 +555,6 @@ static void HID_update_state(struct xinput_controller *device, XINPUT_STATE *sta
memcpy(state, &device->state, sizeof(*state));
}
-static DWORD HID_set_state(struct xinput_controller *device, XINPUT_VIBRATION *state)
-{
- struct hid_platform_private *private = device->platform_private;
- char *output_report_buf = private->output_report_buf;
- ULONG output_report_len = private->caps.OutputReportByteLength;
-
- if (device->caps.Flags & XINPUT_CAPS_FFB_SUPPORTED)
- {
- device->vibration.wLeftMotorSpeed = state->wLeftMotorSpeed;
- device->vibration.wRightMotorSpeed = state->wRightMotorSpeed;
-
- if (private->enabled)
- {
- memset(output_report_buf, 0, output_report_len);
- output_report_buf[0] = /* report id */ 0;
- output_report_buf[1] = 0x8;
- output_report_buf[3] = (BYTE)(state->wLeftMotorSpeed / 256);
- output_report_buf[4] = (BYTE)(state->wRightMotorSpeed / 256);
-
- if (!HidD_SetOutputReport(private->device, output_report_buf, output_report_len))
- {
- WARN("unable to set output report, HidD_SetOutputReport failed with error %u\n", GetLastError());
- return GetLastError();
- }
-
- return ERROR_SUCCESS;
- }
- }
-
- return ERROR_SUCCESS;
-}
-
-static void HID_enable(struct xinput_controller *device, BOOL enable)
-{
- struct hid_platform_private *private = device->platform_private;
-
- if (device->caps.Flags & XINPUT_CAPS_FFB_SUPPORTED)
- {
- if (private->enabled && !enable)
- {
- XINPUT_VIBRATION state;
- state.wLeftMotorSpeed = 0;
- state.wRightMotorSpeed = 0;
- HID_set_state(device, &state);
- }
- else if (!private->enabled && enable)
- {
- HID_set_state(device, &device->vibration);
- }
- }
-
- private->enabled = enable;
-}
-
static BOOL verify_and_lock_device(struct xinput_controller *device)
{
if (!device->platform_private) return FALSE;
@@ -603,7 +605,8 @@ void WINAPI DECLSPEC_HOTPATCH XInputEnable(BOOL enable)
for (index = 0; index < XUSER_MAX_COUNT; index++)
{
if (!verify_and_lock_device(&controllers[index])) continue;
- HID_enable(&controllers[index], enable);
+ if (enable) controller_enable(&controllers[index]);
+ else controller_disable(&controllers[index]);
unlock_device(&controllers[index]);
}
}
--
2.32.0
More information about the wine-devel
mailing list