1/*
2 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6#include "dpms.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-dpms-client-protocol.h>
13
14namespace KWayland
15{
16namespace Client
17{
18class Q_DECL_HIDDEN DpmsManager::Private
19{
20public:
21 WaylandPointer<org_kde_kwin_dpms_manager, org_kde_kwin_dpms_manager_destroy> manager;
22 EventQueue *queue = nullptr;
23};
24
25DpmsManager::DpmsManager(QObject *parent)
26 : QObject(parent)
27 , d(new Private)
28{
29}
30
31DpmsManager::~DpmsManager()
32{
33 release();
34}
35
36void DpmsManager::release()
37{
38 d->manager.release();
39}
40
41void DpmsManager::destroy()
42{
43 d->manager.destroy();
44}
45
46bool DpmsManager::isValid() const
47{
48 return d->manager.isValid();
49}
50
51void DpmsManager::setup(org_kde_kwin_dpms_manager *manager)
52{
53 Q_ASSERT(manager);
54 Q_ASSERT(!d->manager.isValid());
55 d->manager.setup(pointer: manager);
56}
57
58EventQueue *DpmsManager::eventQueue()
59{
60 return d->queue;
61}
62
63void DpmsManager::setEventQueue(EventQueue *queue)
64{
65 d->queue = queue;
66}
67
68Dpms *DpmsManager::getDpms(Output *output, QObject *parent)
69{
70 Q_ASSERT(isValid());
71 Q_ASSERT(output);
72 Dpms *dpms = new Dpms(output, parent);
73 auto w = org_kde_kwin_dpms_manager_get(org_kde_kwin_dpms_manager: d->manager, output: *output);
74 if (d->queue) {
75 d->queue->addProxy(proxy: w);
76 }
77 dpms->setup(w);
78 return dpms;
79}
80
81DpmsManager::operator org_kde_kwin_dpms_manager *() const
82{
83 return d->manager;
84}
85
86DpmsManager::operator org_kde_kwin_dpms_manager *()
87{
88 return d->manager;
89}
90
91class Q_DECL_HIDDEN Dpms::Private
92{
93public:
94 explicit Private(const QPointer<Output> &output, Dpms *q);
95 void setup(org_kde_kwin_dpms *d);
96
97 WaylandPointer<org_kde_kwin_dpms, org_kde_kwin_dpms_release> dpms;
98 struct Data {
99 bool supported = false;
100 Mode mode = Mode::On;
101 bool supportedChanged = false;
102 bool modeChanged = false;
103 };
104 Data current;
105 Data pending;
106 QPointer<Output> output;
107
108private:
109 static void supportedCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t supported);
110 static void modeCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t mode);
111 static void doneCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms);
112 static const struct org_kde_kwin_dpms_listener s_listener;
113
114 Dpms *q;
115};
116
117#ifndef K_DOXYGEN
118const org_kde_kwin_dpms_listener Dpms::Private::s_listener = {.supported: supportedCallback, .mode: modeCallback, .done: doneCallback};
119#endif
120
121void Dpms::Private::supportedCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t supported)
122{
123 Q_UNUSED(org_kde_kwin_dpms)
124 Private *p = reinterpret_cast<Private *>(data);
125 p->pending.supported = supported == 0 ? false : true;
126 p->pending.supportedChanged = true;
127}
128
129void Dpms::Private::modeCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t mode)
130{
131 Q_UNUSED(org_kde_kwin_dpms)
132 Mode m;
133 switch (mode) {
134 case ORG_KDE_KWIN_DPMS_MODE_ON:
135 m = Mode::On;
136 break;
137 case ORG_KDE_KWIN_DPMS_MODE_STANDBY:
138 m = Mode::Standby;
139 break;
140 case ORG_KDE_KWIN_DPMS_MODE_SUSPEND:
141 m = Mode::Suspend;
142 break;
143 case ORG_KDE_KWIN_DPMS_MODE_OFF:
144 m = Mode::Off;
145 break;
146 default:
147 return;
148 }
149 Private *p = reinterpret_cast<Private *>(data);
150 p->pending.mode = m;
151 p->pending.modeChanged = true;
152}
153
154void Dpms::Private::doneCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms)
155{
156 Q_UNUSED(org_kde_kwin_dpms)
157 Private *p = reinterpret_cast<Private *>(data);
158 const bool supportedChanged = p->pending.supportedChanged && p->pending.supported != p->current.supported;
159 const bool modeChanged = p->pending.modeChanged && p->pending.mode != p->current.mode;
160 if (supportedChanged) {
161 p->current.supported = p->pending.supported;
162 Q_EMIT p->q->supportedChanged();
163 }
164 if (modeChanged) {
165 p->current.mode = p->pending.mode;
166 Q_EMIT p->q->modeChanged();
167 }
168 p->pending = Data();
169}
170
171Dpms::Private::Private(const QPointer<Output> &output, Dpms *q)
172 : output(output)
173 , q(q)
174{
175}
176
177void Dpms::Private::setup(org_kde_kwin_dpms *d)
178{
179 Q_ASSERT(d);
180 Q_ASSERT(!dpms.isValid());
181 dpms.setup(pointer: d);
182 org_kde_kwin_dpms_add_listener(org_kde_kwin_dpms: dpms, listener: &s_listener, data: this);
183}
184
185Dpms::Dpms(const QPointer<Output> &o, QObject *parent)
186 : QObject(parent)
187 , d(new Private(o, this))
188{
189}
190
191Dpms::~Dpms()
192{
193 release();
194}
195
196void Dpms::destroy()
197{
198 d->dpms.destroy();
199}
200
201void Dpms::release()
202{
203 d->dpms.release();
204}
205
206bool Dpms::isValid() const
207{
208 return d->dpms.isValid();
209}
210
211void Dpms::setup(org_kde_kwin_dpms *dpms)
212{
213 d->setup(dpms);
214}
215
216bool Dpms::isSupported() const
217{
218 return d->current.supported;
219}
220
221Dpms::Mode Dpms::mode() const
222{
223 return d->current.mode;
224}
225
226void Dpms::requestMode(Dpms::Mode mode)
227{
228 uint32_t wlMode;
229 switch (mode) {
230 case Mode::On:
231 wlMode = ORG_KDE_KWIN_DPMS_MODE_ON;
232 break;
233 case Mode::Standby:
234 wlMode = ORG_KDE_KWIN_DPMS_MODE_STANDBY;
235 break;
236 case Mode::Suspend:
237 wlMode = ORG_KDE_KWIN_DPMS_MODE_SUSPEND;
238 break;
239 case Mode::Off:
240 wlMode = ORG_KDE_KWIN_DPMS_MODE_OFF;
241 break;
242 default:
243 Q_UNREACHABLE();
244 }
245 org_kde_kwin_dpms_set(org_kde_kwin_dpms: d->dpms, mode: wlMode);
246}
247
248QPointer<Output> Dpms::output() const
249{
250 return d->output;
251}
252
253Dpms::operator org_kde_kwin_dpms *()
254{
255 return d->dpms;
256}
257
258Dpms::operator org_kde_kwin_dpms *() const
259{
260 return d->dpms;
261}
262
263}
264}
265
266#include "moc_dpms.cpp"
267

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