8#include <QtGui/QGuiApplication>
9#include <QtGui/QPointingDevice>
10#include <QtGui/QScreen>
11#include <QtGui/QPointingDevice>
12#include <QtGui/private/qhighdpiscaling_p.h>
13#include <QtGui/private/qpointingdevice_p.h>
19QWindowSystemInterface::TouchPoint *QLibInputTouch::DeviceState::point(int32_t slot)
21 const int id = qMax(0, slot);
23 for (
int i = 0; i < m_points.size(); ++i)
24 if (m_points.at(i).id == id)
32 libinput_device *dev = libinput_event_get_device(libinput_event_touch_get_base_event(e));
33 return &m_devState[dev];
38 QScreen *screen = QGuiApplication::primaryScreen();
39 if (!state->m_screenName.isEmpty()) {
41 const QList<QScreen *> screens = QGuiApplication::screens();
42 for (QScreen *s : screens) {
43 if (s->name() == state->m_screenName) {
52 return screen ? QHighDpi::toNativePixels(screen->geometry(), screen) : QRect();
57 DeviceState *state = deviceState(e);
58 QRect geom = screenGeometry(state);
59 const double x = libinput_event_touch_get_x_transformed(e, geom.width());
60 const double y = libinput_event_touch_get_y_transformed(e, geom.height());
61 return geom.topLeft() + QPointF(x, y);
66 if (libinput_device_config_calibration_has_matrix(dev)) {
67 QByteArray env = qgetenv(
"QT_QPA_LIBINPUT_TOUCH_MATRIX");
68 env = env.simplified();
71 QList<QByteArray> list = env.split(
' ');
72 if (list.length() != 6) {
73 qCWarning(qLcLibInput,
"matrix length %" PRIdQSIZETYPE
" wrong, should be 6",
77 for (
int i = 0; i < 6; i++) {
79 matrix[i] = list[i].toFloat(&ok);
81 qCWarning(qLcLibInput,
"Invalid matrix entry %d %s ", i, list[i].constData());
85 if (libinput_device_config_calibration_set_matrix(dev, matrix) != LIBINPUT_CONFIG_STATUS_SUCCESS)
86 qCWarning(qLcLibInput,
"Failed to set libinput calibration matrix ");
89 qCWarning(qLcLibInput,
"Touch device doesn't support matrix");
94 struct udev_device *udev_device;
95 udev_device = libinput_device_get_udev_device(dev);
96 QString devNode = QString::fromUtf8(udev_device_get_devnode(udev_device));
97 QString devName = QString::fromUtf8(libinput_device_get_name(dev));
99 qCDebug(qLcLibInput,
"libinput: registerDevice %s - %s",
100 qPrintable(devNode), qPrintable(devName));
105 m_devState[dev].m_screenName = mapping->screenNameForDeviceNode(devNode);
106 if (!m_devState[dev].m_screenName.isEmpty()) {
107 geom = screenGeometry(&m_devState[dev]);
108 qCDebug(qLcLibInput) <<
"libinput: Mapping device" << devNode
109 <<
"to screen" << m_devState[dev].m_screenName
110 <<
"with geometry" << geom;
114 QPointingDevice *&td = m_devState[dev].m_touchDevice;
115 td =
new QPointingDevice(devName, udev_device_get_devnum(udev_device),
116 QInputDevice::DeviceType::TouchScreen, QPointingDevice::PointerType::Finger,
117 QPointingDevice::Capability::Position | QPointingDevice::Capability::Area, 16, 0);
118 auto devPriv = QPointingDevicePrivate::get(td);
119 devPriv->busId = QString::fromLocal8Bit(udev_device_get_syspath(udev_device));
121 devPriv->setAvailableVirtualGeometry(geom);
122 QWindowSystemInterface::registerInputDevice(td);
134 int slot = libinput_event_touch_get_slot(e);
135 DeviceState *state = deviceState(e);
136 QWindowSystemInterface::TouchPoint *tp = state->point(slot);
138 qWarning(
"Incorrect touch state");
140 QWindowSystemInterface::TouchPoint newTp;
141 newTp.id = qMax(0, slot);
142 newTp.state = QEventPoint::State::Pressed;
143 newTp.area = QRect(0, 0, 8, 8);
144 newTp.area.moveCenter(getPos(e));
145 state->m_points.append(newTp);
146 qCDebug(qLcLibInputEvents) <<
"touch down" << newTp;
152 int slot = libinput_event_touch_get_slot(e);
153 DeviceState *state = deviceState(e);
154 QWindowSystemInterface::TouchPoint *tp = state->point(slot);
156 QEventPoint::State tmpState = QEventPoint::State::Updated;
157 const QPointF p = getPos(e);
158 if (tp->area.center() == p)
159 tmpState = QEventPoint::State::Stationary;
161 tp->area.moveCenter(p);
164 if (tp->state != QEventPoint::State::Pressed && tp->state != QEventPoint::State::Released)
165 tp->state = tmpState;
166 qCDebug(qLcLibInputEvents) <<
"touch move" << tp;
168 qWarning(
"Inconsistent touch state (got 'motion' without 'down')");
174 int slot = libinput_event_touch_get_slot(e);
175 DeviceState *state = deviceState(e);
176 QWindowSystemInterface::TouchPoint *tp = state->point(slot);
178 tp->state = QEventPoint::State::Released;
180 QEventPoint::States s;
181 for (
int i = 0; i < state->m_points.size(); ++i)
182 s |= state->m_points.at(i).state;
183 qCDebug(qLcLibInputEvents) <<
"touch up" << s << tp;
184 if (s == QEventPoint::State::Released)
187 qCDebug(qLcLibInputEvents,
"waiting for all points to be released");
189 qWarning(
"Inconsistent touch state (got 'up' without 'down')");
195 DeviceState *state = deviceState(e);
196 qCDebug(qLcLibInputEvents) <<
"touch cancel" << state->m_points;
197 if (state->m_touchDevice)
198 QWindowSystemInterface::handleTouchCancelEvent(
nullptr, state->m_touchDevice, QGuiApplication::keyboardModifiers());
200 qWarning(
"TouchCancel without registered device");
205 DeviceState *state = deviceState(e);
206 if (!state->m_touchDevice) {
207 qWarning(
"TouchFrame without registered device");
210 qCDebug(qLcLibInputEvents) <<
"touch frame" << state->m_points;
211 if (state->m_points.isEmpty())
214 QWindowSystemInterface::handleTouchEvent(
nullptr, state->m_touchDevice, state->m_points,
215 QGuiApplication::keyboardModifiers());
217 for (
int i = 0; i < state->m_points.size(); ++i) {
218 QWindowSystemInterface::TouchPoint &tp(state->m_points[i]);
219 if (tp.state == QEventPoint::State::Released)
220 state->m_points.removeAt(i--);
221 else if (tp.state == QEventPoint::State::Pressed)
222 tp.state = QEventPoint::State::Stationary;
static QOutputMapping * get()
Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core")