From 7a9c5eea815dbc124503180d91eb835ede3f3e50 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 30 Jun 2011 12:24:35 +0300 Subject: Add a touchscreen generic qpa plugin. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iaf79df05eb4f60d254d95f5d0f280a8f8f8a8de8 Reviewed-on: http://codereview.qt.nokia.com/941 Reviewed-by: Jørgen Lind --- .../generic/touchscreen/70-qtouchscreen.rules | 1 + src/plugins/generic/touchscreen/README | 45 +++ src/plugins/generic/touchscreen/main.cpp | 80 +++++ .../generic/touchscreen/qtoucheventsenderqpa.cpp | 113 +++++++ .../generic/touchscreen/qtoucheventsenderqpa.h | 68 +++++ src/plugins/generic/touchscreen/qtouchscreen.cpp | 324 +++++++++++++++++++++ src/plugins/generic/touchscreen/qtouchscreen.h | 106 +++++++ src/plugins/generic/touchscreen/touchscreen.pro | 18 ++ 8 files changed, 755 insertions(+) create mode 100644 src/plugins/generic/touchscreen/70-qtouchscreen.rules create mode 100644 src/plugins/generic/touchscreen/README create mode 100644 src/plugins/generic/touchscreen/main.cpp create mode 100644 src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp create mode 100644 src/plugins/generic/touchscreen/qtoucheventsenderqpa.h create mode 100644 src/plugins/generic/touchscreen/qtouchscreen.cpp create mode 100644 src/plugins/generic/touchscreen/qtouchscreen.h create mode 100644 src/plugins/generic/touchscreen/touchscreen.pro (limited to 'src/plugins/generic/touchscreen') diff --git a/src/plugins/generic/touchscreen/70-qtouchscreen.rules b/src/plugins/generic/touchscreen/70-qtouchscreen.rules new file mode 100644 index 0000000000..8119a14382 --- /dev/null +++ b/src/plugins/generic/touchscreen/70-qtouchscreen.rules @@ -0,0 +1 @@ +KERNEL=="event*", ENV{ID_INPUT_TOUCHPAD}=="1", ENV{QT_TOUCH}="1", MODE="0644" diff --git a/src/plugins/generic/touchscreen/README b/src/plugins/generic/touchscreen/README new file mode 100644 index 0000000000..76f695371d --- /dev/null +++ b/src/plugins/generic/touchscreen/README @@ -0,0 +1,45 @@ +Generic plug-in for evdev touch events + +(a) Using as a QPA generic plug-in + +1. set up the touch device +2. sudo apt-get install libmtdev-dev libudev-dev +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. run apps like this: app -platform xcb -plugin LinuxTouchScreen + +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, define FORCE_TO_ACTIVE_WINDOW in +qtoucheventsenderqpa.cpp. This will map the touch surface to the +active window instead. + +Only touch events are generated (via +QWindowSystemInterface::handleTouchEvent), mouse events are not. This +is because on desktop the touch device will usually act as a +single-touch mouse replacement anyway. For pointer-less systems the +code needs to be extended to generate also mouse events (by calling +handleMouseEvent too). + +(b) Using in a compositor + +The classes (QTouchScreenHandler, QTouchScreenHandlerThread) are also +suitable for direct inclusion into an application, e.g. a Wayland +compositor. The compositor will then usually register its own +QTouchScreenObserver because relying on the QTouchEvents generated by +the QPA event sender is often not satisfactory, as some low-level +details may get lost, and due to performance reasons. + + +Known issues: + +The udev rule matches any touchpad device. If there are multiple ones, +specify the device as described above. + +On recent distributions (e.g. Ubuntu 11.04) you may need to remove +50-synaptics.conf from /usr/share/X11/xorg.conf.d (followed by +logout/login) otherwise no evdev events can be read. diff --git a/src/plugins/generic/touchscreen/main.cpp b/src/plugins/generic/touchscreen/main.cpp new file mode 100644 index 0000000000..8ad756355d --- /dev/null +++ b/src/plugins/generic/touchscreen/main.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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)) { + QTouchScreenHandler *h = new QTouchScreenHandler(spec); + h->addObserver(new QTouchEventSenderQPA); + 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 new file mode 100644 index 0000000000..7dff55b1bc --- /dev/null +++ b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 + +QT_BEGIN_NAMESPACE + +//#define POINT_DEBUG +//#define FORCE_TO_ACTIVE_WINDOW + +void QTouchEventSenderQPA::touch_configure(int x_min, int x_max, int y_min, int y_max) +{ + hw_range_x_min = x_min; + hw_range_x_max = x_max; + hw_range_y_min = y_min; + hw_range_y_max = y_max; +} + +void QTouchEventSenderQPA::touch_point(QEvent::Type state, + const QList &points) +{ +#ifdef FORCE_TO_ACTIVE_WINDOW + QWidget *win = QApplication::activeWindow(); // ### migrate to QWindow later on + if (!win) { +#ifdef POINT_DEBUG + qDebug("sendTouchEvent: No active window"); +#endif + return; + } + const QRect winRect = win->geometry(); +#else + const QRect winRect = QApplication::desktop()->screenGeometry(); +#endif + +#ifdef POINT_DEBUG + qDebug() << points.size() << "points" << winRect << state; +#endif + + QList touchPoints = points; + // Translate the coordinates and set the normalized position. QPA expects + // 'area' to be in screen coordinates, while the device reports them in its + // own system with (0, 0) being the center point of the device. + for (int i = 0; i < touchPoints.size(); ++i) { + QWindowSystemInterface::TouchPoint &tp(touchPoints[i]); + + // Translate so that (0, 0) is the top-left corner. + const int hw_x = qBound(hw_range_x_min, int(tp.area.left()), hw_range_x_max) - hw_range_x_min; + const int hw_y = qBound(hw_range_y_min, int(tp.area.top()), hw_range_y_max) - hw_range_y_min; + + // Get a normalized position in range 0..1. + const int hw_w = hw_range_x_max - hw_range_x_min; + const int hw_h = hw_range_y_max - hw_range_y_min; + tp.normalPosition = QPointF(hw_x / qreal(hw_w), + hw_y / qreal(hw_h)); + + qreal nx = tp.normalPosition.x(); + qreal ny = tp.normalPosition.y(); + + // Generate a screen position that is always inside the active window or the default screen. + const int wx = winRect.left() + int(nx * winRect.width()); + const int wy = winRect.top() + int(ny * winRect.height()); + tp.area.moveTopLeft(QPoint(wx, wy)); + +#ifdef POINT_DEBUG + qDebug() << " " << i << tp.area << tp.state << tp.id << tp.isPrimary << tp.pressure; +#endif + } + + QWindowSystemInterface::handleTouchEvent(0, state, QTouchEvent::TouchScreen, touchPoints); +} + +QT_END_NAMESPACE diff --git a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h new file mode 100644 index 0000000000..68d621a4e5 --- /dev/null +++ b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 QTouchEventSenderQPA : public QTouchScreenObserver +{ +public: + void touch_configure(int x_min, int x_max, int y_min, int y_max); + void touch_point(QEvent::Type state, const QList &points); + +private: + int hw_range_x_min; + int hw_range_x_max; + int hw_range_y_min; + int hw_range_y_max; +}; + +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 new file mode 100644 index 0000000000..2bbed6a62f --- /dev/null +++ b/src/plugins/generic/touchscreen/qtouchscreen.cpp @@ -0,0 +1,324 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 + +extern "C" { +#include +} + +//#define POINT_DEBUG + +QT_BEGIN_NAMESPACE + +class QTouchScreenData +{ +public: + QTouchScreenData(QTouchScreenHandler *q_ptr); + + void handle(input_event *data); + + QTouchScreenHandler *q; + QEvent::Type m_state; + QEvent::Type m_prevState; + QList m_touchPoints; + + struct Slot { + int trackingId; + int x; + int y; + Qt::TouchPointState state; + bool primary; + Slot() : trackingId(0), x(0), y(0), state(Qt::TouchPointPressed), primary(false) { } + }; + QMap m_slots; + QMap m_lastReport; + int m_currentSlot; + + int hw_range_x_min; + int hw_range_x_max; + int hw_range_y_min; + int hw_range_y_max; + QString hw_name; + + QList m_observers; +}; + +QTouchScreenData::QTouchScreenData(QTouchScreenHandler *q_ptr) + : q(q_ptr), + m_state(QEvent::TouchBegin), + m_prevState(m_state), + m_currentSlot(0), + hw_range_x_min(0), hw_range_x_max(0), + hw_range_y_min(0), hw_range_y_max(0) +{ +} + +QTouchScreenHandler::QTouchScreenHandler(const QString &spec) + : m_notify(0), m_fd(-1), m_mtdev(0), d(0) +{ + setObjectName(QLatin1String("LinuxInputSubsystem 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; + } + + m_mtdev = (mtdev *) calloc(1, sizeof(mtdev)); + int mtdeverr = mtdev_open(m_mtdev, m_fd); + if (mtdeverr) { + qWarning("mtdev_open failed: %d", mtdeverr); + QT_CLOSE(m_fd); + return; + } + + d = new QTouchScreenData(this); + + input_absinfo absInfo; + memset(&absInfo, 0, sizeof(input_absinfo)); + if (!ioctl(m_fd, EVIOCGABS(ABS_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_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; + } + char name[1024]; + if (ioctl(m_fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) { + d->hw_name = QString::fromUtf8(name); + qDebug() << "device name" << d->hw_name; + } +} + +QTouchScreenHandler::~QTouchScreenHandler() +{ + if (m_fd >= 0) + QT_CLOSE(m_fd); + + if (m_mtdev) { + mtdev_close(m_mtdev); + free(m_mtdev); + } + + 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); +} + +void QTouchScreenHandler::try_udev(QString *path) +{ + udev *u = udev_new(); + udev_enumerate *ue = udev_enumerate_new(u); + udev_enumerate_add_match_subsystem(ue, "input"); + udev_enumerate_add_match_property(ue, "QT_TOUCH", "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); + *path = QString::fromLocal8Bit(udev_device_get_devnode(udevice)); + qDebug("from udev: %s", qPrintable(*path)); + udev_device_unref(udevice); + } + udev_enumerate_unref(ue); + udev_unref(u); +} + +void QTouchScreenHandler::readData() +{ + input_event buffer[32]; + int n = 0; + n = mtdev_get(m_mtdev, m_fd, buffer, sizeof(buffer) / sizeof(input_event)); + if (n < 0) { + if (errno != EINTR && errno != EAGAIN) + qWarning("Could not read from input device: %s", strerror(errno)); + } else if (n > 0) { + for (int i = 0; i < n; ++i) { + input_event *data = &buffer[i]; + d->handle(data); + } + } +} + +void QTouchScreenData::handle(input_event *data) +{ + if (data->type == EV_ABS) { + if (data->code == ABS_MT_POSITION_X) { + m_slots[m_currentSlot].x = data->value; + } else if (data->code == ABS_MT_POSITION_Y) { + m_slots[m_currentSlot].y = data->value; + } else if (data->code == ABS_MT_SLOT) { + m_currentSlot = data->value; + } else if (data->code == ABS_MT_TRACKING_ID) { + if (data->value == -1) { + bool wasPrimary = m_slots[m_currentSlot].primary; + m_lastReport.remove(m_slots[m_currentSlot].trackingId); + m_slots.remove(m_currentSlot); + if (wasPrimary && !m_slots.isEmpty()) + m_slots[m_slots.keys().at(0)].primary = true; + } else { + m_slots[m_currentSlot].trackingId = data->value; + m_slots[m_currentSlot].primary = m_slots.count() == 1; + } + } else if (data->code == ABS_MT_TOUCH_MAJOR) { + if (data->value == 0) + m_slots[m_currentSlot].state = Qt::TouchPointReleased; + } + } else if (data->type == EV_SYN && data->code == SYN_REPORT) { + m_touchPoints.clear(); + QList keys = m_slots.keys(); + int ignoredSlotCount = 0; + for (int i = 0; i < keys.count(); ++i) { + const Slot &slot(m_slots.value(keys.at(i))); + if (slot.trackingId == 0) { + ++ignoredSlotCount; + continue; + } + QWindowSystemInterface::TouchPoint tp; + tp.id = slot.trackingId; + tp.isPrimary = slot.primary; + tp.pressure = slot.state == Qt::TouchPointReleased ? 0 : 1; + tp.area = QRectF(slot.x, slot.y, 1, 1); + tp.state = slot.state; + if (slot.state == Qt::TouchPointMoved && m_lastReport.contains(slot.trackingId)) { + QPoint lastPos = m_lastReport.value(slot.trackingId); + if (lastPos.x() == slot.x && lastPos.y() == slot.y) + tp.state = Qt::TouchPointStationary; + } + m_touchPoints.append(tp); + m_lastReport.insert(slot.trackingId, QPoint(slot.x, slot.y)); + } + if (m_slots.count() - ignoredSlotCount == 0) + m_state = QEvent::TouchEnd; + + // Skip if state is TouchUpdate and all points are Stationary. + bool skip = false; + if (m_state == QEvent::TouchUpdate) { + skip = true; + for (int i = 0; i < m_touchPoints.count(); ++i) + if (m_touchPoints.at(i).state != Qt::TouchPointStationary) { + skip = false; + break; + } + } + + // ### TODO Add timestamps and remove points that stay unchanged for too long. + // The user's finger may fall off the touchscreen, which means there will be + // no released event sent ever for that particular point. + +#ifdef POINT_DEBUG + qDebug() << m_touchPoints.count() << "touchpoints, event type" << m_state; + for (int i = 0; i < m_touchPoints.count(); ++i) + qDebug() << " " << m_touchPoints[i].id << m_touchPoints[i].state << m_touchPoints[i].area; +#endif + + if (!skip && !(m_state == m_prevState && m_state == QEvent::TouchEnd)) + for (int i = 0; i < m_observers.count(); ++i) + m_observers.at(i)->touch_point(m_state, m_touchPoints); + + for (int i = 0; i < keys.count(); ++i) { + Slot &slot(m_slots[keys.at(i)]); + if (slot.state == Qt::TouchPointPressed) + slot.state = Qt::TouchPointMoved; + } + m_prevState = m_state; + if (m_state == QEvent::TouchBegin) + m_state = QEvent::TouchUpdate; + else if (m_state == QEvent::TouchEnd) + m_state = QEvent::TouchBegin; + } +} + + +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 new file mode 100644 index 0000000000..915a213d41 --- /dev/null +++ b/src/plugins/generic/touchscreen/qtouchscreen.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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 + +struct mtdev; + +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) = 0; + virtual void touch_point(QEvent::Type state, 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; + mtdev *m_mtdev; + 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 new file mode 100644 index 0000000000..26725190b0 --- /dev/null +++ b/src/plugins/generic/touchscreen/touchscreen.pro @@ -0,0 +1,18 @@ +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 -lmtdev -- cgit v1.2.3