From 684a1559f0de4354cd9427e4c9a86e4a6a4e238a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sun, 5 Feb 2012 13:32:40 +0200 Subject: Reorganize evdev plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit linuxinput becomes evdevmouse. The experimental touch code is removed, now the plugin's purpose is solely to generate mouse events from absolute and relative pointer events. The plugin key is EvdevMouse. touchscreen becomes evdevtouch. The plugin key is EvdevTouch. In case keyboard support appears some day, it will fit nicely in the system by the name of evdevkeyboard or similar. Some little udev code is moved to platformsupport so it can be shared between the plugins. This may be extended later if more sophisticated udev support is needed. N.B. the intention is to keep this as simple as possible. We are shipping these plug-ins as reference examples, not as full-featured drivers. evdev and udev support has configure time tests from now on. This means the "drivers" (generic plugins) will get built automatically when the support is available. Change-Id: Iaf6260b5c2edfb9f25d070d2764466725adc6b4e Reviewed-by: Oswald Buddenhagen Reviewed-by: Samuel Rødal --- config.tests/unix/evdev/evdev.cpp | 59 +++ config.tests/unix/evdev/evdev.pro | 2 + config.tests/unix/libudev/libudev.cpp | 49 +++ config.tests/unix/libudev/libudev.pro | 3 + configure | 42 +++ src/platformsupport/platformsupport.pro | 1 + src/platformsupport/udev/qudevhelper.cpp | 73 ++++ src/platformsupport/udev/qudevhelper_p.h | 59 +++ src/platformsupport/udev/udev.pri | 5 + src/plugins/generic/evdevmouse/README | 11 + src/plugins/generic/evdevmouse/evdevmouse.pro | 13 + src/plugins/generic/evdevmouse/main.cpp | 77 ++++ src/plugins/generic/evdevmouse/qevdevmouse.cpp | 214 +++++++++++ src/plugins/generic/evdevmouse/qevdevmouse.h | 84 +++++ .../generic/evdevtouch/70-qtouchscreen.rules | 1 + src/plugins/generic/evdevtouch/README | 36 ++ src/plugins/generic/evdevtouch/evdevtouch.pro | 14 + src/plugins/generic/evdevtouch/main.cpp | 76 ++++ src/plugins/generic/evdevtouch/qevdevtouch.cpp | 419 +++++++++++++++++++++ src/plugins/generic/evdevtouch/qevdevtouch.h | 94 +++++ src/plugins/generic/generic.pro | 6 + src/plugins/generic/linuxinput/linuxinput.pro | 14 - src/plugins/generic/linuxinput/main.cpp | 77 ---- src/plugins/generic/linuxinput/qlinuxinput.cpp | 365 ------------------ src/plugins/generic/linuxinput/qlinuxinput.h | 86 ----- .../generic/touchscreen/70-qtouchscreen.rules | 1 - src/plugins/generic/touchscreen/README | 45 --- src/plugins/generic/touchscreen/main.cpp | 80 ---- .../generic/touchscreen/qtoucheventsenderqpa.cpp | 116 ------ .../generic/touchscreen/qtoucheventsenderqpa.h | 77 ---- src/plugins/generic/touchscreen/qtouchscreen.cpp | 396 ------------------- src/plugins/generic/touchscreen/qtouchscreen.h | 104 ----- src/plugins/generic/touchscreen/touchscreen.pro | 18 - 33 files changed, 1338 insertions(+), 1379 deletions(-) create mode 100644 config.tests/unix/evdev/evdev.cpp create mode 100644 config.tests/unix/evdev/evdev.pro create mode 100644 config.tests/unix/libudev/libudev.cpp create mode 100644 config.tests/unix/libudev/libudev.pro create mode 100644 src/platformsupport/udev/qudevhelper.cpp create mode 100644 src/platformsupport/udev/qudevhelper_p.h create mode 100644 src/platformsupport/udev/udev.pri create mode 100644 src/plugins/generic/evdevmouse/README create mode 100644 src/plugins/generic/evdevmouse/evdevmouse.pro create mode 100644 src/plugins/generic/evdevmouse/main.cpp create mode 100644 src/plugins/generic/evdevmouse/qevdevmouse.cpp create mode 100644 src/plugins/generic/evdevmouse/qevdevmouse.h create mode 100644 src/plugins/generic/evdevtouch/70-qtouchscreen.rules create mode 100644 src/plugins/generic/evdevtouch/README create mode 100644 src/plugins/generic/evdevtouch/evdevtouch.pro create mode 100644 src/plugins/generic/evdevtouch/main.cpp create mode 100644 src/plugins/generic/evdevtouch/qevdevtouch.cpp create mode 100644 src/plugins/generic/evdevtouch/qevdevtouch.h delete mode 100644 src/plugins/generic/linuxinput/linuxinput.pro delete mode 100644 src/plugins/generic/linuxinput/main.cpp delete mode 100644 src/plugins/generic/linuxinput/qlinuxinput.cpp delete mode 100644 src/plugins/generic/linuxinput/qlinuxinput.h delete mode 100644 src/plugins/generic/touchscreen/70-qtouchscreen.rules delete mode 100644 src/plugins/generic/touchscreen/README delete mode 100644 src/plugins/generic/touchscreen/main.cpp delete mode 100644 src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp delete mode 100644 src/plugins/generic/touchscreen/qtoucheventsenderqpa.h delete mode 100644 src/plugins/generic/touchscreen/qtouchscreen.cpp delete mode 100644 src/plugins/generic/touchscreen/qtouchscreen.h delete mode 100644 src/plugins/generic/touchscreen/touchscreen.pro diff --git a/config.tests/unix/evdev/evdev.cpp b/config.tests/unix/evdev/evdev.cpp new file mode 100644 index 0000000000..3dddd60038 --- /dev/null +++ b/config.tests/unix/evdev/evdev.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +enum { + e1 = ABS_MT_POSITION_X, + e2 = ABS_MT_TRACKING_ID, + e3 = ABS_PRESSURE, + e4 = ABS_X, + e5 = REL_X, + e6 = SYN_REPORT, + e7 = SYN_MT_REPORT +}; + +int main() +{ + ::input_event buf[32]; + (void) buf; + return 0; +} diff --git a/config.tests/unix/evdev/evdev.pro b/config.tests/unix/evdev/evdev.pro new file mode 100644 index 0000000000..42db391216 --- /dev/null +++ b/config.tests/unix/evdev/evdev.pro @@ -0,0 +1,2 @@ +SOURCES = evdev.cpp +CONFIG -= qt diff --git a/config.tests/unix/libudev/libudev.cpp b/config.tests/unix/libudev/libudev.cpp new file mode 100644 index 0000000000..1a08a715d8 --- /dev/null +++ b/config.tests/unix/libudev/libudev.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +int main() +{ + udev *u = udev_new(); + udev_unref(u); + return 0; +} diff --git a/config.tests/unix/libudev/libudev.pro b/config.tests/unix/libudev/libudev.pro new file mode 100644 index 0000000000..7f571b5a6d --- /dev/null +++ b/config.tests/unix/libudev/libudev.pro @@ -0,0 +1,3 @@ +SOURCES = libudev.cpp +CONFIG -= qt +LIBS += -ludev diff --git a/configure b/configure index 5e78360fa6..a3b94e1eee 100755 --- a/configure +++ b/configure @@ -727,6 +727,8 @@ CFG_XKB=auto CFG_XCB=auto CFG_XCB_LIMITED=yes CFG_WAYLAND=auto +CFG_LIBUDEV=auto +CFG_EVDEV=auto CFG_NIS=auto CFG_CUPS=auto CFG_ICONV=auto @@ -1843,6 +1845,20 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + libudev) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_LIBUDEV="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; + evdev) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_EVDEV="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; cups) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_CUPS="$VAL" @@ -5651,6 +5667,32 @@ if [ "$PLATFORM_QPA" = "yes" ]; then fi fi + if [ "$CFG_LIBUDEV" != "no" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/libudev "libudev" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_LIBUDEV=yes + QT_CONFIG="$QT_CONFIG libudev" + elif [ "$CFG_LIBUDEV" = "yes" ]; then + echo "The libudev functionality test failed!" + exit 1 + else + CFG_LIBUDEV=no + QMakeVar add DEFINES QT_NO_LIBUDEV + fi + fi + + if [ "$CFG_EVDEV" != "no" ]; then + if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/evdev "evdev" $L_FLAGS $I_FLAGS $l_FLAGS; then + CFG_EVDEV=yes + QT_CONFIG="$QT_CONFIG evdev" + elif [ "$CFG_EVDEV" = "yes" ]; then + echo "The evdev functionality test failed!" + exit 1 + else + CFG_EVDEV=no + QMakeVar add DEFINES QT_NO_EVDEV + fi + fi + # Check we actually have X11 :-) if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/xlib "XLib" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then QT_CONFIG="$QT_CONFIG xlib" diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 36323d9766..64decd0392 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -33,3 +33,4 @@ include(fontdatabases/fontdatabases.pri) include(glxconvenience/glxconvenience.pri) #include(printersupport/printersupport.pri) include(inputcontext/inputcontext.pri) +include(udev/udev.pri) diff --git a/src/platformsupport/udev/qudevhelper.cpp b/src/platformsupport/udev/qudevhelper.cpp new file mode 100644 index 0000000000..b63ef64ed8 --- /dev/null +++ b/src/platformsupport/udev/qudevhelper.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qudevhelper_p.h" +#include + +QT_BEGIN_NAMESPACE + +void q_udev_devicePath(int type, QString *path) +{ + *path = QString(); + udev *u = udev_new(); + udev_enumerate *ue = udev_enumerate_new(u); + udev_enumerate_add_match_subsystem(ue, "input"); + if (type & UDev_Mouse) + udev_enumerate_add_match_property(ue, "ID_INPUT_MOUSE", "1"); + if (type & UDev_Touchpad) + udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHPAD", "1"); + if (type & UDev_Touchscreen) + udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHSCREEN", "1"); + udev_enumerate_scan_devices(ue); + udev_list_entry *entry; + udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(ue)) { + const char *syspath = udev_list_entry_get_name(entry); + udev_device *udevice = udev_device_new_from_syspath(u, syspath); + QString candidate = QString::fromLocal8Bit(udev_device_get_devnode(udevice)); + udev_device_unref(udevice); + if (path->isEmpty() && candidate.startsWith(QLatin1String("/dev/input/event"))) + *path = candidate; + } + udev_enumerate_unref(ue); + udev_unref(u); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/udev/qudevhelper_p.h b/src/platformsupport/udev/qudevhelper_p.h new file mode 100644 index 0000000000..e6046ca085 --- /dev/null +++ b/src/platformsupport/udev/qudevhelper_p.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QUDEVHELPER_P_H +#define QUDEVHELPER_P_H + +#include + +QT_BEGIN_NAMESPACE + +enum QUDeviceType { + UDev_Mouse = 0x01, + UDev_Touchpad = 0x02, + UDev_Touchscreen = 0x04 +}; + +void q_udev_devicePath(int type, QString *path); + +QT_END_NAMESPACE + +#endif // QUDEVHELPER_P_H diff --git a/src/platformsupport/udev/udev.pri b/src/platformsupport/udev/udev.pri new file mode 100644 index 0000000000..ac3f7df40a --- /dev/null +++ b/src/platformsupport/udev/udev.pri @@ -0,0 +1,5 @@ +contains(QT_CONFIG, libudev) { + HEADERS += $$PWD/qudevhelper_p.h + SOURCES += $$PWD/qudevhelper.cpp + LIBS += -ludev +} diff --git a/src/plugins/generic/evdevmouse/README b/src/plugins/generic/evdevmouse/README new file mode 100644 index 0000000000..b89c0a7066 --- /dev/null +++ b/src/plugins/generic/evdevmouse/README @@ -0,0 +1,11 @@ +Generic plug-in for absolute & relative evdev pointer events. + +To use it, launch apps with -plugin EvdevMouse + +The plug-in will try to pick a mouse or touchpad device from udev. +If automatic detection does not work, use -plugin +EvdevMouse:/dev/input/eventN to explicitly set the device node. + +The initial cursor position is assumed to be (0, 0). Relative events +will generate Qt mouse events with screen positions relative to this +initial position. diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro new file mode 100644 index 0000000000..f25199161b --- /dev/null +++ b/src/plugins/generic/evdevmouse/evdevmouse.pro @@ -0,0 +1,13 @@ +TARGET = qevdevmouseplugin +load(qt_plugin) + +DESTDIR = $$QT.gui.plugins/generic +target.path = $$[QT_INSTALL_PLUGINS]/generic +INSTALLS += target + +HEADERS = qevdevmouse.h + +QT += core-private platformsupport-private + +SOURCES = main.cpp \ + qevdevmouse.cpp diff --git a/src/plugins/generic/evdevmouse/main.cpp b/src/plugins/generic/evdevmouse/main.cpp new file mode 100644 index 0000000000..34ca62f960 --- /dev/null +++ b/src/plugins/generic/evdevmouse/main.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "qevdevmouse.h" + +QT_BEGIN_NAMESPACE + +class QEvdevMousePlugin : public QGenericPlugin +{ +public: + QEvdevMousePlugin(); + + QStringList keys() const; + QObject* create(const QString &key, const QString &specification); +}; + +QEvdevMousePlugin::QEvdevMousePlugin() + : QGenericPlugin() +{ +} + +QStringList QEvdevMousePlugin::keys() const +{ + return (QStringList() + << QLatin1String("EvdevMouse")); +} + +QObject* QEvdevMousePlugin::create(const QString &key, + const QString &specification) +{ + if (!key.compare(QLatin1String("EvdevMouse"), Qt::CaseInsensitive)) + return new QEvdevMouseHandler(key, specification); + return 0; +} + +Q_EXPORT_PLUGIN2(qevdevmouseplugin, QEvdevMousePlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevmouse/qevdevmouse.cpp b/src/plugins/generic/evdevmouse/qevdevmouse.cpp new file mode 100644 index 0000000000..0b72123c02 --- /dev/null +++ b/src/plugins/generic/evdevmouse/qevdevmouse.cpp @@ -0,0 +1,214 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qevdevmouse.h" + +#include +#include +#include +#include + +#include +#include // overrides QT_OPEN +#include + +#include + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +QEvdevMouseHandler::QEvdevMouseHandler(const QString &key, + const QString &specification) + : m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0), + m_xoffset(0), m_yoffset(0), m_buttons(0) +{ + Q_UNUSED(key); + setObjectName(QLatin1String("Evdev Mouse Handler")); + + QString dev; + q_udev_devicePath(UDev_Mouse | UDev_Touchpad, &dev); + if (dev.isEmpty()) + dev = QLatin1String("/dev/input/event0"); + + m_compression = true; + m_smooth = false; + int jitterLimit = 0; + + QStringList args = specification.split(QLatin1Char(':')); + foreach (const QString &arg, args) { + if (arg == "nocompress") + m_compression = false; + else if (arg.startsWith("dejitter=")) + jitterLimit = arg.mid(9).toInt(); + else if (arg.startsWith("xoffset=")) + m_xoffset = arg.mid(8).toInt(); + else if (arg.startsWith("yoffset=")) + m_yoffset = arg.mid(8).toInt(); + else if (arg.startsWith(QLatin1String("/dev/"))) + dev = arg; + } + m_jitterLimitSquared = jitterLimit*jitterLimit; + + qDebug("evdevmouse: Using device %s", qPrintable(dev)); + m_fd = QT_OPEN(dev.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(readMouseData())); + } else { + qWarning("Cannot open mouse input device '%s': %s", qPrintable(dev), strerror(errno)); + return; + } +} + +QEvdevMouseHandler::~QEvdevMouseHandler() +{ + if (m_fd >= 0) + QT_CLOSE(m_fd); +} + +void QEvdevMouseHandler::sendMouseEvent() +{ + QPoint pos(m_x + m_xoffset, m_y + m_yoffset); + //qDebug("mouse event %d %d %d", pos.x(), pos.y(), int(m_buttons)); + QWindowSystemInterface::handleMouseEvent(0, pos, pos, m_buttons); + m_prevx = m_x; + m_prevy = m_y; +} + +void QEvdevMouseHandler::readMouseData() +{ + struct ::input_event buffer[32]; + int n = 0; + bool posChanged = false; + bool pendingMouseEvent = false; + int eventCompressCount = 0; + forever { + n = QT_READ(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); + + if (n == 0) { + qWarning("Got EOF from the input device."); + return; + } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { + qWarning("Could not read from input device: %s", strerror(errno)); + return; + } else if (n % sizeof(buffer[0]) == 0) { + break; + } + } + + n /= sizeof(buffer[0]); + + for (int i = 0; i < n; ++i) { + struct ::input_event *data = &buffer[i]; + //qDebug() << ">>" << hex << data->type << data->code << dec << data->value; + if (data->type == EV_ABS) { + if (data->code == ABS_X && m_x != data->value) { + m_x = data->value; + posChanged = true; + } else if (data->code == ABS_Y && m_y != data->value) { + m_y = data->value; + posChanged = true; + } + } else if (data->type == EV_REL) { + if (data->code == REL_X) { + m_x += data->value; + posChanged = true; + } else if (data->code == REL_Y) { + m_y += data->value; + posChanged = true; + } else if (data->code == ABS_WHEEL) { // vertical scroll + // data->value: 1 == up, -1 == down + int delta = 120 * data->value; + QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), + QPoint(m_x, m_y), + delta, Qt::Vertical); + } else if (data->code == ABS_THROTTLE) { // horizontal scroll + // data->value: 1 == right, -1 == left + int delta = 120 * -data->value; + QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), + QPoint(m_x, m_y), + delta, Qt::Horizontal); + } + } else if (data->type == EV_KEY && data->code == BTN_TOUCH) { + m_buttons = data->value ? Qt::LeftButton : Qt::NoButton; + + sendMouseEvent(); + pendingMouseEvent = false; + } else if (data->type == EV_KEY && data->code >= BTN_LEFT && data->code <= BTN_MIDDLE) { + Qt::MouseButton button = Qt::NoButton; + switch (data->code) { + case BTN_LEFT: button = Qt::LeftButton; break; + case BTN_MIDDLE: button = Qt::MidButton; break; + case BTN_RIGHT: button = Qt::RightButton; break; + } + if (data->value) + m_buttons |= button; + else + m_buttons &= ~button; + sendMouseEvent(); + pendingMouseEvent = false; + } else if (data->type == EV_SYN && data->code == SYN_REPORT) { + if (posChanged) { + posChanged = false; + if (m_compression) { + pendingMouseEvent = true; + eventCompressCount++; + } else { + sendMouseEvent(); + } + } + } else if (data->type == EV_MSC && data->code == MSC_SCAN) { + // kernel encountered an unmapped key - just ignore it + continue; + } + } + if (m_compression && pendingMouseEvent) { + int distanceSquared = (m_x - m_prevx)*(m_x - m_prevx) + (m_y - m_prevy)*(m_y - m_prevy); + if (distanceSquared > m_jitterLimitSquared) + sendMouseEvent(); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevmouse/qevdevmouse.h b/src/plugins/generic/evdevmouse/qevdevmouse.h new file mode 100644 index 0000000000..9542d133f2 --- /dev/null +++ b/src/plugins/generic/evdevmouse/qevdevmouse.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVDEVMOUSE_H +#define QEVDEVMOUSE_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QSocketNotifier; + +class QEvdevMouseHandler : public QObject +{ + Q_OBJECT +public: + QEvdevMouseHandler(const QString &key, const QString &specification); + ~QEvdevMouseHandler(); + +private slots: + void readMouseData(); + +private: + void sendMouseEvent(); + void pathFromUdev(QString *path); + + QSocketNotifier *m_notify; + int m_fd; + int m_x, m_y; + int m_prevx, m_prevy; + int m_xoffset, m_yoffset; + int m_smoothx, m_smoothy; + Qt::MouseButtons m_buttons; + bool m_compression; + bool m_smooth; + int m_jitterLimitSquared; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QEVDEVMOUSE_H diff --git a/src/plugins/generic/evdevtouch/70-qtouchscreen.rules b/src/plugins/generic/evdevtouch/70-qtouchscreen.rules new file mode 100644 index 0000000000..2afde8f8a3 --- /dev/null +++ b/src/plugins/generic/evdevtouch/70-qtouchscreen.rules @@ -0,0 +1 @@ +KERNEL=="event*", ENV{ID_INPUT_TOUCHPAD}=="1", MODE="0644" diff --git a/src/plugins/generic/evdevtouch/README b/src/plugins/generic/evdevtouch/README new file mode 100644 index 0000000000..4764ef8f70 --- /dev/null +++ b/src/plugins/generic/evdevtouch/README @@ -0,0 +1,36 @@ +Generic plug-in for evdev touch events. (protocol type A) + +Tested with the following drivers: bcm5974, hid_magicmouse. + +To use it, pass -plugin EvdevTouch on the command line. + +If automatic detection does not work, use -plugin +EvdevTouch:/dev/input/eventN to explicitly set the device file +name. + +By default the surface of the touch device is mapped to the entire +screen. If this is not desired, pass force_window in the plugin +specification as shown in the example above. This will cause mapping +the touch surface to the active window instead. For example: +./fingerpaint -plugin EvdevTouch:force_window + +Only touch events are generated, mouse events are not. Be aware however +that ignored touch events will generate a mouse event from the first +touch point by default. See AA_SynthesizeMouseForUnhandledTouchEvents. + +If no evdev events are read, disable the synaptics driver from X or +temporarily disable the device by running +xinput set-prop 0. +Use xinput list and xinput list-props to figure out the values. + +When not running on a windowing system (eglfs, kms, etc.) and having a +touchpad, the evdevmouse and touch plugins can be combined to get both +mouse and touch events: +./app -platform kms -plugin EvdevTouch -plugin EvdevMouse + +If the input device cannot be accessed, set up a udev rule. +For example: + sudo cp 70-qtouchscreen.rules /etc/udev/rules.d + sudo udevadm trigger --subsystem-match=input +The udev rule matches any touchpad or touchscreen device. If there are +multiple ones, specify the device manually as described above. diff --git a/src/plugins/generic/evdevtouch/evdevtouch.pro b/src/plugins/generic/evdevtouch/evdevtouch.pro new file mode 100644 index 0000000000..78fe551aa2 --- /dev/null +++ b/src/plugins/generic/evdevtouch/evdevtouch.pro @@ -0,0 +1,14 @@ +TARGET = qevdevtouchplugin +load(qt_plugin) + +DESTDIR = $$QT.gui.plugins/generic +target.path = $$[QT_INSTALL_PLUGINS]/generic +INSTALLS += target + +HEADERS = \ + qevdevtouch.h + +SOURCES = main.cpp \ + qevdevtouch.cpp + +QT += core-private platformsupport-private diff --git a/src/plugins/generic/evdevtouch/main.cpp b/src/plugins/generic/evdevtouch/main.cpp new file mode 100644 index 0000000000..526e336fd8 --- /dev/null +++ b/src/plugins/generic/evdevtouch/main.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "qevdevtouch.h" + +QT_BEGIN_NAMESPACE + +class QTouchScreenPlugin : public QGenericPlugin +{ +public: + QTouchScreenPlugin(); + + QStringList keys() const; + QObject* create(const QString &key, const QString &specification); +}; + +QTouchScreenPlugin::QTouchScreenPlugin() +{ +} + +QStringList QTouchScreenPlugin::keys() const +{ + return QStringList() << "EvdevTouch"; +} + +QObject* QTouchScreenPlugin::create(const QString &key, + const QString &spec) +{ + if (!key.compare(QLatin1String("EvdevTouch"), Qt::CaseInsensitive)) + return new QTouchScreenHandlerThread(spec); + + return 0; +} + +Q_EXPORT_PLUGIN2(qevdevtouchplugin, QTouchScreenPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevtouch/qevdevtouch.cpp b/src/plugins/generic/evdevtouch/qevdevtouch.cpp new file mode 100644 index 0000000000..d508c4a12a --- /dev/null +++ b/src/plugins/generic/evdevtouch/qevdevtouch.cpp @@ -0,0 +1,419 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qevdevtouch.h" +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QTouchScreenData +{ +public: + QTouchScreenData(QTouchScreenHandler *q_ptr, const QStringList &args); + + void processInputEvent(input_event *data); + void assignIds(); + + QTouchScreenHandler *q; + int m_lastEventType; + QList m_touchPoints; + + struct Contact { + int trackingId; + int x; + int y; + int maj; + int pressure; + Qt::TouchPointState state; + QTouchEvent::TouchPoint::InfoFlags flags; + Contact() : trackingId(-1), + x(0), y(0), maj(1), pressure(0), + state(Qt::TouchPointPressed), flags(0) { } + }; + QHash m_contacts, m_lastContacts; + Contact m_currentData; + + int findClosestContact(const QHash &contacts, int x, int y, int *dist); + void reportPoints(); + void registerDevice(); + + int hw_range_x_min; + int hw_range_x_max; + int hw_range_y_min; + int hw_range_y_max; + int hw_pressure_min; + int hw_pressure_max; + QString hw_name; + bool m_forceToActiveWindow; + QTouchDevice *m_device; +}; + +QTouchScreenData::QTouchScreenData(QTouchScreenHandler *q_ptr, const QStringList &args) + : q(q_ptr), + m_lastEventType(-1), + hw_range_x_min(0), hw_range_x_max(0), + hw_range_y_min(0), hw_range_y_max(0), + hw_pressure_min(0), hw_pressure_max(0) +{ + m_forceToActiveWindow = args.contains(QLatin1String("force_window")); +} + +void QTouchScreenData::registerDevice() +{ + m_device = new QTouchDevice; + m_device->setName(hw_name); + m_device->setType(QTouchDevice::TouchScreen); + m_device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area); + if (hw_pressure_max > hw_pressure_min) + m_device->setCapabilities(m_device->capabilities() | QTouchDevice::Pressure); + + QWindowSystemInterface::registerTouchDevice(m_device); +} + +QTouchScreenHandler::QTouchScreenHandler(const QString &spec) + : m_notify(0), m_fd(-1), d(0) +{ + setObjectName(QLatin1String("Evdev Touch Handler")); + + QString dev; + q_udev_devicePath(UDev_Touchpad | UDev_Touchscreen, &dev); + if (dev.isEmpty()) + dev = QLatin1String("/dev/input/event0"); + + QStringList args = spec.split(QLatin1Char(':')); + for (int i = 0; i < args.count(); ++i) + if (args.at(i).startsWith(QLatin1String("/dev/"))) + dev = args.at(i); + + qDebug("evdevtouch: Using device %s", qPrintable(dev)); + m_fd = QT_OPEN(dev.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 { + qWarning("Cannot open input device '%s': %s", qPrintable(dev), strerror(errno)); + return; + } + + d = new QTouchScreenData(this, args); + + input_absinfo absInfo; + memset(&absInfo, 0, sizeof(input_absinfo)); + if (ioctl(m_fd, EVIOCGABS(ABS_MT_POSITION_X), &absInfo) >= 0) { + qDebug("min X: %d max X: %d", absInfo.minimum, absInfo.maximum); + d->hw_range_x_min = absInfo.minimum; + d->hw_range_x_max = absInfo.maximum; + } + if (ioctl(m_fd, EVIOCGABS(ABS_MT_POSITION_Y), &absInfo) >= 0) { + qDebug("min Y: %d max Y: %d", absInfo.minimum, absInfo.maximum); + d->hw_range_y_min = absInfo.minimum; + d->hw_range_y_max = absInfo.maximum; + } + if (ioctl(m_fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) { + qDebug("min pressure: %d max pressure: %d", absInfo.minimum, absInfo.maximum); + if (absInfo.maximum > absInfo.minimum) { + d->hw_pressure_min = absInfo.minimum; + d->hw_pressure_max = absInfo.maximum; + } + } + char name[1024]; + if (ioctl(m_fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) { + d->hw_name = QString::fromLocal8Bit(name); + qDebug("device name: %s", name); + } + + d->registerDevice(); +} + +QTouchScreenHandler::~QTouchScreenHandler() +{ + if (m_fd >= 0) + QT_CLOSE(m_fd); + + delete d; +} + +void QTouchScreenHandler::readData() +{ + ::input_event buffer[32]; + int n = 0; + for (; ;) { + n = QT_READ(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); + + if (!n) { + qWarning("Got EOF from input device"); + return; + } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { + qWarning("Could not read from input device: %s", strerror(errno)); + if (errno == ENODEV) { // device got disconnected -> stop reading + delete m_notify; + m_notify = 0; + QT_CLOSE(m_fd); + m_fd = -1; + } + return; + } else if (n % sizeof(::input_event) == 0) { + break; + } + } + + n /= sizeof(::input_event); + + for (int i = 0; i < n; ++i) + d->processInputEvent(&buffer[i]); +} + +void QTouchScreenData::processInputEvent(input_event *data) +{ + if (data->type == EV_ABS) { + + if (data->code == ABS_MT_POSITION_X) { + m_currentData.x = qBound(hw_range_x_min, data->value, hw_range_x_max); + } else if (data->code == ABS_MT_POSITION_Y) { + m_currentData.y = qBound(hw_range_y_min, data->value, hw_range_y_max); + } else if (data->code == ABS_MT_TRACKING_ID) { + m_currentData.trackingId = data->value; + } else if (data->code == ABS_MT_TOUCH_MAJOR) { + m_currentData.maj = data->value; + if (data->value == 0) + m_currentData.state = Qt::TouchPointReleased; + } else if (data->code == ABS_PRESSURE) { + m_currentData.pressure = qBound(hw_pressure_min, data->value, hw_pressure_max); + } + + } else if (data->type == EV_SYN && data->code == SYN_MT_REPORT && m_lastEventType != EV_SYN) { + + // If there is no tracking id, one will be generated later. + // Until that use a temporary key. + int key = m_currentData.trackingId; + if (key == -1) + key = m_contacts.count(); + + m_contacts.insert(key, m_currentData); + m_currentData = Contact(); + + } else if (data->type == EV_SYN && data->code == SYN_REPORT) { + + // Ensure valid IDs even when the driver does not report ABS_MT_TRACKING_ID. + if (!m_contacts.isEmpty() && m_contacts.constBegin().value().trackingId == -1) + assignIds(); + + m_touchPoints.clear(); + Qt::TouchPointStates combinedStates; + QMutableHashIterator it(m_contacts); + while (it.hasNext()) { + it.next(); + QWindowSystemInterface::TouchPoint tp; + Contact &contact(it.value()); + tp.id = contact.trackingId; + tp.flags = contact.flags; + + if (m_lastContacts.contains(contact.trackingId)) { + const Contact &prev(m_lastContacts.value(contact.trackingId)); + if (contact.state == Qt::TouchPointReleased) { + // Copy over the previous values for released points, just in case. + contact.x = prev.x; + contact.y = prev.y; + contact.maj = prev.maj; + } else { + contact.state = (prev.x == contact.x && prev.y == contact.y) + ? Qt::TouchPointStationary : Qt::TouchPointMoved; + } + } + + // Avoid reporting a contact in released state more than once. + if (contact.state == Qt::TouchPointReleased + && !m_lastContacts.contains(contact.trackingId)) { + it.remove(); + continue; + } + + tp.state = contact.state; + combinedStates |= tp.state; + + // Store the HW coordinates for now, will be updated later. + tp.area = QRectF(0, 0, contact.maj, contact.maj); + tp.area.moveCenter(QPoint(contact.x, contact.y)); + tp.pressure = contact.pressure; + + // Get a normalized position in range 0..1. + tp.normalPosition = QPointF((contact.x - hw_range_x_min) / qreal(hw_range_x_max - hw_range_x_min), + (contact.y - hw_range_y_min) / qreal(hw_range_y_max - hw_range_y_min)); + + m_touchPoints.append(tp); + + if (contact.state == Qt::TouchPointReleased) + it.remove(); + } + + m_lastContacts = m_contacts; + m_contacts.clear(); + + if (!m_touchPoints.isEmpty() && combinedStates != Qt::TouchPointStationary) + reportPoints(); + } + + m_lastEventType = data->type; +} + +int QTouchScreenData::findClosestContact(const QHash &contacts, int x, int y, int *dist) +{ + int minDist = -1, id = -1; + for (QHash::const_iterator it = contacts.constBegin(), ite = contacts.constEnd(); + it != ite; ++it) { + const Contact &contact(it.value()); + int dx = x - contact.x; + int dy = y - contact.y; + int dist = dx * dx + dy * dy; + if (minDist == -1 || dist < minDist) { + minDist = dist; + id = contact.trackingId; + } + } + if (dist) + *dist = minDist; + return id; +} + +void QTouchScreenData::assignIds() +{ + QHash candidates = m_lastContacts, pending = m_contacts, newContacts; + int maxId = -1; + QHash::iterator it, ite, bestMatch; + while (!pending.isEmpty() && !candidates.isEmpty()) { + int bestDist = -1, bestId; + for (it = pending.begin(), ite = pending.end(); it != ite; ++it) { + int dist; + int id = findClosestContact(candidates, it->x, it->y, &dist); + if (id >= 0 && (bestDist == -1 || dist < bestDist)) { + bestDist = dist; + bestId = id; + bestMatch = it; + } + } + if (bestDist >= 0) { + bestMatch->trackingId = bestId; + newContacts.insert(bestId, *bestMatch); + candidates.remove(bestId); + pending.erase(bestMatch); + if (bestId > maxId) + maxId = bestId; + } + } + if (candidates.isEmpty()) { + for (it = pending.begin(), ite = pending.end(); it != ite; ++it) { + it->trackingId = ++maxId; + newContacts.insert(it->trackingId, *it); + } + } + m_contacts = newContacts; +} + +void QTouchScreenData::reportPoints() +{ + QRect winRect; + if (m_forceToActiveWindow) { + QWindow *win = QGuiApplication::activeWindow(); + if (!win) + return; + winRect = win->geometry(); + } else { + winRect = QGuiApplication::primaryScreen()->geometry(); + } + + const int hw_w = hw_range_x_max - hw_range_x_min; + const int hw_h = hw_range_y_max - hw_range_y_min; + + // Map the coordinates based on the normalized position. QPA expects 'area' + // to be in screen coordinates. + const int pointCount = m_touchPoints.count(); + for (int i = 0; i < pointCount; ++i) { + QWindowSystemInterface::TouchPoint &tp(m_touchPoints[i]); + + // Generate a screen position that is always inside the active window + // or the primary screen. + const int wx = winRect.left() + int(tp.normalPosition.x() * winRect.width()); + const int wy = winRect.top() + int(tp.normalPosition.y() * winRect.height()); + const qreal sizeRatio = (winRect.width() + winRect.height()) / qreal(hw_w + hw_h); + tp.area = QRect(0, 0, tp.area.width() * sizeRatio, tp.area.height() * sizeRatio); + tp.area.moveCenter(QPoint(wx, wy)); + + // Calculate normalized pressure. + if (!hw_pressure_min && !hw_pressure_max) + tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1; + else + tp.pressure = (tp.pressure - hw_pressure_min) / qreal(hw_pressure_max - hw_pressure_min); + } + + QWindowSystemInterface::handleTouchEvent(0, m_device, m_touchPoints); +} + + +QTouchScreenHandlerThread::QTouchScreenHandlerThread(const QString &spec) + : m_spec(spec), m_handler(0) +{ + start(); +} + +QTouchScreenHandlerThread::~QTouchScreenHandlerThread() +{ + quit(); + wait(); +} + +void QTouchScreenHandlerThread::run() +{ + m_handler = new QTouchScreenHandler(m_spec); + exec(); + delete m_handler; + m_handler = 0; +} + + +QT_END_NAMESPACE diff --git a/src/plugins/generic/evdevtouch/qevdevtouch.h b/src/plugins/generic/evdevtouch/qevdevtouch.h new file mode 100644 index 0000000000..343f638526 --- /dev/null +++ b/src/plugins/generic/evdevtouch/qevdevtouch.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVDEVTOUCH_H +#define QEVDEVTOUCH_H + +#include +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QSocketNotifier; +class QTouchScreenData; + +class QTouchScreenHandler : public QObject +{ + Q_OBJECT + +public: + QTouchScreenHandler(const QString &spec = QString()); + ~QTouchScreenHandler(); + +private slots: + void readData(); + +private: + void pathFromUdev(QString *path); + + QSocketNotifier *m_notify; + int m_fd; + QTouchScreenData *d; +}; + +class QTouchScreenHandlerThread : public QThread +{ +public: + QTouchScreenHandlerThread(const QString &spec); + ~QTouchScreenHandlerThread(); + void run(); + QTouchScreenHandler *handler() { return m_handler; } + +private: + QString m_spec; + QTouchScreenHandler *m_handler; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QEVDEVTOUCH_H diff --git a/src/plugins/generic/generic.pro b/src/plugins/generic/generic.pro index 68c7636940..c4c3f9229a 100644 --- a/src/plugins/generic/generic.pro +++ b/src/plugins/generic/generic.pro @@ -1,3 +1,9 @@ TEMPLATE = subdirs linux-g++-maemo: SUBDIRS += meego + +contains(QT_CONFIG, evdev) { + contains(QT_CONFIG, libudev) { + SUBDIRS += evdevmouse evdevtouch + } +} diff --git a/src/plugins/generic/linuxinput/linuxinput.pro b/src/plugins/generic/linuxinput/linuxinput.pro deleted file mode 100644 index 6ef5f0fb3a..0000000000 --- a/src/plugins/generic/linuxinput/linuxinput.pro +++ /dev/null @@ -1,14 +0,0 @@ -TARGET = qlinuxinputplugin -load(qt_plugin) - -DESTDIR = $$QT.gui.plugins/generic -target.path = $$[QT_INSTALL_PLUGINS]/generic -INSTALLS += target - -HEADERS = qlinuxinput.h - -QT += core-private - -SOURCES = main.cpp \ - qlinuxinput.cpp - diff --git a/src/plugins/generic/linuxinput/main.cpp b/src/plugins/generic/linuxinput/main.cpp deleted file mode 100644 index 04fc00f528..0000000000 --- a/src/plugins/generic/linuxinput/main.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "qlinuxinput.h" - -QT_BEGIN_NAMESPACE - -class QLinuxInputPlugin : public QGenericPlugin -{ -public: - QLinuxInputPlugin(); - - QStringList keys() const; - QObject* create(const QString &key, const QString &specification); -}; - -QLinuxInputPlugin::QLinuxInputPlugin() - : QGenericPlugin() -{ -} - -QStringList QLinuxInputPlugin::keys() const -{ - return (QStringList() - << QLatin1String("LinuxInputMouse")); -} - -QObject* QLinuxInputPlugin::create(const QString &key, - const QString &specification) -{ - if (!key.compare(QLatin1String("LinuxInputMouse"), Qt::CaseInsensitive)) - return new QLinuxInputMouseHandler(key, specification); - return 0; - } - -Q_EXPORT_PLUGIN2(qlinuxinputplugin, QLinuxInputPlugin) - -QT_END_NAMESPACE diff --git a/src/plugins/generic/linuxinput/qlinuxinput.cpp b/src/plugins/generic/linuxinput/qlinuxinput.cpp deleted file mode 100644 index 04633845cb..0000000000 --- a/src/plugins/generic/linuxinput/qlinuxinput.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qlinuxinput.h" - - -#include -#include -#include -#include - -#include -#include // overrides QT_OPEN - -#include -#include - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - - -//#define QT_QPA_EXPERIMENTAL_TOUCHEVENT - -#ifdef QT_QPA_EXPERIMENTAL_TOUCHEVENT -class QLinuxInputMouseHandlerData -{ -public: - QLinuxInputMouseHandlerData() :seenMT(false), state(QEvent::TouchBegin), currentIdx(0) {} - - void ensureCurrentPoint() { - if (currentIdx >= touchPoints.size()) { - Q_ASSERT(currentIdx == touchPoints.size()); - QWindowSystemInterface::TouchPoint tp; - tp.id = currentIdx; - tp.isPrimary = (currentIdx == 0); - tp.pressure = 1; - tp.area = QRectF(0,0,1,1); - tp.state = Qt::TouchPointReleased; // init in neutral state - touchPoints.append(tp); - } - } - void setCurrentPoint(int i) { - currentIdx = i; - if (currentIdx < touchPoints.size()) { - currentX = int(touchPoints[currentIdx].area.left()); - currentY = int(touchPoints[currentIdx].area.top()); - } else { - currentY = currentX = -999; - } - } - void advanceCurrentPoint() { - setCurrentPoint(currentIdx + 1); - } - int currentPoint() { return currentIdx; } - void setCurrentX(int value) { - ensureCurrentPoint(); - touchPoints[currentIdx].area.moveLeft(value); - } - bool currentMoved() { - return currentX != touchPoints[currentIdx].area.left() || currentY != touchPoints[currentIdx].area.top(); - } - void updateCurrentPos() { - ensureCurrentPoint(); - touchPoints[currentIdx].area.moveTopLeft(QPointF(currentX, currentY)); - } - void setCurrentState(Qt::TouchPointState state) { - ensureCurrentPoint(); - touchPoints[currentIdx].state = state; - } - Qt::TouchPointState currentState() const { - if (currentIdx < touchPoints.size()) - return touchPoints[currentIdx].state; - return Qt::TouchPointReleased; - } - QList touchPoints; - int currentX; - int currentY; - bool seenMT; - QEvent::Type state; -private: - int currentIdx; -}; -#endif - - -QLinuxInputMouseHandler::QLinuxInputMouseHandler(const QString &key, - const QString &specification) - : m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0), m_xoffset(0), m_yoffset(0), m_buttons(0), d(0) -{ - qDebug() << "QLinuxInputMouseHandler" << key << specification; - - - setObjectName(QLatin1String("LinuxInputSubsystem Mouse Handler")); - - QString dev = QLatin1String("/dev/input/event0"); - m_compression = true; - m_smooth = false; - int jitterLimit = 0; - - QStringList args = specification.split(QLatin1Char(':')); - foreach (const QString &arg, args) { - if (arg == "nocompress") - m_compression = false; - else if (arg.startsWith("dejitter=")) - jitterLimit = arg.mid(9).toInt(); - else if (arg.startsWith("xoffset=")) - m_xoffset = arg.mid(8).toInt(); - else if (arg.startsWith("yoffset=")) - m_yoffset = arg.mid(8).toInt(); - else if (arg.startsWith(QLatin1String("/dev/"))) - dev = arg; - } - m_jitterLimitSquared = jitterLimit*jitterLimit; - - m_fd = QT_OPEN(dev.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(readMouseData())); - } else { - qWarning("Cannot open mouse input device '%s': %s", qPrintable(dev), strerror(errno)); - return; - } -#ifdef QT_QPA_EXPERIMENTAL_TOUCHEVENT - d = new QLinuxInputMouseHandlerData; -#endif -} - - -QLinuxInputMouseHandler::~QLinuxInputMouseHandler() -{ - if (m_fd >= 0) - QT_CLOSE(m_fd); -#ifdef QT_QPA_EXPERIMENTAL_TOUCHEVENT - delete d; -#endif -} - -void QLinuxInputMouseHandler::sendMouseEvent(int x, int y, Qt::MouseButtons buttons) -{ - QPoint pos(x+m_xoffset, y+m_yoffset); - QWindowSystemInterface::handleMouseEvent(0, pos, pos, m_buttons); - m_prevx = x; - m_prevy = y; -} - -void QLinuxInputMouseHandler::readMouseData() -{ - struct ::input_event buffer[32]; - int n = 0; - bool posChanged = false; - bool pendingMouseEvent = false; - int eventCompressCount = 0; - forever { - n = QT_READ(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); - - if (n == 0) { - qWarning("Got EOF from the input device."); - return; - } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { - qWarning("Could not read from input device: %s", strerror(errno)); - return; - } else if (n % sizeof(buffer[0]) == 0) { - break; - } - } - - n /= sizeof(buffer[0]); - - for (int i = 0; i < n; ++i) { - struct ::input_event *data = &buffer[i]; - //qDebug() << ">>" << hex << data->type << data->code << dec << data->value; - bool unknown = false; - if (data->type == EV_ABS) { - if (data->code == ABS_X && m_x != data->value) { - m_x = data->value; - posChanged = true; - } else if (data->code == ABS_Y && m_y != data->value) { - m_y = data->value; - posChanged = true; - } else if (data->code == ABS_PRESSURE) { - //ignore for now... - } else if (data->code == ABS_TOOL_WIDTH) { - //ignore for now... - } else if (data->code == ABS_HAT0X) { - //ignore for now... - } else if (data->code == ABS_HAT0Y) { - //ignore for now... -#ifdef QT_QPA_EXPERIMENTAL_TOUCHEVENT - } else if (data->code == ABS_MT_POSITION_X) { - d->currentX = data->value; - d->seenMT = true; - } else if (data->code == ABS_MT_POSITION_Y) { - d->currentY = data->value; - d->seenMT = true; - } else if (data->code == ABS_MT_TOUCH_MAJOR) { - if (data->value == 0) - d->setCurrentState(Qt::TouchPointReleased); - //otherwise, ignore for now... - } else if (data->code == ABS_MT_TOUCH_MINOR) { - //ignore for now... -#endif - } else { - unknown = true; - } - } else if (data->type == EV_REL) { - if (data->code == REL_X) { - m_x += data->value; - posChanged = true; - } else if (data->code == REL_Y) { - m_y += data->value; - posChanged = true; - } else if (data->code == ABS_WHEEL) { // vertical scroll - // data->value: 1 == up, -1 == down - int delta = 120 * data->value; - QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), - QPoint(m_x, m_y), - delta, Qt::Vertical); - } else if (data->code == ABS_THROTTLE) { // horizontal scroll - // data->value: 1 == right, -1 == left - int delta = 120 * -data->value; - QWindowSystemInterface::handleWheelEvent(0, QPoint(m_x, m_y), - QPoint(m_x, m_y), - delta, Qt::Horizontal); - } else { - unknown = true; - } - } else if (data->type == EV_KEY && data->code == BTN_TOUCH) { - m_buttons = data->value ? Qt::LeftButton : Qt::NoButton; - - sendMouseEvent(m_x, m_y, m_buttons); - pendingMouseEvent = false; - } else if (data->type == EV_KEY && data->code >= BTN_LEFT && data->code <= BTN_MIDDLE) { - Qt::MouseButton button = Qt::NoButton; - switch (data->code) { - case BTN_LEFT: button = Qt::LeftButton; break; - case BTN_MIDDLE: button = Qt::MidButton; break; - case BTN_RIGHT: button = Qt::RightButton; break; - } - if (data->value) - m_buttons |= button; - else - m_buttons &= ~button; - sendMouseEvent(m_x, m_y, m_buttons); - pendingMouseEvent = false; - } else if (data->type == EV_SYN && data->code == SYN_REPORT) { - if (posChanged) { - posChanged = false; - if (m_compression) { - pendingMouseEvent = true; - eventCompressCount++; - } else { - sendMouseEvent(m_x, m_y, m_buttons); - } - } -#ifdef QT_QPA_EXPERIMENTAL_TOUCHEVENT - if (d->state == QEvent::TouchBegin && !d->seenMT) { - //no multipoint-touch events to send - } else { - if (!d->seenMT) - d->state = QEvent::TouchEnd; - - for (int i = d->currentPoint(); i < d->touchPoints.size(); ++i) { - d->touchPoints[i].pressure = 0; - d->touchPoints[i].state = Qt::TouchPointReleased; - } - //qDebug() << "handleTouchEvent" << d->state << d->touchPoints.size() << d->touchPoints[0].state; - QWindowSystemInterface::handleTouchEvent(0, d->state, QTouchEvent::TouchScreen, d->touchPoints); - if (d->seenMT) { - d->state = QEvent::TouchUpdate; - } else { - d->state = QEvent::TouchBegin; - d->touchPoints.clear(); - } - d->setCurrentPoint(0); - d->seenMT = false; - } - } else if (data->type == EV_SYN && data->code == SYN_MT_REPORT) { - //store data for this touch point - - if (!d->seenMT) { - d->setCurrentState(Qt::TouchPointReleased); - } else if (d->currentState() == Qt::TouchPointReleased) { - d->updateCurrentPos(); - d->setCurrentState(Qt::TouchPointPressed); - } else if (d->currentMoved()) { - d->updateCurrentPos(); - d->setCurrentState(Qt::TouchPointMoved); - } else { - d->setCurrentState(Qt::TouchPointStationary); - } - //qDebug() << "end of point" << d->currentPoint() << d->currentX << d->currentY << d->currentState(); - - //advance to next tp: - d->advanceCurrentPoint(); -#endif - } else if (data->type == EV_MSC && data->code == MSC_SCAN) { - // kernel encountered an unmapped key - just ignore it - continue; - } else { - unknown = true; - } -#ifdef QLINUXINPUT_EXTRA_DEBUG - if (unknown) { - qWarning("unknown mouse event type=%x, code=%x, value=%x", data->type, data->code, data->value); - } -#endif - } - if (m_compression && pendingMouseEvent) { - int distanceSquared = (m_x - m_prevx)*(m_x - m_prevx) + (m_y - m_prevy)*(m_y - m_prevy); - if (distanceSquared > m_jitterLimitSquared) - sendMouseEvent(m_x, m_y, m_buttons); - } -} - - - - - - - -QT_END_NAMESPACE - diff --git a/src/plugins/generic/linuxinput/qlinuxinput.h b/src/plugins/generic/linuxinput/qlinuxinput.h deleted file mode 100644 index a512ad959a..0000000000 --- a/src/plugins/generic/linuxinput/qlinuxinput.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QLINUXINPUT_H -#define QLINUXINPUT_H - -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QSocketNotifier; - -class QLinuxInputMouseHandlerData; - -class QLinuxInputMouseHandler : public QObject -{ - Q_OBJECT -public: - QLinuxInputMouseHandler(const QString &key, const QString &specification); - ~QLinuxInputMouseHandler(); - -private slots: - void readMouseData(); - -private: - void sendMouseEvent(int x, int y, Qt::MouseButtons buttons); - QSocketNotifier * m_notify; - int m_fd; - int m_x, m_y; - int m_prevx, m_prevy; - int m_xoffset, m_yoffset; - int m_smoothx, m_smoothy; - Qt::MouseButtons m_buttons; - bool m_compression; - bool m_smooth; - int m_jitterLimitSquared; - QLinuxInputMouseHandlerData *d; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QLINUXINPUT_H diff --git a/src/plugins/generic/touchscreen/70-qtouchscreen.rules b/src/plugins/generic/touchscreen/70-qtouchscreen.rules deleted file mode 100644 index 2afde8f8a3..0000000000 --- a/src/plugins/generic/touchscreen/70-qtouchscreen.rules +++ /dev/null @@ -1 +0,0 @@ -KERNEL=="event*", ENV{ID_INPUT_TOUCHPAD}=="1", MODE="0644" diff --git a/src/plugins/generic/touchscreen/README b/src/plugins/generic/touchscreen/README deleted file mode 100644 index ac73f5f147..0000000000 --- a/src/plugins/generic/touchscreen/README +++ /dev/null @@ -1,45 +0,0 @@ -Generic plug-in for evdev touch events. - -Tested with the following drivers: bcm5974, hid_magicmouse. - -(1) Using as a QPA generic plug-in - -1. set up and connect the touch device -2. install libudev-dev or similar -3. build this plug-in (qmake && make) -4. sudo cp 70-qtouchscreen.rules /etc/udev/rules.d -5. sudo udevadm trigger --subsystem-match=input -6. ./fingerpaint -plugin LinuxTouchScreen:force_window - -If automatic detection does not work, use -plugin -LinuxTouchScreen:/dev/input/eventN to explicitly set the device file -name. - -By default the surface of the touch device is mapped to the entire -screen. If this is not desired, pass force_window in the plugin -specification as shown in the example above. This will cause mapping -the touch surface to the active window instead. - -Only touch events are generated, mouse events are not. Be aware however -that ignored touch events will generate a mouse event from the first -touch point by default. See AA_SynthesizeMouseForUnhandledTouchEvents. - -(2) Using in a compositor - -The classes (QTouchScreenHandler, QTouchScreenHandlerThread) are also -suitable for direct inclusion into an application, e.g. a Wayland -compositor. The compositor may then register its own -QTouchScreenObserver because relying on the QTouchEvents generated by -the QPA event sender may not always be satisfactory as some low-level -details get lost, and due to performance reasons. - -(3) Possible issues and solutions - -The udev rule matches any touchpad device. If there are multiple ones, -specify the device as described above. - -If no evdev events are read, remove 50-synaptics.conf (or similar) -from /usr/share/X11/xorg.conf.d and restart X. Or at least temporarily -disable the device by running xinput set-prop 0. Use xinput list and xinput list-props to figure out the -values. diff --git a/src/plugins/generic/touchscreen/main.cpp b/src/plugins/generic/touchscreen/main.cpp deleted file mode 100644 index 1f438ef1e7..0000000000 --- a/src/plugins/generic/touchscreen/main.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "qtouchscreen.h" -#include "qtoucheventsenderqpa.h" - -QT_BEGIN_NAMESPACE - -class QTouchScreenPlugin : public QGenericPlugin -{ -public: - QTouchScreenPlugin(); - - QStringList keys() const; - QObject* create(const QString &key, const QString &specification); -}; - -QTouchScreenPlugin::QTouchScreenPlugin() -{ -} - -QStringList QTouchScreenPlugin::keys() const -{ - return QStringList() << "LinuxTouchScreen"; -} - -QObject* QTouchScreenPlugin::create(const QString &key, - const QString &spec) -{ - if (!key.compare(QLatin1String("LinuxTouchScreen"), Qt::CaseInsensitive)) { - QTouchScreenObserver *obs = new QTouchEventSenderQPA(spec); - QTouchScreenHandlerThread *h = new QTouchScreenHandlerThread(spec, obs); - return h; - } - - return 0; - } - -Q_EXPORT_PLUGIN2(qtouchscreenplugin, QTouchScreenPlugin) - -QT_END_NAMESPACE diff --git a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp deleted file mode 100644 index ac4a12c09a..0000000000 --- a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtoucheventsenderqpa.h" -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -QTouchEventSenderQPA::QTouchEventSenderQPA(const QString &spec) -{ - m_forceToActiveWindow = spec.split(QLatin1Char(':')).contains(QLatin1String("force_window")); - m_device = new QTouchDevice; - m_device->setType(QTouchDevice::TouchScreen); - m_device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area); - QWindowSystemInterface::registerTouchDevice(m_device); -} - -void QTouchEventSenderQPA::touch_configure(int x_min, int x_max, int y_min, int y_max, - int pressure_min, int pressure_max, - const QString &dev_name) -{ - hw_range_x_min = x_min; - hw_range_x_max = x_max; - hw_range_y_min = y_min; - hw_range_y_max = y_max; - - hw_pressure_min = pressure_min; - hw_pressure_max = pressure_max; - - m_device->setName(dev_name); - - if (hw_pressure_max > hw_pressure_min) - m_device->setCapabilities(m_device->capabilities() | QTouchDevice::Pressure); -} - -void QTouchEventSenderQPA::touch_point(const QList &points) -{ - QRect winRect; - if (m_forceToActiveWindow) { - QWindow *win = QGuiApplication::activeWindow(); - if (!win) - return; - winRect = win->geometry(); - } else { - winRect = QGuiApplication::primaryScreen()->geometry(); - } - - const int hw_w = hw_range_x_max - hw_range_x_min; - const int hw_h = hw_range_y_max - hw_range_y_min; - - QList touchPoints = points; - // Map the coordinates based on the normalized position. QPA expects 'area' - // to be in screen coordinates. - for (int i = 0; i < touchPoints.size(); ++i) { - QWindowSystemInterface::TouchPoint &tp(touchPoints[i]); - - // Generate a screen position that is always inside the active window - // or the primary screen. - const int wx = winRect.left() + int(tp.normalPosition.x() * winRect.width()); - const int wy = winRect.top() + int(tp.normalPosition.y() * winRect.height()); - const qreal sizeRatio = (winRect.width() + winRect.height()) / qreal(hw_w + hw_h); - tp.area = QRect(0, 0, tp.area.width() * sizeRatio, tp.area.height() * sizeRatio); - tp.area.moveCenter(QPoint(wx, wy)); - - // Calculate normalized pressure. - if (!hw_pressure_min && !hw_pressure_max) - tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1; - else - tp.pressure = (tp.pressure - hw_pressure_min) / qreal(hw_pressure_max - hw_pressure_min); - } - - QWindowSystemInterface::handleTouchEvent(0, m_device, touchPoints); -} - -QT_END_NAMESPACE diff --git a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h deleted file mode 100644 index 6b21dfe259..0000000000 --- a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTOUCHEVENTSENDERQPA_H -#define QTOUCHEVENTSENDERQPA_H - -#include "qtouchscreen.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QTouchDevice; - -class QTouchEventSenderQPA : public QTouchScreenObserver -{ -public: - QTouchEventSenderQPA(const QString &spec = QString()); - void touch_configure(int x_min, int x_max, int y_min, int y_max, - int pressure_min, int pressure_max, const QString &dev_name); - void touch_point(const QList &points); - -private: - bool m_forceToActiveWindow; - int hw_range_x_min; - int hw_range_x_max; - int hw_range_y_min; - int hw_range_y_max; - int hw_pressure_min; - int hw_pressure_max; - QString hw_dev_name; - QTouchDevice *m_device; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QTOUCHEVENTSENDERQPA_H diff --git a/src/plugins/generic/touchscreen/qtouchscreen.cpp b/src/plugins/generic/touchscreen/qtouchscreen.cpp deleted file mode 100644 index 8e04c10b9f..0000000000 --- a/src/plugins/generic/touchscreen/qtouchscreen.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtouchscreen.h" -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QTouchScreenData -{ -public: - QTouchScreenData(QTouchScreenHandler *q_ptr, const QStringList &args); - - void processInputEvent(input_event *data); - void assignIds(); - - QTouchScreenHandler *q; - int m_lastEventType; - QList m_touchPoints; - - struct Contact { - int trackingId; - int x; - int y; - int maj; - int pressure; - Qt::TouchPointState state; - QTouchEvent::TouchPoint::InfoFlags flags; - Contact() : trackingId(-1), - x(0), y(0), maj(1), pressure(0), - state(Qt::TouchPointPressed), flags(0) { } - }; - QHash m_contacts, m_lastContacts; - Contact m_currentData; - - int findClosestContact(const QHash &contacts, int x, int y, int *dist); - - int hw_range_x_min; - int hw_range_x_max; - int hw_range_y_min; - int hw_range_y_max; - int hw_pressure_min; - int hw_pressure_max; - QString hw_name; - - QList m_observers; -}; - -QTouchScreenData::QTouchScreenData(QTouchScreenHandler *q_ptr, const QStringList &args) - : q(q_ptr), - m_lastEventType(-1), - hw_range_x_min(0), hw_range_x_max(0), - hw_range_y_min(0), hw_range_y_max(0), - hw_pressure_min(0), hw_pressure_max(0) -{ - Q_UNUSED(args); -} - -QTouchScreenHandler::QTouchScreenHandler(const QString &spec) - : m_notify(0), m_fd(-1), d(0) -{ - setObjectName(QLatin1String("Linux Touch Handler")); - - QString dev = QLatin1String("/dev/input/event5"); - try_udev(&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); - - qDebug("Using device '%s'", qPrintable(dev)); - m_fd = QT_OPEN(dev.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 { - qWarning("Cannot open input device '%s': %s", qPrintable(dev), strerror(errno)); - return; - } - - d = new QTouchScreenData(this, args); - - input_absinfo absInfo; - memset(&absInfo, 0, sizeof(input_absinfo)); - if (ioctl(m_fd, EVIOCGABS(ABS_MT_POSITION_X), &absInfo) >= 0) { - qDebug("min X: %d max X: %d", absInfo.minimum, absInfo.maximum); - d->hw_range_x_min = absInfo.minimum; - d->hw_range_x_max = absInfo.maximum; - } - if (ioctl(m_fd, EVIOCGABS(ABS_MT_POSITION_Y), &absInfo) >= 0) { - qDebug("min Y: %d max Y: %d", absInfo.minimum, absInfo.maximum); - d->hw_range_y_min = absInfo.minimum; - d->hw_range_y_max = absInfo.maximum; - } - if (ioctl(m_fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) { - qDebug("min pressure: %d max pressure: %d", absInfo.minimum, absInfo.maximum); - if (absInfo.maximum > absInfo.minimum) { - d->hw_pressure_min = absInfo.minimum; - d->hw_pressure_max = absInfo.maximum; - } - } - char name[1024]; - if (ioctl(m_fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) { - d->hw_name = QString::fromLocal8Bit(name); - qDebug("device name: %s", name); - } -} - -QTouchScreenHandler::~QTouchScreenHandler() -{ - if (m_fd >= 0) - QT_CLOSE(m_fd); - - delete d; -} - -void QTouchScreenHandler::addObserver(QTouchScreenObserver *observer) -{ - if (!d || !observer) - return; - d->m_observers.append(observer); - observer->touch_configure(d->hw_range_x_min, d->hw_range_x_max, - d->hw_range_y_min, d->hw_range_y_max, - d->hw_pressure_min, d->hw_pressure_max, - d->hw_name); -} - -void QTouchScreenHandler::try_udev(QString *path) -{ - *path = QString(); - udev *u = udev_new(); - udev_enumerate *ue = udev_enumerate_new(u); - udev_enumerate_add_match_subsystem(ue, "input"); - udev_enumerate_add_match_property(ue, "ID_INPUT_TOUCHPAD", "1"); - udev_enumerate_scan_devices(ue); - udev_list_entry *entry; - udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(ue)) { - const char *syspath = udev_list_entry_get_name(entry); - udev_device *udevice = udev_device_new_from_syspath(u, syspath); - QString candidate = QString::fromLocal8Bit(udev_device_get_devnode(udevice)); - udev_device_unref(udevice); - if (path->isEmpty() && candidate.startsWith("/dev/input/event")) - *path = candidate; - } - udev_enumerate_unref(ue); - udev_unref(u); -} - -void QTouchScreenHandler::readData() -{ - ::input_event buffer[32]; - int n = 0; - for (; ;) { - n = QT_READ(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); - - if (!n) { - qWarning("Got EOF from input device"); - return; - } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { - qWarning("Could not read from input device: %s", strerror(errno)); - if (errno == ENODEV) { // device got disconnected -> stop reading - delete m_notify; - m_notify = 0; - QT_CLOSE(m_fd); - m_fd = -1; - } - return; - } else if (n % sizeof(::input_event) == 0) { - break; - } - } - - n /= sizeof(::input_event); - - for (int i = 0; i < n; ++i) - d->processInputEvent(&buffer[i]); -} - -void QTouchScreenData::processInputEvent(input_event *data) -{ - if (data->type == EV_ABS) { - - if (data->code == ABS_MT_POSITION_X) { - m_currentData.x = qBound(hw_range_x_min, data->value, hw_range_x_max); - } else if (data->code == ABS_MT_POSITION_Y) { - m_currentData.y = qBound(hw_range_y_min, data->value, hw_range_y_max); - } else if (data->code == ABS_MT_TRACKING_ID) { - m_currentData.trackingId = data->value; - } else if (data->code == ABS_MT_TOUCH_MAJOR) { - m_currentData.maj = data->value; - if (data->value == 0) - m_currentData.state = Qt::TouchPointReleased; - } else if (data->code == ABS_PRESSURE) { - m_currentData.pressure = qBound(hw_pressure_min, data->value, hw_pressure_max); - } - - } else if (data->type == EV_SYN && data->code == SYN_MT_REPORT && m_lastEventType != EV_SYN) { - - // If there is no tracking id, one will be generated later. - // Until that use a temporary key. - int key = m_currentData.trackingId; - if (key == -1) - key = m_contacts.count(); - - m_contacts.insert(key, m_currentData); - m_currentData = Contact(); - - } else if (data->type == EV_SYN && data->code == SYN_REPORT) { - - // Ensure valid IDs even when the driver does not report ABS_MT_TRACKING_ID. - if (!m_contacts.isEmpty() && m_contacts.constBegin().value().trackingId == -1) - assignIds(); - - m_touchPoints.clear(); - Qt::TouchPointStates combinedStates; - QMutableHashIterator it(m_contacts); - while (it.hasNext()) { - it.next(); - QWindowSystemInterface::TouchPoint tp; - Contact &contact(it.value()); - tp.id = contact.trackingId; - tp.flags = contact.flags; - - if (m_lastContacts.contains(contact.trackingId)) { - const Contact &prev(m_lastContacts.value(contact.trackingId)); - if (contact.state == Qt::TouchPointReleased) { - // Copy over the previous values for released points, just in case. - contact.x = prev.x; - contact.y = prev.y; - contact.maj = prev.maj; - } else { - contact.state = (prev.x == contact.x && prev.y == contact.y) - ? Qt::TouchPointStationary : Qt::TouchPointMoved; - } - } - - // Avoid reporting a contact in released state more than once. - if (contact.state == Qt::TouchPointReleased - && !m_lastContacts.contains(contact.trackingId)) { - it.remove(); - continue; - } - - tp.state = contact.state; - combinedStates |= tp.state; - - // Store the HW coordinates. Observers can then map it to screen space or something else. - tp.area = QRectF(0, 0, contact.maj, contact.maj); - tp.area.moveCenter(QPoint(contact.x, contact.y)); - tp.pressure = contact.pressure; - - // Get a normalized position in range 0..1. - tp.normalPosition = QPointF((contact.x - hw_range_x_min) / qreal(hw_range_x_max - hw_range_x_min), - (contact.y - hw_range_y_min) / qreal(hw_range_y_max - hw_range_y_min)); - - m_touchPoints.append(tp); - - if (contact.state == Qt::TouchPointReleased) - it.remove(); - } - - m_lastContacts = m_contacts; - m_contacts.clear(); - - if (!m_touchPoints.isEmpty() && combinedStates != Qt::TouchPointStationary) { - for (int i = 0; i < m_observers.count(); ++i) - m_observers.at(i)->touch_point(m_touchPoints); - } - } - - m_lastEventType = data->type; -} - -int QTouchScreenData::findClosestContact(const QHash &contacts, int x, int y, int *dist) -{ - int minDist = -1, id = -1; - for (QHash::const_iterator it = contacts.constBegin(), ite = contacts.constEnd(); - it != ite; ++it) { - const Contact &contact(it.value()); - int dx = x - contact.x; - int dy = y - contact.y; - int dist = dx * dx + dy * dy; - if (minDist == -1 || dist < minDist) { - minDist = dist; - id = contact.trackingId; - } - } - if (dist) - *dist = minDist; - return id; -} - -void QTouchScreenData::assignIds() -{ - QHash candidates = m_lastContacts, pending = m_contacts, newContacts; - int maxId = -1; - QHash::iterator it, ite, bestMatch; - while (!pending.isEmpty() && !candidates.isEmpty()) { - int bestDist = -1, bestId; - for (it = pending.begin(), ite = pending.end(); it != ite; ++it) { - int dist; - int id = findClosestContact(candidates, it->x, it->y, &dist); - if (id >= 0 && (bestDist == -1 || dist < bestDist)) { - bestDist = dist; - bestId = id; - bestMatch = it; - } - } - if (bestDist >= 0) { - bestMatch->trackingId = bestId; - newContacts.insert(bestId, *bestMatch); - candidates.remove(bestId); - pending.erase(bestMatch); - if (bestId > maxId) - maxId = bestId; - } - } - if (candidates.isEmpty()) { - for (it = pending.begin(), ite = pending.end(); it != ite; ++it) { - it->trackingId = ++maxId; - newContacts.insert(it->trackingId, *it); - } - } - m_contacts = newContacts; -} - - -QTouchScreenHandlerThread::QTouchScreenHandlerThread(const QString &spec, - QTouchScreenObserver *observer) - : m_spec(spec), m_handler(0), m_observer(observer) -{ - start(); -} - -QTouchScreenHandlerThread::~QTouchScreenHandlerThread() -{ - quit(); - wait(); -} - -void QTouchScreenHandlerThread::run() -{ - m_handler = new QTouchScreenHandler(m_spec); - m_handler->addObserver(m_observer); - exec(); - delete m_handler; - m_handler = 0; -} - - -QT_END_NAMESPACE diff --git a/src/plugins/generic/touchscreen/qtouchscreen.h b/src/plugins/generic/touchscreen/qtouchscreen.h deleted file mode 100644 index 33a1b0ad2f..0000000000 --- a/src/plugins/generic/touchscreen/qtouchscreen.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTOUCHSCREEN_H -#define QTOUCHSCREEN_H - -#include -#include -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QSocketNotifier; -class QTouchScreenData; - -class QTouchScreenObserver -{ -public: - virtual void touch_configure(int x_min, int x_max, int y_min, int y_max, - int pressure_min, int pressure_max, const QString &dev_name) = 0; - virtual void touch_point(const QList &points) = 0; -}; - -class QTouchScreenHandler : public QObject -{ - Q_OBJECT - -public: - QTouchScreenHandler(const QString &spec = QString()); - ~QTouchScreenHandler(); - void addObserver(QTouchScreenObserver *observer); - -private slots: - void readData(); - -private: - void try_udev(QString *path); - - QSocketNotifier *m_notify; - int m_fd; - QTouchScreenData *d; -}; - -class QTouchScreenHandlerThread : public QThread -{ -public: - QTouchScreenHandlerThread(const QString &spec, QTouchScreenObserver *observer); - ~QTouchScreenHandlerThread(); - void run(); - QTouchScreenHandler *handler() { return m_handler; } - -private: - QString m_spec; - QTouchScreenHandler *m_handler; - QTouchScreenObserver *m_observer; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QTOUCHSCREEN_H diff --git a/src/plugins/generic/touchscreen/touchscreen.pro b/src/plugins/generic/touchscreen/touchscreen.pro deleted file mode 100644 index 60aa29c5ec..0000000000 --- a/src/plugins/generic/touchscreen/touchscreen.pro +++ /dev/null @@ -1,18 +0,0 @@ -TARGET = qtouchscreenplugin -load(qt_plugin) - -DESTDIR = $$QT.gui.plugins/generic -target.path = $$[QT_INSTALL_PLUGINS]/generic -INSTALLS += target - -HEADERS = \ - qtouchscreen.h \ - qtoucheventsenderqpa.h - -SOURCES = main.cpp \ - qtouchscreen.cpp \ - qtoucheventsenderqpa.cpp - -QT += core-private gui-private - -LIBS += -ludev -- cgit v1.2.3