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
12
13#include <QtGui/private/qguiapplication_p.h>
14#include <QtGui/private/qpointingdevice_p.h>
15#include <QtGui/qpa/qplatformtheme.h>
16#include <QtGui/qpa/qwindowsysteminterface_p.h>
17
18#include <wayland-cursor.h>
19
20QT_BEGIN_NAMESPACE
21
22namespace QtWaylandClient {
23
24using namespace Qt::StringLiterals;
25
26#if QT_CONFIG(cursor)
28{
29 if (m_tabletSeat->seat()->mQDisplay->compositor()->version() < 3) {
30 return 1;
31 }
32
33 if (auto *s = mCursor.surface.data()) {
34 if (s->outputScale() > 0)
35 return s->outputScale();
36 }
37
39}
40
42{
45
49 }
50
53 if (cursorSize.isEmpty())
54 cursorSize = QSize(24, 24);
55
56 int scale = idealCursorScale();
60
61 if (!mCursor.theme)
62 return; // A warning has already been printed in loadCursorTheme
63
64 if (auto *arrow = mCursor.theme->cursor(Qt::ArrowCursor)) {
66 arrow->images[0]->height); // Not all cursor themes are square
67 while (scale > 1 && arrowPixelSize / scale < cursorSize.width())
68 --scale;
69 } else {
70 qCWarning(lcQpaWayland) << "Cursor theme does not support the arrow cursor";
71 }
73}
74
76{
77 if (mEnterSerial == 0)
78 return;
79
81
82 if (shape == Qt::BlankCursor) {
83 if (mCursor.surface)
85 set_cursor(mEnterSerial, nullptr, 0, 0);
86 return;
87 }
88
89 if (shape == Qt::BitmapCursor) {
91 if (!buffer) {
92 qCWarning(lcQpaWayland) << "No buffer for bitmap cursor, can't set cursor";
93 return;
94 }
98 return;
99 }
100
101 if (mCursor.shape) {
102 if (mCursor.surface) {
104 }
106 return;
107 }
108
111
112 if (!mCursor.theme)
113 return;
114
115 // Set from shape using theme
117
118 if (struct ::wl_cursor *waylandCursor = mCursor.theme->cursor(shape)) {
119 uint duration = 0;
122
124 if (!buffer) {
125 qCWarning(lcQpaWayland) << "Could not find buffer for cursor" << shape;
126 return;
127 }
131 bool animated = duration > 0;
132 if (animated) {
136 }
138 return;
139 }
140
141 qCWarning(lcQpaWayland) << "Unable to change to cursor" << shape;
142}
143
145{
146 if (!mCursor.surface)
149 return mCursor.surface.get();
150}
151
153{
156 updateCursor();
157}
158
160{
163 updateCursor();
164}
165
166#endif // QT_CONFIG(cursor)
167
173
178
185
194
203
205{
207 auto *tool = new QWaylandTabletToolV2(this, id);
208 if (m_tablets.size() == 1) {
211 d->name = m_tablets.first()->name() + u" stylus";
212 } else {
213 qCDebug(lcQpaInputDevices) << "seat" << this << "has tool" << tool << "for one of these tablets:" << m_tablets;
214 // TODO identify which tablet if there are several; then tool->setParent(tablet)
215 }
220 });
221}
222
224{
225 auto *pad = new QWaylandTabletPadV2(id);
226 if (m_tablets.size() == 1) {
229 d->name = m_tablets.first()->name() + u" touchpad";
230 } else {
231 qCDebug(lcQpaInputDevices) << "seat" << this << "has touchpad" << pad << "for one of these tablets:" << m_tablets;
232 // TODO identify which tablet if there are several
233 }
236}
237
248
253
259
261{
263 d->systemId = (quint64(vid) << 32) | pid;
264 qCDebug(lcQpaInputDevices) << "vid" << vid << "pid" << pid << "stored as systemId in" << this;
265}
266
272
277
279{
280 for (auto tool : m_tools)
282}
283
289
294
314
319
321{
323
324 switch (tool_type) {
325 case type_airbrush:
326 case type_brush:
327 case type_pencil:
328 case type_pen:
330 break;
331 case type_eraser:
333 break;
334 case type_mouse:
335 case type_lens:
337 break;
338 case type_finger:
340 break;
341 }
342
343 switch (tool_type) {
344 case type::type_airbrush:
347 break;
348 case type::type_brush:
349 case type::type_pencil:
350 case type::type_pen:
351 case type::type_eraser:
353 break;
354 case type::type_lens:
356 break;
357 case type::type_mouse:
358 case type::type_finger:
360 break;
361 }
362}
363
369
375
377{
379 switch (capability) {
380 case capability_tilt:
381 // no distinction... we have to assume it has both axes
384 break;
387 break;
390 break;
393 break;
395 // nothing to represent that so far
396 break;
397 case capability_wheel:
400 break;
401 }
402 qCDebug(lcQpaInputDevices) << capability << "->" << this;
403}
404
409
414
416{
418
421
422 if (Q_UNLIKELY(!surface)) {
423 qCDebug(lcQpaWayland) << "Ignoring zwp_tablet_tool_v2_proximity_v2 with no surface";
424 return;
425 }
428
429#if QT_CONFIG(cursor)
430 // Depends on mEnterSerial being updated
431 updateCursor();
432#endif
433}
434
440
454
459
464
470
475
481
486
491
493{
494 switch (button) {
495 case 0x110: return Qt::MouseButton::LeftButton; // BTN_LEFT
496 case 0x14b: return Qt::MouseButton::MiddleButton; // BTN_STYLUS
497 case 0x14c: return Qt::MouseButton::RightButton; // BTN_STYLUS2
498 default:
499 return Qt::NoButton;
500 }
501}
502
504{
506
511 else
513 // ideally we'd get button count when the tool is discovered; seems to be a shortcoming in tablet-unstable-v2
514 // but if we get events from buttons we didn't know existed, increase it
515 if (mouseButton == Qt::RightButton)
517 else if (mouseButton == Qt::MiddleButton)
519}
520
522{
525 // leaving proximity
527 m_pending = State(); // Don't leave pressure etc. lying around when we enter the next surface
528 m_applied = State();
529 } else {
530 qCWarning(lcQpaWayland) << "Can't send tablet event with no proximity surface, ignoring";
531 }
532 return;
533 }
534
537
539 // TODO get position etc. as below
542 }
543
544 if (!(m_pending == m_applied)) {
547
549
557 int z = int(m_pending.distance);
558
559 // do not use localPosition here since that is in Qt window coordinates
560 // but we need surface coordinates to include the decoration
565
571 }
572 }
573
575}
576
577// TODO: delete when upgrading to c++20
579 return
580 down == o.down &&
584 distance == o.distance &&
585 pressure == o.pressure &&
586 rotation == o.rotation &&
587 xTilt == o.xTilt &&
588 yTilt == o.yTilt &&
589 slider == o.slider &&
590 buttons == o.buttons;
591}
592
600
605
611
617
619{
620 // As of writing Qt does not handle tablet pads group and the controls on it
621 // This proxy is server created so it is just deleted here to not leak it
623}
624
629
631{
632 delete this;
633}
634
635} // namespace QtWaylandClient
636
637QT_END_NAMESPACE
638
639#include "moc_qwaylandtabletv2_p.cpp"
static Qt::MouseButton mouseButtonFromTablet(uint button)