KWayland

qtsurfaceextension_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2015 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 "qtsurfaceextension_interface.h"
7 #include "display.h"
8 #include "global_p.h"
9 #include "resource_p.h"
10 #include "surface_interface.h"
11 
12 #include <QTimer>
13 #include <QVariant>
14 
15 #include <wayland-qt-surface-extension-server-protocol.h>
16 #include <wayland-server.h>
17 
18 namespace KWayland
19 {
20 namespace Server
21 {
22 class QtSurfaceExtensionInterface::Private : public Global::Private
23 {
24 public:
25  Private(QtSurfaceExtensionInterface *q, Display *d);
26 
28 
29 private:
30  static void createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface);
31  void bind(wl_client *client, uint32_t version, uint32_t id) override;
32  void createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface, wl_resource *parentResource);
33 
34  QtSurfaceExtensionInterface *q;
35  static const struct qt_surface_extension_interface s_interface;
36  static const quint32 s_version;
37 };
38 
39 const quint32 QtSurfaceExtensionInterface::Private::s_version = 1;
40 
41 QtSurfaceExtensionInterface::Private::Private(QtSurfaceExtensionInterface *q, Display *d)
42  : Global::Private(d, &qt_surface_extension_interface, s_version)
43  , q(q)
44 {
45 }
46 
47 #ifndef K_DOXYGEN
48 const struct qt_surface_extension_interface QtSurfaceExtensionInterface::Private::s_interface = {createSurfaceCallback};
49 #endif
50 
51 class QtExtendedSurfaceInterface::Private : public Resource::Private
52 {
53 public:
54  Private(QtExtendedSurfaceInterface *q, QtSurfaceExtensionInterface *shell, SurfaceInterface *surface, wl_resource *parentResource);
55 
56  SurfaceInterface *surface;
57 
58 private:
59  // interface callbacks
60  static void updateGenericPropertyCallback(wl_client *client, wl_resource *resource, const char *name, wl_array *value);
61  static void setContentOrientationMaskCallback(wl_client *client, wl_resource *resource, int32_t orientation);
62  static void setWindowFlagsCallback(wl_client *client, wl_resource *resource, int32_t flags);
63  static void raiseCallback(wl_client *client, wl_resource *resource);
64  static void lowerCallback(wl_client *client, wl_resource *resource);
65 
66  QtExtendedSurfaceInterface *q_func()
67  {
68  return reinterpret_cast<QtExtendedSurfaceInterface *>(q);
69  }
70 
71  static const struct qt_extended_surface_interface s_interface;
72 };
73 
74 QtSurfaceExtensionInterface::QtSurfaceExtensionInterface(Display *display, QObject *parent)
75  : Global(new Private(this, display), parent)
76 {
77 }
78 
79 QtSurfaceExtensionInterface::~QtSurfaceExtensionInterface() = default;
80 
81 void QtSurfaceExtensionInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
82 {
83  auto c = display->getConnection(client);
84  wl_resource *shell = c->createResource(&qt_surface_extension_interface, qMin(version, s_version), id);
85  if (!shell) {
86  wl_client_post_no_memory(client);
87  return;
88  }
89  wl_resource_set_implementation(shell, &s_interface, this, nullptr);
90 }
91 
92 void QtSurfaceExtensionInterface::Private::createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface)
93 {
94  auto s = reinterpret_cast<QtSurfaceExtensionInterface::Private *>(wl_resource_get_user_data(resource));
95  s->createSurface(client, wl_resource_get_version(resource), id, SurfaceInterface::get(surface), resource);
96 }
97 
98 void QtSurfaceExtensionInterface::Private::createSurface(wl_client *client,
99  uint32_t version,
100  uint32_t id,
101  SurfaceInterface *surface,
102  wl_resource *parentResource)
103 {
104  auto it = std::find_if(surfaces.constBegin(), surfaces.constEnd(), [surface](QtExtendedSurfaceInterface *s) {
105  return surface == s->surface();
106  });
107  if (it != surfaces.constEnd()) {
108  wl_resource_post_error(surface->resource(), WL_DISPLAY_ERROR_INVALID_OBJECT, "Qt Surface Extension already created");
109  return;
110  }
111  QtExtendedSurfaceInterface *shellSurface = new QtExtendedSurfaceInterface(q, surface, parentResource);
112  surfaces << shellSurface;
113  QObject::connect(shellSurface, &QtExtendedSurfaceInterface::destroyed, q, [this, shellSurface] {
114  surfaces.removeAll(shellSurface);
115  });
116  shellSurface->d->create(display->getConnection(client), version, id);
117  Q_EMIT q->surfaceCreated(shellSurface);
118 }
119 
120 /*********************************
121  * ShellSurfaceInterface
122  *********************************/
123 QtExtendedSurfaceInterface::Private::Private(QtExtendedSurfaceInterface *q,
124  QtSurfaceExtensionInterface *shell,
125  SurfaceInterface *surface,
126  wl_resource *parentResource)
127  : Resource::Private(q, shell, parentResource, &qt_extended_surface_interface, &s_interface)
128  , surface(surface)
129 {
130 }
131 
132 #ifndef K_DOXYGEN
133 const struct qt_extended_surface_interface QtExtendedSurfaceInterface::Private::s_interface = {updateGenericPropertyCallback,
134  setContentOrientationMaskCallback,
135  setWindowFlagsCallback,
136  raiseCallback,
137  lowerCallback};
138 #endif
139 
140 void QtExtendedSurfaceInterface::Private::lowerCallback(wl_client *client, wl_resource *resource)
141 {
142  Q_UNUSED(client)
143  Q_EMIT cast<Private>(resource)->q_func()->lowerRequested();
144 }
145 
146 void QtExtendedSurfaceInterface::Private::raiseCallback(wl_client *client, wl_resource *resource)
147 {
148  Q_UNUSED(client)
149  Q_EMIT cast<Private>(resource)->q_func()->raiseRequested();
150 }
151 
152 void QtExtendedSurfaceInterface::Private::setContentOrientationMaskCallback(wl_client *client, wl_resource *resource, int32_t orientation)
153 {
154  Q_UNUSED(client)
155  Q_UNUSED(resource)
156  Q_UNUSED(orientation)
157 }
158 
159 void QtExtendedSurfaceInterface::Private::setWindowFlagsCallback(wl_client *client, wl_resource *resource, int32_t flags)
160 {
161  Q_UNUSED(client)
162  Q_UNUSED(resource)
163  Q_UNUSED(flags)
164 }
165 
166 void QtExtendedSurfaceInterface::Private::updateGenericPropertyCallback(wl_client *client, wl_resource *resource, const char *name, wl_array *value)
167 {
168  Q_UNUSED(client)
169  QByteArray data = QByteArray::fromRawData(static_cast<char *>(value->data), value->size);
170 
171  QVariant variantValue;
172  QDataStream ds(data);
173  ds >> variantValue;
174  cast<Private>(resource)->q_func()->setProperty(name, variantValue);
175 }
176 
177 QtExtendedSurfaceInterface::QtExtendedSurfaceInterface(QtSurfaceExtensionInterface *shell, SurfaceInterface *parent, wl_resource *parentResource)
178  : Resource(new Private(this, shell, parent, parentResource))
179 {
180  auto unsetSurface = [this] {
181  Q_D();
182  d->surface = nullptr;
183  };
184  connect(parent, &Resource::unbound, this, unsetSurface);
185  connect(parent, &QObject::destroyed, this, unsetSurface);
186 }
187 
188 QtExtendedSurfaceInterface::~QtExtendedSurfaceInterface() = default;
189 
190 SurfaceInterface *QtExtendedSurfaceInterface::surface() const
191 {
192  Q_D();
193  return d->surface;
194 }
195 
196 QtSurfaceExtensionInterface *QtExtendedSurfaceInterface::shell() const
197 {
198  Q_D();
199  return reinterpret_cast<QtSurfaceExtensionInterface *>(d->global);
200 }
201 
202 QtExtendedSurfaceInterface::Private *QtExtendedSurfaceInterface::d_func() const
203 {
204  return reinterpret_cast<QtExtendedSurfaceInterface::Private *>(d.data());
205 }
206 
207 void QtExtendedSurfaceInterface::close()
208 {
209  Q_D();
210  if (!d->resource) {
211  return;
212  }
213  qt_extended_surface_send_close(d->resource);
214  d->client->flush();
215 }
216 
217 }
218 }
ClientConnection * getConnection(wl_client *client)
Gets the ClientConnection for the given client.
Definition: display.cpp:673
static SurfaceInterface * get(wl_resource *native)
void unbound()
This signal is emitted when the client unbound this Resource.
wl_resource * createResource(const wl_interface *interface, quint32 version, quint32 id)
Creates a new wl_resource for the provided interface.
bool setProperty(const char *name, const QVariant &value)
Display * display()
Definition: global.cpp:78
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 Thu Sep 23 2021 22:51:09 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.