summaryrefslogtreecommitdiffstats
path: root/src/platformsupport
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 /src/platformsupport
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>
Diffstat (limited to 'src/platformsupport')
-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
4 files changed, 100 insertions, 32 deletions
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;