/* SPDX-FileCopyrightText: 2015 Martin Gräßlin SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL */ #include "dpms.h" #include "event_queue.h" #include "output.h" #include "wayland_pointer_p.h" #include #include namespace KWayland { namespace Client { class Q_DECL_HIDDEN DpmsManager::Private { public: WaylandPointer manager; EventQueue *queue = nullptr; }; DpmsManager::DpmsManager(QObject *parent) : QObject(parent) , d(new Private) { } DpmsManager::~DpmsManager() { release(); } void DpmsManager::release() { d->manager.release(); } void DpmsManager::destroy() { d->manager.destroy(); } bool DpmsManager::isValid() const { return d->manager.isValid(); } void DpmsManager::setup(org_kde_kwin_dpms_manager *manager) { Q_ASSERT(manager); Q_ASSERT(!d->manager.isValid()); d->manager.setup(manager); } EventQueue *DpmsManager::eventQueue() { return d->queue; } void DpmsManager::setEventQueue(EventQueue *queue) { d->queue = queue; } Dpms *DpmsManager::getDpms(Output *output, QObject *parent) { Q_ASSERT(isValid()); Q_ASSERT(output); Dpms *dpms = new Dpms(output, parent); auto w = org_kde_kwin_dpms_manager_get(d->manager, *output); if (d->queue) { d->queue->addProxy(w); } dpms->setup(w); return dpms; } DpmsManager::operator org_kde_kwin_dpms_manager *() const { return d->manager; } DpmsManager::operator org_kde_kwin_dpms_manager *() { return d->manager; } class Q_DECL_HIDDEN Dpms::Private { public: explicit Private(const QPointer &output, Dpms *q); void setup(org_kde_kwin_dpms *d); WaylandPointer dpms; struct Data { bool supported = false; Mode mode = Mode::On; bool supportedChanged = false; bool modeChanged = false; }; Data current; Data pending; QPointer output; private: static void supportedCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t supported); static void modeCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t mode); static void doneCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms); static const struct org_kde_kwin_dpms_listener s_listener; Dpms *q; }; #ifndef K_DOXYGEN const org_kde_kwin_dpms_listener Dpms::Private::s_listener = {supportedCallback, modeCallback, doneCallback}; #endif void Dpms::Private::supportedCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t supported) { Q_UNUSED(org_kde_kwin_dpms) Private *p = reinterpret_cast(data); p->pending.supported = supported == 0 ? false : true; p->pending.supportedChanged = true; } void Dpms::Private::modeCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms, uint32_t mode) { Q_UNUSED(org_kde_kwin_dpms) Mode m; switch (mode) { case ORG_KDE_KWIN_DPMS_MODE_ON: m = Mode::On; break; case ORG_KDE_KWIN_DPMS_MODE_STANDBY: m = Mode::Standby; break; case ORG_KDE_KWIN_DPMS_MODE_SUSPEND: m = Mode::Suspend; break; case ORG_KDE_KWIN_DPMS_MODE_OFF: m = Mode::Off; break; default: return; } Private *p = reinterpret_cast(data); p->pending.mode = m; p->pending.modeChanged = true; } void Dpms::Private::doneCallback(void *data, org_kde_kwin_dpms *org_kde_kwin_dpms) { Q_UNUSED(org_kde_kwin_dpms) Private *p = reinterpret_cast(data); const bool supportedChanged = p->pending.supportedChanged && p->pending.supported != p->current.supported; const bool modeChanged = p->pending.modeChanged && p->pending.mode != p->current.mode; if (supportedChanged) { p->current.supported = p->pending.supported; Q_EMIT p->q->supportedChanged(); } if (modeChanged) { p->current.mode = p->pending.mode; Q_EMIT p->q->modeChanged(); } p->pending = Data(); } Dpms::Private::Private(const QPointer &output, Dpms *q) : output(output) , q(q) { } void Dpms::Private::setup(org_kde_kwin_dpms *d) { Q_ASSERT(d); Q_ASSERT(!dpms.isValid()); dpms.setup(d); org_kde_kwin_dpms_add_listener(dpms, &s_listener, this); } Dpms::Dpms(const QPointer &o, QObject *parent) : QObject(parent) , d(new Private(o, this)) { } Dpms::~Dpms() { release(); } void Dpms::destroy() { d->dpms.destroy(); } void Dpms::release() { d->dpms.release(); } bool Dpms::isValid() const { return d->dpms.isValid(); } void Dpms::setup(org_kde_kwin_dpms *dpms) { d->setup(dpms); } bool Dpms::isSupported() const { return d->current.supported; } Dpms::Mode Dpms::mode() const { return d->current.mode; } void Dpms::requestMode(Dpms::Mode mode) { uint32_t wlMode; switch (mode) { case Mode::On: wlMode = ORG_KDE_KWIN_DPMS_MODE_ON; break; case Mode::Standby: wlMode = ORG_KDE_KWIN_DPMS_MODE_STANDBY; break; case Mode::Suspend: wlMode = ORG_KDE_KWIN_DPMS_MODE_SUSPEND; break; case Mode::Off: wlMode = ORG_KDE_KWIN_DPMS_MODE_OFF; break; default: Q_UNREACHABLE(); } org_kde_kwin_dpms_set(d->dpms, wlMode); } QPointer Dpms::output() const { return d->output; } Dpms::operator org_kde_kwin_dpms *() { return d->dpms; } Dpms::operator org_kde_kwin_dpms *() const { return d->dpms; } } } #include "moc_dpms.cpp"