File indexing completed on 2024-11-10 04:57:26

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 "display.h"
0008 #include "output.h"
0009 
0010 #include <QPointer>
0011 
0012 #include <qwayland-server-dpms.h>
0013 
0014 namespace KWin
0015 {
0016 
0017 static const quint32 s_version = 1;
0018 
0019 class DpmsManagerInterfacePrivate : public QtWaylandServer::org_kde_kwin_dpms_manager
0020 {
0021 public:
0022     DpmsManagerInterfacePrivate(Display *d);
0023 
0024 protected:
0025     void org_kde_kwin_dpms_manager_get(Resource *resource, uint32_t id, wl_resource *output) override;
0026 };
0027 
0028 class DpmsInterface : public QObject, QtWaylandServer::org_kde_kwin_dpms
0029 {
0030     Q_OBJECT
0031 public:
0032     explicit DpmsInterface(OutputInterface *output, wl_resource *resource);
0033 
0034     void sendSupported();
0035     void sendMode();
0036     void sendDone();
0037 
0038     QPointer<OutputInterface> m_output;
0039 
0040 protected:
0041     void org_kde_kwin_dpms_destroy_resource(Resource *resource) override;
0042     void org_kde_kwin_dpms_set(Resource *resource, uint32_t mode) override;
0043     void org_kde_kwin_dpms_release(Resource *resource) override;
0044 };
0045 
0046 DpmsManagerInterfacePrivate::DpmsManagerInterfacePrivate(Display *display)
0047     : QtWaylandServer::org_kde_kwin_dpms_manager(*display, s_version)
0048 {
0049 }
0050 
0051 void DpmsManagerInterfacePrivate::org_kde_kwin_dpms_manager_get(Resource *resource, uint32_t id, wl_resource *output)
0052 {
0053     OutputInterface *o = OutputInterface::get(output);
0054 
0055     wl_resource *dpms_resource = wl_resource_create(resource->client(), &org_kde_kwin_dpms_interface, resource->version(), id);
0056     if (!dpms_resource) {
0057         wl_client_post_no_memory(resource->client());
0058         return;
0059     }
0060 
0061     new DpmsInterface(o, dpms_resource);
0062 }
0063 
0064 DpmsManagerInterface::DpmsManagerInterface(Display *display, QObject *parent)
0065     : QObject(parent)
0066     , d(new DpmsManagerInterfacePrivate(display))
0067 {
0068 }
0069 
0070 DpmsManagerInterface::~DpmsManagerInterface() = default;
0071 
0072 DpmsInterface::DpmsInterface(OutputInterface *output, wl_resource *resource)
0073     : QObject()
0074     , QtWaylandServer::org_kde_kwin_dpms(resource)
0075     , m_output(output)
0076 {
0077     if (!m_output || m_output->isRemoved()) {
0078         return;
0079     }
0080 
0081     sendSupported();
0082     sendMode();
0083     sendDone();
0084 
0085     connect(m_output->handle(), &Output::capabilitiesChanged, this, [this]() {
0086         sendSupported();
0087         sendDone();
0088     });
0089     connect(m_output->handle(), &Output::dpmsModeChanged, this, [this]() {
0090         sendMode();
0091         sendDone();
0092     });
0093 }
0094 
0095 void DpmsInterface::org_kde_kwin_dpms_release(Resource *resource)
0096 {
0097     wl_resource_destroy(resource->handle);
0098 }
0099 
0100 void DpmsInterface::org_kde_kwin_dpms_destroy_resource(Resource *resource)
0101 {
0102     delete this;
0103 }
0104 
0105 void DpmsInterface::org_kde_kwin_dpms_set(Resource *resource, uint32_t mode)
0106 {
0107     if (!m_output || m_output->isRemoved()) {
0108         return;
0109     }
0110 
0111     Output::DpmsMode dpmsMode;
0112     switch (mode) {
0113     case ORG_KDE_KWIN_DPMS_MODE_ON:
0114         dpmsMode = Output::DpmsMode::On;
0115         break;
0116     case ORG_KDE_KWIN_DPMS_MODE_STANDBY:
0117         dpmsMode = Output::DpmsMode::Standby;
0118         break;
0119     case ORG_KDE_KWIN_DPMS_MODE_SUSPEND:
0120         dpmsMode = Output::DpmsMode::Suspend;
0121         break;
0122     case ORG_KDE_KWIN_DPMS_MODE_OFF:
0123         dpmsMode = Output::DpmsMode::Off;
0124         break;
0125     default:
0126         return;
0127     }
0128 
0129     m_output->handle()->setDpmsMode(dpmsMode);
0130 }
0131 
0132 void DpmsInterface::sendSupported()
0133 {
0134     if (!m_output || m_output->isRemoved()) {
0135         return;
0136     }
0137 
0138     send_supported(m_output->handle()->capabilities() & Output::Capability::Dpms ? 1 : 0);
0139 }
0140 
0141 void DpmsInterface::sendMode()
0142 {
0143     if (!m_output || m_output->isRemoved()) {
0144         return;
0145     }
0146 
0147     const auto mode = m_output->handle()->dpmsMode();
0148     org_kde_kwin_dpms_mode wlMode;
0149     switch (mode) {
0150     case Output::DpmsMode::On:
0151         wlMode = ORG_KDE_KWIN_DPMS_MODE_ON;
0152         break;
0153     case Output::DpmsMode::Standby:
0154         wlMode = ORG_KDE_KWIN_DPMS_MODE_STANDBY;
0155         break;
0156     case Output::DpmsMode::Suspend:
0157         wlMode = ORG_KDE_KWIN_DPMS_MODE_SUSPEND;
0158         break;
0159     case Output::DpmsMode::Off:
0160         wlMode = ORG_KDE_KWIN_DPMS_MODE_OFF;
0161         break;
0162     default:
0163         Q_UNREACHABLE();
0164     }
0165     send_mode(wlMode);
0166 }
0167 
0168 void DpmsInterface::sendDone()
0169 {
0170     send_done();
0171 }
0172 
0173 }
0174 
0175 #include "dpms.moc"
0176 
0177 #include "moc_dpms.cpp"