Commit 476d6afc authored by Kai Uwe Broulik's avatar Kai Uwe Broulik 🍇
Browse files

Remove XRandRBrightness

We have animated brightness changes on sysfs these days. Most drivers don't support
XRandR brightness these days and it naturally doesn't work on Wayland.
parent 0b4e4016
########################## UPower Backend #####################################
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/upower
${X11_INCLUDE_DIR}
${X11_Xrandr_INCLUDE_PATH})
set(powerdevilupowerbackend_SRCS
${CMAKE_CURRENT_BINARY_DIR}/../powerdevil_debug.cpp
upower/upowersuspendjob.cpp
upower/login1suspendjob.cpp
upower/powerdevilupowerbackend.cpp
upower/xrandrbrightness.cpp
upower/xrandrxcbhelper.cpp
upower/udevqtclient.cpp
upower/udevqtdevice.cpp
upower/ddcutilbrightness.cpp
......@@ -56,10 +50,6 @@ target_link_libraries(powerdevilupowerbackend
KF5::DBusAddons
KF5::I18n
${UDEV_LIBS}
${X11_LIBRARIES}
${X11_Xrandr_LIB}
${XCB_XCB_LIBRARY}
${XCB_RANDR_LIBRARY}
powerdevilcore
)
if(DDCUTIL_FOUND)
......
......@@ -37,8 +37,6 @@
#include <KPluginFactory>
#include <KSharedConfig>
#include "xrandrxcbhelper.h"
#include "xrandrbrightness.h"
#include "ddcutilbrightness.h"
#include "upowersuspendjob.h"
#include "login1suspendjob.h"
......@@ -49,8 +47,6 @@
PowerDevilUPowerBackend::PowerDevilUPowerBackend(QObject* parent)
: BackendInterface(parent)
, m_displayDevice(nullptr)
, m_brightnessControl(nullptr)
, m_randrHelper(nullptr)
, m_upowerInterface(nullptr)
, m_kbdBacklight(nullptr)
, m_kbdMaxBrightness(0)
......@@ -62,10 +58,7 @@ PowerDevilUPowerBackend::PowerDevilUPowerBackend(QObject* parent)
}
PowerDevilUPowerBackend::~PowerDevilUPowerBackend()
{
delete m_brightnessControl;
}
PowerDevilUPowerBackend::~PowerDevilUPowerBackend() = default;
bool PowerDevilUPowerBackend::isAvailable()
{
......@@ -152,90 +145,69 @@ void PowerDevilUPowerBackend::init()
connect(this, &PowerDevilUPowerBackend::brightnessSupportQueried, this, &PowerDevilUPowerBackend::initWithBrightness);
m_upowerInterface = new OrgFreedesktopUPowerInterface(UPOWER_SERVICE, "/org/freedesktop/UPower", QDBusConnection::systemBus(), this);
m_brightnessControl = new XRandrBrightness();
if (!m_brightnessControl->isSupported()) {
qCWarning(POWERDEVIL)<<"Xrandr not supported, trying ddc, helper";
m_ddcBrightnessControl = new DDCutilBrightness();
m_ddcBrightnessControl->detect();
if (!m_ddcBrightnessControl->isSupported()) {
qCDebug(POWERDEVIL) << "Falling back to helper to get brightness";
KAuth::Action brightnessAction("org.kde.powerdevil.backlighthelper.brightness");
brightnessAction.setHelperId(HELPER_ID);
KAuth::ExecuteJob *brightnessJob = brightnessAction.execute();
connect(brightnessJob, &KJob::result, this,
[this, brightnessJob] {
if (brightnessJob->error()) {
qCWarning(POWERDEVIL) << "org.kde.powerdevil.backlighthelper.brightness failed";
qCDebug(POWERDEVIL) << brightnessJob->errorText();
Q_EMIT brightnessSupportQueried(false);
return;
}
m_cachedBrightnessMap.insert(Screen, brightnessJob->data()["brightness"].toFloat());
KAuth::Action brightnessMaxAction("org.kde.powerdevil.backlighthelper.brightnessmax");
brightnessMaxAction.setHelperId(HELPER_ID);
KAuth::ExecuteJob *brightnessMaxJob = brightnessMaxAction.execute();
connect(brightnessMaxJob, &KJob::result, this,
[this, brightnessMaxJob] {
if (brightnessMaxJob->error()) {
qCWarning(POWERDEVIL) << "org.kde.powerdevil.backlighthelper.brightnessmax failed";
qCDebug(POWERDEVIL) << brightnessMaxJob->errorText();
} else {
m_brightnessMax = brightnessMaxJob->data()["brightnessmax"].toInt();
}
qCDebug(POWERDEVIL)<<"Trying ddc, helper for brightness controls";
m_ddcBrightnessControl = new DDCutilBrightness();
m_ddcBrightnessControl->detect();
if (!m_ddcBrightnessControl->isSupported()) {
qCDebug(POWERDEVIL) << "Falling back to helper to get brightness";
KAuth::Action brightnessAction("org.kde.powerdevil.backlighthelper.brightness");
brightnessAction.setHelperId(HELPER_ID);
KAuth::ExecuteJob *brightnessJob = brightnessAction.execute();
connect(brightnessJob, &KJob::result, this,
[this, brightnessJob] {
if (brightnessJob->error()) {
qCWarning(POWERDEVIL) << "org.kde.powerdevil.backlighthelper.brightness failed";
qCDebug(POWERDEVIL) << brightnessJob->errorText();
Q_EMIT brightnessSupportQueried(false);
return;
}
m_cachedBrightnessMap.insert(Screen, brightnessJob->data()["brightness"].toFloat());
KAuth::Action brightnessMaxAction("org.kde.powerdevil.backlighthelper.brightnessmax");
brightnessMaxAction.setHelperId(HELPER_ID);
KAuth::ExecuteJob *brightnessMaxJob = brightnessMaxAction.execute();
connect(brightnessMaxJob, &KJob::result, this,
[this, brightnessMaxJob] {
if (brightnessMaxJob->error()) {
qCWarning(POWERDEVIL) << "org.kde.powerdevil.backlighthelper.brightnessmax failed";
qCDebug(POWERDEVIL) << brightnessMaxJob->errorText();
} else {
m_brightnessMax = brightnessMaxJob->data()["brightnessmax"].toInt();
}
KAuth::Action syspathAction("org.kde.powerdevil.backlighthelper.syspath");
syspathAction.setHelperId(HELPER_ID);
KAuth::ExecuteJob* syspathJob = syspathAction.execute();
connect(syspathJob, &KJob::result, this,
[this, syspathJob] {
if (syspathJob->error()) {
qCWarning(POWERDEVIL) << "org.kde.powerdevil.backlighthelper.syspath failed";
qCDebug(POWERDEVIL) << syspathJob->errorText();
Q_EMIT brightnessSupportQueried(false);
return;
}
m_syspath = syspathJob->data()["syspath"].toString();
m_syspath = QFileInfo(m_syspath).symLinkTarget();
m_isLedBrightnessControl = m_syspath.contains(QLatin1String("/leds/"));
if (!m_isLedBrightnessControl) {
UdevQt::Client *client = new UdevQt::Client(QStringList("backlight"), this);
connect(client, SIGNAL(deviceChanged(UdevQt::Device)), SLOT(onDeviceChanged(UdevQt::Device)));
}
Q_EMIT brightnessSupportQueried(m_brightnessMax > 0);
KAuth::Action syspathAction("org.kde.powerdevil.backlighthelper.syspath");
syspathAction.setHelperId(HELPER_ID);
KAuth::ExecuteJob* syspathJob = syspathAction.execute();
connect(syspathJob, &KJob::result, this,
[this, syspathJob] {
if (syspathJob->error()) {
qCWarning(POWERDEVIL) << "org.kde.powerdevil.backlighthelper.syspath failed";
qCDebug(POWERDEVIL) << syspathJob->errorText();
Q_EMIT brightnessSupportQueried(false);
return;
}
);
syspathJob->start();
}
);
brightnessMaxJob->start();
}
);
brightnessJob->start();
}
else{
qCDebug(POWERDEVIL) << "Using DDCutillib";
m_cachedBrightnessMap.insert(Screen, brightness(Screen));
const int duration = PowerDevilSettings::brightnessAnimationDuration();
if (duration > 0 && brightnessMax() >= PowerDevilSettings::brightnessAnimationThreshold()) {
m_brightnessAnimation = new QPropertyAnimation(this);
m_brightnessAnimation->setTargetObject(this);
m_brightnessAnimation->setDuration(duration);
m_brightnessAnimation->setEasingCurve(QEasingCurve::OutQuad);
connect(m_brightnessAnimation, &QPropertyAnimation::valueChanged, this, &PowerDevilUPowerBackend::animationValueChanged);
connect(m_brightnessAnimation, &QPropertyAnimation::finished, this, &PowerDevilUPowerBackend::slotScreenBrightnessChanged);
m_syspath = syspathJob->data()["syspath"].toString();
m_syspath = QFileInfo(m_syspath).symLinkTarget();
m_isLedBrightnessControl = m_syspath.contains(QLatin1String("/leds/"));
if (!m_isLedBrightnessControl) {
UdevQt::Client *client = new UdevQt::Client(QStringList("backlight"), this);
connect(client, SIGNAL(deviceChanged(UdevQt::Device)), SLOT(onDeviceChanged(UdevQt::Device)));
}
Q_EMIT brightnessSupportQueried(m_brightnessMax > 0);
}
);
syspathJob->start();
}
);
brightnessMaxJob->start();
}
Q_EMIT brightnessSupportQueried(true);
}
);
brightnessJob->start();
} else {
qCDebug(POWERDEVIL) << "Using XRandR";
m_randrHelper = XRandRXCBHelper::self();
Q_ASSERT(m_randrHelper);
connect(m_randrHelper, &XRandRXCBHelper::brightnessChanged, this, &PowerDevilUPowerBackend::slotScreenBrightnessChanged);
qCDebug(POWERDEVIL) << "Using DDCutillib";
m_cachedBrightnessMap.insert(Screen, brightness(Screen));
const int duration = PowerDevilSettings::brightnessAnimationDuration();
......@@ -423,20 +395,13 @@ int PowerDevilUPowerBackend::brightness(PowerDevil::BackendInterface::Brightness
int result = 0;
if (type == Screen) {
if (m_brightnessControl->isSupported()) {
if (m_brightnessAnimation && m_brightnessAnimation->state() == QPropertyAnimation::Running) {
result = m_brightnessAnimation->endValue().toInt();
} else {
//qCDebug(POWERDEVIL) << "Calling xrandr brightness";
result = (int) m_brightnessControl->brightness();
}
} else if (m_ddcBrightnessControl->isSupported()){
if (m_ddcBrightnessControl->isSupported()) {
if (m_brightnessAnimation && m_brightnessAnimation->state() == QPropertyAnimation::Running) {
result = m_brightnessAnimation->endValue().toInt();
} else {
result = (int)m_ddcBrightnessControl->brightness();
}
}else{
} else {
result = m_cachedBrightnessMap[Screen];
}
qCDebug(POWERDEVIL) << "Screen brightness value: " << result;
......@@ -453,12 +418,9 @@ int PowerDevilUPowerBackend::brightnessMax(PowerDevil::BackendInterface::Brightn
int result = 0;
if (type == Screen) {
if (m_brightnessControl->isSupported()) {
//qCDebug(POWERDEVIL) << "Calling xrandr brightness";
result = (int) m_brightnessControl->brightnessMax();
} else if (m_ddcBrightnessControl->isSupported()){
if (m_ddcBrightnessControl->isSupported()) {
result = (int)m_ddcBrightnessControl->brightnessMax();
}else{
} else {
result = m_brightnessMax;
}
qCDebug(POWERDEVIL) << "Screen brightness value max: " << result;
......@@ -474,18 +436,7 @@ void PowerDevilUPowerBackend::setBrightness(int value, PowerDevil::BackendInterf
{
if (type == Screen) {
qCDebug(POWERDEVIL) << "set screen brightness value: " << value;
if (m_brightnessControl->isSupported()) {
if (m_brightnessAnimation) {
m_brightnessAnimation->stop();
disconnect(m_brightnessAnimation, &QPropertyAnimation::valueChanged, this, &PowerDevilUPowerBackend::animationValueChanged);
m_brightnessAnimation->setStartValue(brightness());
m_brightnessAnimation->setEndValue(value);
connect(m_brightnessAnimation, &QPropertyAnimation::valueChanged, this, &PowerDevilUPowerBackend::animationValueChanged);
m_brightnessAnimation->start();
} else {
m_brightnessControl->setBrightness(value);
}
} else if (m_ddcBrightnessControl->isSupported()){
if (m_ddcBrightnessControl->isSupported()) {
if (m_brightnessAnimation) {
m_brightnessAnimation->stop();
disconnect(m_brightnessAnimation, &QPropertyAnimation::valueChanged, this, &PowerDevilUPowerBackend::animationValueChanged);
......@@ -497,8 +448,6 @@ void PowerDevilUPowerBackend::setBrightness(int value, PowerDevil::BackendInterf
m_ddcBrightnessControl->setBrightness((long)value);
}
} else {
//qCDebug(POWERDEVIL) << "Falling back to helper to set brightness";
KAuth::Action action("org.kde.powerdevil.backlighthelper.setbrightness");
action.setHelperId(HELPER_ID);
action.addArgument("brightness", value);
......@@ -744,12 +693,9 @@ void PowerDevilUPowerBackend::slotLogin1PrepareForSleep(bool active)
void PowerDevilUPowerBackend::animationValueChanged(const QVariant &value)
{
if (m_brightnessControl->isSupported()) {
m_brightnessControl->setBrightness(value.toInt());
}else if (m_ddcBrightnessControl->isSupported()) {
if (m_ddcBrightnessControl->isSupported()) {
m_ddcBrightnessControl->setBrightness(value.toInt());
}
else{
} else {
qCInfo(POWERDEVIL)<<"PowerDevilUPowerBackend::animationValueChanged: brightness control not supported";
}
}
......@@ -41,8 +41,6 @@
#define LOGIN1_SERVICE "org.freedesktop.login1"
#define CONSOLEKIT2_SERVICE "org.freedesktop.ConsoleKit"
class XRandRXCBHelper;
class XRandrBrightness;
class QPropertyAnimation;
class QTimer;
class DDCutilBrightness;
......@@ -99,8 +97,6 @@ private:
// brightness
QMap<BrightnessControlType, int> m_cachedBrightnessMap;
XRandrBrightness *m_brightnessControl;
XRandRXCBHelper *m_randrHelper;
DDCutilBrightness *m_ddcBrightnessControl;
OrgFreedesktopUPowerInterface *m_upowerInterface;
......
/* This file is part of the KDE project
* Copyright (C) 2010 Lukas Tinkl <ltinkl@redhat.com>
* Copyright (C) 2015 Kai Uwe Broulik <kde@privat.broulik.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#include <powerdevil_debug.h>
#include <QX11Info>
#include "xrandrbrightness.h"
XRandrBrightness::XRandrBrightness()
{
if (!QX11Info::isPlatformX11()) {
return;
}
auto *c = QX11Info::connection();
xcb_prefetch_extension_data(c, &xcb_randr_id);
// this reply, for once, does not need to be managed by us
auto *extension = xcb_get_extension_data(c, &xcb_randr_id);
if (!extension || !extension->present) {
qCWarning(POWERDEVIL) << "XRandR extension not available";
return;
}
ScopedCPointer<xcb_randr_query_version_reply_t> versionReply(xcb_randr_query_version_reply(c,
xcb_randr_query_version(c, 1, 2),
nullptr));
if (!versionReply) {
qCWarning(POWERDEVIL) << "RandR Query version returned null";
return;
}
if (versionReply->major_version < 1 || (versionReply->major_version == 1 && versionReply->minor_version < 2)) {
qCWarning(POWERDEVIL, "RandR version %d.%d too old", versionReply->major_version, versionReply->minor_version);
return;
}
ScopedCPointer<xcb_intern_atom_reply_t> backlightReply(xcb_intern_atom_reply(c,
xcb_intern_atom(c, 1, strlen("Backlight"), "Backlight"),
nullptr));
if (!backlightReply) {
qCWarning(POWERDEVIL, "Intern Atom for Backlight returned null");
return;
}
m_backlight = backlightReply->atom;
if (m_backlight == XCB_NONE) {
qCWarning(POWERDEVIL, "No outputs have backlight property");
return;
}
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(c));
if (!iter.rem) {
qCWarning(POWERDEVIL, "XCB Screen Roots Iterator rem was null");
return;
}
xcb_screen_t *screen = iter.data;
xcb_window_t root = screen->root;
m_resources.reset(xcb_randr_get_screen_resources_current_reply(c,
xcb_randr_get_screen_resources_current(c, root)
, nullptr));
if (!m_resources) {
qCWarning(POWERDEVIL, "RANDR Get Screen Resources returned null");
return;
}
}
bool XRandrBrightness::isSupported() const
{
if (!m_resources) {
return false;
}
auto *outputs = xcb_randr_get_screen_resources_current_outputs(m_resources.data());
for (int i = 0; i < m_resources->num_outputs; ++i) {
if (backlight_get(outputs[i]) != -1) {
return true;
}
}
return false;
}
long XRandrBrightness::brightness() const
{
if (!m_resources) {
return 0;
}
auto *outputs = xcb_randr_get_screen_resources_current_outputs(m_resources.data());
for (int i = 0; i < m_resources->num_outputs; ++i) {
auto output = outputs[i];
long cur, min, max;
if (backlight_get_with_range(output, cur, min, max)) {
// FIXME for now just return the first output's value
return cur - min;
}
}
return 0;
}
long XRandrBrightness::brightnessMax() const
{
if (!m_resources) {
return 0;
}
auto *outputs = xcb_randr_get_screen_resources_current_outputs(m_resources.data());
for (int i = 0; i < m_resources->num_outputs; ++i) {
auto output = outputs[i];
long cur, min, max;
if (backlight_get_with_range(output, cur, min, max)) {
// FIXME for now just return the first output's value
return max - min;
}
}
return 0;
}
void XRandrBrightness::setBrightness(long value)
{
if (!m_resources) {
return;
}
auto *outputs = xcb_randr_get_screen_resources_current_outputs(m_resources.data());
for (int i = 0; i < m_resources->num_outputs; ++i) {
auto output = outputs[i];
long cur, min, max;
if (backlight_get_with_range(output, cur, min, max)) {
// FIXME for now just set the first output's value
backlight_set(output, min + value);
}
}
free(xcb_get_input_focus_reply(QX11Info::connection(), xcb_get_input_focus(QX11Info::connection()), nullptr)); // sync
}
bool XRandrBrightness::backlight_get_with_range(xcb_randr_output_t output, long &value, long &min, long &max) const {
long cur = backlight_get(output);
if (cur == -1) {
return false;
}
ScopedCPointer<xcb_randr_query_output_property_reply_t> propertyReply(xcb_randr_query_output_property_reply(QX11Info::connection(),
xcb_randr_query_output_property(QX11Info::connection(), output, m_backlight)
, nullptr));
if (!propertyReply) {
return -1;
}
if (propertyReply->range && xcb_randr_query_output_property_valid_values_length(propertyReply.data()) == 2) {
int32_t *values = xcb_randr_query_output_property_valid_values(propertyReply.data());
value = cur;
min = values[0];
max = values[1];
return true;
}
return false;
}
long XRandrBrightness::backlight_get(xcb_randr_output_t output) const
{
ScopedCPointer<xcb_randr_get_output_property_reply_t> propertyReply;
long value;
if (m_backlight != XCB_ATOM_NONE) {
propertyReply.reset(xcb_randr_get_output_property_reply(QX11Info::connection(),
xcb_randr_get_output_property(QX11Info::connection(), output, m_backlight, XCB_ATOM_NONE, 0, 4, 0, 0)
, nullptr));
if (!propertyReply) {
return -1;
}
}
if (!propertyReply || propertyReply->type != XCB_ATOM_INTEGER || propertyReply->num_items != 1 || propertyReply->format != 32) {
value = -1;
} else {
value = *(reinterpret_cast<long *>(xcb_randr_get_output_property_data(propertyReply.data())));
}
return value;
}
void XRandrBrightness::backlight_set(xcb_randr_output_t output, long value)
{
xcb_randr_change_output_property(QX11Info::connection(), output, m_backlight, XCB_ATOM_INTEGER,
32, XCB_PROP_MODE_REPLACE,
1, reinterpret_cast<unsigned char *>(&value));
}
/* This file is part of the KDE project
* Copyright (C) 2010 Lukas Tinkl <ltinkl@redhat.com>
* Copyright (C) 2015 Kai Uwe Broulik <kde@privat.broulik.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#ifndef XRANDRBRIGHTNESS_H
#define XRANDRBRIGHTNESS_H
#include <xcb/xcb.h>
#include <xcb/randr.h>
#include <QScopedPointer>
template <typename T> using ScopedCPointer = QScopedPointer<T, QScopedPointerPodDeleter>;
class XRandrBrightness
{
public:
XRandrBrightness();
~XRandrBrightness() = default;
bool isSupported() const;
long brightness() const;
long brightnessMax() const;
void setBrightness(long value);
private:
bool backlight_get_with_range(xcb_randr_output_t output, long &value, long &min, long &max) const;
long backlight_get(xcb_randr_output_t output) const;
void backlight_set(xcb_randr_output_t output, long value);
xcb_atom_t m_backlight = XCB_ATOM_NONE;
ScopedCPointer<xcb_randr_get_screen_resources_current_reply_t> m_resources;
};
#endif // XRANDRBRIGHTNESS_H
/*************************************************************************************
* Copyright (C) 2013 by Alejandro Fiestas Olivares <afiestas@kde.org> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
*************************************************************************************/
#include "xrandrxcbhelper.h"