mirror of
https://gitlab.freedesktop.org/libevdev/libevdev.git
synced 2025-12-28 06:10:07 +01:00
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 <peter.hutterer@who-t.net> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
parent
d9cfd143d0
commit
1e605f6282
7 changed files with 191 additions and 2 deletions
|
|
@ -142,6 +142,29 @@ libevdev_event_code_from_name_n(unsigned int type, const char *name, size_t len)
|
|||
return entry ? (int)entry->value : -1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2019,6 +2019,29 @@ const char * libevdev_event_type_get_name(unsigned int type);
|
|||
*/
|
||||
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
|
||||
*
|
||||
|
|
@ -2127,6 +2150,56 @@ int libevdev_event_code_from_name(unsigned int type, const char *name);
|
|||
int libevdev_event_code_from_name_n(unsigned int type, 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
|
||||
* 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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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("};")
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue