summaryrefslogtreecommitdiffhomepage
path: root/proto-libevdev/ftnoir_protocol_libevdev.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'proto-libevdev/ftnoir_protocol_libevdev.cpp')
-rw-r--r--proto-libevdev/ftnoir_protocol_libevdev.cpp87
1 files changed, 63 insertions, 24 deletions
diff --git a/proto-libevdev/ftnoir_protocol_libevdev.cpp b/proto-libevdev/ftnoir_protocol_libevdev.cpp
index 6bf9b511..fefcd9bb 100644
--- a/proto-libevdev/ftnoir_protocol_libevdev.cpp
+++ b/proto-libevdev/ftnoir_protocol_libevdev.cpp
@@ -1,36 +1,65 @@
+// strerror_r(3)
+
+#ifdef __clang__
+# pragma clang diagnostic ignored "-Wreserved-id-macro"
+# pragma clang diagnostic ignored "-Wunused-macros"
+#endif
+
+#ifndef _POSIX_C_SOURCE
+# define _POSIX_C_SOURCE 200112L
+#endif
+
#include "ftnoir_protocol_libevdev.h"
#include "api/plugin-api.hpp"
#include "compat/math.hpp"
-#include <stdio.h>
+#include <cstdlib>
+#include <cstring>
+#include <cstdio>
+#include <algorithm>
+
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
-#include <string.h>
-#include <algorithm>
+#include <QDebug>
-#define CHECK_LIBEVDEV(expr) if ((error = (expr)) != 0) goto error;
+#define CHECK_LIBEVDEV(expr) \
+ do { \
+ if (int error = (expr); error != 0) \
+ { \
+ error_code = -error; \
+ error_expr = #expr; \
+ goto fail; \
+ } \
+ } while (false)
-static const int max_input = 65535;
-static const int mid_input = 32767;
-static const int min_input = 0;
+static constexpr int max_input = 1 << 16;
+static constexpr int mid_input = (1 << 15) - 1;
+static constexpr int min_input = 0;
-evdev::evdev() : dev(NULL), uidev(NULL)
+evdev::evdev()
{
- int error = 0;
-
dev = libevdev_new();
if (!dev)
- goto error;
+ {
+ error_code = errno;
+ error_expr = "libevdev_new();";
+ goto fail;
+ }
CHECK_LIBEVDEV(libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD));
libevdev_set_name(dev, "opentrack headpose");
+
+ libevdev_set_id_bustype(dev, 3);
+ libevdev_set_id_vendor(dev, 4324);
+ libevdev_set_id_product(dev, 3798);
+ libevdev_set_id_version(dev, 123);
struct input_absinfo absinfo;
@@ -57,15 +86,17 @@ evdev::evdev() : dev(NULL), uidev(NULL)
CHECK_LIBEVDEV(libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev));
return;
-error:
+
+fail:
if (uidev)
libevdev_uinput_destroy(uidev);
if (dev)
libevdev_free(dev);
- if (error)
- fprintf(stderr, "libevdev error: %d\n", error);
- uidev = NULL;
- dev = NULL;
+
+ qDebug() << "libevdev error" << error_code;
+
+ uidev = nullptr;
+ dev = nullptr;
}
evdev::~evdev()
@@ -76,7 +107,7 @@ evdev::~evdev()
libevdev_free(dev);
}
-void evdev::pose(const double* headpose) {
+void evdev::pose(const double* headpose, const double*) {
static const int axes[] = {
/* translation goes first */
ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ
@@ -93,8 +124,8 @@ void evdev::pose(const double* headpose) {
for (int i = 0; i < 6; i++)
{
- int value = headpose[i] * mid_input / max_value[i] + mid_input;
- int normalized = clamp(value, min_input, max_input);
+ int value = (int)(headpose[i] * mid_input / max_value[i] + mid_input);
+ int normalized = std::clamp(value, min_input, max_input);
(void) libevdev_uinput_write_event(uidev, EV_ABS, axes[i], normalized);
}
@@ -103,14 +134,22 @@ void evdev::pose(const double* headpose) {
module_status evdev::initialize()
{
- if (access("/dev/uinput", R_OK | W_OK))
+ if (error_code)
{
+ const char* msg;
char buf[128] {};
- (void) strerror_r(errno, buf, sizeof(buf));
- return error(_("Can't open /dev/uinput: %1").arg(buf));
- }
- return status_ok();
+ if (!(msg = strerror_r(error_code, buf, sizeof(buf))))
+ {
+ snprintf(buf, sizeof(buf), "%d", error_code);
+ msg = buf;
+ }
+
+ return error(QStringLiteral("libevdev call '%1' failed with error '%2'")
+ .arg(!error_expr ? "<NULL>" : error_expr, msg));
+ }
+ else
+ return {};
}
OPENTRACK_DECLARE_PROTOCOL(evdev, LibevdevControls, evdevDll)