KWaylandServer

tablet_v2_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2019 Aleix Pol Gonzalez <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 
7 #include "tablet_v2_interface.h"
8 #include "display.h"
9 #include "seat_interface.h"
10 #include "surface_interface.h"
11 
12 #include "qwayland-server-tablet-unstable-v2.h"
13 #include <QHash>
14 
15 namespace KWaylandServer
16 {
17 static int s_version = 1;
18 
19 class TabletV2InterfacePrivate : public QtWaylandServer::zwp_tablet_v2
20 {
21 public:
22  TabletV2InterfacePrivate(TabletV2Interface *q, uint32_t vendorId, uint32_t productId, const QString &name, const QStringList &paths)
23  : zwp_tablet_v2()
24  , q(q)
25  , m_vendorId(vendorId)
26  , m_productId(productId)
27  , m_name(name)
28  , m_paths(paths)
29  {
30  }
31 
32  wl_resource *resourceForSurface(SurfaceInterface *surface) const
33  {
34  ClientConnection *client = surface->client();
35  Resource *r = resourceMap().value(*client);
36  return r ? r->handle : nullptr;
37  }
38 
39  TabletV2Interface *const q;
40  TabletPadV2Interface *m_pad = nullptr;
41  const uint32_t m_vendorId;
42  const uint32_t m_productId;
43  const QString m_name;
44  const QStringList m_paths;
45 };
46 
47 TabletV2Interface::TabletV2Interface(uint32_t vendorId, uint32_t productId, const QString &name, const QStringList &paths, QObject *parent)
48  : QObject(parent)
49  , d(new TabletV2InterfacePrivate(this, vendorId, productId, name, paths))
50 {
51 }
52 
53 TabletV2Interface::~TabletV2Interface()
54 {
55  const auto tabletResources = d->resourceMap();
56  for (TabletV2InterfacePrivate::Resource *resource : tabletResources) {
57  d->send_removed(resource->handle);
58  }
59 }
60 
61 bool TabletV2Interface::isSurfaceSupported(SurfaceInterface *surface) const
62 {
63  return d->resourceForSurface(surface);
64 }
65 
66 TabletPadV2Interface *TabletV2Interface::pad() const
67 {
68  return d->m_pad;
69 }
70 
71 class TabletCursorV2Private
72 {
73 public:
74  TabletCursorV2Private(TabletCursorV2 *q)
75  : q(q)
76  {
77  }
78 
79  void update(quint32 serial, SurfaceInterface *surface, const QPoint &hotspot)
80  {
81  const bool diff = m_serial != serial || m_surface != surface || m_hotspot != hotspot;
82  if (diff) {
83  m_serial = serial;
84  m_surface = surface;
85  m_hotspot = hotspot;
86 
87  Q_EMIT q->changed();
88  }
89  }
90 
91  TabletCursorV2 *const q;
92 
93  quint32 m_serial = 0;
94  SurfaceInterface *m_surface = nullptr;
95  QPoint m_hotspot;
96 };
97 
98 TabletCursorV2::TabletCursorV2()
99  : QObject()
100  , d(new TabletCursorV2Private(this))
101 {
102 }
103 
104 TabletCursorV2::~TabletCursorV2() = default;
105 
106 QPoint TabletCursorV2::hotspot() const
107 {
108  return d->m_hotspot;
109 }
110 
111 quint32 TabletCursorV2::enteredSerial() const
112 {
113  return d->m_serial;
114 }
115 
116 SurfaceInterface *TabletCursorV2::surface() const
117 {
118  return d->m_surface;
119 }
120 
121 class TabletToolV2InterfacePrivate : public QtWaylandServer::zwp_tablet_tool_v2
122 {
123 public:
124  TabletToolV2InterfacePrivate(TabletToolV2Interface *q,
125  Display *display,
126  TabletToolV2Interface::Type type,
127  uint32_t hsh,
128  uint32_t hsl,
129  uint32_t hih,
130  uint32_t hil,
131  const QVector<TabletToolV2Interface::Capability> &capabilities)
132  : zwp_tablet_tool_v2()
133  , m_display(display)
134  , m_type(type)
135  , m_hardwareSerialHigh(hsh)
136  , m_hardwareSerialLow(hsl)
137  , m_hardwareIdHigh(hih)
138  , m_hardwareIdLow(hil)
139  , m_capabilities(capabilities)
140  , q(q)
141  {
142  }
143 
144  wl_resource *targetResource()
145  {
146  if (!m_surface)
147  return nullptr;
148 
149  ClientConnection *client = m_surface->client();
150  const Resource *r = resourceMap().value(*client);
151  return r ? r->handle : nullptr;
152  }
153 
154  quint64 hardwareId() const
155  {
156  return quint64(quint64(m_hardwareIdHigh) << 32) + m_hardwareIdLow;
157  }
158  quint64 hardwareSerial() const
159  {
160  return quint64(quint64(m_hardwareSerialHigh) << 32) + m_hardwareSerialLow;
161  }
162 
163  void zwp_tablet_tool_v2_bind_resource(QtWaylandServer::zwp_tablet_tool_v2::Resource *resource) override
164  {
165  TabletCursorV2 *&c = m_cursors[resource->handle];
166  if (!c)
167  c = new TabletCursorV2;
168  }
169 
170  void zwp_tablet_tool_v2_set_cursor(Resource *resource, uint32_t serial, struct ::wl_resource *_surface, int32_t hotspot_x, int32_t hotspot_y) override
171  {
172  TabletCursorV2 *c = m_cursors[resource->handle];
173  c->d->update(serial, SurfaceInterface::get(_surface), {hotspot_x, hotspot_y});
174  if (resource->handle == targetResource())
175  q->cursorChanged(c);
176  }
177 
178  void zwp_tablet_tool_v2_destroy_resource(Resource *resource) override
179  {
180  delete m_cursors.take(resource->handle);
181  if (m_removed && resourceMap().isEmpty()) {
182  delete q;
183  }
184  }
185 
186  void zwp_tablet_tool_v2_destroy(Resource *resource) override
187  {
188  wl_resource_destroy(resource->handle);
189  }
190 
191  Display *const m_display;
192  bool m_cleanup = false;
193  bool m_removed = false;
194  QPointer<SurfaceInterface> m_surface;
195  QPointer<TabletV2Interface> m_lastTablet;
196  const uint32_t m_type;
197  const uint32_t m_hardwareSerialHigh, m_hardwareSerialLow;
198  const uint32_t m_hardwareIdHigh, m_hardwareIdLow;
199  const QVector<TabletToolV2Interface::Capability> m_capabilities;
201  TabletToolV2Interface *const q;
202 };
203 
204 TabletToolV2Interface::TabletToolV2Interface(Display *display,
205  Type type,
206  uint32_t hsh,
207  uint32_t hsl,
208  uint32_t hih,
209  uint32_t hil,
210  const QVector<Capability> &capabilities,
211  QObject *parent)
212  : QObject(parent)
213  , d(new TabletToolV2InterfacePrivate(this, display, type, hsh, hsl, hih, hil, capabilities))
214 {
215 }
216 
217 TabletToolV2Interface::~TabletToolV2Interface()
218 {
219  const auto toolResources = d->resourceMap();
220  for (TabletToolV2InterfacePrivate::Resource *resource : toolResources) {
221  d->send_removed(resource->handle);
222  }
223 }
224 
225 void TabletToolV2Interface::setCurrentSurface(SurfaceInterface *surface)
226 {
227  if (d->m_surface == surface)
228  return;
229 
230  TabletV2Interface *const lastTablet = d->m_lastTablet;
231  if (d->m_surface && d->resourceMap().contains(*d->m_surface->client())) {
232  sendProximityOut();
233  sendFrame(0);
234  }
235 
236  d->m_surface = surface;
237 
238  if (lastTablet && lastTablet->d->resourceForSurface(surface)) {
239  sendProximityIn(lastTablet);
240  } else {
241  d->m_lastTablet = lastTablet;
242  }
243 
244  Q_EMIT cursorChanged(d->m_cursors.value(d->targetResource()));
245 }
246 
247 bool TabletToolV2Interface::isClientSupported() const
248 {
249  return d->m_surface && d->targetResource();
250 }
251 
252 void TabletToolV2Interface::sendButton(uint32_t button, bool pressed)
253 {
254  d->send_button(d->targetResource(),
255  d->m_display->nextSerial(),
256  button,
257  pressed ? QtWaylandServer::zwp_tablet_tool_v2::button_state_pressed : QtWaylandServer::zwp_tablet_tool_v2::button_state_released);
258 }
259 
260 void TabletToolV2Interface::sendMotion(const QPointF &pos)
261 {
262  d->send_motion(d->targetResource(), wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y()));
263 }
264 
265 void TabletToolV2Interface::sendDistance(uint32_t distance)
266 {
267  d->send_distance(d->targetResource(), distance);
268 }
269 
270 void TabletToolV2Interface::sendFrame(uint32_t time)
271 {
272  d->send_frame(d->targetResource(), time);
273 
274  if (d->m_cleanup) {
275  d->m_surface = nullptr;
276  d->m_lastTablet = nullptr;
277  d->m_cleanup = false;
278  }
279 }
280 
281 void TabletToolV2Interface::sendPressure(uint32_t pressure)
282 {
283  d->send_pressure(d->targetResource(), pressure);
284 }
285 
286 void TabletToolV2Interface::sendRotation(qreal rotation)
287 {
288  d->send_rotation(d->targetResource(), wl_fixed_from_double(rotation));
289 }
290 
291 void TabletToolV2Interface::sendSlider(int32_t position)
292 {
293  d->send_slider(d->targetResource(), position);
294 }
295 
296 void TabletToolV2Interface::sendTilt(qreal degreesX, qreal degreesY)
297 {
298  d->send_tilt(d->targetResource(), wl_fixed_from_double(degreesX), wl_fixed_from_double(degreesY));
299 }
300 
301 void TabletToolV2Interface::sendWheel(int32_t degrees, int32_t clicks)
302 {
303  d->send_wheel(d->targetResource(), degrees, clicks);
304 }
305 
306 void TabletToolV2Interface::sendProximityIn(TabletV2Interface *tablet)
307 {
308  wl_resource *tabletResource = tablet->d->resourceForSurface(d->m_surface);
309  d->send_proximity_in(d->targetResource(), d->m_display->nextSerial(), tabletResource, d->m_surface->resource());
310  d->m_lastTablet = tablet;
311 }
312 
313 void TabletToolV2Interface::sendProximityOut()
314 {
315  d->send_proximity_out(d->targetResource());
316  d->m_cleanup = true;
317 }
318 
319 void TabletToolV2Interface::sendDown()
320 {
321  d->send_down(d->targetResource(), d->m_display->nextSerial());
322 }
323 
324 void TabletToolV2Interface::sendUp()
325 {
326  d->send_up(d->targetResource());
327 }
328 
329 class TabletPadRingV2InterfacePrivate : public QtWaylandServer::zwp_tablet_pad_ring_v2
330 {
331 public:
332  TabletPadRingV2InterfacePrivate(TabletPadRingV2Interface *q)
333  : zwp_tablet_pad_ring_v2()
334  , q(q)
335  {
336  }
337 
338  wl_resource *resourceForSurface(SurfaceInterface *surface) const
339  {
340  ClientConnection *client = surface->client();
341  Resource *r = resourceMap().value(*client);
342  return r ? r->handle : nullptr;
343  }
344 
345  void zwp_tablet_pad_ring_v2_destroy(Resource *resource) override
346  {
347  wl_resource_destroy(resource->handle);
348  }
349  TabletPadRingV2Interface *const q;
350  TabletPadV2Interface *m_pad;
351 };
352 
353 TabletPadRingV2Interface::TabletPadRingV2Interface(TabletPadV2Interface *parent)
354  : QObject(parent)
355  , d(new TabletPadRingV2InterfacePrivate(this))
356 {
357  d->m_pad = parent;
358 }
359 
360 TabletPadRingV2Interface::~TabletPadRingV2Interface() = default;
361 
362 void TabletPadRingV2Interface::sendAngle(qreal angle)
363 {
364  d->send_angle(d->resourceForSurface(d->m_pad->currentSurface()), wl_fixed_from_double(angle));
365 }
366 
367 void TabletPadRingV2Interface::sendFrame(quint32 time)
368 {
369  d->send_frame(d->resourceForSurface(d->m_pad->currentSurface()), time);
370 }
371 
372 void TabletPadRingV2Interface::sendSource(Source source)
373 {
374  d->send_source(d->resourceForSurface(d->m_pad->currentSurface()), source);
375 }
376 
377 void TabletPadRingV2Interface::sendStop()
378 {
379  d->send_stop(d->resourceForSurface(d->m_pad->currentSurface()));
380 }
381 
382 class TabletPadStripV2InterfacePrivate : public QtWaylandServer::zwp_tablet_pad_strip_v2
383 {
384 public:
385  TabletPadStripV2InterfacePrivate(TabletPadStripV2Interface *q)
386  : zwp_tablet_pad_strip_v2()
387  , q(q)
388  {
389  }
390 
391  wl_resource *resourceForSurface(SurfaceInterface *surface) const
392  {
393  ClientConnection *client = surface->client();
394  Resource *r = resourceMap().value(*client);
395  return r ? r->handle : nullptr;
396  }
397 
398  void zwp_tablet_pad_strip_v2_destroy(Resource *resource) override
399  {
400  wl_resource_destroy(resource->handle);
401  }
402  TabletPadV2Interface *m_pad = nullptr;
403  TabletPadStripV2Interface *const q;
404 };
405 
406 TabletPadStripV2Interface::TabletPadStripV2Interface(TabletPadV2Interface *parent)
407  : QObject(parent)
408  , d(new TabletPadStripV2InterfacePrivate(this))
409 {
410  d->m_pad = parent;
411 }
412 
413 TabletPadStripV2Interface::~TabletPadStripV2Interface() = default;
414 
415 void TabletPadStripV2Interface::sendFrame(quint32 time)
416 {
417  d->send_frame(d->resourceForSurface(d->m_pad->currentSurface()), time);
418 }
419 
420 void TabletPadStripV2Interface::sendPosition(quint32 position)
421 {
422  d->send_position(d->resourceForSurface(d->m_pad->currentSurface()), position);
423 }
424 
425 void TabletPadStripV2Interface::sendSource(Source source)
426 {
427  d->send_source(d->resourceForSurface(d->m_pad->currentSurface()), source);
428 }
429 
430 void TabletPadStripV2Interface::sendStop()
431 {
432  d->send_stop(d->resourceForSurface(d->m_pad->currentSurface()));
433 }
434 
435 class TabletPadGroupV2InterfacePrivate : public QtWaylandServer::zwp_tablet_pad_group_v2
436 {
437 public:
438  TabletPadGroupV2InterfacePrivate(quint32 currentMode, TabletPadGroupV2Interface *q)
439  : zwp_tablet_pad_group_v2()
440  , q(q)
441  , m_currentMode(currentMode)
442  {
443  }
444 
445  wl_resource *resourceForSurface(SurfaceInterface *surface) const
446  {
447  ClientConnection *client = surface->client();
448  Resource *r = resourceMap().value(*client);
449  return r ? r->handle : nullptr;
450  }
451 
452  void zwp_tablet_pad_group_v2_destroy(Resource *resource) override
453  {
454  wl_resource_destroy(resource->handle);
455  }
456 
457  TabletPadGroupV2Interface *const q;
458  TabletPadV2Interface *m_pad = nullptr;
459  quint32 m_currentMode;
460 };
461 
462 TabletPadGroupV2Interface::TabletPadGroupV2Interface(quint32 currentMode, TabletPadV2Interface *parent)
463  : QObject(parent)
464  , d(new TabletPadGroupV2InterfacePrivate(currentMode, this))
465 {
466  d->m_pad = parent;
467 }
468 
469 TabletPadGroupV2Interface::~TabletPadGroupV2Interface() = default;
470 
471 void TabletPadGroupV2Interface::sendModeSwitch(quint32 time, quint32 serial, quint32 mode)
472 {
473  d->m_currentMode = mode;
474  d->send_mode_switch(d->resourceForSurface(d->m_pad->currentSurface()), time, serial, mode);
475 }
476 
477 class TabletPadV2InterfacePrivate : public QtWaylandServer::zwp_tablet_pad_v2
478 {
479 public:
480  TabletPadV2InterfacePrivate(const QString &path,
481  quint32 buttons,
482  quint32 rings,
483  quint32 strips,
484  quint32 modes,
485  quint32 currentMode,
486  Display *display,
487  TabletPadV2Interface *q)
488  : zwp_tablet_pad_v2()
489  , q(q)
490  , m_path(path)
491  , m_buttons(buttons)
492  , m_modes(modes)
493  , m_padGroup(new TabletPadGroupV2Interface(currentMode, q))
494  , m_display(display)
495  {
496  for (uint i = 0; i < buttons; ++i) {
497  m_buttons[i] = i;
498  }
499 
500  m_rings.reserve(rings);
501  for (quint32 i = 0; i < rings; ++i) {
502  m_rings += new TabletPadRingV2Interface(q);
503  }
504 
505  m_strips.reserve(strips);
506  for (quint32 i = 0; i < strips; ++i) {
507  m_strips += new TabletPadStripV2Interface(q);
508  }
509  }
510 
511  ~TabletPadV2InterfacePrivate() override
512  {
513  qDeleteAll(m_rings);
514  qDeleteAll(m_strips);
515  }
516 
517  void zwp_tablet_pad_v2_destroy(Resource *resource) override
518  {
519  wl_resource_destroy(resource->handle);
520  }
521 
522  void zwp_tablet_pad_v2_set_feedback(Resource *resource, quint32 button, const QString &description, quint32 serial) override
523  {
524  Q_EMIT q->feedback(m_display->getConnection(resource->client()), button, description, serial);
525  }
526 
527  wl_resource *resourceForSurface(SurfaceInterface *surface) const
528  {
529  ClientConnection *client = surface->client();
530  Resource *r = resourceMap().value(*client);
531  return r ? r->handle : nullptr;
532  }
533 
534  TabletPadV2Interface *const q;
535 
536  const QString m_path;
537  QVector<quint32> m_buttons;
538  const int m_modes;
539 
542  TabletPadGroupV2Interface *const m_padGroup;
543  TabletSeatV2Interface *m_seat = nullptr;
544  SurfaceInterface *m_currentSurface = nullptr;
545  Display *const m_display;
546 };
547 
548 TabletPadV2Interface::TabletPadV2Interface(const QString &path,
549  quint32 buttons,
550  quint32 rings,
551  quint32 strips,
552  quint32 modes,
553  quint32 currentMode,
554  Display *display,
555  TabletSeatV2Interface *parent)
556  : QObject(parent)
557  , d(new TabletPadV2InterfacePrivate(path, buttons, rings, strips, modes, currentMode, display, this))
558 {
559  d->m_seat = parent;
560 }
561 
562 TabletPadV2Interface::~TabletPadV2Interface()
563 {
564  const auto tabletPadResources = d->resourceMap();
565  for (TabletPadV2InterfacePrivate::Resource *resource : tabletPadResources) {
566  d->send_removed(resource->handle);
567  }
568 }
569 
570 void TabletPadV2Interface::sendButton(quint32 time, quint32 button, bool pressed)
571 {
572  d->send_button(d->resourceForSurface(currentSurface()), time, button, pressed);
573 }
574 
575 TabletPadRingV2Interface *TabletPadV2Interface::ring(uint at) const
576 {
577  return d->m_rings[at];
578 }
579 
580 TabletPadStripV2Interface *TabletPadV2Interface::strip(uint at) const
581 {
582  return d->m_strips[at];
583 }
584 
585 void TabletPadV2Interface::setCurrentSurface(SurfaceInterface *surface, TabletV2Interface *tablet)
586 {
587  if (surface == d->m_currentSurface) {
588  return;
589  }
590 
591  if (d->m_currentSurface) {
592  d->send_leave(d->m_display->nextSerial(), surface->resource());
593  }
594 
595  d->m_currentSurface = surface;
596  if (surface) {
597  wl_resource *tabletResource = tablet->d->resourceForSurface(surface);
598 
599  d->send_enter(d->resourceForSurface(surface), d->m_display->nextSerial(), tabletResource, surface->resource());
600  d->m_padGroup->sendModeSwitch(0, d->m_display->nextSerial(), d->m_padGroup->d->m_currentMode);
601  }
602 }
603 
604 SurfaceInterface *TabletPadV2Interface::currentSurface() const
605 {
606  return d->m_currentSurface;
607 }
608 
609 class TabletSeatV2InterfacePrivate : public QtWaylandServer::zwp_tablet_seat_v2
610 {
611 public:
612  TabletSeatV2InterfacePrivate(Display *display, TabletSeatV2Interface *q)
613  : zwp_tablet_seat_v2()
614  , q(q)
615  , m_display(display)
616  {
617  }
618 
619  void zwp_tablet_seat_v2_bind_resource(Resource *resource) override
620  {
621  for (auto tablet : qAsConst(m_tablets)) {
622  sendTabletAdded(resource, tablet);
623  }
624 
625  for (auto pad : qAsConst(m_pads)) {
626  sendPadAdded(resource, pad);
627  }
628 
629  for (auto *tool : qAsConst(m_tools)) {
630  sendToolAdded(resource, tool);
631  }
632  }
633 
634  void sendToolAdded(Resource *resource, TabletToolV2Interface *tool)
635  {
636  wl_resource *toolResource = tool->d->add(resource->client(), resource->version())->handle;
637  send_tool_added(resource->handle, toolResource);
638 
639  tool->d->send_type(toolResource, tool->d->m_type);
640  tool->d->send_hardware_serial(toolResource, tool->d->m_hardwareSerialHigh, tool->d->m_hardwareSerialLow);
641  tool->d->send_hardware_id_wacom(toolResource, tool->d->m_hardwareIdHigh, tool->d->m_hardwareIdLow);
642  for (uint32_t cap : qAsConst(tool->d->m_capabilities)) {
643  tool->d->send_capability(toolResource, cap);
644  }
645  tool->d->send_done(toolResource);
646  }
647  void sendTabletAdded(Resource *resource, TabletV2Interface *tablet)
648  {
649  wl_resource *tabletResource = tablet->d->add(resource->client(), resource->version())->handle;
650  send_tablet_added(resource->handle, tabletResource);
651 
652  tablet->d->send_name(tabletResource, tablet->d->m_name);
653  if (tablet->d->m_vendorId && tablet->d->m_productId) {
654  tablet->d->send_id(tabletResource, tablet->d->m_vendorId, tablet->d->m_productId);
655  }
656  for (const QString &path : qAsConst(tablet->d->m_paths)) {
657  tablet->d->send_path(tabletResource, path);
658  }
659  tablet->d->send_done(tabletResource);
660  }
661 
662  void sendPadAdded(Resource *resource, TabletPadV2Interface *pad)
663  {
664  wl_resource *tabletResource = pad->d->add(resource->client(), resource->version())->handle;
665  send_pad_added(resource->handle, tabletResource);
666 
667  pad->d->send_buttons(tabletResource, pad->d->m_buttons.size());
668  pad->d->send_path(tabletResource, pad->d->m_path);
669 
670  auto groupResource = pad->d->m_padGroup->d->add(resource->client(), resource->version());
671  pad->d->send_group(tabletResource, groupResource->handle);
672  pad->d->m_padGroup->d->send_modes(groupResource->handle, pad->d->m_modes);
673 
674  pad->d->m_padGroup->d->send_buttons(
675  groupResource->handle,
676  QByteArray::fromRawData(reinterpret_cast<const char *>(pad->d->m_buttons.data()), pad->d->m_buttons.size() * sizeof(quint32)));
677 
678  for (auto ring : qAsConst(pad->d->m_rings)) {
679  auto ringResource = ring->d->add(resource->client(), resource->version());
680  pad->d->m_padGroup->d->send_ring(groupResource->handle, ringResource->handle);
681  }
682 
683  for (auto strip : qAsConst(pad->d->m_strips)) {
684  auto stripResource = strip->d->add(resource->client(), resource->version());
685  pad->d->m_padGroup->d->send_strip(groupResource->handle, stripResource->handle);
686  }
687  pad->d->m_padGroup->d->send_done(groupResource->handle);
688  pad->d->send_done(tabletResource);
689  }
690 
691  TabletSeatV2Interface *const q;
695  Display *const m_display;
696 };
697 
698 TabletSeatV2Interface::TabletSeatV2Interface(Display *display, QObject *parent)
699  : QObject(parent)
700  , d(new TabletSeatV2InterfacePrivate(display, this))
701 {
702 }
703 
704 TabletSeatV2Interface::~TabletSeatV2Interface() = default;
705 
706 TabletToolV2Interface *TabletSeatV2Interface::addTool(TabletToolV2Interface::Type type,
707  quint64 hardwareSerial,
708  quint64 hardwareId,
709  const QVector<TabletToolV2Interface::Capability> &capabilities)
710 {
711  constexpr auto MAX_UINT_32 = std::numeric_limits<quint32>::max();
712  auto tool = new TabletToolV2Interface(d->m_display,
713  type,
714  hardwareSerial >> 32,
715  hardwareSerial & MAX_UINT_32,
716  hardwareId >> 32,
717  hardwareId & MAX_UINT_32,
718  capabilities,
719  this);
720  for (QtWaylandServer::zwp_tablet_seat_v2::Resource *resource : d->resourceMap()) {
721  d->sendToolAdded(resource, tool);
722  }
723 
724  d->m_tools.append(tool);
725  QObject::connect(tool, &QObject::destroyed, this, [this](QObject *object) {
726  auto tti = static_cast<TabletToolV2Interface *>(object);
727  d->m_tools.removeAll(tti);
728  });
729  return tool;
730 }
731 
732 TabletV2Interface *
733 TabletSeatV2Interface::addTablet(uint32_t vendorId, uint32_t productId, const QString &sysname, const QString &name, const QStringList &paths)
734 {
735  Q_ASSERT(!d->m_tablets.contains(sysname));
736 
737  auto iface = new TabletV2Interface(vendorId, productId, name, paths, this);
738 
739  for (QtWaylandServer::zwp_tablet_seat_v2::Resource *r : d->resourceMap()) {
740  d->sendTabletAdded(r, iface);
741  }
742 
743  d->m_tablets[sysname] = iface;
744  return iface;
745 }
746 
747 TabletPadV2Interface *TabletSeatV2Interface::addTabletPad(const QString &sysname,
748  const QString &name,
749  const QStringList &paths,
750  quint32 buttons,
751  quint32 rings,
752  quint32 strips,
753  quint32 modes,
754  quint32 currentMode,
755  TabletV2Interface *tablet)
756 {
757  Q_UNUSED(name);
758  auto iface = new TabletPadV2Interface(paths.at(0), buttons, rings, strips, modes, currentMode, d->m_display, this);
759  iface->d->m_seat = this;
760  for (auto r : d->resourceMap()) {
761  d->sendPadAdded(r, iface);
762  }
763 
764  tablet->d->m_pad = iface;
765 
766  d->m_pads[sysname] = iface;
767  return iface;
768 }
769 
770 void TabletSeatV2Interface::removeDevice(const QString &sysname)
771 {
772  delete d->m_tablets.take(sysname);
773  delete d->m_pads.take(sysname);
774 }
775 
776 TabletToolV2Interface *TabletSeatV2Interface::toolByHardwareId(quint64 hardwareId) const
777 {
778  for (TabletToolV2Interface *tool : qAsConst(d->m_tools)) {
779  if (tool->d->hardwareId() == hardwareId) {
780  return tool;
781  }
782  }
783  return nullptr;
784 }
785 
786 TabletToolV2Interface *TabletSeatV2Interface::toolByHardwareSerial(quint64 hardwareSerial, TabletToolV2Interface::Type type) const
787 {
788  for (TabletToolV2Interface *tool : qAsConst(d->m_tools)) {
789  if (tool->d->hardwareSerial() == hardwareSerial && tool->d->m_type == type)
790  return tool;
791  }
792  return nullptr;
793 }
794 
795 TabletPadV2Interface *TabletSeatV2Interface::padByName(const QString &name) const
796 {
797  Q_ASSERT(d->m_pads.contains(name));
798  return d->m_pads.value(name);
799 }
800 
801 class TabletManagerV2InterfacePrivate : public QtWaylandServer::zwp_tablet_manager_v2
802 {
803 public:
804  TabletManagerV2InterfacePrivate(Display *display, TabletManagerV2Interface *q)
805  : zwp_tablet_manager_v2(*display, s_version)
806  , q(q)
807  , m_display(display)
808  {
809  }
810 
811  void zwp_tablet_manager_v2_get_tablet_seat(Resource *resource, uint32_t tablet_seat, struct ::wl_resource *seat_resource) override
812  {
813  SeatInterface *seat = SeatInterface::get(seat_resource);
814  TabletSeatV2Interface *tsi = get(seat);
815  tsi->d->add(resource->client(), tablet_seat, s_version);
816  }
817 
818  TabletSeatV2Interface *get(SeatInterface *seat)
819  {
820  TabletSeatV2Interface *&tabletSeat = m_seats[seat];
821  if (!tabletSeat) {
822  tabletSeat = new TabletSeatV2Interface(m_display, q);
823  }
824  return tabletSeat;
825  }
826 
827  TabletManagerV2Interface *const q;
828  Display *const m_display;
830 };
831 
832 TabletManagerV2Interface::TabletManagerV2Interface(Display *display, QObject *parent)
833  : QObject(parent)
834  , d(new TabletManagerV2InterfacePrivate(display, this))
835 {
836 }
837 
838 TabletSeatV2Interface *TabletManagerV2Interface::seat(SeatInterface *seat) const
839 {
840  return d->get(seat);
841 }
842 
843 bool TabletSeatV2Interface::isClientSupported(ClientConnection *client) const
844 {
845  return d->resourceMap().value(*client);
846 }
847 
848 TabletManagerV2Interface::~TabletManagerV2Interface() = default;
849 
850 } // namespace KWaylandServer
const T & at(int i) const const
T * get() const const
QByteArray fromRawData(const char *data, int size)
qreal x() const const
qreal y() const const
static SurfaceInterface * get(wl_resource *native)
void update(Part *part, const QByteArray &data, qint64 dataSize)
wl_resource * resource() const
Returns the Wayland resource corresponding to this SurfaceInterface.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
void destroyed(QObject *obj)
Q_EMITQ_EMIT
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 23 2021 23:08:28 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.