summaryrefslogtreecommitdiffhomepage
path: root/tracker-linux-joystick/linux_joystick.cpp
blob: 49718b52eaa4fb17da02bb750b25143ccafdd288 (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
#include "ftnoir_tracker_linux_joystick.h"

#include <QDir>
#include <QFileInfo>
#include <QVariant>

// Discovery is done by searching for devices in the sys file system.
//
// Given a path like this
// /sys/devices/pci0000:00/0000:00:14.0/usb1/1-10/1-10:1.2/0003:2341:8036.0170/input/input380/js0
// we want to get this part of the string 2341:8036, it will allow us to
// identify the device in the future.
// alternative way of doing this https://stackoverflow.com/questions/21173988/linux-attempting-to-get-joystick-vendor-and-product-ids-via-ioctl-get-einval-i
std::tuple<QString, QString> sysfsDeviceToJsDev(QFileInfo device) {
    using ret = std::tuple<QString, QString>;
    QString symlink = device.symLinkTarget();
    QString js_dev = QString("/dev/input/%1").arg(device.fileName());

    QRegExp sep(QString("[:.%1]").arg(QDir::separator()));
    QString device_id = symlink.section(sep, -6, -5);
    return ret(js_dev, device_id);
}

QList<linux_joystick> getJoysticks()
{
    char name[128];
    QList<linux_joystick> joysticks;

    QDir dir("/sys/class/input/");
    dir.setNameFilters({ "js*" });
    QFileInfoList list = dir.entryInfoList();
    for (int i = 0; i < list.size(); ++i)
    {
        QFileInfo device = list.at(i);
        auto [js_dev, device_id] = sysfsDeviceToJsDev(device);
        int iFile = open(js_dev.toUtf8().data(), O_RDONLY | O_NONBLOCK);
        if (iFile == -1) continue;
        if (ioctl(iFile, JSIOCGNAME(sizeof(name)), &name) > 0)
        {
            linux_joystick j;
            j.name = name;
            j.dev = js_dev;
            j.device_id = device_id;
            joysticks.append(j);
        }
        close(iFile);

    }

    return joysticks;
}

QString getJoystickDevice(QString guid) {
    QDir dir("/sys/class/input/");
    dir.setNameFilters({ "js*" });
    QFileInfoList list = dir.entryInfoList();
    for (int i = 0; i < list.size(); ++i)
    {
        QFileInfo device = list.at(i);
        auto [js_dev, device_id] = sysfsDeviceToJsDev(device);
        if (device_id == guid) return js_dev;
    }

    return {};
}