From 46bd78bdd9f185b90c138b9f7afe51d974684c41 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sat, 11 Jul 2020 00:10:00 -0700 Subject: [PATCH] Add event test utility This change is a wrapper around libx52io to print the raw events coming from the X52 device. --- configure.ac | 1 + utils/Makefile.am | 2 +- utils/evtest/Makefile.am | 15 +++++ utils/evtest/ev_test.c | 134 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 utils/evtest/Makefile.am create mode 100644 utils/evtest/ev_test.c diff --git a/configure.ac b/configure.ac index 492a053..6f3caf2 100644 --- a/configure.ac +++ b/configure.ac @@ -110,6 +110,7 @@ AC_CONFIG_FILES([ po/Makefile.in utils/Makefile utils/cli/Makefile utils/test/Makefile + utils/evtest/Makefile tests/Makefile ]) AC_OUTPUT diff --git a/utils/Makefile.am b/utils/Makefile.am index 2b3de0a..964f28e 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -4,5 +4,5 @@ # # SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 -SUBDIRS = cli test +SUBDIRS = cli test evtest diff --git a/utils/evtest/Makefile.am b/utils/evtest/Makefile.am new file mode 100644 index 0000000..b676c05 --- /dev/null +++ b/utils/evtest/Makefile.am @@ -0,0 +1,15 @@ +# Automake for x52evtest +# +# Copyright (C) 2012-2020 Nirenjan Krishnan (nirenjan@nirenjan.org) +# +# SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 + +ACLOCAL_AMFLAGS = -I m4 + +bin_PROGRAMS = x52evtest + +# Event test utility that works similarly to the Linux evtest +x52evtest_SOURCES = ev_test.c +x52evtest_CFLAGS = -I $(top_srcdir)/lib/libx52io -I $(top_srcdir) -DLOCALEDIR=\"$(localedir)\" $(WARN_CFLAGS) +x52evtest_LDFLAGS = $(WARN_LDFLAGS) +x52evtest_LDADD = ../../lib/libx52io/libx52io.la diff --git a/utils/evtest/ev_test.c b/utils/evtest/ev_test.c new file mode 100644 index 0000000..f9725dd --- /dev/null +++ b/utils/evtest/ev_test.c @@ -0,0 +1,134 @@ +/* + * Saitek X52 Pro MFD & LED driver - Event test utility + * + * Copyright (C) 2012-2020 Nirenjan Krishnan (nirenjan@nirenjan.org) + * + * SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libx52io.h" +#include "gettext.h" + +/* +Output Format +============= + +Driver version is 0.0.0 +Device ID: bus 0x3 vendor 0x06a3 product 0x0762 version 0x110 +Device name: "Saitek X52 Pro Flight Control System" +Testing ... (interrupt to exit) + +Event @ 1594431236.817842, ABS_X, value 512 +Event @ 1594431236.817842, ABS_Y, value 511 +Event @ 1594431236.817842, BTN_TRIGGER, value 1 +Event @ 1594431236.817842, BTN_MODE_1, value 1 + +Event @ 1594431236.847810, BTN_MODE_1, value 0 + +Event @ 1594431236.877802, BTN_MODE_2, value 1 + + */ + +static bool exit_loop = false; + +static void signal_handler(int sig) +{ + exit_loop = true; +} + +/* For i18n */ +#define _(x) gettext(x) +int main(int argc, char **argv) +{ + libx52io_context *ctx; + libx52io_report last, curr; + int rc; + #define CHECK_RC() do { \ + if (rc != LIBX52IO_SUCCESS) { \ + fprintf(stderr, "%s\n", libx52io_strerror(rc)); \ + return rc; \ + } \ + } while(0) + + /* Initialize gettext */ + #if ENABLE_NLS + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(LOCALEDIR); + #endif + + memset(&last, 0, sizeof(last)); + memset(&curr, 0, sizeof(curr)); + + /* Initialize libx52io */ + rc = libx52io_init(&ctx); + CHECK_RC(); + + /* Make sure that we have a device to connect to */ + rc = libx52io_open(ctx); + CHECK_RC(); + + /* Set up the signal handler to terminate the loop on SIGTERM or SIGINT */ + exit_loop = false; + signal(SIGTERM, signal_handler); + signal(SIGINT, signal_handler); + + /* TODO: Print the driver version and the connected device */ + puts(_("Testing (interrupt to exit)\n")); + + /* Wait until we get an event */ + while (!exit_loop) { + struct timeval tv; + + /* Wait for 1 second before timing out */ + rc = libx52io_read_timeout(ctx, &curr, 1000); + if (rc == LIBX52IO_ERROR_TIMEOUT) { + continue; + } else if (rc != LIBX52IO_SUCCESS) { + /* Some other error while reading. Abort the loop */ + break; + } + + /* + * Successful read, compare the current report against the previous + * one and display the result + */ + if (memcmp(&last, &curr, sizeof(curr)) == 0) { + /* No change, ignore the output */ + continue; + } + + /* Get the current timeval - we don't need a timezone */ + gettimeofday(&tv, NULL); + puts(""); + for (int axis = 0; axis < LIBX52IO_AXIS_MAX; axis++) { + if (last.axis[axis] != curr.axis[axis]) { + printf(_("Event @ %ld.%09lu: %s, value %d\n"), tv.tv_sec, tv.tv_usec, + libx52io_axis_to_str(axis), curr.axis[axis]); + } + } + for (int btn = 0; btn < LIBX52IO_BUTTON_MAX; btn++) { + if (last.button[btn] != curr.button[btn]) { + printf(_("Event @ %ld.%09lu: %s, value %d\n"), tv.tv_sec, tv.tv_usec, + libx52io_button_to_str(btn), curr.button[btn]); + } + } + + memcpy(&last, &curr, sizeof(curr)); + } + + /* Close and exit the libx52io library */ + libx52io_close(ctx); + libx52io_exit(ctx); +}