1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qwlqttouch_p.h"
5#include "qwaylandview.h"
6#include <QPointingDevice>
7#include <QTouchEvent>
8#include <QWindow>
9
10QT_BEGIN_NAMESPACE
11
12namespace QtWayland {
13
14static const int maxRawPos = 24;
15
16TouchExtensionGlobal::TouchExtensionGlobal(QWaylandCompositor *compositor)
17 : QWaylandCompositorExtensionTemplate(compositor)
18 , QtWaylandServer::qt_touch_extension(compositor->display(), 1)
19 , m_compositor(compositor)
20 , m_posData(maxRawPos * 2)
21{
22}
23
24TouchExtensionGlobal::~TouchExtensionGlobal()
25{
26}
27
28static inline int toFixed(qreal f)
29{
30 return int(f * 10000);
31}
32
33bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, QWaylandSurface *surface)
34{
35 const QList<QTouchEvent::TouchPoint> points = event->points();
36 const int pointCount = points.size();
37 if (!pointCount)
38 return false;
39
40 wl_client *surfaceClient = surface->client()->client();
41 uint32_t time = m_compositor->currentTimeMsecs();
42 const int rescount = m_resources.size();
43
44 for (int res = 0; res < rescount; ++res) {
45 Resource *target = m_resources.at(res);
46 if (target->client() != surfaceClient)
47 continue;
48
49 // We will use no touch_frame type of event, to reduce the number of
50 // events flowing through the wire. Instead, the number of points sent is
51 // included in the touch point events.
52 int sentPointCount = 0;
53 for (int i = 0; i < pointCount; ++i) {
54 if (points.at(i).state() != QEventPoint::Stationary)
55 ++sentPointCount;
56 }
57
58 for (int i = 0; i < pointCount; ++i) {
59 const QTouchEvent::TouchPoint &tp(points.at(i));
60 // Stationary points are never sent. They are cached on client side.
61 if (tp.state() == QEventPoint::Stationary)
62 continue;
63
64 uint32_t id = tp.id();
65 uint32_t state = (tp.state() & 0xFFFF) | (sentPointCount << 16);
66 uint32_t flags = (int(event->pointingDevice()->capabilities()) << 16);
67
68 int x = toFixed(f: tp.position().x());
69 int y = toFixed(f: tp.position().y());
70 int nx = toFixed(f: tp.normalizedPosition().x());
71 int ny = toFixed(f: tp.normalizedPosition().y());
72 int w = toFixed(f: tp.ellipseDiameters().width());
73 int h = toFixed(f: tp.ellipseDiameters().height());
74 int vx = toFixed(f: tp.velocity().x());
75 int vy = toFixed(f: tp.velocity().y());
76 uint32_t pressure = uint32_t(tp.pressure() * 255);
77
78 QByteArray rawData;
79 send_touch(target->handle,
80 time, id, state,
81 x, y, nx, ny, w, h,
82 pressure, vx, vy,
83 flags, rawData);
84 }
85
86 return true;
87 }
88
89 return false;
90}
91
92void TouchExtensionGlobal::setBehviorFlags(BehaviorFlags flags)
93{
94 if (m_flags == flags)
95 return;
96
97 m_flags = flags;
98 behaviorFlagsChanged();
99}
100
101void TouchExtensionGlobal::touch_extension_bind_resource(Resource *resource)
102{
103 m_resources.append(resource);
104 send_configure(resource->handle, m_flags);
105}
106
107void TouchExtensionGlobal::touch_extension_destroy_resource(Resource *resource)
108{
109 m_resources.removeOne(resource);
110}
111
112}
113
114QT_END_NAMESPACE
115
116#include "moc_qwlqttouch_p.cpp"
117

source code of qtwayland/src/compositor/extensions/qwlqttouch.cpp