[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