KWaylandServer

xdgoutput_v1_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2018 David Edmundson <[email protected]>
3  SPDX-FileCopyrightText: 2020 David Edmundson <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 #include "xdgoutput_v1_interface.h"
8 #include "display.h"
9 #include "output_interface.h"
10 
11 #include "qwayland-server-xdg-output-unstable-v1.h"
12 
13 #include <QDebug>
14 #include <QHash>
15 #include <QPointer>
16 
17 namespace KWaylandServer
18 {
19 static const quint32 s_version = 3;
20 
21 class XdgOutputManagerV1InterfacePrivate : public QtWaylandServer::zxdg_output_manager_v1
22 {
23 public:
24  XdgOutputManagerV1InterfacePrivate(XdgOutputManagerV1Interface *q, Display *display);
26 
27  XdgOutputManagerV1Interface *q;
28 
29 protected:
30  void zxdg_output_manager_v1_destroy(Resource *resource) override;
31  void zxdg_output_manager_v1_get_xdg_output(Resource *resource, uint32_t id, wl_resource *output) override;
32 };
33 
34 class XdgOutputV1InterfacePrivate : public QtWaylandServer::zxdg_output_v1
35 {
36 public:
37  XdgOutputV1InterfacePrivate(OutputInterface *wlOutput)
38  : output(wlOutput)
39  {
40  }
41 
42  QPoint pos;
43  QSize size;
44  QString name;
45  QString description;
46  bool dirty = false;
47  bool doneOnce = false;
49 
50 protected:
51  void zxdg_output_v1_bind_resource(Resource *resource) override;
52  void zxdg_output_v1_destroy(Resource *resource) override;
53 };
54 
55 XdgOutputManagerV1Interface::XdgOutputManagerV1Interface(Display *display, QObject *parent)
56  : QObject(parent)
57  , d(new XdgOutputManagerV1InterfacePrivate(this, display))
58 {
59 }
60 
61 XdgOutputManagerV1Interface::~XdgOutputManagerV1Interface()
62 {
63 }
64 
66 {
67  Q_ASSERT_X(!d->outputs.contains(output), "createXdgOutput", "An XdgOuputInterface already exists for this output");
68 
69  auto xdgOutput = new XdgOutputV1Interface(output, parent);
70  d->outputs[output] = xdgOutput;
71 
72  // as XdgOutput lifespan is managed by user, delete our mapping when either
73  // it or the relevant Output gets deleted
74  connect(output, &QObject::destroyed, this, [this, output]() {
75  d->outputs.remove(output);
76  });
77  connect(xdgOutput, &QObject::destroyed, this, [this, output]() {
78  d->outputs.remove(output);
79  });
80 
81  return xdgOutput;
82 }
83 
84 XdgOutputManagerV1InterfacePrivate::XdgOutputManagerV1InterfacePrivate(XdgOutputManagerV1Interface *qptr, Display *d)
85  : QtWaylandServer::zxdg_output_manager_v1(*d, s_version)
86  , q(qptr)
87 {
88 }
89 
90 void XdgOutputManagerV1InterfacePrivate::zxdg_output_manager_v1_get_xdg_output(Resource *resource, uint32_t id, wl_resource *outputResource)
91 {
92  auto output = OutputInterface::get(outputResource);
93  if (!output) { // output client is requesting XdgOutput for an Output that doesn't exist
94  return;
95  }
96  auto xdgOutput = outputs.value(output);
97  if (!xdgOutput) {
98  return; // client is requesting XdgOutput for an Output that doesn't exist
99  }
100  xdgOutput->d->add(resource->client(), id, resource->version());
101 }
102 
103 void XdgOutputManagerV1InterfacePrivate::zxdg_output_manager_v1_destroy(Resource *resource)
104 {
105  wl_resource_destroy(resource->handle);
106 }
107 
108 XdgOutputV1Interface::XdgOutputV1Interface(OutputInterface *output, QObject *parent)
109  : QObject(parent)
110  , d(new XdgOutputV1InterfacePrivate(output))
111 {
112 }
113 
114 XdgOutputV1Interface::~XdgOutputV1Interface()
115 {
116 }
117 
119 {
120  if (size == d->size) {
121  return;
122  }
123  d->size = size;
124  d->dirty = true;
125 
126  const auto outputResources = d->resourceMap();
127  for (auto resource : outputResources) {
128  d->send_logical_size(resource->handle, size.width(), size.height());
129  }
130 }
131 
133 {
134  return d->size;
135 }
136 
138 {
139  if (pos == d->pos) {
140  return;
141  }
142  d->pos = pos;
143  d->dirty = true;
144 
145  const auto outputResources = d->resourceMap();
146  for (auto resource : outputResources) {
147  d->send_logical_position(resource->handle, pos.x(), pos.y());
148  }
149 }
150 
152 {
153  return d->pos;
154 }
155 
157 {
158  d->name = name;
159  // this can only be set once before the client connects
160 }
161 
163 {
164  d->description = description;
165  // this can only be set once before the client connects
166 }
167 
169 {
170  d->doneOnce = true;
171  if (!d->dirty) {
172  return;
173  }
174  d->dirty = false;
175 
176  const auto outputResources = d->resourceMap();
177  for (auto resource : outputResources) {
178  if (wl_resource_get_version(resource->handle) < 3) {
179  d->send_done(resource->handle);
180  }
181  }
182 }
183 
184 void XdgOutputV1InterfacePrivate::zxdg_output_v1_destroy(Resource *resource)
185 {
186  wl_resource_destroy(resource->handle);
187 }
188 
189 void XdgOutputV1InterfacePrivate::zxdg_output_v1_bind_resource(Resource *resource)
190 {
191  send_logical_position(resource->handle, pos.x(), pos.y());
192  send_logical_size(resource->handle, size.width(), size.height());
193  if (resource->version() >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
194  send_name(resource->handle, name);
195  }
196  if (resource->version() >= ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION) {
197  send_description(resource->handle, description);
198  }
199 
200  if (doneOnce) {
201  if (wl_resource_get_version(resource->handle) >= 3) {
202  if (output) {
203  output->done();
204  }
205  } else {
206  send_done(resource->handle);
207  }
208  }
209 }
210 
211 }
int width() const const
The OutputInterface class represents a screen.
void setDescription(const QString &description)
Sets a longer description of the output This should be consistent across reboots for the same monitor...
QString name(const QVariant &location)
Extension to Output Users should set all relevant values on creation and on future changes...
Class holding the Wayland server display loop.
Definition: display.h:47
QPoint logicalPosition() const
Returns the last set logical position on this output.
int x() const const
int y() const const
XdgOutputV1Interface * createXdgOutput(OutputInterface *output, QObject *parent)
Creates an XdgOutputInterface object for an existing Output which exposes XDG specific properties of ...
void setLogicalSize(const QSize &size)
Sets the size of this output in logical co-ordinates.
void done()
Submit changes to all clients.
QSize logicalSize() const
Returns the last set logical size on this output.
void done()
Submit changes to all clients.
void setName(const QString &name)
Sets a short name of the output This should be consistent across reboots for the same monitor It shou...
QObject(QObject *parent)
void setLogicalPosition(const QPoint &pos)
Sets the topleft position of this output in logical co-ordinates.
int height() const const
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)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 16 2021 23:10:15 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.