diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | ftnoir_tracker_libevdev/ftnoir_libevdev.ui | 56 | ||||
-rw-r--r-- | ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.cpp | 92 | ||||
-rw-r--r-- | ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.h | 55 | ||||
-rw-r--r-- | ftnoir_tracker_libevdev/ftnoir_tracker_libevdev_dialog.cpp | 41 | ||||
-rw-r--r-- | ftnoir_tracker_libevdev/ftnoir_tracker_libevdev_dll.cpp | 27 |
6 files changed, 272 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c47f18e8..2e2772f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,6 +259,7 @@ if(SDK_ENABLE_LIBEVDEV) pkg_check_modules(libevdev REQUIRED QUIET libevdev) include_directories(${libevdev_INCLUDE_DIRS}) target_link_libraries(opentrack-proto-libevdev ${libevdev_LIBRARIES}) + target_link_libraries(opentrack-tracker-libevdev ${libevdev_LIBRARIES}) endif() if(SDK_FSUIPC) diff --git a/ftnoir_tracker_libevdev/ftnoir_libevdev.ui b/ftnoir_tracker_libevdev/ftnoir_libevdev.ui new file mode 100644 index 00000000..e45ab34a --- /dev/null +++ b/ftnoir_tracker_libevdev/ftnoir_libevdev.ui @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ui_libevdev_tracker_dialog</class> + <widget class="QWidget" name="ui_libevdev_tracker_dialog"> + <property name="windowModality"> + <enum>Qt::NonModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>335</width> + <height>85</height> + </rect> + </property> + <property name="windowTitle"> + <string>libevdev tracker settings</string> + </property> + <property name="windowIcon"> + <iconset> + <normaloff>../facetracknoir/images/facetracknoir.png</normaloff>../facetracknoir/images/facetracknoir.png</iconset> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="1"> + <widget class="QComboBox" name="comboBox"/> + </item> + <item row="1" column="1"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Device</string> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> + <slots> + <slot>startEngineClicked()</slot> + <slot>stopEngineClicked()</slot> + <slot>cameraSettingsClicked()</slot> + </slots> +</ui> diff --git a/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.cpp b/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.cpp new file mode 100644 index 00000000..a36e821c --- /dev/null +++ b/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.cpp @@ -0,0 +1,92 @@ +#include "ftnoir_tracker_libevdev.h" +#include "facetracknoir/plugin-support.h" + +#include <algorithm> + +#include <QDir> +#include <QDebug> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <unistd.h> +#include <string> + +static const int ot_libevdev_joystick_axes[6] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ }; + +FTNoIR_Tracker::FTNoIR_Tracker() : node(nullptr), success(false) +{ +} + +FTNoIR_Tracker::~FTNoIR_Tracker() +{ + if (node) + libevdev_free(node); + if (fd != -1) + close(fd); +} + +void FTNoIR_Tracker::StartTracker(QFrame*) +{ + QString pretty_name = s.device_name; + QString node_name = "usb-" + pretty_name.replace(' ', '_') + "-event-joystick"; + std::string str = (QString("/dev/input/by-id/") + node_name).toStdString(); + const char* filename = str.c_str(); + + fd = open(filename, O_NONBLOCK, O_RDWR); + if (fd == -1) + { + qDebug() << "error opening" << filename; + return; + } + + int ret = libevdev_new_from_fd(fd, &node); + if (ret) + { + qDebug() << "libevdev open error" << ret; + return; + } + + for (int i = 0; i < 6; i++) + { + // no error checking here, errors result in SIGFPE + a_min[i] = libevdev_get_abs_minimum(node, ot_libevdev_joystick_axes[i]); + a_max[i] = libevdev_get_abs_maximum(node, ot_libevdev_joystick_axes[i]); + qDebug() << "axis limits" << i << a_min[i] << "->" << a_max[i]; + } + + success = true; +} + +void FTNoIR_Tracker::GetHeadPoseData(double *data) +{ + if (node) + { + int max = 64; + while (libevdev_has_event_pending(node) == 1 && max-- > 0) + { + struct input_event ev; + int status = libevdev_next_event(node, LIBEVDEV_READ_FLAG_NORMAL, &ev); + if (status != LIBEVDEV_READ_STATUS_SUCCESS) + continue; + if (ev.type == EV_ABS) + { + const int val = ev.value, code = ev.code; + for (int i = 0; i < 6; i++) + { + if (ot_libevdev_joystick_axes[i] == code) + { + data[i] = (val - a_min[i])*(i >= Yaw ? 180. : 100.) / a_max[i] - a_min[i]; + break; + } + } + } + } + } +} + +extern "C" OPENTRACK_EXPORT ITracker* GetConstructor() +{ + return new FTNoIR_Tracker; +} diff --git a/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.h b/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.h new file mode 100644 index 00000000..2474fb35 --- /dev/null +++ b/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.h @@ -0,0 +1,55 @@ +#pragma once +#include <cmath> +#include "libevdev/libevdev.h" +#include "facetracknoir/plugin-api.hpp" +#include "facetracknoir/options.h" +#include "./ui_ftnoir_libevdev.h" +using namespace options; + +struct settings { + pbundle b; + value<QString> device_name; + settings() : + b(bundle("libevdev-tracker")), + device_name(b, "device-name", "") + {} +}; + +class FTNoIR_Tracker : public ITracker +{ +public: + FTNoIR_Tracker(); + ~FTNoIR_Tracker() override; + void StartTracker(QFrame *); + void GetHeadPoseData(double *data); +private: + struct libevdev* node; + int fd; + settings s; + bool success; + int a_min[6], a_max[6]; +}; + +class TrackerControls: public QWidget, public ITrackerDialog +{ + Q_OBJECT +public: + TrackerControls(); + void registerTracker(ITracker *) {} + void unRegisterTracker() {} +private: + Ui::ui_libevdev_tracker_dialog ui; + settings s; +private slots: + void doOK(); + void doCancel(); +}; + +class FTNoIR_TrackerDll : public Metadata +{ +public: + void getFullName(QString *strToBeFilled); + void getShortName(QString *strToBeFilled); + void getDescription(QString *strToBeFilled); + void getIcon(QIcon *icon); +}; diff --git a/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev_dialog.cpp b/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev_dialog.cpp new file mode 100644 index 00000000..267101be --- /dev/null +++ b/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev_dialog.cpp @@ -0,0 +1,41 @@ +#include "ftnoir_tracker_libevdev.h" +#include "facetracknoir/plugin-support.h" + +#include <QDir> + +TrackerControls::TrackerControls() +{ + ui.setupUi(this); + + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); + connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); + + ui.comboBox->clear(); + + QDir dir("/dev/input/by-id"); + auto devices = dir.entryList(QStringList { "usb-?*-event-joystick"}); + for (QString dev : devices) + { + dev.replace(QRegularExpression("^usb-"), ""); + dev.replace(QRegularExpression("-event-.[^-]*"), ""); + dev.replace("_", " "); + ui.comboBox->addItem(dev); + } + + tie_setting(s.device_name, ui.comboBox); +} + +void TrackerControls::doOK() { + s.b->save(); + this->close(); +} + +void TrackerControls::doCancel() { + s.b->reload(); + this->close(); +} + +extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog() +{ + return new TrackerControls; +} diff --git a/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev_dll.cpp b/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev_dll.cpp new file mode 100644 index 00000000..6ad13c8c --- /dev/null +++ b/ftnoir_tracker_libevdev/ftnoir_tracker_libevdev_dll.cpp @@ -0,0 +1,27 @@ +#include "ftnoir_tracker_libevdev.h" +#include "facetracknoir/plugin-support.h" + +void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled) +{ + *strToBeFilled = "Joystick"; +} + +void FTNoIR_TrackerDll::getShortName(QString *strToBeFilled) +{ + *strToBeFilled = "Joystick"; +} + +void FTNoIR_TrackerDll::getDescription(QString *strToBeFilled) +{ + *strToBeFilled = "Joystick"; +} + +void FTNoIR_TrackerDll::getIcon(QIcon *icon) +{ + *icon = QIcon(":/images/facetracknoir.png"); +} + +extern "C" OPENTRACK_EXPORT Metadata* GetMetadata() +{ + return new FTNoIR_TrackerDll; +} |