1 /*
2     SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "display.h"
7 #include "dpms_interface_p.h"
8 #include "output_interface.h"
9 
10 namespace KWayland
11 {
12 namespace Server
13 {
14 const quint32 DpmsManagerInterface::Private::s_version = 1;
15 
16 #ifndef K_DOXYGEN
17 const struct org_kde_kwin_dpms_manager_interface DpmsManagerInterface::Private::s_interface = {getDpmsCallback};
18 #endif
19 
Private(DpmsManagerInterface * qptr,Display * d)20 DpmsManagerInterface::Private::Private(DpmsManagerInterface *qptr, Display *d)
21     : Global::Private(d, &org_kde_kwin_dpms_manager_interface, s_version)
22     , q(qptr)
23 {
24 }
25 
bind(wl_client * client,uint32_t version,uint32_t id)26 void DpmsManagerInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
27 {
28     auto c = display->getConnection(client);
29     wl_resource *dpms = c->createResource(&org_kde_kwin_dpms_manager_interface, qMin(version, s_version), id);
30     if (!dpms) {
31         wl_client_post_no_memory(client);
32         return;
33     }
34     wl_resource_set_implementation(dpms, &s_interface, this, nullptr);
35 }
36 
getDpmsCallback(wl_client * client,wl_resource * resource,uint32_t id,wl_resource * output)37 void DpmsManagerInterface::Private::getDpmsCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *output)
38 {
39     auto p = Private::cast(resource);
40     auto c = p->display->getConnection(client);
41     OutputInterface *o = OutputInterface::get(output);
42     DpmsInterface *dpms = new DpmsInterface(o, resource, p->q);
43     dpms->create(c, wl_resource_get_version(resource), id);
44     if (!dpms->resource()) {
45         wl_resource_post_no_memory(resource);
46         return;
47     }
48     dpms->sendSupported();
49     dpms->sendMode();
50     dpms->sendDone();
51 }
52 
DpmsManagerInterface(Display * display,QObject * parent)53 DpmsManagerInterface::DpmsManagerInterface(Display *display, QObject *parent)
54     : Global(new Private(this, display), parent)
55 {
56 }
57 
58 DpmsManagerInterface::~DpmsManagerInterface() = default;
59 
60 #ifndef K_DOXYGEN
61 const struct org_kde_kwin_dpms_interface DpmsInterface::Private::s_interface = {setCallback, resourceDestroyedCallback};
62 #endif
63 
Private(DpmsInterface * q,DpmsManagerInterface * g,wl_resource * parentResource,OutputInterface * outputInterface)64 DpmsInterface::Private::Private(DpmsInterface *q, DpmsManagerInterface *g, wl_resource *parentResource, OutputInterface *outputInterface)
65     : Resource::Private(q, g, parentResource, &org_kde_kwin_dpms_interface, &s_interface)
66     , output(outputInterface)
67 {
68 }
69 
setCallback(wl_client * client,wl_resource * resource,uint32_t mode)70 void DpmsInterface::Private::setCallback(wl_client *client, wl_resource *resource, uint32_t mode)
71 {
72     Q_UNUSED(client)
73     OutputInterface::DpmsMode dpmsMode;
74     switch (mode) {
75     case ORG_KDE_KWIN_DPMS_MODE_ON:
76         dpmsMode = OutputInterface::DpmsMode::On;
77         break;
78     case ORG_KDE_KWIN_DPMS_MODE_STANDBY:
79         dpmsMode = OutputInterface::DpmsMode::Standby;
80         break;
81     case ORG_KDE_KWIN_DPMS_MODE_SUSPEND:
82         dpmsMode = OutputInterface::DpmsMode::Suspend;
83         break;
84     case ORG_KDE_KWIN_DPMS_MODE_OFF:
85         dpmsMode = OutputInterface::DpmsMode::Off;
86         break;
87     default:
88         return;
89     }
90     Q_EMIT cast<Private>(resource)->output->dpmsModeRequested(dpmsMode);
91 }
92 
DpmsInterface(OutputInterface * output,wl_resource * parentResource,DpmsManagerInterface * manager)93 DpmsInterface::DpmsInterface(OutputInterface *output, wl_resource *parentResource, DpmsManagerInterface *manager)
94     : Resource(new Private(this, manager, parentResource, output))
95 {
96     connect(output, &OutputInterface::dpmsSupportedChanged, this, [this] {
97         sendSupported();
98         sendDone();
99     });
100     connect(output, &OutputInterface::dpmsModeChanged, this, [this] {
101         sendMode();
102         sendDone();
103     });
104 }
105 
106 DpmsInterface::~DpmsInterface() = default;
107 
sendSupported()108 void DpmsInterface::sendSupported()
109 {
110     Q_D();
111     org_kde_kwin_dpms_send_supported(d->resource, d->output->isDpmsSupported() ? 1 : 0);
112 }
113 
sendMode()114 void DpmsInterface::sendMode()
115 {
116     Q_D();
117     const auto mode = d->output->dpmsMode();
118     org_kde_kwin_dpms_mode wlMode;
119     switch (mode) {
120     case OutputInterface::DpmsMode::On:
121         wlMode = ORG_KDE_KWIN_DPMS_MODE_ON;
122         break;
123     case OutputInterface::DpmsMode::Standby:
124         wlMode = ORG_KDE_KWIN_DPMS_MODE_STANDBY;
125         break;
126     case OutputInterface::DpmsMode::Suspend:
127         wlMode = ORG_KDE_KWIN_DPMS_MODE_SUSPEND;
128         break;
129     case OutputInterface::DpmsMode::Off:
130         wlMode = ORG_KDE_KWIN_DPMS_MODE_OFF;
131         break;
132     default:
133         Q_UNREACHABLE();
134     }
135     org_kde_kwin_dpms_send_mode(d->resource, wlMode);
136 }
137 
sendDone()138 void DpmsInterface::sendDone()
139 {
140     Q_D();
141     org_kde_kwin_dpms_send_done(d->resource);
142     client()->flush();
143 }
144 
d_func() const145 DpmsInterface::Private *DpmsInterface::d_func() const
146 {
147     return reinterpret_cast<Private *>(d.data());
148 }
149 
150 }
151 }
152