From: Peter Hutterer Date: Fri, 15 Jun 2018 03:51:43 +0000 (+1000) Subject: Add libevdev_event_value_get_name() to resolve ABS_MT_TOOL_TYPE values X-Git-Tag: libevdev-1.6.0~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1e605f62823240c749476ab820f5c6baa8ad038a;p=platform%2Fupstream%2Flibevdev.git Add libevdev_event_value_get_name() to resolve ABS_MT_TOOL_TYPE values ABS_MT_TOOL_TYPE values are an enum, not a numerical value like all other axes. So let's allow converting those values to string. Fixes https://gitlab.freedesktop.org/libevdev/libevdev/issues/1 Signed-off-by: Peter Hutterer Reviewed-by: Benjamin Tissoires --- diff --git a/libevdev/libevdev-names.c b/libevdev/libevdev-names.c index ad318de..6d06df3 100644 --- a/libevdev/libevdev-names.c +++ b/libevdev/libevdev-names.c @@ -143,6 +143,29 @@ libevdev_event_code_from_name_n(unsigned int type, const char *name, size_t len) } LIBEVDEV_EXPORT int +libevdev_event_value_from_name(unsigned int type, unsigned int code, const char *name) +{ + return libevdev_event_value_from_name_n(type, code, name, strlen(name)); +} + +LIBEVDEV_EXPORT int +libevdev_event_value_from_name_n(unsigned int type, unsigned int code, const char *name, size_t len) +{ + struct name_lookup lookup; + const struct name_entry *entry; + + if (type != EV_ABS || code != ABS_MT_TOOL_TYPE) + return -1; + + lookup.name = name; + lookup.len = len; + + entry = lookup_name(tool_type_names, ARRAY_LENGTH(tool_type_names), &lookup); + + return entry ? (int)entry->value : -1; +} + +LIBEVDEV_EXPORT int libevdev_property_from_name(const char *name) { return libevdev_property_from_name_n(name, strlen(name)); diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c index c6ec114..fab87cf 100644 --- a/libevdev/libevdev.c +++ b/libevdev/libevdev.c @@ -1613,6 +1613,23 @@ libevdev_event_code_get_name(unsigned int type, unsigned int code) return event_type_map[type][code]; } +LIBEVDEV_EXPORT const char * +libevdev_event_value_get_name(unsigned int type, + unsigned int code, + int value) +{ + /* This is a simplified version because nothing else + is an enum like ABS_MT_TOOL_TYPE so we don't need + a generic lookup */ + if (type != EV_ABS || code != ABS_MT_TOOL_TYPE) + return NULL; + + if (value > MT_TOOL_MAX) + return NULL; + + return mt_tool_map[value]; +} + LIBEVDEV_EXPORT const char* libevdev_property_get_name(unsigned int prop) { diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h index 4c516ad..f0f34bb 100644 --- a/libevdev/libevdev.h +++ b/libevdev/libevdev.h @@ -2022,6 +2022,29 @@ const char * libevdev_event_code_get_name(unsigned int type, unsigned int code); /** * @ingroup misc * + * This function resolves the event value for a code. + * + * For almost all event codes this will return NULL as the value is just a + * numerical value. As of kernel 4.17, the only event code that will return + * a non-NULL value is EV_ABS/ABS_MT_TOOL_TYPE. + * + * @param type The event type for the value to query (EV_ABS, etc.) + * @param code The event code for the value to query (e.g. ABS_MT_TOOL_TYPE) + * @param value The event value to return the name for (e.g. MT_TOOL_PALM) + * + * @return The name of the given event value (e.g. MT_TOOL_PALM) or NULL for + * an invalid type or code or NULL for an axis that has numerical values + * only. + * + * @note The list of names is compiled into libevdev. If the kernel adds new + * defines for new event values, libevdev will not automatically pick these up. + */ +const char * libevdev_event_value_get_name(unsigned int type, + unsigned int code, + int value); +/** + * @ingroup misc + * * @param prop The input prop to return the name for (e.g. INPUT_PROP_BUTTONPAD) * * @return The name of the given input prop (e.g. INPUT_PROP_BUTTONPAD) or NULL for an @@ -2130,6 +2153,56 @@ int libevdev_event_code_from_name_n(unsigned int type, const char *name, /** * @ingroup misc * + * Look up an event value by its type, code and name. Event values start + * with a fixed prefix followed by their name (eg., "MT_TOOL_PALM"). The + * prefix must be included in the name. It returns the constant assigned + * to the event code or -1 if not found. + * + * You have to pass the event type and code where to look for the name. For + * instance, to resolve "MT_TOOL_PALM" you need to pass EV_ABS as type, + * ABS_MT_TOOL_TYPE as code and "MT_TOOL_PALM" as string. + * + * As of kernel 4.17, only EV_ABS/ABS_MT_TOOL_TYPE support name resolution. + * + * @param type The event type (EV_* constant) where to look for the name. + * @param code The event code (ABS_* constant) where to look for the name. + * @param name A non-NULL string describing an input-event value + * ("MT_TOOL_TYPE", ...) + * + * @return The given value constant for the name or -1 if not found. + */ +int libevdev_event_value_from_name(unsigned int type, unsigned int code, + const char *name); + +/** + * @ingroup misc + * + * Look up an event value by its type, code and name. Event values start + * with a fixed prefix followed by their name (eg., "MT_TOOL_PALM"). The + * prefix must be included in the name. It returns the constant assigned + * to the event code or -1 if not found. + * + * You have to pass the event type and code where to look for the name. For + * instance, to resolve "MT_TOOL_PALM" you need to pass EV_ABS as type, + * ABS_MT_TOOL_TYPE as code and "MT_TOOL_PALM" as string. + * + * As of kernel 4.17, only EV_ABS/ABS_MT_TOOL_TYPE support name resolution. + * + * @param type The event type (EV_* constant) where to look for the name. + * @param code The event code (ABS_* constant) where to look for the name. + * @param name A non-NULL string describing an input-event value + * ("MT_TOOL_TYPE", ...) + * @param len The length of the string in @p name excluding any terminating 0 + * character. + * + * @return The given value constant for the name or -1 if not found. + */ +int libevdev_event_value_from_name_n(unsigned int type, unsigned int code, + const char *name, size_t len); + +/** + * @ingroup misc + * * Look up an input property by its name. Properties start with the fixed * prefix "INPUT_PROP_" followed by their name (eg., "INPUT_PROP_POINTER"). * The prefix must be included in the name. It returns the constant assigned diff --git a/libevdev/libevdev.sym b/libevdev/libevdev.sym index 374712f..7dd0c20 100644 --- a/libevdev/libevdev.sym +++ b/libevdev/libevdev.sym @@ -112,3 +112,12 @@ global: local: *; } LIBEVDEV_1; + +LIBEVDEV_1_6 { +global: + libevdev_event_value_get_name; + libevdev_event_value_from_name; + libevdev_event_value_from_name_n; +local: + *; +} LIBEVDEV_1_3; diff --git a/libevdev/make-event-names.py b/libevdev/make-event-names.py index 38b44cf..8d572d0 100755 --- a/libevdev/make-event-names.py +++ b/libevdev/make-event-names.py @@ -26,6 +26,7 @@ prefixes = [ "SYN_", "REP_", "INPUT_PROP_", + "MT_TOOL_", ] duplicates = [ @@ -39,6 +40,7 @@ duplicates = [ "BTN_TRIGGER_HAPPY", "SW_MAX", "REP_MAX", + "MT_TOOL_MAX", ] btn_additional = [ @@ -78,7 +80,7 @@ def print_map(bits): print("static const char * const * const event_type_map[EV_MAX + 1] = {") for prefix in prefixes: - if prefix in ["BTN_", "EV_", "INPUT_PROP_"]: + if prefix in ["BTN_", "EV_", "INPUT_PROP_", "MT_TOOL_"]: continue print(" [EV_%s] = %s_map," % (prefix[:-1], prefix[:-1].lower())) @@ -95,7 +97,7 @@ def print_map(bits): print("static const int ev_max[EV_MAX + 1] = {") print(" [0 ... EV_MAX] = -1,") for prefix in prefixes: - if prefix in ["BTN_", "EV_", "INPUT_PROP_"]: + if prefix in ["BTN_", "EV_", "INPUT_PROP_", "MT_TOOL_"]: continue print(" [EV_%s] = %s_MAX," % (prefix[:-1], prefix[:-1])) print("};") @@ -129,6 +131,10 @@ def print_lookup_table(bits): print(" unsigned int value;") print("};") print("") + print("static const struct name_entry tool_type_names[] = {") + print_lookup(bits, "mt_tool") + print("};") + print("") print("static const struct name_entry ev_names[] = {") print_lookup(bits, "ev") print("};") diff --git a/test/test-event-codes.c b/test/test-event-codes.c index 8b587d9..643b537 100644 --- a/test/test-event-codes.c +++ b/test/test-event-codes.c @@ -114,6 +114,28 @@ START_TEST(test_code_names_max) } END_TEST +START_TEST(test_value_names) +{ + ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_PALM"), MT_TOOL_PALM); + ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_FINGER"), MT_TOOL_FINGER); + ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_PEN"), MT_TOOL_PEN); + ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_MAX"), MT_TOOL_MAX); +} +END_TEST + +START_TEST(test_value_names_invalid) +{ + ck_assert_int_eq(libevdev_event_value_from_name(EV_SYN, REL_X, "MT_TOOL_PALM"), -1); + ck_assert_int_eq(libevdev_event_value_from_name(EV_REL, REL_X, "MT_TOOL_PALM"), -1); + ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_X, "MT_TOOL_PALM"), -1); + ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_"), -1); + ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "MT_TOOL_PALMA"), -1); + ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, ""), -1); + ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "EV_ABS"), -1); + ck_assert_int_eq(libevdev_event_value_from_name(EV_ABS, ABS_MT_TOOL_TYPE, "ABS_X"), -1); +} +END_TEST + START_TEST(test_properties) { struct prop { @@ -161,6 +183,11 @@ TEST_SUITE(event_code_suite) tcase_add_test(tc, test_code_names_max); suite_add_tcase(s, tc); + tc = tcase_create("value tests"); + tcase_add_test(tc, test_value_names); + tcase_add_test(tc, test_value_names_invalid); + suite_add_tcase(s, tc); + tc = tcase_create("property tests"); tcase_add_test(tc, test_properties); tcase_add_test(tc, test_properties_invalid); diff --git a/test/test-event-names.c b/test/test-event-names.c index 9ed23d0..0116fab 100644 --- a/test/test-event-names.c +++ b/test/test-event-names.c @@ -36,6 +36,7 @@ START_TEST(test_limits) ck_assert(libevdev_event_code_get_name(EV_REP, REP_MAX + 1) == NULL); ck_assert(libevdev_event_code_get_name(EV_FF, FF_MAX + 1) == NULL); ck_assert(libevdev_event_code_get_name(EV_MAX + 1, 0) == NULL); + ck_assert(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_MAX + 1) == NULL); } END_TEST @@ -201,6 +202,35 @@ START_TEST(test_code_syn_name) } END_TEST +START_TEST(test_value_name) +{ + unsigned int type, code; + int value; + + for (type = 0; type < EV_MAX; type++) { + int max = libevdev_event_type_get_max(type); + + if (max == -1) + continue; + + for (code = 0; code < (unsigned int)max; code++) { + if (type == EV_ABS && code == ABS_MT_TOOL_TYPE) + continue; + + for (value = 0; value < 0xff; value++) { + ck_assert(libevdev_event_value_get_name(type, code, value) == NULL); + } + } + } + + ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER), "MT_TOOL_FINGER"); + ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM), "MT_TOOL_PALM"); + ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PEN), "MT_TOOL_PEN"); + /* overlapping value */ + ck_assert_str_eq(libevdev_event_value_get_name(EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_MAX), "MT_TOOL_PALM"); +} +END_TEST + START_TEST(test_prop_name) { ck_assert_str_eq(libevdev_property_get_name(INPUT_PROP_POINTER), "INPUT_PROP_POINTER"); @@ -297,6 +327,10 @@ TEST_SUITE(event_name_suite) tcase_add_test(tc, test_code_syn_name); suite_add_tcase(s, tc); + tc = tcase_create("value names"); + tcase_add_test(tc, test_value_name); + suite_add_tcase(s, tc); + tc = tcase_create("prop names"); tcase_add_test(tc, test_prop_name); suite_add_tcase(s, tc);