1 /********************************************************************
2 Copyright © 2020 Roman Gilg <subdiff@gmail.com>
3 
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), which shall
10 act as a proxy defined in Section 6 of version 3 of the license.
11 
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library.  If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
20 #include "dpms_p.h"
21 
22 #include "display.h"
23 #include "wl_output_p.h"
24 
25 #include "wayland/client.h"
26 #include "wayland/display.h"
27 
28 namespace Wrapland::Server
29 {
30 
31 const struct org_kde_kwin_dpms_manager_interface DpmsManager::Private::s_interface = {
32     cb<getDpmsCallback>,
33 };
34 
Private(Display * display,DpmsManager * q)35 DpmsManager::Private::Private(Display* display, DpmsManager* q)
36     : DpmsManagerGlobal(q, display, &org_kde_kwin_dpms_manager_interface, &s_interface)
37 {
38     create();
39 }
40 
getDpmsCallback(DpmsManagerBind * bind,uint32_t id,wl_resource * output)41 void DpmsManager::Private::getDpmsCallback(DpmsManagerBind* bind, uint32_t id, wl_resource* output)
42 {
43     auto dpms
44         = new Dpms(bind->client()->handle(), bind->version(), id, WlOutputGlobal::handle(output));
45     if (!dpms) {
46         return;
47     }
48 
49     dpms->sendSupported();
50     dpms->sendMode();
51     dpms->sendDone();
52 }
53 
DpmsManager(Display * display,QObject * parent)54 DpmsManager::DpmsManager(Display* display, QObject* parent)
55     : QObject(parent)
56     , d_ptr(new Private(display, this))
57 {
58 }
59 
60 DpmsManager::~DpmsManager() = default;
61 
62 const struct org_kde_kwin_dpms_interface Dpms::Private::s_interface = {
63     setCallback,
64     destroyCallback,
65 };
66 
Private(Client * client,uint32_t version,uint32_t id,WlOutput * output,Dpms * q)67 Dpms::Private::Private(Client* client, uint32_t version, uint32_t id, WlOutput* output, Dpms* q)
68     : Wayland::Resource<Dpms>(client, version, id, &org_kde_kwin_dpms_interface, &s_interface, q)
69     , output(output)
70 {
71 }
72 
setCallback(wl_client * client,wl_resource * wlResource,uint32_t mode)73 void Dpms::Private::setCallback(wl_client* client, wl_resource* wlResource, uint32_t mode)
74 {
75     Q_UNUSED(client)
76     Output::DpmsMode dpmsMode;
77     switch (mode) {
78     case ORG_KDE_KWIN_DPMS_MODE_ON:
79         dpmsMode = Output::DpmsMode::On;
80         break;
81     case ORG_KDE_KWIN_DPMS_MODE_STANDBY:
82         dpmsMode = Output::DpmsMode::Standby;
83         break;
84     case ORG_KDE_KWIN_DPMS_MODE_SUSPEND:
85         dpmsMode = Output::DpmsMode::Suspend;
86         break;
87     case ORG_KDE_KWIN_DPMS_MODE_OFF:
88         dpmsMode = Output::DpmsMode::Off;
89         break;
90     default:
91         return;
92     }
93     Q_EMIT handle(wlResource)->d_ptr->output->output()->dpms_mode_requested(dpmsMode);
94 }
95 
Dpms(Client * client,uint32_t version,uint32_t id,WlOutput * output)96 Dpms::Dpms(Client* client, uint32_t version, uint32_t id, WlOutput* output)
97     : d_ptr(new Private(client, version, id, output, this))
98 {
99     auto master_output = output->output();
100     connect(master_output, &Output::dpms_supported_changed, this, [this] {
101         sendSupported();
102         sendDone();
103     });
104     connect(master_output, &Output::dpms_mode_changed, this, [this] {
105         sendMode();
106         sendDone();
107     });
108 }
109 
sendSupported()110 void Dpms::sendSupported()
111 {
112     d_ptr->send<org_kde_kwin_dpms_send_supported>(d_ptr->output->output()->dpms_supported());
113 }
114 
sendMode()115 void Dpms::sendMode()
116 {
117     org_kde_kwin_dpms_mode mode = ORG_KDE_KWIN_DPMS_MODE_ON;
118 
119     switch (d_ptr->output->output()->dpms_mode()) {
120     case Output::DpmsMode::On:
121         mode = ORG_KDE_KWIN_DPMS_MODE_ON;
122         break;
123     case Output::DpmsMode::Standby:
124         mode = ORG_KDE_KWIN_DPMS_MODE_STANDBY;
125         break;
126     case Output::DpmsMode::Suspend:
127         mode = ORG_KDE_KWIN_DPMS_MODE_SUSPEND;
128         break;
129     case Output::DpmsMode::Off:
130         mode = ORG_KDE_KWIN_DPMS_MODE_OFF;
131         break;
132     default:
133         Q_UNREACHABLE();
134     }
135 
136     d_ptr->send<org_kde_kwin_dpms_send_mode>(mode);
137 }
138 
sendDone()139 void Dpms::sendDone()
140 {
141     d_ptr->send<org_kde_kwin_dpms_send_done>();
142     d_ptr->flush();
143 }
144 
145 }
146