summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Pokrzywka <romain.pokrzywka@bluescape.com>2015-09-22 11:38:09 -0700
committerRomain Pokrzywka <romain.pokrzywka@gmail.com>2015-09-23 16:29:30 +0000
commit68ea2f7e9bb2d4ea6182101521325dbfd9b74abb (patch)
tree567634fce8b3e51cdd8fee16eef6048b9359c561
parent29bc68cf169b8cf87d306a1c72e12eb9b6fbfce7 (diff)
Synchronize QInputDeviceManager touch device count with QTouchDevice
This ensures that the values and signals reported by QInputDeviceManager for touch devices always have corresponding entries in the list returned by QTouchDevice::devices(). It also adds proper QTouchDevice unregistration when the underlying input device gets removed by the evdevtouch QPA plugin. Change-Id: I7bdf2f7435c775d15bddce8ba1e731afdc1d948a Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
-rw-r--r--src/gui/kernel/qtouchdevice.cpp11
-rw-r--r--src/gui/kernel/qtouchdevice_p.h1
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp7
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h3
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp83
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h20
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp27
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h2
8 files changed, 120 insertions, 34 deletions
diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp
index 9d19fa4b92..266b5308a2 100644
--- a/src/gui/kernel/qtouchdevice.cpp
+++ b/src/gui/kernel/qtouchdevice.cpp
@@ -237,6 +237,17 @@ void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
deviceList()->append(dev);
}
+/*!
+ \internal
+ */
+void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
+{
+ QMutexLocker lock(&devicesMutex);
+ bool wasRemoved = deviceList()->removeOne(dev);
+ if (wasRemoved && deviceList()->isEmpty())
+ qRemovePostRoutine(cleanupDevicesList);
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QTouchDevice *device)
{
diff --git a/src/gui/kernel/qtouchdevice_p.h b/src/gui/kernel/qtouchdevice_p.h
index 4aff8f2f33..63b83d33ec 100644
--- a/src/gui/kernel/qtouchdevice_p.h
+++ b/src/gui/kernel/qtouchdevice_p.h
@@ -65,6 +65,7 @@ public:
int maxTouchPoints;
static void registerDevice(const QTouchDevice *dev);
+ static void unregisterDevice(const QTouchDevice *dev);
static bool isRegistered(const QTouchDevice *dev);
};
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 91a935ad0f..faa1ff8068 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -486,11 +486,16 @@ bool QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfa
return accepted;
}
-void QWindowSystemInterface::registerTouchDevice(QTouchDevice *device)
+void QWindowSystemInterface::registerTouchDevice(const QTouchDevice *device)
{
QTouchDevicePrivate::registerDevice(device);
}
+void QWindowSystemInterface::unregisterTouchDevice(const QTouchDevice *device)
+{
+ QTouchDevicePrivate::unregisterDevice(device);
+}
+
void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device,
const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
{
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 99589e8aa1..97bd087b53 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -127,7 +127,8 @@ public:
QVector<QPointF> rawPositions; // in screen coordinates
};
- static void registerTouchDevice(QTouchDevice *device);
+ static void registerTouchDevice(const QTouchDevice *device);
+ static void unregisterTouchDevice(const QTouchDevice *device);
static void handleTouchEvent(QWindow *w, QTouchDevice *device,
const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier);
static void handleTouchEvent(QWindow *w, ulong timestamp, QTouchDevice *device,
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
index 5560d910ac..ad348cc083 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
@@ -107,9 +107,8 @@ public:
int m_currentSlot;
int findClosestContact(const QHash<int, Contact> &contacts, int x, int y, int *dist);
- void reportPoints();
- void registerDevice();
void addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates);
+ void reportPoints();
int hw_range_x_min;
int hw_range_x_max;
@@ -119,7 +118,6 @@ public:
int hw_pressure_max;
QString hw_name;
bool m_forceToActiveWindow;
- QTouchDevice *m_device;
bool m_typeB;
QTransform m_rotate;
bool m_singleTouch;
@@ -132,23 +130,11 @@ QEvdevTouchScreenData::QEvdevTouchScreenData(QEvdevTouchScreenHandler *q_ptr, co
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_device(0), m_typeB(false), m_singleTouch(false)
+ m_typeB(false), m_singleTouch(false)
{
m_forceToActiveWindow = args.contains(QLatin1String("force_window"));
}
-void QEvdevTouchScreenData::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);
-}
-
#define LONG_BITS (sizeof(long) << 3)
#define NUM_LONGS(bits) (((bits) + LONG_BITS - 1) / LONG_BITS)
@@ -160,9 +146,9 @@ static inline bool testBit(long bit, const long *array)
#endif
QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const QString &spec, QObject *parent)
- : QObject(parent), m_notify(0), m_fd(-1), d(0)
+ : QObject(parent), m_notify(Q_NULLPTR), m_fd(-1), d(Q_NULLPTR), m_device(Q_NULLPTR)
#if !defined(QT_NO_MTDEV)
- , m_mtdev(0)
+ , m_mtdev(Q_NULLPTR)
#endif
{
setObjectName(QLatin1String("Evdev Touch Handler"));
@@ -299,7 +285,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const
if (inverty)
d->m_rotate *= QTransform::fromTranslate(0.5, 0.5).scale(1.0, -1.0).translate(-0.5, -0.5);
- d->registerDevice();
+ registerTouchDevice();
}
QEvdevTouchScreenHandler::~QEvdevTouchScreenHandler()
@@ -315,6 +301,13 @@ QEvdevTouchScreenHandler::~QEvdevTouchScreenHandler()
QT_CLOSE(m_fd);
delete d;
+
+ unregisterTouchDevice();
+}
+
+QTouchDevice *QEvdevTouchScreenHandler::touchDevice() const
+{
+ return m_device;
}
void QEvdevTouchScreenHandler::readData()
@@ -368,15 +361,44 @@ err:
qErrnoWarning(errno, "evdevtouch: Could not read from input device");
if (errno == ENODEV) { // device got disconnected -> stop reading
delete m_notify;
- m_notify = 0;
+ m_notify = Q_NULLPTR;
+
QT_CLOSE(m_fd);
m_fd = -1;
+
+ unregisterTouchDevice();
}
return;
}
}
}
+void QEvdevTouchScreenHandler::registerTouchDevice()
+{
+ if (m_device)
+ return;
+
+ m_device = new QTouchDevice;
+ m_device->setName(d->hw_name);
+ m_device->setType(QTouchDevice::TouchScreen);
+ m_device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area);
+ if (d->hw_pressure_max > d->hw_pressure_min)
+ m_device->setCapabilities(m_device->capabilities() | QTouchDevice::Pressure);
+
+ QWindowSystemInterface::registerTouchDevice(m_device);
+}
+
+void QEvdevTouchScreenHandler::unregisterTouchDevice()
+{
+ if (!m_device)
+ return;
+
+ QWindowSystemInterface::unregisterTouchDevice(m_device);
+
+ delete m_device;
+ m_device = Q_NULLPTR;
+}
+
void QEvdevTouchScreenData::addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates)
{
QWindowSystemInterface::TouchPoint tp;
@@ -639,12 +661,12 @@ void QEvdevTouchScreenData::reportPoints()
tp.pressure = (tp.pressure - hw_pressure_min) / qreal(hw_pressure_max - hw_pressure_min);
}
- QWindowSystemInterface::handleTouchEvent(0, m_device, m_touchPoints);
+ QWindowSystemInterface::handleTouchEvent(Q_NULLPTR, q->touchDevice(), m_touchPoints);
}
QEvdevTouchScreenHandlerThread::QEvdevTouchScreenHandlerThread(const QString &device, const QString &spec, QObject *parent)
- : QDaemonThread(parent), m_device(device), m_spec(spec), m_handler(0)
+ : QDaemonThread(parent), m_device(device), m_spec(spec), m_handler(Q_NULLPTR), m_touchDeviceRegistered(false)
{
start();
}
@@ -658,9 +680,24 @@ QEvdevTouchScreenHandlerThread::~QEvdevTouchScreenHandlerThread()
void QEvdevTouchScreenHandlerThread::run()
{
m_handler = new QEvdevTouchScreenHandler(m_device, m_spec);
+ // Report the registration to the parent thread by invoking the method asynchronously
+ QMetaObject::invokeMethod(this, "notifyTouchDeviceRegistered", Qt::QueuedConnection);
+
exec();
+
delete m_handler;
- m_handler = 0;
+ m_handler = Q_NULLPTR;
+}
+
+bool QEvdevTouchScreenHandlerThread::isTouchDeviceRegistered() const
+{
+ return m_touchDeviceRegistered;
+}
+
+void QEvdevTouchScreenHandlerThread::notifyTouchDeviceRegistered()
+{
+ m_touchDeviceRegistered = true;
+ emit touchDeviceRegistered();
}
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h b/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h
index 8e7dfe59bb..ca9756d5de 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h
@@ -66,16 +66,22 @@ class QEvdevTouchScreenHandler : public QObject
Q_OBJECT
public:
- explicit QEvdevTouchScreenHandler(const QString &device, const QString &spec = QString(), QObject *parent = 0);
+ explicit QEvdevTouchScreenHandler(const QString &device, const QString &spec = QString(), QObject *parent = Q_NULLPTR);
~QEvdevTouchScreenHandler();
+ QTouchDevice *touchDevice() const;
+
private slots:
void readData();
private:
+ void registerTouchDevice();
+ void unregisterTouchDevice();
+
QSocketNotifier *m_notify;
int m_fd;
QEvdevTouchScreenData *d;
+ QTouchDevice *m_device;
#if !defined(QT_NO_MTDEV)
mtdev *m_mtdev;
#endif
@@ -83,16 +89,24 @@ private:
class QEvdevTouchScreenHandlerThread : public QDaemonThread
{
+ Q_OBJECT
public:
- explicit QEvdevTouchScreenHandlerThread(const QString &device, const QString &spec, QObject *parent = 0);
+ explicit QEvdevTouchScreenHandlerThread(const QString &device, const QString &spec, QObject *parent = Q_NULLPTR);
~QEvdevTouchScreenHandlerThread();
void run() Q_DECL_OVERRIDE;
- QEvdevTouchScreenHandler *handler() { return m_handler; }
+
+ bool isTouchDeviceRegistered() const;
+
+signals:
+ void touchDeviceRegistered();
private:
+ Q_INVOKABLE void notifyTouchDeviceRegistered();
+
QString m_device;
QString m_spec;
QEvdevTouchScreenHandler *m_handler;
+ bool m_touchDeviceRegistered;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp
index 98fc83700c..35a685ff21 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp
@@ -91,17 +91,17 @@ QEvdevTouchManager::QEvdevTouchManager(const QString &key, const QString &specif
QEvdevTouchManager::~QEvdevTouchManager()
{
qDeleteAll(m_activeDevices);
+ updateInputDeviceCount();
}
void QEvdevTouchManager::addDevice(const QString &deviceNode)
{
- qCDebug(qLcEvdevTouch) << "Adding device at" << deviceNode;
+ qCDebug(qLcEvdevTouch) << "evdevtouch: Adding device at" << deviceNode;
QEvdevTouchScreenHandlerThread *handler;
handler = new QEvdevTouchScreenHandlerThread(deviceNode, m_spec);
if (handler) {
m_activeDevices.insert(deviceNode, handler);
- QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount(
- QInputDeviceManager::DeviceTypeTouch, m_activeDevices.count());
+ connect(handler, &QEvdevTouchScreenHandlerThread::touchDeviceRegistered, this, &QEvdevTouchManager::updateInputDeviceCount);
} else {
qWarning("evdevtouch: Failed to open touch device %s", qPrintable(deviceNode));
}
@@ -110,13 +110,28 @@ void QEvdevTouchManager::addDevice(const QString &deviceNode)
void QEvdevTouchManager::removeDevice(const QString &deviceNode)
{
if (m_activeDevices.contains(deviceNode)) {
- qCDebug(qLcEvdevTouch) << "Removing device at" << deviceNode;
+ qCDebug(qLcEvdevTouch) << "evdevtouch: Removing device at" << deviceNode;
QEvdevTouchScreenHandlerThread *handler = m_activeDevices.value(deviceNode);
m_activeDevices.remove(deviceNode);
- QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount(
- QInputDeviceManager::DeviceTypeTouch, m_activeDevices.count());
delete handler;
+
+ updateInputDeviceCount();
}
}
+void QEvdevTouchManager::updateInputDeviceCount()
+{
+ int registeredTouchDevices = 0;
+ Q_FOREACH (QEvdevTouchScreenHandlerThread *handler, m_activeDevices) {
+ if (handler->isTouchDeviceRegistered())
+ ++registeredTouchDevices;
+ }
+
+ qCDebug(qLcEvdevTouch) << "evdevtouch: Updating QInputDeviceManager device count:" << registeredTouchDevices << " touch devices,"
+ << m_activeDevices.count() - registeredTouchDevices << "pending handler(s)" ;
+
+ QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount(
+ QInputDeviceManager::DeviceTypeTouch, registeredTouchDevices);
+}
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h b/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h
index bf484fd88b..289c345ac4 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h
@@ -65,6 +65,8 @@ private slots:
void addDevice(const QString &deviceNode);
void removeDevice(const QString &deviceNode);
+ void updateInputDeviceCount();
+
private:
QString m_spec;
QDeviceDiscovery *m_deviceDiscovery;