summaryrefslogtreecommitdiffstats
path: root/src/plugins/generic
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>2011-07-18 13:44:47 +0300
committerQt by Nokia <qt-info@nokia.com>2011-07-19 15:00:46 +0200
commitba1b6f16ae042e5fdeb2e2c5968e1e5b1834ab88 (patch)
tree1a4c08b41efbe4f7f5a6f9ecf89a6e03847884e6 /src/plugins/generic
parent9581c90395086932d2e853864bf962b0896597d5 (diff)
Implement todos in touchscreen generic plug-in.
The patch implements periodic clearing of the point states when no activity occurs (i.e. no ev_syn is coming at all, meaning that most probably all the fingers are already up) and also moves the entire functionality into a separate thread even when used as a plug-in. Change-Id: Ib1daa738085b61af9b07eb8a284416e5a3fcabe8 Reviewed-on: http://codereview.qt.nokia.com/1744 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Diffstat (limited to 'src/plugins/generic')
-rw-r--r--src/plugins/generic/touchscreen/README6
-rw-r--r--src/plugins/generic/touchscreen/main.cpp4
-rw-r--r--src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp27
-rw-r--r--src/plugins/generic/touchscreen/qtoucheventsenderqpa.h2
-rw-r--r--src/plugins/generic/touchscreen/qtouchscreen.cpp50
-rw-r--r--src/plugins/generic/touchscreen/qtouchscreen.h1
6 files changed, 62 insertions, 28 deletions
diff --git a/src/plugins/generic/touchscreen/README b/src/plugins/generic/touchscreen/README
index 76f695371d..25e0e1abe8 100644
--- a/src/plugins/generic/touchscreen/README
+++ b/src/plugins/generic/touchscreen/README
@@ -14,9 +14,9 @@ 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.
+screen. If this is not desired, pass force_window in the plugin
+specification. This will cause mapping the touch surface to the active
+window instead.
Only touch events are generated (via
QWindowSystemInterface::handleTouchEvent), mouse events are not. This
diff --git a/src/plugins/generic/touchscreen/main.cpp b/src/plugins/generic/touchscreen/main.cpp
index 8ad756355d..ff476d1648 100644
--- a/src/plugins/generic/touchscreen/main.cpp
+++ b/src/plugins/generic/touchscreen/main.cpp
@@ -67,8 +67,8 @@ 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);
+ QTouchScreenObserver *obs = new QTouchEventSenderQPA(spec);
+ QTouchScreenHandlerThread *h = new QTouchScreenHandlerThread(spec, obs);
return h;
}
diff --git a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp
index 7dff55b1bc..cd11f44bed 100644
--- a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp
+++ b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp
@@ -47,7 +47,11 @@
QT_BEGIN_NAMESPACE
//#define POINT_DEBUG
-//#define FORCE_TO_ACTIVE_WINDOW
+
+QTouchEventSenderQPA::QTouchEventSenderQPA(const QString &spec)
+{
+ m_forceToActiveWindow = spec.split(QLatin1Char(':')).contains(QLatin1String("force_window"));
+}
void QTouchEventSenderQPA::touch_configure(int x_min, int x_max, int y_min, int y_max)
{
@@ -60,21 +64,18 @@ void QTouchEventSenderQPA::touch_configure(int x_min, int x_max, int y_min, int
void QTouchEventSenderQPA::touch_point(QEvent::Type state,
const QList<QWindowSystemInterface::TouchPoint> &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;
+ QRect winRect;
+ if (m_forceToActiveWindow) {
+ QWidget *win = QApplication::activeWindow(); // ### migrate to QWindow later on
+ if (!win)
+ return;
+ winRect = win->geometry();
+ } else {
+ winRect = QApplication::desktop()->screenGeometry();
}
- const QRect winRect = win->geometry();
-#else
- const QRect winRect = QApplication::desktop()->screenGeometry();
-#endif
#ifdef POINT_DEBUG
- qDebug() << points.size() << "points" << winRect << state;
+ qDebug() << "QPA: Mapping" << points.size() << "points to" << winRect << state;
#endif
QList<QWindowSystemInterface::TouchPoint> touchPoints = points;
diff --git a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h
index 68d621a4e5..91a6b4f3bb 100644
--- a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h
+++ b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h
@@ -51,10 +51,12 @@ QT_BEGIN_NAMESPACE
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);
void touch_point(QEvent::Type state, const QList<QWindowSystemInterface::TouchPoint> &points);
private:
+ bool m_forceToActiveWindow;
int hw_range_x_min;
int hw_range_x_max;
int hw_range_y_min;
diff --git a/src/plugins/generic/touchscreen/qtouchscreen.cpp b/src/plugins/generic/touchscreen/qtouchscreen.cpp
index 2bbed6a62f..2a56ac3451 100644
--- a/src/plugins/generic/touchscreen/qtouchscreen.cpp
+++ b/src/plugins/generic/touchscreen/qtouchscreen.cpp
@@ -43,6 +43,7 @@
#include <QStringList>
#include <QSocketNotifier>
#include <QtCore/private/qcore_unix_p.h>
+#include <QTimer>
#include <QDebug>
#include <libudev.h>
@@ -58,9 +59,9 @@ QT_BEGIN_NAMESPACE
class QTouchScreenData
{
public:
- QTouchScreenData(QTouchScreenHandler *q_ptr);
+ QTouchScreenData(QTouchScreenHandler *q_ptr, const QStringList &args);
- void handle(input_event *data);
+ void processInputEvent(input_event *data);
QTouchScreenHandler *q;
QEvent::Type m_state;
@@ -78,6 +79,8 @@ public:
QMap<int, Slot> m_slots;
QMap<int, QPoint> m_lastReport;
int m_currentSlot;
+ QTimer m_clearTimer;
+ bool m_clearTimerEnabled;
int hw_range_x_min;
int hw_range_x_max;
@@ -88,7 +91,7 @@ public:
QList<QTouchScreenObserver *> m_observers;
};
-QTouchScreenData::QTouchScreenData(QTouchScreenHandler *q_ptr)
+QTouchScreenData::QTouchScreenData(QTouchScreenHandler *q_ptr, const QStringList &args)
: q(q_ptr),
m_state(QEvent::TouchBegin),
m_prevState(m_state),
@@ -96,6 +99,15 @@ QTouchScreenData::QTouchScreenData(QTouchScreenHandler *q_ptr)
hw_range_x_min(0), hw_range_x_max(0),
hw_range_y_min(0), hw_range_y_max(0)
{
+ m_clearTimerEnabled = !args.contains(QLatin1String("no_timeout"));
+ if (m_clearTimerEnabled) {
+ QObject::connect(&m_clearTimer, SIGNAL(timeout()), q, SLOT(onTimeout()));
+ m_clearTimer.setSingleShot(true);
+ m_clearTimer.setInterval(2000); // default timeout is 2 seconds
+ for (int i = 0; i < args.count(); ++i)
+ if (args.at(i).startsWith(QLatin1String("timeout=")))
+ m_clearTimer.setInterval(args.at(i).mid(8).toInt());
+ }
}
QTouchScreenHandler::QTouchScreenHandler(const QString &spec)
@@ -130,7 +142,7 @@ QTouchScreenHandler::QTouchScreenHandler(const QString &spec)
return;
}
- d = new QTouchScreenData(this);
+ d = new QTouchScreenData(this, args);
input_absinfo absInfo;
memset(&absInfo, 0, sizeof(input_absinfo));
@@ -203,12 +215,25 @@ void QTouchScreenHandler::readData()
} else if (n > 0) {
for (int i = 0; i < n; ++i) {
input_event *data = &buffer[i];
- d->handle(data);
+ d->processInputEvent(data);
}
}
}
-void QTouchScreenData::handle(input_event *data)
+void QTouchScreenHandler::onTimeout()
+{
+#ifdef POINT_DEBUG
+ qDebug("TIMEOUT (%d slots)", d->m_slots.count());
+#endif
+ d->m_slots.clear();
+ if (d->m_state != QEvent::TouchEnd)
+ for (int i = 0; i < d->m_observers.count(); ++i)
+ d->m_observers.at(i)->touch_point(QEvent::TouchEnd,
+ QList<QWindowSystemInterface::TouchPoint>());
+ d->m_state = QEvent::TouchBegin;
+}
+
+void QTouchScreenData::processInputEvent(input_event *data)
{
if (data->type == EV_ABS) {
if (data->code == ABS_MT_POSITION_X) {
@@ -233,6 +258,8 @@ void QTouchScreenData::handle(input_event *data)
m_slots[m_currentSlot].state = Qt::TouchPointReleased;
}
} else if (data->type == EV_SYN && data->code == SYN_REPORT) {
+ if (m_clearTimerEnabled)
+ m_clearTimer.stop();
m_touchPoints.clear();
QList<int> keys = m_slots.keys();
int ignoredSlotCount = 0;
@@ -270,10 +297,6 @@ void QTouchScreenData::handle(input_event *data)
}
}
- // ### 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)
@@ -294,6 +317,13 @@ void QTouchScreenData::handle(input_event *data)
m_state = QEvent::TouchUpdate;
else if (m_state == QEvent::TouchEnd)
m_state = QEvent::TouchBegin;
+
+ // The user's finger may fall off the touchscreen which in some rare
+ // cases may mean there will be no released event ever received for that
+ // particular point. Use a timer to clear all points when no activity
+ // occurs for a certain period of time.
+ if (m_clearTimerEnabled && m_state != QEvent::TouchBegin)
+ m_clearTimer.start();
}
}
diff --git a/src/plugins/generic/touchscreen/qtouchscreen.h b/src/plugins/generic/touchscreen/qtouchscreen.h
index 915a213d41..80a6d3ac58 100644
--- a/src/plugins/generic/touchscreen/qtouchscreen.h
+++ b/src/plugins/generic/touchscreen/qtouchscreen.h
@@ -75,6 +75,7 @@ public:
private slots:
void readData();
+ void onTimeout();
private:
void try_udev(QString *path);