Exemple #1
0
static void test_action_mapping(void)
{
    HRESULT hr;
    HINSTANCE hinst = GetModuleHandleA(NULL);
    IDirectInput8A *pDI = NULL;
    DIACTIONFORMATA af;
    DIPROPSTRING dps;
    struct enum_data data =  {pDI, &af, NULL, NULL, NULL, 0};
    HWND hwnd;

    hr = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER, &IID_IDirectInput8A, (LPVOID*)&pDI);
    if (hr == DIERR_OLDDIRECTINPUTVERSION ||
        hr == DIERR_BETADIRECTINPUTVERSION ||
        hr == REGDB_E_CLASSNOTREG)
    {
        win_skip("ActionMapping requires dinput8\n");
        return;
    }
    ok(SUCCEEDED(hr), "DirectInput8 Create failed: hr=%08x\n", hr);
    if (FAILED(hr)) return;

    hr = IDirectInput8_Initialize(pDI,hinst, DIRECTINPUT_VERSION);
    if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_BETADIRECTINPUTVERSION)
    {
        win_skip("ActionMapping requires dinput8\n");
        return;
    }
    ok(SUCCEEDED(hr), "DirectInput8 Initialize failed: hr=%08x\n", hr);
    if (FAILED(hr)) return;

    memset (&af, 0, sizeof(af));
    af.dwSize = sizeof(af);
    af.dwActionSize = sizeof(DIACTIONA);
    af.dwDataSize = 4 * ARRAY_SIZE(actionMapping);
    af.dwNumActions = ARRAY_SIZE(actionMapping);
    af.rgoAction = actionMapping;
    af.guidActionMap = ACTION_MAPPING_GUID;
    af.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
    af.dwBufferSize = 32;

    /* This enumeration builds and sets the action map for all devices */
    data.pDI = pDI;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, 0, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);

    /* Repeat tests with a non NULL user */
    data.username = "******";
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &af, enumeration_callback, &data, DIEDBSFL_ATTACHEDONLY);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);

    hwnd = CreateWindowExA(WS_EX_TOPMOST, "static", "dinput",
            WS_POPUP | WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, NULL, NULL);
    ok(hwnd != NULL, "failed to create window\n");
    SetCursorPos(50, 50);

    if (data.keyboard != NULL)
    {
        /* Test keyboard BuildActionMap */
        test_build_action_map(data.keyboard, data.lpdiaf, DITEST_KEYBOARDSPACE, DIDFT_PSHBUTTON, DIK_SPACE);
        /* Test keyboard input */
        test_device_input(data.keyboard, INPUT_KEYBOARD, VK_SPACE, 2);

        /* Test BuildActionMap with no suitable actions for a device */
        IDirectInputDevice_Unacquire(data.keyboard);
        af.dwDataSize = 4 * DITEST_KEYBOARDSPACE;
        af.dwNumActions = DITEST_KEYBOARDSPACE;

        hr = IDirectInputDevice8_BuildActionMap(data.keyboard, data.lpdiaf, NULL, DIDBAM_HWDEFAULTS);
        ok (hr == DI_NOEFFECT, "BuildActionMap should have no effect with no actions hr=%08x\n", hr);

        hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, 0);
        ok (hr == DI_NOEFFECT, "SetActionMap should have no effect with no actions to map hr=%08x\n", hr);

        af.dwDataSize = 4 * ARRAY_SIZE(actionMapping);
        af.dwNumActions = ARRAY_SIZE(actionMapping);

        /* test DIDSAM_NOUSER */
        dps.diph.dwSize = sizeof(dps);
        dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
        dps.diph.dwObj = 0;
        dps.diph.dwHow = DIPH_DEVICE;
        dps.wsz[0] = '\0';

        hr = IDirectInputDevice_GetProperty(data.keyboard, DIPROP_USERNAME, &dps.diph);
        ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
        ok (dps.wsz[0] != 0, "Expected any username, got=%s\n", wine_dbgstr_w(dps.wsz));

        hr = IDirectInputDevice8_SetActionMap(data.keyboard, data.lpdiaf, NULL, DIDSAM_NOUSER);
        ok (SUCCEEDED(hr), "SetActionMap failed hr=%08x\n", hr);

        dps.diph.dwSize = sizeof(dps);
        dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
        dps.diph.dwObj = 0;
        dps.diph.dwHow = DIPH_DEVICE;
        dps.wsz[0] = '\0';

        hr = IDirectInputDevice_GetProperty(data.keyboard, DIPROP_USERNAME, &dps.diph);
        ok (SUCCEEDED(hr), "GetProperty failed hr=%08x\n", hr);
        ok (dps.wsz[0] == 0, "Expected empty username, got=%s\n", wine_dbgstr_w(dps.wsz));
    }

    if (data.mouse != NULL)
    {
        /* Test mouse BuildActionMap */
        test_build_action_map(data.mouse, data.lpdiaf, DITEST_MOUSEBUTTON0, DIDFT_PSHBUTTON, 0x03);
        test_build_action_map(data.mouse, data.lpdiaf, DITEST_YAXIS, DIDFT_RELAXIS, 0x01);

        test_device_input(data.mouse, INPUT_MOUSE, MOUSEEVENTF_LEFTDOWN, 3);
    }

    DestroyWindow(hwnd);
}
Exemple #2
0
static void test_EnumDevicesBySemantics(void)
{
    IDirectInput8A *pDI;
    HRESULT hr;
    DIACTIONFORMATA diaf;
    const GUID ACTION_MAPPING_GUID = { 0x1, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
    struct enum_semantics_test data = { 0, 0, FALSE, FALSE, &diaf, NULL };
    int device_total = 0;

    hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, &IID_IDirectInput8A, (void **)&pDI, NULL);
    if (FAILED(hr))
    {
        win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
        return;
    }

    memset (&diaf, 0, sizeof(diaf));
    diaf.dwSize = sizeof(diaf);
    diaf.dwActionSize = sizeof(DIACTIONA);
    diaf.dwNumActions = ARRAY_SIZE(actionMapping);
    diaf.dwDataSize = 4 * diaf.dwNumActions;
    diaf.rgoAction = actionMapping;
    diaf.guidActionMap = ACTION_MAPPING_GUID;
    diaf.dwGenre = 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
    diaf.dwBufferSize = 32;

    /* Test enumerating all attached and installed devices */
    data.keyboard = FALSE;
    data.mouse = FALSE;
    data.device_count = 0;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_ATTACHEDONLY);
    ok (data.device_count > 0, "EnumDevicesBySemantics did not call the callback hr=%08x\n", hr);
    ok (data.keyboard, "EnumDevicesBySemantics should enumerate the keyboard\n");
    ok (data.mouse, "EnumDevicesBySemantics should enumerate the mouse\n");

    /* Enumerate Force feedback devices. We should get no mouse nor keyboard */
    data.keyboard = FALSE;
    data.mouse = FALSE;
    data.device_count = 0;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_FORCEFEEDBACK);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
    ok (!data.keyboard, "Keyboard should not be enumerated when asking for forcefeedback\n");
    ok (!data.mouse, "Mouse should not be enumerated when asking for forcefeedback\n");

    /* Enumerate available devices. That is devices not owned by any user.
       Before setting the action map for all devices we still have them available. */
    data.device_count = 0;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_AVAILABLEDEVICES);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
    ok (data.device_count > 0, "There should be devices available before action mapping available=%d\n", data.device_count);

    /* Keep the device total */
    device_total = data.device_count;

    /* There should be no devices for any user. No device should be enumerated with DIEDBSFL_THISUSER.
       MSDN defines that all unowned devices are also enumerated but this doesn't seem to be happening. */
    data.device_count = 0;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, "Sh4d0w M4g3", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
    ok (data.device_count == 0, "No devices should be assigned for this user assigned=%d\n", data.device_count);

    /* This enumeration builds and sets the action map for all devices with a NULL username */
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, set_action_map_callback, &data, DIEDBSFL_ATTACHEDONLY);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);

    /* After a successful action mapping we should have no devices available */
    data.device_count = 0;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_AVAILABLEDEVICES);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
    ok (data.device_count == 0, "No device should be available after action mapping available=%d\n", data.device_count);

    /* Now we'll give all the devices to a specific user */
    data.username = "******";
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, set_action_map_callback, &data, DIEDBSFL_ATTACHEDONLY);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed: hr=%08x\n", hr);

    /* Testing with the default user, DIEDBSFL_THISUSER has no effect */
    data.device_count = 0;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
    ok (data.device_count == device_total, "THISUSER has no effect with NULL username owned=%d, expected=%d\n", data.device_count, device_total);

    /* Using an empty user string is the same as passing NULL, DIEDBSFL_THISUSER has no effect */
    data.device_count = 0;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, "", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
    ok (data.device_count == device_total, "THISUSER has no effect with \"\" as username owned=%d, expected=%d\n", data.device_count, device_total);

    /* Testing with a user with no ownership of the devices */
    data.device_count = 0;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, "Ninja Brian", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
    ok (data.device_count == 0, "This user should own no devices owned=%d\n", data.device_count);

    /* Sh4d0w M4g3 has ownership of all devices */
    data.device_count = 0;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, "Sh4d0w M4g3", &diaf, enum_semantics_callback, &data, DIEDBSFL_THISUSER);
    ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
    ok (data.device_count == device_total, "This user should own %d devices owned=%d\n", device_total, data.device_count);

    /* The call fails with a zeroed GUID */
    memset(&diaf.guidActionMap, 0, sizeof(GUID));
    data.device_count = 0;
    hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, NULL, 0);
    todo_wine ok(FAILED(hr), "EnumDevicesBySemantics succeeded with invalid GUID hr=%08x\n", hr);

    IDirectInput8_Release(pDI);
}