[PATCH 3/4] xinput1_3: Stub XInputGetStateEx

Bruno Jesus 00cpxxx at gmail.com
Wed Aug 31 13:17:44 CDT 2016


Fixes bug https://bugs.winehq.org/show_bug.cgi?id=40953

Signed-off-by: Bruno Jesus <00cpxxx at gmail.com>
---
 dlls/xinput1_3/tests/xinput.c   | 79 ++++++++++++++++++++++++++++-------------
 dlls/xinput1_3/xinput1_3.spec   |  1 +
 dlls/xinput1_3/xinput1_3_main.c | 15 ++++++++
 include/xinput.h                | 18 ++++++++++
 4 files changed, 89 insertions(+), 24 deletions(-)

diff --git a/dlls/xinput1_3/tests/xinput.c b/dlls/xinput1_3/tests/xinput.c
index 2a07f2d..5261425 100644
--- a/dlls/xinput1_3/tests/xinput.c
+++ b/dlls/xinput1_3/tests/xinput.c
@@ -24,6 +24,7 @@
 #include "wine/test.h"
 
 static DWORD (WINAPI *pXInputGetState)(DWORD, XINPUT_STATE*);
+static DWORD (WINAPI *pXInputGetStateEx)(DWORD, XINPUT_STATE_EX*);
 static DWORD (WINAPI *pXInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
 static DWORD (WINAPI *pXInputSetState)(DWORD, XINPUT_VIBRATION*);
 static void  (WINAPI *pXInputEnable)(BOOL);
@@ -62,41 +63,63 @@ static void test_set_state(void)
 
 static void test_get_state(void)
 {
-
-    XINPUT_STATE controllerState;
-    DWORD controllerNum;
+    union
+    {
+        XINPUT_STATE state;
+        XINPUT_STATE_EX state_ex;
+    } xinput;
+    DWORD controllerNum, i;
     DWORD result;
 
-    for(controllerNum=0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
+    for (i = 0; i < (pXInputGetStateEx ? 2 : 1); i++)
     {
-        ZeroMemory(&controllerState, sizeof(XINPUT_STATE));
+        for (controllerNum = 0; controllerNum < XUSER_MAX_COUNT; controllerNum++)
+        {
+            ZeroMemory(&xinput, sizeof(xinput));
 
-        result = pXInputGetState(controllerNum, &controllerState);
-        ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED, "XInputGetState failed with (%d)\n", result);
+            if (i == 0)
+                result = pXInputGetState(controllerNum, &xinput.state);
+            else
+                result = pXInputGetStateEx(controllerNum, &xinput.state_ex);
+            ok(result == ERROR_SUCCESS || result == ERROR_DEVICE_NOT_CONNECTED,
+               "%s failed with (%d)\n", i == 0 ? "XInputGetState" : "XInputGetStateEx", result);
+
+            if (ERROR_DEVICE_NOT_CONNECTED == result)
+            {
+                skip("Controller %d is not connected\n", controllerNum);
+                continue;
+            }
 
-        if (ERROR_DEVICE_NOT_CONNECTED == result)
-        {
-            skip("Controller %d is not connected\n", controllerNum);
-        }
-        else
-        {
             trace("-- Results for controller %d --\n", controllerNum);
-            trace("XInputGetState: %d\n", result);
-            trace("State->dwPacketNumber: %d\n", controllerState.dwPacketNumber);
+            if (i == 0)
+                trace("XInputGetState: %d\n", result);
+            else
+                trace("XInputGetStateEx: %d\n", result);
+            trace("State->dwPacketNumber: %d\n", xinput.state.dwPacketNumber);
             trace("Gamepad Variables --\n");
-            trace("Gamepad.wButtons: %#x\n", controllerState.Gamepad.wButtons);
-            trace("Gamepad.bLeftTrigger: 0x%08x\n", controllerState.Gamepad.bLeftTrigger);
-            trace("Gamepad.bRightTrigger: 0x%08x\n", controllerState.Gamepad.bRightTrigger);
-            trace("Gamepad.sThumbLX: %d\n", controllerState.Gamepad.sThumbLX);
-            trace("Gamepad.sThumbLY: %d\n", controllerState.Gamepad.sThumbLY);
-            trace("Gamepad.sThumbRX: %d\n", controllerState.Gamepad.sThumbRX);
-            trace("Gamepad.sThumbRY: %d\n", controllerState.Gamepad.sThumbRY);
+            trace("Gamepad.wButtons: %#x\n", xinput.state.Gamepad.wButtons);
+            trace("Gamepad.bLeftTrigger: 0x%08x\n", xinput.state.Gamepad.bLeftTrigger);
+            trace("Gamepad.bRightTrigger: 0x%08x\n", xinput.state.Gamepad.bRightTrigger);
+            trace("Gamepad.sThumbLX: %d\n", xinput.state.Gamepad.sThumbLX);
+            trace("Gamepad.sThumbLY: %d\n", xinput.state.Gamepad.sThumbLY);
+            trace("Gamepad.sThumbRX: %d\n", xinput.state.Gamepad.sThumbRX);
+            trace("Gamepad.sThumbRY: %d\n", xinput.state.Gamepad.sThumbRY);
         }
     }
 
-    ZeroMemory(&controllerState, sizeof(XINPUT_STATE));
-    result = pXInputGetState(XUSER_MAX_COUNT+1, &controllerState);
+    result = pXInputGetState(XUSER_MAX_COUNT, &xinput.state);
+    ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result);
+
+    result = pXInputGetState(XUSER_MAX_COUNT+1, &xinput.state);
     ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result);
+    if (pXInputGetStateEx)
+    {
+        result = pXInputGetStateEx(XUSER_MAX_COUNT, &xinput.state_ex);
+        ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result);
+
+        result = pXInputGetStateEx(XUSER_MAX_COUNT+1, &xinput.state_ex);
+        ok(result == ERROR_BAD_ARGUMENTS, "XInputGetState returned (%d)\n", result);
+    }
 }
 
 static void test_get_keystroke(void)
@@ -196,6 +219,7 @@ static void test_get_batteryinformation(void)
 START_TEST(xinput)
 {
     HMODULE hXinput;
+    void *pXInputGetStateEx_Ordinal;
     hXinput = LoadLibraryA( "xinput1_3.dll" );
 
     if (!hXinput)
@@ -207,11 +231,18 @@ START_TEST(xinput)
     pXInputEnable = (void*)GetProcAddress(hXinput, "XInputEnable");
     pXInputSetState = (void*)GetProcAddress(hXinput, "XInputSetState");
     pXInputGetState = (void*)GetProcAddress(hXinput, "XInputGetState");
+    pXInputGetStateEx = (void*)GetProcAddress(hXinput, "XInputGetStateEx"); /* Win >= 8 */
+    pXInputGetStateEx_Ordinal = (void*)GetProcAddress(hXinput, (LPCSTR) 100);
     pXInputGetKeystroke = (void*)GetProcAddress(hXinput, "XInputGetKeystroke");
     pXInputGetCapabilities = (void*)GetProcAddress(hXinput, "XInputGetCapabilities");
     pXInputGetDSoundAudioDeviceGuids = (void*)GetProcAddress(hXinput, "XInputGetDSoundAudioDeviceGuids");
     pXInputGetBatteryInformation = (void*)GetProcAddress(hXinput, "XInputGetBatteryInformation");
 
+    if (pXInputGetStateEx_Ordinal)
+        ok (pXInputGetStateEx_Ordinal == pXInputGetStateEx, "XInputGetStateEx in the wrong ordinal\n");
+    else
+        ok (broken(1), "XInputGetStateEx not found in this dll version\n");
+
     test_set_state();
     test_get_state();
     test_get_keystroke();
diff --git a/dlls/xinput1_3/xinput1_3.spec b/dlls/xinput1_3/xinput1_3.spec
index 67805d1..0023016 100644
--- a/dlls/xinput1_3/xinput1_3.spec
+++ b/dlls/xinput1_3/xinput1_3.spec
@@ -6,3 +6,4 @@
 6 stdcall XInputGetDSoundAudioDeviceGuids(long ptr ptr)
 7 stdcall XInputGetBatteryInformation(long long ptr)
 8 stdcall XInputGetKeystroke(long long ptr)
+100 stdcall XInputGetStateEx(long ptr)
diff --git a/dlls/xinput1_3/xinput1_3_main.c b/dlls/xinput1_3/xinput1_3_main.c
index a088913..227ab7a 100644
--- a/dlls/xinput1_3/xinput1_3_main.c
+++ b/dlls/xinput1_3/xinput1_3_main.c
@@ -85,6 +85,21 @@ DWORD WINAPI DECLSPEC_HOTPATCH XInputGetState(DWORD index, XINPUT_STATE* state)
     return ERROR_NOT_SUPPORTED;
 }
 
+DWORD WINAPI DECLSPEC_HOTPATCH XInputGetStateEx(DWORD index, XINPUT_STATE_EX* state_ex)
+{
+    static int warn_once;
+
+    if (!warn_once++)
+        FIXME("(index %u, state %p) Stub!\n", index, state_ex);
+
+    if (index >= XUSER_MAX_COUNT)
+        return ERROR_BAD_ARGUMENTS;
+    if (!controllers[index].connected)
+        return ERROR_DEVICE_NOT_CONNECTED;
+
+    return ERROR_NOT_SUPPORTED;
+}
+
 DWORD WINAPI XInputGetKeystroke(DWORD index, DWORD reserved, PXINPUT_KEYSTROKE keystroke)
 {
     FIXME("(index %u, reserved %u, keystroke %p) Stub!\n", index, reserved, keystroke);
diff --git a/include/xinput.h b/include/xinput.h
index 98d23a3..ccdc023 100644
--- a/include/xinput.h
+++ b/include/xinput.h
@@ -170,11 +170,27 @@ typedef struct _XINPUT_GAMEPAD {
     SHORT sThumbRY;
 } XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
 
+typedef struct _XINPUT_GAMEPAD_EX {
+    WORD wButtons;
+    BYTE bLeftTrigger;
+    BYTE bRightTrigger;
+    SHORT sThumbLX;
+    SHORT sThumbLY;
+    SHORT sThumbRX;
+    SHORT sThumbRY;
+    DWORD dwPaddingReserved;
+} XINPUT_GAMEPAD_EX, *PXINPUT_GAMEPAD_EX;
+
 typedef struct _XINPUT_STATE {
     DWORD dwPacketNumber;
     XINPUT_GAMEPAD Gamepad;
 } XINPUT_STATE, *PXINPUT_STATE;
 
+typedef struct _XINPUT_STATE_EX {
+    DWORD dwPacketNumber;
+    XINPUT_GAMEPAD_EX Gamepad;
+} XINPUT_STATE_EX, *PXINPUT_STATE_EX;
+
 /*
  * Defines the structure of how much vibration is set on both the
  * right and left motors in a joystick. If you're not using a 360
@@ -232,6 +248,8 @@ DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
 DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
 DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
 
+DWORD WINAPI XInputGetStateEx(DWORD, XINPUT_STATE_EX*);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.9.3




More information about the wine-patches mailing list