1 /***************************************************************************
2  *   Copyright (C) 2010 by Dario Freddi <drf@kde.org>                      *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
18  ***************************************************************************/
19 
20 #include "brightnesscontrol.h"
21 
22 #include "brightnessosdwidget.h"
23 
24 #include "brightnesscontroladaptor.h"
25 
26 #include <powerdevilcore.h>
27 #include <powerdevil_debug.h>
28 
29 #include <QDesktopWidget>
30 #include <QAction>
31 #include <QDebug>
32 
33 #include <KActionCollection>
34 #include <KConfigGroup>
35 #include <KLocalizedString>
36 #include <KGlobalAccel>
37 namespace PowerDevil {
38 namespace BundledActions {
39 
BrightnessControl(QObject * parent)40 BrightnessControl::BrightnessControl(QObject* parent)
41     : Action(parent)
42 {
43     // DBus
44     new BrightnessControlAdaptor(this);
45 
46     setRequiredPolicies(PowerDevil::PolicyAgent::ChangeScreenSettings);
47 
48     connect(core()->backend(), &PowerDevil::BackendInterface::brightnessChanged, this, &PowerDevil::BundledActions::BrightnessControl::onBrightnessChangedFromBackend);
49 
50     KActionCollection* actionCollection = new KActionCollection( this );
51     actionCollection->setComponentDisplayName(i18nc("Name for powerdevil shortcuts category", "Power Management"));
52 
53     QAction* globalAction = actionCollection->addAction(QLatin1String("Increase Screen Brightness"));
54     globalAction->setText(i18nc("@action:inmenu Global shortcut", "Increase Screen Brightness"));
55     KGlobalAccel::setGlobalShortcut(globalAction, Qt::Key_MonBrightnessUp);
56     connect(globalAction, &QAction::triggered, this, &BrightnessControl::increaseBrightness);
57 
58     globalAction = actionCollection->addAction(QLatin1String("Decrease Screen Brightness"));
59     globalAction->setText(i18nc("@action:inmenu Global shortcut", "Decrease Screen Brightness"));
60     KGlobalAccel::setGlobalShortcut(globalAction, Qt::Key_MonBrightnessDown);
61     connect(globalAction, &QAction::triggered, this, &BrightnessControl::decreaseBrightness);
62 }
63 
onProfileUnload()64 void BrightnessControl::onProfileUnload()
65 {
66     //
67 }
68 
onWakeupFromIdle()69 void BrightnessControl::onWakeupFromIdle()
70 {
71     //
72 }
73 
onIdleTimeout(int msec)74 void BrightnessControl::onIdleTimeout(int msec)
75 {
76     Q_UNUSED(msec);
77 }
78 
onProfileLoad()79 void BrightnessControl::onProfileLoad()
80 {
81     const int absoluteBrightnessValue = qRound(m_defaultValue / 100.0 * brightnessMax());
82 
83     // if the current profile is more conservative than the previous one and the
84     // current brightness is lower than the new profile
85     if (((m_currentProfile == QLatin1String("Battery") && m_lastProfile == QLatin1String("AC")) ||
86          (m_currentProfile == QLatin1String("LowBattery") && (m_lastProfile == QLatin1String("AC") || m_lastProfile == QLatin1String("Battery")))) &&
87         absoluteBrightnessValue > brightness()) {
88 
89         // We don't want to change anything here
90         qCDebug(POWERDEVIL) << "Not changing brightness, the current one is lower and the profile is more conservative";
91     } else if (absoluteBrightnessValue >= 0) {
92         QVariantMap args{
93             {QStringLiteral("Value"), QVariant::fromValue(absoluteBrightnessValue)}
94         };
95 
96         // plugging in/out the AC is always explicit
97         if ((m_currentProfile == QLatin1String("AC") && m_lastProfile != QLatin1String("AC")) ||
98             (m_currentProfile != QLatin1String("AC") && m_lastProfile == QLatin1String("AC"))) {
99             args["Explicit"] = true;
100             args["Silent"] = true; // but we still don't want to show the OSD then
101         }
102 
103         trigger(args);
104     }
105 }
106 
triggerImpl(const QVariantMap & args)107 void BrightnessControl::triggerImpl(const QVariantMap &args)
108 {
109     const int value = args.value(QStringLiteral("Value")).toInt();
110 
111     backend()->setBrightness(value);
112     if (args.value(QStringLiteral("Explicit")).toBool() && !args.value(QStringLiteral("Silent")).toBool()) {
113         BrightnessOSDWidget::show(brightnessPercent(value));
114     }
115 }
116 
isSupported()117 bool BrightnessControl::isSupported()
118 {
119     BackendInterface::BrightnessControlsList controls = backend()->brightnessControlsAvailable();
120     if (controls.key(BackendInterface::Screen).isEmpty()) {
121         return false;
122     }
123 
124     return true;
125 }
126 
loadAction(const KConfigGroup & config)127 bool BrightnessControl::loadAction(const KConfigGroup& config)
128 {
129     // Handle profile changes
130     m_lastProfile = m_currentProfile;
131     m_currentProfile = config.parent().name();
132 
133     qCDebug(POWERDEVIL) << "Profiles: " << m_currentProfile << m_lastProfile;
134 
135     if (config.hasKey("value")) {
136         m_defaultValue = config.readEntry<int>("value", 50);
137     }
138 
139     return true;
140 }
141 
onBrightnessChangedFromBackend(const BrightnessLogic::BrightnessInfo & info,BackendInterface::BrightnessControlType type)142 void BrightnessControl::onBrightnessChangedFromBackend(const BrightnessLogic::BrightnessInfo &info, BackendInterface::BrightnessControlType type)
143 {
144     if (type == BackendInterface::Screen) {
145         Q_EMIT brightnessChanged(info.value);
146         Q_EMIT brightnessMaxChanged(info.valueMax);
147     }
148 }
149 
brightness() const150 int BrightnessControl::brightness() const
151 {
152     return backend()->brightness();
153 }
154 
brightnessMax() const155 int BrightnessControl::brightnessMax() const
156 {
157     return backend()->brightnessMax();
158 }
159 
setBrightness(int value)160 void BrightnessControl::setBrightness(int value)
161 {
162     trigger({
163         {QStringLiteral("Value"), QVariant::fromValue(value)},
164         {QStringLiteral("Explicit"), true}
165     });
166 }
167 
setBrightnessSilent(int value)168 void BrightnessControl::setBrightnessSilent(int value)
169 {
170     trigger({
171         {QStringLiteral("Value"), QVariant::fromValue(value)},
172         {QStringLiteral("Explicit"), true},
173         {QStringLiteral("Silent"), true}
174     });
175 }
176 
increaseBrightness()177 void BrightnessControl::increaseBrightness()
178 {
179     const int newBrightness = backend()->brightnessKeyPressed(BrightnessLogic::Increase);
180     if (newBrightness > -1) {
181         BrightnessOSDWidget::show(brightnessPercent(newBrightness));
182     }
183 }
184 
decreaseBrightness()185 void BrightnessControl::decreaseBrightness()
186 {
187     const int newBrightness = backend()->brightnessKeyPressed(BrightnessLogic::Decrease);
188     if (newBrightness > -1) {
189         BrightnessOSDWidget::show(brightnessPercent(newBrightness));
190     }
191 }
192 
brightnessSteps() const193 int BrightnessControl::brightnessSteps() const
194 {
195     return backend()->brightnessSteps();
196 }
197 
brightnessPercent(float value) const198 int BrightnessControl::brightnessPercent(float value) const
199 {
200     const float maxBrightness = brightnessMax();
201     if (maxBrightness <= 0) {
202         return 0;
203     }
204 
205     return qRound(value / maxBrightness * 100);
206 }
207 
208 }
209 }
210