summaryrefslogtreecommitdiffhomepage
path: root/tracker-tobii-eyex/tobii-eyex.hpp
blob: aeac4d89f6da801c8836a4fd0be915d7ef1cb787 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#pragma once

/* Copyright (c) 2016 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.
 */

#include <EyeX.h>

#include "ui_tobii-eyex-dialog.h"
#include "api/plugin-api.hpp"
#include "options/options.hpp"
using namespace options;
#include "compat/timer.hpp"
#include "spline-widget/spline.hpp"
#include "spline-widget/spline-widget.hpp"

#include <atomic>
#include <QObject>
#include <QMutex>

enum tobii_mode
{
    tobii_relative,
    tobii_absolute,
};

class rel_settings final : public QObject, public opts
{
    Q_OBJECT
public:
    using s = slider_value;
    value<slider_value> speed, dz_end_pt, expt_slope, expt_norm, lin_norm;
    spline acc_mode_spline;
    rel_settings();
private slots:
    void draw_spline();
};

struct settings final : public opts
{
    value<tobii_mode> mode;
    settings() :
        opts("tobii-eyex"),
        mode(b, "mode", tobii_relative)
    {}
};

class tobii_eyex_tracker : public ITracker
{
public:
    tobii_eyex_tracker();
    ~tobii_eyex_tracker() override;
    void start_tracker(QFrame *) override;
    void data(double *data) override;
    bool center() override
    {
        do_center = true;
        return true;
    }
private:
    static constexpr const char* client_id = "opentrack-tobii-eyex";

    static void call_tx_deinit();

    static bool register_state_snapshot(TX_CONTEXTHANDLE ctx, TX_HANDLE* state_snapshot_ptr);
    static std::atomic_flag atexit_done;
    static void TX_CALLCONVENTION connection_state_change_handler(TX_CONNECTIONSTATE state, TX_USERPARAM param);
    static void TX_CALLCONVENTION event_handler(TX_CONSTHANDLE async_data_handle, TX_USERPARAM param);
    void gaze_data_handler(TX_HANDLE gaze_data_handle);
    static void TX_CALLCONVENTION snapshot_committed_handler(TX_CONSTHANDLE async_data_handle, TX_USERPARAM param);
    static void TX_CALLCONVENTION display_state_handler(TX_CONSTHANDLE async_data_handle, TX_USERPARAM param);
    void process_display_state(TX_HANDLE display_state_handle);

    using num = double;

    num gain(num x);

    settings s;
    rel_settings rel_s;

    TX_CONTEXTHANDLE dev_ctx;
    TX_TICKET conn_state_changed_ticket;
    TX_TICKET event_handler_ticket;
    TX_HANDLE state_snapshot;
    TX_HANDLE display_state;

    QMutex global_state_mtx;

    Timer t;

    struct state
    {
        TX_REAL display_res_x, display_res_y;
        TX_REAL px, py;
        TX_REAL last_timestamp;
        bool fresh;

        state() : display_res_x(-1), display_res_y(-1), px(-1), py(-1), last_timestamp(0), fresh(false) {}
        bool is_valid() const { return !(display_res_x < 0 || px < 0); }
    } dev_state;

    double yaw, pitch;
    volatile bool do_center;
};

class tobii_eyex_dialog final : public ITrackerDialog
{
    Q_OBJECT
public:
    tobii_eyex_dialog();
    void register_tracker(ITracker *) override {}
    void unregister_tracker() override {}
private:
    Ui::tobii_eyex_dialog_widgets ui;
    settings s;
    rel_settings rs;
private slots:
    void do_ok();
    void do_cancel();
};

class tobii_eyex_metadata : public Metadata
{
public:
    QString name() { return QString("Tobii EyeX"); }
    QIcon icon() { return QIcon(":/images/tobii-eyex-logo.png"); }
};