KWayland

datadevice.cpp
1 /*
2  SPDX-FileCopyrightText: 2014 Martin Gräßlin <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "datadevice.h"
7 #include "datasource.h"
8 #include "surface.h"
9 #include "wayland_pointer_p.h"
10 // Qt
11 #include <QPointer>
12 // Wayland
13 #include <wayland-client-protocol.h>
14 
15 namespace KWayland
16 {
17 namespace Client
18 {
19 class Q_DECL_HIDDEN DataDevice::Private
20 {
21 public:
22  explicit Private(DataDevice *q);
23  void setup(wl_data_device *d);
24 
25  WaylandPointer<wl_data_device, wl_data_device_release> device;
26  QScopedPointer<DataOffer> selectionOffer;
27  struct Drag {
28  QPointer<DataOffer> offer;
29  QPointer<Surface> surface;
30  };
31  Drag drag;
32 
33 private:
34  void dataOffer(wl_data_offer *id);
35  void selection(wl_data_offer *id);
36  void dragEnter(quint32 serial, const QPointer<Surface> &surface, const QPointF &relativeToSurface, wl_data_offer *dataOffer);
37  void dragLeft();
38  static void dataOfferCallback(void *data, wl_data_device *dataDevice, wl_data_offer *id);
39  static void enterCallback(void *data, wl_data_device *dataDevice, uint32_t serial, wl_surface *surface, wl_fixed_t x, wl_fixed_t y, wl_data_offer *id);
40  static void leaveCallback(void *data, wl_data_device *dataDevice);
41  static void motionCallback(void *data, wl_data_device *dataDevice, uint32_t time, wl_fixed_t x, wl_fixed_t y);
42  static void dropCallback(void *data, wl_data_device *dataDevice);
43  static void selectionCallback(void *data, wl_data_device *dataDevice, wl_data_offer *id);
44 
45  static const struct wl_data_device_listener s_listener;
46 
47  DataDevice *q;
48  DataOffer *lastOffer = nullptr;
49 };
50 
51 const wl_data_device_listener DataDevice::Private::s_listener =
52  {dataOfferCallback, enterCallback, leaveCallback, motionCallback, dropCallback, selectionCallback};
53 
54 void DataDevice::Private::dataOfferCallback(void *data, wl_data_device *dataDevice, wl_data_offer *id)
55 {
56  auto d = reinterpret_cast<Private *>(data);
57  Q_ASSERT(d->device == dataDevice);
58  d->dataOffer(id);
59 }
60 
61 void DataDevice::Private::dataOffer(wl_data_offer *id)
62 {
63  Q_ASSERT(!lastOffer);
64  lastOffer = new DataOffer(q, id);
65  Q_ASSERT(lastOffer->isValid());
66 }
67 
68 void DataDevice::Private::enterCallback(void *data,
69  wl_data_device *dataDevice,
70  uint32_t serial,
71  wl_surface *surface,
72  wl_fixed_t x,
73  wl_fixed_t y,
74  wl_data_offer *id)
75 {
76  auto d = reinterpret_cast<Private *>(data);
77  Q_ASSERT(d->device == dataDevice);
78  d->dragEnter(serial, QPointer<Surface>(Surface::get(surface)), QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), id);
79 }
80 
81 void DataDevice::Private::dragEnter(quint32 serial, const QPointer<Surface> &surface, const QPointF &relativeToSurface, wl_data_offer *dataOffer)
82 {
83  drag.surface = surface;
84  Q_ASSERT(*lastOffer == dataOffer);
85  drag.offer = lastOffer;
86  lastOffer = nullptr;
87  Q_EMIT q->dragEntered(serial, relativeToSurface);
88 }
89 
90 void DataDevice::Private::leaveCallback(void *data, wl_data_device *dataDevice)
91 {
92  auto d = reinterpret_cast<Private *>(data);
93  Q_ASSERT(d->device == dataDevice);
94  d->dragLeft();
95 }
96 
97 void DataDevice::Private::dragLeft()
98 {
99  if (drag.offer) {
100  delete drag.offer;
101  }
102  drag = Drag();
103  Q_EMIT q->dragLeft();
104 }
105 
106 void DataDevice::Private::motionCallback(void *data, wl_data_device *dataDevice, uint32_t time, wl_fixed_t x, wl_fixed_t y)
107 {
108  auto d = reinterpret_cast<Private *>(data);
109  Q_ASSERT(d->device == dataDevice);
110  Q_EMIT d->q->dragMotion(QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), time);
111 }
112 
113 void DataDevice::Private::dropCallback(void *data, wl_data_device *dataDevice)
114 {
115  auto d = reinterpret_cast<Private *>(data);
116  Q_ASSERT(d->device == dataDevice);
117  Q_EMIT d->q->dropped();
118 }
119 
120 void DataDevice::Private::selectionCallback(void *data, wl_data_device *dataDevice, wl_data_offer *id)
121 {
122  auto d = reinterpret_cast<Private *>(data);
123  Q_ASSERT(d->device == dataDevice);
124  d->selection(id);
125 }
126 
127 void DataDevice::Private::selection(wl_data_offer *id)
128 {
129  if (!id) {
130  selectionOffer.reset();
131  Q_EMIT q->selectionCleared();
132  return;
133  }
134  Q_ASSERT(*lastOffer == id);
135  selectionOffer.reset(lastOffer);
136  lastOffer = nullptr;
137  Q_EMIT q->selectionOffered(selectionOffer.data());
138 }
139 
140 DataDevice::Private::Private(DataDevice *q)
141  : q(q)
142 {
143 }
144 
145 void DataDevice::Private::setup(wl_data_device *d)
146 {
147  Q_ASSERT(d);
148  Q_ASSERT(!device.isValid());
149  device.setup(d);
150  wl_data_device_add_listener(device, &s_listener, this);
151 }
152 
153 DataDevice::DataDevice(QObject *parent)
154  : QObject(parent)
155  , d(new Private(this))
156 {
157 }
158 
159 DataDevice::~DataDevice()
160 {
161  if (d->drag.offer) {
162  delete d->drag.offer;
163  }
164  release();
165 }
166 
167 void DataDevice::destroy()
168 {
169  d->device.destroy();
170 }
171 
173 {
174  d->device.release();
175 }
176 
177 bool DataDevice::isValid() const
178 {
179  return d->device.isValid();
180 }
181 
182 void DataDevice::setup(wl_data_device *dataDevice)
183 {
184  d->setup(dataDevice);
185 }
186 
187 void DataDevice::startDragInternally(quint32 serial, Surface *origin, Surface *icon)
188 {
189  startDrag(serial, nullptr, origin, icon);
190 }
191 
192 namespace
193 {
194 static wl_data_source *dataSource(const DataSource *source)
195 {
196  if (!source) {
197  return nullptr;
198  }
199  return *source;
200 }
201 }
202 
203 void DataDevice::startDrag(quint32 serial, DataSource *source, Surface *origin, Surface *icon)
204 {
205  wl_data_device_start_drag(d->device, dataSource(source), *origin, icon ? (wl_surface *)*icon : nullptr, serial);
206 }
207 
208 void DataDevice::setSelection(quint32 serial, DataSource *source)
209 {
210  wl_data_device_set_selection(d->device, dataSource(source), serial);
211 }
212 
213 void DataDevice::clearSelection(quint32 serial)
214 {
215  setSelection(serial);
216 }
217 
218 DataOffer *DataDevice::offeredSelection() const
219 {
220  return d->selectionOffer.data();
221 }
222 
223 QPointer<Surface> DataDevice::dragSurface() const
224 {
225  return d->drag.surface;
226 }
227 
228 DataOffer *DataDevice::dragOffer() const
229 {
230  return d->drag.offer;
231 }
232 
233 DataDevice::operator wl_data_device *()
234 {
235  return d->device;
236 }
237 
238 DataDevice::operator wl_data_device *() const
239 {
240  return d->device;
241 }
242 
243 }
244 }
virtual void release(quint64 objid)
Wrapper for the wl_surface interface.
Definition: surface.h:43
static Surface * get(wl_surface *native)
Definition: surface.cpp:212
Wrapper for the wl_data_offer interface.
Definition: dataoffer.h:33
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Feb 8 2023 03:59:21 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.