Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
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// Qt-Security score:significant reason:default
4
13
14#include <QtGui/private/qguiapplication_p.h>
15#include <QtGui/private/qpointingdevice_p.h>
16#include <QtGui/qpa/qplatformtheme.h>
17#include <QtGui/qpa/qwindowsysteminterface_p.h>
18
19#include <wayland-cursor.h>
20
21QT_BEGIN_NAMESPACE
22
23namespace QtWaylandClient {
24
25using namespace Qt::StringLiterals;
26
27#if QT_CONFIG(cursor)
29{
30 if (m_tabletSeat->seat()->mQDisplay->compositor()->version() < 3) {
31 return 1;
32 }
33
34 if (auto *s = mCursor.surface.get()) {
35 if (s->outputScale() > 0)
36 return s->outputScale();
37 }
38
40}
41
43{
46
50 }
51
54 if (cursorSize.isEmpty())
55 cursorSize = QSize(24, 24);
56
57 int scale = idealCursorScale();
61
62 if (!mCursor.theme)
63 return; // A warning has already been printed in loadCursorTheme
64
65 if (auto *arrow = mCursor.theme->cursor(Qt::ArrowCursor)) {
67 arrow->images[0]->height); // Not all cursor themes are square
68 while (scale > 1 && arrowPixelSize / scale < cursorSize.width())
69 --scale;
70 } else {
71 qCWarning(lcQpaWayland) << "Cursor theme does not support the arrow cursor";
72 }
74}
75
77{
78 if (mEnterSerial == 0)
79 return;
80
82
83 if (shape == Qt::BlankCursor) {
84 if (mCursor.surface)
86 set_cursor(mEnterSerial, nullptr, 0, 0);
87 return;
88 }
89
90 if (shape == Qt::BitmapCursor) {
92 if (!buffer) {
93 qCWarning(lcQpaWayland) << "No buffer for bitmap cursor, can't set cursor";
94 return;
95 }
99 return;
100 }
101
102 if (mCursor.shape) {
103 if (mCursor.surface) {
105 }
107 return;
108 }
109
112
113 if (!mCursor.theme)
114 return;
115
116 // Set from shape using theme
118 const uint time = timer.isValid() ? timer.elapsed() : 0;
119
120 if (struct ::wl_cursor *waylandCursor = mCursor.theme->cursor(shape)) {
121 uint duration = 0;
124
126 if (!buffer) {
127 qCWarning(lcQpaWayland) << "Could not find buffer for cursor" << shape;
128 return;
129 }
133 bool animated = duration > 0;
134 if (animated) {
138 }
140 return;
141 }
142
143 qCWarning(lcQpaWayland) << "Unable to change to cursor" << shape;
144}
145
147{
148 if (!mCursor.surface)
151 return mCursor.surface.get();
152}
153
155{
158 updateCursor();
159}
160
162{
165 updateCursor();
166}
167
168#endif // QT_CONFIG(cursor)
169
175
180
188
197
206
208{
210 auto *tool = new QWaylandTabletToolV2(this, id);
211 if (m_tablets.size() == 1) {
214 d->name = m_tablets.first()->name() + u" stylus";
215 } else {
216 qCDebug(lcQpaInputDevices) << "seat" << this << "has tool" << tool << "for one of these tablets:" << m_tablets;
217 // TODO identify which tablet if there are several; then tool->setParent(tablet)
218 }
223 });
224}
225
227{
228 auto *pad = new QWaylandTabletPadV2(id);
229 if (m_tablets.size() == 1) {
232 d->name = m_tablets.first()->name() + u" touchpad";
233 } else {
234 qCDebug(lcQpaInputDevices) << "seat" << this << "has touchpad" << pad << "for one of these tablets:" << m_tablets;
235 // TODO identify which tablet if there are several
236 }
239}
240
253
258
264
266{
268 d->systemId = (quint64(vid) << 32) | pid;
269 qCDebug(lcQpaInputDevices) << "vid" << vid << "pid" << pid << "stored as systemId in" << this;
270}
271
277
282
284{
285 for (auto tool : m_tools)
287}
288
294
299
321
326
328{
330
331 switch (tool_type) {
332 case type_airbrush:
333 case type_brush:
334 case type_pencil:
335 case type_pen:
337 break;
338 case type_eraser:
340 break;
341 case type_mouse:
342 case type_lens:
344 break;
345 case type_finger:
347 break;
348 }
349
350 switch (tool_type) {
351 case type::type_airbrush:
354 break;
355 case type::type_brush:
356 case type::type_pencil:
357 case type::type_pen:
358 case type::type_eraser:
360 break;
361 case type::type_lens:
363 break;
364 case type::type_mouse:
365 case type::type_finger:
367 break;
368 }
369}
370
376
382
384{
386 switch (capability) {
387 case capability_tilt:
388 // no distinction... we have to assume it has both axes
391 break;
394 break;
397 break;
400 break;
402 // nothing to represent that so far
403 break;
404 case capability_wheel:
407 break;
408 }
409 qCDebug(lcQpaInputDevices) << capability << "->" << this;
410}
411
416
421
423{
425
428
429 if (Q_UNLIKELY(!surface)) {
430 qCDebug(lcQpaWayland) << "Ignoring zwp_tablet_tool_v2_proximity_v2 with no surface";
431 return;
432 }
435
436#if QT_CONFIG(cursor)
437 // Depends on mEnterSerial being updated
438 updateCursor();
439#endif
440}
441
447
461
466
471
477
482
488
493
498
500{
501 switch (button) {
502 case 0x110: return Qt::MouseButton::LeftButton; // BTN_LEFT
503 case 0x14b: return Qt::MouseButton::MiddleButton; // BTN_STYLUS
504 case 0x14c: return Qt::MouseButton::RightButton; // BTN_STYLUS2
505 default:
506 return Qt::NoButton;
507 }
508}
509
511{
513
518 else
520 // ideally we'd get button count when the tool is discovered; seems to be a shortcoming in tablet-unstable-v2
521 // but if we get events from buttons we didn't know existed, increase it
522 if (mouseButton == Qt::RightButton)
524 else if (mouseButton == Qt::MiddleButton)
526}
527
529{
532 // leaving proximity
534 m_pending = State(); // Don't leave pressure etc. lying around when we enter the next surface
535 m_applied = State();
536 } else {
537 qCWarning(lcQpaWayland) << "Can't send tablet event with no proximity surface, ignoring";
538 }
539 return;
540 }
541
544 const bool needsTabletEvent = !(m_pending == m_applied);
545
553 const qreal xTilt = m_pending.xTilt;
554 const qreal yTilt = m_pending.yTilt;
557 const int z = int(m_pending.distance);
558
564 }
565
566 if (needsTabletEvent) {
567 // do not use localPosition here since that is in Qt window coordinates
568 // but we need surface coordinates to include the decoration
573
580 }
581 }
582 }
583
585}
586
587// TODO: delete when upgrading to c++20
589 return
590 down == o.down &&
594 distance == o.distance &&
595 pressure == o.pressure &&
596 rotation == o.rotation &&
597 xTilt == o.xTilt &&
598 yTilt == o.yTilt &&
599 slider == o.slider &&
600 buttons == o.buttons;
601}
602
612
617
623
629
631{
632 // As of writing Qt does not handle tablet pads group and the controls on it
633 // This proxy is server created so it is just deleted here to not leak it
635}
636
641
643{
644 delete this;
645}
646
647} // namespace QtWaylandClient
648
649QT_END_NAMESPACE
650
651#include "moc_qwaylandtabletv2_p.cpp"
static Qt::MouseButton mouseButtonFromTablet(uint button)