[DINPUT_WINETEST] Sync with Wine Staging 3.17. CORE-15127
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 30 Sep 2018 23:21:34 +0000 (00:21 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 30 Sep 2018 23:21:34 +0000 (00:21 +0100)
modules/rostests/winetests/dinput/device.c
modules/rostests/winetests/dinput/dinput.c
modules/rostests/winetests/dinput/joystick.c
modules/rostests/winetests/dinput/keyboard.c

index 7494024..fa9b6f1 100644 (file)
@@ -51,7 +51,7 @@ static const DIDATAFORMAT data_format = {
     sizeof(DIOBJECTDATAFORMAT),
     DIDF_ABSAXIS,
     32,
-    sizeof(obj_data_format) / sizeof(obj_data_format[0]),
+    ARRAY_SIZE(obj_data_format),
     (LPDIOBJECTDATAFORMAT)obj_data_format
 };
 
@@ -94,7 +94,7 @@ static void test_object_info(IDirectInputDeviceA *device, HWND hwnd)
     ok(cnt == cnt1, "Enum count changed from %d to %d\n", cnt, cnt1);
 
     /* Testing EnumObjects with different types of device objects */
-    for (type_index=0; type_index < sizeof(obj_types)/sizeof(obj_types[0]); type_index++)
+    for (type_index=0; type_index < ARRAY_SIZE(obj_types); type_index++)
     {
         hr = IDirectInputDevice_EnumObjects(device, enum_type_callback, &obj_types[type_index], obj_types[type_index]);
         ok(SUCCEEDED(hr), "EnumObjects() failed: %08x\n", hr);
index a5f7c0c..7e2da9f 100644 (file)
@@ -106,7 +106,7 @@ static void test_preinitialization(void)
         return;
     }
 
-    for (i = 0; i < sizeof(create_device_tests)/sizeof(create_device_tests[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(create_device_tests); i++)
     {
         if (create_device_tests[i].pdev) pDID = (void *)0xdeadbeef;
         hr = IDirectInput_CreateDevice(pDI, create_device_tests[i].rguid,
@@ -117,7 +117,7 @@ static void test_preinitialization(void)
             ok(pDID == NULL, "[%d] Output interface pointer is %p\n", i, pDID);
     }
 
-    for (i = 0; i < sizeof(enum_devices_tests)/sizeof(enum_devices_tests[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(enum_devices_tests); i++)
     {
         hr = IDirectInput_EnumDevices(pDI, enum_devices_tests[i].dwDevType,
                                            enum_devices_tests[i].lpCallback,
@@ -217,7 +217,7 @@ static void test_DirectInputCreateEx(void)
         return;
     }
 
-    for (i = 0; i < sizeof(invalid_param_list)/sizeof(invalid_param_list[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(invalid_param_list); i++)
     {
         if (invalid_param_list[i].ppdi) pUnk = (void *)0xdeadbeef;
         hr = pDirectInputCreateEx(invalid_param_list[i].hinst ? hInstance : NULL,
@@ -230,7 +230,7 @@ static void test_DirectInputCreateEx(void)
             ok(pUnk == invalid_param_list[i].expected_ppdi, "[%d] Output interface pointer is %p\n", i, pUnk);
     }
 
-    for (i = 0; i < sizeof(no_interface_list)/sizeof(no_interface_list[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(no_interface_list); i++)
     {
         pUnk = (void *)0xdeadbeef;
         hr = pDirectInputCreateEx(hInstance, DIRECTINPUT_VERSION, no_interface_list[i], (void **)&pUnk, NULL);
@@ -238,7 +238,7 @@ static void test_DirectInputCreateEx(void)
         ok(pUnk == (void *)0xdeadbeef, "[%d] Output interface pointer is %p\n", i, pUnk);
     }
 
-    for (i = 0; i < sizeof(iid_list)/sizeof(iid_list[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(iid_list); i++)
     {
         pUnk = NULL;
         hr = pDirectInputCreateEx(hInstance, DIRECTINPUT_VERSION, iid_list[i], (void **)&pUnk, NULL);
@@ -249,9 +249,9 @@ static void test_DirectInputCreateEx(void)
     }
 
     /* Examine combinations of requested interfaces and version numbers. */
-    for (i = 0; i < sizeof(directinput_version_list)/sizeof(directinput_version_list[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(directinput_version_list); i++)
     {
-        for (j = 0; j < sizeof(iid_list)/sizeof(iid_list[0]); j++)
+        for (j = 0; j < ARRAY_SIZE(iid_list); j++)
         {
             pUnk = NULL;
             hr = pDirectInputCreateEx(hInstance, directinput_version_list[i], iid_list[j], (void **)&pUnk, NULL);
@@ -311,7 +311,7 @@ static void test_QueryInterface(void)
     hr = IDirectInput_QueryInterface(pDI, &IID_IUnknown, NULL);
     ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr);
 
-    for (i = 0; i < sizeof(iid_list)/sizeof(iid_list[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(iid_list); i++)
     {
         pUnk = NULL;
         hr = IDirectInput_QueryInterface(pDI, iid_list[i], (void **)&pUnk);
@@ -320,7 +320,7 @@ static void test_QueryInterface(void)
         if (pUnk) IUnknown_Release(pUnk);
     }
 
-    for (i = 0; i < sizeof(no_interface_list)/sizeof(no_interface_list[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(no_interface_list); i++)
     {
         pUnk = (void *)0xdeadbeef;
         hr = IDirectInput_QueryInterface(pDI, no_interface_list[i].riid, (void **)&pUnk);
@@ -512,7 +512,7 @@ static void test_Initialize(void)
     hr = IDirectInput_Initialize(pDI, hInstance, 0xcafe);
     ok(hr == DIERR_OLDDIRECTINPUTVERSION, "IDirectInput_Initialize returned 0x%08x\n", hr);
 
-    for (i = 0; i < sizeof(directinput_version_list)/sizeof(directinput_version_list[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(directinput_version_list); i++)
     {
         hr = IDirectInput_Initialize(pDI, hInstance, directinput_version_list[i]);
         ok(hr == DI_OK, "IDirectInput_Initialize returned 0x%08x\n", hr);
index b4ffba5..69e95d0 100644 (file)
@@ -30,8 +30,6 @@
 #include "wingdi.h"
 #include "dinput.h"
 
-#define numObjects(x) (sizeof(x) / sizeof(x[0]))
-
 typedef struct tagUserData {
     IDirectInputA *pDI;
     DWORD version;
@@ -62,7 +60,7 @@ static const DIDATAFORMAT c_dfDIJoystickTest = {
     sizeof(DIOBJECTDATAFORMAT),
     DIDF_ABSAXIS,
     sizeof(DIJOYSTATE2),
-    numObjects(dfDIJoystickTest),
+    ARRAY_SIZE(dfDIJoystickTest),
     (LPDIOBJECTDATAFORMAT)dfDIJoystickTest
 };
 
@@ -178,7 +176,7 @@ static const struct effect_id
 static const struct effect_id* effect_from_guid(const GUID *guid)
 {
     unsigned int i;
-    for (i = 0; i < sizeof(effect_conversion) / sizeof(effect_conversion[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(effect_conversion); i++)
         if (IsEqualGUID(guid, effect_conversion[i].guid))
             return &effect_conversion[i];
     return NULL;
@@ -504,7 +502,7 @@ static BOOL CALLBACK EnumJoysticks(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
     effect_data.eff.dwDuration      = INFINITE;
     effect_data.eff.dwGain          = DI_FFNOMINALMAX;
     effect_data.eff.dwTriggerButton = DIEB_NOTRIGGER;
-    effect_data.eff.cAxes           = sizeof(axes) / sizeof(axes[0]);
+    effect_data.eff.cAxes           = ARRAY_SIZE(axes);
     effect_data.eff.rgdwAxes        = axes;
     effect_data.eff.rglDirection    = direction;
 
index 576a94c..8ee22fa 100644 (file)
@@ -101,7 +101,7 @@ static void acquire_tests(IDirectInputA *pDI, HWND hwnd)
     df.dwObjSize = sizeof( DIOBJECTDATAFORMAT );
     df.dwFlags = DIDF_RELAXIS;
     df.dwDataSize = sizeof( custom_state );
-    df.dwNumObjs = sizeof( dodf )/sizeof( dodf[0] );
+    df.dwNumObjs = ARRAY_SIZE(dodf);
     df.rgodf = dodf;
 
     hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKeyboard, NULL);
@@ -139,7 +139,7 @@ static void acquire_tests(IDirectInputA *pDI, HWND hwnd)
 
     memset(custom_state, 0x56, sizeof(custom_state));
     IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(custom_state), custom_state);
-    for (i = 0; i < sizeof(custom_state) / sizeof(custom_state[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(custom_state); i++)
         ok(custom_state[i] == 0, "Should be zeroed, got 0x%08x\n", custom_state[i]);
 
     /* simulate some keyboard input */
@@ -160,7 +160,7 @@ static void acquire_tests(IDirectInputA *pDI, HWND hwnd)
         ok(SUCCEEDED(hr), "IDirectInputDevice_Acquire() failed: %08x\n", hr);
         hr = IDirectInputDevice_GetDeviceState(pKeyboard, sizeof(custom_state), custom_state);
         ok(SUCCEEDED(hr), "IDirectInputDevice_GetDeviceState failed: %08x\n", hr);
-        for (i = 0; i < sizeof(custom_state) / sizeof(custom_state[0]); i++)
+        for (i = 0; i < ARRAY_SIZE(custom_state); i++)
             ok(custom_state[i] == 0, "Should be zeroed, got 0x%08x\n", custom_state[i]);
     }
     keybd_event('Q', 0, KEYEVENTF_KEYUP, 0);
@@ -263,6 +263,7 @@ static void test_capabilities(IDirectInputA *pDI, HWND hwnd)
     HRESULT hr;
     IDirectInputDeviceA *pKeyboard = NULL;
     DIDEVCAPS caps;
+    int kbd_type, kbd_subtype, dev_subtype;
 
     hr = IDirectInput_CreateDevice(pDI, &GUID_SysKeyboard, &pKeyboard, NULL);
     ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
@@ -273,10 +274,23 @@ static void test_capabilities(IDirectInputA *pDI, HWND hwnd)
 
     ok (SUCCEEDED(hr), "GetCapabilities failed: 0x%08x\n", hr);
     ok (caps.dwFlags & DIDC_ATTACHED, "GetCapabilities dwFlags: 0x%08x\n", caps.dwFlags);
-    ok (LOWORD(LOBYTE(caps.dwDevType)) == DIDEVTYPE_KEYBOARD,
+    ok (GET_DIDEVICE_TYPE(caps.dwDevType) == DIDEVTYPE_KEYBOARD,
         "GetCapabilities invalid device type for dwDevType: 0x%08x\n", caps.dwDevType);
-    ok (LOWORD(HIBYTE(caps.dwDevType)) != DIDEVTYPEKEYBOARD_UNKNOWN,
-        "GetCapabilities invalid device subtype for dwDevType: 0x%08x\n", caps.dwDevType);
+    kbd_type = GetKeyboardType(0);
+    kbd_subtype = GetKeyboardType(1);
+    dev_subtype = GET_DIDEVICE_SUBTYPE(caps.dwDevType);
+    if (kbd_type == 4 || (kbd_type == 7 && kbd_subtype == 0))
+        ok (dev_subtype == DIDEVTYPEKEYBOARD_PCENH,
+            "GetCapabilities invalid device subtype for dwDevType: 0x%08x (%04x:%04x)\n",
+            caps.dwDevType, kbd_type, kbd_subtype);
+    else if (kbd_type == 7 && kbd_subtype == 2)
+        ok (dev_subtype == DIDEVTYPEKEYBOARD_JAPAN106,
+            "GetCapabilities invalid device subtype for dwDevType: 0x%08x (%04x:%04x)\n",
+            caps.dwDevType, kbd_type, kbd_subtype);
+    else
+        ok (dev_subtype != DIDEVTYPEKEYBOARD_UNKNOWN,
+            "GetCapabilities invalid device subtype for dwDevType: 0x%08x (%04x:%04x)\n",
+            caps.dwDevType, kbd_type, kbd_subtype);
 
     IUnknown_Release(pKeyboard);
 }
@@ -285,38 +299,52 @@ static void test_dik_codes(IDirectInputA *dI, HWND hwnd, LANGID langid)
 {
     static const struct key2dik
     {
-        BYTE key, dik;
+        BYTE key, dik, todo;
     } key2dik_en[] =
     {
-        {'Q',DIK_Q}, {'W',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Y',DIK_Y}
+        {'Q',DIK_Q}, {'W',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Y',DIK_Y},
+        {'[',DIK_LBRACKET}, {']',DIK_RBRACKET}, {'.',DIK_PERIOD}
     },
     key2dik_fr[] =
     {
-        {'A',DIK_Q}, {'Z',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Y',DIK_Y}
+        {'A',DIK_Q}, {'Z',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Y',DIK_Y},
+        {'^',DIK_LBRACKET}, {'$',DIK_RBRACKET}, {':',DIK_PERIOD}
     },
     key2dik_de[] =
     {
-        {'Q',DIK_Q}, {'W',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Z',DIK_Y}
+        {'Q',DIK_Q}, {'W',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Z',DIK_Y},
+        {'\xfc',DIK_LBRACKET,1}, {'+',DIK_RBRACKET}, {'.',DIK_PERIOD}
+    },
+    key2dik_ja[] =
+    {
+        {'Q',DIK_Q}, {'W',DIK_W}, {'E',DIK_E}, {'R',DIK_R}, {'T',DIK_T}, {'Y',DIK_Y},
+        {'@',DIK_AT}, {']',DIK_RBRACKET}, {'.',DIK_PERIOD}
     };
     static const struct
     {
         LANGID langid;
         const struct key2dik *map;
+        DWORD type;
     } expected[] =
     {
-        { MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), key2dik_en },
-        { MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH), key2dik_fr },
-        { MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), key2dik_de },
-        { MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), key2dik_en }
+        { MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
+          key2dik_en, DIDEVTYPEKEYBOARD_PCENH },
+        { MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH),
+          key2dik_fr, DIDEVTYPEKEYBOARD_PCENH },
+        { MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN),
+          key2dik_de, DIDEVTYPEKEYBOARD_PCENH },
+        { MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN),
+          key2dik_ja, DIDEVTYPEKEYBOARD_JAPAN106 }
     };
     const struct key2dik *map = NULL;
     UINT i;
     HRESULT hr;
     IDirectInputDeviceA *device;
+    DIDEVCAPS caps;
     HKL hkl, hkl_orig;
     MSG msg;
 
-    for (i = 0; i < sizeof(expected)/sizeof(expected[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(expected); i++)
     {
         if (expected[i].langid == langid)
         {
@@ -333,6 +361,14 @@ static void test_dik_codes(IDirectInputA *dI, HWND hwnd, LANGID langid)
     ok(hr == S_OK, "SetDataFormat() failed: %08x\n", hr);
     hr = IDirectInputDevice_Acquire(device);
     ok(hr == S_OK, "Acquire() failed: %08x\n", hr);
+    caps.dwSize = sizeof( caps );
+    hr = IDirectInputDevice_GetCapabilities(device, &caps);
+    ok(hr == S_OK, "GetDeviceInstance() failed: %08x\n", hr);
+    if (expected[i].type != GET_DIDEVICE_SUBTYPE(caps.dwDevType)) {
+        skip("Keyboard type(%u) doesn't match for lang %04x\n",
+             GET_DIDEVICE_SUBTYPE(caps.dwDevType), langid);
+        goto fail;
+    }
 
     hkl = activate_keyboard_layout(langid, &hkl_orig);
     if (!hkl) goto fail;
@@ -340,42 +376,51 @@ static void test_dik_codes(IDirectInputA *dI, HWND hwnd, LANGID langid)
     SetFocus(hwnd);
     pump_messages();
 
-    for (i = 0; i < sizeof(key2dik_en)/sizeof(key2dik_en[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(key2dik_en); i++)
     {
         BYTE kbd_state[256];
         UINT n;
+        WORD vkey, scan;
         INPUT in;
 
-        n = MapVirtualKeyA(map[i].key, MAPVK_VK_TO_CHAR);
-        ok(n == map[i].key, "%u: expected %c, got %c\n", i, map[i].key, n);
-        n = MapVirtualKeyA(map[i].key, MAPVK_VK_TO_VSC);
-        ok(n == map[i].dik, "%u: expected %02x, got %02x\n", i, map[i].dik, n);
+        n = VkKeyScanExW(map[i].key, hkl);
+        todo_wine_if(map[i].todo & 1)
+        ok(n != 0xffff, "%u: failed to get virtual key value for %c(%02x)\n", i, map[i].key, map[i].key);
+        vkey = LOBYTE(n);
+        n = MapVirtualKeyExA(vkey, MAPVK_VK_TO_CHAR, hkl) & 0xff;
+        todo_wine_if(map[i].todo & 1)
+        ok(n == map[i].key, "%u: expected %c(%02x), got %c(%02x)\n", i, map[i].key, map[i].key, n, n);
+        scan = MapVirtualKeyExA(vkey, MAPVK_VK_TO_VSC, hkl);
+        /* scan codes match the DIK_ codes on US keyboard.
+           however, it isn't true for symbols and punctuations in other layouts. */
+        if (isalpha(map[i].key) || langid == MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT))
+            ok(scan == map[i].dik, "%u: expected %02x, got %02x\n", i, map[i].dik, n);
+        else
+            todo_wine_if(map[i].todo & 1)
+            ok(scan, "%u: fail to get scan code value, expected %02x (vkey=%02x)\n",
+               i, map[i].dik, vkey);
 
         in.type = INPUT_KEYBOARD;
-        U(in).ki.wVk = map[i].key;
-        U(in).ki.wScan = map[i].dik; /* scan codes match the DIK_ codes */
+        U(in).ki.wVk = vkey;
+        U(in).ki.wScan = scan;
         U(in).ki.dwFlags = 0;
         U(in).ki.dwExtraInfo = 0;
         U(in).ki.time = 0;
         n = SendInput(1, &in, sizeof(in));
         ok(n == 1, "got %u\n", n);
 
-        if (!PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
-        {
-            win_skip("failed to queue keyboard event\n");
-            break;
-        }
-        ok(msg.message == WM_KEYDOWN || broken(msg.message != WM_KEYDOWN), "expected WM_KEYDOWN, got %04x\n", msg.message);
-        /* this never happens on real hardware but tesbot VMs seem to have timing issues */
-        if (msg.message != WM_KEYDOWN)
+        if (!PeekMessageA(&msg, hwnd, 0, 0, PM_REMOVE))
         {
             win_skip("failed to queue keyboard event\n");
             break;
         }
+        ok(msg.message == WM_KEYDOWN, "expected WM_KEYDOWN, got %04x\n", msg.message);
         DispatchMessageA(&msg);
 
-        trace("keydown wParam: %#lx (%c) lParam: %#lx, MapVirtualKey(MAPVK_VK_TO_CHAR) = %c\n",
-              msg.wParam, LOWORD(msg.wParam), msg.lParam, MapVirtualKeyA(msg.wParam, MAPVK_VK_TO_CHAR));
+        n = MapVirtualKeyExA(msg.wParam, MAPVK_VK_TO_CHAR, hkl);
+        trace("keydown wParam: %#08lx (%c) lParam: %#08lx, MapVirtualKey(MAPVK_VK_TO_CHAR) = %c\n",
+              msg.wParam, isprint(LOWORD(msg.wParam)) ? LOWORD(msg.wParam) : '?',
+              msg.lParam, isprint(n) ? n : '?');
 
         pump_messages();
 
@@ -389,6 +434,7 @@ static void test_dik_codes(IDirectInputA *dI, HWND hwnd, LANGID langid)
             break;
         }
 
+        todo_wine_if(map[i].todo)
         ok(kbd_state[map[i].dik] == 0x80, "DI key %#x has state %#x\n", map[i].dik, kbd_state[map[i].dik]);
 
         U(in).ki.dwFlags = KEYEVENTF_KEYUP;
@@ -448,7 +494,7 @@ static void keyboard_tests(DWORD version)
 
 START_TEST(keyboard)
 {
-    pDirectInputCreateA = (void *)GetProcAddress(LoadLibraryA("dinput.dll"), "DirectInputCreateA");
+    pDirectInputCreateA = (void *)GetProcAddress(GetModuleHandleA("dinput.dll"), "DirectInputCreateA");
 
     CoInitialize(NULL);