Rémi Bernon : dinput: Enumerate HID joystick DIDFT_OUTPUT objects.

Alexandre Julliard julliard at winehq.org
Wed Sep 29 15:54:11 CDT 2021


Module: wine
Branch: master
Commit: b468349ec223425d58ce77d9bb9e1d7d9d75b37f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b468349ec223425d58ce77d9bb9e1d7d9d75b37f

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Wed Sep 29 10:24:59 2021 +0200

dinput: Enumerate HID joystick DIDFT_OUTPUT objects.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dinput/joystick_hid.c | 35 ++++++++++++++++++++++++++++++++++-
 dlls/dinput8/tests/hid.c   | 18 ++++--------------
 2 files changed, 38 insertions(+), 15 deletions(-)

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 );
 




More information about the wine-cvs mailing list