Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v2: Remove the HID usage to GUID mapping from PATCH 2, as it's outdated and probably better to keep HID code in the HID joystick only. It was an optimisation to avoid comparing GUIDs but probably not worth it.
dlls/dinput8/tests/device.c | 810 +++++++++++++++++++++++++++++++++++- 1 file changed, 807 insertions(+), 3 deletions(-)
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 17deed193dd..6571d1b26b2 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -19,12 +19,22 @@
#define DIRECTINPUT_VERSION 0x0800
-#define COBJMACROS -#include <windows.h> +#include <stdarg.h> +#include <stddef.h>
-#include "wine/test.h" +#include "ntstatus.h" +#define WIN32_NO_STATUS #include "windef.h" +#include "winbase.h" + +#define COBJMACROS #include "dinput.h" +#include "hidusage.h" + +#include "wine/test.h" + +static HINSTANCE instance; +static BOOL localized; /* object names get translated */
struct enum_data { IDirectInput8A *pDI; @@ -1011,10 +1021,804 @@ static void test_appdata_property(void) IDirectInput_Release(pDI); }
+#define check_member_( file, line, val, exp, fmt, member ) \ + ok_( file, line )((val).member == (exp).member, "got " #member " " fmt ", expected " fmt "\n", \ + (val).member, (exp).member) +#define check_member( val, exp, fmt, member ) \ + check_member_( __FILE__, __LINE__, val, exp, fmt, member ) + +#define check_member_guid_( file, line, val, exp, member ) \ + ok_( file, line )(IsEqualGUID( &(val).member, &(exp).member ), "got " #member " %s, expected %s\n", \ + debugstr_guid( &(val).member ), debugstr_guid( &(exp).member )) +#define check_member_guid( val, exp, member ) \ + check_member_guid_( __FILE__, __LINE__, val, exp, member ) + +#define check_member_wstr_( file, line, val, exp, member ) \ + ok_( file, line )(!wcscmp( (val).member, (exp).member ), "got " #member " %s, expected %s\n", \ + debugstr_w((val).member), debugstr_w((exp).member)) +#define check_member_wstr( val, exp, member ) \ + check_member_wstr_( __FILE__, __LINE__, val, exp, member ) + +struct check_objects_todos +{ + BOOL offset; + BOOL type; + BOOL name; +}; + +struct check_objects_params +{ + UINT index; + UINT stop_count; + UINT expect_count; + const DIDEVICEOBJECTINSTANCEW *expect_objs; + const struct check_objects_todos *todo_objs; + BOOL todo_extra; +}; + +static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *args ) +{ + struct check_objects_params *params = args; + const DIDEVICEOBJECTINSTANCEW *exp = params->expect_objs + params->index; + const struct check_objects_todos *todo = params->todo_objs + params->index; + + todo_wine_if( params->todo_extra && params->index >= params->expect_count ) + ok( params->index < params->expect_count, "unexpected extra object\n" ); + if (params->index >= params->expect_count) return DIENUM_CONTINUE; + + winetest_push_context( "obj[%d]", params->index ); + + todo_wine + check_member( *obj, *exp, "%u", dwSize ); + check_member_guid( *obj, *exp, guidType ); + todo_wine_if( todo->offset ) + check_member( *obj, *exp, "%#x", dwOfs ); + todo_wine_if( todo->type ) + check_member( *obj, *exp, "%#x", dwType ); + check_member( *obj, *exp, "%#x", dwFlags ); + if (!localized) todo_wine_if( todo->name ) check_member_wstr( *obj, *exp, tszName ); + check_member( *obj, *exp, "%u", dwFFMaxForce ); + check_member( *obj, *exp, "%u", dwFFForceResolution ); + check_member( *obj, *exp, "%u", wCollectionNumber ); + check_member( *obj, *exp, "%u", wDesignatorIndex ); + check_member( *obj, *exp, "%#04x", wUsagePage ); + check_member( *obj, *exp, "%#04x", wUsage ); + check_member( *obj, *exp, "%#04x", dwDimension ); + check_member( *obj, *exp, "%#04x", wExponent ); + check_member( *obj, *exp, "%u", wReportId ); + + winetest_pop_context(); + + params->index++; + if (params->stop_count && params->index == params->stop_count) return DIENUM_STOP; + return DIENUM_CONTINUE; +} + +static BOOL CALLBACK check_object_count( const DIDEVICEOBJECTINSTANCEW *obj, void *args ) +{ + DWORD *count = args; + *count = *count + 1; + return DIENUM_CONTINUE; +} + +static void test_mouse_info(void) +{ + static const DIDEVCAPS expect_caps = + { + .dwSize = sizeof(DIDEVCAPS), + .dwFlags = DIDC_ATTACHED | DIDC_EMULATED, + .dwDevType = (DI8DEVTYPEMOUSE_UNKNOWN << 8) | DI8DEVTYPE_MOUSE, + .dwAxes = 3, + .dwButtons = 5, + }; + const DIDEVICEINSTANCEW expect_devinst = + { + .dwSize = sizeof(DIDEVICEINSTANCEW), + .guidInstance = GUID_SysMouse, + .guidProduct = GUID_SysMouse, + .dwDevType = (DI8DEVTYPEMOUSE_UNKNOWN << 8) | DI8DEVTYPE_MOUSE, + .tszInstanceName = L"Mouse", + .tszProductName = L"Mouse", + .guidFFDriver = GUID_NULL, + }; + const DIDEVICEOBJECTINSTANCEW expect_objects[] = + { + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_XAxis, + .dwOfs = 0x0, + .dwType = DIDFT_RELAXIS|DIDFT_MAKEINSTANCE(0), + .dwFlags = DIDOI_ASPECTPOSITION, + .tszName = L"X-axis", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_YAxis, + .dwOfs = 0x4, + .dwType = DIDFT_RELAXIS|DIDFT_MAKEINSTANCE(1), + .dwFlags = DIDOI_ASPECTPOSITION, + .tszName = L"Y-axis", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_ZAxis, + .dwOfs = 0x8, + .dwType = DIDFT_RELAXIS|DIDFT_MAKEINSTANCE(2), + .dwFlags = DIDOI_ASPECTPOSITION, + .tszName = L"Wheel", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = 0xc, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(3), + .tszName = L"Button 0", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = 0xd, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(4), + .tszName = L"Button 1", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = 0xe, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(5), + .tszName = L"Button 2", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = 0xf, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(6), + .tszName = L"Button 3", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = 0x10, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(7), + .tszName = L"Button 4", + }, + }; + struct check_objects_todos todo_objects[ARRAY_SIZE(expect_objects)] = + { + {.name = TRUE}, + {.name = TRUE}, + }; + struct check_objects_params check_objects_params = + { + .expect_count = ARRAY_SIZE(expect_objects), + .expect_objs = expect_objects, + .todo_objs = todo_objects, + .todo_extra = TRUE, + }; + DIPROPGUIDANDPATH prop_guid_path = + { + .diph = + { + .dwSize = sizeof(DIPROPGUIDANDPATH), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + DIPROPSTRING prop_string = + { + .diph = + { + .dwSize = sizeof(DIPROPSTRING), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + DIPROPDWORD prop_dword = + { + .diph = + { + .dwSize = sizeof(DIPROPDWORD), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + DIPROPRANGE prop_range = + { + .diph = + { + .dwSize = sizeof(DIPROPRANGE), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + DIDEVICEOBJECTINSTANCEW objinst = {0}; + DIDEVICEINSTANCEW devinst = {0}; + IDirectInputDevice8W *device; + DIDEVCAPS caps = {0}; + IDirectInput8W *di; + ULONG res, ref; + HRESULT hr; + GUID guid; + + localized = LOWORD( GetKeyboardLayout( 0 ) ) != 0x0409; + + hr = DirectInput8Create( instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W, (void **)&di, NULL ); + ok( hr == DI_OK, "DirectInput8Create returned %#x\n", hr ); + hr = IDirectInput8_CreateDevice( di, &GUID_SysMouse, &device, NULL ); + ok( hr == DI_OK, "CreateDevice returned %#x\n", hr ); + + hr = IDirectInputDevice8_Initialize( device, instance, DIRECTINPUT_VERSION, &GUID_SysMouseEm ); + ok( hr == DI_OK, "Initialize returned %#x\n", hr ); + guid = GUID_SysMouseEm; + memset( &devinst, 0, sizeof(devinst) ); + devinst.dwSize = sizeof(DIDEVICEINSTANCEW); + hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst ); + ok( hr == DI_OK, "GetDeviceInfo returned %#x\n", hr ); + ok( IsEqualGUID( &guid, &GUID_SysMouseEm ), "got %s expected %s\n", debugstr_guid( &guid ), + debugstr_guid( &GUID_SysMouseEm ) ); + + hr = IDirectInputDevice8_Initialize( device, instance, DIRECTINPUT_VERSION, &GUID_SysMouse ); + ok( hr == DI_OK, "Initialize returned %#x\n", hr ); + + memset( &devinst, 0, sizeof(devinst) ); + devinst.dwSize = sizeof(DIDEVICEINSTANCEW); + hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst ); + ok( hr == DI_OK, "GetDeviceInfo returned %#x\n", hr ); + check_member( devinst, expect_devinst, "%d", dwSize ); + check_member_guid( devinst, expect_devinst, guidInstance ); + check_member_guid( devinst, expect_devinst, guidProduct ); + todo_wine + check_member( devinst, expect_devinst, "%#x", dwDevType ); + if (!localized) check_member_wstr( devinst, expect_devinst, tszInstanceName ); + if (!localized) todo_wine check_member_wstr( devinst, expect_devinst, tszProductName ); + check_member_guid( devinst, expect_devinst, guidFFDriver ); + check_member( devinst, expect_devinst, "%04x", wUsagePage ); + check_member( devinst, expect_devinst, "%04x", wUsage ); + + caps.dwSize = sizeof(DIDEVCAPS); + hr = IDirectInputDevice8_GetCapabilities( device, &caps ); + ok( hr == DI_OK, "GetCapabilities returned %#x\n", hr ); + check_member( caps, expect_caps, "%d", dwSize ); + check_member( caps, expect_caps, "%#x", dwFlags ); + todo_wine + check_member( caps, expect_caps, "%#x", dwDevType ); + check_member( caps, expect_caps, "%d", dwAxes ); + todo_wine + check_member( caps, expect_caps, "%d", dwButtons ); + check_member( caps, expect_caps, "%d", dwPOVs ); + check_member( caps, expect_caps, "%d", dwFFSamplePeriod ); + check_member( caps, expect_caps, "%d", dwFFMinTimeResolution ); + todo_wine + check_member( caps, expect_caps, "%d", dwFirmwareRevision ); + todo_wine + check_member( caps, expect_caps, "%d", dwHardwareRevision ); + check_member( caps, expect_caps, "%d", dwFFDriverVersion ); + + prop_dword.diph.dwHow = DIPH_BYOFFSET; + prop_dword.diph.dwObj = DIMOFS_X; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); + prop_range.diph.dwHow = DIPH_BYOFFSET; + prop_range.diph.dwObj = DIMOFS_X; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); + todo_wine + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_RANGE returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_DEVICE; + prop_dword.diph.dwObj = 0; + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_AXISMODE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_AXISMODE returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == DIPROPAXISMODE_ABS, "got %u expected %u\n", prop_dword.dwData, DIPROPAXISMODE_ABS ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph ); + ok( hr == DI_OK, "GetProperty DIPROP_BUFFERSIZE returned %#x\n", hr ); + ok( prop_dword.dwData == 0, "got %#x expected %#x\n", prop_dword.dwData, 0 ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFGAIN, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_FFGAIN returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == 10000, "got %u expected %u\n", prop_dword.dwData, 10000 ); + + hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIMouse2 ); + ok( hr == DI_OK, "SetDataFormat returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_DEVICE; + prop_dword.diph.dwObj = 0; + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_AXISMODE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_AXISMODE returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == DIPROPAXISMODE_REL, "got %u expected %u\n", prop_dword.dwData, DIPROPAXISMODE_ABS ); + + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_VIDPID, &prop_dword.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_VIDPID returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GUIDANDPATH, &prop_guid_path.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_INSTANCENAME, &prop_string.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_INSTANCENAME returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_PRODUCTNAME, &prop_string.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_PRODUCTNAME returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_TYPENAME, &prop_string.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_TYPENAME returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_USERNAME, &prop_string.diph ); + ok( hr == S_FALSE, "GetProperty DIPROP_USERNAME returned %#x\n", hr ); + ok( !wcscmp( prop_string.wsz, L"" ), "got user %s\n", debugstr_w(prop_string.wsz) ); + + hr = IDirectInputDevice8_GetProperty( device, DIPROP_JOYSTICKID, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_VIDPID returned %#x\n", hr ); + + hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATION, &prop_dword.diph ); + ok( hr == DIERR_INVALIDPARAM, "GetProperty DIPROP_CALIBRATION returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_AUTOCENTER returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_FFLOAD returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_BYUSAGE; + prop_dword.diph.dwObj = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_BYOFFSET; + prop_dword.diph.dwObj = DIMOFS_X; + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph ); + ok( hr == DI_OK, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr ); + ok( prop_dword.dwData == 1, "got %d expected 1\n", prop_dword.dwData ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); + prop_range.lMin = 0xdeadbeef; + prop_range.lMax = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); + ok( hr == DI_OK, "GetProperty DIPROP_RANGE returned %#x\n", hr ); + todo_wine + ok( prop_range.lMin == DIPROPRANGE_NOMIN, "got %d expected %d\n", prop_range.lMin, DIPROPRANGE_NOMIN ); + todo_wine + ok( prop_range.lMax == DIPROPRANGE_NOMAX, "got %d expected %d\n", prop_range.lMax, DIPROPRANGE_NOMAX ); + + res = 0; + hr = IDirectInputDevice8_EnumObjects( device, check_object_count, &res, DIDFT_AXIS | DIDFT_PSHBUTTON ); + ok( hr == DI_OK, "EnumObjects returned %#x\n", hr ); + todo_wine + ok( res == 8, "got %u expected %u\n", res, 8 ); + hr = IDirectInputDevice8_EnumObjects( device, check_objects, &check_objects_params, DIDFT_ALL ); + ok( hr == DI_OK, "EnumObjects returned %#x\n", hr ); + ok( check_objects_params.index >= check_objects_params.expect_count, "missing %u objects\n", + check_objects_params.expect_count - check_objects_params.index ); + + objinst.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW); + res = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYUSAGE ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetObjectInfo returned: %#x\n", hr ); + + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, DIMOFS_Y, DIPH_BYOFFSET ); + ok( hr == DI_OK, "GetObjectInfo returned: %#x\n", hr ); + + check_member( objinst, expect_objects[1], "%u", dwSize ); + check_member_guid( objinst, expect_objects[1], guidType ); + check_member( objinst, expect_objects[1], "%#x", dwOfs ); + check_member( objinst, expect_objects[1], "%#x", dwType ); + check_member( objinst, expect_objects[1], "%#x", dwFlags ); + if (!localized) todo_wine check_member_wstr( objinst, expect_objects[1], tszName ); + check_member( objinst, expect_objects[1], "%u", dwFFMaxForce ); + check_member( objinst, expect_objects[1], "%u", dwFFForceResolution ); + check_member( objinst, expect_objects[1], "%u", wCollectionNumber ); + check_member( objinst, expect_objects[1], "%u", wDesignatorIndex ); + check_member( objinst, expect_objects[1], "%#04x", wUsagePage ); + check_member( objinst, expect_objects[1], "%#04x", wUsage ); + check_member( objinst, expect_objects[1], "%#04x", dwDimension ); + check_member( objinst, expect_objects[1], "%#04x", wExponent ); + check_member( objinst, expect_objects[1], "%u", wReportId ); + + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, 7, DIPH_BYOFFSET ); + ok( hr == DIERR_NOTFOUND, "GetObjectInfo returned: %#x\n", hr ); + res = DIDFT_TGLBUTTON | DIDFT_MAKEINSTANCE( 3 ); + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYID ); + ok( hr == DIERR_NOTFOUND, "GetObjectInfo returned: %#x\n", hr ); + res = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 3 ); + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYID ); + ok( hr == DI_OK, "GetObjectInfo returned: %#x\n", hr ); + + check_member( objinst, expect_objects[3], "%u", dwSize ); + check_member_guid( objinst, expect_objects[3], guidType ); + check_member( objinst, expect_objects[3], "%#x", dwOfs ); + check_member( objinst, expect_objects[3], "%#x", dwType ); + check_member( objinst, expect_objects[3], "%#x", dwFlags ); + if (!localized) check_member_wstr( objinst, expect_objects[3], tszName ); + check_member( objinst, expect_objects[3], "%u", dwFFMaxForce ); + check_member( objinst, expect_objects[3], "%u", dwFFForceResolution ); + check_member( objinst, expect_objects[3], "%u", wCollectionNumber ); + check_member( objinst, expect_objects[3], "%u", wDesignatorIndex ); + check_member( objinst, expect_objects[3], "%#04x", wUsagePage ); + check_member( objinst, expect_objects[3], "%#04x", wUsage ); + check_member( objinst, expect_objects[3], "%#04x", dwDimension ); + check_member( objinst, expect_objects[3], "%#04x", wExponent ); + check_member( objinst, expect_objects[3], "%u", wReportId ); + + ref = IDirectInputDevice8_Release( device ); + ok( ref == 0, "Release returned %d\n", ref ); + + ref = IDirectInput8_Release( di ); + ok( ref == 0, "Release returned %d\n", ref ); +} + +static void test_keyboard_info(void) +{ + static const DIDEVCAPS expect_caps = + { + .dwSize = sizeof(DIDEVCAPS), + .dwFlags = DIDC_ATTACHED | DIDC_EMULATED, + .dwDevType = (DI8DEVTYPEKEYBOARD_PCENH << 8) | DI8DEVTYPE_KEYBOARD, + .dwButtons = 128, + }; + const DIDEVICEINSTANCEW expect_devinst = + { + .dwSize = sizeof(DIDEVICEINSTANCEW), + .guidInstance = GUID_SysKeyboard, + .guidProduct = GUID_SysKeyboard, + .dwDevType = (DI8DEVTYPEKEYBOARD_PCENH << 8) | DI8DEVTYPE_KEYBOARD, + .tszInstanceName = L"Keyboard", + .tszProductName = L"Keyboard", + .guidFFDriver = GUID_NULL, + }; + + DIDEVICEOBJECTINSTANCEW expect_objects[] = + { + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Key, + .dwOfs = DIK_ESCAPE, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(DIK_ESCAPE), + .tszName = L"Esc", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Key, + .dwOfs = DIK_1, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(DIK_1), + .tszName = L"1", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Key, + .dwOfs = DIK_2, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(DIK_2), + .tszName = L"2", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Key, + .dwOfs = DIK_3, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(DIK_3), + .tszName = L"3", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Key, + .dwOfs = DIK_4, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(DIK_4), + .tszName = L"4", + }, + }; + struct check_objects_todos todo_objects[ARRAY_SIZE(expect_objects)] = {{0}}; + struct check_objects_params check_objects_params = + { + .stop_count = ARRAY_SIZE(expect_objects), + .expect_count = ARRAY_SIZE(expect_objects), + .expect_objs = expect_objects, + .todo_objs = todo_objects, + }; + DIPROPGUIDANDPATH prop_guid_path = + { + .diph = + { + .dwSize = sizeof(DIPROPGUIDANDPATH), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + DIPROPSTRING prop_string = + { + .diph = + { + .dwSize = sizeof(DIPROPSTRING), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + DIPROPDWORD prop_dword = + { + .diph = + { + .dwSize = sizeof(DIPROPDWORD), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + DIPROPRANGE prop_range = + { + .diph = + { + .dwSize = sizeof(DIPROPRANGE), + .dwHeaderSize = sizeof(DIPROPHEADER), + .dwHow = DIPH_DEVICE, + }, + }; + DIDEVICEOBJECTINSTANCEW objinst = {0}; + DIDEVICEINSTANCEW devinst = {0}; + IDirectInputDevice8W *device; + DIDEVCAPS caps = {0}; + IDirectInput8W *di; + ULONG res, ref; + HRESULT hr; + GUID guid; + + localized = TRUE; /* Skip name tests, Wine sometimes succeeds depending on the host key names */ + + hr = DirectInput8Create( instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W, (void **)&di, NULL ); + ok( hr == DI_OK, "DirectInput8Create returned %#x\n", hr ); + hr = IDirectInput8_CreateDevice( di, &GUID_SysKeyboard, &device, NULL ); + ok( hr == DI_OK, "CreateDevice returned %#x\n", hr ); + + hr = IDirectInputDevice8_Initialize( device, instance, DIRECTINPUT_VERSION, &GUID_SysKeyboardEm ); + ok( hr == DI_OK, "Initialize returned %#x\n", hr ); + guid = GUID_SysKeyboardEm; + memset( &devinst, 0, sizeof(devinst) ); + devinst.dwSize = sizeof(DIDEVICEINSTANCEW); + hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst ); + ok( hr == DI_OK, "GetDeviceInfo returned %#x\n", hr ); + ok( IsEqualGUID( &guid, &GUID_SysKeyboardEm ), "got %s expected %s\n", debugstr_guid( &guid ), + debugstr_guid( &GUID_SysKeyboardEm ) ); + + hr = IDirectInputDevice8_Initialize( device, instance, DIRECTINPUT_VERSION, &GUID_SysKeyboard ); + ok( hr == DI_OK, "Initialize returned %#x\n", hr ); + + memset( &devinst, 0, sizeof(devinst) ); + devinst.dwSize = sizeof(DIDEVICEINSTANCEW); + hr = IDirectInputDevice8_GetDeviceInfo( device, &devinst ); + ok( hr == DI_OK, "GetDeviceInfo returned %#x\n", hr ); + check_member( devinst, expect_devinst, "%d", dwSize ); + check_member_guid( devinst, expect_devinst, guidInstance ); + check_member_guid( devinst, expect_devinst, guidProduct ); + check_member( devinst, expect_devinst, "%#x", dwDevType ); + if (!localized) check_member_wstr( devinst, expect_devinst, tszInstanceName ); + if (!localized) todo_wine check_member_wstr( devinst, expect_devinst, tszProductName ); + check_member_guid( devinst, expect_devinst, guidFFDriver ); + check_member( devinst, expect_devinst, "%04x", wUsagePage ); + check_member( devinst, expect_devinst, "%04x", wUsage ); + + caps.dwSize = sizeof(DIDEVCAPS); + hr = IDirectInputDevice8_GetCapabilities( device, &caps ); + ok( hr == DI_OK, "GetCapabilities returned %#x\n", hr ); + check_member( caps, expect_caps, "%d", dwSize ); + check_member( caps, expect_caps, "%#x", dwFlags ); + check_member( caps, expect_caps, "%#x", dwDevType ); + check_member( caps, expect_caps, "%d", dwAxes ); + todo_wine + check_member( caps, expect_caps, "%d", dwButtons ); + check_member( caps, expect_caps, "%d", dwPOVs ); + check_member( caps, expect_caps, "%d", dwFFSamplePeriod ); + check_member( caps, expect_caps, "%d", dwFFMinTimeResolution ); + todo_wine + check_member( caps, expect_caps, "%d", dwFirmwareRevision ); + todo_wine + check_member( caps, expect_caps, "%d", dwHardwareRevision ); + check_member( caps, expect_caps, "%d", dwFFDriverVersion ); + + prop_dword.diph.dwHow = DIPH_BYOFFSET; + prop_dword.diph.dwObj = 1; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); + prop_range.diph.dwHow = DIPH_BYOFFSET; + prop_range.diph.dwObj = 1; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); + todo_wine + ok( hr == DIERR_NOTFOUND, "GetProperty DIPROP_RANGE returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_DEVICE; + prop_dword.diph.dwObj = 0; + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_AXISMODE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_AXISMODE returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == DIPROPAXISMODE_ABS, "got %u expected %u\n", prop_dword.dwData, DIPROPAXISMODE_ABS ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_BUFFERSIZE, &prop_dword.diph ); + ok( hr == DI_OK, "GetProperty DIPROP_BUFFERSIZE returned %#x\n", hr ); + ok( prop_dword.dwData == 0, "got %#x expected %#x\n", prop_dword.dwData, 0 ); + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFGAIN, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_FFGAIN returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == 10000, "got %u expected %u\n", prop_dword.dwData, 10000 ); + + hr = IDirectInputDevice8_SetDataFormat( device, &c_dfDIKeyboard ); + ok( hr == DI_OK, "SetDataFormat returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_DEVICE; + prop_dword.diph.dwObj = 0; + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_AXISMODE, &prop_dword.diph ); + todo_wine + ok( hr == DI_OK, "GetProperty DIPROP_AXISMODE returned %#x\n", hr ); + todo_wine + ok( prop_dword.dwData == DIPROPAXISMODE_REL, "got %u expected %u\n", prop_dword.dwData, DIPROPAXISMODE_ABS ); + + prop_dword.dwData = 0xdeadbeef; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_VIDPID, &prop_dword.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_VIDPID returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GUIDANDPATH, &prop_guid_path.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GUIDANDPATH returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_INSTANCENAME, &prop_string.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_INSTANCENAME returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_PRODUCTNAME, &prop_string.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_PRODUCTNAME returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_TYPENAME, &prop_string.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_TYPENAME returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_USERNAME, &prop_string.diph ); + ok( hr == S_FALSE, "GetProperty DIPROP_USERNAME returned %#x\n", hr ); + ok( !wcscmp( prop_string.wsz, L"" ), "got user %s\n", debugstr_w(prop_string.wsz) ); + + hr = IDirectInputDevice8_GetProperty( device, DIPROP_JOYSTICKID, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_VIDPID returned %#x\n", hr ); + + hr = IDirectInputDevice8_GetProperty( device, DIPROP_CALIBRATION, &prop_dword.diph ); + ok( hr == DIERR_INVALIDPARAM, "GetProperty DIPROP_CALIBRATION returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_AUTOCENTER, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_AUTOCENTER returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_FFLOAD, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_FFLOAD returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_BYUSAGE; + prop_dword.diph.dwObj = MAKELONG( HID_USAGE_KEYBOARD_LCTRL, HID_USAGE_PAGE_KEYBOARD ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr ); + + prop_dword.diph.dwHow = DIPH_BYOFFSET; + prop_dword.diph.dwObj = 1; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_GRANULARITY, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_GRANULARITY returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_DEADZONE, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_DEADZONE returned %#x\n", hr ); + hr = IDirectInputDevice8_GetProperty( device, DIPROP_SATURATION, &prop_dword.diph ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_SATURATION returned %#x\n", hr ); + prop_range.diph.dwHow = DIPH_BYOFFSET; + prop_range.diph.dwObj = 1; + hr = IDirectInputDevice8_GetProperty( device, DIPROP_RANGE, &prop_range.diph ); + ok( hr == DIERR_UNSUPPORTED, "GetProperty DIPROP_RANGE returned %#x\n", hr ); + + res = 0; + hr = IDirectInputDevice8_EnumObjects( device, check_object_count, &res, DIDFT_AXIS | DIDFT_PSHBUTTON ); + ok( hr == DI_OK, "EnumObjects returned %#x\n", hr ); + if (!localized) todo_wine ok( res == 127, "got %u expected %u\n", res, 127 ); + hr = IDirectInputDevice8_EnumObjects( device, check_objects, &check_objects_params, DIDFT_ALL ); + ok( hr == DI_OK, "EnumObjects returned %#x\n", hr ); + ok( check_objects_params.index >= check_objects_params.expect_count, "missing %u objects\n", + check_objects_params.expect_count - check_objects_params.index ); + + objinst.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW); + res = MAKELONG( HID_USAGE_KEYBOARD_LCTRL, HID_USAGE_PAGE_KEYBOARD ); + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYUSAGE ); + todo_wine + ok( hr == DIERR_UNSUPPORTED, "GetObjectInfo returned: %#x\n", hr ); + + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, 2, DIPH_BYOFFSET ); + ok( hr == DI_OK, "GetObjectInfo returned: %#x\n", hr ); + + check_member( objinst, expect_objects[1], "%u", dwSize ); + check_member_guid( objinst, expect_objects[1], guidType ); + check_member( objinst, expect_objects[1], "%#x", dwOfs ); + check_member( objinst, expect_objects[1], "%#x", dwType ); + check_member( objinst, expect_objects[1], "%#x", dwFlags ); + if (!localized) check_member_wstr( objinst, expect_objects[1], tszName ); + check_member( objinst, expect_objects[1], "%u", dwFFMaxForce ); + check_member( objinst, expect_objects[1], "%u", dwFFForceResolution ); + check_member( objinst, expect_objects[1], "%u", wCollectionNumber ); + check_member( objinst, expect_objects[1], "%u", wDesignatorIndex ); + check_member( objinst, expect_objects[1], "%#04x", wUsagePage ); + check_member( objinst, expect_objects[1], "%#04x", wUsage ); + check_member( objinst, expect_objects[1], "%#04x", dwDimension ); + check_member( objinst, expect_objects[1], "%#04x", wExponent ); + check_member( objinst, expect_objects[1], "%u", wReportId ); + + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, 423, DIPH_BYOFFSET ); + ok( hr == DIERR_NOTFOUND, "GetObjectInfo returned: %#x\n", hr ); + res = DIDFT_TGLBUTTON | DIDFT_MAKEINSTANCE( 3 ); + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYID ); + ok( hr == DIERR_NOTFOUND, "GetObjectInfo returned: %#x\n", hr ); + res = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( 3 ); + hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYID ); + ok( hr == DI_OK, "GetObjectInfo returned: %#x\n", hr ); + + check_member( objinst, expect_objects[2], "%u", dwSize ); + check_member_guid( objinst, expect_objects[2], guidType ); + check_member( objinst, expect_objects[2], "%#x", dwOfs ); + check_member( objinst, expect_objects[2], "%#x", dwType ); + check_member( objinst, expect_objects[2], "%#x", dwFlags ); + if (!localized) check_member_wstr( objinst, expect_objects[2], tszName ); + check_member( objinst, expect_objects[2], "%u", dwFFMaxForce ); + check_member( objinst, expect_objects[2], "%u", dwFFForceResolution ); + check_member( objinst, expect_objects[2], "%u", wCollectionNumber ); + check_member( objinst, expect_objects[2], "%u", wDesignatorIndex ); + check_member( objinst, expect_objects[2], "%#04x", wUsagePage ); + check_member( objinst, expect_objects[2], "%#04x", wUsage ); + check_member( objinst, expect_objects[2], "%#04x", dwDimension ); + check_member( objinst, expect_objects[2], "%#04x", wExponent ); + check_member( objinst, expect_objects[2], "%u", wReportId ); + + ref = IDirectInputDevice8_Release( device ); + ok( ref == 0, "Release returned %d\n", ref ); + + ref = IDirectInput8_Release( di ); + ok( ref == 0, "Release returned %d\n", ref ); +} + START_TEST(device) { + instance = GetModuleHandleW( NULL ); + CoInitialize(NULL);
+ test_mouse_info(); + test_keyboard_info(); test_action_mapping(); test_save_settings(); test_mouse_keyboard();
To initialize the device data format by enumerating its objects.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 73 +++++++++++++++++++++++++++++ dlls/dinput/device_private.h | 6 +++ dlls/dinput/joystick_hid.c | 89 ++++++------------------------------ 3 files changed, 92 insertions(+), 76 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index e2d2e551d02..d23bb8ea975 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -35,6 +35,7 @@ #include "winerror.h" #include "dinput.h" #include "dinputd.h" +#include "hidusage.h"
#include "initguid.h" #include "device_private.h" @@ -1821,3 +1822,75 @@ HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl * *out = This; return DI_OK; } + +static const GUID *object_instance_guid( const DIDEVICEOBJECTINSTANCEW *instance ) +{ + if (IsEqualGUID( &instance->guidType, &GUID_XAxis )) return &GUID_XAxis; + if (IsEqualGUID( &instance->guidType, &GUID_YAxis )) return &GUID_YAxis; + if (IsEqualGUID( &instance->guidType, &GUID_ZAxis )) return &GUID_ZAxis; + if (IsEqualGUID( &instance->guidType, &GUID_RxAxis )) return &GUID_RxAxis; + if (IsEqualGUID( &instance->guidType, &GUID_RyAxis )) return &GUID_RyAxis; + if (IsEqualGUID( &instance->guidType, &GUID_RzAxis )) return &GUID_RzAxis; + if (IsEqualGUID( &instance->guidType, &GUID_Slider )) return &GUID_Slider; + if (IsEqualGUID( &instance->guidType, &GUID_Button )) return &GUID_Button; + if (IsEqualGUID( &instance->guidType, &GUID_Key )) return &GUID_Key; + if (IsEqualGUID( &instance->guidType, &GUID_POV )) return &GUID_POV; + return &GUID_Unknown; +} + +static BOOL CALLBACK enum_objects_init( const DIDEVICEOBJECTINSTANCEW *instance, void *data ) +{ + IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( data ); + DIDATAFORMAT *format = impl->data_format.wine_df; + DIOBJECTDATAFORMAT *obj_format; + + if (!format->rgodf) + { + format->dwDataSize = max( format->dwDataSize, instance->dwOfs + sizeof(LONG) ); + if (instance->dwType & DIDFT_BUTTON) impl->caps.dwButtons++; + if (instance->dwType & DIDFT_AXIS) impl->caps.dwAxes++; + if (instance->dwType & DIDFT_POV) impl->caps.dwPOVs++; + if (instance->dwType & (DIDFT_BUTTON|DIDFT_AXIS|DIDFT_POV)) + { + if (!impl->device_state_report_id) + impl->device_state_report_id = instance->wReportId; + else if (impl->device_state_report_id != instance->wReportId) + FIXME( "multiple device state reports found!\n" ); + } + } + else + { + obj_format = format->rgodf + format->dwNumObjs; + obj_format->pguid = object_instance_guid( instance ); + obj_format->dwOfs = instance->dwOfs; + obj_format->dwType = instance->dwType; + obj_format->dwFlags = instance->dwFlags; + } + + format->dwNumObjs++; + return DIENUM_CONTINUE; +} + +HRESULT direct_input_device_init( IDirectInputDevice8W *iface ) +{ + IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface ); + DIDATAFORMAT *format = impl->data_format.wine_df; + ULONG size; + + IDirectInputDevice8_EnumObjects( iface, enum_objects_init, iface, DIDFT_ALL ); + if (format->dwDataSize > DEVICE_STATE_MAX_SIZE) + { + FIXME( "unable to create device, state is too large\n" ); + return DIERR_OUTOFMEMORY; + } + + size = format->dwNumObjs * sizeof(*format->rgodf); + if (!(format->rgodf = calloc( 1, size ))) return DIERR_OUTOFMEMORY; + format->dwSize = sizeof(*format); + format->dwObjSize = sizeof(*format->rgodf); + format->dwFlags = DIDF_ABSAXIS; + format->dwNumObjs = 0; + IDirectInputDevice8_EnumObjects( iface, enum_objects_init, iface, DIDFT_ALL ); + + return DI_OK; +} diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index 7ae040744cb..43629abdb15 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -62,6 +62,8 @@ struct dinput_device_vtbl HRESULT (*unacquire)(IDirectInputDevice8W *); };
+#define DEVICE_STATE_MAX_SIZE 1024 + /* Device implementation */ typedef struct IDirectInputDeviceImpl IDirectInputDeviceImpl; struct IDirectInputDeviceImpl @@ -99,10 +101,14 @@ struct IDirectInputDeviceImpl /* internal device callbacks */ HANDLE read_event; const struct dinput_device_vtbl *vtbl; + + BYTE device_state_report_id; + BYTE device_state[DEVICE_STATE_MAX_SIZE]; };
extern HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl *vtbl, const struct dinput_device_vtbl *internal_vtbl, const GUID *guid, IDirectInputImpl *dinput, void **out ) DECLSPEC_HIDDEN; +extern HRESULT direct_input_device_init( IDirectInputDevice8W *iface ); extern const IDirectInputDevice8AVtbl dinput_device_a_vtbl DECLSPEC_HIDDEN;
extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN; diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 03005964c67..b6eeb772fcf 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -150,8 +150,6 @@ struct pid_set_ramp_force struct hid_value_caps *end_caps; };
-#define DEVICE_STATE_MAX_SIZE 1024 - struct hid_joystick { IDirectInputDeviceImpl base; @@ -172,9 +170,6 @@ struct hid_joystick USAGE_AND_PAGE *usages_buf; ULONG usages_count;
- BYTE device_state_report_id; - BYTE device_state[DEVICE_STATE_MAX_SIZE]; - BYTE effect_inuse[255]; struct list effect_list; struct pid_control_report pid_device_control; @@ -856,13 +851,13 @@ static BOOL set_property_prop_range( struct hid_joystick *impl, struct hid_value { if (!caps->physical_min) tmp = caps->physical_max / 2; else tmp = round( (caps->physical_min + caps->physical_max) / 2.0 ); - *(LONG *)(impl->device_state + instance->dwOfs) = tmp; + *(LONG *)(impl->base.device_state + instance->dwOfs) = tmp; } else if (instance->dwType & DIDFT_POV) { tmp = caps->logical_max - caps->logical_min; if (tmp > 0) caps->physical_max -= value->lMax / (tmp + 1); - *(LONG *)(impl->device_state + instance->dwOfs) = -1; + *(LONG *)(impl->base.device_state + instance->dwOfs) = -1; } return DIENUM_CONTINUE; } @@ -1009,7 +1004,7 @@ static HRESULT WINAPI hid_joystick_GetDeviceState( IDirectInputDevice8W *iface,
EnterCriticalSection( &impl->base.crit ); if (!impl->base.acquired) hr = DIERR_NOTACQUIRED; - else fill_DataFormat( ptr, len, impl->device_state, &impl->base.data_format ); + else fill_DataFormat( ptr, len, impl->base.device_state, &impl->base.data_format ); LeaveCriticalSection( &impl->base.crit );
return hr; @@ -1445,11 +1440,11 @@ static BOOL check_device_state_button( struct hid_joystick *impl, struct hid_val struct parse_device_state_params *params = data; BYTE old_value, value;
- if (instance->wReportId != impl->device_state_report_id) return DIENUM_CONTINUE; + if (instance->wReportId != impl->base.device_state_report_id) return DIENUM_CONTINUE;
value = params->buttons[instance->wUsage - 1]; old_value = params->old_state[instance->dwOfs]; - impl->device_state[instance->dwOfs] = value; + impl->base.device_state[instance->dwOfs] = value; if (old_value != value) queue_event( iface, instance->dwType, value, params->time, params->seq );
@@ -1518,7 +1513,7 @@ static BOOL read_device_state_value( struct hid_joystick *impl, struct hid_value LONG old_value, value; NTSTATUS status;
- if (instance->wReportId != impl->device_state_report_id) return DIENUM_CONTINUE; + if (instance->wReportId != impl->base.device_state_report_id) return DIENUM_CONTINUE;
extra = impl->input_extra_caps + (caps - HID_INPUT_VALUE_CAPS( preparsed )); status = HidP_GetUsageValue( HidP_Input, instance->wUsagePage, 0, instance->wUsage, @@ -1529,7 +1524,7 @@ static BOOL read_device_state_value( struct hid_joystick *impl, struct hid_value else value = scale_value( logical_value, caps, caps->physical_min, caps->physical_max );
old_value = *(LONG *)(params->old_state + instance->dwOfs); - *(LONG *)(impl->device_state + instance->dwOfs) = value; + *(LONG *)(impl->base.device_state + instance->dwOfs) = value; if (old_value != value) queue_event( iface, instance->dwType, value, params->time, params->seq );
@@ -1579,12 +1574,12 @@ static HRESULT hid_joystick_internal_read( IDirectInputDevice8W *iface ) impl->preparsed, report_buf, report_len ); if (status != HIDP_STATUS_SUCCESS) WARN( "HidP_GetUsagesEx returned %#x\n", status );
- if (report_buf[0] == impl->device_state_report_id) + if (report_buf[0] == impl->base.device_state_report_id) { params.time = GetCurrentTime(); params.seq = impl->base.dinput->evsequence++; - memcpy( params.old_state, impl->device_state, format->dwDataSize ); - memset( impl->device_state, 0, format->dwDataSize ); + memcpy( params.old_state, impl->base.device_state, format->dwDataSize ); + memset( impl->base.device_state, 0, format->dwDataSize );
while (count--) { @@ -1599,7 +1594,7 @@ static HRESULT hid_joystick_internal_read( IDirectInputDevice8W *iface )
enum_objects( impl, &filter, DIDFT_AXIS | DIDFT_POV, read_device_state_value, ¶ms ); enum_objects( impl, &filter, DIDFT_BUTTON, check_device_state_button, ¶ms ); - if (impl->base.hEvent && memcmp( ¶ms.old_state, impl->device_state, format->dwDataSize )) + if (impl->base.hEvent && memcmp( ¶ms.old_state, impl->base.device_state, format->dwDataSize )) SetEvent( impl->base.hEvent ); }
@@ -1884,47 +1879,6 @@ static HRESULT hid_joystick_enum_device( DWORD type, DWORD flags, DIDEVICEINSTAN return DI_OK; }
-static BOOL init_objects( struct hid_joystick *impl, struct hid_value_caps *caps, - DIDEVICEOBJECTINSTANCEW *instance, void *data ) -{ - DIDATAFORMAT *format = impl->base.data_format.wine_df; - - format->dwNumObjs++; - format->dwDataSize = max( format->dwDataSize, instance->dwOfs + sizeof(LONG) ); - if (instance->dwType & DIDFT_BUTTON) impl->base.caps.dwButtons++; - if (instance->dwType & DIDFT_AXIS) impl->base.caps.dwAxes++; - if (instance->dwType & DIDFT_POV) impl->base.caps.dwPOVs++; - - if (instance->dwType & (DIDFT_BUTTON|DIDFT_AXIS|DIDFT_POV) && - (instance->wUsagePage == HID_USAGE_PAGE_GENERIC || - instance->wUsagePage == HID_USAGE_PAGE_BUTTON)) - { - if (!impl->device_state_report_id) - impl->device_state_report_id = instance->wReportId; - else if (impl->device_state_report_id != instance->wReportId) - FIXME( "multiple device state reports found!\n" ); - } - - return DIENUM_CONTINUE; -} - -static BOOL init_data_format( struct hid_joystick *impl, struct hid_value_caps *caps, - DIDEVICEOBJECTINSTANCEW *instance, void *data ) -{ - DIDATAFORMAT *format = impl->base.data_format.wine_df; - DIOBJECTDATAFORMAT *obj_format; - DWORD *index = data; - - obj_format = format->rgodf + *index; - obj_format->pguid = object_usage_to_guid( instance->wUsagePage, instance->wUsage ); - obj_format->dwOfs = instance->dwOfs; - obj_format->dwType = instance->dwType; - obj_format->dwFlags = instance->dwFlags; - (*index)++; - - return DIENUM_CONTINUE; -} - static BOOL init_pid_reports( struct hid_joystick *impl, struct hid_value_caps *caps, DIDEVICEOBJECTINSTANCEW *instance, void *data ) { @@ -2203,11 +2157,10 @@ static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID struct hid_preparsed_data *preparsed; struct hid_joystick *impl = NULL; struct extra_caps *extra; - DIDATAFORMAT *format = NULL; USAGE_AND_PAGE *usages; - DWORD size, index; char *buffer; HRESULT hr; + DWORD size;
TRACE( "dinput %p, guid %s, out %p\n", dinput, debugstr_guid( guid ), out );
@@ -2255,7 +2208,6 @@ static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID if (!(usages = malloc( size ))) goto failed; impl->usages_buf = usages;
- enum_objects( impl, &filter, DIDFT_ALL, init_objects, NULL ); enum_objects( impl, &filter, DIDFT_COLLECTION, init_pid_reports, NULL ); enum_objects( impl, &filter, DIDFT_NODATA, init_pid_caps, NULL );
@@ -2296,23 +2248,8 @@ static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID impl->base.caps.dwFFDriverVersion = 1; }
- format = impl->base.data_format.wine_df; - if (format->dwDataSize > DEVICE_STATE_MAX_SIZE) - { - FIXME( "unable to create device, state is too large\n" ); + if (FAILED(hr = direct_input_device_init( &impl->base.IDirectInputDevice8W_iface ))) goto failed; - } - - size = format->dwNumObjs * sizeof(*format->rgodf); - if (!(format->rgodf = calloc( 1, size ))) goto failed; - format->dwSize = sizeof(*format); - format->dwObjSize = sizeof(*format->rgodf); - format->dwFlags = DIDF_ABSAXIS; - - index = 0; - enum_objects( impl, &filter, DIDFT_ALL, init_data_format, &index ); - - _dump_DIDATAFORMAT( impl->base.data_format.wine_df );
range.lMax = 65535; enum_objects( impl, &range.diph, DIDFT_AXIS, set_property_prop_range, &range );
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 77 ++++++++++++++++++++++++--------- dlls/dinput/device_private.h | 8 ++-- dlls/dinput/joystick_hid.c | 84 ++++++++++-------------------------- dlls/dinput/keyboard.c | 1 + dlls/dinput/mouse.c | 1 + 5 files changed, 87 insertions(+), 84 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index d23bb8ea975..3d3865ec6dd 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1140,33 +1140,70 @@ ULONG WINAPI IDirectInputDevice2WImpl_AddRef(LPDIRECTINPUTDEVICE8W iface) return ref; }
-HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface, - LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID lpvRef, DWORD dwFlags) +HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects( IDirectInputDevice8W *iface, LPDIENUMDEVICEOBJECTSCALLBACKW callback, + void *context, DWORD flags ) { - IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); - DIDEVICEOBJECTINSTANCEW ddoi; - int i; - - TRACE("(%p)->(%p,%p flags:%08x)\n", This, lpCallback, lpvRef, dwFlags); - TRACE(" - flags = "); - _dump_EnumObjects_flags(dwFlags); - TRACE("\n"); + static const DIPROPHEADER filter = + { + .dwSize = sizeof(filter), + .dwHeaderSize = sizeof(filter), + .dwHow = DIPH_DEVICE, + }; + struct IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface ); + HRESULT hr;
- if (!lpCallback) return DIERR_INVALIDPARAM; + TRACE( "iface %p, callback %p, context %p, flags %#x.\n", iface, callback, context, flags );
- /* Only the fields till dwFFMaxForce are relevant */ - memset(&ddoi, 0, sizeof(ddoi)); - ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEW, dwFFMaxForce); + if (!callback) return DIERR_INVALIDPARAM; + if (flags & ~(DIDFT_AXIS | DIDFT_POV | DIDFT_BUTTON | DIDFT_NODATA | DIDFT_COLLECTION)) + return DIERR_INVALIDPARAM;
- for (i = 0; i < This->data_format.wine_df->dwNumObjs; i++) + if (!impl->vtbl->enum_objects) { - LPDIOBJECTDATAFORMAT odf = dataformat_to_odf(This->data_format.wine_df, i); + DIDEVICEOBJECTINSTANCEW ddoi; + DWORD i; + + /* Only the fields till dwFFMaxForce are relevant */ + memset( &ddoi, 0, sizeof(ddoi) ); + ddoi.dwSize = FIELD_OFFSET( DIDEVICEOBJECTINSTANCEW, dwFFMaxForce );
- if (dwFlags != DIDFT_ALL && !(dwFlags & DIDFT_GETTYPE(odf->dwType))) continue; - if (IDirectInputDevice_GetObjectInfo(iface, &ddoi, odf->dwType, DIPH_BYID) != DI_OK) - continue; + for (i = 0; i < impl->data_format.wine_df->dwNumObjs; i++) + { + LPDIOBJECTDATAFORMAT odf = dataformat_to_odf( impl->data_format.wine_df, i ); + + if (flags != DIDFT_ALL && !(flags & DIDFT_GETTYPE( odf->dwType ))) continue; + if (IDirectInputDevice_GetObjectInfo( iface, &ddoi, odf->dwType, DIPH_BYID ) != DI_OK) + continue;
- if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) break; + if (callback( &ddoi, context ) != DIENUM_CONTINUE) break; + } + + return DI_OK; + } + + if (flags == DIDFT_ALL || (flags & DIDFT_AXIS)) + { + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, callback, context ); + if (FAILED(hr)) return hr; + if (hr != DIENUM_CONTINUE) return DI_OK; + } + if (flags == DIDFT_ALL || (flags & DIDFT_POV)) + { + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_POV, callback, context ); + if (FAILED(hr)) return hr; + if (hr != DIENUM_CONTINUE) return DI_OK; + } + if (flags == DIDFT_ALL || (flags & DIDFT_BUTTON)) + { + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_BUTTON, callback, context ); + if (FAILED(hr)) return hr; + if (hr != DIENUM_CONTINUE) return DI_OK; + } + if (flags == DIDFT_ALL || (flags & (DIDFT_NODATA | DIDFT_COLLECTION))) + { + hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_NODATA, callback, context ); + if (FAILED(hr)) return hr; + if (hr != DIENUM_CONTINUE) return DI_OK; }
return DI_OK; diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index 43629abdb15..8589eca41e3 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -57,9 +57,11 @@ typedef HRESULT dinput_device_read_state( IDirectInputDevice8W *iface );
struct dinput_device_vtbl { - HRESULT (*read)(IDirectInputDevice8W *); - HRESULT (*acquire)(IDirectInputDevice8W *); - HRESULT (*unacquire)(IDirectInputDevice8W *); + HRESULT (*read)( IDirectInputDevice8W *iface ); + HRESULT (*acquire)( IDirectInputDevice8W *iface ); + HRESULT (*unacquire)( IDirectInputDevice8W *iface ); + HRESULT (*enum_objects)( IDirectInputDevice8W *iface, const DIPROPHEADER *filter, DWORD flags, + LPDIENUMDEVICEOBJECTSCALLBACKW callback, void *context ); };
#define DEVICE_STATE_MAX_SIZE 1024 diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index b6eeb772fcf..89ad70cbf19 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -656,66 +656,6 @@ static ULONG WINAPI hid_joystick_Release( IDirectInputDevice8W *iface ) return ref; }
-struct enum_objects_params -{ - LPDIENUMDEVICEOBJECTSCALLBACKW callback; - void *context; -}; - -static BOOL enum_objects_callback( struct hid_joystick *impl, struct hid_value_caps *caps, - DIDEVICEOBJECTINSTANCEW *instance, void *data ) -{ - struct enum_objects_params *params = data; - return params->callback( instance, params->context ); -} - -static HRESULT WINAPI hid_joystick_EnumObjects( IDirectInputDevice8W *iface, LPDIENUMDEVICEOBJECTSCALLBACKW callback, - void *context, DWORD flags ) -{ - static const DIPROPHEADER filter = - { - .dwSize = sizeof(filter), - .dwHeaderSize = sizeof(filter), - .dwHow = DIPH_DEVICE, - }; - struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); - struct enum_objects_params params = - { - .callback = callback, - .context = context, - }; - BOOL ret; - - TRACE( "iface %p, callback %p, context %p, flags %#x.\n", iface, callback, context, flags ); - - if (!callback) return DIERR_INVALIDPARAM; - if (flags & ~(DIDFT_AXIS | DIDFT_POV | DIDFT_BUTTON | DIDFT_NODATA | DIDFT_COLLECTION)) - return DIERR_INVALIDPARAM; - - if (flags == DIDFT_ALL || (flags & DIDFT_AXIS)) - { - ret = enum_objects( impl, &filter, DIDFT_AXIS, enum_objects_callback, ¶ms ); - if (ret != DIENUM_CONTINUE) return DI_OK; - } - if (flags == DIDFT_ALL || (flags & DIDFT_POV)) - { - ret = enum_objects( impl, &filter, DIDFT_POV, enum_objects_callback, ¶ms ); - if (ret != DIENUM_CONTINUE) return DI_OK; - } - if (flags == DIDFT_ALL || (flags & DIDFT_BUTTON)) - { - ret = enum_objects( impl, &filter, DIDFT_BUTTON, enum_objects_callback, ¶ms ); - if (ret != DIENUM_CONTINUE) return DI_OK; - } - if (flags == DIDFT_ALL || (flags & (DIDFT_NODATA | DIDFT_COLLECTION))) - { - ret = enum_objects( impl, &filter, DIDFT_NODATA, enum_objects_callback, ¶ms ); - if (ret != DIENUM_CONTINUE) return DI_OK; - } - - return DI_OK; -} - static BOOL get_property_prop_range( struct hid_joystick *impl, struct hid_value_caps *caps, DIDEVICEOBJECTINSTANCEW *instance, void *data ) { @@ -1392,7 +1332,7 @@ static const IDirectInputDevice8WVtbl hid_joystick_vtbl = hid_joystick_Release, /*** IDirectInputDevice methods ***/ IDirectInputDevice2WImpl_GetCapabilities, - hid_joystick_EnumObjects, + IDirectInputDevice2WImpl_EnumObjects, hid_joystick_GetProperty, hid_joystick_SetProperty, IDirectInputDevice2WImpl_Acquire, @@ -1616,11 +1556,33 @@ static HRESULT hid_joystick_internal_read( IDirectInputDevice8W *iface ) return hr; }
+struct enum_objects_params +{ + LPDIENUMDEVICEOBJECTSCALLBACKW callback; + void *context; +}; + +static BOOL enum_objects_callback( struct hid_joystick *impl, struct hid_value_caps *caps, + DIDEVICEOBJECTINSTANCEW *instance, void *data ) +{ + struct enum_objects_params *params = data; + return params->callback( instance, params->context ); +} + +static HRESULT hid_joystick_internal_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *filter, DWORD flags, + LPDIENUMDEVICEOBJECTSCALLBACKW callback, void *context ) +{ + struct enum_objects_params params = {.callback = callback, .context = context}; + struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); + return enum_objects( impl, filter, flags, enum_objects_callback, ¶ms ); +} + static const struct dinput_device_vtbl hid_joystick_internal_vtbl = { hid_joystick_internal_read, hid_joystick_internal_acquire, hid_joystick_internal_unacquire, + hid_joystick_internal_enum_objects, };
static DWORD device_type_for_version( DWORD type, DWORD version ) diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 138b8439374..a296ebc98ce 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -412,6 +412,7 @@ static const struct dinput_device_vtbl keyboard_internal_vtbl = NULL, keyboard_internal_acquire, keyboard_internal_unacquire, + NULL, };
static const IDirectInputDevice8WVtbl SysKeyboardWvt = diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 20a4ab9af40..ea3fcbb5581 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -668,6 +668,7 @@ static const struct dinput_device_vtbl mouse_internal_vtbl = NULL, mouse_internal_acquire, mouse_internal_unacquire, + NULL, };
static const IDirectInputDevice8WVtbl SysMouseWvt =
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/mouse.c | 142 ++++++++++++++++++++++++++++++------ dlls/dinput8/tests/device.c | 10 +-- 2 files changed, 121 insertions(+), 31 deletions(-)
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index ea3fcbb5581..cdbdd083c00 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -138,8 +138,6 @@ static HRESULT mousedev_enum_device(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEIN static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, SysMouseImpl **out ) { SysMouseImpl* newDevice; - LPDIDATAFORMAT df = NULL; - unsigned i; WCHAR buffer[20]; HKEY hkey, appkey; HRESULT hr; @@ -147,13 +145,10 @@ static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, SysMouseIm if (FAILED(hr = direct_input_device_alloc( sizeof(SysMouseImpl), &SysMouseWvt, &mouse_internal_vtbl, rguid, dinput, (void **)&newDevice ))) return hr; - df = newDevice->base.data_format.wine_df; newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysMouseImpl*->base.crit");
fill_mouse_dideviceinstanceW( &newDevice->base.instance, newDevice->base.dinput->dwVersion ); newDevice->base.caps.dwDevType = newDevice->base.instance.dwDevType; - newDevice->base.caps.dwAxes = 3; - newDevice->base.caps.dwButtons = 8; newDevice->base.caps.dwFirmwareRevision = 100; newDevice->base.caps.dwHardwareRevision = 100; newDevice->base.dwCoopLevel = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND; @@ -167,17 +162,11 @@ static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, SysMouseIm if (appkey) RegCloseKey(appkey); if (hkey) RegCloseKey(hkey);
- /* Create copy of default data format */ - memcpy(df, &c_dfDIMouse2, c_dfDIMouse2.dwSize); - if (!(df->rgodf = malloc( df->dwNumObjs * df->dwObjSize ))) goto failed; - memcpy(df->rgodf, c_dfDIMouse2.rgodf, df->dwNumObjs * df->dwObjSize); - - /* Because we don't do any detection yet just modify instance and type */ - for (i = 0; i < df->dwNumObjs; i++) - if (DIDFT_GETTYPE(df->rgodf[i].dwType) & DIDFT_AXIS) - df->rgodf[i].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_RELAXIS; - else - df->rgodf[i].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON; + if (FAILED(hr = direct_input_device_init( &newDevice->base.IDirectInputDevice8W_iface ))) + { + IDirectInputDevice_Release( &newDevice->base.IDirectInputDevice8W_iface ); + return hr; + }
if (dinput->dwVersion >= 0x0800) { @@ -188,12 +177,6 @@ static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, SysMouseIm
*out = newDevice; return DI_OK; - -failed: - if (df) free( df->rgodf ); - free( df ); - free( newDevice ); - return DIERR_OUTOFMEMORY; }
static HRESULT mousedev_create_device( IDirectInputImpl *dinput, REFGUID rguid, IDirectInputDevice8W **out ) @@ -663,12 +646,125 @@ static HRESULT mouse_internal_unacquire( IDirectInputDevice8W *iface ) return DI_OK; }
+static BOOL try_enum_object( const DIPROPHEADER *filter, DWORD flags, LPDIENUMDEVICEOBJECTSCALLBACKW callback, + DIDEVICEOBJECTINSTANCEW *instance, void *data ) +{ + if (flags != DIDFT_ALL && !(flags & DIDFT_GETTYPE( instance->dwType ))) return DIENUM_CONTINUE; + + switch (filter->dwHow) + { + case DIPH_DEVICE: + return callback( instance, data ); + case DIPH_BYOFFSET: + if (filter->dwObj != instance->dwOfs) return DIENUM_CONTINUE; + return callback( instance, data ); + case DIPH_BYID: + if ((filter->dwObj & 0x00ffffff) != (instance->dwType & 0x00ffffff)) return DIENUM_CONTINUE; + return callback( instance, data ); + } + + return DIENUM_CONTINUE; +} + +static HRESULT mouse_internal_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *header, DWORD flags, + LPDIENUMDEVICEOBJECTSCALLBACKW callback, void *context ) +{ + DIDEVICEOBJECTINSTANCEW instances[] = + { + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_XAxis, + .dwOfs = DIMOFS_X, + .dwType = DIDFT_RELAXIS|DIDFT_MAKEINSTANCE(0), + .dwFlags = DIDOI_ASPECTPOSITION, + .tszName = L"X-axis", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_YAxis, + .dwOfs = DIMOFS_Y, + .dwType = DIDFT_RELAXIS|DIDFT_MAKEINSTANCE(1), + .dwFlags = DIDOI_ASPECTPOSITION, + .tszName = L"Y-axis", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_ZAxis, + .dwOfs = DIMOFS_Z, + .dwType = DIDFT_RELAXIS|DIDFT_MAKEINSTANCE(2), + .dwFlags = DIDOI_ASPECTPOSITION, + .tszName = L"Wheel", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = DIMOFS_BUTTON0, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(3), + .tszName = L"Button 0", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = DIMOFS_BUTTON1, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(4), + .tszName = L"Button 1", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = DIMOFS_BUTTON2, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(5), + .tszName = L"Button 2", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = DIMOFS_BUTTON3, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(6), + .tszName = L"Button 3", + }, + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Button, + .dwOfs = DIMOFS_BUTTON4, + .dwType = DIDFT_PSHBUTTON|DIDFT_MAKEINSTANCE(7), + .tszName = L"Button 4", + }, + }; + SysMouseImpl *impl = impl_from_IDirectInputDevice8W( iface ); + DIDATAFORMAT *format = impl->base.data_format.wine_df; + int *offsets = impl->base.data_format.offsets; + DIPROPHEADER filter = *header; + BOOL ret; + DWORD i; + + if (header->dwHow != DIPH_DEVICE && header->dwHow != DIPH_BYOFFSET && header->dwHow != DIPH_BYID) + return DIERR_UNSUPPORTED; + + if (filter.dwHow == DIPH_BYOFFSET) + { + if (!offsets) return DIENUM_CONTINUE; + for (i = 0; i < format->dwNumObjs; ++i) + if (offsets[i] == filter.dwObj) break; + if (i == format->dwNumObjs) return DIENUM_CONTINUE; + filter.dwObj = format->rgodf[i].dwOfs; + } + + for (i = 0; i < ARRAY_SIZE(instances); ++i) + { + ret = try_enum_object( &filter, flags, callback, instances + i, context ); + if (ret != DIENUM_CONTINUE) return DIENUM_STOP; + } + + return DIENUM_CONTINUE; +} + static const struct dinput_device_vtbl mouse_internal_vtbl = { NULL, mouse_internal_acquire, mouse_internal_unacquire, - NULL, + mouse_internal_enum_objects, };
static const IDirectInputDevice8WVtbl SysMouseWvt = diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 6571d1b26b2..9122799b118 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -1068,7 +1068,7 @@ static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *ar
winetest_push_context( "obj[%d]", params->index );
- todo_wine + todo_wine_if( obj->dwSize == sizeof(DIDEVICEOBJECTINSTANCE_DX3W) ) check_member( *obj, *exp, "%u", dwSize ); check_member_guid( *obj, *exp, guidType ); todo_wine_if( todo->offset ) @@ -1183,11 +1183,7 @@ static void test_mouse_info(void) .tszName = L"Button 4", }, }; - struct check_objects_todos todo_objects[ARRAY_SIZE(expect_objects)] = - { - {.name = TRUE}, - {.name = TRUE}, - }; + struct check_objects_todos todo_objects[ARRAY_SIZE(expect_objects)] = {{0}}; struct check_objects_params check_objects_params = { .expect_count = ARRAY_SIZE(expect_objects), @@ -1283,7 +1279,6 @@ static void test_mouse_info(void) todo_wine check_member( caps, expect_caps, "%#x", dwDevType ); check_member( caps, expect_caps, "%d", dwAxes ); - todo_wine check_member( caps, expect_caps, "%d", dwButtons ); check_member( caps, expect_caps, "%d", dwPOVs ); check_member( caps, expect_caps, "%d", dwFFSamplePeriod ); @@ -1410,7 +1405,6 @@ static void test_mouse_info(void) res = 0; hr = IDirectInputDevice8_EnumObjects( device, check_object_count, &res, DIDFT_AXIS | DIDFT_PSHBUTTON ); ok( hr == DI_OK, "EnumObjects returned %#x\n", hr ); - todo_wine ok( res == 8, "got %u expected %u\n", res, 8 ); hr = IDirectInputDevice8_EnumObjects( device, check_objects, &check_objects_params, DIDFT_ALL ); ok( hr == DI_OK, "EnumObjects returned %#x\n", hr );
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=100284
Your paranoid android.
=== w7u_adm (32 bit report) ===
dinput8: device.c:140: Test failed: GetDeviceData() failed: 00000000 device.c:143: Test failed: GetDeviceData() failed: 00000000 cnt:0
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 25 +--------- dlls/dinput/keyboard.c | 93 ++++++++++++++++++++++++++----------- dlls/dinput8/tests/device.c | 1 - 3 files changed, 68 insertions(+), 51 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 3d3865ec6dd..56354e886d1 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1158,29 +1158,6 @@ HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects( IDirectInputDevice8W *iface if (flags & ~(DIDFT_AXIS | DIDFT_POV | DIDFT_BUTTON | DIDFT_NODATA | DIDFT_COLLECTION)) return DIERR_INVALIDPARAM;
- if (!impl->vtbl->enum_objects) - { - DIDEVICEOBJECTINSTANCEW ddoi; - DWORD i; - - /* Only the fields till dwFFMaxForce are relevant */ - memset( &ddoi, 0, sizeof(ddoi) ); - ddoi.dwSize = FIELD_OFFSET( DIDEVICEOBJECTINSTANCEW, dwFFMaxForce ); - - for (i = 0; i < impl->data_format.wine_df->dwNumObjs; i++) - { - LPDIOBJECTDATAFORMAT odf = dataformat_to_odf( impl->data_format.wine_df, i ); - - if (flags != DIDFT_ALL && !(flags & DIDFT_GETTYPE( odf->dwType ))) continue; - if (IDirectInputDevice_GetObjectInfo( iface, &ddoi, odf->dwType, DIPH_BYID ) != DI_OK) - continue; - - if (callback( &ddoi, context ) != DIENUM_CONTINUE) break; - } - - return DI_OK; - } - if (flags == DIDFT_ALL || (flags & DIDFT_AXIS)) { hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_AXIS, callback, context ); @@ -1421,7 +1398,7 @@ HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo( memset(pdidoi, 0, pdidoi->dwSize); pdidoi->dwSize = dwSize; if (odf->pguid) pdidoi->guidType = *odf->pguid; - pdidoi->dwOfs = This->data_format.offsets ? This->data_format.offsets[idx] : odf->dwOfs; + pdidoi->dwOfs = odf->dwOfs; pdidoi->dwType = odf->dwType; pdidoi->dwFlags = odf->dwFlags;
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index a296ebc98ce..50e292abaad 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -196,14 +196,11 @@ static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, SysKeyboar { BYTE subtype = get_keyboard_subtype(); SysKeyboardImpl* newDevice; - LPDIDATAFORMAT df = NULL; - int i, idx = 0; HRESULT hr;
if (FAILED(hr = direct_input_device_alloc( sizeof(SysKeyboardImpl), &SysKeyboardWvt, &keyboard_internal_vtbl, rguid, dinput, (void **)&newDevice ))) return hr; - df = newDevice->base.data_format.wine_df; newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysKeyboardImpl*->base.crit");
fill_keyboard_dideviceinstanceW( &newDevice->base.instance, newDevice->base.dinput->dwVersion, subtype ); @@ -211,33 +208,14 @@ static HRESULT alloc_device( REFGUID rguid, IDirectInputImpl *dinput, SysKeyboar newDevice->base.caps.dwFirmwareRevision = 100; newDevice->base.caps.dwHardwareRevision = 100;
- /* Create copy of default data format */ - memcpy(df, &c_dfDIKeyboard, c_dfDIKeyboard.dwSize); - if (!(df->rgodf = malloc( df->dwNumObjs * df->dwObjSize ))) goto failed; - - for (i = 0; i < df->dwNumObjs; i++) + if (FAILED(hr = direct_input_device_init( &newDevice->base.IDirectInputDevice8W_iface ))) { - char buf[MAX_PATH]; - BYTE dik_code; - - if (!GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), buf, sizeof(buf))) - continue; - - dik_code = map_dik_code( i, 0, subtype, dinput->dwVersion ); - memcpy(&df->rgodf[idx], &c_dfDIKeyboard.rgodf[dik_code], df->dwObjSize); - df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON; + IDirectInputDevice_Release( &newDevice->base.IDirectInputDevice8W_iface ); + return hr; } - df->dwNumObjs = idx; - newDevice->base.caps.dwButtons = idx;
*out = newDevice; return DI_OK; - -failed: - if (df) free( df->rgodf ); - free( df ); - free( newDevice ); - return DIERR_OUTOFMEMORY; }
static HRESULT keyboarddev_create_device( IDirectInputImpl *dinput, REFGUID rguid, IDirectInputDevice8W **out ) @@ -407,12 +385,75 @@ static HRESULT keyboard_internal_unacquire( IDirectInputDevice8W *iface ) return DI_OK; }
+static BOOL try_enum_object( const DIPROPHEADER *filter, DWORD flags, LPDIENUMDEVICEOBJECTSCALLBACKW callback, + DIDEVICEOBJECTINSTANCEW *instance, void *data ) +{ + if (flags != DIDFT_ALL && !(flags & DIDFT_GETTYPE( instance->dwType ))) return DIENUM_CONTINUE; + + switch (filter->dwHow) + { + case DIPH_DEVICE: + return callback( instance, data ); + case DIPH_BYOFFSET: + if (filter->dwObj != instance->dwOfs) return DIENUM_CONTINUE; + return callback( instance, data ); + case DIPH_BYID: + if ((filter->dwObj & 0x00ffffff) != (instance->dwType & 0x00ffffff)) return DIENUM_CONTINUE; + return callback( instance, data ); + } + + return DIENUM_CONTINUE; +} + +static HRESULT keyboard_internal_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *header, DWORD flags, + LPDIENUMDEVICEOBJECTSCALLBACKW callback, void *context ) +{ + SysKeyboardImpl *impl = impl_from_IDirectInputDevice8W( iface ); + BYTE subtype = GET_DIDEVICE_SUBTYPE( impl->base.instance.dwDevType ); + DIDEVICEOBJECTINSTANCEW instance = + { + .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW), + .guidType = GUID_Key, + .dwOfs = DIK_ESCAPE, + .dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ), + }; + DIDATAFORMAT *format = impl->base.data_format.wine_df; + int *offsets = impl->base.data_format.offsets; + DIPROPHEADER filter = *header; + DWORD i, dik; + BOOL ret; + + if (header->dwHow != DIPH_DEVICE && header->dwHow != DIPH_BYOFFSET && header->dwHow != DIPH_BYID) + return DIERR_UNSUPPORTED; + + if (filter.dwHow == DIPH_BYOFFSET) + { + if (!offsets) return DIENUM_CONTINUE; + for (i = 0; i < format->dwNumObjs; ++i) + if (offsets[i] == filter.dwObj) break; + if (i == format->dwNumObjs) return DIENUM_CONTINUE; + filter.dwObj = format->rgodf[i].dwOfs; + } + + for (i = 0; i < 512; ++i) + { + if (!GetKeyNameTextW( i << 16, instance.tszName, ARRAY_SIZE(instance.tszName) )) continue; + if (!(dik = map_dik_code( i, 0, subtype, impl->base.dinput->dwVersion ))) continue; + instance.dwOfs = dik; + instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik ); + ret = try_enum_object( &filter, flags, callback, &instance, context ); + if (ret != DIENUM_CONTINUE) return DIENUM_STOP; + } + + return DIENUM_CONTINUE; +} + static const struct dinput_device_vtbl keyboard_internal_vtbl = { NULL, keyboard_internal_acquire, keyboard_internal_unacquire, - NULL, + keyboard_internal_enum_objects, };
static const IDirectInputDevice8WVtbl SysKeyboardWvt = diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 9122799b118..8d208a0bcb1 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -1068,7 +1068,6 @@ static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *ar
winetest_push_context( "obj[%d]", params->index );
- todo_wine_if( obj->dwSize == sizeof(DIDEVICEOBJECTINSTANCE_DX3W) ) check_member( *obj, *exp, "%u", dwSize ); check_member_guid( *obj, *exp, guidType ); todo_wine_if( todo->offset )
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/device.c | 68 ++++++++++++++----------------------- dlls/dinput/joystick_hid.c | 36 +------------------- dlls/dinput/keyboard.c | 64 ++-------------------------------- dlls/dinput/mouse.c | 30 +--------------- dlls/dinput8/tests/device.c | 4 +-- 5 files changed, 31 insertions(+), 171 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 56354e886d1..7a8864a45d2 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -1352,56 +1352,40 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty( return DI_OK; }
-HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo( - LPDIRECTINPUTDEVICE8W iface, - LPDIDEVICEOBJECTINSTANCEW pdidoi, - DWORD dwObj, - DWORD dwHow) +static BOOL CALLBACK get_object_info( const DIDEVICEOBJECTINSTANCEW *instance, void *data ) { - IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface); - DWORD dwSize; - LPDIOBJECTDATAFORMAT odf; - int idx = -1; + DIDEVICEOBJECTINSTANCEW *dest = data; + DWORD size = dest->dwSize;
- TRACE("(%p) %d(0x%08x) -> %p\n", This, dwHow, dwObj, pdidoi); + memcpy( dest, instance, size ); + dest->dwSize = size;
- if (!pdidoi) return E_POINTER; - if (pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCEW) && - pdidoi->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3W)) - return DIERR_INVALIDPARAM; + return DIENUM_STOP; +}
- switch (dwHow) +HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo( IDirectInputDevice8W *iface, DIDEVICEOBJECTINSTANCEW *instance, + DWORD obj, DWORD how ) +{ + IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface ); + const DIPROPHEADER filter = { - case DIPH_BYOFFSET: - if (!This->data_format.offsets) break; - for (idx = This->data_format.wine_df->dwNumObjs - 1; idx >= 0; idx--) - if (This->data_format.offsets[idx] == dwObj) break; - break; - case DIPH_BYID: - dwObj &= 0x00ffffff; - for (idx = This->data_format.wine_df->dwNumObjs - 1; idx >= 0; idx--) - if ((dataformat_to_odf(This->data_format.wine_df, idx)->dwType & 0x00ffffff) == dwObj) - break; - break; + .dwSize = sizeof(filter), + .dwHeaderSize = sizeof(filter), + .dwHow = how, + .dwObj = obj + }; + HRESULT hr;
- case DIPH_BYUSAGE: - FIXME("dwHow = DIPH_BYUSAGE not implemented\n"); - break; - default: - WARN("invalid parameter: dwHow = %08x\n", dwHow); - return DIERR_INVALIDPARAM; - } - if (idx < 0) return DIERR_OBJECTNOTFOUND; + TRACE( "iface %p, instance %p, obj %#x, how %#x.\n", iface, instance, obj, how );
- odf = dataformat_to_odf(This->data_format.wine_df, idx); - dwSize = pdidoi->dwSize; /* save due to memset below */ - memset(pdidoi, 0, pdidoi->dwSize); - pdidoi->dwSize = dwSize; - if (odf->pguid) pdidoi->guidType = *odf->pguid; - pdidoi->dwOfs = odf->dwOfs; - pdidoi->dwType = odf->dwType; - pdidoi->dwFlags = odf->dwFlags; + if (!instance) return E_POINTER; + if (instance->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3W) && instance->dwSize != sizeof(DIDEVICEOBJECTINSTANCEW)) + return DIERR_INVALIDPARAM; + if (how == DIPH_DEVICE) return DIERR_INVALIDPARAM;
+ hr = impl->vtbl->enum_objects( iface, &filter, DIDFT_ALL, get_object_info, instance ); + if (FAILED(hr)) return hr; + if (hr == DIENUM_CONTINUE) return DIERR_NOTFOUND; return DI_OK; }
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 89ad70cbf19..a6715463690 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -950,40 +950,6 @@ static HRESULT WINAPI hid_joystick_GetDeviceState( IDirectInputDevice8W *iface, return hr; }
-static BOOL get_object_info( struct hid_joystick *impl, struct hid_value_caps *caps, - DIDEVICEOBJECTINSTANCEW *instance, void *data ) -{ - DIDEVICEOBJECTINSTANCEW *dest = data; - memcpy( dest, instance, dest->dwSize ); - return DIENUM_STOP; -} - -static HRESULT WINAPI hid_joystick_GetObjectInfo( IDirectInputDevice8W *iface, DIDEVICEOBJECTINSTANCEW *instance, - DWORD obj, DWORD how ) -{ - struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface ); - const DIPROPHEADER filter = - { - .dwSize = sizeof(filter), - .dwHeaderSize = sizeof(filter), - .dwHow = how, - .dwObj = obj - }; - BOOL ret; - - TRACE( "iface %p, instance %p, obj %#x, how %#x.\n", iface, instance, obj, how ); - - if (!instance) return E_POINTER; - if (instance->dwSize != sizeof(DIDEVICEOBJECTINSTANCE_DX3W) && - instance->dwSize != sizeof(DIDEVICEOBJECTINSTANCEW)) - return DIERR_INVALIDPARAM; - if (how == DIPH_DEVICE) return DIERR_INVALIDPARAM; - - ret = enum_objects( impl, &filter, DIDFT_ALL, get_object_info, instance ); - if (ret != DIENUM_CONTINUE) return DI_OK; - return DIERR_NOTFOUND; -} - static HRESULT hid_joystick_effect_create( struct hid_joystick *joystick, IDirectInputEffect **out );
static HRESULT WINAPI hid_joystick_CreateEffect( IDirectInputDevice8W *iface, const GUID *guid, @@ -1342,7 +1308,7 @@ static const IDirectInputDevice8WVtbl hid_joystick_vtbl = IDirectInputDevice2WImpl_SetDataFormat, IDirectInputDevice2WImpl_SetEventNotification, IDirectInputDevice2WImpl_SetCooperativeLevel, - hid_joystick_GetObjectInfo, + IDirectInputDevice2WImpl_GetObjectInfo, IDirectInputDevice2WImpl_GetDeviceInfo, IDirectInputDevice2WImpl_RunControlPanel, IDirectInputDevice2WImpl_Initialize, diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c index 50e292abaad..0d1baec3807 100644 --- a/dlls/dinput/keyboard.c +++ b/dlls/dinput/keyboard.c @@ -273,66 +273,6 @@ static HRESULT WINAPI SysKeyboardWImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W ifac return DI_OK; }
-static DWORD map_dik_to_scan(DWORD dik_code, DWORD subtype) -{ - if (dik_code == DIK_PAUSE || dik_code == DIK_NUMLOCK) dik_code ^= 0x80; - if (subtype == DIDEVTYPEKEYBOARD_JAPAN106) - { - switch (dik_code) - { - case DIK_CIRCUMFLEX: - dik_code = 0x0d; - break; - case DIK_AT: - dik_code = 0x1a; - break; - case DIK_LBRACKET: - dik_code = 0x1b; - break; - case DIK_COLON: - dik_code = 0x28; - break; - case DIK_KANJI: - dik_code = 0x29; - break; - case DIK_RBRACKET: - dik_code = 0x2b; - break; - case DIK_BACKSLASH: - dik_code = 0x73; - break; - } - } - - return dik_code; -} - -/****************************************************************************** - * GetObjectInfo : get information about a device object such as a button - * or axis - */ -static HRESULT WINAPI SysKeyboardWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface, - LPDIDEVICEOBJECTINSTANCEW pdidoi, - DWORD dwObj, - DWORD dwHow) -{ - SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface); - BYTE subtype = GET_DIDEVICE_SUBTYPE( This->base.instance.dwDevType ); - HRESULT res; - LONG scan; - - res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow); - if (res != DI_OK) return res; - - scan = map_dik_to_scan( DIDFT_GETINSTANCE( pdidoi->dwType ), subtype ); - if (!GetKeyNameTextW((scan & 0x80) << 17 | (scan & 0x7f) << 16, - pdidoi->tszName, ARRAY_SIZE(pdidoi->tszName))) - return DIERR_OBJECTNOTFOUND; - - _dump_OBJECTINSTANCEW(pdidoi); - return res; -} - /****************************************************************************** * GetProperty : Retrieves information about the input device. */ @@ -359,7 +299,7 @@ static HRESULT WINAPI SysKeyboardWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface,
didoi.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW);
- hr = SysKeyboardWImpl_GetObjectInfo(iface, &didoi, ps->diph.dwObj, ps->diph.dwHow); + hr = IDirectInputDevice8_GetObjectInfo( iface, &didoi, ps->diph.dwObj, ps->diph.dwHow ); if (hr == DI_OK) memcpy(ps->wsz, didoi.tszName, sizeof(ps->wsz)); return hr; @@ -472,7 +412,7 @@ static const IDirectInputDevice8WVtbl SysKeyboardWvt = IDirectInputDevice2WImpl_SetDataFormat, IDirectInputDevice2WImpl_SetEventNotification, IDirectInputDevice2WImpl_SetCooperativeLevel, - SysKeyboardWImpl_GetObjectInfo, + IDirectInputDevice2WImpl_GetObjectInfo, IDirectInputDevice2WImpl_GetDeviceInfo, IDirectInputDevice2WImpl_RunControlPanel, IDirectInputDevice2WImpl_Initialize, diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index cdbdd083c00..23570e1f906 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -554,34 +554,6 @@ static HRESULT WINAPI SysMouseWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REF return DI_OK; }
-/****************************************************************************** - * GetObjectInfo : get information about a device object such as a button - * or axis - */ -static HRESULT WINAPI SysMouseWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface, - LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) -{ - HRESULT res; - - res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow); - if (res != DI_OK) return res; - - if (IsEqualGUID( &pdidoi->guidType, &GUID_XAxis )) - wcscpy( pdidoi->tszName, L"X-Axis" ); - else if (IsEqualGUID( &pdidoi->guidType, &GUID_YAxis )) - wcscpy( pdidoi->tszName, L"Y-Axis" ); - else if (IsEqualGUID( &pdidoi->guidType, &GUID_ZAxis )) - wcscpy( pdidoi->tszName, L"Wheel" ); - else if (pdidoi->dwType & DIDFT_BUTTON) - swprintf( pdidoi->tszName, MAX_PATH, L"Button %d", DIDFT_GETINSTANCE( pdidoi->dwType ) - 3 ); - - if(pdidoi->dwType & DIDFT_AXIS) - pdidoi->dwFlags |= DIDOI_ASPECTPOSITION; - - _dump_OBJECTINSTANCEW(pdidoi); - return res; -} - static HRESULT mouse_internal_acquire( IDirectInputDevice8W *iface ) { SysMouseImpl *impl = impl_from_IDirectInputDevice8W( iface ); @@ -783,7 +755,7 @@ static const IDirectInputDevice8WVtbl SysMouseWvt = IDirectInputDevice2WImpl_SetDataFormat, IDirectInputDevice2WImpl_SetEventNotification, IDirectInputDevice2WImpl_SetCooperativeLevel, - SysMouseWImpl_GetObjectInfo, + IDirectInputDevice2WImpl_GetObjectInfo, IDirectInputDevice2WImpl_GetDeviceInfo, IDirectInputDevice2WImpl_RunControlPanel, IDirectInputDevice2WImpl_Initialize, diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 8d208a0bcb1..c6cf5867657 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -1413,7 +1413,6 @@ static void test_mouse_info(void) objinst.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW); res = MAKELONG( HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC ); hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYUSAGE ); - todo_wine ok( hr == DIERR_UNSUPPORTED, "GetObjectInfo returned: %#x\n", hr );
hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, DIMOFS_Y, DIPH_BYOFFSET ); @@ -1424,7 +1423,7 @@ static void test_mouse_info(void) check_member( objinst, expect_objects[1], "%#x", dwOfs ); check_member( objinst, expect_objects[1], "%#x", dwType ); check_member( objinst, expect_objects[1], "%#x", dwFlags ); - if (!localized) todo_wine check_member_wstr( objinst, expect_objects[1], tszName ); + if (!localized) check_member_wstr( objinst, expect_objects[1], tszName ); check_member( objinst, expect_objects[1], "%u", dwFFMaxForce ); check_member( objinst, expect_objects[1], "%u", dwFFForceResolution ); check_member( objinst, expect_objects[1], "%u", wCollectionNumber ); @@ -1750,7 +1749,6 @@ static void test_keyboard_info(void) objinst.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW); res = MAKELONG( HID_USAGE_KEYBOARD_LCTRL, HID_USAGE_PAGE_KEYBOARD ); hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, res, DIPH_BYUSAGE ); - todo_wine ok( hr == DIERR_UNSUPPORTED, "GetObjectInfo returned: %#x\n", hr );
hr = IDirectInputDevice8_GetObjectInfo( device, &objinst, 2, DIPH_BYOFFSET );
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=100281
Your paranoid android.
=== w7u_adm (32 bit report) ===
dinput8: device.c:140: Test failed: GetDeviceData() failed: 00000000