File indexing completed on 2024-05-19 05:39:20
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2006 Kevin Ottens <ervin@kde.org> 0003 SPDX-FileCopyrightText: 2008-2010 Dario Freddi <drf@kde.org> 0004 SPDX-FileCopyrightText: 2010 Alejandro Fiestas <alex@eyeos.org> 0005 SPDX-FileCopyrightText: 2010-2013 Lukáš Tinkl <ltinkl@redhat.com> 0006 SPDX-FileCopyrightText: 2015 Kai Uwe Broulik <kde@privat.broulik.de> 0007 0008 SPDX-License-Identifier: LGPL-2.0-only 0009 0010 */ 0011 0012 #include "screenbrightnesscontroller.h" 0013 0014 #include <brightnessosdwidget.h> 0015 #include <powerdevil_debug.h> 0016 0017 #include <QDebug> 0018 #include <QPropertyAnimation> 0019 0020 #include "backlightbrightness.h" 0021 #include "ddcutilbrightness.h" 0022 0023 ScreenBrightnessController::ScreenBrightnessController() 0024 : QObject() 0025 , m_backlightBrightnessControl(new BacklightBrightness(this)) 0026 , m_ddcBrightnessControl(new DDCutilBrightness(this)) 0027 { 0028 connect(m_backlightBrightnessControl, &BacklightBrightness::detectionFinished, this, &ScreenBrightnessController::onBacklightDetectionFinished); 0029 connect(m_backlightBrightnessControl, &BacklightBrightness::brightnessChanged, this, &ScreenBrightnessController::onScreenBrightnessChanged); 0030 0031 qCDebug(POWERDEVIL) << "Trying to detect internal display backlight for brightness control..."; 0032 m_backlightBrightnessControl->detect(); 0033 } 0034 0035 void ScreenBrightnessController::onBacklightDetectionFinished(bool isSupported) 0036 { 0037 disconnect(m_backlightBrightnessControl, &BacklightBrightness::detectionFinished, this, &ScreenBrightnessController::onBacklightDetectionFinished); 0038 0039 if (isSupported) { 0040 m_screenBrightnessAvailable = true; 0041 m_cachedBrightness = m_backlightBrightnessControl->brightness(); 0042 } else { 0043 qCDebug(POWERDEVIL) << "No internal dislay backlight detected. Trying DDC for brightness controls..."; 0044 m_ddcBrightnessControl->detect(); 0045 if (m_ddcBrightnessControl->isSupported()) { 0046 qCDebug(POWERDEVIL) << "Using DDCutillib"; 0047 m_cachedBrightness = screenBrightness(); 0048 if (m_brightnessAnimationDurationMsec > 0 && screenBrightnessMax() >= m_brightnessAnimationThreshold) { 0049 m_brightnessAnimation = new QPropertyAnimation(this); 0050 m_brightnessAnimation->setTargetObject(this); 0051 m_brightnessAnimation->setDuration(m_brightnessAnimationDurationMsec); 0052 connect(m_brightnessAnimation, &QPropertyAnimation::valueChanged, this, &ScreenBrightnessController::animationValueChanged); 0053 connect(m_brightnessAnimation, &QPropertyAnimation::finished, this, &ScreenBrightnessController::ddcScreenBrightnessChanged); 0054 } 0055 m_screenBrightnessAvailable = true; 0056 } 0057 } 0058 // Brightness Controls available 0059 if (m_screenBrightnessAvailable) { 0060 qCDebug(POWERDEVIL) << "initial screen brightness value:" << m_cachedBrightness; 0061 } 0062 Q_EMIT detectionFinished(); 0063 } 0064 0065 int ScreenBrightnessController::screenBrightnessSteps() 0066 { 0067 m_screenBrightnessLogic.setValueMax(screenBrightnessMax()); 0068 return m_screenBrightnessLogic.steps(); 0069 } 0070 0071 int ScreenBrightnessController::calculateNextScreenBrightnessStep(int value, int valueMax, PowerDevil::BrightnessLogic::BrightnessKeyType keyType) 0072 { 0073 m_screenBrightnessLogic.setValueMax(valueMax); 0074 m_screenBrightnessLogic.setValue(value); 0075 0076 return m_screenBrightnessLogic.action(keyType); 0077 } 0078 0079 int ScreenBrightnessController::screenBrightnessKeyPressed(PowerDevil::BrightnessLogic::BrightnessKeyType type) 0080 { 0081 if (!m_screenBrightnessAvailable) { 0082 return -1; // ignore as we are not able to determine the brightness level 0083 } 0084 0085 int currentBrightness = screenBrightness(); 0086 // m_cachedBrightness is not being updated during animation, thus checking the m_cachedBrightness 0087 // value here doesn't make much sense, use the endValue from brightness() anyway. 0088 // This prevents brightness key being ignored during the animation. 0089 if (!(m_brightnessAnimation && m_brightnessAnimation->state() == QPropertyAnimation::Running) && currentBrightness != m_cachedBrightness) { 0090 m_cachedBrightness = currentBrightness; 0091 return currentBrightness; 0092 } 0093 0094 int maxBrightness = screenBrightnessMax(); 0095 int newBrightness = calculateNextScreenBrightnessStep(currentBrightness, maxBrightness, type); 0096 0097 if (newBrightness < 0) { 0098 return -1; 0099 } 0100 0101 setScreenBrightness(newBrightness); 0102 return newBrightness; 0103 } 0104 0105 int ScreenBrightnessController::screenBrightness() const 0106 { 0107 int result = 0; 0108 0109 if (m_ddcBrightnessControl->isSupported()) { 0110 if (m_brightnessAnimation && m_brightnessAnimation->state() == QPropertyAnimation::Running) { 0111 result = m_brightnessAnimation->endValue().toInt(); 0112 } else { 0113 result = m_ddcBrightnessControl->brightness(m_ddcBrightnessControl->displayIds().constFirst()); 0114 } 0115 } else { 0116 result = m_cachedBrightness; 0117 } 0118 qCDebug(POWERDEVIL) << "Screen brightness value:" << result; 0119 return result; 0120 } 0121 0122 int ScreenBrightnessController::screenBrightnessMax() const 0123 { 0124 int result = 0; 0125 0126 if (m_ddcBrightnessControl->isSupported()) { 0127 result = m_ddcBrightnessControl->maxBrightness(m_ddcBrightnessControl->displayIds().constFirst()); 0128 } else if (m_backlightBrightnessControl->isSupported()) { 0129 result = m_backlightBrightnessControl->maxBrightness(); 0130 } 0131 qCDebug(POWERDEVIL) << "Screen brightness value max:" << result; 0132 0133 return result; 0134 } 0135 0136 void ScreenBrightnessController::setScreenBrightness(int value) 0137 { 0138 qCDebug(POWERDEVIL) << "set screen brightness value:" << value; 0139 if (m_ddcBrightnessControl->isSupported()) { 0140 if (m_brightnessAnimation) { 0141 m_brightnessAnimation->stop(); 0142 disconnect(m_brightnessAnimation, &QPropertyAnimation::valueChanged, this, &ScreenBrightnessController::animationValueChanged); 0143 m_brightnessAnimation->setStartValue(screenBrightness()); 0144 m_brightnessAnimation->setEndValue(value); 0145 m_brightnessAnimation->setEasingCurve(screenBrightness() < value ? QEasingCurve::OutQuad : QEasingCurve::InQuad); 0146 connect(m_brightnessAnimation, &QPropertyAnimation::valueChanged, this, &ScreenBrightnessController::animationValueChanged); 0147 m_brightnessAnimation->start(); 0148 } else { 0149 for (const QString &displayId : m_ddcBrightnessControl->displayIds()) { 0150 m_ddcBrightnessControl->setBrightness(displayId, value); 0151 } 0152 } 0153 } else if (m_backlightBrightnessControl->isSupported()) { 0154 m_backlightBrightnessControl->setBrightness(value, m_brightnessAnimationDurationMsec); 0155 } 0156 } 0157 0158 bool ScreenBrightnessController::screenBrightnessAvailable() const 0159 { 0160 return m_screenBrightnessAvailable; 0161 } 0162 0163 void ScreenBrightnessController::ddcScreenBrightnessChanged() 0164 { 0165 if (m_brightnessAnimation && m_brightnessAnimation->state() != QPropertyAnimation::Stopped) { 0166 return; 0167 } 0168 0169 if (int currentBrightness = screenBrightness(); currentBrightness != m_cachedBrightness) { 0170 onScreenBrightnessChanged(currentBrightness, screenBrightnessMax()); 0171 } 0172 } 0173 0174 void ScreenBrightnessController::animationValueChanged(const QVariant &value) 0175 { 0176 if (m_ddcBrightnessControl->isSupported()) { 0177 for (const QString &displayId : m_ddcBrightnessControl->displayIds()) { 0178 m_ddcBrightnessControl->setBrightness(displayId, value.toInt()); 0179 } 0180 } else { 0181 qCInfo(POWERDEVIL) << "ScreenBrightnessController::animationValueChanged: brightness control not supported"; 0182 } 0183 } 0184 0185 void ScreenBrightnessController::onScreenBrightnessChanged(int value, int valueMax) 0186 { 0187 m_cachedBrightness = value; 0188 0189 m_screenBrightnessLogic.setValueMax(valueMax); 0190 m_screenBrightnessLogic.setValue(value); 0191 0192 Q_EMIT screenBrightnessChanged(m_screenBrightnessLogic.info()); 0193 } 0194 0195 #include "moc_screenbrightnesscontroller.cpp"