Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qwaylandtabletv2.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6#include "qwaylanddisplay_p.h"
7#include "qwaylandsurface_p.h"
8
10
11namespace QtWaylandClient {
12
14 : zwp_tablet_manager_v2(display->wl_registry(), id, qMin(version, uint(1)))
15{
16 // Create tabletSeats for all seats.
17 // This only works if we get the manager after all seats
18 const auto seats = display->inputDevices();
19 for (auto *seat : seats)
20 createTabletSeat(seat);
21}
22
27
32
34 : QtWayland::zwp_tablet_seat_v2(manager->get_tablet_seat(seat->wl_seat()))
35 , m_seat(seat)
36{
37}
38
40{
41 for (auto *tablet : m_tablets)
42 tablet->destroy();
43 for (auto *tool : m_tools)
44 tool->destroy();
45 for (auto *pad : m_pads)
46 pad->destroy();
47 qDeleteAll(m_tablets);
48 qDeleteAll(m_tools);
49 qDeleteAll(m_pads);
50 destroy();
51}
52
54{
55 auto *tablet = new QWaylandTabletV2(id);
56 m_tablets.push_back(tablet);
57 connect(tablet, &QWaylandTabletV2::destroyed, this, [this, tablet] { m_tablets.removeOne(tablet); });
58}
59
61{
62 auto *tool = new QWaylandTabletToolV2(this, id);
63 m_tools.push_back(tool);
64 connect(tool, &QWaylandTabletToolV2::destroyed, this, [this, tool] { m_tools.removeOne(tool); });
65}
66
68{
69 auto *pad = new QWaylandTabletPadV2(id);
70 m_pads.push_back(pad);
71 connect(pad, &QWaylandTabletPadV2::destroyed, this, [this, pad] { m_pads.removeOne(pad); });
72}
73
74QWaylandTabletV2::QWaylandTabletV2(::zwp_tablet_v2 *tablet)
75 : QtWayland::zwp_tablet_v2(tablet)
76{
77}
78
80{
81 destroy();
82 delete this;
83}
84
86 : QtWayland::zwp_tablet_tool_v2(tool)
87 , m_tabletSeat(tabletSeat)
88{
89}
90
92{
93 m_toolType = type(tool_type);
94}
95
96void QWaylandTabletToolV2::zwp_tablet_tool_v2_hardware_serial(uint32_t hardware_serial_hi, uint32_t hardware_serial_lo)
97{
98 m_uid = (quint64(hardware_serial_hi) << 32) + hardware_serial_lo;
99}
100
102{
103 if (capability == capability_rotation)
104 m_hasRotation = true;
105}
106
108{
109 switch (m_toolType) {
110 case type::type_airbrush:
111 case type::type_brush:
112 case type::type_pencil:
113 case type::type_pen:
114 m_pointerType = QPointingDevice::PointerType::Pen;
115 break;
116 case type::type_eraser:
118 break;
119 case type::type_mouse:
120 case type::type_lens:
122 break;
123 case type::type_finger:
125 break;
126 }
127 switch (m_toolType) {
128 case type::type_airbrush:
129 m_tabletDevice = QInputDevice::DeviceType::Airbrush;
130 break;
131 case type::type_brush:
132 case type::type_pencil:
133 case type::type_pen:
134 case type::type_eraser:
135 m_tabletDevice = QInputDevice::DeviceType::Stylus;
136 break;
137 case type::type_lens:
138 m_tabletDevice = QInputDevice::DeviceType::Puck;
139 break;
140 case type::type_mouse:
141 case type::type_finger:
142 m_tabletDevice = QInputDevice::DeviceType::Unknown;
143 break;
144 }
145}
146
148{
149 destroy();
150 delete this;
151}
152
153void QWaylandTabletToolV2::zwp_tablet_tool_v2_proximity_in(uint32_t serial, zwp_tablet_v2 *tablet, wl_surface *surface)
154{
155 Q_UNUSED(tablet);
156 Q_UNUSED(serial);
157 if (Q_UNLIKELY(!surface)) {
158 qCDebug(lcQpaWayland) << "Ignoring zwp_tablet_tool_v2_proximity_v2 with no surface";
159 return;
160 }
161 m_pending.enteredSurface = true;
162 m_pending.proximitySurface = QWaylandSurface::fromWlSurface(surface);
163}
164
166{
167 m_pending.enteredSurface = false;
168 m_pending.proximitySurface = nullptr;
169}
170
172{
173 m_pending.down = true;
174
175 if (m_pending.proximitySurface) {
176 if (QWaylandWindow *window = m_pending.proximitySurface->waylandWindow()) {
177 QWaylandInputDevice *seat = m_tabletSeat->seat();
178 seat->display()->setLastInputDevice(seat, serial, window);
179 }
180 }
181}
182
184{
185 m_pending.down = false;
186}
187
189{
190 m_pending.surfacePosition = QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y));
191}
192
194{
195 const int maxPressure = 65535;
196 m_pending.pressure = qreal(pressure)/maxPressure;
197}
198
200{
201 m_pending.distance = distance;
202}
203
204void QWaylandTabletToolV2::zwp_tablet_tool_v2_tilt(wl_fixed_t tilt_x, wl_fixed_t tilt_y)
205{
206 m_pending.xTilt = wl_fixed_to_double(tilt_x);
207 m_pending.yTilt = wl_fixed_to_double(tilt_y);
208}
209
211{
212 m_pending.rotation = wl_fixed_to_double(degrees);
213}
214
216{
217 m_pending.slider = qreal(position) / 65535;
218}
219
221{
222 switch (button) {
223 case 0x110: return Qt::MouseButton::LeftButton; // BTN_LEFT
224 case 0x14b: return Qt::MouseButton::MiddleButton; // BTN_STYLUS
225 case 0x14c: return Qt::MouseButton::RightButton; // BTN_STYLUS2
226 default:
227 return Qt::NoButton;
228 }
229}
230
231void QWaylandTabletToolV2::zwp_tablet_tool_v2_button(uint32_t serial, uint32_t button, uint32_t state)
232{
233 Q_UNUSED(serial);
235 if (state == button_state_pressed)
236 m_pending.buttons |= mouseButton;
237 else
238 m_pending.buttons &= ~mouseButton;
239}
240
242{
243 if (m_pending.proximitySurface && !m_applied.proximitySurface) {
244 QWindowSystemInterface::handleTabletEnterProximityEvent(int(m_tabletDevice), int(m_pointerType), m_uid);
245 m_applied.proximitySurface = m_pending.proximitySurface;
246 }
247
248 if (!(m_pending == m_applied) && m_pending.proximitySurface) {
249 if (!m_pending.proximitySurface) {
250 qCWarning(lcQpaWayland) << "Can't send tablet event with no proximity surface, ignoring";
251 return;
252 }
253 QWaylandWindow *waylandWindow = QWaylandWindow::fromWlSurface(m_pending.proximitySurface->object());
254 QWindow *window = waylandWindow->window();
255 ulong timestamp = time;
256 const QPointF localPosition = waylandWindow->mapFromWlSurface(m_pending.surfacePosition);
257
258 QPointF delta = localPosition - localPosition.toPoint();
259 QPointF globalPosition = window->mapToGlobal(localPosition.toPoint());
260 globalPosition += delta;
261
262 Qt::MouseButtons buttons = m_pending.down ? Qt::MouseButton::LeftButton : Qt::MouseButton::NoButton;
263 buttons |= m_pending.buttons;
264 qreal pressure = m_pending.pressure;
265 int xTilt = int(m_pending.xTilt);
266 int yTilt = int(m_pending.yTilt);
267 qreal tangentialPressure = m_pending.slider;
268 qreal rotation = m_pending.rotation;
269 int z = int(m_pending.distance);
270 QWindowSystemInterface::handleTabletEvent(window, timestamp, localPosition, globalPosition,
271 int(m_tabletDevice), int(m_pointerType), buttons, pressure,
272 xTilt, yTilt, tangentialPressure, rotation, z, m_uid);
273 }
274
275 if (!m_pending.proximitySurface && m_applied.enteredSurface) {
276 QWindowSystemInterface::handleTabletLeaveProximityEvent(int(m_tabletDevice), int(m_pointerType), m_uid);
277 m_pending = State(); // Don't leave pressure etc. lying around when we enter the next surface
278 }
279
280 m_applied = m_pending;
281}
282
283// TODO: delete when upgrading to c++20
284bool QWaylandTabletToolV2::State::operator==(const QWaylandTabletToolV2::State &o) const {
285 return
286 down == o.down &&
287 proximitySurface.data() == o.proximitySurface.data() &&
288 enteredSurface == o.enteredSurface &&
289 surfacePosition == o.surfacePosition &&
290 distance == o.distance &&
291 pressure == o.pressure &&
292 rotation == o.rotation &&
293 xTilt == o.xTilt &&
294 yTilt == o.yTilt &&
295 slider == o.slider &&
296 buttons == o.buttons;
297}
298
300 : QtWayland::zwp_tablet_pad_v2(pad)
301{
302}
303
305{
306 destroy();
307 delete this;
308}
309
310} // namespace QtWaylandClient
311
313
314#include "moc_qwaylandtabletv2_p.cpp"
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
QWindow * window() const
Returns the window which belongs to the QPlatformWindow.
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition qpoint.h:404
T * data() const noexcept
Definition qpointer.h:73
static bool handleTabletEvent(QWindow *window, ulong timestamp, const QPointingDevice *device, const QPointF &local, const QPointF &global, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, Qt::KeyboardModifiers modifiers=Qt::NoModifier)
static bool handleTabletLeaveProximityEvent(ulong timestamp, int deviceType, int pointerType, qint64 uid)
static bool handleTabletEnterProximityEvent(ulong timestamp, int deviceType, int pointerType, qint64 uid)
\inmodule QtGui
Definition qwindow.h:63
void setLastInputDevice(QWaylandInputDevice *device, uint32_t serial, QWaylandWindow *window)
static QWaylandSurface * fromWlSurface(::wl_surface *surface)
QWaylandTabletManagerV2(QWaylandDisplay *display, uint id, uint version)
QWaylandTabletSeatV2 * createTabletSeat(QWaylandInputDevice *seat)
QWaylandTabletPadV2(::zwp_tablet_pad_v2 *pad)
QWaylandInputDevice * seat() const
void zwp_tablet_seat_v2_pad_added(struct ::zwp_tablet_pad_v2 *id) override
QWaylandTabletSeatV2(QWaylandTabletManagerV2 *manager, QWaylandInputDevice *seat)
void zwp_tablet_seat_v2_tool_added(struct ::zwp_tablet_tool_v2 *id) override
void zwp_tablet_seat_v2_tablet_added(struct ::zwp_tablet_v2 *id) override
void zwp_tablet_tool_v2_button(uint32_t serial, uint32_t button, uint32_t state) override
void zwp_tablet_tool_v2_motion(wl_fixed_t x, wl_fixed_t y) override
void zwp_tablet_tool_v2_tilt(wl_fixed_t tilt_x, wl_fixed_t tilt_y) override
QWaylandTabletToolV2(QWaylandTabletSeatV2 *tabletSeat, ::zwp_tablet_tool_v2 *tool)
void zwp_tablet_tool_v2_rotation(wl_fixed_t degrees) override
void zwp_tablet_tool_v2_distance(uint32_t distance) override
void zwp_tablet_tool_v2_hardware_serial(uint32_t hardware_serial_hi, uint32_t hardware_serial_lo) override
void zwp_tablet_tool_v2_down(uint32_t serial) override
void zwp_tablet_tool_v2_capability(uint32_t capability) override
void zwp_tablet_tool_v2_frame(uint32_t time) override
void zwp_tablet_tool_v2_pressure(uint32_t pressure) override
void zwp_tablet_tool_v2_type(uint32_t tool_type) override
void zwp_tablet_tool_v2_slider(int32_t position) override
void zwp_tablet_tool_v2_proximity_in(uint32_t serial, struct ::zwp_tablet_v2 *tablet, struct ::wl_surface *surface) override
QWaylandTabletV2(::zwp_tablet_v2 *tablet)
QPointF mapFromWlSurface(const QPointF &surfacePosition) const
Converts from wl_surface coordinates to Qt window coordinates.
static QWaylandWindow * fromWlSurface(::wl_surface *surface)
QPushButton * button
[2]
qDeleteAll(list.begin(), list.end())
else opt state
[0]
struct wl_display * display
Definition linuxdmabuf.h:41
Combined button and popup list for selecting options.
static Qt::MouseButton mouseButtonFromTablet(uint button)
MouseButton
Definition qnamespace.h:56
@ LeftButton
Definition qnamespace.h:58
@ RightButton
Definition qnamespace.h:59
@ MiddleButton
Definition qnamespace.h:60
@ NoButton
Definition qnamespace.h:57
#define Q_UNLIKELY(x)
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLenum GLuint id
[7]
GLsizei GLsizei GLfloat distance
GLenum type
GLint y
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_UNUSED(x)
unsigned long ulong
Definition qtypes.h:35
unsigned long long quint64
Definition qtypes.h:61
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187
aWidget window() -> setWindowTitle("New Window Title")
[2]
QNetworkAccessManager manager