diff options
Diffstat (limited to 'src/platformsupport/input/evdevtablet')
-rw-r--r-- | src/platformsupport/input/evdevtablet/evdevtablet.pri | 6 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtablet/qevdevtablet_p.h | 87 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp (renamed from src/platformsupport/input/evdevtablet/qevdevtablet.cpp) | 237 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtablet/qevdevtablethandler_p.h | 102 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp | 128 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h | 82 |
6 files changed, 426 insertions, 216 deletions
diff --git a/src/platformsupport/input/evdevtablet/evdevtablet.pri b/src/platformsupport/input/evdevtablet/evdevtablet.pri index 5ace0df61d..fb9489353c 100644 --- a/src/platformsupport/input/evdevtablet/evdevtablet.pri +++ b/src/platformsupport/input/evdevtablet/evdevtablet.pri @@ -1,8 +1,10 @@ HEADERS += \ - $$PWD/qevdevtablet_p.h + $$PWD/qevdevtablethandler_p.h \ + $$PWD/qevdevtabletmanager_p.h SOURCES += \ - $$PWD/qevdevtablet.cpp + $$PWD/qevdevtablethandler.cpp \ + $$PWD/qevdevtabletmanager.cpp contains(QT_CONFIG, libudev) { LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h b/src/platformsupport/input/evdevtablet/qevdevtablet_p.h deleted file mode 100644 index f546f9a88a..0000000000 --- a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef QEVDEVTABLET_P_H -#define QEVDEVTABLET_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 <QString> -#include <QThread> -#include <QtCore/private/qthread_p.h> - -QT_BEGIN_NAMESPACE - -class QEvdevTabletData; - -class QEvdevTabletHandler : public QObject -{ - Q_OBJECT - -public: - explicit QEvdevTabletHandler(const QString &spec = QString(), QObject *parent = 0); - ~QEvdevTabletHandler(); - -private slots: - void readData(); - -private: - QEvdevTabletData *d; -}; - -class QEvdevTabletHandlerThread : public QDaemonThread -{ -public: - explicit QEvdevTabletHandlerThread(const QString &spec, QObject *parent = 0); - ~QEvdevTabletHandlerThread(); - void run() Q_DECL_OVERRIDE; - QEvdevTabletHandler *handler() { return m_handler; } - -private: - QString m_spec; - QEvdevTabletHandler *m_handler; -}; - -QT_END_NAMESPACE - -#endif // QEVDEVTABLET_P_H diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp b/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp index c6f952c64d..dc03daedda 100644 --- a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp +++ b/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp @@ -1,44 +1,50 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** 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 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. +** 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. ** -** 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. +** 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 "qevdevtablet_p.h" -#include <qpa/qwindowsysteminterface.h> +#include "qevdevtablethandler_p.h" + #include <QStringList> #include <QSocketNotifier> #include <QGuiApplication> #include <QLoggingCategory> #include <QtCore/private/qcore_unix_p.h> -#include <QtPlatformSupport/private/qdevicediscovery_p.h> +#include <qpa/qwindowsysteminterface.h> #include <linux/input.h> QT_BEGIN_NAMESPACE @@ -49,16 +55,11 @@ class QEvdevTabletData { public: QEvdevTabletData(QEvdevTabletHandler *q_ptr); - bool queryLimits(); - void testGrab(); + void processInputEvent(input_event *ev); - void reportProximityEnter(); - void reportProximityLeave(); void report(); QEvdevTabletHandler *q; - QSocketNotifier *notifier; - int fd; int lastEventType; QString devName; struct { @@ -73,57 +74,13 @@ public: }; QEvdevTabletData::QEvdevTabletData(QEvdevTabletHandler *q_ptr) - : q(q_ptr), notifier(0), fd(-1), lastEventType(0) + : q(q_ptr), lastEventType(0) { memset(&minValues, 0, sizeof(minValues)); memset(&maxValues, 0, sizeof(maxValues)); memset(&state, 0, sizeof(state)); } -bool QEvdevTabletData::queryLimits() -{ - bool ok = true; - input_absinfo absInfo; - memset(&absInfo, 0, sizeof(input_absinfo)); - ok &= ioctl(fd, EVIOCGABS(ABS_X), &absInfo) >= 0; - if (ok) { - minValues.x = absInfo.minimum; - maxValues.x = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: min X: %d max X: %d", minValues.x, maxValues.x); - } - ok &= ioctl(fd, EVIOCGABS(ABS_Y), &absInfo) >= 0; - if (ok) { - minValues.y = absInfo.minimum; - maxValues.y = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: min Y: %d max Y: %d", minValues.y, maxValues.y); - } - if (ioctl(fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) { - minValues.p = absInfo.minimum; - maxValues.p = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: min pressure: %d max pressure: %d", minValues.p, maxValues.p); - } - if (ioctl(fd, EVIOCGABS(ABS_DISTANCE), &absInfo) >= 0) { - minValues.d = absInfo.minimum; - maxValues.d = absInfo.maximum; - qCDebug(qLcEvdevTablet, "evdevtablet: min distance: %d max distance: %d", minValues.d, maxValues.d); - } - char name[128]; - if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) { - devName = QString::fromLocal8Bit(name); - qCDebug(qLcEvdevTablet, "evdevtablet: device name: %s", name); - } - return ok; -} - -void QEvdevTabletData::testGrab() -{ - bool grabSuccess = !ioctl(fd, EVIOCGRAB, (void *) 1); - if (grabSuccess) - ioctl(fd, EVIOCGRAB, (void *) 0); - else - qWarning("evdevtablet: ERROR: The device is grabbed by another process. No events will be read."); -} - void QEvdevTabletData::processInputEvent(input_event *ev) { if (ev->type == EV_ABS) { @@ -167,20 +124,10 @@ void QEvdevTabletData::processInputEvent(input_event *ev) lastEventType = ev->type; } -void QEvdevTabletData::reportProximityEnter() -{ - QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus, state.tool, 1); -} - -void QEvdevTabletData::reportProximityLeave() -{ - QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus, state.tool, 1); -} - void QEvdevTabletData::report() { if (!state.lastReportTool && state.tool) - reportProximityEnter(); + QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId()); qreal nx = (state.x - minValues.x) / qreal(maxValues.x - minValues.x); qreal ny = (state.y - minValues.y) / qreal(maxValues.y - minValues.y); @@ -194,16 +141,17 @@ void QEvdevTabletData::report() pointer = state.lastReportTool; } - qreal pressure = (state.p - minValues.p) / qreal(maxValues.p - minValues.p); + int pressureRange = maxValues.p - minValues.p; + qreal pressure = pressureRange ? (state.p - minValues.p) / qreal(pressureRange) : qreal(1); if (state.down || state.lastReportDown) { QWindowSystemInterface::handleTabletEvent(0, state.down, QPointF(), globalPos, QTabletEvent::Stylus, pointer, - pressure, 0, 0, 0, 0, 0, 1, qGuiApp->keyboardModifiers()); + pressure, 0, 0, 0, 0, 0, q->deviceId(), qGuiApp->keyboardModifiers()); } if (state.lastReportTool && !state.tool) - reportProximityLeave(); + QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId()); state.lastReportDown = state.down; state.lastReportTool = state.tool; @@ -211,69 +159,104 @@ void QEvdevTabletData::report() } -QEvdevTabletHandler::QEvdevTabletHandler(const QString &spec, QObject *parent) - : QObject(parent), d(0) +QEvdevTabletHandler::QEvdevTabletHandler(const QString &device, const QString &spec, QObject *parent) + : QObject(parent), m_fd(-1), m_device(device), m_notifier(0), d(0) { + Q_UNUSED(spec) + setObjectName(QLatin1String("Evdev Tablet Handler")); - d = new QEvdevTabletData(this); - QString dev; - QStringList args = spec.split(QLatin1Char(':')); - for (int i = 0; i < args.count(); ++i) { - if (args.at(i).startsWith(QLatin1String("/dev/"))) { - dev = args.at(i); - break; - } - } - if (dev.isEmpty()) { - QScopedPointer<QDeviceDiscovery> deviceDiscovery( - QDeviceDiscovery::create(QDeviceDiscovery::Device_Tablet, this)); - if (deviceDiscovery) { - QStringList devices = deviceDiscovery->scanConnectedDevices(); - if (!devices.isEmpty()) - dev = devices.at(0); - } - } - if (!dev.isEmpty()) { - qCDebug(qLcEvdevTablet, "evdevtablet: using %s", qPrintable(dev)); - d->fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); - if (d->fd >= 0) { - d->testGrab(); - if (d->queryLimits()) { - d->notifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, this); - connect(d->notifier, SIGNAL(activated(int)), this, SLOT(readData())); - } - } else { - qErrnoWarning(errno, "evdevtablet: Cannot open input device"); - } + + qCDebug(qLcEvdevTablet, "evdevtablet: using %s", qPrintable(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)); + return; } + + bool grabSuccess = !ioctl(m_fd, EVIOCGRAB, (void *) 1); + 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)); + + d = new QEvdevTabletData(this); + if (!queryLimits()) + qWarning("evdevtablet: %s: Unset or invalid ABS limits. Behavior will be unspecified.", qPrintable(device)); + + m_notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(m_notifier, &QSocketNotifier::activated, this, &QEvdevTabletHandler::readData); } QEvdevTabletHandler::~QEvdevTabletHandler() { - delete d->notifier; - if (d->fd >= 0) - QT_CLOSE(d->fd); + if (m_fd >= 0) + QT_CLOSE(m_fd); delete d; } +qint64 QEvdevTabletHandler::deviceId() const +{ + return m_fd; +} + +bool QEvdevTabletHandler::queryLimits() +{ + bool ok = true; + input_absinfo absInfo; + memset(&absInfo, 0, sizeof(input_absinfo)); + ok &= ioctl(m_fd, EVIOCGABS(ABS_X), &absInfo) >= 0; + 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), + 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), + 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), + 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), + 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); + } + return ok; +} + void QEvdevTabletHandler::readData() { static input_event buffer[32]; int n = 0; for (; ;) { - int result = QT_READ(d->fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n); + int result = QT_READ(m_fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n); if (!result) { - qWarning("evdevtablet: Got EOF from input device"); + qWarning("evdevtablet: %s: Got EOF from input device", qPrintable(m_device)); return; } else if (result < 0) { if (errno != EINTR && errno != EAGAIN) { - qErrnoWarning(errno, "evdevtablet: Could not read from input device"); + qErrnoWarning(errno, "evdevtablet: %s: Could not read from input device", qPrintable(m_device)); if (errno == ENODEV) { // device got disconnected -> stop reading - delete d->notifier; - d->notifier = 0; - QT_CLOSE(d->fd); - d->fd = -1; + delete m_notifier; + m_notifier = 0; + QT_CLOSE(m_fd); + m_fd = -1; } return; } @@ -291,8 +274,8 @@ void QEvdevTabletHandler::readData() } -QEvdevTabletHandlerThread::QEvdevTabletHandlerThread(const QString &spec, QObject *parent) - : QDaemonThread(parent), m_spec(spec), m_handler(0) +QEvdevTabletHandlerThread::QEvdevTabletHandlerThread(const QString &device, const QString &spec, QObject *parent) + : QDaemonThread(parent), m_device(device), m_spec(spec), m_handler(0) { start(); } @@ -305,7 +288,7 @@ QEvdevTabletHandlerThread::~QEvdevTabletHandlerThread() void QEvdevTabletHandlerThread::run() { - m_handler = new QEvdevTabletHandler(m_spec); + m_handler = new QEvdevTabletHandler(m_device, m_spec); exec(); delete m_handler; m_handler = 0; diff --git a/src/platformsupport/input/evdevtablet/qevdevtablethandler_p.h b/src/platformsupport/input/evdevtablet/qevdevtablethandler_p.h new file mode 100644 index 0000000000..20dfda89f7 --- /dev/null +++ b/src/platformsupport/input/evdevtablet/qevdevtablethandler_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** 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 QEVDEVTABLETHANDLER_P_H +#define QEVDEVTABLETHANDLER_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 <QString> +#include <QThread> +#include <QtCore/private/qthread_p.h> + +QT_BEGIN_NAMESPACE + +class QSocketNotifier; +class QEvdevTabletData; + +class QEvdevTabletHandler : public QObject +{ + Q_OBJECT + +public: + explicit QEvdevTabletHandler(const QString &device, const QString &spec = QString(), QObject *parent = 0); + ~QEvdevTabletHandler(); + + qint64 deviceId() const; + +private slots: + void readData(); + +private: + bool queryLimits(); + + int m_fd; + QString m_device; + QSocketNotifier *m_notifier; + QEvdevTabletData *d; +}; + +class QEvdevTabletHandlerThread : public QDaemonThread +{ +public: + explicit QEvdevTabletHandlerThread(const QString &device, const QString &spec, QObject *parent = 0); + ~QEvdevTabletHandlerThread(); + void run() Q_DECL_OVERRIDE; + QEvdevTabletHandler *handler() { return m_handler; } + +private: + QString m_device; + QString m_spec; + QEvdevTabletHandler *m_handler; +}; + +QT_END_NAMESPACE + +#endif // QEVDEVTABLETHANDLER_P_H diff --git a/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp b/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp new file mode 100644 index 0000000000..00a8c7a65d --- /dev/null +++ b/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** 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 "qevdevtabletmanager_p.h" +#include "qevdevtablethandler_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(qLcEvdevTablet) + +QEvdevTabletManager::QEvdevTabletManager(const QString &key, const QString &specification, QObject *parent) + : QObject(parent) +{ + Q_UNUSED(key); + + if (qEnvironmentVariableIsSet("QT_QPA_EVDEV_DEBUG")) + const_cast<QLoggingCategory &>(qLcEvdevTablet()).setEnabled(QtDebugMsg, true); + + QString spec = QString::fromLocal8Bit(qgetenv("QT_QPA_EVDEV_TABLET_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(qLcEvdevTablet) << "evdevtablet: Using device discovery"; + m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Tablet, 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))); + } + } +} + +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); + if (handler) { + m_activeDevices.insert(deviceNode, handler); + QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount( + QInputDeviceManager::DeviceTypeTablet, m_activeDevices.count()); + } else { + qWarning("evdevtablet: Failed to open tablet device %s", qPrintable(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; + } +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h b/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h new file mode 100644 index 0000000000..d166c06cf3 --- /dev/null +++ b/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** 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 QEVDEVTABLETMANAGER_P_H +#define QEVDEVTABLETMANAGER_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 QEvdevTabletHandlerThread; + +class QEvdevTabletManager : public QObject +{ + Q_OBJECT +public: + QEvdevTabletManager(const QString &key, const QString &spec, QObject *parent = 0); + ~QEvdevTabletManager(); + +private slots: + void addDevice(const QString &deviceNode); + void removeDevice(const QString &deviceNode); + +private: + QString m_spec; + QDeviceDiscovery *m_deviceDiscovery; + QHash<QString, QEvdevTabletHandlerThread *> m_activeDevices; +}; + +QT_END_NAMESPACE + +#endif // QEVDEVTABLETMANAGER_P_H |