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 
22 class ServerSideDecorationManagerInterface::Private : public Global::Private
23 {
24 public:
25  Private(ServerSideDecorationManagerInterface *q, Display *d);
26 
28 
29  QVector<wl_resource*> resources;
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  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 = {
51  createCallback
52 };
53 #endif
54 
55 void ServerSideDecorationManagerInterface::Private::createCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface)
56 {
57  reinterpret_cast<Private*>(wl_resource_get_user_data(resource))->create(client, resource, id, surface);
58 }
59 
60 void ServerSideDecorationManagerInterface::Private::create(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface)
61 {
62  SurfaceInterface *s = SurfaceInterface::get(surface);
63  if (!s) {
64  // TODO: send error?
65  qCWarning(KWAYLAND_SERVER) << "ServerSideDecorationInterface requested for non existing SurfaceInterface";
66  return;
67  }
68  ServerSideDecorationInterface *decoration = new ServerSideDecorationInterface(q, s, resource);
69  decoration->create(display->getConnection(client), wl_resource_get_version(resource), id);
70  if (!decoration->resource()) {
71  wl_resource_post_no_memory(resource);
72  delete decoration;
73  return;
74  }
75  decoration->setMode(defaultMode);
76  emit q->decorationCreated(decoration);
77 }
78 
80 {
81  return d_func()->defaultMode;
82 }
83 
84 ServerSideDecorationManagerInterface::Private::Private(ServerSideDecorationManagerInterface *q, Display *d)
85  : Global::Private(d, &org_kde_kwin_server_decoration_manager_interface, s_version)
86  , q(q)
87 {
88 }
89 
90 namespace {
91 static uint32_t modeWayland(ServerSideDecorationManagerInterface::Mode mode)
92 {
93  switch (mode) {
95  return ORG_KDE_KWIN_SERVER_DECORATION_MODE_NONE;
96  break;
98  return ORG_KDE_KWIN_SERVER_DECORATION_MODE_CLIENT;
99  break;
101  return ORG_KDE_KWIN_SERVER_DECORATION_MODE_SERVER;
102  break;
103  default:
104  Q_UNREACHABLE();
105  }
106 }
107 }
108 
109 void ServerSideDecorationManagerInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
110 {
111  auto c = display->getConnection(client);
112  wl_resource *resource = c->createResource(&org_kde_kwin_server_decoration_manager_interface, qMin(version, s_version), id);
113  if (!resource) {
114  wl_client_post_no_memory(client);
115  return;
116  }
117  wl_resource_set_implementation(resource, &s_interface, this, unbind);
118 
119  resources << resource;
120 
121  org_kde_kwin_server_decoration_manager_send_default_mode(resource, modeWayland(defaultMode));
122  c->flush();
123 }
124 
125 void ServerSideDecorationManagerInterface::Private::unbind(wl_resource *resource)
126 {
127  cast(resource)->resources.removeAll(resource);
128 }
129 
130 ServerSideDecorationManagerInterface::ServerSideDecorationManagerInterface(Display *display, QObject *parent)
131  : Global(new Private(this, display), parent)
132 {
133 }
134 
135 ServerSideDecorationManagerInterface::~ServerSideDecorationManagerInterface() = default;
136 
137 ServerSideDecorationManagerInterface::Private *ServerSideDecorationManagerInterface::d_func() const
138 {
139  return reinterpret_cast<ServerSideDecorationManagerInterface::Private*>(d.data());
140 }
141 
143 {
144  Q_D();
145  d->defaultMode = mode;
146  const uint32_t wlMode = modeWayland(mode);
147  for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); it++) {
148  org_kde_kwin_server_decoration_manager_send_default_mode(*it, wlMode);
149  }
150 }
151 
152 class ServerSideDecorationInterface::Private : public Resource::Private
153 {
154 public:
155  Private(ServerSideDecorationInterface *q, ServerSideDecorationManagerInterface *c, SurfaceInterface *surface, wl_resource *parentResource);
156  ~Private();
157 
159  SurfaceInterface *surface;
160 
162 
163 private:
164  static void requestModeCallback(wl_client *client, wl_resource *resource, uint32_t mode);
165 
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 = {
176  resourceDestroyedCallback,
177  requestModeCallback
178 };
179 QVector<ServerSideDecorationInterface::Private*> ServerSideDecorationInterface::Private::s_all;
180 #endif
181 
182 void ServerSideDecorationInterface::Private::requestModeCallback(wl_client *client, wl_resource *resource, uint32_t mode)
183 {
184  Q_UNUSED(client)
186  switch (mode) {
187  case ORG_KDE_KWIN_SERVER_DECORATION_MODE_NONE:
189  break;
190  case ORG_KDE_KWIN_SERVER_DECORATION_MODE_CLIENT:
192  break;
193  case ORG_KDE_KWIN_SERVER_DECORATION_MODE_SERVER:
195  break;
196  default:
197  // invalid mode
198  qCWarning(KWAYLAND_SERVER) << "Invalid mode:" << mode;
199  return;
200  }
201  emit cast<Private>(resource)->q_func()->modeRequested(m);
202 }
203 
204 ServerSideDecorationInterface *ServerSideDecorationInterface::Private::get(SurfaceInterface *s)
205 {
206  auto it = std::find_if(s_all.constBegin(), s_all.constEnd(), [s] (Private *p) { return p->surface == s; });
207  if (it == s_all.constEnd()) {
208  return nullptr;
209  }
210  return (*it)->q_func();
211 }
212 
213 ServerSideDecorationInterface::Private::Private(ServerSideDecorationInterface *q, ServerSideDecorationManagerInterface *c, SurfaceInterface *surface, wl_resource *parentResource)
214  : Resource::Private(q, c, parentResource, &org_kde_kwin_server_decoration_interface, &s_interface)
215  , surface(surface)
216 {
217  s_all << this;
218 }
219 
220 ServerSideDecorationInterface::Private::~Private()
221 {
222  s_all.removeAll(this);
223 }
224 
225 ServerSideDecorationInterface::ServerSideDecorationInterface(ServerSideDecorationManagerInterface *parent, SurfaceInterface *surface, wl_resource *parentResource)
226  : Resource(new Private(this, parent, surface, parentResource))
227 {
228 }
229 
230 ServerSideDecorationInterface::~ServerSideDecorationInterface() = default;
231 
233 {
234  Q_D();
235  d->mode = mode;
236  org_kde_kwin_server_decoration_send_mode(resource(), modeWayland(mode));
237  client()->flush();
238 }
239 
241 {
242  Q_D();
243  return d->mode;
244 }
245 
247 {
248  Q_D();
249  return d->surface;
250 }
251 
252 ServerSideDecorationInterface::Private *ServerSideDecorationInterface::d_func() const
253 {
254  return reinterpret_cast<ServerSideDecorationInterface::Private*>(d.data());
255 }
256 
257 ServerSideDecorationInterface *ServerSideDecorationInterface::get(SurfaceInterface *s)
258 {
259  return Private::get(s);
260 }
261 
262 }
263 }
Undecorated: neither client, nor server provide decoration.
ClientConnection * getConnection(wl_client *client)
Gets the ClientConnection for the given client.
Definition: display.cpp:592
Representing how a SurfaceInterface should be decorated.
static ServerSideDecorationInterface * get(SurfaceInterface *surface)
Manager to create ServerSideDecorationInterface.
The surface gets embedded into a decoration frame provided by the Server.
void create()
Creates the global by creating a native wl_global and by that announcing it to the clients...
Definition: global.cpp:49
static SurfaceInterface * get(wl_resource *native)
void setMode(ServerSideDecorationManagerInterface::Mode mode)
Sets the mode on the SurfaceInterface.
Resource representing a wl_surface.
Class holding the Wayland server display loop.
Definition: display.h:89
ServerSideDecorationManagerInterface::Mode mode() const
wl_resource * createResource(const wl_interface *interface, quint32 version, quint32 id)
Creates a new wl_resource for the provided interface.
Base class for all Globals.
Definition: global.h:46
Represents a bound Resource.
Definition: resource.h:32
void setDefaultMode(Mode mode)
Sets the default mode which is pushed to the Clients on creating a ServerSideDecorationInterface.
Display * display()
Definition: global.cpp:79
QObject * parent() 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:19 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.