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(qMin(x, geom.width() - 1.0),
62 qMin(y, geom.height() - 1.0));
67 if (libinput_device_config_calibration_has_matrix(dev)) {
68 QByteArray env = qgetenv(
"QT_QPA_LIBINPUT_TOUCH_MATRIX");
69 env = env.simplified();
72 QList<QByteArray> list = env.split(
' ');
73 if (list.length() != 6) {
74 qCWarning(qLcLibInput,
"matrix length %" PRIdQSIZETYPE
" wrong, should be 6",
78 for (
int i = 0; i < 6; i++) {
80 matrix[i] = list[i].toFloat(&ok);
82 qCWarning(qLcLibInput,
"Invalid matrix entry %d %s ", i, list[i].constData());
86 if (libinput_device_config_calibration_set_matrix(dev, matrix) != LIBINPUT_CONFIG_STATUS_SUCCESS)
87 qCWarning(qLcLibInput,
"Failed to set libinput calibration matrix ");
90 qCWarning(qLcLibInput,
"Touch device doesn't support matrix");
95 struct udev_device *udev_device;
96 udev_device = libinput_device_get_udev_device(dev);
97 QString devNode = QString::fromUtf8(udev_device_get_devnode(udev_device));
98 QString devName = QString::fromUtf8(libinput_device_get_name(dev));
100 qCDebug(qLcLibInput,
"libinput: registerDevice %s - %s",
101 qPrintable(devNode), qPrintable(devName));
106 m_devState[dev].m_screenName = mapping->screenNameForDeviceNode(devNode);
107 if (!m_devState[dev].m_screenName.isEmpty()) {
108 geom = screenGeometry(&m_devState[dev]);
109 qCDebug(qLcLibInput) <<
"libinput: Mapping device" << devNode
110 <<
"to screen" << m_devState[dev].m_screenName
111 <<
"with geometry" << geom;
115 QPointingDevice *&td = m_devState[dev].m_touchDevice;
116 td =
new QPointingDevice(devName, udev_device_get_devnum(udev_device),
117 QInputDevice::DeviceType::TouchScreen, QPointingDevice::PointerType::Finger,
118 QPointingDevice::Capability::Position | QPointingDevice::Capability::Area, 16, 0);
119 auto devPriv = QPointingDevicePrivate::get(td);
120 devPriv->busId = QString::fromLocal8Bit(udev_device_get_syspath(udev_device));
122 devPriv->setAvailableVirtualGeometry(geom);
123 QWindowSystemInterface::registerInputDevice(td);
135 int slot = libinput_event_touch_get_slot(e);
136 DeviceState *state = deviceState(e);
137 QWindowSystemInterface::TouchPoint *tp = state->point(slot);
139 qWarning(
"Incorrect touch state");
141 QWindowSystemInterface::TouchPoint newTp;
142 newTp.id = qMax(0, slot);
143 newTp.state = QEventPoint::State::Pressed;
144 newTp.area = QRect(0, 0, 8, 8);
145 newTp.area.moveCenter(getPos(e));
146 state->m_points.append(newTp);
147 qCDebug(qLcLibInputEvents) <<
"libinput touch down" << newTp;
153 int slot = libinput_event_touch_get_slot(e);
154 DeviceState *state = deviceState(e);
155 QWindowSystemInterface::TouchPoint *tp = state->point(slot);
157 QEventPoint::State tmpState = QEventPoint::State::Updated;
158 const QPointF p = getPos(e);
159 if (tp->area.center() == p)
160 tmpState = QEventPoint::State::Stationary;
162 tp->area.moveCenter(p);
165 if (tp->state != QEventPoint::State::Pressed && tp->state != QEventPoint::State::Released)
166 tp->state = tmpState;
167 qCDebug(qLcLibInputEvents) <<
"libinput touch move" << tp;
169 qWarning(
"Inconsistent touch state (got 'motion' without 'down')");
175 int slot = libinput_event_touch_get_slot(e);
176 DeviceState *state = deviceState(e);
177 QWindowSystemInterface::TouchPoint *tp = state->point(slot);
179 tp->state = QEventPoint::State::Released;
181 QEventPoint::States s;
182 for (
int i = 0; i < state->m_points.size(); ++i)
183 s |= state->m_points.at(i).state;
184 qCDebug(qLcLibInputEvents) <<
"libinput touch up" << s << tp;
185 if (s == QEventPoint::State::Released)
188 qCDebug(qLcLibInputEvents,
"libinput waiting for all points to be released");
190 qWarning(
"Inconsistent touch state (got 'up' without 'down')");
196 DeviceState *state = deviceState(e);
197 qCDebug(qLcLibInputEvents) <<
"libinput touch cancel" << state->m_points;
198 if (state->m_touchDevice)
199 QWindowSystemInterface::handleTouchCancelEvent(
nullptr, state->m_touchDevice, QGuiApplication::keyboardModifiers());
201 qWarning(
"TouchCancel without registered device");
206 DeviceState *state = deviceState(e);
207 if (!state->m_touchDevice) {
208 qWarning(
"TouchFrame without registered device");
211 qCDebug(qLcLibInputEvents) <<
"libinput touch frame" << state->m_points;
212 if (state->m_points.isEmpty())
215 QWindowSystemInterface::handleTouchEvent(
nullptr, state->m_touchDevice, state->m_points,
216 QGuiApplication::keyboardModifiers());
218 for (
int i = 0; i < state->m_points.size(); ++i) {
219 QWindowSystemInterface::TouchPoint &tp(state->m_points[i]);
220 if (tp.state == QEventPoint::State::Released)
221 state->m_points.removeAt(i--);
222 else if (tp.state == QEventPoint::State::Pressed)
223 tp.state = QEventPoint::State::Stationary;
static QOutputMapping * get()
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)