KWayland

server_decoration_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 "server_decoration_interface.h"
7 #include "display.h"
8 #include "global_p.h"
9 #include "logging.h"
10 #include "resource_p.h"
11 #include "surface_interface.h"
12 
13 #include <QVector>
14 
15 #include <wayland-server_decoration-server-protocol.h>
16 
17 namespace KWayland
18 {
19 namespace Server
20 {
21 class ServerSideDecorationManagerInterface::Private : public Global::Private
22 {
23 public:
24  Private(ServerSideDecorationManagerInterface *q, Display *d);
25 
27 
28  QVector<wl_resource *> resources;
29 
30 private:
31  void bind(wl_client *client, uint32_t version, uint32_t id) override;
32 
33  static void unbind(wl_resource *resource);
34  static Private *cast(wl_resource *r)
35  {
36  return reinterpret_cast<Private *>(wl_resource_get_user_data(r));
37  }
38 
39  static void createCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface);
40  void create(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface);
41 
42  ServerSideDecorationManagerInterface *q;
43  static const struct org_kde_kwin_server_decoration_manager_interface s_interface;
44  static const quint32 s_version;
45 };
46 
47 const quint32 ServerSideDecorationManagerInterface::Private::s_version = 1;
48 
49 #ifndef K_DOXYGEN
50 const struct org_kde_kwin_server_decoration_manager_interface ServerSideDecorationManagerInterface::Private::s_interface = {createCallback};
51 #endif
52 
53 void ServerSideDecorationManagerInterface::Private::createCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface)
54 {
55  reinterpret_cast<Private *>(wl_resource_get_user_data(resource))->create(client, resource, id, surface);
56 }
57 
58 void ServerSideDecorationManagerInterface::Private::create(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface)
59 {
60  SurfaceInterface *s = SurfaceInterface::get(surface);
61  if (!s) {
62  // TODO: send error?
63  qCWarning(KWAYLAND_SERVER) << "ServerSideDecorationInterface requested for non existing SurfaceInterface";
64  return;
65  }
66  ServerSideDecorationInterface *decoration = new ServerSideDecorationInterface(q, s, resource);
67  decoration->create(display->getConnection(client), wl_resource_get_version(resource), id);
68  if (!decoration->resource()) {
69  wl_resource_post_no_memory(resource);
70  delete decoration;
71  return;
72  }
73  decoration->setMode(defaultMode);
74  Q_EMIT q->decorationCreated(decoration);
75 }
76 
78 {
79  return d_func()->defaultMode;
80 }
81 
82 ServerSideDecorationManagerInterface::Private::Private(ServerSideDecorationManagerInterface *q, Display *d)
83  : Global::Private(d, &org_kde_kwin_server_decoration_manager_interface, s_version)
84  , q(q)
85 {
86 }
87 
88 namespace
89 {
90 static uint32_t modeWayland(ServerSideDecorationManagerInterface::Mode mode)
91 {
92  switch (mode) {
94  return ORG_KDE_KWIN_SERVER_DECORATION_MODE_NONE;
95  break;
97  return ORG_KDE_KWIN_SERVER_DECORATION_MODE_CLIENT;
98  break;
100  return ORG_KDE_KWIN_SERVER_DECORATION_MODE_SERVER;
101  break;
102  default:
103  Q_UNREACHABLE();
104  }
105 }
106 }
107 
108 void ServerSideDecorationManagerInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
109 {
110  auto c = display->getConnection(client);
111  wl_resource *resource = c->createResource(&org_kde_kwin_server_decoration_manager_interface, qMin(version, s_version), id);
112  if (!resource) {
113  wl_client_post_no_memory(client);
114  return;
115  }
116  wl_resource_set_implementation(resource, &s_interface, this, unbind);
117 
118  resources << resource;
119 
120  org_kde_kwin_server_decoration_manager_send_default_mode(resource, modeWayland(defaultMode));
121  c->flush();
122 }
123 
124 void ServerSideDecorationManagerInterface::Private::unbind(wl_resource *resource)
125 {
126  cast(resource)->resources.removeAll(resource);
127 }
128 
129 ServerSideDecorationManagerInterface::ServerSideDecorationManagerInterface(Display *display, QObject *parent)
130  : Global(new Private(this, display), parent)
131 {
132 }
133 
134 ServerSideDecorationManagerInterface::~ServerSideDecorationManagerInterface() = default;
135 
136 ServerSideDecorationManagerInterface::Private *ServerSideDecorationManagerInterface::d_func() const
137 {
138  return reinterpret_cast<ServerSideDecorationManagerInterface::Private *>(d.data());
139 }
140 
142 {
143  Q_D();
144  d->defaultMode = mode;
145  const uint32_t wlMode = modeWayland(mode);
146  for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); it++) {
147  org_kde_kwin_server_decoration_manager_send_default_mode(*it, wlMode);
148  }
149 }
150 
151 class ServerSideDecorationInterface::Private : public Resource::Private
152 {
153 public:
155  ~Private() override;
156 
159 
161 
162 private:
163  static void requestModeCallback(wl_client *client, wl_resource *resource, uint32_t mode);
164 
166  {
167  return reinterpret_cast<ServerSideDecorationInterface *>(q);
168  }
169 
170  static const struct org_kde_kwin_server_decoration_interface s_interface;
171  static QVector<Private *> s_all;
172 };
173 
174 #ifndef K_DOXYGEN
175 const struct org_kde_kwin_server_decoration_interface ServerSideDecorationInterface::Private::s_interface = {resourceDestroyedCallback, requestModeCallback};
176 QVector<ServerSideDecorationInterface::Private *> ServerSideDecorationInterface::Private::s_all;
177 #endif
178 
179 void ServerSideDecorationInterface::Private::requestModeCallback(wl_client *client, wl_resource *resource, uint32_t mode)
180 {
181  Q_UNUSED(client)
183  switch (mode) {
184  case ORG_KDE_KWIN_SERVER_DECORATION_MODE_NONE:
186  break;
187  case ORG_KDE_KWIN_SERVER_DECORATION_MODE_CLIENT:
189  break;
190  case ORG_KDE_KWIN_SERVER_DECORATION_MODE_SERVER:
192  break;
193  default:
194  // invalid mode
195  qCWarning(KWAYLAND_SERVER) << "Invalid mode:" << mode;
196  return;
197  }
198  Q_EMIT cast<Private>(resource)->q_func()->modeRequested(m);
199 }
200 
201 ServerSideDecorationInterface *ServerSideDecorationInterface::Private::get(SurfaceInterface *s)
202 {
203  auto it = std::find_if(s_all.constBegin(), s_all.constEnd(), [s](Private *p) {
204  return p->surface == s;
205  });
206  if (it == s_all.constEnd()) {
207  return nullptr;
208  }
209  return (*it)->q_func();
210 }
211 
212 ServerSideDecorationInterface::Private::Private(ServerSideDecorationInterface *q,
213  ServerSideDecorationManagerInterface *c,
214  SurfaceInterface *surface,
215  wl_resource *parentResource)
216  : Resource::Private(q, c, parentResource, &org_kde_kwin_server_decoration_interface, &s_interface)
217  , surface(surface)
218 {
219  s_all << this;
220 }
221 
222 ServerSideDecorationInterface::Private::~Private()
223 {
224  s_all.removeAll(this);
225 }
226 
227 ServerSideDecorationInterface::ServerSideDecorationInterface(ServerSideDecorationManagerInterface *parent,
228  SurfaceInterface *surface,
229  wl_resource *parentResource)
230  : Resource(new Private(this, parent, surface, parentResource))
231 {
232 }
233 
234 ServerSideDecorationInterface::~ServerSideDecorationInterface() = default;
235 
237 {
238  Q_D();
239  d->mode = mode;
240  org_kde_kwin_server_decoration_send_mode(resource(), modeWayland(mode));
241  client()->flush();
242 }
243 
245 {
246  Q_D();
247  return d->mode;
248 }
249 
251 {
252  Q_D();
253  return d->surface;
254 }
255 
256 ServerSideDecorationInterface::Private *ServerSideDecorationInterface::d_func() const
257 {
258  return reinterpret_cast<ServerSideDecorationInterface::Private *>(d.data());
259 }
260 
262 {
263  return Private::get(s);
264 }
265 
266 }
267 }
wl_resource * parentResource() const
Definition: resource.cpp:91
ClientConnection * client()
Definition: resource.cpp:76
void setMode(ServerSideDecorationManagerInterface::Mode mode)
Sets the mode on the SurfaceInterface.
static ServerSideDecorationInterface * get(SurfaceInterface *surface)
wl_resource * resource()
Definition: resource.cpp:86
@ None
Undecorated: neither client, nor server provide decoration.
Representing how a SurfaceInterface should be decorated.
@ Server
The surface gets embedded into a decoration frame provided by the Server.
static SurfaceInterface * get(wl_resource *native)
void create()
Creates the global by creating a native wl_global and by that announcing it to the clients.
Definition: global.cpp:48
T * data() const const
void setDefaultMode(Mode mode)
Sets the default mode which is pushed to the Clients on creating a ServerSideDecorationInterface.
@ Client
The decoration is part of the surface.
Class holding the Wayland server display loop.
Definition: display.h:86
QAction * create(StandardGameAction id, const QObject *recvr, const char *slot, QObject *parent)
Manager to create ServerSideDecorationInterface.
ServerSideDecorationManagerInterface::Mode mode() const
Base class for all Globals.
Definition: global.h:46
void flush()
Flushes the connection to this client.
Resource representing a wl_surface.
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 Wed Feb 8 2023 03:59:22 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.