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 "KWayland/Client/dpms.h"
7 #include "KWayland/Client/connection_thread.h"
8 #include "KWayland/Client/output.h"
9 #include "KWayland/Client/registry.h"
10 #include <QApplication>
11 #include <QDialogButtonBox>
12 #include <QFormLayout>
13 #include <QLabel>
14 #include <QPushButton>
15 #include <QVBoxLayout>
16 #include <QWidget>
17 
18 using namespace KWayland::Client;
19 
modeToString(Dpms::Mode mode)20 static QString modeToString(Dpms::Mode mode)
21 {
22     switch (mode) {
23     case Dpms::Mode::On:
24         return QStringLiteral("On");
25     case Dpms::Mode::Standby:
26         return QStringLiteral("Standby");
27     case Dpms::Mode::Suspend:
28         return QStringLiteral("Suspend");
29     case Dpms::Mode::Off:
30         return QStringLiteral("Off");
31     default:
32         Q_UNREACHABLE();
33     }
34 }
35 
supportedToString(bool supported)36 QString supportedToString(bool supported)
37 {
38     return supported ? QStringLiteral("Yes") : QStringLiteral("No");
39 }
40 
setupOutput(Registry::AnnouncedInterface outputInterface,Registry * registry,DpmsManager * manager)41 static QLayout *setupOutput(Registry::AnnouncedInterface outputInterface, Registry *registry, DpmsManager *manager)
42 {
43     Output *output = registry->createOutput(outputInterface.name, outputInterface.version, registry);
44     QLabel *label = new QLabel(output->model());
45     QObject::connect(
46         output,
47         &Output::changed,
48         label,
49         [label, output] {
50             label->setText(output->model());
51         },
52         Qt::QueuedConnection);
53 
54     Dpms *dpms = nullptr;
55     if (manager) {
56         dpms = manager->getDpms(output, output);
57     }
58 
59     QFormLayout *dpmsForm = new QFormLayout;
60     bool supported = dpms ? dpms->isSupported() : false;
61     QLabel *supportedLabel = new QLabel(supportedToString(supported));
62     dpmsForm->addRow(QStringLiteral("Supported:"), supportedLabel);
63     QLabel *modeLabel = new QLabel(modeToString(dpms ? dpms->mode() : Dpms::Mode::On));
64     dpmsForm->addRow(QStringLiteral("Mode:"), modeLabel);
65 
66     QPushButton *standbyButton = new QPushButton(QStringLiteral("Standby"));
67     QPushButton *suspendButton = new QPushButton(QStringLiteral("Suspend"));
68     QPushButton *offButton = new QPushButton(QStringLiteral("Off"));
69     standbyButton->setEnabled(supported);
70     suspendButton->setEnabled(supported);
71     offButton->setEnabled(supported);
72     QDialogButtonBox *bg = new QDialogButtonBox;
73     bg->addButton(standbyButton, QDialogButtonBox::ActionRole);
74     bg->addButton(suspendButton, QDialogButtonBox::ActionRole);
75     bg->addButton(offButton, QDialogButtonBox::ActionRole);
76 
77     if (dpms) {
78         QObject::connect(
79             dpms,
80             &Dpms::supportedChanged,
81             supportedLabel,
82             [supportedLabel, dpms, standbyButton, suspendButton, offButton] {
83                 const bool supported = dpms->isSupported();
84                 supportedLabel->setText(supportedToString(supported));
85                 standbyButton->setEnabled(supported);
86                 suspendButton->setEnabled(supported);
87                 offButton->setEnabled(supported);
88             },
89             Qt::QueuedConnection);
90         QObject::connect(
91             dpms,
92             &Dpms::modeChanged,
93             modeLabel,
94             [modeLabel, dpms] {
95                 modeLabel->setText(modeToString(dpms->mode()));
96             },
97             Qt::QueuedConnection);
98         QObject::connect(standbyButton, &QPushButton::clicked, dpms, [dpms] {
99             dpms->requestMode(Dpms::Mode::Standby);
100         });
101         QObject::connect(suspendButton, &QPushButton::clicked, dpms, [dpms] {
102             dpms->requestMode(Dpms::Mode::Suspend);
103         });
104         QObject::connect(offButton, &QPushButton::clicked, dpms, [dpms] {
105             dpms->requestMode(Dpms::Mode::Off);
106         });
107     }
108 
109     QVBoxLayout *layout = new QVBoxLayout;
110     layout->addWidget(label);
111     layout->addLayout(dpmsForm);
112     layout->addWidget(bg);
113     return layout;
114 }
115 
main(int argc,char ** argv)116 int main(int argc, char **argv)
117 {
118     qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("wayland"));
119     QApplication app(argc, argv);
120 
121     QWidget window;
122 
123     ConnectionThread *connection = ConnectionThread::fromApplication();
124     Registry registry;
125     registry.create(connection);
126     QObject::connect(
127         &registry,
128         &Registry::interfacesAnnounced,
129         &app,
130         [&registry, &window] {
131             const bool hasDpms = registry.hasInterface(Registry::Interface::Dpms);
132             QLabel *hasDpmsLabel = new QLabel(&window);
133             if (hasDpms) {
134                 hasDpmsLabel->setText(QStringLiteral("Compositor provides a DpmsManager"));
135             } else {
136                 hasDpmsLabel->setText(QStringLiteral("Compositor does not provide a DpmsManager"));
137             }
138 
139             QVBoxLayout *layout = new QVBoxLayout;
140             layout->addWidget(hasDpmsLabel);
141             QFrame *hline = new QFrame;
142             hline->setFrameShape(QFrame::HLine);
143             layout->addWidget(hline);
144 
145             DpmsManager *dpmsManager = nullptr;
146             if (hasDpms) {
147                 const auto dpmsData = registry.interface(Registry::Interface::Dpms);
148                 dpmsManager = registry.createDpmsManager(dpmsData.name, dpmsData.version);
149             }
150 
151             // get all Outputs
152             const auto outputs = registry.interfaces(Registry::Interface::Output);
153             for (auto o : outputs) {
154                 layout->addLayout(setupOutput(o, &registry, dpmsManager));
155                 QFrame *hline = new QFrame;
156                 hline->setFrameShape(QFrame::HLine);
157                 layout->addWidget(hline);
158             }
159 
160             window.setLayout(layout);
161             window.show();
162         },
163         Qt::QueuedConnection);
164     registry.setup();
165 
166     return app.exec();
167 }
168