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

KDE's Doxygen guidelines are available online.