diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-07-11 17:17:13 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2019-07-11 17:17:51 +0200 |
commit | 4dac45c9ee59ff6586d90d423654da91523ab679 (patch) | |
tree | cd4a4adf2cbc9e77bf86d2d11e71ec66afdf3be4 /src/platformsupport/input | |
parent | 078cd61751aeaa310d35a3d596a21a36004a1a0f (diff) | |
parent | f44850b5c3464cdda0ee9b1ee858d95f3ffaa3e2 (diff) |
Merge remote-tracking branch 'origin/wip/qt6' into wip/cmake
Change-Id: I715b1d743d5f11560e7b3fbeb8fd64a5e5ddb277
Diffstat (limited to 'src/platformsupport/input')
20 files changed, 420 insertions, 201 deletions
diff --git a/src/platformsupport/input/.prev_CMakeLists.txt b/src/platformsupport/input/.prev_CMakeLists.txt index 902e61f4a5..d5e013ba9f 100644 --- a/src/platformsupport/input/.prev_CMakeLists.txt +++ b/src/platformsupport/input/.prev_CMakeLists.txt @@ -92,6 +92,8 @@ extend_target(InputSupport CONDITION QT_FEATURE_libinput AND QT_FEATURE_xkbcommo extend_target(InputSupport CONDITION QT_FEATURE_evdev OR QT_FEATURE_libinput SOURCES + shared/devicehandlerlist_p.h + shared/qevdevutil.cpp shared/qevdevutil_p.h shared/qtouchoutputmapping.cpp shared/qtouchoutputmapping_p.h ) diff --git a/src/platformsupport/input/CMakeLists.txt b/src/platformsupport/input/CMakeLists.txt index f3d1b66a95..859d2d33ad 100644 --- a/src/platformsupport/input/CMakeLists.txt +++ b/src/platformsupport/input/CMakeLists.txt @@ -97,6 +97,8 @@ extend_target(InputSupport CONDITION QT_FEATURE_libinput AND QT_FEATURE_xkbcommo extend_target(InputSupport CONDITION QT_FEATURE_evdev OR QT_FEATURE_libinput SOURCES + shared/devicehandlerlist_p.h + shared/qevdevutil.cpp shared/qevdevutil_p.h shared/qtouchoutputmapping.cpp shared/qtouchoutputmapping_p.h ) diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp index 02d6586fe8..bff4a2522c 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -98,11 +98,12 @@ QEvdevKeyboardHandler::~QEvdevKeyboardHandler() unloadKeymap(); } -QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, +std::unique_ptr<QEvdevKeyboardHandler> QEvdevKeyboardHandler::create(const QString &device, const QString &specification, const QString &defaultKeymapFile) { - qCDebug(qLcEvdevKey) << "Try to create keyboard handler for" << device << specification; + qCDebug(qLcEvdevKey, "Try to create keyboard handler for \"%ls\" \"%ls\"", + qUtf16Printable(device), qUtf16Printable(specification)); QString keymapFile = defaultKeymapFile; int repeatDelay = 400; @@ -127,7 +128,7 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, grab = arg.mid(5).toInt(); } - qCDebug(qLcEvdevKey) << "Opening keyboard at" << device; + qCDebug(qLcEvdevKey, "Opening keyboard at %ls", qUtf16Printable(device)); QFdContainer fd(qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0)); if (fd.get() >= 0) { @@ -137,16 +138,16 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, ::ioctl(fd.get(), EVIOCSREP, kbdrep); } - return new QEvdevKeyboardHandler(device, fd, disableZap, enableCompose, keymapFile); + return std::unique_ptr<QEvdevKeyboardHandler>(new QEvdevKeyboardHandler(device, fd, disableZap, enableCompose, keymapFile)); } else { - qWarning("Cannot open keyboard input device '%s': %s", qPrintable(device), strerror(errno)); - return 0; + qErrnoWarning("Cannot open keyboard input device '%ls'", qUtf16Printable(device)); + return nullptr; } } void QEvdevKeyboardHandler::switchLed(int led, bool state) { - qCDebug(qLcEvdevKey) << "switchLed" << led << state; + qCDebug(qLcEvdevKey, "switchLed %d %d", led, int(state)); struct ::input_event led_ie; ::gettimeofday(&led_ie.time, 0); @@ -170,7 +171,7 @@ void QEvdevKeyboardHandler::readKeycode() return; } else if (result < 0) { if (errno != EINTR && errno != EAGAIN) { - qErrnoWarning(errno, "evdevkeyboard: Could not read from input device"); + qErrnoWarning("evdevkeyboard: Could not read from input device"); // If the device got disconnected, stop reading, otherwise we get flooded // by the above error over and over again. if (errno == ENODEV) { @@ -473,7 +474,7 @@ QEvdevKeyboardHandler::KeycodeAction QEvdevKeyboardHandler::processKeycode(quint void QEvdevKeyboardHandler::unloadKeymap() { - qCDebug(qLcEvdevKey) << "Unload current keymap and restore built-in"; + qCDebug(qLcEvdevKey, "Unload current keymap and restore built-in"); if (m_keymap && m_keymap != s_keymap_default) delete [] m_keymap; @@ -517,12 +518,12 @@ void QEvdevKeyboardHandler::unloadKeymap() bool QEvdevKeyboardHandler::loadKeymap(const QString &file) { - qCDebug(qLcEvdevKey) << "Loading keymap" << file; + qCDebug(qLcEvdevKey, "Loading keymap %ls", qUtf16Printable(file)); QFile f(file); if (!f.open(QIODevice::ReadOnly)) { - qWarning("Could not open keymap file '%s'", qPrintable(file)); + qWarning("Could not open keymap file '%ls'", qUtf16Printable(file)); return false; } @@ -541,7 +542,7 @@ bool QEvdevKeyboardHandler::loadKeymap(const QString &file) ds >> qmap_magic >> qmap_version >> qmap_keymap_size >> qmap_keycompose_size; if (ds.status() != QDataStream::Ok || qmap_magic != QEvdevKeyboardMap::FileMagic || qmap_version != 1 || qmap_keymap_size == 0) { - qWarning("'%s' is not a valid .qmap keymap file", qPrintable(file)); + qWarning("'%ls' is not a valid .qmap keymap file", qUtf16Printable(file)); return false; } @@ -557,7 +558,7 @@ bool QEvdevKeyboardHandler::loadKeymap(const QString &file) delete [] qmap_keymap; delete [] qmap_keycompose; - qWarning("Keymap file '%s' cannot be loaded.", qPrintable(file)); + qWarning("Keymap file '%ls' cannot be loaded.", qUtf16Printable(file)); return false; } diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h index d154c30ed5..f92a2bf704 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h @@ -55,6 +55,8 @@ #include <QTimer> #include <QDataStream> +#include <memory> + QT_BEGIN_NAMESPACE class QSocketNotifier; @@ -168,7 +170,7 @@ public: SwitchConsoleMask = 0x0000007f }; - static QEvdevKeyboardHandler *create(const QString &device, + static std::unique_ptr<QEvdevKeyboardHandler> create(const QString &device, const QString &specification, const QString &defaultKeymapFile = QString()); diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp index e1659bc0d9..52d9c34b1c 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager.cpp @@ -39,6 +39,8 @@ #include "qevdevkeyboardmanager_p.h" +#include <QtInputSupport/private/qevdevutil_p.h> + #include <QStringList> #include <QCoreApplication> #include <QLoggingCategory> @@ -61,36 +63,24 @@ QEvdevKeyboardManager::QEvdevKeyboardManager(const QString &key, const QString & if (spec.isEmpty()) spec = specification; - QStringList args = spec.split(QLatin1Char(':')); - QStringList devices; - - foreach (const QString &arg, args) { - if (arg.startsWith(QLatin1String("/dev/"))) { - // if device is specified try to use it - devices.append(arg); - args.removeAll(arg); - } - } - - // build new specification without /dev/ elements - m_spec = args.join(QLatin1Char(':')); + auto parsed = QEvdevUtil::parseSpecification(spec); + m_spec = std::move(parsed.spec); // add all keyboards for devices specified in the argument list - foreach (const QString &device, devices) + for (const QString &device : qAsConst(parsed.devices)) addKeyboard(device); - if (devices.isEmpty()) { - qCDebug(qLcEvdevKey) << "evdevkeyboard: Using device discovery"; - m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Keyboard, this); - if (m_deviceDiscovery) { + if (parsed.devices.isEmpty()) { + qCDebug(qLcEvdevKey, "evdevkeyboard: Using device discovery"); + if (auto deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Keyboard, this)) { // scan and add already connected keyboards - const QStringList devices = m_deviceDiscovery->scanConnectedDevices(); + const QStringList devices = deviceDiscovery->scanConnectedDevices(); for (const QString &device : devices) addKeyboard(device); - connect(m_deviceDiscovery, &QDeviceDiscovery::deviceDetected, + connect(deviceDiscovery, &QDeviceDiscovery::deviceDetected, this, &QEvdevKeyboardManager::addKeyboard); - connect(m_deviceDiscovery, &QDeviceDiscovery::deviceRemoved, + connect(deviceDiscovery, &QDeviceDiscovery::deviceRemoved, this, &QEvdevKeyboardManager::removeKeyboard); } } @@ -98,36 +88,34 @@ QEvdevKeyboardManager::QEvdevKeyboardManager(const QString &key, const QString & QEvdevKeyboardManager::~QEvdevKeyboardManager() { - qDeleteAll(m_keyboards); - m_keyboards.clear(); } void QEvdevKeyboardManager::addKeyboard(const QString &deviceNode) { - qCDebug(qLcEvdevKey) << "Adding keyboard at" << deviceNode; - QEvdevKeyboardHandler *keyboard; - keyboard = QEvdevKeyboardHandler::create(deviceNode, m_spec, m_defaultKeymapFile); + qCDebug(qLcEvdevKey, "Adding keyboard at %ls", qUtf16Printable(deviceNode)); + auto keyboard = QEvdevKeyboardHandler::create(deviceNode, m_spec, m_defaultKeymapFile); if (keyboard) { - m_keyboards.insert(deviceNode, keyboard); - QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( - QInputDeviceManager::DeviceTypeKeyboard, m_keyboards.count()); + m_keyboards.add(deviceNode, std::move(keyboard)); + updateDeviceCount(); } else { - qWarning("Failed to open keyboard device %s", qPrintable(deviceNode)); + qWarning("Failed to open keyboard device %ls", qUtf16Printable(deviceNode)); } } void QEvdevKeyboardManager::removeKeyboard(const QString &deviceNode) { - if (m_keyboards.contains(deviceNode)) { - qCDebug(qLcEvdevKey) << "Removing keyboard at" << deviceNode; - QEvdevKeyboardHandler *keyboard = m_keyboards.value(deviceNode); - m_keyboards.remove(deviceNode); - QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( - QInputDeviceManager::DeviceTypeKeyboard, m_keyboards.count()); - delete keyboard; + if (m_keyboards.remove(deviceNode)) { + qCDebug(qLcEvdevKey, "Removing keyboard at %ls", qUtf16Printable(deviceNode)); + updateDeviceCount(); } } +void QEvdevKeyboardManager::updateDeviceCount() +{ + QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( + QInputDeviceManager::DeviceTypeKeyboard, m_keyboards.count()); +} + void QEvdevKeyboardManager::loadKeymap(const QString &file) { m_defaultKeymapFile = file; @@ -141,22 +129,22 @@ void QEvdevKeyboardManager::loadKeymap(const QString &file) if (arg.startsWith(QLatin1String("keymap="))) keymapFromSpec = arg.mid(7).toString(); } - foreach (QEvdevKeyboardHandler *handler, m_keyboards) { + for (const auto &keyboard : m_keyboards) { if (keymapFromSpec.isEmpty()) - handler->unloadKeymap(); + keyboard.handler->unloadKeymap(); else - handler->loadKeymap(keymapFromSpec); + keyboard.handler->loadKeymap(keymapFromSpec); } } else { - foreach (QEvdevKeyboardHandler *handler, m_keyboards) - handler->loadKeymap(file); + for (const auto &keyboard : m_keyboards) + keyboard.handler->loadKeymap(file); } } void QEvdevKeyboardManager::switchLang() { - foreach (QEvdevKeyboardHandler *handler, m_keyboards) - handler->switchLang(); + for (const auto &keyboard : m_keyboards) + keyboard.handler->switchLang(); } QT_END_NAMESPACE diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager_p.h index 01b7e9fc0e..d91da330c3 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager_p.h +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardmanager_p.h @@ -53,6 +53,7 @@ #include "qevdevkeyboardhandler_p.h" +#include <QtInputSupport/private/devicehandlerlist_p.h> #include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h> #include <QObject> @@ -74,9 +75,10 @@ public: void removeKeyboard(const QString &deviceNode); private: + void updateDeviceCount(); + QString m_spec; - QHash<QString,QEvdevKeyboardHandler*> m_keyboards; - QDeviceDiscovery *m_deviceDiscovery; + QtInputSupport::DeviceHandlerList<QEvdevKeyboardHandler> m_keyboards; QString m_defaultKeymapFile; }; diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp index 86a4cd0076..6a53ad2088 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp +++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp @@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(qLcEvdevMouse, "qt.qpa.input") -QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QString &specification) +std::unique_ptr<QEvdevMouseHandler> QEvdevMouseHandler::create(const QString &device, const QString &specification) { qCDebug(qLcEvdevMouse) << "create mouse handler for" << device << specification; @@ -91,10 +91,10 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (fd >= 0) { ::ioctl(fd, EVIOCGRAB, grab); - return new QEvdevMouseHandler(device, fd, abs, compression, jitterLimit); + return std::unique_ptr<QEvdevMouseHandler>(new QEvdevMouseHandler(device, fd, abs, compression, jitterLimit)); } else { qErrnoWarning(errno, "Cannot open mouse input device %s", qPrintable(device)); - return 0; + return nullptr; } } diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h b/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h index c7f2b04eb2..727f1a02f9 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h +++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h @@ -56,6 +56,8 @@ #include <QPoint> #include <QEvent> +#include <memory> + QT_BEGIN_NAMESPACE class QSocketNotifier; @@ -64,7 +66,7 @@ class QEvdevMouseHandler : public QObject { Q_OBJECT public: - static QEvdevMouseHandler *create(const QString &device, const QString &specification); + static std::unique_ptr<QEvdevMouseHandler> create(const QString &device, const QString &specification); ~QEvdevMouseHandler(); void readMouseData(); diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp index ae81bca00f..0c19294905 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp +++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp @@ -39,6 +39,8 @@ #include "qevdevmousemanager_p.h" +#include <QtInputSupport/private/qevdevutil_p.h> + #include <QStringList> #include <QGuiApplication> #include <QScreen> @@ -63,40 +65,32 @@ QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specif if (spec.isEmpty()) spec = specification; - QStringList args = spec.split(QLatin1Char(':')); - QStringList devices; + auto parsed = QEvdevUtil::parseSpecification(spec); + m_spec = std::move(parsed.spec); - foreach (const QString &arg, args) { - if (arg.startsWith(QLatin1String("/dev/"))) { - // if device is specified try to use it - devices.append(arg); - args.removeAll(arg); - } else if (arg.startsWith(QLatin1String("xoffset="))) { + for (const QStringRef &arg : qAsConst(parsed.args)) { + if (arg.startsWith(QLatin1String("xoffset="))) { m_xoffset = arg.mid(8).toInt(); } else if (arg.startsWith(QLatin1String("yoffset="))) { m_yoffset = arg.mid(8).toInt(); } } - // build new specification without /dev/ elements - m_spec = args.join(QLatin1Char(':')); - // add all mice for devices specified in the argument list - foreach (const QString &device, devices) + for (const QString &device : qAsConst(parsed.devices)) addMouse(device); - if (devices.isEmpty()) { - qCDebug(qLcEvdevMouse) << "evdevmouse: Using device discovery"; - m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse | QDeviceDiscovery::Device_Touchpad, this); - if (m_deviceDiscovery) { + if (parsed.devices.isEmpty()) { + qCDebug(qLcEvdevMouse, "evdevmouse: Using device discovery"); + if (auto deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse | QDeviceDiscovery::Device_Touchpad, this)) { // scan and add already connected keyboards - const QStringList devices = m_deviceDiscovery->scanConnectedDevices(); + const QStringList devices = deviceDiscovery->scanConnectedDevices(); for (const QString &device : devices) addMouse(device); - connect(m_deviceDiscovery, &QDeviceDiscovery::deviceDetected, + connect(deviceDiscovery, &QDeviceDiscovery::deviceDetected, this, &QEvdevMouseManager::addMouse); - connect(m_deviceDiscovery, &QDeviceDiscovery::deviceRemoved, + connect(deviceDiscovery, &QDeviceDiscovery::deviceRemoved, this, &QEvdevMouseManager::removeMouse); } } @@ -111,8 +105,6 @@ QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specif QEvdevMouseManager::~QEvdevMouseManager() { - qDeleteAll(m_mice); - m_mice.clear(); } void QEvdevMouseManager::clampPosition() @@ -159,31 +151,32 @@ void QEvdevMouseManager::handleWheelEvent(QPoint delta) void QEvdevMouseManager::addMouse(const QString &deviceNode) { - qCDebug(qLcEvdevMouse) << "Adding mouse at" << deviceNode; - QEvdevMouseHandler *handler = QEvdevMouseHandler::create(deviceNode, m_spec); + qCDebug(qLcEvdevMouse, "Adding mouse at %ls", qUtf16Printable(deviceNode)); + auto handler = QEvdevMouseHandler::create(deviceNode, m_spec); if (handler) { - connect(handler, &QEvdevMouseHandler::handleMouseEvent, + connect(handler.get(), &QEvdevMouseHandler::handleMouseEvent, this, &QEvdevMouseManager::handleMouseEvent); - connect(handler, &QEvdevMouseHandler::handleWheelEvent, + connect(handler.get(), &QEvdevMouseHandler::handleWheelEvent, this, &QEvdevMouseManager::handleWheelEvent); - m_mice.insert(deviceNode, handler); - QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( - QInputDeviceManager::DeviceTypePointer, m_mice.count()); + m_mice.add(deviceNode, std::move(handler)); + updateDeviceCount(); } else { - qWarning("evdevmouse: Failed to open mouse device %s", qPrintable(deviceNode)); + qWarning("evdevmouse: Failed to open mouse device %ls", qUtf16Printable(deviceNode)); } } void QEvdevMouseManager::removeMouse(const QString &deviceNode) { - if (m_mice.contains(deviceNode)) { - qCDebug(qLcEvdevMouse) << "Removing mouse at" << deviceNode; - QEvdevMouseHandler *handler = m_mice.value(deviceNode); - m_mice.remove(deviceNode); - QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( - QInputDeviceManager::DeviceTypePointer, m_mice.count()); - delete handler; + if (m_mice.remove(deviceNode)) { + qCDebug(qLcEvdevMouse, "Removing mouse at %ls", qUtf16Printable(deviceNode)); + updateDeviceCount(); } } +void QEvdevMouseManager::updateDeviceCount() +{ + QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( + QInputDeviceManager::DeviceTypePointer, m_mice.count()); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h b/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h index c63ca29a71..f5c32ed8b5 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h +++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h @@ -53,6 +53,8 @@ #include "qevdevmousehandler_p.h" +#include <QtInputSupport/private/devicehandlerlist_p.h> + #include <QObject> #include <QHash> #include <QSocketNotifier> @@ -77,10 +79,10 @@ public: private: void clampPosition(); + void updateDeviceCount(); QString m_spec; - QHash<QString,QEvdevMouseHandler*> m_mice; - QDeviceDiscovery *m_deviceDiscovery; + QtInputSupport::DeviceHandlerList<QEvdevMouseHandler> m_mice; int m_x; int m_y; int m_xoffset; diff --git a/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp b/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp index b6051aaf3c..c86840b76c 100644 --- a/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp +++ b/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp @@ -172,11 +172,11 @@ QEvdevTabletHandler::QEvdevTabletHandler(const QString &device, const QString &s setObjectName(QLatin1String("Evdev Tablet Handler")); - qCDebug(qLcEvdevTablet, "evdevtablet: using %s", qPrintable(device)); + qCDebug(qLcEvdevTablet, "evdevtablet: using %ls", qUtf16Printable(device)); m_fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (m_fd < 0) { - qErrnoWarning(errno, "evdevtablet: Cannot open input device %s", qPrintable(device)); + qErrnoWarning("evdevtablet: Cannot open input device %ls", qUtf16Printable(device)); return; } @@ -184,11 +184,11 @@ QEvdevTabletHandler::QEvdevTabletHandler(const QString &device, const QString &s if (grabSuccess) ioctl(m_fd, EVIOCGRAB, (void *) 0); else - qWarning("evdevtablet: %s: The device is grabbed by another process. No events will be read.", qPrintable(device)); + qWarning("evdevtablet: %ls: The device is grabbed by another process. No events will be read.", qUtf16Printable(device)); d = new QEvdevTabletData(this); if (!queryLimits()) - qWarning("evdevtablet: %s: Unset or invalid ABS limits. Behavior will be unspecified.", qPrintable(device)); + qWarning("evdevtablet: %ls: Unset or invalid ABS limits. Behavior will be unspecified.", qUtf16Printable(device)); m_notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); connect(m_notifier, &QSocketNotifier::activated, this, &QEvdevTabletHandler::readData); @@ -216,32 +216,32 @@ bool QEvdevTabletHandler::queryLimits() if (ok) { d->minValues.x = absInfo.minimum; d->maxValues.x = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: %s: min X: %d max X: %d", qPrintable(m_device), + qCDebug(qLcEvdevTablet, "evdevtablet: %ls: min X: %d max X: %d", qUtf16Printable(m_device), d->minValues.x, d->maxValues.x); } ok &= ioctl(m_fd, EVIOCGABS(ABS_Y), &absInfo) >= 0; if (ok) { d->minValues.y = absInfo.minimum; d->maxValues.y = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: %s: min Y: %d max Y: %d", qPrintable(m_device), + qCDebug(qLcEvdevTablet, "evdevtablet: %ls: min Y: %d max Y: %d", qUtf16Printable(m_device), d->minValues.y, d->maxValues.y); } if (ioctl(m_fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) { d->minValues.p = absInfo.minimum; d->maxValues.p = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: %s: min pressure: %d max pressure: %d", qPrintable(m_device), + qCDebug(qLcEvdevTablet, "evdevtablet: %ls: min pressure: %d max pressure: %d", qUtf16Printable(m_device), d->minValues.p, d->maxValues.p); } if (ioctl(m_fd, EVIOCGABS(ABS_DISTANCE), &absInfo) >= 0) { d->minValues.d = absInfo.minimum; d->maxValues.d = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: %s: min distance: %d max distance: %d", qPrintable(m_device), + qCDebug(qLcEvdevTablet, "evdevtablet: %ls: min distance: %d max distance: %d", qUtf16Printable(m_device), d->minValues.d, d->maxValues.d); } char name[128]; if (ioctl(m_fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) { d->devName = QString::fromLocal8Bit(name); - qCDebug(qLcEvdevTablet, "evdevtablet: %s: device name: %s", qPrintable(m_device), name); + qCDebug(qLcEvdevTablet, "evdevtablet: %ls: device name: %s", qUtf16Printable(m_device), name); } return ok; } @@ -253,11 +253,11 @@ void QEvdevTabletHandler::readData() for (; ;) { int result = QT_READ(m_fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n); if (!result) { - qWarning("evdevtablet: %s: Got EOF from input device", qPrintable(m_device)); + qWarning("evdevtablet: %ls: Got EOF from input device", qUtf16Printable(m_device)); return; } else if (result < 0) { if (errno != EINTR && errno != EAGAIN) { - qErrnoWarning(errno, "evdevtablet: %s: Could not read from input device", qPrintable(m_device)); + qErrnoWarning("evdevtablet: %ls: Could not read from input device", qUtf16Printable(m_device)); if (errno == ENODEV) { // device got disconnected -> stop reading delete m_notifier; m_notifier = 0; diff --git a/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp b/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp index 90949408ac..d9888c5b97 100644 --- a/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp +++ b/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp @@ -40,12 +40,15 @@ #include "qevdevtabletmanager_p.h" #include "qevdevtablethandler_p.h" +#include <QtInputSupport/private/qevdevutil_p.h> + #include <QStringList> #include <QGuiApplication> #include <QLoggingCategory> #include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h> #include <private/qguiapplication_p.h> #include <private/qinputdevicemanager_p_p.h> +#include <private/qmemory_p.h> QT_BEGIN_NAMESPACE @@ -64,34 +67,23 @@ QEvdevTabletManager::QEvdevTabletManager(const QString &key, const QString &spec if (spec.isEmpty()) spec = specification; - QStringList args = spec.split(QLatin1Char(':')); - QStringList devices; - - foreach (const QString &arg, args) { - if (arg.startsWith(QLatin1String("/dev/"))) { - devices.append(arg); - args.removeAll(arg); - } - } - - // build new specification without /dev/ elements - m_spec = args.join(QLatin1Char(':')); + auto parsed = QEvdevUtil::parseSpecification(spec); + m_spec = std::move(parsed.spec); - foreach (const QString &device, devices) + for (const QString &device : qAsConst(parsed.devices)) addDevice(device); // when no devices specified, use device discovery to scan and monitor - if (devices.isEmpty()) { - qCDebug(qLcEvdevTablet) << "evdevtablet: Using device discovery"; - m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Tablet, this); - if (m_deviceDiscovery) { - const QStringList devices = m_deviceDiscovery->scanConnectedDevices(); + if (parsed.devices.isEmpty()) { + qCDebug(qLcEvdevTablet, "evdevtablet: Using device discovery"); + if (auto deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Tablet, this)) { + const QStringList devices = deviceDiscovery->scanConnectedDevices(); for (const QString &device : devices) addDevice(device); - connect(m_deviceDiscovery, &QDeviceDiscovery::deviceDetected, + connect(deviceDiscovery, &QDeviceDiscovery::deviceDetected, this, &QEvdevTabletManager::addDevice); - connect(m_deviceDiscovery, &QDeviceDiscovery::deviceRemoved, + connect(deviceDiscovery, &QDeviceDiscovery::deviceRemoved, this, &QEvdevTabletManager::removeDevice); } } @@ -99,33 +91,32 @@ QEvdevTabletManager::QEvdevTabletManager(const QString &key, const QString &spec QEvdevTabletManager::~QEvdevTabletManager() { - qDeleteAll(m_activeDevices); } void QEvdevTabletManager::addDevice(const QString &deviceNode) { - qCDebug(qLcEvdevTablet) << "Adding device at" << deviceNode; - QEvdevTabletHandlerThread *handler; - handler = new QEvdevTabletHandlerThread(deviceNode, m_spec); + qCDebug(qLcEvdevTablet, "Adding device at %ls", qUtf16Printable(deviceNode)); + auto handler = qt_make_unique<QEvdevTabletHandlerThread>(deviceNode, m_spec); if (handler) { - m_activeDevices.insert(deviceNode, handler); - QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( - QInputDeviceManager::DeviceTypeTablet, m_activeDevices.count()); + m_activeDevices.add(deviceNode, std::move(handler)); + updateDeviceCount(); } else { - qWarning("evdevtablet: Failed to open tablet device %s", qPrintable(deviceNode)); + qWarning("evdevtablet: Failed to open tablet device %ls", qUtf16Printable(deviceNode)); } } void QEvdevTabletManager::removeDevice(const QString &deviceNode) { - if (m_activeDevices.contains(deviceNode)) { - qCDebug(qLcEvdevTablet) << "Removing device at" << deviceNode; - QEvdevTabletHandlerThread *handler = m_activeDevices.value(deviceNode); - m_activeDevices.remove(deviceNode); - QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( - QInputDeviceManager::DeviceTypeTablet, m_activeDevices.count()); - delete handler; + if (m_activeDevices.remove(deviceNode)) { + qCDebug(qLcEvdevTablet, "Removing device at %ls", qUtf16Printable(deviceNode)); + updateDeviceCount(); } } +void QEvdevTabletManager::updateDeviceCount() +{ + QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( + QInputDeviceManager::DeviceTypeTablet, m_activeDevices.count()); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h b/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h index b598156e52..bb18ffba04 100644 --- a/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h +++ b/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h @@ -51,6 +51,8 @@ // We mean it. // +#include <QtInputSupport/private/devicehandlerlist_p.h> + #include <QObject> #include <QHash> #include <QSocketNotifier> @@ -70,9 +72,10 @@ public: void removeDevice(const QString &deviceNode); private: + void updateDeviceCount(); + QString m_spec; - QDeviceDiscovery *m_deviceDiscovery; - QHash<QString, QEvdevTabletHandlerThread *> m_activeDevices; + QtInputSupport::DeviceHandlerList<QEvdevTabletHandlerThread> m_activeDevices; }; QT_END_NAMESPACE diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp index c3a5391255..737d85d5c3 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp @@ -228,7 +228,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const } } - qCDebug(qLcEvdevTouch, "evdevtouch: Using device %s", qPrintable(device)); + qCDebug(qLcEvdevTouch, "evdevtouch: Using device %ls", qUtf16Printable(device)); m_fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); @@ -236,7 +236,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); connect(m_notify, &QSocketNotifier::activated, this, &QEvdevTouchScreenHandler::readData); } else { - qErrnoWarning(errno, "evdevtouch: Cannot open input device %s", qPrintable(device)); + qErrnoWarning("evdevtouch: Cannot open input device %ls", qUtf16Printable(device)); return; } @@ -266,8 +266,8 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const d->deviceNode = device; qCDebug(qLcEvdevTouch, - "evdevtouch: %s: Protocol type %c %s (%s), filtered=%s", - qPrintable(d->deviceNode), + "evdevtouch: %ls: Protocol type %c %s (%s), filtered=%s", + qUtf16Printable(d->deviceNode), d->m_typeB ? 'B' : 'A', mtdevStr, d->m_singleTouch ? "single" : "multi", d->m_filtered ? "yes" : "no"); @@ -279,7 +279,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const bool has_x_range = false, has_y_range = false; if (ioctl(m_fd, EVIOCGABS((d->m_singleTouch ? ABS_X : ABS_MT_POSITION_X)), &absInfo) >= 0) { - qCDebug(qLcEvdevTouch, "evdevtouch: %s: min X: %d max X: %d", qPrintable(device), + qCDebug(qLcEvdevTouch, "evdevtouch: %ls: min X: %d max X: %d", qUtf16Printable(device), absInfo.minimum, absInfo.maximum); d->hw_range_x_min = absInfo.minimum; d->hw_range_x_max = absInfo.maximum; @@ -287,7 +287,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const } if (ioctl(m_fd, EVIOCGABS((d->m_singleTouch ? ABS_Y : ABS_MT_POSITION_Y)), &absInfo) >= 0) { - qCDebug(qLcEvdevTouch, "evdevtouch: %s: min Y: %d max Y: %d", qPrintable(device), + qCDebug(qLcEvdevTouch, "evdevtouch: %ls: min Y: %d max Y: %d", qUtf16Printable(device), absInfo.minimum, absInfo.maximum); d->hw_range_y_min = absInfo.minimum; d->hw_range_y_max = absInfo.maximum; @@ -295,10 +295,10 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const } if (!has_x_range || !has_y_range) - qWarning("evdevtouch: %s: Invalid ABS limits, behavior unspecified", qPrintable(device)); + qWarning("evdevtouch: %ls: Invalid ABS limits, behavior unspecified", qUtf16Printable(device)); if (ioctl(m_fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) { - qCDebug(qLcEvdevTouch, "evdevtouch: %s: min pressure: %d max pressure: %d", qPrintable(device), + qCDebug(qLcEvdevTouch, "evdevtouch: %ls: min pressure: %d max pressure: %d", qUtf16Printable(device), absInfo.minimum, absInfo.maximum); if (absInfo.maximum > absInfo.minimum) { d->hw_pressure_min = absInfo.minimum; @@ -309,7 +309,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const char name[1024]; if (ioctl(m_fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) { d->hw_name = QString::fromLocal8Bit(name); - qCDebug(qLcEvdevTouch, "evdevtouch: %s: device name: %s", qPrintable(device), name); + qCDebug(qLcEvdevTouch, "evdevtouch: %ls: device name: %s", qUtf16Printable(device), name); } // Fix up the coordinate ranges for am335x in case the kernel driver does not have them fixed. @@ -345,8 +345,8 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const if (mapping.load()) { d->m_screenName = mapping.screenNameForDeviceNode(d->deviceNode); if (!d->m_screenName.isEmpty()) - qCDebug(qLcEvdevTouch, "evdevtouch: Mapping device %s to screen %s", - qPrintable(d->deviceNode), qPrintable(d->m_screenName)); + qCDebug(qLcEvdevTouch, "evdevtouch: Mapping device %ls to screen %ls", + qUtf16Printable(d->deviceNode), qUtf16Printable(d->m_screenName)); } registerTouchDevice(); @@ -427,7 +427,7 @@ err: return; } else if (events < 0) { if (errno != EINTR && errno != EAGAIN) { - qErrnoWarning(errno, "evdevtouch: Could not read from input device"); + qErrnoWarning("evdevtouch: Could not read from input device"); if (errno == ENODEV) { // device got disconnected -> stop reading delete m_notify; m_notify = nullptr; diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp index 4cacbf03e5..b280f27fac 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp @@ -40,12 +40,15 @@ #include "qevdevtouchmanager_p.h" #include "qevdevtouchhandler_p.h" +#include <QtInputSupport/private/qevdevutil_p.h> + #include <QStringList> #include <QGuiApplication> #include <QLoggingCategory> #include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h> #include <private/qguiapplication_p.h> #include <private/qinputdevicemanager_p_p.h> +#include <private/qmemory_p.h> QT_BEGIN_NAMESPACE @@ -64,34 +67,23 @@ QEvdevTouchManager::QEvdevTouchManager(const QString &key, const QString &specif if (spec.isEmpty()) spec = specification; - QStringList args = spec.split(QLatin1Char(':')); - QStringList devices; - - foreach (const QString &arg, args) { - if (arg.startsWith(QLatin1String("/dev/"))) { - devices.append(arg); - args.removeAll(arg); - } - } - - // build new specification without /dev/ elements - m_spec = args.join(QLatin1Char(':')); + auto parsed = QEvdevUtil::parseSpecification(spec); + m_spec = std::move(parsed.spec); - foreach (const QString &device, devices) + for (const QString &device : qAsConst(parsed.devices)) addDevice(device); // when no devices specified, use device discovery to scan and monitor - if (devices.isEmpty()) { - qCDebug(qLcEvdevTouch) << "evdevtouch: Using device discovery"; - m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Touchpad | QDeviceDiscovery::Device_Touchscreen, this); - if (m_deviceDiscovery) { - const QStringList devices = m_deviceDiscovery->scanConnectedDevices(); + if (parsed.devices.isEmpty()) { + qCDebug(qLcEvdevTouch, "evdevtouch: Using device discovery"); + if (auto deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Touchpad | QDeviceDiscovery::Device_Touchscreen, this)) { + const QStringList devices = deviceDiscovery->scanConnectedDevices(); for (const QString &device : devices) addDevice(device); - connect(m_deviceDiscovery, &QDeviceDiscovery::deviceDetected, + connect(deviceDiscovery, &QDeviceDiscovery::deviceDetected, this, &QEvdevTouchManager::addDevice); - connect(m_deviceDiscovery, &QDeviceDiscovery::deviceRemoved, + connect(deviceDiscovery, &QDeviceDiscovery::deviceRemoved, this, &QEvdevTouchManager::removeDevice); } } @@ -99,30 +91,24 @@ QEvdevTouchManager::QEvdevTouchManager(const QString &key, const QString &specif QEvdevTouchManager::~QEvdevTouchManager() { - qDeleteAll(m_activeDevices); } void QEvdevTouchManager::addDevice(const QString &deviceNode) { - qCDebug(qLcEvdevTouch) << "evdevtouch: Adding device at" << deviceNode; - QEvdevTouchScreenHandlerThread *handler; - handler = new QEvdevTouchScreenHandlerThread(deviceNode, m_spec); + qCDebug(qLcEvdevTouch, "evdevtouch: Adding device at %ls", qUtf16Printable(deviceNode)); + auto handler = qt_make_unique<QEvdevTouchScreenHandlerThread>(deviceNode, m_spec); if (handler) { - m_activeDevices.insert(deviceNode, handler); - connect(handler, &QEvdevTouchScreenHandlerThread::touchDeviceRegistered, this, &QEvdevTouchManager::updateInputDeviceCount); + m_activeDevices.add(deviceNode, std::move(handler)); + connect(handler.get(), &QEvdevTouchScreenHandlerThread::touchDeviceRegistered, this, &QEvdevTouchManager::updateInputDeviceCount); } else { - qWarning("evdevtouch: Failed to open touch device %s", qPrintable(deviceNode)); + qWarning("evdevtouch: Failed to open touch device %ls", qUtf16Printable(deviceNode)); } } void QEvdevTouchManager::removeDevice(const QString &deviceNode) { - if (m_activeDevices.contains(deviceNode)) { - qCDebug(qLcEvdevTouch) << "evdevtouch: Removing device at" << deviceNode; - QEvdevTouchScreenHandlerThread *handler = m_activeDevices.value(deviceNode); - m_activeDevices.remove(deviceNode); - delete handler; - + if (m_activeDevices.remove(deviceNode)) { + qCDebug(qLcEvdevTouch, "evdevtouch: Removing device at %ls", qUtf16Printable(deviceNode)); updateInputDeviceCount(); } } @@ -130,13 +116,13 @@ void QEvdevTouchManager::removeDevice(const QString &deviceNode) void QEvdevTouchManager::updateInputDeviceCount() { int registeredTouchDevices = 0; - Q_FOREACH (QEvdevTouchScreenHandlerThread *handler, m_activeDevices) { - if (handler->isTouchDeviceRegistered()) + for (const auto &device : m_activeDevices) { + if (device.handler->isTouchDeviceRegistered()) ++registeredTouchDevices; } - qCDebug(qLcEvdevTouch) << "evdevtouch: Updating QInputDeviceManager device count:" << registeredTouchDevices << " touch devices," - << m_activeDevices.count() - registeredTouchDevices << "pending handler(s)" ; + qCDebug(qLcEvdevTouch, "evdevtouch: Updating QInputDeviceManager device count: %d touch devices, %d pending handler(s)", + registeredTouchDevices, m_activeDevices.count() - registeredTouchDevices); QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( QInputDeviceManager::DeviceTypeTouch, registeredTouchDevices); diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h b/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h index b9b772fb3a..94ee05d900 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h +++ b/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h @@ -51,6 +51,8 @@ // We mean it. // +#include <QtInputSupport/private/devicehandlerlist_p.h> + #include <QObject> #include <QHash> #include <QSocketNotifier> @@ -73,8 +75,7 @@ public: private: QString m_spec; - QDeviceDiscovery *m_deviceDiscovery; - QHash<QString, QEvdevTouchScreenHandlerThread *> m_activeDevices; + QtInputSupport::DeviceHandlerList<QEvdevTouchScreenHandlerThread> m_activeDevices; }; QT_END_NAMESPACE diff --git a/src/platformsupport/input/shared/devicehandlerlist_p.h b/src/platformsupport/input/shared/devicehandlerlist_p.h new file mode 100644 index 0000000000..97794d4d7d --- /dev/null +++ b/src/platformsupport/input/shared/devicehandlerlist_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTINPUTSUPPORT_DEVICEHANDLERLIST_P_H +#define QTINPUTSUPPORT_DEVICEHANDLERLIST_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QString> + +#include <vector> +#include <memory> + +namespace QtInputSupport { + +template <typename Handler> +class DeviceHandlerList { +public: + struct Device { + QString deviceNode; + std::unique_ptr<Handler> handler; + }; + + void add(const QString &deviceNode, std::unique_ptr<Handler> handler) + { + v.push_back({deviceNode, std::move(handler)}); + } + + bool remove(const QString &deviceNode) + { + const auto deviceNodeMatches = [&] (const Device &d) { return d.deviceNode == deviceNode; }; + const auto it = std::find_if(v.cbegin(), v.cend(), deviceNodeMatches); + if (it == v.cend()) + return false; + v.erase(it); + return true; + } + + int count() const noexcept { return static_cast<int>(v.size()); } + + typename std::vector<Device>::const_iterator begin() const noexcept { return v.begin(); } + typename std::vector<Device>::const_iterator end() const noexcept { return v.end(); } + +private: + std::vector<Device> v; +}; + +} // QtInputSupport + +#endif // QTINPUTSUPPORT_DEVICEHANDLERLIST_P_H diff --git a/src/platformsupport/input/shared/qevdevutil.cpp b/src/platformsupport/input/shared/qevdevutil.cpp new file mode 100644 index 0000000000..74f8bcdc2b --- /dev/null +++ b/src/platformsupport/input/shared/qevdevutil.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qevdevutil_p.h" + +QT_BEGIN_NAMESPACE + +namespace QEvdevUtil { + +ParsedSpecification parseSpecification(const QString &specification) +{ + ParsedSpecification result; + + result.args = specification.splitRef(QLatin1Char(':')); + + for (const QStringRef &arg : qAsConst(result.args)) { + if (arg.startsWith(QLatin1String("/dev/"))) { + // if device is specified try to use it + result.devices.append(arg.toString()); + } else { + // build new specification without /dev/ elements + result.spec += arg + QLatin1Char(':'); + } + } + + if (!result.spec.isEmpty()) + result.spec.chop(1); // remove trailing ':' + + return result; +} + +} // namespace QEvdevUtil + +QT_END_NAMESPACE diff --git a/src/platformsupport/input/shared/qevdevutil_p.h b/src/platformsupport/input/shared/qevdevutil_p.h new file mode 100644 index 0000000000..7d0a5af130 --- /dev/null +++ b/src/platformsupport/input/shared/qevdevutil_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVDEVUTIL_P_H +#define QEVDEVUTIL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QString> +#include <QStringList> +#include <QVector> +#include <QStringRef> + +QT_BEGIN_NAMESPACE + +namespace QEvdevUtil { + +struct ParsedSpecification +{ + QString spec; + QStringList devices; + QVector<QStringRef> args; +}; + +ParsedSpecification parseSpecification(const QString &specification); + +} + +QT_END_NAMESPACE + +#endif // QEVDEVUTIL_P_H diff --git a/src/platformsupport/input/shared/shared.pri b/src/platformsupport/input/shared/shared.pri index 1443235244..c29d11e7d6 100644 --- a/src/platformsupport/input/shared/shared.pri +++ b/src/platformsupport/input/shared/shared.pri @@ -1,5 +1,8 @@ HEADERS += \ + $$PWD/devicehandlerlist_p.h \ + $$PWD/qevdevutil_p.h \ $$PWD/qtouchoutputmapping_p.h SOURCES += \ + $$PWD/qevdevutil.cpp \ $$PWD/qtouchoutputmapping.cpp |