diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt
index 25ecf2b6fc..bdbf688d06 100644
--- a/src/wayland/CMakeLists.txt
+++ b/src/wayland/CMakeLists.txt
@@ -7,6 +7,7 @@ set(SERVER_LIB_SRCS
dataoffer_interface.cpp
datasource_interface.cpp
display.cpp
+ dpms_interface.cpp
global.cpp
idle_interface.cpp
fakeinput_interface.cpp
@@ -59,6 +60,10 @@ ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWAYLAND_SOURCE_DIR}/src/client/protocols/shadow.xml
BASENAME shadow
)
+ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
+ PROTOCOL ${KWAYLAND_SOURCE_DIR}/src/client/protocols/dpms.xml
+ BASENAME dpms
+)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWAYLAND_SOURCE_DIR}/src/client/protocols/blur.xml
@@ -120,6 +125,7 @@ install(FILES
dataoffer_interface.h
datasource_interface.h
display.h
+ dpms_interface.h
fakeinput_interface.h
global.h
idle_interface.h
diff --git a/src/wayland/display.cpp b/src/wayland/display.cpp
index c7cfa0ad2c..019991a6e7 100644
--- a/src/wayland/display.cpp
+++ b/src/wayland/display.cpp
@@ -20,6 +20,7 @@ License along with this library. If not, see .
#include "display.h"
#include "compositor_interface.h"
#include "datadevicemanager_interface.h"
+#include "dpms_interface.h"
#include "idle_interface.h"
#include "fakeinput_interface.h"
#include "logging_p.h"
@@ -295,6 +296,13 @@ SlideManagerInterface *Display::createSlideManager(QObject *parent)
return b;
}
+DpmsManagerInterface *Display::createDpmsManager(QObject *parent)
+{
+ auto d = new DpmsManagerInterface(this, parent);
+ connect(this, &Display::aboutToTerminate, d, [this, d] { delete d; });
+ return d;
+}
+
void Display::createShm()
{
Q_ASSERT(d->display);
diff --git a/src/wayland/display.h b/src/wayland/display.h
index fc885a5dbf..677c0313c7 100644
--- a/src/wayland/display.h
+++ b/src/wayland/display.h
@@ -38,6 +38,7 @@ namespace Server
class CompositorInterface;
class DataDeviceManagerInterface;
+class DpmsManagerInterface;
class IdleInterface;
class FakeInputInterface;
class OutputInterface;
@@ -137,6 +138,7 @@ public:
BlurManagerInterface *createBlurManager(QObject *parent = nullptr);
ContrastManagerInterface *createContrastManager(QObject *parent = nullptr);
SlideManagerInterface *createSlideManager(QObject *parent = nullptr);
+ DpmsManagerInterface *createDpmsManager(QObject *parent = nullptr);
/**
* Gets the ClientConnection for the given @p client.
diff --git a/src/wayland/dpms_interface.cpp b/src/wayland/dpms_interface.cpp
new file mode 100644
index 0000000000..fa299f30f5
--- /dev/null
+++ b/src/wayland/dpms_interface.cpp
@@ -0,0 +1,184 @@
+/********************************************************************
+Copyright 2015 Martin Gräßlin
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) version 3, or any
+later version accepted by the membership of KDE e.V. (or its
+successor approved by the membership of KDE e.V.), which shall
+act as a proxy defined in Section 6 of version 3 of the license.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library. If not, see .
+*********************************************************************/
+#include "dpms_interface_p.h"
+#include "display.h"
+#include "output_interface.h"
+
+namespace KWayland
+{
+namespace Server
+{
+
+static const quint32 s_version = 1;
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+const struct org_kde_kwin_dpms_manager_interface DpmsManagerInterface::Private::s_interface = {
+ getDpmsCallback
+};
+#endif
+
+DpmsManagerInterface::Private::Private(DpmsManagerInterface *q, Display *d)
+ : Global::Private(d, &org_kde_kwin_dpms_manager_interface, s_version)
+ , q(q)
+{
+}
+
+void DpmsManagerInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
+{
+ auto c = display->getConnection(client);
+ wl_resource *dpms = c->createResource(&org_kde_kwin_dpms_manager_interface, qMin(version, s_version), id);
+ if (!dpms) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+ wl_resource_set_implementation(dpms, &s_interface, this, nullptr);
+}
+
+void DpmsManagerInterface::Private::getDpmsCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *output)
+{
+ auto p = Private::cast(resource);
+ auto c = p->display->getConnection(client);
+ OutputInterface *o = OutputInterface::get(output);
+ DpmsInterface *dpms = new DpmsInterface(o, resource, p->q);
+ dpms->create(c, wl_resource_get_version(resource), id);
+ if (!dpms->resource()) {
+ wl_resource_post_no_memory(resource);
+ return;
+ }
+ dpms->sendSupported();
+ dpms->sendMode();
+ dpms->sendDone();
+}
+
+DpmsManagerInterface::DpmsManagerInterface(Display *display, QObject *parent)
+ : Global(new Private(this, display), parent)
+{
+}
+
+DpmsManagerInterface::~DpmsManagerInterface() = default;
+
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+const struct org_kde_kwin_dpms_interface DpmsInterface::Private::s_interface = {
+ setCallback,
+ releaseCallback
+};
+#endif
+
+DpmsInterface::Private::Private(DpmsInterface *q, DpmsManagerInterface *g, wl_resource *parentResource, OutputInterface *output)
+ : Resource::Private(q, g, parentResource, &org_kde_kwin_dpms_interface, &s_interface)
+ , output(output)
+{
+}
+
+void DpmsInterface::Private::setCallback(wl_client *client, wl_resource *resource, uint32_t mode)
+{
+ Q_UNUSED(client)
+ OutputInterface::DpmsMode dpmsMode;
+ switch (mode) {
+ case ORG_KDE_KWIN_DPMS_MODE_ON:
+ dpmsMode = OutputInterface::DpmsMode::On;
+ break;
+ case ORG_KDE_KWIN_DPMS_MODE_STANDBY:
+ dpmsMode = OutputInterface::DpmsMode::Standby;
+ break;
+ case ORG_KDE_KWIN_DPMS_MODE_SUSPEND:
+ dpmsMode = OutputInterface::DpmsMode::Suspend;
+ break;
+ case ORG_KDE_KWIN_DPMS_MODE_OFF:
+ dpmsMode = OutputInterface::DpmsMode::Off;
+ break;
+ default:
+ return;
+ }
+ emit cast(resource)->output->dpmsModeRequested(dpmsMode);
+}
+
+void DpmsInterface::Private::releaseCallback(wl_client *client, wl_resource *resource)
+{
+ Q_UNUSED(client)
+ Private *p = reinterpret_cast(wl_resource_get_user_data(resource));
+ wl_resource_destroy(resource);
+ p->q->deleteLater();
+}
+
+DpmsInterface::DpmsInterface(OutputInterface *output, wl_resource *parentResource, DpmsManagerInterface *manager)
+ : Resource(new Private(this, manager, parentResource, output), manager)
+{
+ connect(output, &OutputInterface::dpmsSupportedChanged, this,
+ [this] {
+ sendSupported();
+ sendDone();
+ }
+ );
+ connect(output, &OutputInterface::dpmsModeChanged, this,
+ [this] {
+ sendMode();
+ sendDone();
+ }
+ );
+}
+
+DpmsInterface::~DpmsInterface() = default;
+
+void DpmsInterface::sendSupported()
+{
+ Q_D();
+ org_kde_kwin_dpms_send_supported(d->resource, d->output->isDpmsSupported() ? 1 : 0);
+}
+
+void DpmsInterface::sendMode()
+{
+ Q_D();
+ const auto mode = d->output->dpmsMode();
+ org_kde_kwin_dpms_mode wlMode;
+ switch (mode) {
+ case OutputInterface::DpmsMode::On:
+ wlMode = ORG_KDE_KWIN_DPMS_MODE_ON;
+ break;
+ case OutputInterface::DpmsMode::Standby:
+ wlMode = ORG_KDE_KWIN_DPMS_MODE_STANDBY;
+ break;
+ case OutputInterface::DpmsMode::Suspend:
+ wlMode = ORG_KDE_KWIN_DPMS_MODE_SUSPEND;
+ break;
+ case OutputInterface::DpmsMode::Off:
+ wlMode = ORG_KDE_KWIN_DPMS_MODE_OFF;
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+ org_kde_kwin_dpms_send_mode(d->resource, wlMode);
+}
+
+void DpmsInterface::sendDone()
+{
+ Q_D();
+ org_kde_kwin_dpms_send_done(d->resource);
+ client()->flush();
+}
+
+DpmsInterface::Private *DpmsInterface::d_func() const
+{
+ return reinterpret_cast(d.data());
+}
+
+}
+}
diff --git a/src/wayland/dpms_interface.h b/src/wayland/dpms_interface.h
new file mode 100644
index 0000000000..cb3045ea4a
--- /dev/null
+++ b/src/wayland/dpms_interface.h
@@ -0,0 +1,81 @@
+/********************************************************************
+Copyright 2015 Martin Gräßlin
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) version 3, or any
+later version accepted by the membership of KDE e.V. (or its
+successor approved by the membership of KDE e.V.), which shall
+act as a proxy defined in Section 6 of version 3 of the license.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library. If not, see .
+*********************************************************************/
+#ifndef WAYLAND_SERVER_DPMS_INTERFACE_H
+#define WAYLAND_SERVER_DPMS_INTERFACE_H
+
+#include
+
+#include
+#include "global.h"
+
+namespace KWayland
+{
+namespace Server
+{
+
+class Display;
+
+/**
+ * @brief Global for the org_kde_kwin_dpms_manager interface.
+ *
+ * If the DpmsManagerInterface is created it allows a client to
+ * query the Dpms state on a given OutputInterface and request
+ * changes for it. The code interaction happens only via the
+ * OutputInterface.
+ *
+ * To create a DpmsManagerInterface use:
+ * @code
+ * auto manager = display->createDpmsManager();
+ * manager->create();
+ * @endcode
+ *
+ * To interact with Dpms use one needs to mark it as enabled and set the
+ * proper mode on the OutputInterface.
+ * @code
+ * // We have our OutputInterface called output.
+ * output->setDpmsSupported(true);
+ * output->setDpmsMode(OutputInterface::DpmsMode::On);
+ * @endcode
+ *
+ * To connect to Dpms change requests use:
+ * @code
+ * connect(output, &OutputInterface::dpmsModeRequested,
+ * [] (KWayland::Server::OutputInterface::DpmsMode requestedMode) { qDebug() << "Mode change requested"; });
+ * @endcode
+ *
+ * @see Display
+ * @see OutputInterface
+ **/
+class KWAYLANDSERVER_EXPORT DpmsManagerInterface : public Global
+{
+ Q_OBJECT
+public:
+ virtual ~DpmsManagerInterface();
+
+private:
+ explicit DpmsManagerInterface(Display *display, QObject *parent = nullptr);
+ friend class Display;
+ class Private;
+};
+
+}
+}
+
+#endif
diff --git a/src/wayland/dpms_interface_p.h b/src/wayland/dpms_interface_p.h
new file mode 100644
index 0000000000..9e156b2816
--- /dev/null
+++ b/src/wayland/dpms_interface_p.h
@@ -0,0 +1,84 @@
+/********************************************************************
+Copyright 2015 Martin Gräßlin
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) version 3, or any
+later version accepted by the membership of KDE e.V. (or its
+successor approved by the membership of KDE e.V.), which shall
+act as a proxy defined in Section 6 of version 3 of the license.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library. If not, see .
+*********************************************************************/
+#ifndef WAYLAND_SERVER_DPMS_INTERFACE_P_H
+#define WAYLAND_SERVER_DPMS_INTERFACE_P_H
+
+#include "dpms_interface.h"
+#include "global_p.h"
+#include "resource_p.h"
+
+#include
+
+namespace KWayland
+{
+namespace Server
+{
+
+class OutputInterface;
+
+class DpmsManagerInterface::Private : public Global::Private
+{
+public:
+ Private(DpmsManagerInterface *q, Display *d);
+
+private:
+ static void getDpmsCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *output);
+ static Private *cast(wl_resource *r) {
+ return reinterpret_cast(wl_resource_get_user_data(r));
+ }
+ void bind(wl_client *client, uint32_t version, uint32_t id) override;
+
+ DpmsManagerInterface *q;
+ static const struct org_kde_kwin_dpms_manager_interface s_interface;
+};
+
+class DpmsInterface : public Resource
+{
+ Q_OBJECT
+public:
+ explicit DpmsInterface(OutputInterface *output, wl_resource *parentResource, DpmsManagerInterface *manager);
+ virtual ~DpmsInterface();
+
+ void sendSupported();
+ void sendMode();
+ void sendDone();
+
+private:
+ class Private;
+ Private *d_func() const;
+};
+
+class DpmsInterface::Private : public Resource::Private
+{
+public:
+ explicit Private(DpmsInterface *q, DpmsManagerInterface *g, wl_resource *parentResource, OutputInterface *output);
+
+ OutputInterface *output;
+
+private:
+ static void setCallback(wl_client *client, wl_resource *resource, uint32_t mode);
+ static void releaseCallback(wl_client *client, wl_resource *resource);
+ static const struct org_kde_kwin_dpms_interface s_interface;
+};
+
+}
+}
+
+#endif
diff --git a/src/wayland/output_interface.cpp b/src/wayland/output_interface.cpp
index e295eb6ab7..707ceb17a6 100644
--- a/src/wayland/output_interface.cpp
+++ b/src/wayland/output_interface.cpp
@@ -55,6 +55,10 @@ public:
Transform transform = Transform::Normal;
QList modes;
QList resources;
+ struct {
+ DpmsMode mode = DpmsMode::On;
+ bool supported = false;
+ } dpms;
static OutputInterface *get(wl_resource *native);
@@ -458,6 +462,38 @@ QList< OutputInterface::Mode > OutputInterface::modes() const
return d->modes;
}
+void OutputInterface::setDpmsMode(OutputInterface::DpmsMode mode)
+{
+ Q_D();
+ if (d->dpms.mode == mode) {
+ return;
+ }
+ d->dpms.mode = mode;
+ emit dpmsModeChanged();
+}
+
+void OutputInterface::setDpmsSupported(bool supported)
+{
+ Q_D();
+ if (d->dpms.supported == supported) {
+ return;
+ }
+ d->dpms.supported = supported;
+ emit dpmsSupportedChanged();
+}
+
+OutputInterface::DpmsMode OutputInterface::dpmsMode() const
+{
+ Q_D();
+ return d->dpms.mode;
+}
+
+bool OutputInterface::isDpmsSupported() const
+{
+ Q_D();
+ return d->dpms.supported;
+}
+
OutputInterface *OutputInterface::get(wl_resource* native)
{
return Private::get(native);
diff --git a/src/wayland/output_interface.h b/src/wayland/output_interface.h
index 56a8845e4c..b40f2a9a53 100644
--- a/src/wayland/output_interface.h
+++ b/src/wayland/output_interface.h
@@ -77,6 +77,12 @@ public:
int refreshRate = 60000;
ModeFlags flags;
};
+ enum class DpmsMode {
+ On,
+ Standby,
+ Suspend,
+ Off
+ };
virtual ~OutputInterface();
QSize physicalSize() const;
@@ -89,6 +95,8 @@ public:
SubPixel subPixel() const;
Transform transform() const;
QList modes() const;
+ bool isDpmsSupported() const;
+ DpmsMode dpmsMode() const;
void setPhysicalSize(const QSize &size);
void setGlobalPosition(const QPoint &pos);
@@ -100,6 +108,19 @@ public:
void addMode(const QSize &size, ModeFlags flags = ModeFlags(), int refreshRate = 60000);
void setCurrentMode(const QSize &size, int refreshRate = 60000);
+ /**
+ * Sets whether Dpms is supported for this output.
+ * Default is @c false.
+ * @since 5.5
+ **/
+ void setDpmsSupported(bool supported);
+ /**
+ * Sets the currently used dpms mode.
+ * Default is @c DpmsMode::On.
+ * @since 5.5
+ **/
+ void setDpmsMode(DpmsMode mode);
+
static OutputInterface *get(wl_resource *native);
Q_SIGNALS:
@@ -114,6 +135,15 @@ Q_SIGNALS:
void transformChanged(Transform);
void modesChanged();
void currentModeChanged();
+ void dpmsModeChanged();
+ void dpmsSupportedChanged();
+
+ /**
+ * Change of dpms @p mode is requested.
+ * A server is free to ignore this request.
+ * @since 5.5
+ **/
+ void dpmsModeRequested(KWayland::Server::OutputInterface::DpmsMode mode);
private:
friend class Display;
@@ -128,5 +158,6 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(KWayland::Server::OutputInterface::ModeFlags)
Q_DECLARE_METATYPE(KWayland::Server::OutputInterface::SubPixel)
Q_DECLARE_METATYPE(KWayland::Server::OutputInterface::Transform)
+Q_DECLARE_METATYPE(KWayland::Server::OutputInterface::DpmsMode)
#endif