[PATCH libevdev v2 4/5] Add libevdev_event_type/code_from_name() resolvers

Peter Hutterer peter.hutterer at who-t.net
Tue Oct 29 02:06:51 CET 2013


On Mon, Oct 28, 2013 at 05:16:46PM +0100, David Herrmann wrote:
> Three new helpers are added:
> (1) libevdev_event_type_from_name() takes a string describing an EV_*
> event type and returns the given event-type constant.
> (2) libevdev_event_type_from_prefix() takes a string describing an event
> code and returns the type given by the prefix of the event code.

what's the use-case for this? Specifically returning a valid type for an
invalid event code is what worries me a bit.

> (2) libevdev_event_code_from_name() takes a string describing an event
> code and returns the given event-code constant.
> 
> Signed-off-by: David Herrmann <dh.herrmann at gmail.com>
> ---
>  libevdev/Makefile.am      |   3 +-
>  libevdev/libevdev-names.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++
>  libevdev/libevdev.h       |  63 +++++++++++++++++++++++
>  test/Makefile.am          |   1 +
>  4 files changed, 194 insertions(+), 1 deletion(-)
>  create mode 100644 libevdev/libevdev-names.c
> 
> diff --git a/libevdev/Makefile.am b/libevdev/Makefile.am
> index 3833d61..38c8de0 100644
> --- a/libevdev/Makefile.am
> +++ b/libevdev/Makefile.am
> @@ -10,7 +10,8 @@ libevdev_la_SOURCES = \
>                     libevdev-uinput.h \
>                     libevdev-uinput-int.h \
>                     libevdev.c \
> -		   ../include/linux/input.h
> +                   ../include/linux/input.h \
> +                   libevdev-names.c

this is personal style, but I'd prefer to have the libevdev stuff grouped
together, so that linux/input.h is always the last line (amplifies that it's
a bit special). also, it'll mean the diff is only one line as opposed to
two.

The rest of the patch looks good, thanks.

Cheers,
   Peter


>  
>  libevdev_la_LDFLAGS = \
>  	-version-info $(LIBEVDEV_LT_VERSION) \
> diff --git a/libevdev/libevdev-names.c b/libevdev/libevdev-names.c
> new file mode 100644
> index 0000000..ee6c7f3
> --- /dev/null
> +++ b/libevdev/libevdev-names.c
> @@ -0,0 +1,128 @@
> +/*
> + * Copyright © 2013 David Herrmann <dh.herrmann at gmail.com>
> + *
> + * Permission to use, copy, modify, distribute, and sell this software and its
> + * documentation for any purpose is hereby granted without fee, provided that
> + * the above copyright notice appear in all copies and that both that copyright
> + * notice and this permission notice appear in supporting documentation, and
> + * that the name of the copyright holders not be used in advertising or
> + * publicity pertaining to distribution of the software without specific,
> + * written prior permission.  The copyright holders make no representations
> + * about the suitability of this software for any purpose.  It is provided "as
> + * is" without express or implied warranty.
> + *
> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
> + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
> + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
> + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
> + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
> + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
> + * OF THIS SOFTWARE.
> + */
> +
> +#include <config.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <strings.h>
> +
> +#include "libevdev.h"
> +#include "libevdev-int.h"
> +#include "libevdev-util.h"
> +#include "event-names.h"
> +
> +struct name_lookup {
> +	const char *name;
> +	size_t len;
> +};
> +
> +static int cmp_entry(const void *vlookup, const void *ventry)
> +{
> +	const struct name_lookup *lookup = vlookup;
> +	const struct name_entry *entry = ventry;
> +	int r;
> +
> +	r = strncmp(lookup->name, entry->name, lookup->len);
> +	if (!r) {
> +		if (entry->name[lookup->len])
> +			r = -1;
> +		else
> +			r = 0;
> +	}
> +
> +	return r;
> +}
> +
> +static const struct name_entry*
> +lookup_name(const struct name_entry *array, size_t asize,
> +	    struct name_lookup *lookup)
> +{
> +	const struct name_entry *entry;
> +
> +	entry = bsearch(lookup, array, asize, sizeof(*array), cmp_entry);
> +	if (!entry)
> +		return NULL;
> +
> +	return entry;
> +}
> +
> +LIBEVDEV_EXPORT int
> +libevdev_event_type_from_name(const char *name, ssize_t len)
> +{
> +	struct name_lookup lookup;
> +	const struct name_entry *entry;
> +
> +	lookup.name = name;
> +	lookup.len = (len < 0) ? strlen(name) : (size_t)len;
> +
> +	entry = lookup_name(ev_names, ARRAY_LENGTH(ev_names), &lookup);
> +
> +	return entry ? (int)entry->value : -1;
> +}
> +
> +LIBEVDEV_EXPORT int
> +libevdev_event_type_from_prefix(const char *name, ssize_t len)
> +{
> +	const char *e;
> +	size_t i;
> +	ssize_t l;
> +
> +	if (len < 0)
> +		len = strlen(name);
> +
> +	/* MAX_ is not allowed, even though EV_MAX exists */
> +	if (startswith(name, len, "MAX_", 4))
> +		return -1;
> +	/* BTN_ is special as there is no EV_BTN type */
> +	if (startswith(name, len, "BTN_", 4))
> +		return EV_KEY;
> +	/* FF_STATUS_ is special as FF_ is a prefix of it, so test it first */
> +	if (startswith(name, len, "FF_STATUS_", 10))
> +		return EV_FF_STATUS;
> +
> +	for (i = 0; i < ARRAY_LENGTH(ev_names); ++i) {
> +		/* skip EV_ prefix */
> +		e = &ev_names[i].name[3];
> +		l = strlen(e);
> +
> +		/* @e is suffix of [EV_]XYZ, test it and trailing _ */
> +		if (len > l && startswith(name, len, e, l) && name[l] == '_')
> +			return ev_names[i].value;
> +	}
> +
> +	return -1;
> +}
> +
> +LIBEVDEV_EXPORT int
> +libevdev_event_code_from_name(const char *name, ssize_t len)
> +{
> +	struct name_lookup lookup;
> +	const struct name_entry *entry;
> +
> +	lookup.name = name;
> +	lookup.len = (len < 0) ? strlen(name) : (size_t)len;
> +
> +	entry = lookup_name(code_names, ARRAY_LENGTH(code_names), &lookup);
> +
> +	return entry ? (int)entry->value : -1;
> +}
> diff --git a/libevdev/libevdev.h b/libevdev/libevdev.h
> index 426e9c8..b8d85e1 100644
> --- a/libevdev/libevdev.h
> +++ b/libevdev/libevdev.h
> @@ -1416,6 +1416,7 @@ int libevdev_event_is_code(const struct input_event *ev, unsigned int type, unsi
>   * defines for new properties libevdev will not automatically pick these up.
>   */
>  const char * libevdev_event_type_get_name(unsigned int type);
> +
>  /**
>   * @ingroup misc
>   *
> @@ -1460,6 +1461,68 @@ const char* libevdev_property_get_name(unsigned int prop);
>  int libevdev_event_type_get_max(unsigned int type);
>  
>  /**
> + * @ingroup misc
> + *
> + * Look up an event-type by its name. Event-types start with "EV_" followed by
> + * the name (eg., "EV_ABS"). The "EV_" prefix must be included in the name. It
> + * returns the constant assigned to the event-type or -1 if not found.
> + *
> + * @param name A non-NULL string describing an input-event type ("EV_KEY",
> + * "EV_ABS", ...).
> + * @param len The length of the passed string excluding any terminating 0
> + * character. If less than zero the string is assumed to be zero-terminated.
> + *
> + * @return The given type constant for the passed name or -1 if not found.
> + *
> + * @note EV_MAX is also recognized.
> + */
> +int libevdev_event_type_from_name(const char *name, ssize_t len);
> +
> +/**
> + * @ingroup misc
> + *
> + * Look up an event-type by an event-code name. Event-codes start with a fixed
> + * prefix followed by their name (eg., "ABS_X"). It performs a prefix-match on
> + * the name and returns the constant assigned to the event-type of the
> + * event-code or -1 if the prefix is unknown.
> + *
> + * For instance this returns the constant EV_ABS for the string "ABS_X". Note
> + * that the event-code must not necessarily exist. A lookup for "ABS_XYZ" will
> + * also return EV_ABS, even though ABS_XYZ is not a valid event-code. This only
> + * tests the prefix (for performance reasons).
> + *
> + * All EV_* codes are supported by this call and are returned if their prefix
> + * is used. For BTN_* codes, EV_KEY is returned.
> + *
> + * @param name A non-NULL string describing an input-event code (KEY_A,
> + * ABS_X, BTN_Y, ...).
> + * @param len The length of the passed string excluding any terminating 0
> + * character. If less than zero the string is assumed to be zero-terminated.
> + *
> + * @return The given type constant for the passed name or -1 if not found.
> + */
> +int libevdev_event_type_from_prefix(const char *name, ssize_t len);
> +
> +/**
> + * @ingroup misc
> + *
> + * Look up an event-code by its name. Event-codes start with a fixed prefix
> + * followed by their name (eg., "ABS_X"). The prefix must be included in the
> + * name. It returns the constant assigned to the event-code or -1 if not found.
> + *
> + * Supported event-codes are codes starting with SYN_, KEY_, BTN_, REL_, ABS_,
> + * MSC_, SND_, SW_, LED_, REP_, FF_.
> + *
> + * @param name A non-NULL string describing an input-event code (KEY_A,
> + * ABS_X, BTN_Y, ...).
> + * @param len The length of the passed string excluding any terminating 0
> + * character. If less than zero the string is assumed to be zero-terminated.
> + *
> + * @return The given code constant for the passed name or -1 if not found.
> + */
> +int libevdev_event_code_from_name(const char *name, ssize_t len);
> +
> +/**
>   * @ingroup bits
>   *
>   * Get the repeat delay and repeat period values for this device.
> diff --git a/test/Makefile.am b/test/Makefile.am
> index 2baafb0..c18b277 100644
> --- a/test/Makefile.am
> +++ b/test/Makefile.am
> @@ -5,6 +5,7 @@ TESTS = $(noinst_PROGRAMS)
>  
>  libevdev_sources = $(top_srcdir)/libevdev/libevdev.c \
>  		   $(top_srcdir)/libevdev/libevdev.h \
> +		   $(top_srcdir)/libevdev/libevdev-names.c \
>  		   $(top_srcdir)/libevdev/libevdev-uinput.h \
>  		   $(top_srcdir)/libevdev/libevdev-uinput.c \
>  		   $(top_srcdir)/libevdev/libevdev-uinput-int.h \
> -- 
> 1.8.4.1
> 


More information about the Input-tools mailing list