Aric Stewart : xinput: Implement XInputEnable.

Alexandre Julliard julliard at winehq.org
Thu Feb 15 14:42:28 CST 2018


Module: wine
Branch: master
Commit: 50e53643300da159a7680fb862a4f4c747a12697
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=50e53643300da159a7680fb862a4f4c747a12697

Author: Aric Stewart <aric at codeweavers.com>
Date:   Wed Feb 14 12:42:00 2018 -0600

xinput: Implement XInputEnable.

Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/xinput1_3/hid.c            | 59 ++++++++++++++++++++++++++++++++---------
 dlls/xinput1_3/xinput_main.c    | 12 ++++++++-
 dlls/xinput1_3/xinput_private.h |  1 +
 3 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/dlls/xinput1_3/hid.c b/dlls/xinput1_3/hid.c
index 33a92e1..3c54890 100644
--- a/dlls/xinput1_3/hid.c
+++ b/dlls/xinput1_3/hid.c
@@ -63,6 +63,7 @@ struct hid_platform_private {
     PHIDP_PREPARSED_DATA ppd;
     HANDLE device;
     WCHAR *device_path;
+    BOOL enabled;
 
     CRITICAL_SECTION crit;
 
@@ -212,6 +213,7 @@ static void build_private(struct hid_platform_private *private, PHIDP_PREPARSED_
     size = (strlenW(path) + 1) * sizeof(WCHAR);
     private->device_path = HeapAlloc(GetProcessHeap(), 0, size);
     memcpy(private->device_path, path, size);
+    private->enabled = TRUE;
 
     InitializeCriticalSection(&private->crit);
     private->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": JoystickImpl*->generic.base.crit");
@@ -351,6 +353,9 @@ void HID_update_state(xinput_controller* device)
     ULONG button_length;
     ULONG value;
 
+    if (!private->enabled)
+        return;
+
     EnterCriticalSection(&private->crit);
     if (!HidD_GetInputReport(private->device, target_report, private->report_length))
     {
@@ -431,25 +436,53 @@ DWORD HID_set_state(xinput_controller* device, XINPUT_VIBRATION* state)
 
     if (device->caps.Flags & XINPUT_CAPS_FFB_SUPPORTED)
     {
-        BOOLEAN rc;
-
         device->caps.Vibration.wLeftMotorSpeed = state->wLeftMotorSpeed;
         device->caps.Vibration.wRightMotorSpeed = state->wRightMotorSpeed;
 
-        report.report = 0;
-        report.pad1[0] = 0x8;
-        report.pad1[1] = 0x0;
-        report.left = (BYTE)(state->wLeftMotorSpeed / 255);
-        report.right = (BYTE)(state->wRightMotorSpeed / 255);
-        memset(&report.pad2, 0, sizeof(report.pad2));
+        if (private->enabled)
+        {
+            BOOLEAN rc;
+
+            report.report = 0;
+            report.pad1[0] = 0x8;
+            report.pad1[1] = 0x0;
+            report.left = (BYTE)(state->wLeftMotorSpeed / 255);
+            report.right = (BYTE)(state->wRightMotorSpeed / 255);
+            memset(&report.pad2, 0, sizeof(report.pad2));
+
+            EnterCriticalSection(&private->crit);
+            rc = HidD_SetOutputReport(private->device, &report, sizeof(report));
+            LeaveCriticalSection(&private->crit);
+            if (rc)
+                return ERROR_SUCCESS;
+            return GetLastError();
+        }
+        return ERROR_SUCCESS;
+    }
+
+    return ERROR_NOT_SUPPORTED;
+}
 
+void HID_enable(xinput_controller* device, BOOL enable)
+{
+    struct hid_platform_private *private = device->platform_private;
+
+    if (device->caps.Flags & XINPUT_CAPS_FFB_SUPPORTED)
+    {
         EnterCriticalSection(&private->crit);
-        rc = HidD_SetOutputReport(private->device, &report, sizeof(report));
+        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->caps.Vibration);
+        }
         LeaveCriticalSection(&private->crit);
-        if (rc)
-            return ERROR_SUCCESS;
-        return GetLastError();
     }
 
-    return ERROR_NOT_SUPPORTED;
+    private->enabled = enable;
 }
diff --git a/dlls/xinput1_3/xinput_main.c b/dlls/xinput1_3/xinput_main.c
index 680aba3..46d9918 100644
--- a/dlls/xinput1_3/xinput_main.c
+++ b/dlls/xinput1_3/xinput_main.c
@@ -54,11 +54,21 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
 
 void WINAPI DECLSPEC_HOTPATCH XInputEnable(BOOL enable)
 {
+    int index;
+
+    TRACE("(enable %d)\n", enable);
+
     /* Setting to false will stop messages from XInputSetState being sent
     to the controllers. Setting to true will send the last vibration
     value (sent to XInputSetState) to the controller and allow messages to
     be sent */
-    FIXME("(enable %d) Stub!\n", enable);
+    HID_find_gamepads(controllers);
+
+    for (index = 0; index < XUSER_MAX_COUNT; index ++)
+    {
+        if (!controllers[index].connected) continue;
+        HID_enable(&controllers[index], enable);
+    }
 }
 
 DWORD WINAPI XInputSetState(DWORD index, XINPUT_VIBRATION* vibration)
diff --git a/dlls/xinput1_3/xinput_private.h b/dlls/xinput1_3/xinput_private.h
index c10f869..00888f4 100644
--- a/dlls/xinput1_3/xinput_private.h
+++ b/dlls/xinput1_3/xinput_private.h
@@ -30,3 +30,4 @@ void HID_find_gamepads(xinput_controller *devices) DECLSPEC_HIDDEN;
 void HID_destroy_gamepads(xinput_controller *devices) DECLSPEC_HIDDEN;
 void HID_update_state(xinput_controller* device) DECLSPEC_HIDDEN;
 DWORD HID_set_state(xinput_controller* device, XINPUT_VIBRATION* state) DECLSPEC_HIDDEN;
+void HID_enable(xinput_controller* device, BOOL enable) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list