Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- 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 | 93 ++++++++++++++++++++++++++++++++++++ dlls/dinput/device_private.h | 6 +++ dlls/dinput/joystick_hid.c | 89 +++++----------------------------- 3 files changed, 112 insertions(+), 76 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index e2d2e551d02..03c10c7360f 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,95 @@ HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl * *out = This; return DI_OK; } + +static const GUID *object_instance_guid( const DIDEVICEOBJECTINSTANCEW *instance ) +{ + switch (instance->wUsagePage) + { + case HID_USAGE_PAGE_BUTTON: return &GUID_Button; + case HID_USAGE_PAGE_GENERIC: + switch (instance->wUsage) + { + case HID_USAGE_GENERIC_X: return &GUID_XAxis; + case HID_USAGE_GENERIC_Y: return &GUID_YAxis; + case HID_USAGE_GENERIC_Z: return &GUID_ZAxis; + case HID_USAGE_GENERIC_WHEEL: return &GUID_ZAxis; + case HID_USAGE_GENERIC_RX: return &GUID_RxAxis; + case HID_USAGE_GENERIC_RY: return &GUID_RyAxis; + case HID_USAGE_GENERIC_RZ: return &GUID_RzAxis; + case HID_USAGE_GENERIC_SLIDER: return &GUID_Slider; + case HID_USAGE_GENERIC_HATSWITCH: return &GUID_POV; + } + break; + } + + 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 03c10c7360f..bee9ac8ab45 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 );
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 bee9ac8ab45..72b6e85a900 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 72b6e85a900..415bc1fa4db 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 );