diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c index 4d6d53b588e..526cfaeb456 100644 --- a/dlls/dinput/joystick_hid.c +++ b/dlls/dinput/joystick_hid.c @@ -175,7 +175,7 @@ static void set_axis_type( DIDEVICEOBJECTINSTANCEW *instance, BOOL *seen, DWORD static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header, DWORD flags, enum_object_callback callback, void *data ) { - DWORD collection = 0, axis = 0, button = 0, pov = 0, value_ofs = 0, button_ofs = 0, i, j; + DWORD collection = 0, object = 0, axis = 0, button = 0, pov = 0, value_ofs = 0, button_ofs = 0, i, j; struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)impl->preparsed; DIDEVICEOBJECTINSTANCEW instance = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)}; DIDATAFORMAT *format = impl->base.data_format.wine_df; @@ -220,6 +220,7 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header, instance.guidType = *object_usage_to_guid( instance.wUsagePage, instance.wUsage ); instance.wReportId = caps->report_id; instance.wCollectionNumber = caps->link_collection; + object++; switch (instance.wUsage) { @@ -306,12 +307,44 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header, instance.wCollectionNumber = caps->link_collection; ret = enum_object( impl, &filter, flags, callback, caps, &instance, data ); if (ret != DIENUM_CONTINUE) return ret; + object++; } } button_ofs += caps->usage_max - caps->usage_min + 1; } + for (caps = HID_OUTPUT_VALUE_CAPS( preparsed ), caps_end = caps + preparsed->output_caps_count; + caps != caps_end; ++caps) + { + if (!caps->usage_page) continue; + + if (caps->usage_page >= HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN) + { + TRACE( "Ignoring output caps %s, vendor specific.\n", debugstr_hid_value_caps( caps ) ); + if (caps->flags & HID_VALUE_CAPS_IS_BUTTON) button_ofs += caps->usage_max - caps->usage_min + 1; + else value_ofs += (caps->usage_max - caps->usage_min + 1) * sizeof(LONG); + } + else for (j = caps->usage_min; j <= caps->usage_max; ++j) + { + if (caps->flags & HID_VALUE_CAPS_IS_BUTTON) instance.dwOfs = button_ofs; + else instance.dwOfs = value_ofs; + + instance.dwType = DIDFT_NODATA | DIDFT_MAKEINSTANCE( object++ ) | DIDFT_OUTPUT; + instance.dwFlags = 0x80008000; + instance.wUsagePage = caps->usage_page; + instance.wUsage = j; + instance.guidType = GUID_Unknown; + instance.wReportId = caps->report_id; + instance.wCollectionNumber = caps->link_collection; + ret = enum_object( impl, &filter, flags, callback, caps, &instance, data ); + if (ret != DIENUM_CONTINUE) return ret; + + if (caps->flags & HID_VALUE_CAPS_IS_BUTTON) button_ofs++; + else value_ofs += sizeof(LONG); + } + } + for (node = HID_COLLECTION_NODES( preparsed ), node_end = node + preparsed->number_link_collection_nodes; node != node_end; ++node) { diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c index bd84bac0aca..8f6b568eae9 100644 --- a/dlls/dinput8/tests/hid.c +++ b/dlls/dinput8/tests/hid.c @@ -3288,13 +3288,9 @@ static BOOL CALLBACK find_test_device( const DIDEVICEINSTANCEW *devinst, void *c struct check_objects_todos { - BOOL ofs; BOOL type; BOOL flags; - BOOL collection_number; - BOOL usage_page; BOOL usage; - BOOL report_id; }; struct check_objects_params @@ -3319,7 +3315,6 @@ static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *ar check_member( *obj, *exp, "%u", dwSize ); check_member_guid( *obj, *exp, guidType ); - todo_wine_if( todo->ofs ) check_member( *obj, *exp, "%#x", dwOfs ); todo_wine_if( todo->type ) check_member( *obj, *exp, "%#x", dwType ); @@ -3328,16 +3323,13 @@ static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *ar if (!localized) todo_wine check_member_wstr( *obj, *exp, tszName ); check_member( *obj, *exp, "%u", dwFFMaxForce ); check_member( *obj, *exp, "%u", dwFFForceResolution ); - todo_wine_if( todo->collection_number ) check_member( *obj, *exp, "%u", wCollectionNumber ); check_member( *obj, *exp, "%u", wDesignatorIndex ); - todo_wine_if( todo->usage_page ) check_member( *obj, *exp, "%#04x", wUsagePage ); todo_wine_if( todo->usage ) check_member( *obj, *exp, "%#04x", wUsage ); check_member( *obj, *exp, "%#04x", dwDimension ); check_member( *obj, *exp, "%#04x", wExponent ); - todo_wine_if( todo->report_id ) check_member( *obj, *exp, "%u", wReportId ); winetest_pop_context(); @@ -5198,11 +5190,10 @@ static void test_force_feedback_joystick( void ) {}, {.type = TRUE, .flags = TRUE}, {.type = TRUE, .flags = TRUE}, - {.ofs = TRUE, .type = TRUE, .flags = TRUE, .collection_number = TRUE, .usage_page = TRUE, .usage = TRUE, .report_id = TRUE}, - {.ofs = TRUE, .type = TRUE, .flags = TRUE, .collection_number = TRUE, .usage_page = TRUE, .usage = TRUE, .report_id = TRUE}, - {.ofs = TRUE, .type = TRUE, .flags = TRUE, .collection_number = TRUE, .usage = TRUE, .report_id = TRUE}, - {.ofs = TRUE, .type = TRUE, .flags = TRUE, .collection_number = TRUE, .usage = TRUE, .report_id = TRUE}, - {.ofs = TRUE, .type = TRUE, .flags = TRUE, .usage = TRUE, .report_id = TRUE}, + {}, + {.usage = TRUE}, + {}, + {.usage = TRUE}, }; struct check_objects_params check_objects_params = @@ -5302,7 +5293,6 @@ static void test_force_feedback_joystick( void ) hr = IDirectInputDevice8_EnumObjects( device, check_objects, &check_objects_params, DIDFT_ALL ); ok( hr == DI_OK, "IDirectInputDevice8_EnumObjects returned %#x\n", hr ); - todo_wine ok( check_objects_params.index >= check_objects_params.expect_count, "missing %u objects\n", check_objects_params.expect_count - check_objects_params.index );