aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp
diff options
context:
space:
mode:
authorBogDan Vatra <bogdan@kdab.com>2015-10-26 12:38:33 +0200
committerAndy Nichols <andy.nichols@theqtcompany.com>2015-10-26 12:40:37 +0000
commitc32e995bc79035e600893e91fdcec984f8293c75 (patch)
tree6de9a857b695fedfb3a52c5e4e34334759a09acc /src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp
parent00871e531f7fb44feb3dac7abfe4eff0af5dfada (diff)
Enable the usage of unknown gamepads.
Allowing the user to configure every button & axis of (s)his gamepad, will enable the usage of any gamepad. Currently only evdev backed has this feature. Change-Id: I6e0692980e77b448d20d5ba818b787a7b89e7257 Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
Diffstat (limited to 'src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp')
-rw-r--r--src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp494
1 files changed, 296 insertions, 198 deletions
diff --git a/src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp b/src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp
index 6319441..17bd74e 100644
--- a/src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp
+++ b/src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp
@@ -45,8 +45,59 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcEGB, "qt.gamepad")
+QEvdevGamepadDevice::EvdevAxisInfo::EvdevAxisInfo()
+ : QGamepadBackend::AxisInfo<int>(0, 1, QGamepadManager::AxisInvalid)
+{
+}
+
+QEvdevGamepadDevice::EvdevAxisInfo::EvdevAxisInfo(int fd, quint16 abs, int min, int max, QGamepadManager::GamepadAxis gamepadAxis)
+ : QGamepadBackend::AxisInfo<int>(min, max, gamepadAxis)
+ , flat(0)
+ , gamepadMinButton(QGamepadManager::ButtonInvalid)
+ , gamepadMaxButton(QGamepadManager::ButtonInvalid)
+ , gamepadLastButton(QGamepadManager::ButtonInvalid)
+{
+ setAbsInfo(fd, abs);
+}
+
+double QEvdevGamepadDevice::EvdevAxisInfo::normalized(int value) const
+{
+ double val = AxisInfo::normalized(value);
+ if (qAbs(val) <= flat)
+ val = 0;
+ return val;
+}
+
+void QEvdevGamepadDevice::EvdevAxisInfo::setAbsInfo(int fd, int abs)
+{
+ input_absinfo absInfo;
+ memset(&absInfo, 0, sizeof(input_absinfo));
+ if (ioctl(fd, EVIOCGABS(abs), &absInfo) >= 0) {
+ minValue = absInfo.minimum;
+ maxValue = absInfo.maximum;
+ if (maxValue - minValue)
+ flat = fabs(absInfo.flat / double(maxValue - minValue));
+ }
+}
+
+void QEvdevGamepadDevice::EvdevAxisInfo::restoreSavedData(int fd, int abs, const QVariantMap &value)
+{
+ gamepadAxis = QGamepadManager::GamepadAxis(value[QLatin1Literal("axis")].toInt());
+ gamepadMinButton = QGamepadManager::GamepadButton(value[QLatin1Literal("minButton")].toInt());
+ gamepadMaxButton = QGamepadManager::GamepadButton(value[QLatin1Literal("maxButton")].toInt());
+ setAbsInfo(fd, abs);
+}
+
+QVariantMap QEvdevGamepadDevice::EvdevAxisInfo::dataToSave() const
+{
+ QVariantMap data;
+ data[QLatin1Literal("axis")] = gamepadAxis;
+ data[QLatin1Literal("minButton")] = gamepadMinButton;
+ data[QLatin1Literal("maxButton")] = gamepadMaxButton;
+ return data;
+}
+
QEvdevGamepadBackend::QEvdevGamepadBackend()
- : m_nextIndex(0)
{
}
@@ -83,17 +134,46 @@ QEvdevGamepadDevice *QEvdevGamepadBackend::newDevice(const QByteArray &device)
return new QEvdevGamepadDevice(device, this);
}
-// To be called only when it is sure that there is a controller on-line.
-int QEvdevGamepadBackend::idForDevice(const QByteArray &device)
+QEvdevGamepadDevice *QEvdevGamepadBackend::device(int deviceId)
{
- int index;
- if (m_devIndex.contains(device)) {
- index = m_devIndex[device];
- } else {
- index = m_nextIndex++;
- m_devIndex[device] = index;
- }
- return index;
+ foreach (QEvdevGamepadDevice *device, m_devices)
+ if (device->deviceId() == deviceId)
+ return device;
+ return nullptr;
+}
+
+void QEvdevGamepadBackend::resetConfiguration(int deviceId)
+{
+ if (QEvdevGamepadDevice *dev = device(deviceId))
+ return dev->resetConfiguration();
+}
+
+bool QEvdevGamepadBackend::isConfigurationNeeded(int deviceId)
+{
+ if (QEvdevGamepadDevice *dev = device(deviceId))
+ return dev->isConfigurationNeeded();
+ return false;
+}
+
+bool QEvdevGamepadBackend::configureButton(int deviceId, QGamepadManager::GamepadButton button)
+{
+ if (QEvdevGamepadDevice *dev = device(deviceId))
+ return dev->configureButton(button);
+ return false;
+}
+
+bool QEvdevGamepadBackend::configureAxis(int deviceId, QGamepadManager::GamepadAxis axis)
+{
+ if (QEvdevGamepadDevice *dev = device(deviceId))
+ return dev->configureAxis(axis);
+ return false;
+}
+
+bool QEvdevGamepadBackend::setCancelConfigureButton(int deviceId, QGamepadManager::GamepadButton button)
+{
+ if (QEvdevGamepadDevice *dev = device(deviceId))
+ return dev->setCancelConfigureButton(button);
+ return false;
}
void QEvdevGamepadBackend::stop()
@@ -128,11 +208,12 @@ void QEvdevGamepadBackend::handleRemovedDevice(const QString &device)
QEvdevGamepadDevice::QEvdevGamepadDevice(const QByteArray &dev, QEvdevGamepadBackend *backend)
: m_dev(dev),
m_backend(backend),
- m_index(-1),
m_fd(-1),
+ m_productId(0),
+ m_needsConfigure(true),
m_notifier(0),
- m_prevYHatButton(QGamepadManager::ButtonInvalid),
- m_prevXHatButton(QGamepadManager::ButtonInvalid)
+ m_configureButton(QGamepadManager::ButtonInvalid),
+ m_configureAxis(QGamepadManager::AxisInvalid)
{
openDevice(dev);
}
@@ -141,8 +222,75 @@ QEvdevGamepadDevice::~QEvdevGamepadDevice()
{
if (m_fd != -1)
QT_CLOSE(m_fd);
- if (m_index >= 0)
- emit m_backend->gamepadRemoved(m_index);
+ if (m_fd >= 0)
+ emit m_backend->gamepadRemoved(m_fd);
+}
+
+void QEvdevGamepadDevice::resetConfiguration()
+{
+ m_axisMap.insert(ABS_X, EvdevAxisInfo(m_fd, ABS_X, -32768, 32767, QGamepadManager::AxisLeftX));
+ m_axisMap.insert(ABS_Y, EvdevAxisInfo(m_fd, ABS_Y, -32768, 32767, QGamepadManager::AxisLeftY));
+ m_axisMap.insert(ABS_RX, EvdevAxisInfo(m_fd, ABS_RX, -32768, 32767, QGamepadManager::AxisRightX));
+ m_axisMap.insert(ABS_RY, EvdevAxisInfo(m_fd, ABS_RY, -32768, 32767, QGamepadManager::AxisRightY));
+ m_axisMap.insert(ABS_Z, EvdevAxisInfo(m_fd, ABS_Z, 0, 255));
+ m_axisMap[ABS_Z].gamepadMinButton = QGamepadManager::ButtonL2;
+ m_axisMap[ABS_Z].gamepadMaxButton = QGamepadManager::ButtonL2;
+
+ m_axisMap.insert(ABS_RZ, EvdevAxisInfo(m_fd, ABS_RZ, 0, 255));
+ m_axisMap[ABS_RZ].gamepadMinButton = QGamepadManager::ButtonR2;
+ m_axisMap[ABS_RZ].gamepadMaxButton = QGamepadManager::ButtonR2;
+
+ m_axisMap.insert(ABS_HAT0X, EvdevAxisInfo(m_fd, ABS_HAT0X, -1, 1));
+ m_axisMap[ABS_HAT0X].gamepadMinButton = QGamepadManager::ButtonLeft;
+ m_axisMap[ABS_HAT0X].gamepadMaxButton = QGamepadManager::ButtonRight;
+
+ m_axisMap.insert(ABS_HAT0Y, EvdevAxisInfo(m_fd, ABS_HAT0Y, -1, 1));
+ m_axisMap[ABS_HAT0Y].gamepadMinButton = QGamepadManager::ButtonUp;
+ m_axisMap[ABS_HAT0Y].gamepadMaxButton = QGamepadManager::ButtonDown;
+
+ m_buttonsMap[BTN_START] = QGamepadManager::ButtonStart;
+ m_buttonsMap[BTN_SELECT] = QGamepadManager::ButtonSelect;
+ m_buttonsMap[BTN_MODE] = QGamepadManager::ButtonGuide;
+ m_buttonsMap[BTN_X] = QGamepadManager::ButtonX;
+ m_buttonsMap[BTN_Y] = QGamepadManager::ButtonY;
+ m_buttonsMap[BTN_A] = QGamepadManager::ButtonA;
+ m_buttonsMap[BTN_B] = QGamepadManager::ButtonB;
+ m_buttonsMap[BTN_TL] = QGamepadManager::ButtonL1;
+ m_buttonsMap[BTN_TR] = QGamepadManager::ButtonR1;
+ m_buttonsMap[BTN_TL2] = QGamepadManager::ButtonL2;
+ m_buttonsMap[BTN_TR2] = QGamepadManager::ButtonR2;
+ m_buttonsMap[BTN_THUMB] = m_buttonsMap[BTN_THUMBL] = QGamepadManager::ButtonL3;
+ m_buttonsMap[BTN_THUMBR] = QGamepadManager::ButtonR3;
+ m_buttonsMap[BTN_TRIGGER_HAPPY1] = QGamepadManager::ButtonLeft;
+ m_buttonsMap[BTN_TRIGGER_HAPPY2] = QGamepadManager::ButtonRight;
+ m_buttonsMap[BTN_TRIGGER_HAPPY3] = QGamepadManager::ButtonUp;
+ m_buttonsMap[BTN_TRIGGER_HAPPY4] = QGamepadManager::ButtonDown;
+
+ if (m_productId)
+ m_backend->saveSettings(m_productId, QVariant());
+}
+
+bool QEvdevGamepadDevice::isConfigurationNeeded()
+{
+ return m_needsConfigure;
+}
+
+bool QEvdevGamepadDevice::configureButton(QGamepadManager::GamepadButton button)
+{
+ m_configureButton = button;
+ return true;
+}
+
+bool QEvdevGamepadDevice::configureAxis(QGamepadManager::GamepadAxis axis)
+{
+ m_configureAxis = axis;
+ return true;
+}
+
+bool QEvdevGamepadDevice::setCancelConfigureButton(QGamepadManager::GamepadButton button)
+{
+ m_configureCancelButton = button;
+ return true;
}
bool QEvdevGamepadDevice::openDevice(const QByteArray &dev)
@@ -152,41 +300,41 @@ bool QEvdevGamepadDevice::openDevice(const QByteArray &dev)
if (m_fd >= 0) {
m_notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readData()));
+ emit m_backend->gamepadAdded(m_fd);
qCDebug(lcEGB) << "Successfully opened" << dev;
} else {
qErrnoWarning(errno, "Gamepad: Cannot open input device %s", qPrintable(dev));
return false;
}
- // Defaults. To be replaced with queried values below.
- m_axisInfo.insert(ABS_X, AxisInfo(-32768, 32767, 0));
- m_axisInfo.insert(ABS_Y, AxisInfo(-32768, 32767, 0));
- m_axisInfo.insert(ABS_RX, AxisInfo(-32768, 32767, 0));
- m_axisInfo.insert(ABS_RY, AxisInfo(-32768, 32767, 0));
- m_axisInfo.insert(ABS_Z, AxisInfo(0, 255, 0));
- m_axisInfo.insert(ABS_RZ, AxisInfo(0, 255, 0));
+ input_id id;
+ if (ioctl(m_fd, EVIOCGID, &id) >= 0)
+ m_productId = id.product;
+
+ if (m_productId) {
+ QVariant settings = m_backend->readSettings(m_productId);
+ if (!settings.isNull()) {
+ m_needsConfigure = false;
+ QVariantMap data = settings.toMap()[QLatin1Literal("axes")].toMap();
+ for (QVariantMap::const_iterator it = data.begin(); it != data.end(); ++it) {
+ const int key = it.key().toInt();
+ m_axisMap[key].restoreSavedData(m_fd, key, it.value().toMap());
+ }
- input_absinfo absInfo;
- memset(&absInfo, 0, sizeof(input_absinfo));
- if (ioctl(m_fd, EVIOCGABS(ABS_X), &absInfo) >= 0)
- m_axisInfo.insert(ABS_X, AxisInfo(absInfo.minimum, absInfo.maximum, absInfo.flat));
- if (ioctl(m_fd, EVIOCGABS(ABS_Y), &absInfo) >= 0)
- m_axisInfo.insert(ABS_Y, AxisInfo(absInfo.minimum, absInfo.maximum, absInfo.flat));
- if (ioctl(m_fd, EVIOCGABS(ABS_RX), &absInfo) >= 0)
- m_axisInfo.insert(ABS_RX, AxisInfo(absInfo.minimum, absInfo.maximum, absInfo.flat));
- if (ioctl(m_fd, EVIOCGABS(ABS_RY), &absInfo) >= 0)
- m_axisInfo.insert(ABS_RY, AxisInfo(absInfo.minimum, absInfo.maximum, absInfo.flat));
- if (ioctl(m_fd, EVIOCGABS(ABS_Z), &absInfo) >= 0)
- m_axisInfo.insert(ABS_Z, AxisInfo(absInfo.minimum, absInfo.maximum, absInfo.flat));
- if (ioctl(m_fd, EVIOCGABS(ABS_RZ), &absInfo) >= 0)
- m_axisInfo.insert(ABS_RZ, AxisInfo(absInfo.minimum, absInfo.maximum, absInfo.flat));
-
- qCDebug(lcEGB) << "Axis limits:" << m_axisInfo;
+ data = settings.toMap()[QLatin1Literal("buttons")].toMap();
+ for (QVariantMap::const_iterator it = data.begin(); it != data.end(); ++it)
+ m_buttonsMap[it.key().toInt()] = QGamepadManager::GamepadButton(it.value().toInt());
+ }
+ }
+ if (m_needsConfigure)
+ resetConfiguration();
+
+ qCDebug(lcEGB) << "Axis limits:" << m_axisMap;
return true;
}
-QDebug operator<<(QDebug dbg, const QEvdevGamepadDevice::AxisInfo &axisInfo)
+QDebug operator<<(QDebug dbg, const QEvdevGamepadDevice::EvdevAxisInfo &axisInfo)
{
dbg.nospace() << "AxisInfo(min=" << axisInfo.minValue << ", max=" << axisInfo.maxValue << ")";
return dbg.space();
@@ -229,185 +377,135 @@ err:
}
}
-double QEvdevGamepadDevice::AxisInfo::normalized(int value) const
+void QEvdevGamepadDevice::saveData()
{
- double ret = 0;
- if (minValue >= 0)
- ret = 2 * (value - double(maxValue - minValue) / 2) / double(maxValue - minValue);
- else
- ret = 2 * (value - minValue) / double(maxValue - minValue) - 1.0;
- if (fabs(ret) <= fabs(flat))
- ret = 0;
- return ret;
+ if (!m_productId)
+ return ;
+
+ QVariantMap settings, data;
+ for (AxisMap::const_iterator it = m_axisMap.begin(); it != m_axisMap.end(); ++it)
+ data[QString::number(it.key())] = it.value().dataToSave();
+ settings[QLatin1Literal("axes")] = data;
+
+ data.clear();
+ for (ButtonsMap::const_iterator it = m_buttonsMap.begin(); it != m_buttonsMap.end(); ++it)
+ data[QString::number(it.key())] = it.value();
+
+ settings[QLatin1Literal("buttons")] = data;
+
+ m_backend->saveSettings(m_productId, settings);
}
void QEvdevGamepadDevice::processInputEvent(input_event *e)
{
- if (m_index < 0) {
- m_index = m_backend->idForDevice(m_dev);
- qCDebug(lcEGB) << "Adding gamepad" << m_dev << "with index" << m_index;
- emit m_backend->gamepadAdded(m_index);
- }
-
if (e->type == EV_KEY) {
- const bool pressed = e->value;
QGamepadManager::GamepadButton btn = QGamepadManager::ButtonInvalid;
+ ButtonsMap::const_iterator it = m_buttonsMap.find(e->code);
+ if (it != m_buttonsMap.end())
+ btn = it.value();
- switch (e->code) {
- case BTN_START:
- btn = QGamepadManager::ButtonStart;
- break;
- case BTN_SELECT:
- btn = QGamepadManager::ButtonSelect;
- break;
- case BTN_MODE:
- btn = QGamepadManager::ButtonGuide;
- break;
-
- case BTN_X:
- btn = QGamepadManager::ButtonX;
- break;
- case BTN_Y:
- btn = QGamepadManager::ButtonY;
- break;
- case BTN_A:
- btn = QGamepadManager::ButtonA;
- break;
- case BTN_B:
- btn = QGamepadManager::ButtonB;
- break;
-
- case BTN_TL:
- btn = QGamepadManager::ButtonL1;
- break;
- case BTN_TR:
- btn = QGamepadManager::ButtonR1;
- break;
-
- case BTN_TL2:
- btn = QGamepadManager::ButtonL2;
- break;
- case BTN_TR2:
- btn = QGamepadManager::ButtonR2;
- break;
-
+ const bool pressed = e->value;
+ if (m_configureCancelButton != QGamepadManager::ButtonInvalid &&
+ m_configureCancelButton != m_configureButton &&
+ !pressed && btn == m_configureCancelButton &&
+ (m_configureButton != QGamepadManager::ButtonInvalid ||
+ m_configureAxis != QGamepadManager::AxisInvalid)) {
+ m_configureButton = QGamepadManager::ButtonInvalid;
+ m_configureAxis = QGamepadManager::AxisInvalid;
+ emit m_backend->configurationCanceled(m_fd);
+ return;
+ }
- case BTN_THUMB: // wireless
- case BTN_THUMBL: // wired
- btn = QGamepadManager::ButtonL3;
- break;
- case BTN_THUMBR:
- btn = QGamepadManager::ButtonR3;
- break;
+ if (!pressed && m_configureButton != QGamepadManager::ButtonInvalid) {
+ m_buttonsMap[e->code] = m_configureButton;
+ QGamepadManager::GamepadButton but = m_configureButton;
+ m_configureButton = QGamepadManager::ButtonInvalid;
+ saveData();
+ emit m_backend->buttonConfigured(m_fd, but);
+ }
- // Directional buttons for wireless
- case BTN_TRIGGER_HAPPY1:
- btn = QGamepadManager::ButtonLeft;
- break;
- case BTN_TRIGGER_HAPPY2:
- btn = QGamepadManager::ButtonRight;
- break;
- case BTN_TRIGGER_HAPPY3:
- btn = QGamepadManager::ButtonUp;
- break;
- case BTN_TRIGGER_HAPPY4:
- btn = QGamepadManager::ButtonDown;
- break;
+ it = m_buttonsMap.find(e->code);
+ if (it != m_buttonsMap.end())
+ btn = it.value();
- default:
- break;
- }
if (btn != QGamepadManager::ButtonInvalid) {
if (pressed)
- emit m_backend->gamepadButtonPressed(m_index, btn, 1.0);
+ emit m_backend->gamepadButtonPressed(m_fd, btn, 1.0);
else
- emit m_backend->gamepadButtonReleased(m_index, btn);
+ emit m_backend->gamepadButtonReleased(m_fd, btn);
}
} else if (e->type == EV_ABS) {
- if (e->code == ABS_HAT0X || e->code == ABS_HAT0Y) {
- //Special logic for digital direction buttons as it is treated as a hat axis
- //with the wired controller.
- double value = m_axisInfo.value(e->code).normalized(e->value);
- QGamepadManager::GamepadButton btn = QGamepadManager::ButtonInvalid;
- bool pressed = false;
- if (e->code == ABS_HAT0X) {
- if (value == 1.0) {
- btn = QGamepadManager::ButtonRight;
- m_prevXHatButton = btn;
- pressed = true;
- } else if (value == -1.0) {
- btn = QGamepadManager::ButtonLeft;
- m_prevXHatButton = btn;
- pressed = true;
- } else {
- //Release
- btn = m_prevXHatButton;
- m_prevXHatButton = QGamepadManager::ButtonInvalid;
- pressed = false;
- }
- } else {
- if (value == 1.0) {
- btn = QGamepadManager::ButtonDown;
- m_prevYHatButton = btn;
- pressed = true;
- } else if (value == -1.0) {
- btn = QGamepadManager::ButtonUp;
- m_prevYHatButton = btn;
- pressed = true;
- } else {
- //Release
- btn = m_prevYHatButton;
- m_prevYHatButton = QGamepadManager::ButtonInvalid;
- pressed = false;
- }
- }
- if (btn != QGamepadManager::ButtonInvalid) {
- if (pressed)
- emit m_backend->gamepadButtonPressed(m_index, btn, 1.0);
- else
- emit m_backend->gamepadButtonReleased(m_index, btn);
+ if (m_configureAxis != QGamepadManager::AxisInvalid) {
+ m_axisMap.insert(e->code, EvdevAxisInfo(m_fd, e->code, -32768, 32767, m_configureAxis));
+
+ QGamepadManager::GamepadAxis axis = m_configureAxis;
+ m_configureAxis = QGamepadManager::AxisInvalid;
+
+ saveData();
+ emit m_backend->axisConfigured(m_fd, axis);
+ }
+
+ AxisMap::iterator it = m_axisMap.find(e->code);
+ if (m_configureButton != QGamepadManager::ButtonInvalid) {
+ EvdevAxisInfo axisInfo;
+ if (it != m_axisMap.end())
+ axisInfo = it.value();
+ else
+ axisInfo = EvdevAxisInfo(m_fd, e->code);
+
+ axisInfo.gamepadAxis = QGamepadManager::AxisInvalid;
+
+ bool save = false;
+ if (e->value == axisInfo.minValue) {
+ axisInfo.gamepadMinButton = m_configureButton;
+ if (axisInfo.gamepadMaxButton != QGamepadManager::ButtonInvalid)
+ axisInfo.gamepadMaxButton = m_configureButton;
+ save = true;
+ } else if (e->value == axisInfo.maxValue) {
+ axisInfo.gamepadMaxButton = m_configureButton;
+ if (axisInfo.gamepadMinButton != QGamepadManager::ButtonInvalid)
+ axisInfo.gamepadMinButton = m_configureButton;
+ save = true;
}
- } else {
- QGamepadManager::GamepadAxis axis = QGamepadManager::AxisInvalid;
- QGamepadManager::GamepadButton btn = QGamepadManager::ButtonInvalid;
-
- switch (e->code) {
- case ABS_X:
- axis = QGamepadManager::AxisLeftX;
- break;
- case ABS_Y:
- axis = QGamepadManager::AxisLeftY;
- break;
-
- case ABS_RX:
- axis = QGamepadManager::AxisRightX;
- break;
- case ABS_RY:
- axis = QGamepadManager::AxisRightY;
- break;
-
- case ABS_Z:
- btn = QGamepadManager::ButtonL2;
- break;
- case ABS_RZ:
- btn = QGamepadManager::ButtonR2;
- break;
-
- default:
- break;
+ if (save) {
+ QGamepadManager::GamepadButton but = m_configureButton;
+ m_configureButton = QGamepadManager::ButtonInvalid;
+ saveData();
+ emit m_backend->buttonConfigured(m_fd, but);
}
+ }
+
+ it = m_axisMap.find(e->code);
+ if (it == m_axisMap.end())
+ return;
+
+ EvdevAxisInfo &info = it.value();
- AxisInfo axisInfo = m_axisInfo.value(e->code);
- const double value = axisInfo.normalized(e->value);
+ double val = info.normalized(e->value);
- if (axis != QGamepadManager::AxisInvalid) {
- emit m_backend->gamepadAxisMoved(m_index, axis, value);
- } else if (btn != QGamepadManager::ButtonInvalid) {
- if (!qFuzzyIsNull(value))
- emit m_backend->gamepadButtonPressed(m_index, btn, value);
- else
- emit m_backend->gamepadButtonReleased(m_index, btn);
+ if (info.gamepadAxis != QGamepadManager::AxisInvalid)
+ emit m_backend->gamepadAxisMoved(m_fd, info.gamepadAxis, val);
+
+ if (info.gamepadMaxButton == info.gamepadMinButton &&
+ info.gamepadMaxButton != QGamepadManager::ButtonInvalid) {
+ if (val)
+ emit m_backend->gamepadButtonPressed(m_fd, info.gamepadMaxButton, val);
+ else
+ emit m_backend->gamepadButtonReleased(m_fd, info.gamepadMaxButton);
+ } else {
+ if (info.gamepadMaxButton != QGamepadManager::ButtonInvalid
+ && val == 1.0) {
+ info.gamepadLastButton = info.gamepadMaxButton;
+ emit m_backend->gamepadButtonPressed(m_fd, info.gamepadMaxButton, val);
+ } else if (info.gamepadMinButton != QGamepadManager::ButtonInvalid
+ && val == -1.0) {
+ info.gamepadLastButton = info.gamepadMinButton;
+ emit m_backend->gamepadButtonPressed(m_fd, info.gamepadMinButton, val);
+ } else if (!val && info.gamepadLastButton != QGamepadManager::ButtonInvalid) {
+ QGamepadManager::GamepadButton but = info.gamepadLastButton;
+ info.gamepadLastButton = QGamepadManager::ButtonInvalid;
+ emit m_backend->gamepadButtonReleased(m_fd, but);
}
}
}