KWayland

xdgdecoration_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2018 David Edmundson <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "xdgdecoration_interface.h"
7 
8 #include "display.h"
9 #include "global_p.h"
10 #include "resource_p.h"
11 #include "xdgshell_interface.h"
12 #include "xdgshell_stable_interface_p.h"
13 
14 #include "wayland-xdg-decoration-server-protocol.h"
15 
16 #include <QPointer>
17 #include <QtDebug>
18 
19 namespace KWayland
20 {
21 namespace Server
22 {
23 class XdgDecorationManagerInterface::Private : public Global::Private
24 {
25 public:
26  Private(XdgDecorationManagerInterface *q, XdgShellInterface *shellInterface, Display *d);
27 
29  KWayland::Server::XdgShellStableInterface *m_shellInterface;
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 getToplevelDecorationCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *toplevel);
42 
43  XdgDecorationManagerInterface *q;
44  static const struct zxdg_decoration_manager_v1_interface s_interface;
45  static const quint32 s_version;
46 };
47 
48 const quint32 XdgDecorationManagerInterface::Private::s_version = 1;
49 
50 XdgDecorationManagerInterface::XdgDecorationManagerInterface(Display *display, XdgShellInterface *shellInterface, QObject *parent)
51  : Global(new Private(this, shellInterface, display), parent)
52 {
53 }
54 
55 XdgDecorationManagerInterface::~XdgDecorationManagerInterface()
56 {
57 }
58 
59 #ifndef K_DOXYGEN
60 const struct zxdg_decoration_manager_v1_interface XdgDecorationManagerInterface::Private::s_interface = {destroyCallback, getToplevelDecorationCallback};
61 #endif
62 
63 void XdgDecorationManagerInterface::Private::destroyCallback(wl_client *client, wl_resource *resource)
64 {
65  Q_UNUSED(client)
66  wl_resource_destroy(resource);
67 }
68 
69 void XdgDecorationManagerInterface::Private::getToplevelDecorationCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *toplevel)
70 {
71  auto p = reinterpret_cast<Private *>(wl_resource_get_user_data(resource));
72  Q_ASSERT(p);
73 
74  auto shell = p->m_shellInterface->getSurface(toplevel);
75  if (!shell) {
76  wl_resource_post_error(resource, ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED, "No XDGToplevel found object");
77  return;
78  }
79  if (p->m_decorations.contains(shell)) {
80  wl_resource_post_error(resource, ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED, "XDGDecoration already exists for this surface");
81  return;
82  }
83 
84  auto xdgDecoration = new XdgDecorationInterface(p->q, shell, resource);
85  xdgDecoration->create(p->display->getConnection(client), wl_resource_get_version(resource), id);
86  if (!xdgDecoration->resource()) {
87  wl_resource_post_no_memory(resource);
88  delete xdgDecoration;
89  return;
90  }
91  p->m_decorations[shell] = xdgDecoration;
92  QObject::connect(xdgDecoration, &QObject::destroyed, p->q, [=]() {
93  p->m_decorations.remove(shell);
94  });
95  Q_EMIT p->q->xdgDecorationInterfaceCreated(xdgDecoration);
96 }
97 
98 XdgDecorationManagerInterface::Private::Private(XdgDecorationManagerInterface *q, XdgShellInterface *shellInterface, Display *d)
99  : Global::Private(d, &zxdg_decoration_manager_v1_interface, s_version)
100  , q(q)
101 {
102  m_shellInterface = qobject_cast<XdgShellStableInterface *>(shellInterface);
103  Q_ASSERT(m_shellInterface);
104 }
105 
106 void XdgDecorationManagerInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
107 {
108  auto c = display->getConnection(client);
109  wl_resource *resource = c->createResource(&zxdg_decoration_manager_v1_interface, qMin(version, s_version), id);
110  if (!resource) {
111  wl_client_post_no_memory(client);
112  return;
113  }
114  wl_resource_set_implementation(resource, &s_interface, this, unbind);
115 }
116 
117 void XdgDecorationManagerInterface::Private::unbind(wl_resource *resource)
118 {
119  Q_UNUSED(resource)
120 }
121 
122 class XdgDecorationInterface::Private : public Resource::Private
123 {
124 public:
125  Private(XdgDecorationInterface *q, XdgDecorationManagerInterface *c, XdgShellSurfaceInterface *s, wl_resource *parentResource);
126  ~Private() override;
127  Mode m_requestedMode = Mode::Undefined;
128  XdgShellSurfaceInterface *m_shell;
129 
130 private:
131  static void setModeCallback(wl_client *client, wl_resource *resource, uint32_t mode);
132  static void unsetModeCallback(wl_client *client, wl_resource *resource);
133 
134  XdgDecorationInterface *q_func()
135  {
136  return reinterpret_cast<XdgDecorationInterface *>(q);
137  }
138 
139  static const struct zxdg_toplevel_decoration_v1_interface s_interface;
140 };
141 
142 #ifndef K_DOXYGEN
143 const struct zxdg_toplevel_decoration_v1_interface XdgDecorationInterface::Private::s_interface = {resourceDestroyedCallback,
144  setModeCallback,
145  unsetModeCallback};
146 #endif
147 
148 void XdgDecorationInterface::Private::setModeCallback(wl_client *client, wl_resource *resource, uint32_t mode_raw)
149 {
150  Q_UNUSED(client);
151  auto p = reinterpret_cast<Private *>(wl_resource_get_user_data(resource));
152  Q_ASSERT(p);
153 
154  Mode mode = Mode::Undefined;
155  switch (mode_raw) {
156  case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE:
157  mode = Mode::ClientSide;
158  break;
159  case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE:
160  mode = Mode::ServerSide;
161  break;
162  default:
163  break;
164  }
165 
166  p->m_requestedMode = mode;
167  Q_EMIT p->q_func()->modeRequested(p->m_requestedMode);
168 }
169 
170 void XdgDecorationInterface::Private::unsetModeCallback(wl_client *client, wl_resource *resource)
171 {
172  Q_UNUSED(client);
173  auto p = reinterpret_cast<Private *>(wl_resource_get_user_data(resource));
174  Q_ASSERT(p);
175 
176  p->m_requestedMode = Mode::Undefined;
177  Q_EMIT p->q_func()->modeRequested(p->m_requestedMode);
178 }
179 
180 XdgDecorationInterface::Private::Private(XdgDecorationInterface *q,
181  XdgDecorationManagerInterface *c,
182  XdgShellSurfaceInterface *shell,
183  wl_resource *parentResource)
184  : Resource::Private(q, c, parentResource, &zxdg_toplevel_decoration_v1_interface, &s_interface)
185  , m_shell(shell)
186 {
187 }
188 
189 XdgDecorationInterface::Private::~Private()
190 {
191  if (resource) {
192  wl_resource_destroy(resource);
193  resource = nullptr;
194  }
195 }
196 
197 XdgDecorationInterface::XdgDecorationInterface(XdgDecorationManagerInterface *parent, XdgShellSurfaceInterface *shell, wl_resource *parentResource)
198  : Resource(new Private(this, parent, shell, parentResource))
199 {
200 }
201 
202 XdgDecorationInterface::~XdgDecorationInterface()
203 {
204 }
205 
206 void XdgDecorationInterface::configure(XdgDecorationInterface::Mode mode)
207 {
208  switch (mode) {
209  case Mode::ClientSide:
210  zxdg_toplevel_decoration_v1_send_configure(resource(), ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE);
211  break;
212  case Mode::ServerSide:
213  zxdg_toplevel_decoration_v1_send_configure(resource(), ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
214  break;
215  default:
216  // configure(Mode::Undefined) should no-op, as it semantically makes no sense
217  break;
218  }
219 }
220 
221 XdgDecorationInterface::Mode XdgDecorationInterface::requestedMode() const
222 {
223  Q_D();
224  return d->m_requestedMode;
225 }
226 
227 XdgShellSurfaceInterface *XdgDecorationInterface::surface() const
228 {
229  Q_D();
230  return d->m_shell;
231 }
232 
233 XdgDecorationInterface::Private *XdgDecorationInterface::d_func() const
234 {
235  return reinterpret_cast<XdgDecorationInterface::Private *>(d.data());
236 }
237 
238 }
239 }
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void destroyed(QObject *obj)
Q_D(Todo)
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.