File indexing completed on 2024-05-19 16:35:18

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