From cee42a364e1450d0fb867104cff660871e1d02a4 Mon Sep 17 00:00:00 2001
From: Stanislaw Halik <sthalik@misaki.pl>
Date: Sat, 18 Oct 2014 13:46:33 +0200
Subject: add libevdev tracker to build

Issue: #75
---
 ftnoir_tracker_libevdev/ftnoir_libevdev.ui         | 56 +++++++++++++
 .../ftnoir_tracker_libevdev.cpp                    | 92 ++++++++++++++++++++++
 ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.h  | 55 +++++++++++++
 .../ftnoir_tracker_libevdev_dialog.cpp             | 41 ++++++++++
 .../ftnoir_tracker_libevdev_dll.cpp                | 27 +++++++
 5 files changed, 271 insertions(+)
 create mode 100644 ftnoir_tracker_libevdev/ftnoir_libevdev.ui
 create mode 100644 ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.cpp
 create mode 100644 ftnoir_tracker_libevdev/ftnoir_tracker_libevdev.h
 create mode 100644 ftnoir_tracker_libevdev/ftnoir_tracker_libevdev_dialog.cpp
 create mode 100644 ftnoir_tracker_libevdev/ftnoir_tracker_libevdev_dll.cpp

(limited to 'ftnoir_tracker_libevdev')

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;
+}
-- 
cgit v1.2.3