summaryrefslogtreecommitdiffhomepage
path: root/proto-libevdev
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2015-10-30 09:16:32 +0100
committerStanislaw Halik <sthalik@misaki.pl>2015-10-30 09:16:32 +0100
commit0739d5b595be9492c1e574192eba12174111e52c (patch)
tree01225d2335ff784b35b59a5438f8ea1e07535486 /proto-libevdev
parent05b2f05b72c706908e961eff8c0e4aa70dcadbd3 (diff)
also rename protocol -> proto
Diffstat (limited to 'proto-libevdev')
-rw-r--r--proto-libevdev/CMakeLists.txt10
-rw-r--r--proto-libevdev/ftnoir_libevdev_controls.ui111
-rw-r--r--proto-libevdev/ftnoir_protocol_libevdev.cpp97
-rw-r--r--proto-libevdev/ftnoir_protocol_libevdev.h57
-rw-r--r--proto-libevdev/ftnoir_protocol_libevdev_dialog.cpp21
-rw-r--r--proto-libevdev/images/linux.pngbin0 -> 668 bytes
-rw-r--r--proto-libevdev/libevdev-protocol.qrc5
7 files changed, 301 insertions, 0 deletions
diff --git a/proto-libevdev/CMakeLists.txt b/proto-libevdev/CMakeLists.txt
new file mode 100644
index 00000000..960a1271
--- /dev/null
+++ b/proto-libevdev/CMakeLists.txt
@@ -0,0 +1,10 @@
+if(LINUX OR APPLE)
+ set(SDK_ENABLE_LIBEVDEV FALSE CACHE BOOL "libevdev virtual joystick protocol support")
+ if(SDK_ENABLE_LIBEVDEV)
+ include(FindPkgConfig)
+ opentrack_boilerplate(opentrack-proto-libevdev)
+ pkg_check_modules(libevdev REQUIRED QUIET libevdev)
+ target_link_libraries(opentrack-proto-libevdev ${libevdev_LIBRARIES})
+ include_directories(opentrack-proto-libevdev SYSTEM PUBLIC ${libevdev_INCLUDE_DIRS})
+ endif()
+endif()
diff --git a/proto-libevdev/ftnoir_libevdev_controls.ui b/proto-libevdev/ftnoir_libevdev_controls.ui
new file mode 100644
index 00000000..d2b86445
--- /dev/null
+++ b/proto-libevdev/ftnoir_libevdev_controls.ui
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UICLibevdevControls</class>
+ <widget class="QWidget" name="UICLibevdevControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>228</width>
+ <height>69</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>VJoy</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>:/images/vjoy.png</normaloff>:/images/vjoy.png</iconset>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <layout class="QVBoxLayout" name="_vertical_layout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Make sure rw for /dev/input/uinput!</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <widget class="QPushButton" name="btnOK">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCancel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>btnOK</tabstop>
+ <tabstop>btnCancel</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/proto-libevdev/ftnoir_protocol_libevdev.cpp b/proto-libevdev/ftnoir_protocol_libevdev.cpp
new file mode 100644
index 00000000..96805b39
--- /dev/null
+++ b/proto-libevdev/ftnoir_protocol_libevdev.cpp
@@ -0,0 +1,97 @@
+#include "ftnoir_protocol_libevdev.h"
+#include "opentrack/plugin-api.hpp"
+#include <cstdio>
+#include <algorithm>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define CHECK_LIBEVDEV(expr) if ((error = (expr)) != 0) goto error;
+
+static const int max_input = 65535;
+static const int mid_input = 32767;
+static const int min_input = 0;
+
+FTNoIR_Protocol::FTNoIR_Protocol() : dev(NULL), uidev(NULL)
+{
+ int error = 0;
+
+ dev = libevdev_new();
+
+ if (!dev)
+ goto error;
+
+ CHECK_LIBEVDEV(libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD));
+
+ libevdev_set_name(dev, "opentrack headpose");
+
+ struct input_absinfo absinfo;
+
+ absinfo.minimum = min_input;
+ absinfo.maximum = max_input;
+ absinfo.resolution = 1;
+ absinfo.value = mid_input;
+ absinfo.flat = 1;
+ absinfo.fuzz = 0;
+
+ CHECK_LIBEVDEV(libevdev_enable_event_type(dev, EV_ABS));
+ CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_X, &absinfo));
+ CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_Y, &absinfo));
+ CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_Z, &absinfo));
+ CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_RX, &absinfo));
+ CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_RY, &absinfo));
+ CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_ABS, ABS_RZ, &absinfo));
+
+ /* do not remove next 3 lines or udev scripts won't assign 0664 permissions -sh */
+ CHECK_LIBEVDEV(libevdev_enable_event_type(dev, EV_KEY));
+ CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_KEY, BTN_JOYSTICK, NULL));
+ CHECK_LIBEVDEV(libevdev_enable_event_code(dev, EV_KEY, BTN_TRIGGER, NULL));
+
+ CHECK_LIBEVDEV(libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev));
+
+ return;
+error:
+ if (uidev)
+ libevdev_uinput_destroy(uidev);
+ if (dev)
+ libevdev_free(dev);
+ if (error)
+ fprintf(stderr, "libevdev error: %d\n", error);
+ uidev = NULL;
+ dev = NULL;
+}
+
+FTNoIR_Protocol::~FTNoIR_Protocol()
+{
+ if (uidev)
+ libevdev_uinput_destroy(uidev);
+ if (dev)
+ libevdev_free(dev);
+}
+
+void FTNoIR_Protocol::pose(const double* headpose) {
+ static const int axes[] = {
+ /* translation goes first */
+ ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ
+ };
+
+ static const int max_value[] = {
+ 100,
+ 100,
+ 100,
+ 180,
+ 90,
+ 180
+ };
+
+ for (int i = 0; i < 6; i++)
+ {
+ int value = headpose[i] * mid_input / max_value[i] + mid_input;
+ int normalized = std::max(std::min(max_input, value), min_input);
+ (void) libevdev_uinput_write_event(uidev, EV_ABS, axes[i], normalized);
+ }
+
+ (void) libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
+}
+
+OPENTRACK_DECLARE_PROTOCOL(FTNoIR_Protocol, LibevdevControls, FTNoIR_ProtocolDll)
diff --git a/proto-libevdev/ftnoir_protocol_libevdev.h b/proto-libevdev/ftnoir_protocol_libevdev.h
new file mode 100644
index 00000000..ecb3b201
--- /dev/null
+++ b/proto-libevdev/ftnoir_protocol_libevdev.h
@@ -0,0 +1,57 @@
+/* Copyright (c) 2013 Stanislaw Halik <sthalik@misaki.pl>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+#pragma once
+#include "ui_ftnoir_libevdev_controls.h"
+
+#include <QMessageBox>
+#include "opentrack/plugin-api.hpp"
+
+extern "C" {
+# include <libevdev/libevdev.h>
+# include <libevdev/libevdev-uinput.h>
+}
+
+class FTNoIR_Protocol : public IProtocol
+{
+public:
+ FTNoIR_Protocol();
+ ~FTNoIR_Protocol() override;
+ bool correct() {
+ return dev != NULL;
+ }
+ void pose(const double *headpose);
+ QString game_name() {
+ return "Virtual joystick for Linux";
+ }
+private:
+ struct libevdev* dev;
+ struct libevdev_uinput* uidev;
+};
+
+class LibevdevControls: public IProtocolDialog
+{
+ Q_OBJECT
+public:
+ LibevdevControls();
+ void register_protocol(IProtocol *) {}
+ void unregister_protocol() {}
+
+private:
+ Ui::UICLibevdevControls ui;
+ void save();
+
+private slots:
+ void doOK();
+ void doCancel();
+};
+
+class FTNoIR_ProtocolDll : public Metadata
+{
+public:
+ QString name() { return QString("libevdev joystick receiver"); }
+ QIcon icon() { return QIcon(":/images/linux.png"); }
+};
diff --git a/proto-libevdev/ftnoir_protocol_libevdev_dialog.cpp b/proto-libevdev/ftnoir_protocol_libevdev_dialog.cpp
new file mode 100644
index 00000000..70495a8f
--- /dev/null
+++ b/proto-libevdev/ftnoir_protocol_libevdev_dialog.cpp
@@ -0,0 +1,21 @@
+#include "ftnoir_protocol_libevdev.h"
+#include "opentrack/plugin-api.hpp"
+
+LibevdevControls::LibevdevControls()
+{
+ ui.setupUi( this );
+ connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK()));
+ connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel()));
+}
+
+void LibevdevControls::doOK() {
+ save();
+ this->close();
+}
+
+void LibevdevControls::doCancel() {
+ this->close();
+}
+
+void LibevdevControls::save() {
+}
diff --git a/proto-libevdev/images/linux.png b/proto-libevdev/images/linux.png
new file mode 100644
index 00000000..8836c0e2
--- /dev/null
+++ b/proto-libevdev/images/linux.png
Binary files differ
diff --git a/proto-libevdev/libevdev-protocol.qrc b/proto-libevdev/libevdev-protocol.qrc
new file mode 100644
index 00000000..70bb415f
--- /dev/null
+++ b/proto-libevdev/libevdev-protocol.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/linux.png</file>
+ </qresource>
+</RCC>