summaryrefslogtreecommitdiffstats
path: root/src/plugins/generic/evdevtouch
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>2012-02-05 13:32:40 +0200
committerQt by Nokia <qt-info@nokia.com>2012-02-08 03:13:18 +0100
commit684a1559f0de4354cd9427e4c9a86e4a6a4e238a (patch)
treedf297299e0a3683977a7fbee8dd9c345cfebc368 /src/plugins/generic/evdevtouch
parent009cd671ec5a51ab360bce39262482ee1b86dc46 (diff)
Reorganize evdev plugins
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 <oswald.buddenhagen@nokia.com> Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Diffstat (limited to 'src/plugins/generic/evdevtouch')
-rw-r--r--src/plugins/generic/evdevtouch/70-qtouchscreen.rules1
-rw-r--r--src/plugins/generic/evdevtouch/README36
-rw-r--r--src/plugins/generic/evdevtouch/evdevtouch.pro14
-rw-r--r--src/plugins/generic/evdevtouch/main.cpp76
-rw-r--r--src/plugins/generic/evdevtouch/qevdevtouch.cpp419
-rw-r--r--src/plugins/generic/evdevtouch/qevdevtouch.h94
6 files changed, 640 insertions, 0 deletions
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 <device> <device enabled property> 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 <qgenericplugin_qpa.h>
+#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 <QStringList>
+#include <QHash>
+#include <QSocketNotifier>
+#include <QGuiApplication>
+#include <QDebug>
+#include <QtCore/private/qcore_unix_p.h>
+#include <QtPlatformSupport/private/qudevhelper_p.h>
+#include <linux/input.h>
+
+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<QWindowSystemInterface::TouchPoint> 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<int, Contact> m_contacts, m_lastContacts;
+ Contact m_currentData;
+
+ int findClosestContact(const QHash<int, Contact> &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<char*>(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<int, Contact> 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<int, Contact> &contacts, int x, int y, int *dist)
+{
+ int minDist = -1, id = -1;
+ for (QHash<int, Contact>::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<int, Contact> candidates = m_lastContacts, pending = m_contacts, newContacts;
+ int maxId = -1;
+ QHash<int, Contact>::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 <QObject>
+#include <QString>
+#include <QList>
+#include <QThread>
+#include <QWindowSystemInterface>
+
+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