[PATCH libevdev 3/3] Add libevdev_event_value_get_name() to resolve ABS_MT_TOOL_TYPE values

Peter Hutterer peter.hutterer at who-t.net
Thu Jul 5 05:41:29 UTC 2018


On Wed, Jul 04, 2018 at 10:37:19AM +0200, Benjamin Tissoires wrote:
> Hi Peter,
> 
> sorry for the delay in the review.
> 
> 
> On Mon, Jun 18, 2018 at 7:53 AM Peter Hutterer <peter.hutterer at who-t.net> wrote:
> >
> > 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 at who-t.net>
> > ---
> >  libevdev/libevdev-names.c    | 23 ++++++++++++++
> >  libevdev/libevdev.c          | 17 +++++++++++
> >  libevdev/libevdev.h          | 73 ++++++++++++++++++++++++++++++++++++++++++++
> >  libevdev/libevdev.sym        |  9 ++++++
> >  libevdev/make-event-names.py | 10 ++++--
> >  test/test-event-codes.c      | 27 ++++++++++++++++
> >  test/test-event-names.c      | 34 +++++++++++++++++++++
> >  7 files changed, 191 insertions(+), 2 deletions(-)
> >
> > 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
> > @@ -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)
> >  {
> > 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
> > @@ -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
> 
> I am not sure why you are mentioning a kernel v4.17 here. ABS_MT_TOOL
> has been around for a while.

For the archives: I used 4.17 as a reference point indicating "when writing
this 4.17 was the current kernel and only had this one code defined", not as
in "was introduced with 4.17". I simply wanted to future-proof the statement
that only ABS_MT_TOOL resolves this

> Rest looks good. For the series:
> Reviewed-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>

thanks

Cheers,
   Peter

> > + * 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
> >   *
> > 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);
> > --
> > 2.14.4
> >
> > _______________________________________________
> > Input-tools mailing list
> > Input-tools at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/input-tools


More information about the Input-tools mailing list