summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/input/evdevtouch
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-08-09 15:48:12 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2016-08-11 21:11:43 +0000
commitdfae6a7593a6bb4ad6accc30d6aaf01a98bc2a6f (patch)
tree612de4a8c99bb1a9cfe49e8daf9e6712e1622dbb /src/platformsupport/input/evdevtouch
parent2afead0211302799519abee5c164ae0602a7e13b (diff)
evdevtouch: Enable touch in multi-screen eglfs environments
Parse the touchDevice property from the KMS/DRM config file. When all outputs have an explicitly specified index in the virtual desktop, we can set up a mapping between the device node and the screen index. It is somewhat fragile (device nodes may change, requires explicit virtualIndex properties for all outputs, etc.) but better than nothing. For example, having the screen on DisplayPort as primary and the touchscreen on HDMI as the secondary screen breaks by default because touching the second screen generates touch (and synthesized mouse) events for the first screen. Assuming the touchscreen is /dev/input/event5, the issue can now be fixed by setting QT_QPA_EGLFS_KMS_CONFIG with a configuration like the following: { "device": "drm-nvdc", "outputs": [ { "name": "HDMI1", "touchDevice": "/dev/input/event5", "virtualIndex": 1 }, { "name": "DP1", "virtualIndex": 0 } ] } Task-number: QTBUG-54151 Change-Id: If97fa18a65599ccfe64ce408ea43086ec3863682 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/platformsupport/input/evdevtouch')
-rw-r--r--src/platformsupport/input/evdevtouch/evdevtouch.pri3
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp40
2 files changed, 38 insertions, 5 deletions
diff --git a/src/platformsupport/input/evdevtouch/evdevtouch.pri b/src/platformsupport/input/evdevtouch/evdevtouch.pri
index c2edc13143..44eb9da113 100644
--- a/src/platformsupport/input/evdevtouch/evdevtouch.pri
+++ b/src/platformsupport/input/evdevtouch/evdevtouch.pri
@@ -6,6 +6,8 @@ SOURCES += \
$$PWD/qevdevtouchhandler.cpp \
$$PWD/qevdevtouchmanager.cpp
+INCLUDEPATH += $$PWD/../shared
+
contains(QT_CONFIG, libudev) {
LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV
}
@@ -14,4 +16,3 @@ contains(QT_CONFIG, mtdev) {
CONFIG += link_pkgconfig
PKGCONFIG_PRIVATE += mtdev
}
-
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
index 6b98ed30a9..5f9455559d 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qevdevtouchhandler_p.h"
+#include "qtouchoutputmapping_p.h"
#include <QStringList>
#include <QHash>
#include <QSocketNotifier>
@@ -116,6 +117,7 @@ public:
int findClosestContact(const QHash<int, Contact> &contacts, int x, int y, int *dist);
void addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates);
void reportPoints();
+ void loadMultiScreenMappings();
int hw_range_x_min;
int hw_range_x_max;
@@ -124,10 +126,12 @@ public:
int hw_pressure_min;
int hw_pressure_max;
QString hw_name;
+ QString deviceNode;
bool m_forceToActiveWindow;
bool m_typeB;
QTransform m_rotate;
bool m_singleTouch;
+ int m_screenIndex;
};
QEvdevTouchScreenData::QEvdevTouchScreenData(QEvdevTouchScreenHandler *q_ptr, const QStringList &args)
@@ -137,7 +141,8 @@ 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_typeB(false), m_singleTouch(false)
+ m_typeB(false), m_singleTouch(false),
+ m_screenIndex(-1)
{
m_forceToActiveWindow = args.contains(QLatin1String("force_window"));
}
@@ -222,7 +227,9 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const
}
#endif
- qCDebug(qLcEvdevTouch, "evdevtouch: %s: Protocol type %c %s (%s)", qPrintable(device),
+ d->deviceNode = device;
+
+ qCDebug(qLcEvdevTouch, "evdevtouch: %s: Protocol type %c %s (%s)", qPrintable(d->deviceNode),
d->m_typeB ? 'B' : 'A', mtdevStr, d->m_singleTouch ? "single" : "multi");
input_absinfo absInfo;
@@ -292,6 +299,14 @@ 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);
+ QTouchOutputMapping mapping;
+ if (mapping.load()) {
+ d->m_screenIndex = mapping.screenIndexForDeviceNode(d->deviceNode);
+ if (d->m_screenIndex >= 0)
+ qCDebug(qLcEvdevTouch, "evdevtouch: Mapping device %s to screen index %d",
+ qPrintable(d->deviceNode), d->m_screenIndex);
+ }
+
registerTouchDevice();
}
@@ -643,8 +658,23 @@ void QEvdevTouchScreenData::reportPoints()
return;
winRect = QHighDpi::toNativePixels(win->geometry(), win);
} else {
- QScreen *primary = QGuiApplication::primaryScreen();
- winRect = QHighDpi::toNativePixels(primary->geometry(), primary);
+ // Now it becomes tricky. Traditionally we picked the primaryScreen()
+ // and were done with it. But then, enter multiple screens, and
+ // suddenly it was all broken.
+ //
+ // For now we only support the display configuration of the KMS/DRM
+ // backends of eglfs. See QTouchOutputMapping.
+ //
+ // The good news it that once winRect refers to the correct screen
+ // geometry in the full virtual desktop space, there is nothing else
+ // left to do since qguiapp will handle the rest.
+ QScreen *screen = QGuiApplication::primaryScreen();
+ if (m_screenIndex >= 0) {
+ const QList<QScreen *> screens = QGuiApplication::screens();
+ if (m_screenIndex < screens.count())
+ screen = screens.at(m_screenIndex);
+ }
+ winRect = QHighDpi::toNativePixels(screen->geometry(), screen);
}
const int hw_w = hw_range_x_max - hw_range_x_min;
@@ -675,10 +705,12 @@ void QEvdevTouchScreenData::reportPoints()
tp.pressure = (tp.pressure - hw_pressure_min) / qreal(hw_pressure_max - hw_pressure_min);
}
+ // Let qguiapp pick the target window.
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(Q_NULLPTR), m_touchDeviceRegistered(false)
{