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.data()) {
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
187
196
205
207{
209 auto *tool = new QWaylandTabletToolV2(this, id);
210 if (m_tablets.size() == 1) {
213 d->name = m_tablets.first()->name() + u" stylus";
214 } else {
215 qCDebug(lcQpaInputDevices) << "seat" << this << "has tool" << tool << "for one of these tablets:" << m_tablets;
216 // TODO identify which tablet if there are several; then tool->setParent(tablet)
217 }
222 });
223}
224
226{
227 auto *pad = new QWaylandTabletPadV2(id);
228 if (m_tablets.size() == 1) {
231 d->name = m_tablets.first()->name() + u" touchpad";
232 } else {
233 qCDebug(lcQpaInputDevices) << "seat" << this << "has touchpad" << pad << "for one of these tablets:" << m_tablets;
234 // TODO identify which tablet if there are several
235 }
238}
239
250
255
261
263{
265 d->systemId = (quint64(vid) << 32) | pid;
266 qCDebug(lcQpaInputDevices) << "vid" << vid << "pid" << pid << "stored as systemId in" << this;
267}
268
274
279
281{
282 for (auto tool : m_tools)
284}
285
291
296
316
321
323{
325
326 switch (tool_type) {
327 case type_airbrush:
328 case type_brush:
329 case type_pencil:
330 case type_pen:
332 break;
333 case type_eraser:
335 break;
336 case type_mouse:
337 case type_lens:
339 break;
340 case type_finger:
342 break;
343 }
344
345 switch (tool_type) {
346 case type::type_airbrush:
349 break;
350 case type::type_brush:
351 case type::type_pencil:
352 case type::type_pen:
353 case type::type_eraser:
355 break;
356 case type::type_lens:
358 break;
359 case type::type_mouse:
360 case type::type_finger:
362 break;
363 }
364}
365
371
377
379{
381 switch (capability) {
382 case capability_tilt:
383 // no distinction... we have to assume it has both axes
386 break;
389 break;
392 break;
395 break;
397 // nothing to represent that so far
398 break;
399 case capability_wheel:
402 break;
403 }
404 qCDebug(lcQpaInputDevices) << capability << "->" << this;
405}
406
411
416
418{
420
423
424 if (Q_UNLIKELY(!surface)) {
425 qCDebug(lcQpaWayland) << "Ignoring zwp_tablet_tool_v2_proximity_v2 with no surface";
426 return;
427 }
430
431#if QT_CONFIG(cursor)
432 // Depends on mEnterSerial being updated
433 updateCursor();
434#endif
435}
436
442
456
461
466
472
477
483
488
493
495{
496 switch (button) {
497 case 0x110: return Qt::MouseButton::LeftButton; // BTN_LEFT
498 case 0x14b: return Qt::MouseButton::MiddleButton; // BTN_STYLUS
499 case 0x14c: return Qt::MouseButton::RightButton; // BTN_STYLUS2
500 default:
501 return Qt::NoButton;
502 }
503}
504
506{
508
513 else
515 // ideally we'd get button count when the tool is discovered; seems to be a shortcoming in tablet-unstable-v2
516 // but if we get events from buttons we didn't know existed, increase it
517 if (mouseButton == Qt::RightButton)
519 else if (mouseButton == Qt::MiddleButton)
521}
522
524{
527 // leaving proximity
529 m_pending = State(); // Don't leave pressure etc. lying around when we enter the next surface
530 m_applied = State();
531 } else {
532 qCWarning(lcQpaWayland) << "Can't send tablet event with no proximity surface, ignoring";
533 }
534 return;
535 }
536
539
541 // TODO get position etc. as below
544 }
545
546 if (!(m_pending == m_applied)) {
549
551
559 int z = int(m_pending.distance);
560
561 // do not use localPosition here since that is in Qt window coordinates
562 // but we need surface coordinates to include the decoration
567
573 }
574 }
575
577}
578
579// TODO: delete when upgrading to c++20
581 return
582 down == o.down &&
586 distance == o.distance &&
587 pressure == o.pressure &&
588 rotation == o.rotation &&
589 xTilt == o.xTilt &&
590 yTilt == o.yTilt &&
591 slider == o.slider &&
592 buttons == o.buttons;
593}
594
602
607
613
619
621{
622 // As of writing Qt does not handle tablet pads group and the controls on it
623 // This proxy is server created so it is just deleted here to not leak it
625}
626
631
633{
634 delete this;
635}
636
637} // namespace QtWaylandClient
638
639QT_END_NAMESPACE
640
641#include "moc_qwaylandtabletv2_p.cpp"
static Qt::MouseButton mouseButtonFromTablet(uint button)