7 #include <linux/joystick.h>
12 #include <QFileSystemWatcher>
13 #include <QSignalMapper>
14 #include <QSocketNotifier>
19 using namespace swift::misc::input;
23 inline QString inputDevicesDir() {
return QStringLiteral(
"/dev/input/"); }
26 namespace swift::input
28 CJoystickDevice::CJoystickDevice(
const QString &path, QFile *fd, QObject *parent)
29 : QObject(parent), m_path(path), m_fd(fd)
31 m_fd->setParent(
this);
33 if (ioctl(m_fd->handle(), JSIOCGNAME(
sizeof(deviceName)), deviceName) < 0)
35 strncpy(deviceName,
"Unknown",
sizeof(deviceName));
40 fcntl(m_fd->handle(), F_SETFL, O_NONBLOCK);
43 struct js_event event;
44 while (m_fd->read(
reinterpret_cast<char *
>(&event),
sizeof(event)) ==
sizeof(event)) {}
45 QSocketNotifier *notifier =
new QSocketNotifier(m_fd->handle(), QSocketNotifier::Read, m_fd);
46 connect(notifier, &QSocketNotifier::activated,
this, &CJoystickDevice::processInput);
47 m_name = QString(deviceName);
50 CJoystickDevice::~CJoystickDevice()
59 void CJoystickDevice::processInput()
61 struct js_event event;
62 while (m_fd->read(
reinterpret_cast<char *
>(&event),
sizeof(event)) ==
sizeof(event))
64 switch (event.type & ~JS_EVENT_INIT)
67 if (event.value) { emit
buttonChanged(m_name, event.number,
true); }
76 m_inputWatcher->addPath(inputDevicesDir());
77 connect(m_inputWatcher, &QFileSystemWatcher::directoryChanged,
this, &CJoystickLinux::reloadDevices);
78 reloadDevices(inputDevicesDir());
87 void CJoystickLinux::cleanupJoysticks()
89 for (
auto it = m_joystickDevices.begin(); it != m_joystickDevices.end();)
92 if (!(*it)->isAttached())
95 it = m_joystickDevices.erase(it);
96 joystickDevice->deleteLater();
102 void CJoystickLinux::addJoystickDevice(
const QString &path)
104 QFile *fd =
new QFile(path);
105 if (fd->open(QIODevice::ReadOnly))
107 CJoystickDevice *joystickDevice =
new CJoystickDevice(path, fd,
this);
109 m_joystickDevices.push_back(joystickDevice);
114 << fd->fileName() << fd->errorString();
120 void CJoystickLinux::joystickButtonChanged(
const QString &name,
int index,
bool isPressed)
129 void CJoystickLinux::reloadDevices(QString path)
133 QDir dir(path, QLatin1String(
"js*"), QDir::Name, QDir::System);
134 for (
const auto &entry : dir.entryInfoList())
136 QString f = entry.absoluteFilePath();
137 auto it = std::find_if(m_joystickDevices.begin(), m_joystickDevices.end(),
138 [path](
const CJoystickDevice *device) { return device->getPath() == path; });
139 if (it == m_joystickDevices.end()) { addJoystickDevice(f); }
Class for emitting a log message.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
Free functions in swift::misc.