File indexing completed on 2024-12-22 05:09:20

0001 /*
0002     SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #include "dpms.h"
0007 #include "event_queue.h"
0008 #include "output.h"
0009 #include "wayland_pointer_p.h"
0010 
0011 #include <wayland-client-protocol.h>
0012 #include <wayland-dpms-client-protocol.h>
0013 
0014 namespace KWayland
0015 {
0016 namespace Client
0017 {
0018 class Q_DECL_HIDDEN DpmsManager::Private
0019 {
0020 public:
0021     WaylandPointer<org_kde_kwin_dpms_manager, org_kde_kwin_dpms_manager_destroy> manager;
0022     EventQueue *queue = nullptr;
0023 };
0024 
0025 DpmsManager::DpmsManager(QObject *parent)
0026     : QObject(parent)
0027     , d(new Private)
0028 {
0029 }
0030 
0031 DpmsManager::~DpmsManager()
0032 {
0033     release();
0034 }
0035 
0036 void DpmsManager::release()
0037 {
0038     d->manager.release();
0039 }
0040 
0041 void DpmsManager::destroy()
0042 {
0043     d->manager.destroy();
0044 }
0045 
0046 bool DpmsManager::isValid() const
0047 {
0048     return d->manager.isValid();
0049 }
0050 
0051 void DpmsManager::setup(org_kde_kwin_dpms_manager *manager)
0052 {
0053     Q_ASSERT(manager);
0054     Q_ASSERT(!d->manager.isValid());
0055     d->manager.setup(manager);
0056 }
0057 
0058 EventQueue *DpmsManager::eventQueue()
0059 {
0060     return d->queue;
0061 }
0062 
0063 void DpmsManager::setEventQueue(EventQueue *queue)
0064 {
0065     d->queue = queue;
0066 }
0067 
0068 Dpms *DpmsManager::getDpms(Output *output, QObject *parent)
0069 {
0070     Q_ASSERT(isValid());
0071     Q_ASSERT(output);
0072     Dpms *dpms = new Dpms(output, parent);
0073     auto w = org_kde_kwin_dpms_manager_get(d->manager, *output);
0074     if (d->queue) {
0075         d->queue->addProxy(w);
0076     }
0077     dpms->setup(w);
0078     return dpms;
0079 }
0080 
0081 DpmsManager::operator org_kde_kwin_dpms_manager *() const
0082 {
0083     return d->manager;
0084 }
0085 
0086 DpmsManager::operator org_kde_kwin_dpms_manager *()
0087 {
0088     return d->manager;
0089 }
0090 
0091 class Q_DECL_HIDDEN Dpms::Private
0092 {
0093 public:
0094     explicit Private(const QPointer<Output> &output, Dpms *q);
0095     void setup(org_kde_kwin_dpms *d);
0096 
0097     WaylandPointer<org_kde_kwin_dpms, org_kde_kwin_dpms_release> dpms;
0098     struct Data {
0099         bool supported = false;
0100         Mode mode = Mode::On;
0101         bool supportedChanged = false;
0102         bool modeChanged = false;
0103     };
0104     Data current;
0105     Data pending;
0106     QPointer<Output> output;
0107 
0108 private:
0109     static void supportedCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t supported);
0110     static void modeCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t mode);
0111     static void doneCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms);
0112     static const struct org_kde_kwin_dpms_listener s_listener;
0113 
0114     Dpms *q;
0115 };
0116 
0117 #ifndef K_DOXYGEN
0118 const org_kde_kwin_dpms_listener Dpms::Private::s_listener = {supportedCallback, modeCallback, doneCallback};
0119 #endif
0120 
0121 void Dpms::Private::supportedCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t supported)
0122 {
0123     Q_UNUSED(org_kde_kwin_dpms)
0124     Private *p = reinterpret_cast<Private *>(data);
0125     p->pending.supported = supported == 0 ? false : true;
0126     p->pending.supportedChanged = true;
0127 }
0128 
0129 void Dpms::Private::modeCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t mode)
0130 {
0131     Q_UNUSED(org_kde_kwin_dpms)
0132     Mode m;
0133     switch (mode) {
0134     case ORG_KDE_KWIN_DPMS_MODE_ON:
0135         m = Mode::On;
0136         break;
0137     case ORG_KDE_KWIN_DPMS_MODE_STANDBY:
0138         m = Mode::Standby;
0139         break;
0140     case ORG_KDE_KWIN_DPMS_MODE_SUSPEND:
0141         m = Mode::Suspend;
0142         break;
0143     case ORG_KDE_KWIN_DPMS_MODE_OFF:
0144         m = Mode::Off;
0145         break;
0146     default:
0147         return;
0148     }
0149     Private *p = reinterpret_cast<Private *>(data);
0150     p->pending.mode = m;
0151     p->pending.modeChanged = true;
0152 }
0153 
0154 void Dpms::Private::doneCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms)
0155 {
0156     Q_UNUSED(org_kde_kwin_dpms)
0157     Private *p = reinterpret_cast<Private *>(data);
0158     const bool supportedChanged = p->pending.supportedChanged && p->pending.supported != p->current.supported;
0159     const bool modeChanged = p->pending.modeChanged && p->pending.mode != p->current.mode;
0160     if (supportedChanged) {
0161         p->current.supported = p->pending.supported;
0162         Q_EMIT p->q->supportedChanged();
0163     }
0164     if (modeChanged) {
0165         p->current.mode = p->pending.mode;
0166         Q_EMIT p->q->modeChanged();
0167     }
0168     p->pending = Data();
0169 }
0170 
0171 Dpms::Private::Private(const QPointer<Output> &output, Dpms *q)
0172     : output(output)
0173     , q(q)
0174 {
0175 }
0176 
0177 void Dpms::Private::setup(org_kde_kwin_dpms *d)
0178 {
0179     Q_ASSERT(d);
0180     Q_ASSERT(!dpms.isValid());
0181     dpms.setup(d);
0182     org_kde_kwin_dpms_add_listener(dpms, &s_listener, this);
0183 }
0184 
0185 Dpms::Dpms(const QPointer<Output> &o, QObject *parent)
0186     : QObject(parent)
0187     , d(new Private(o, this))
0188 {
0189 }
0190 
0191 Dpms::~Dpms()
0192 {
0193     release();
0194 }
0195 
0196 void Dpms::destroy()
0197 {
0198     d->dpms.destroy();
0199 }
0200 
0201 void Dpms::release()
0202 {
0203     d->dpms.release();
0204 }
0205 
0206 bool Dpms::isValid() const
0207 {
0208     return d->dpms.isValid();
0209 }
0210 
0211 void Dpms::setup(org_kde_kwin_dpms *dpms)
0212 {
0213     d->setup(dpms);
0214 }
0215 
0216 bool Dpms::isSupported() const
0217 {
0218     return d->current.supported;
0219 }
0220 
0221 Dpms::Mode Dpms::mode() const
0222 {
0223     return d->current.mode;
0224 }
0225 
0226 void Dpms::requestMode(Dpms::Mode mode)
0227 {
0228     uint32_t wlMode;
0229     switch (mode) {
0230     case Mode::On:
0231         wlMode = ORG_KDE_KWIN_DPMS_MODE_ON;
0232         break;
0233     case Mode::Standby:
0234         wlMode = ORG_KDE_KWIN_DPMS_MODE_STANDBY;
0235         break;
0236     case Mode::Suspend:
0237         wlMode = ORG_KDE_KWIN_DPMS_MODE_SUSPEND;
0238         break;
0239     case Mode::Off:
0240         wlMode = ORG_KDE_KWIN_DPMS_MODE_OFF;
0241         break;
0242     default:
0243         Q_UNREACHABLE();
0244     }
0245     org_kde_kwin_dpms_set(d->dpms, wlMode);
0246 }
0247 
0248 QPointer<Output> Dpms::output() const
0249 {
0250     return d->output;
0251 }
0252 
0253 Dpms::operator org_kde_kwin_dpms *()
0254 {
0255     return d->dpms;
0256 }
0257 
0258 Dpms::operator org_kde_kwin_dpms *() const
0259 {
0260     return d->dpms;
0261 }
0262 
0263 }
0264 }
0265 
0266 #include "moc_dpms.cpp"