KWayland

xdgforeign_v2_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2017 Marco Martin <[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 "xdgforeign_interface.h"
8 #include "xdgforeign_v2_interface_p.h"
9 #include "display.h"
10 #include "global_p.h"
11 #include "resource_p.h"
12 #include "surface_interface_p.h"
13 
14 #include "wayland-xdg-foreign-unstable-v2-server-protocol.h"
15 
16 #include <QUuid>
17 #include <QDebug>
18 
19 namespace KWayland
20 {
21 namespace Server
22 {
23 
24 class Q_DECL_HIDDEN XdgExporterUnstableV2Interface::Private : public Global::Private
25 {
26 public:
27  Private(XdgExporterUnstableV2Interface *q, Display *d, XdgForeignInterface *foreignInterface);
28 
29  XdgForeignInterface *foreignInterface;
31 
32 private:
33  void bind(wl_client *client, uint32_t version, uint32_t id) override;
34 
35  static void unbind(wl_resource *resource);
36  static Private *cast(wl_resource *r) {
37  return reinterpret_cast<Private*>(wl_resource_get_user_data(r));
38  }
39 
40  static void destroyCallback(wl_client *client, wl_resource *resource);
41  static void exportCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * surface);
42 
43  XdgExporterUnstableV2Interface *q;
44  static const struct zxdg_exporter_v2_interface s_interface;
45  static const quint32 s_version;
46 };
47 
48 const quint32 XdgExporterUnstableV2Interface::Private::s_version = 1;
49 
50 #ifndef K_DOXYGEN
51 const struct zxdg_exporter_v2_interface XdgExporterUnstableV2Interface::Private::s_interface = {
52  destroyCallback,
53  exportCallback
54 };
55 #endif
56 
57 XdgExporterUnstableV2Interface::XdgExporterUnstableV2Interface(Display *display, XdgForeignInterface *parent)
58  : Global(new Private(this, display, parent), parent)
59 {
60 }
61 
62 XdgExporterUnstableV2Interface::~XdgExporterUnstableV2Interface()
63 {}
64 
65 XdgExporterUnstableV2Interface::Private *XdgExporterUnstableV2Interface::d_func() const
66 {
67  return reinterpret_cast<Private*>(d.data());
68 }
69 
70 XdgExportedUnstableV2Interface *XdgExporterUnstableV2Interface::exportedSurface(const QString &handle)
71 {
72  Q_D();
73 
74  auto it = d->exportedSurfaces.constFind(handle);
75  if (it != d->exportedSurfaces.constEnd()) {
76  return it.value();
77  }
78  return nullptr;
79 }
80 
81 void XdgExporterUnstableV2Interface::Private::destroyCallback(wl_client *client, wl_resource *resource)
82 {
83  Q_UNUSED(client)
84  Q_UNUSED(resource)
85 }
86 
87 void XdgExporterUnstableV2Interface::Private::exportCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * surface)
88 {
89  auto s = cast(resource);
90  QPointer <XdgExportedUnstableV2Interface> e = new XdgExportedUnstableV2Interface(s->q, surface);
91 
92  e->create(s->display->getConnection(client), wl_resource_get_version(resource), id);
93 
94  if (!e->resource()) {
95  wl_resource_post_no_memory(resource);
96  delete e;
97  return;
98  }
99 
100  const QString handle = QUuid::createUuid().toString();
101 
102  //a surface not exported anymore
103  connect(e.data(), &XdgExportedUnstableV2Interface::unbound,
104  s->q, [s, handle]() {
105  s->exportedSurfaces.remove(handle);
106  emit s->q->surfaceUnexported(handle);
107  });
108 
109  //if the surface dies before this, this dies too
110  connect(SurfaceInterface::get(surface), &Resource::unbound,
111  s->q, [s, e, handle]() {
112  if (e) {
113  e->deleteLater();
114  }
115  s->exportedSurfaces.remove(handle);
116  emit s->q->surfaceUnexported(handle);
117  });
118 
119  s->exportedSurfaces[handle] = e;
120  zxdg_exported_v2_send_handle(e->resource(), handle.toUtf8().constData());
121  emit s->q->surfaceExported(handle, e);
122 }
123 
124 XdgExporterUnstableV2Interface::Private::Private(XdgExporterUnstableV2Interface *q, Display *d,XdgForeignInterface *foreignInterface)
125  : Global::Private(d, &zxdg_exporter_v2_interface, s_version)
126  , foreignInterface(foreignInterface)
127  , q(q)
128 {
129 }
130 
131 void XdgExporterUnstableV2Interface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
132 {
133  auto c = display->getConnection(client);
134  wl_resource *resource = c->createResource(&zxdg_exporter_v2_interface, qMin(version, s_version), id);
135  if (!resource) {
136  wl_client_post_no_memory(client);
137  return;
138  }
139  wl_resource_set_implementation(resource, &s_interface, this, unbind);
140  // TODO: should we track?
141 }
142 
143 void XdgExporterUnstableV2Interface::Private::unbind(wl_resource *resource)
144 {
145  Q_UNUSED(resource)
146  // TODO: implement?
147 }
148 
149 class Q_DECL_HIDDEN XdgImporterUnstableV2Interface::Private : public Global::Private
150 {
151 public:
152  Private(XdgImporterUnstableV2Interface *q, Display *d, XdgForeignInterface *foreignInterface);
153 
154  XdgForeignInterface *foreignInterface;
155 
157 
158  //child->parent hash
160  //parent->child hash
162 
163 private:
164  void bind(wl_client *client, uint32_t version, uint32_t id) override;
165 
166  static void unbind(wl_resource *resource);
167  static Private *cast(wl_resource *r) {
168  return reinterpret_cast<Private*>(wl_resource_get_user_data(r));
169  }
170 
171  static void destroyCallback(wl_client *client, wl_resource *resource);
172  static void importCallback(wl_client *client, wl_resource *resource, uint32_t id, const char * handle);
173 
174  XdgImporterUnstableV2Interface *q;
175  static const struct zxdg_importer_v2_interface s_interface;
176  static const quint32 s_version;
177 };
178 
179 const quint32 XdgImporterUnstableV2Interface::Private::s_version = 1;
180 
181 #ifndef K_DOXYGEN
182 const struct zxdg_importer_v2_interface XdgImporterUnstableV2Interface::Private::s_interface = {
183  destroyCallback,
184  importCallback
185 };
186 #endif
187 
188 XdgImporterUnstableV2Interface::XdgImporterUnstableV2Interface(Display *display, XdgForeignInterface *parent)
189  : Global(new Private(this, display, parent), parent)
190 {
191 }
192 
193 XdgImporterUnstableV2Interface::~XdgImporterUnstableV2Interface()
194 {
195 }
196 
197 XdgImportedUnstableV2Interface *XdgImporterUnstableV2Interface::importedSurface(const QString &handle)
198 {
199  Q_D();
200 
201  auto it = d->importedSurfaces.constFind(handle);
202  if (it != d->importedSurfaces.constEnd()) {
203  return it.value();
204  }
205  return nullptr;
206 }
207 
208 SurfaceInterface *XdgImporterUnstableV2Interface::transientFor(SurfaceInterface *surface)
209 {
210  Q_D();
211 
212  auto it = d->parents.constFind(surface);
213  if (it == d->parents.constEnd()) {
214  return nullptr;
215  }
216  return SurfaceInterface::get((*it)->parentResource());
217 }
218 
219 XdgImporterUnstableV2Interface::Private *XdgImporterUnstableV2Interface::d_func() const
220 {
221  return reinterpret_cast<Private*>(d.data());
222 }
223 
224 void XdgImporterUnstableV2Interface::Private::destroyCallback(wl_client *client, wl_resource *resource)
225 {
226  Q_UNUSED(client)
227  Q_UNUSED(resource)
228 }
229 
230 void XdgImporterUnstableV2Interface::Private::importCallback(wl_client *client, wl_resource *resource, uint32_t id, const char *h)
231 {
232  auto s = cast(resource);
233 
234  Q_ASSERT(s->foreignInterface);
235  const QString handle = QString::fromUtf8(h);
236 
237  XdgExportedUnstableV2Interface *exp = s->foreignInterface->d->exporter->exportedSurface(handle);
238  if (!exp) {
239  zxdg_imported_v2_send_destroyed(resource);
240  return;
241  }
242 
243  wl_resource *surface = exp->parentResource();
244  if (!surface) {
245  zxdg_imported_v2_send_destroyed(resource);
246  return;
247  }
248 
249  QPointer<XdgImportedUnstableV2Interface> imp = new XdgImportedUnstableV2Interface(s->q, surface);
250  imp->create(s->display->getConnection(client), wl_resource_get_version(resource), id);
251 
252  //surface no longer exported
253  connect(exp, &XdgExportedUnstableV2Interface::unbound,
254  s->q, [s, imp, handle]() {
255  //imp valid when the exported is deleted before the imported
256  if (imp) {
257  zxdg_imported_v2_send_destroyed(imp->resource());
258  imp->deleteLater();
259  }
260  s->importedSurfaces.remove(handle);
261  emit s->q->surfaceUnimported(handle);
262  });
263 
264  connect(imp.data(), &XdgImportedUnstableV2Interface::childChanged,
265  s->q, [s, imp](SurfaceInterface *child) {
266  //remove any previous association
267  auto it = s->children.find(imp);
268  if (it != s->children.end()) {
269  s->parents.remove(*it);
270  s->children.erase(it);
271  }
272 
273  s->parents[child] = imp;
274  s->children[imp] = child;
275  SurfaceInterface *parent = SurfaceInterface::get(imp->parentResource());
276  emit s->q->transientChanged(child, parent);
277 
278  //child surface destroyed
279  connect(child, &Resource::unbound,
280  s->q, [s, child]() {
281  auto it = s->parents.find(child);
282  if (it != s->parents.end()) {
283  KWayland::Server::XdgImportedUnstableV2Interface* parent = *it;
284  s->children.remove(*it);
285  s->parents.erase(it);
286  emit s->q->transientChanged(nullptr, SurfaceInterface::get(parent->parentResource()));
287  }
288  });
289  });
290 
291  //surface no longer imported
292  connect(imp.data(), &XdgImportedUnstableV2Interface::unbound,
293  s->q, [s, handle, imp]() {
294  s->importedSurfaces.remove(handle);
295  emit s->q->surfaceUnimported(handle);
296 
297  auto it = s->children.find(imp);
298  if (it != s->children.end()) {
300  s->parents.remove(*it);
301  s->children.erase(it);
302  emit s->q->transientChanged(child, nullptr);
303  }
304  });
305 
306  if (!imp->resource()) {
307  wl_resource_post_no_memory(resource);
308  delete imp;
309  return;
310  }
311 
312  s->importedSurfaces[handle] = imp;
313  emit s->q->surfaceImported(handle, imp);
314 }
315 
316 XdgImporterUnstableV2Interface::Private::Private(XdgImporterUnstableV2Interface *q, Display *d, XdgForeignInterface *foreignInterface)
317  : Global::Private(d, &zxdg_importer_v2_interface, s_version)
318  , foreignInterface(foreignInterface)
319  , q(q)
320 {
321 }
322 
323 void XdgImporterUnstableV2Interface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
324 {
325  auto c = display->getConnection(client);
326  wl_resource *resource = c->createResource(&zxdg_importer_v2_interface, qMin(version, s_version), id);
327  if (!resource) {
328  wl_client_post_no_memory(client);
329  return;
330  }
331  wl_resource_set_implementation(resource, &s_interface, this, unbind);
332  // TODO: should we track?
333 }
334 
335 void XdgImporterUnstableV2Interface::Private::unbind(wl_resource *resource)
336 {
337  Q_UNUSED(resource)
338  // TODO: implement?
339 }
340 
341 class Q_DECL_HIDDEN XdgExportedUnstableV2Interface::Private : public Resource::Private
342 {
343 public:
344  Private(XdgExportedUnstableV2Interface *q, XdgExporterUnstableV2Interface *c, wl_resource *parentResource);
345  ~Private();
346 
347 private:
348 
349  XdgExportedUnstableV2Interface *q_func() {
350  return reinterpret_cast<XdgExportedUnstableV2Interface *>(q);
351  }
352 
353  static const struct zxdg_exported_v2_interface s_interface;
354 };
355 
356 #ifndef K_DOXYGEN
357 const struct zxdg_exported_v2_interface XdgExportedUnstableV2Interface::Private::s_interface = {
358  resourceDestroyedCallback
359 };
360 #endif
361 
362 XdgExportedUnstableV2Interface::XdgExportedUnstableV2Interface(XdgExporterUnstableV2Interface *parent, wl_resource *parentResource)
363  : Resource(new Private(this, parent, parentResource))
364 {
365 }
366 
367 XdgExportedUnstableV2Interface::~XdgExportedUnstableV2Interface()
368 {}
369 
370 XdgExportedUnstableV2Interface::Private *XdgExportedUnstableV2Interface::d_func() const
371 {
372  return reinterpret_cast<Private*>(d.data());
373 }
374 
375 XdgExportedUnstableV2Interface::Private::Private(XdgExportedUnstableV2Interface *q, XdgExporterUnstableV2Interface *c, wl_resource *parentResource)
376  : Resource::Private(q, c, parentResource, &zxdg_exported_v2_interface, &s_interface)
377 {
378 }
379 
380 XdgExportedUnstableV2Interface::Private::~Private()
381 {}
382 
383 class Q_DECL_HIDDEN XdgImportedUnstableV2Interface::Private : public Resource::Private
384 {
385 public:
386  Private(XdgImportedUnstableV2Interface *q, XdgImporterUnstableV2Interface *c, wl_resource *parentResource);
387  ~Private();
388 
390 
391 private:
392  static void setParentOfCallback(wl_client *client, wl_resource *resource, wl_resource * surface);
393 
394  XdgImportedUnstableV2Interface *q_func() {
395  return reinterpret_cast<XdgImportedUnstableV2Interface *>(q);
396  }
397 
398  static const struct zxdg_imported_v2_interface s_interface;
399 };
400 
401 #ifndef K_DOXYGEN
402 const struct zxdg_imported_v2_interface XdgImportedUnstableV2Interface::Private::s_interface = {
403  resourceDestroyedCallback,
404  setParentOfCallback
405 };
406 #endif
407 
408 XdgImportedUnstableV2Interface::XdgImportedUnstableV2Interface(XdgImporterUnstableV2Interface *parent, wl_resource *parentResource)
409  : Resource(new Private(this, parent, parentResource))
410 {
411 }
412 
413 XdgImportedUnstableV2Interface::~XdgImportedUnstableV2Interface()
414 {}
415 
416 XdgImportedUnstableV2Interface::Private *XdgImportedUnstableV2Interface::d_func() const
417 {
418  return reinterpret_cast<Private*>(d.data());
419 }
420 
421 SurfaceInterface *XdgImportedUnstableV2Interface::child() const
422 {
423  Q_D();
424  return d->parentOf.data();
425 }
426 
427 void XdgImportedUnstableV2Interface::Private::setParentOfCallback(wl_client *client, wl_resource *resource, wl_resource * surface)
428 {
429  Q_UNUSED(client)
430 
431  auto s = cast<Private>(resource);
432  SurfaceInterface *surf = SurfaceInterface::get(surface);
433 
434  if (!surf) {
435  return;
436  }
437 
438  s->parentOf = surf;
439  emit s->q_func()->childChanged(surf);
440 }
441 
442 XdgImportedUnstableV2Interface::Private::Private(XdgImportedUnstableV2Interface *q, XdgImporterUnstableV2Interface *c, wl_resource *parentResource)
443  : Resource::Private(q, c, parentResource, &zxdg_imported_v2_interface, &s_interface)
444 {
445 }
446 
447 XdgImportedUnstableV2Interface::Private::~Private()
448 {}
449 
450 }
451 }
452 
T * data() const const
const QObjectList & children() const const
QString fromUtf8(const char *str, int size)
Resource representing a wl_surface.
const char * constData() const const
T * data() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
QString toString() const const
QUuid createUuid()
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Aug 7 2020 22:48:20 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.