Signed-off-by: Rémi Bernon rbernon@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 );