1/*
2 SPDX-FileCopyrightText: 2018 David Edmundson <kde@davidedmundson.co.uk>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6#include "xdgoutput.h"
7#include "event_queue.h"
8#include "output.h"
9#include "wayland_pointer_p.h"
10
11#include <wayland-client-protocol.h>
12#include <wayland-xdg-output-unstable-v1-client-protocol.h>
13
14#include <QDebug>
15
16namespace KWayland
17{
18namespace Client
19{
20class XdgOutputManager::Private
21{
22public:
23 Private() = default;
24
25 void setup(zxdg_output_manager_v1 *arg);
26
27 WaylandPointer<zxdg_output_manager_v1, zxdg_output_manager_v1_destroy> xdgoutputmanager;
28 EventQueue *queue = nullptr;
29};
30
31XdgOutputManager::XdgOutputManager(QObject *parent)
32 : QObject(parent)
33 , d(new Private)
34{
35}
36
37void XdgOutputManager::Private::setup(zxdg_output_manager_v1 *arg)
38{
39 Q_ASSERT(arg);
40 Q_ASSERT(!xdgoutputmanager);
41 xdgoutputmanager.setup(pointer: arg);
42}
43
44XdgOutputManager::~XdgOutputManager()
45{
46 release();
47}
48
49void XdgOutputManager::setup(zxdg_output_manager_v1 *xdgoutputmanager)
50{
51 d->setup(xdgoutputmanager);
52}
53
54void XdgOutputManager::release()
55{
56 d->xdgoutputmanager.release();
57}
58
59void XdgOutputManager::destroy()
60{
61 d->xdgoutputmanager.destroy();
62}
63
64XdgOutputManager::operator zxdg_output_manager_v1 *()
65{
66 return d->xdgoutputmanager;
67}
68
69XdgOutputManager::operator zxdg_output_manager_v1 *() const
70{
71 return d->xdgoutputmanager;
72}
73
74bool XdgOutputManager::isValid() const
75{
76 return d->xdgoutputmanager.isValid();
77}
78
79void XdgOutputManager::setEventQueue(EventQueue *queue)
80{
81 d->queue = queue;
82}
83
84EventQueue *XdgOutputManager::eventQueue()
85{
86 return d->queue;
87}
88
89XdgOutput *XdgOutputManager::getXdgOutput(Output *output, QObject *parent)
90{
91 Q_ASSERT(isValid());
92 auto p = new XdgOutput(parent);
93 auto w = zxdg_output_manager_v1_get_xdg_output(zxdg_output_manager_v1: d->xdgoutputmanager, output: *output);
94 if (d->queue) {
95 d->queue->addProxy(proxy: w);
96 }
97 p->setup(w);
98 return p;
99}
100
101struct XdgOutputBuffer {
102 QPoint logicalPosition;
103 QSize logicalSize;
104 QString name;
105 QString description;
106};
107
108class XdgOutput::Private
109{
110public:
111 Private(XdgOutput *q);
112
113 void setup(zxdg_output_v1 *arg);
114
115 WaylandPointer<zxdg_output_v1, zxdg_output_v1_destroy> xdgoutput;
116
117 XdgOutputBuffer current;
118 XdgOutputBuffer pending;
119
120private:
121 XdgOutput *q;
122
123private:
124 static void logical_positionCallback(void *data, zxdg_output_v1 *zxdg_output_v1, int32_t x, int32_t y);
125 static void logical_sizeCallback(void *data, zxdg_output_v1 *zxdg_output_v1, int32_t width, int32_t height);
126 static void doneCallback(void *data, zxdg_output_v1 *zxdg_output_v1);
127 static void nameCallback(void *data, zxdg_output_v1 *zxdg_output_v1, const char *name);
128 static void descriptionCallback(void *data, zxdg_output_v1 *zxdg_output_v1, const char *description);
129
130 static const zxdg_output_v1_listener s_listener;
131};
132
133const zxdg_output_v1_listener XdgOutput::Private::s_listener = {.logical_position: logical_positionCallback,
134 .logical_size: logical_sizeCallback,
135 .done: doneCallback,
136 .name: nameCallback,
137 .description: descriptionCallback};
138
139void XdgOutput::Private::logical_positionCallback(void *data, zxdg_output_v1 *zxdg_output_v1, int32_t x, int32_t y)
140{
141 auto p = reinterpret_cast<XdgOutput::Private *>(data);
142 Q_ASSERT(p->xdgoutput == zxdg_output_v1);
143 p->pending.logicalPosition = QPoint(x, y);
144}
145
146void XdgOutput::Private::logical_sizeCallback(void *data, zxdg_output_v1 *zxdg_output_v1, int32_t width, int32_t height)
147{
148 auto p = reinterpret_cast<XdgOutput::Private *>(data);
149 Q_ASSERT(p->xdgoutput == zxdg_output_v1);
150 p->pending.logicalSize = QSize(width, height);
151}
152
153void XdgOutput::Private::nameCallback(void *data, zxdg_output_v1 *zxdg_output_v1, const char *name)
154{
155 auto p = reinterpret_cast<XdgOutput::Private *>(data);
156 Q_ASSERT(p->xdgoutput == zxdg_output_v1);
157 p->pending.name = name;
158}
159
160void XdgOutput::Private::descriptionCallback(void *data, zxdg_output_v1 *zxdg_output_v1, const char *description)
161{
162 auto p = reinterpret_cast<XdgOutput::Private *>(data);
163 Q_ASSERT(p->xdgoutput == zxdg_output_v1);
164 p->pending.description = description;
165}
166
167void XdgOutput::Private::doneCallback(void *data, zxdg_output_v1 *zxdg_output_v1)
168{
169 auto p = reinterpret_cast<XdgOutput::Private *>(data);
170 Q_ASSERT(p->xdgoutput == zxdg_output_v1);
171 std::swap(a&: p->current, b&: p->pending);
172
173 Q_EMIT p->q->changed();
174}
175
176XdgOutput::Private::Private(XdgOutput *qptr)
177 : q(qptr)
178{
179}
180
181XdgOutput::XdgOutput(QObject *parent)
182 : QObject(parent)
183 , d(new Private(this))
184{
185}
186
187void XdgOutput::Private::setup(zxdg_output_v1 *arg)
188{
189 Q_ASSERT(arg);
190 Q_ASSERT(!xdgoutput);
191 xdgoutput.setup(pointer: arg);
192 zxdg_output_v1_add_listener(zxdg_output_v1: xdgoutput, listener: &s_listener, data: this);
193}
194
195XdgOutput::~XdgOutput()
196{
197 release();
198}
199
200void XdgOutput::setup(zxdg_output_v1 *xdgoutput)
201{
202 d->setup(xdgoutput);
203}
204
205void XdgOutput::release()
206{
207 d->xdgoutput.release();
208}
209
210void XdgOutput::destroy()
211{
212 d->xdgoutput.destroy();
213}
214
215QSize XdgOutput::logicalSize() const
216{
217 return d->current.logicalSize;
218}
219
220QPoint XdgOutput::logicalPosition() const
221{
222 return d->current.logicalPosition;
223}
224
225QString XdgOutput::name() const
226{
227 return d->current.name;
228}
229
230QString XdgOutput::description() const
231{
232 return d->current.description;
233}
234
235XdgOutput::operator zxdg_output_v1 *()
236{
237 return d->xdgoutput;
238}
239
240XdgOutput::operator zxdg_output_v1 *() const
241{
242 return d->xdgoutput;
243}
244
245bool XdgOutput::isValid() const
246{
247 return d->xdgoutput.isValid();
248}
249
250}
251}
252
253#include "moc_xdgoutput.cpp"
254

source code of kwayland/src/client/xdgoutput.cpp