summaryrefslogtreecommitdiffhomepage
path: root/ftnoir_protocol_libevdev/ftnoir_protocol_libevdev.cpp
blob: 6f34d20bd3e9b50769a3db73b462afba725fd300 (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
#include "ftnoir_protocol_libevdev.h"
#include "facetracknoir/global-settings.h"
//#include "ftnoir_tracker_base/ftnoir_tracker_types.h"

#define CHECK_LIBEVDEV(expr) if ((expr) != 0) goto error;

FTNoIR_Protocol::FTNoIR_Protocol() : dev(NULL), uidev(NULL)
{
    int error;

    dev = libevdev_new();

    if (!dev)
        goto error;

    libevdev_set_name(dev, "opentrack headpose");

    struct input_absinfo absinfo;

    absinfo.minimum = -ABS_MAX;
    absinfo.maximum = ABS_MAX;
    absinfo.resolution= 1; /* units per radian? let's go shopping */
    absinfo.value = 0;
    absinfo.fuzz = 1; /* no filtering in evdev subsystem, we do our own */

    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))

    CHECK_LIBEVDEV(error = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev))

    return;
error:
    if (uidev)
        libevdev_uinput_destroy(uidev);
    if (dev)
        libevdev_free(dev);
    uidev = NULL;
    dev = NULL;
}

FTNoIR_Protocol::~FTNoIR_Protocol()
{
    if (uidev)
        libevdev_uinput_destroy(uidev);
    if (dev)
        libevdev_free(dev);
}

void FTNoIR_Protocol::sendHeadposeToGame( double *headpose, double *rawheadpose ) {
    static const int axes[] = {
        /* translation goes first */
        ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ
    };
    static const int ranges[] = {
        2,
        2,
        2,
        2, /* | pitch | only goes to 90 */
        1,
        2
    };

    const int max_euler = 90;

    for (int i = 0; i < 6; i++)
        (void) libevdev_uinput_write_event(uidev, EV_ABS, axes[i], ranges[i] * headpose[i] * max_euler / ABS_MAX);
}

extern "C" FTNOIR_PROTOCOL_BASE_EXPORT IProtocol* CALLING_CONVENTION GetConstructor()
{
    return new FTNoIR_Protocol;
}