[PATCH libevdev v2 4/5] Add libevdev_event_type/code_from_name() resolvers
David Herrmann
dh.herrmann at gmail.com
Mon Oct 28 17:16:46 CET 2013
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.
(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
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