diff options
Diffstat (limited to 'src/platformsupport')
-rw-r--r-- | src/platformsupport/eglconvenience/qeglplatformintegration.cpp | 4 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtouch/evdevtouch.pri | 6 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp (renamed from src/platformsupport/input/evdevtouch/qevdevtouch.cpp) | 75 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h (renamed from src/platformsupport/input/evdevtouch/qevdevtouch_p.h) | 9 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp | 122 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h | 76 |
6 files changed, 229 insertions, 63 deletions
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp index 200ded760c..1868ff1665 100644 --- a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp @@ -48,7 +48,7 @@ #if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) #include <QtPlatformSupport/private/qevdevmousemanager_p.h> #include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h> -#include <QtPlatformSupport/private/qevdevtouch_p.h> +#include <QtPlatformSupport/private/qevdevtouchmanager_p.h> #endif #if !defined(QT_NO_TSLIB) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) @@ -359,7 +359,7 @@ void QEGLPlatformIntegration::createInputHandlers() new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */); else #endif // QT_NO_TSLIB - new QEvdevTouchScreenHandlerThread(QString() /* spec */, this); + new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); #endif } diff --git a/src/platformsupport/input/evdevtouch/evdevtouch.pri b/src/platformsupport/input/evdevtouch/evdevtouch.pri index ffbb05d61d..c2edc13143 100644 --- a/src/platformsupport/input/evdevtouch/evdevtouch.pri +++ b/src/platformsupport/input/evdevtouch/evdevtouch.pri @@ -1,8 +1,10 @@ HEADERS += \ - $$PWD/qevdevtouch_p.h + $$PWD/qevdevtouchhandler_p.h \ + $$PWD/qevdevtouchmanager_p.h SOURCES += \ - $$PWD/qevdevtouch.cpp + $$PWD/qevdevtouchhandler.cpp \ + $$PWD/qevdevtouchmanager.cpp contains(QT_CONFIG, libudev) { LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV diff --git a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp index 5c28dfb082..885326e512 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp @@ -31,16 +31,14 @@ ** ****************************************************************************/ -#include "qevdevtouch_p.h" +#include "qevdevtouchhandler_p.h" #include <QStringList> #include <QHash> #include <QSocketNotifier> #include <QGuiApplication> #include <QLoggingCategory> #include <QtCore/private/qcore_unix_p.h> -#include <QtPlatformSupport/private/qdevicediscovery_p.h> #include <QtGui/private/qguiapplication_p.h> -#include <QtGui/private/qinputdevicemanager_p_p.h> #include <linux/input.h> #if !defined(QT_NO_MTDEV) @@ -148,12 +146,6 @@ void QEvdevTouchScreenData::registerDevice() m_device->setCapabilities(m_device->capabilities() | QTouchDevice::Pressure); QWindowSystemInterface::registerTouchDevice(m_device); - - // No monitoring of added/removed devices is done here, so for now just - // increase the number of touch devices. - QInputDeviceManager *imgr = QGuiApplicationPrivate::inputDeviceManager(); - QInputDeviceManagerPrivate::get(imgr)->setDeviceCount(QInputDeviceManager::DeviceTypeTouch, - imgr->deviceCount(QInputDeviceManager::DeviceTypeTouch) + 1); } #define LONG_BITS (sizeof(long) << 3) @@ -166,7 +158,7 @@ static inline bool testBit(long bit, const long *array) } #endif -QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification, QObject *parent) +QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const QString &spec, QObject *parent) : QObject(parent), m_notify(0), m_fd(-1), d(0) #if !defined(QT_NO_MTDEV) , m_mtdev(0) @@ -174,25 +166,12 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification, { setObjectName(QLatin1String("Evdev Touch Handler")); - if (qEnvironmentVariableIsSet("QT_QPA_EVDEV_DEBUG")) - const_cast<QLoggingCategory &>(qLcEvdevTouch()).setEnabled(QtDebugMsg, true); - - // only the first device argument is used for now - QString spec = QString::fromLocal8Bit(qgetenv("QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS")); - - if (spec.isEmpty()) - spec = specification; - - QStringList args = spec.split(QLatin1Char(':')); - - QString dev; + const QStringList args = spec.split(QLatin1Char(':')); int rotationAngle = 0; bool invertx = false; bool inverty = false; for (int i = 0; i < args.count(); ++i) { - if (args.at(i).startsWith(QLatin1String("/dev/")) && dev.isEmpty()) { - dev = args.at(i); - } else if (args.at(i).startsWith(QLatin1String("rotate"))) { + if (args.at(i).startsWith(QLatin1String("rotate"))) { QString rotateArg = args.at(i).section(QLatin1Char('='), 1, 1); bool ok; uint argValue = rotateArg.toUInt(&ok); @@ -213,32 +192,15 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification, } } - if (dev.isEmpty()) { - // try to let udev scan for already connected devices - QScopedPointer<QDeviceDiscovery> deviceDiscovery(QDeviceDiscovery::create(QDeviceDiscovery::Device_Touchpad | QDeviceDiscovery::Device_Touchscreen, this)); - if (deviceDiscovery) { - QStringList devices = deviceDiscovery->scanConnectedDevices(); - - // only the first device found is used for now - if (devices.size() > 0) - dev = devices[0]; - } - } - - if (dev.isEmpty()) { - qCDebug(qLcEvdevTouch, "evdevtouch: No touch devices found"); - return; - } - - qCDebug(qLcEvdevTouch, "evdevtouch: Using device %s", qPrintable(dev)); + qCDebug(qLcEvdevTouch, "evdevtouch: Using device %s", qPrintable(device)); - m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); + m_fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (m_fd >= 0) { m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); connect(m_notify, SIGNAL(activated(int)), this, SLOT(readData())); } else { - qErrnoWarning(errno, "evdevtouch: Cannot open input device %s", qPrintable(dev)); + qErrnoWarning(errno, "evdevtouch: Cannot open input device %s", qPrintable(device)); return; } @@ -266,32 +228,35 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification, } #endif - qCDebug(qLcEvdevTouch, "evdevtouch: Protocol type %c %s (%s)", d->m_typeB ? 'B' : 'A', - mtdevStr, d->m_singleTouch ? "single" : "multi"); + qCDebug(qLcEvdevTouch, "evdevtouch: %s: Protocol type %c %s (%s)", qPrintable(device), + d->m_typeB ? 'B' : 'A', mtdevStr, d->m_singleTouch ? "single" : "multi"); input_absinfo absInfo; memset(&absInfo, 0, sizeof(input_absinfo)); 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: min X: %d max X: %d", absInfo.minimum, absInfo.maximum); + qCDebug(qLcEvdevTouch, "evdevtouch: %s: min X: %d max X: %d", qPrintable(device), + absInfo.minimum, absInfo.maximum); d->hw_range_x_min = absInfo.minimum; d->hw_range_x_max = absInfo.maximum; has_x_range = true; } if (ioctl(m_fd, EVIOCGABS((d->m_singleTouch ? ABS_Y : ABS_MT_POSITION_Y)), &absInfo) >= 0) { - qCDebug(qLcEvdevTouch, "evdevtouch: min Y: %d max Y: %d", absInfo.minimum, absInfo.maximum); + qCDebug(qLcEvdevTouch, "evdevtouch: %s: min Y: %d max Y: %d", qPrintable(device), + absInfo.minimum, absInfo.maximum); d->hw_range_y_min = absInfo.minimum; d->hw_range_y_max = absInfo.maximum; has_y_range = true; } if (!has_x_range || !has_y_range) - qWarning("evdevtouch: Invalid ABS limits, behavior unspecified"); + qWarning("evdevtouch: %s: Invalid ABS limits, behavior unspecified", qPrintable(device)); if (ioctl(m_fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) { - qCDebug(qLcEvdevTouch, "evdevtouch: min pressure: %d max pressure: %d", absInfo.minimum, absInfo.maximum); + qCDebug(qLcEvdevTouch, "evdevtouch: %s: min pressure: %d max pressure: %d", qPrintable(device), + absInfo.minimum, absInfo.maximum); if (absInfo.maximum > absInfo.minimum) { d->hw_pressure_min = absInfo.minimum; d->hw_pressure_max = absInfo.maximum; @@ -301,7 +266,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification, char name[1024]; if (ioctl(m_fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) { d->hw_name = QString::fromLocal8Bit(name); - qCDebug(qLcEvdevTouch, "evdevtouch: device name: %s", name); + qCDebug(qLcEvdevTouch, "evdevtouch: %s: device name: %s", qPrintable(device), name); } // Fix up the coordinate ranges for am335x in case the kernel driver does not have them fixed. @@ -676,8 +641,8 @@ void QEvdevTouchScreenData::reportPoints() } -QEvdevTouchScreenHandlerThread::QEvdevTouchScreenHandlerThread(const QString &spec, QObject *parent) - : QThread(parent), m_spec(spec), m_handler(0) +QEvdevTouchScreenHandlerThread::QEvdevTouchScreenHandlerThread(const QString &device, const QString &spec, QObject *parent) + : QThread(parent), m_device(device), m_spec(spec), m_handler(0) { start(); } @@ -690,7 +655,7 @@ QEvdevTouchScreenHandlerThread::~QEvdevTouchScreenHandlerThread() void QEvdevTouchScreenHandlerThread::run() { - m_handler = new QEvdevTouchScreenHandler(m_spec); + m_handler = new QEvdevTouchScreenHandler(m_device, m_spec); exec(); delete m_handler; m_handler = 0; diff --git a/src/platformsupport/input/evdevtouch/qevdevtouch_p.h b/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h index eca1bf465c..a6d3a860f5 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouch_p.h +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h @@ -31,8 +31,8 @@ ** ****************************************************************************/ -#ifndef QEVDEVTOUCH_P_H -#define QEVDEVTOUCH_P_H +#ifndef QEVDEVTOUCHHANDLER_P_H +#define QEVDEVTOUCHHANDLER_P_H // // W A R N I N G @@ -65,7 +65,7 @@ class QEvdevTouchScreenHandler : public QObject Q_OBJECT public: - explicit QEvdevTouchScreenHandler(const QString &specification = QString(), QObject *parent = 0); + explicit QEvdevTouchScreenHandler(const QString &device, const QString &spec = QString(), QObject *parent = 0); ~QEvdevTouchScreenHandler(); private slots: @@ -83,12 +83,13 @@ private: class QEvdevTouchScreenHandlerThread : public QThread { public: - explicit QEvdevTouchScreenHandlerThread(const QString &spec, QObject *parent = 0); + explicit QEvdevTouchScreenHandlerThread(const QString &device, const QString &spec, QObject *parent = 0); ~QEvdevTouchScreenHandlerThread(); void run() Q_DECL_OVERRIDE; QEvdevTouchScreenHandler *handler() { return m_handler; } private: + QString m_device; QString m_spec; QEvdevTouchScreenHandler *m_handler; }; diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp new file mode 100644 index 0000000000..98fc83700c --- /dev/null +++ b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qevdevtouchmanager_p.h" +#include "qevdevtouchhandler_p.h" + +#include <QStringList> +#include <QGuiApplication> +#include <QLoggingCategory> +#include <QtPlatformSupport/private/qdevicediscovery_p.h> +#include <private/qguiapplication_p.h> +#include <private/qinputdevicemanager_p_p.h> + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(qLcEvdevTouch) + +QEvdevTouchManager::QEvdevTouchManager(const QString &key, const QString &specification, QObject *parent) + : QObject(parent) +{ + Q_UNUSED(key); + + if (qEnvironmentVariableIsSet("QT_QPA_EVDEV_DEBUG")) + const_cast<QLoggingCategory &>(qLcEvdevTouch()).setEnabled(QtDebugMsg, true); + + QString spec = QString::fromLocal8Bit(qgetenv("QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS")); + + 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(':')); + + foreach (const QString &device, 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) { + QStringList devices = m_deviceDiscovery->scanConnectedDevices(); + foreach (const QString &device, devices) + addDevice(device); + connect(m_deviceDiscovery, SIGNAL(deviceDetected(QString)), this, SLOT(addDevice(QString))); + connect(m_deviceDiscovery, SIGNAL(deviceRemoved(QString)), this, SLOT(removeDevice(QString))); + } + } +} + +QEvdevTouchManager::~QEvdevTouchManager() +{ + qDeleteAll(m_activeDevices); +} + +void QEvdevTouchManager::addDevice(const QString &deviceNode) +{ + qCDebug(qLcEvdevTouch) << "Adding device at" << deviceNode; + QEvdevTouchScreenHandlerThread *handler; + handler = new QEvdevTouchScreenHandlerThread(deviceNode, m_spec); + if (handler) { + m_activeDevices.insert(deviceNode, handler); + QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( + QInputDeviceManager::DeviceTypeTouch, m_activeDevices.count()); + } else { + qWarning("evdevtouch: Failed to open touch device %s", qPrintable(deviceNode)); + } +} + +void QEvdevTouchManager::removeDevice(const QString &deviceNode) +{ + if (m_activeDevices.contains(deviceNode)) { + qCDebug(qLcEvdevTouch) << "Removing device at" << deviceNode; + QEvdevTouchScreenHandlerThread *handler = m_activeDevices.value(deviceNode); + m_activeDevices.remove(deviceNode); + QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( + QInputDeviceManager::DeviceTypeTouch, m_activeDevices.count()); + delete handler; + } +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h b/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h new file mode 100644 index 0000000000..bf484fd88b --- /dev/null +++ b/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVDEVTOUCHMANAGER_P_H +#define QEVDEVTOUCHMANAGER_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 <QObject> +#include <QHash> +#include <QSocketNotifier> + +QT_BEGIN_NAMESPACE + +class QDeviceDiscovery; +class QEvdevTouchScreenHandlerThread; + +class QEvdevTouchManager : public QObject +{ + Q_OBJECT +public: + QEvdevTouchManager(const QString &key, const QString &spec, QObject *parent = 0); + ~QEvdevTouchManager(); + +private slots: + void addDevice(const QString &deviceNode); + void removeDevice(const QString &deviceNode); + +private: + QString m_spec; + QDeviceDiscovery *m_deviceDiscovery; + QHash<QString, QEvdevTouchScreenHandlerThread *> m_activeDevices; +}; + +QT_END_NAMESPACE + +#endif // QEVDEVTOUCHMANAGER_P_H |