[PATCH 11/11] dinput: Implement HID joystick object names from their usages.

Rémi Bernon rbernon at codeweavers.com
Wed Oct 6 03:22:01 CDT 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/joystick_hid.c | 99 +++++++++++++++++++++++++++++++++++++-
 dlls/dinput8/tests/hid.c   |  8 +--
 2 files changed, 102 insertions(+), 5 deletions(-)

diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index 2ef01ac6ace..f8623ce7fdb 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -224,6 +224,89 @@ static const WCHAR *effect_guid_to_string( const GUID *guid )
     return NULL;
 }
 
+static const WCHAR *object_usage_to_string( DIDEVICEOBJECTINSTANCEW *instance )
+{
+    static const WCHAR x_axis_w[] = {'X',' ','A','x','i','s',0};
+    static const WCHAR y_axis_w[] = {'Y',' ','A','x','i','s',0};
+    static const WCHAR z_axis_w[] = {'Z',' ','A','x','i','s',0};
+    static const WCHAR x_rotation_w[] = {'X',' ','R','o','t','a','t','i','o','n',0};
+    static const WCHAR y_rotation_w[] = {'Y',' ','R','o','t','a','t','i','o','n',0};
+    static const WCHAR z_rotation_w[] = {'Z',' ','R','o','t','a','t','i','o','n',0};
+    static const WCHAR wheel_w[] = {'W','h','e','e','l',0};
+    static const WCHAR hat_switch_w[] = {'H','a','t',' ','S','w','i','t','c','h',0};
+    static const WCHAR joystick_w[] = {'J','o','y','s','t','i','c','k',0};
+
+    static const WCHAR dc_device_reset_w[] = {'D','C',' ','D','e','v','i','c','e',' ','R','e','s','e','t',0};
+    static const WCHAR effect_block_index_w[] = {'E','f','f','e','c','t',' ','B','l','o','c','k',' ','I','n','d','e','x',0};
+    static const WCHAR op_effect_start_w[] = {'O','p',' ','E','f','f','e','c','t',' ','S','t','a','r','t',0};
+    static const WCHAR op_effect_start_solo_w[] = {'O','p',' ','E','f','f','e','c','t',' ','S','t','a','r','t',' ','S','o','l','o',0};
+    static const WCHAR op_effect_stop_w[] = {'O','p',' ','E','f','f','e','c','t',' ','S','t','o','p',0};
+    static const WCHAR loop_count_w[] = {'L','o','o','p',' ','C','o','u','n','t',0};
+    static const WCHAR et_square_w[] = {'E','T',' ','S','q','u','a','r','e',0};
+    static const WCHAR et_sine_w[] = {'E','T',' ','S','i','n','e',0};
+    static const WCHAR direction_enable_w[] = {'D','i','r','e','c','t','i','o','n',' ','E','n','a','b','l','e',0};
+    static const WCHAR magnitude_w[] = {'M','a','g','n','i','t','u','d','e',0};
+    static const WCHAR state_report_w[] = {'P','I','D',' ','S','t','a','t','e',' ','R','e','p','o','r','t',0};
+    static const WCHAR device_control_report_w[] = {'P','I','D',' ','D','e','v','i','c','e',' ','C','o','n','t','r','o','l',' ','R','e','p','o','r','t',0};
+    static const WCHAR device_control_w[] = {'P','I','D',' ','D','e','v','i','c','e',' ','C','o','n','t','r','o','l',0};
+    static const WCHAR effect_operation_report_w[] = {'E','f','f','e','c','t',' ','O','p','e','r','a','t','i','o','n',' ','R','e','p','o','r','t',0};
+    static const WCHAR effect_operation_w[] = {'E','f','f','e','c','t',' ','O','p','e','r','a','t','i','o','n',0};
+    static const WCHAR set_effect_report_w[] = {'S','e','t',' ','E','f','f','e','c','t',' ','R','e','p','o','r','t',0};
+    static const WCHAR effect_type_w[] = {'E','f','f','e','c','t',' ','T','y','p','e',0};
+    static const WCHAR axes_enable_w[] = {'A','x','e','s',' ','E','n','a','b','l','e',0};
+    static const WCHAR set_periodic_report_w[] = {'S','e','t',' ','P','e','r','i','o','d','i','c',' ','R','e','p','o','r','t',0};
+    static const WCHAR start_delay_w[] = {'S','t','a','r','t',' ','D','e','l','a','y',0};
+    static const WCHAR duration_w[] = {'D','u','r','a','t','i','o','n',0};
+    static const WCHAR trigger_button_w[] = {'T','r','i','g','g','e','r',' ','B','u','t','t','o','n',0};
+    static const WCHAR fade_level_w[] = {'F','a','d','e',' ','L','e','v','e','l',0};
+    static const WCHAR attack_level_w[] = {'A','t','t','a','c','k',' ','L','e','v','e','l',0};
+    static const WCHAR fade_time_w[] = {'F','a','d','e',' ','T','i','m','e',0};
+    static const WCHAR attack_time_w[] = {'A','t','t','a','c','k',' ','T','i','m','e',0};
+    static const WCHAR set_envelope_report_w[] = {'S','e','t',' ','E','n','v','e','l','o','p','e',' ','R','e','p','o','r','t',0};
+
+    switch (MAKELONG(instance->wUsage, instance->wUsagePage))
+    {
+    case MAKELONG(HID_USAGE_GENERIC_X, HID_USAGE_PAGE_GENERIC): return x_axis_w;
+    case MAKELONG(HID_USAGE_GENERIC_Y, HID_USAGE_PAGE_GENERIC): return y_axis_w;
+    case MAKELONG(HID_USAGE_GENERIC_Z, HID_USAGE_PAGE_GENERIC): return z_axis_w;
+    case MAKELONG(HID_USAGE_GENERIC_RX, HID_USAGE_PAGE_GENERIC): return x_rotation_w;
+    case MAKELONG(HID_USAGE_GENERIC_RY, HID_USAGE_PAGE_GENERIC): return y_rotation_w;
+    case MAKELONG(HID_USAGE_GENERIC_RZ, HID_USAGE_PAGE_GENERIC): return z_rotation_w;
+    case MAKELONG(HID_USAGE_GENERIC_WHEEL, HID_USAGE_PAGE_GENERIC): return wheel_w;
+    case MAKELONG(HID_USAGE_GENERIC_HATSWITCH, HID_USAGE_PAGE_GENERIC): return hat_switch_w;
+    case MAKELONG(HID_USAGE_GENERIC_JOYSTICK, HID_USAGE_PAGE_GENERIC): return joystick_w;
+
+    case MAKELONG(PID_USAGE_DC_DEVICE_RESET, HID_USAGE_PAGE_PID): return dc_device_reset_w;
+    case MAKELONG(PID_USAGE_EFFECT_BLOCK_INDEX, HID_USAGE_PAGE_PID): return effect_block_index_w;
+    case MAKELONG(PID_USAGE_OP_EFFECT_START, HID_USAGE_PAGE_PID): return op_effect_start_w;
+    case MAKELONG(PID_USAGE_OP_EFFECT_START_SOLO, HID_USAGE_PAGE_PID): return op_effect_start_solo_w;
+    case MAKELONG(PID_USAGE_OP_EFFECT_STOP, HID_USAGE_PAGE_PID): return op_effect_stop_w;
+    case MAKELONG(PID_USAGE_LOOP_COUNT, HID_USAGE_PAGE_PID): return loop_count_w;
+    case MAKELONG(PID_USAGE_ET_SQUARE, HID_USAGE_PAGE_PID): return et_square_w;
+    case MAKELONG(PID_USAGE_ET_SINE, HID_USAGE_PAGE_PID): return et_sine_w;
+    case MAKELONG(PID_USAGE_DIRECTION_ENABLE, HID_USAGE_PAGE_PID): return direction_enable_w;
+    case MAKELONG(PID_USAGE_MAGNITUDE, HID_USAGE_PAGE_PID): return magnitude_w;
+    case MAKELONG(PID_USAGE_STATE_REPORT, HID_USAGE_PAGE_PID): return state_report_w;
+    case MAKELONG(PID_USAGE_DEVICE_CONTROL_REPORT, HID_USAGE_PAGE_PID): return device_control_report_w;
+    case MAKELONG(PID_USAGE_DEVICE_CONTROL, HID_USAGE_PAGE_PID): return device_control_w;
+    case MAKELONG(PID_USAGE_EFFECT_OPERATION_REPORT, HID_USAGE_PAGE_PID): return effect_operation_report_w;
+    case MAKELONG(PID_USAGE_EFFECT_OPERATION, HID_USAGE_PAGE_PID): return effect_operation_w;
+    case MAKELONG(PID_USAGE_SET_EFFECT_REPORT, HID_USAGE_PAGE_PID): return set_effect_report_w;
+    case MAKELONG(PID_USAGE_EFFECT_TYPE, HID_USAGE_PAGE_PID): return effect_type_w;
+    case MAKELONG(PID_USAGE_AXES_ENABLE, HID_USAGE_PAGE_PID): return axes_enable_w;
+    case MAKELONG(PID_USAGE_SET_PERIODIC_REPORT, HID_USAGE_PAGE_PID): return set_periodic_report_w;
+    case MAKELONG(PID_USAGE_START_DELAY, HID_USAGE_PAGE_PID): return start_delay_w;
+    case MAKELONG(PID_USAGE_DURATION, HID_USAGE_PAGE_PID): return duration_w;
+    case MAKELONG(PID_USAGE_TRIGGER_BUTTON, HID_USAGE_PAGE_PID): return trigger_button_w;
+    case MAKELONG(PID_USAGE_FADE_LEVEL, HID_USAGE_PAGE_PID): return fade_level_w;
+    case MAKELONG(PID_USAGE_ATTACK_LEVEL, HID_USAGE_PAGE_PID): return attack_level_w;
+    case MAKELONG(PID_USAGE_FADE_TIME, HID_USAGE_PAGE_PID): return fade_time_w;
+    case MAKELONG(PID_USAGE_ATTACK_TIME, HID_USAGE_PAGE_PID): return attack_time_w;
+    case MAKELONG(PID_USAGE_SET_ENVELOPE_REPORT, HID_USAGE_PAGE_PID): return set_envelope_report_w;
+    default: return NULL;
+    }
+}
+
 typedef BOOL (*enum_object_callback)( struct hid_joystick *impl, struct hid_value_caps *caps,
                                       DIDEVICEOBJECTINSTANCEW *instance, void *data );
 
@@ -282,7 +365,10 @@ 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, object = 0, axis = 0, button = 0, pov = 0, value_ofs = 0, button_ofs = 0, i, j;
+    static const WCHAR collection_format_w[] = {'C','o','l','l','e','c','t','i','o','n',' ','%','u',' ','-',' ',0};
+    static const WCHAR usage_format_w[] = {'U','s','a','g','e',' ','%','0','4','x',':','%','0','4','x',0};
+    static const WCHAR button_format_w[] = {'B','u','t','t','o','n',' ','%','u',0};
+    DWORD collection = 0, object = 0, axis = 0, button = 0, pov = 0, value_ofs = 0, button_ofs = 0, len, i, j;
     struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)impl->preparsed;
     DIDEVICEOBJECTINSTANCEW instance = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)};
     struct hid_value_caps *caps, *caps_end, *nary, *nary_end, *effect_caps;
@@ -291,6 +377,7 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header,
     struct hid_collection_node *node, *node_end;
     DIPROPHEADER filter = *header;
     BOOL ret, seen_axis[6] = {0};
+    const WCHAR *tmp;
 
     if (filter.dwHow == DIPH_BYOFFSET)
     {
@@ -350,6 +437,8 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header,
             instance.wCollectionNumber = caps->link_collection;
             instance.dwDimension = caps->units;
             instance.wExponent = caps->units_exp;
+            if ((tmp = object_usage_to_string( &instance ))) lstrcpynW( instance.tszName, tmp, MAX_PATH );
+            else snprintfW( instance.tszName, MAX_PATH, usage_format_w, instance.wUsagePage, instance.wUsage );
             check_pid_effect_axis_caps( impl, &instance );
             ret = enum_object( impl, &filter, flags, callback, caps, &instance, data );
             if (ret != DIENUM_CONTINUE) return ret;
@@ -388,6 +477,7 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header,
             instance.wCollectionNumber = caps->link_collection;
             instance.dwDimension = caps->units;
             instance.wExponent = caps->units_exp;
+            snprintfW( instance.tszName, MAX_PATH, button_format_w, DIDFT_GETINSTANCE( instance.dwType ) );
             ret = enum_object( impl, &filter, flags, callback, caps, &instance, data );
             if (ret != DIENUM_CONTINUE) return ret;
             button_ofs++;
@@ -423,6 +513,8 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header,
                 instance.wCollectionNumber = nary->link_collection;
                 instance.dwDimension = caps->units;
                 instance.wExponent = caps->units_exp;
+                if ((tmp = object_usage_to_string( &instance ))) lstrcpynW( instance.tszName, tmp, MAX_PATH );
+                else snprintfW( instance.tszName, MAX_PATH, usage_format_w, instance.wUsagePage, instance.wUsage );
                 ret = enum_object( impl, &filter, flags, callback, nary, &instance, data );
                 if (ret != DIENUM_CONTINUE) return ret;
                 button_ofs++;
@@ -442,6 +534,8 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header,
             instance.wCollectionNumber = caps->link_collection;
             instance.dwDimension = caps->units;
             instance.wExponent = caps->units_exp;
+            if ((tmp = object_usage_to_string( &instance ))) lstrcpynW( instance.tszName, tmp, MAX_PATH );
+            else snprintfW( instance.tszName, MAX_PATH, usage_format_w, instance.wUsagePage, instance.wUsage );
             ret = enum_object( impl, &filter, flags, callback, caps, &instance, data );
             if (ret != DIENUM_CONTINUE) return ret;
 
@@ -468,6 +562,9 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *header,
             instance.wCollectionNumber = node->parent;
             instance.dwDimension = 0;
             instance.wExponent = 0;
+            len = snprintfW( instance.tszName, MAX_PATH, collection_format_w, DIDFT_GETINSTANCE( instance.dwType ) );
+            if ((tmp = object_usage_to_string( &instance ))) lstrcpynW( instance.tszName + len, tmp, MAX_PATH - len );
+            else snprintfW( instance.tszName + len, MAX_PATH - len, usage_format_w, instance.wUsagePage, instance.wUsage );
             ret = enum_object( impl, &filter, flags, callback, NULL, &instance, data );
             if (ret != DIENUM_CONTINUE) return ret;
         }
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index e55adb0aa56..4e02fe73394 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -3315,7 +3315,7 @@ static BOOL CALLBACK check_objects( const DIDEVICEOBJECTINSTANCEW *obj, void *ar
     check_member( *obj, *exp, "%#x", dwOfs );
     check_member( *obj, *exp, "%#x", dwType );
     check_member( *obj, *exp, "%#x", dwFlags );
-    if (!localized) todo_wine check_member_wstr( *obj, *exp, tszName );
+    if (!localized) check_member_wstr( *obj, *exp, tszName );
     check_member( *obj, *exp, "%u", dwFFMaxForce );
     check_member( *obj, *exp, "%u", dwFFForceResolution );
     check_member( *obj, *exp, "%u", wCollectionNumber );
@@ -4022,7 +4022,7 @@ static void test_simple_joystick(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 );
@@ -4049,7 +4049,7 @@ static void test_simple_joystick(void)
     check_member( objinst, expect_objects[5], "%#x", dwOfs );
     check_member( objinst, expect_objects[5], "%#x", dwType );
     check_member( objinst, expect_objects[5], "%#x", dwFlags );
-    if (!localized) todo_wine check_member_wstr( objinst, expect_objects[5], tszName );
+    if (!localized) check_member_wstr( objinst, expect_objects[5], tszName );
     check_member( objinst, expect_objects[5], "%u", dwFFMaxForce );
     check_member( objinst, expect_objects[5], "%u", dwFFForceResolution );
     check_member( objinst, expect_objects[5], "%u", wCollectionNumber );
@@ -4107,7 +4107,7 @@ static void test_simple_joystick(void)
     check_member( objinst, expect_objects[0], "%#x", dwOfs );
     check_member( objinst, expect_objects[0], "%#x", dwType );
     check_member( objinst, expect_objects[0], "%#x", dwFlags );
-    if (!localized) todo_wine check_member_wstr( objinst, expect_objects[0], tszName );
+    if (!localized) check_member_wstr( objinst, expect_objects[0], tszName );
     check_member( objinst, expect_objects[0], "%u", dwFFMaxForce );
     check_member( objinst, expect_objects[0], "%u", dwFFForceResolution );
     check_member( objinst, expect_objects[0], "%u", wCollectionNumber );
-- 
2.33.0




More information about the wine-devel mailing list