From: Peter Hutterer Date: Tue, 19 Mar 2019 01:44:33 +0000 (+1000) Subject: Add a code-based name lookup function X-Git-Tag: libevdev-1.6.901~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9fe185dd3d4d43929a36af351013909b52ce3416;p=platform%2Fupstream%2Flibevdev.git Add a code-based name lookup function Two new function pairs: libevdev_event_code_from_code_name() libevdev_event_type_from_code_name() libevdev_event_code_from_code_name_n() libevdev_event_type_from_code_name_n() These functions look up event codes/types by the name of the event code only, removing the need to figure out what event type an event code has. So if all you have is "BTN_TOUCH", you can now look up the type and code for that, without having to check the prefix yourself to guess at the type. Signed-off-by: Peter Hutterer --- diff --git a/libevdev/libevdev-names.c b/libevdev/libevdev-names.c index 6d06df3..82abddc 100644 --- a/libevdev/libevdev-names.c +++ b/libevdev/libevdev-names.c @@ -184,3 +184,46 @@ libevdev_property_from_name_n(const char *name, size_t len) return entry ? (int)entry->value : -1; } + +LIBEVDEV_EXPORT int +libevdev_event_code_from_code_name(const char *name) +{ + return libevdev_event_code_from_code_name_n(name, strlen(name)); +} + +LIBEVDEV_EXPORT int +libevdev_event_code_from_code_name_n(const char *name, size_t len) +{ + const struct name_entry *entry; + struct name_lookup lookup; + + /* now look up the name @name and return the constant */ + lookup.name = name; + lookup.len = len; + + entry = lookup_name(code_names, ARRAY_LENGTH(code_names), &lookup); + + return entry ? (int)entry->value : -1; +} + +LIBEVDEV_EXPORT int +libevdev_event_type_from_code_name(const char *name) +{ + return libevdev_event_type_from_code_name_n(name, strlen(name)); +} + +LIBEVDEV_EXPORT int +libevdev_event_type_from_code_name_n(const char *name, size_t len) +{ + const struct name_entry *entry; + struct name_lookup lookup; + + /* First look up if the name exists, we dont' want to return a valid + * type for an invalid code name */ + lookup.name = name; + lookup.len = len; + + entry = lookup_name(code_names, ARRAY_LENGTH(code_names), &lookup); + + return entry ? type_from_prefix(name, len) : -1; +} diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h index 198b684..3027d2e 100644 --- a/libevdev/libevdev.h +++ b/libevdev/libevdev.h @@ -2177,6 +2177,84 @@ int libevdev_event_value_from_name(unsigned int type, unsigned int code, /** * @ingroup misc * + * Look up an event type for a event code name. For example, the name + * "ABS_Y" returns EV_ABS. For the lookup to succeed, the name must be + * unique, which is the case for all #defines as of kernel 5.0 and likely to + * be the case in the future. + * + * This is equivalent to libevdev_event_type_from_name() but takes the code + * name instead of the type name. + * + * @param name A non-NULL string describing an input-event value + * ("ABS_X", "REL_Y", "KEY_A", ...) + * + * @return The given event code for the name or -1 if not found. + */ +int +libevdev_event_type_from_code_name(const char *name); + +/** + * @ingroup misc + * + * Look up an event type for a event code name. For example, the name + * "ABS_Y" returns EV_ABS. For the lookup to succeed, the name must be + * unique, which is the case for all #defines as of kernel 5.0 and likely to + * be the case in the future. + * + * This is equivalent to libevdev_event_type_from_name_n() but takes the code + * name instead of the type name. + * + * @param name A non-NULL string describing an input-event value + * ("ABS_X", "REL_Y", "KEY_A", ...) + * @param len The length of the passed string excluding any terminating 0 + * character. + * + * @return The given event code for the name or -1 if not found. + */ +int +libevdev_event_type_from_code_name_n(const char *name, size_t len); + +/** + * @ingroup misc + * + * Look up an event code by its name. For example, the name "ABS_Y" returns + * 1. For the lookup to succeed, the name must be unique, which is the case + * for all #defines as of kernel 5.0 and likely to be the case in the future. + * + * This is equivalent to libevdev_event_code_from_name() without the need + * for knowing the event type. + * + * @param name A non-NULL string describing an input-event value + * ("ABS_X", "REL_Y", "KEY_A", ...) + * + * @return The given event code for the name or -1 if not found. + */ +int +libevdev_event_code_from_code_name(const char *name); + +/** + * @ingroup misc + * + * Look up an event code by its name. For example, the name "ABS_Y" returns + * 1. For the lookup to succeed, the name must be unique, which is the case + * for all #defines as of kernel 5.0 and likely to be the case in the future. + * + * This is equivalent to libevdev_event_code_from_name_n() without the need + * for knowing the event type. + * + * @param name A non-NULL string describing an input-event value + * ("ABS_X", "REL_Y", "KEY_A", ...) + * @param len The length of the passed string excluding any terminating 0 + * character. + * + * @return The given event code for the name or -1 if not found. + */ +int +libevdev_event_code_from_code_name_n(const char *name, size_t len); + +/** + * @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 diff --git a/libevdev/libevdev.sym b/libevdev/libevdev.sym index 7dd0c20..d034669 100644 --- a/libevdev/libevdev.sym +++ b/libevdev/libevdev.sym @@ -121,3 +121,13 @@ global: local: *; } LIBEVDEV_1_3; + +LIBEVDEV_1_7 { +global: + libevdev_event_code_from_code_name; + libevdev_event_code_from_code_name_n; + libevdev_event_type_from_code_name; + libevdev_event_type_from_code_name_n; +local: + *; +} LIBEVDEV_1_6; diff --git a/test/test-event-codes.c b/test/test-event-codes.c index 643b537..b4e6d02 100644 --- a/test/test-event-codes.c +++ b/test/test-event-codes.c @@ -55,6 +55,41 @@ START_TEST(test_type_names_invalid) } END_TEST +START_TEST(test_type_name_lookup) +{ + ck_assert_int_eq(libevdev_event_type_from_code_name("SYN_REPORT"), EV_SYN); + ck_assert_int_eq(libevdev_event_type_from_code_name("KEY_A"), EV_KEY); + ck_assert_int_eq(libevdev_event_type_from_code_name("REL_Z"), EV_REL); + ck_assert_int_eq(libevdev_event_type_from_code_name("ABS_Z"), EV_ABS); + ck_assert_int_eq(libevdev_event_type_from_code_name("MSC_SERIAL"), EV_MSC); + ck_assert_int_eq(libevdev_event_type_from_code_name("SND_TONE"), EV_SND); + ck_assert_int_eq(libevdev_event_type_from_code_name("SW_TABLET_MODE"), EV_SW); + ck_assert_int_eq(libevdev_event_type_from_code_name("LED_CHARGING"), EV_LED); + ck_assert_int_eq(libevdev_event_type_from_code_name("REP_PERIOD"), EV_REP); + ck_assert_int_eq(libevdev_event_type_from_code_name("FF_SPRING"), EV_FF); + ck_assert_int_eq(libevdev_event_type_from_code_name("FF_STATUS_STOPPED"), EV_FF_STATUS); + + ck_assert_int_eq(libevdev_event_type_from_code_name_n("KEY_1zzzzz", 5), EV_KEY); + ck_assert_int_eq(libevdev_event_type_from_code_name_n("ABS_Zooom", 5), EV_ABS); + + ck_assert_int_eq(libevdev_event_type_from_code_name("KEY_MAX"), EV_KEY); + ck_assert_int_eq(libevdev_event_type_from_code_name("REL_MAX"), EV_REL); + ck_assert_int_eq(libevdev_event_type_from_code_name("ABS_MAX"), EV_ABS); +} +END_TEST + +START_TEST(test_type_name_lookup_invalid) +{ + ck_assert_int_eq(libevdev_event_type_from_name("SYN_REPORTED"), -1); + ck_assert_int_eq(libevdev_event_type_from_name("syn_blah"), -1); + ck_assert_int_eq(libevdev_event_type_from_name("SYN_"), -1); + ck_assert_int_eq(libevdev_event_type_from_name("KEY_BANANA"), -1); + + ck_assert_int_eq(libevdev_event_type_from_name_n("KEY_BA", 6), -1); + ck_assert_int_eq(libevdev_event_type_from_name_n("KEY_BLAH", 8), -1); +} +END_TEST + START_TEST(test_code_names) { ck_assert_int_eq(libevdev_event_code_from_name(EV_SYN, "SYN_REPORT"), SYN_REPORT); @@ -78,6 +113,30 @@ START_TEST(test_code_names) } END_TEST +START_TEST(test_code_name_lookup) +{ + /* Same as test_code_names() but without the type */ + ck_assert_int_eq(libevdev_event_code_from_code_name("SYN_REPORT"), SYN_REPORT); + ck_assert_int_eq(libevdev_event_code_from_code_name("ABS_X"), ABS_X); + ck_assert_int_eq(libevdev_event_code_from_code_name("BTN_A"), BTN_A); + ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_A"), KEY_A); + ck_assert_int_eq(libevdev_event_code_from_code_name("REL_X"), REL_X); + ck_assert_int_eq(libevdev_event_code_from_code_name("MSC_RAW"), MSC_RAW); + ck_assert_int_eq(libevdev_event_code_from_code_name("LED_KANA"), LED_KANA); + ck_assert_int_eq(libevdev_event_code_from_code_name("SND_BELL"), SND_BELL); + ck_assert_int_eq(libevdev_event_code_from_code_name("REP_DELAY"), REP_DELAY); + ck_assert_int_eq(libevdev_event_code_from_code_name("SYN_DROPPED"), SYN_DROPPED); + ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_RESERVED"), KEY_RESERVED); + ck_assert_int_eq(libevdev_event_code_from_code_name("BTN_0"), BTN_0); + ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_0"), KEY_0); + ck_assert_int_eq(libevdev_event_code_from_code_name("FF_GAIN"), FF_GAIN); + ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS_MAX"), FF_STATUS_MAX); + ck_assert_int_eq(libevdev_event_code_from_code_name("SW_PEN_INSERTED"), SW_PEN_INSERTED); + + ck_assert_int_eq(libevdev_event_code_from_code_name_n("ABS_YXZ", 5), ABS_Y); +} +END_TEST + START_TEST(test_code_names_invalid) { ck_assert_int_eq(libevdev_event_code_from_name(EV_MAX, "MAX_FAKE"), -1); @@ -99,6 +158,28 @@ START_TEST(test_code_names_invalid) } END_TEST +START_TEST(test_code_name_lookup_invalid) +{ + /* Same as test_code_names_invalid() but without the type */ + ck_assert_int_eq(libevdev_event_code_from_code_name("MAX_FAKE"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("CNT_FAKE"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("PWR_SOMETHING"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("EV_ABS"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("ABS_XY"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("BTN_GAMEPAD"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("BUS_PCI"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS_"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("FF_STATUS_"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("ID_BUS"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("SND_CNT"), -1); + ck_assert_int_eq(libevdev_event_code_from_code_name("SW_CNT"), -1); + + ck_assert_int_eq(libevdev_event_code_from_code_name_n("ABS_X", 4), -1); +} +END_TEST + START_TEST(test_code_names_max) { ck_assert_int_eq(libevdev_event_code_from_name(EV_SYN, "SYN_MAX"), SYN_MAX); @@ -111,6 +192,17 @@ START_TEST(test_code_names_max) ck_assert_int_eq(libevdev_event_code_from_name(EV_SND, "SND_MAX"), SND_MAX); ck_assert_int_eq(libevdev_event_code_from_name(EV_REP, "REP_MAX"), REP_MAX); ck_assert_int_eq(libevdev_event_code_from_name(EV_FF, "FF_MAX"), FF_MAX); + + ck_assert_int_eq(libevdev_event_code_from_code_name("SYN_MAX"), SYN_MAX); + ck_assert_int_eq(libevdev_event_code_from_code_name("KEY_MAX"), KEY_MAX); + ck_assert_int_eq(libevdev_event_code_from_code_name("REL_MAX"), REL_MAX); + ck_assert_int_eq(libevdev_event_code_from_code_name("ABS_MAX"), ABS_MAX); + ck_assert_int_eq(libevdev_event_code_from_code_name("MSC_MAX"), MSC_MAX); + ck_assert_int_eq(libevdev_event_code_from_code_name("SW_MAX"), SW_MAX); + ck_assert_int_eq(libevdev_event_code_from_code_name("LED_MAX"), LED_MAX); + ck_assert_int_eq(libevdev_event_code_from_code_name("SND_MAX"), SND_MAX); + ck_assert_int_eq(libevdev_event_code_from_code_name("REP_MAX"), REP_MAX); + ck_assert_int_eq(libevdev_event_code_from_code_name("FF_MAX"), FF_MAX); } END_TEST @@ -175,11 +267,15 @@ TEST_SUITE(event_code_suite) TCase *tc = tcase_create("type tests"); tcase_add_test(tc, test_type_names); tcase_add_test(tc, test_type_names_invalid); + tcase_add_test(tc, test_type_name_lookup); + tcase_add_test(tc, test_type_name_lookup_invalid); suite_add_tcase(s, tc); tc = tcase_create("code tests"); tcase_add_test(tc, test_code_names); + tcase_add_test(tc, test_code_name_lookup); tcase_add_test(tc, test_code_names_invalid); + tcase_add_test(tc, test_code_name_lookup_invalid); tcase_add_test(tc, test_code_names_max); suite_add_tcase(s, tc);