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

KDE's Doxygen guidelines are available online.