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

KDE's Doxygen guidelines are available online.