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,9 +145,7 @@ 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";
qCDebug(POWERDEVIL)<<"Trying ddc, helper for brightness controls";
m_ddcBrightnessControl = new DDCutilBrightness();
m_ddcBrightnessControl->detect();
if (!m_ddcBrightnessControl->isSupported()) {
......@@ -215,27 +206,8 @@ void PowerDevilUPowerBackend::init()
}
);
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);
}
Q_EMIT brightnessSupportQueried(true);
}
} 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"
#include <xcb/randr.h>
#include <QCoreApplication>
#include <QLatin1String>
bool XRandRXCBHelper::s_init = false;
XRandRInfo XRandRXCBHelper::s_xrandrInfo;
XRandRXCBHelper::XRandRXCBHelper() : QObject()
, m_window(0)
{
if (!s_init) {
init();
}
}
XRandRXCBHelper::~XRandRXCBHelper()
{
xcb_destroy_window(conn(), m_window);
}
bool XRandRXCBHelper::nativeEventFilter(const QByteArray& eventType, void* message, long int* result)
{
Q_UNUSED(result);
if (eventType != "xcb_generic_event_t") {
return false;
}
xcb_generic_event_t* e = static_cast<xcb_generic_event_t *>(message);
const uint8_t xEventType = e->response_type & ~0x80;
//If this event is not xcb_randr_notify, we don't want it
if (xEventType != s_xrandrInfo.eventType) {
return false;
}
xcb_randr_notify_event_t*
randrEvent = reinterpret_cast<xcb_randr_notify_event_t*>(e);
//If the event is not about a change in an output property, we don't want it
if (randrEvent->subCode != XCB_RANDR_NOTIFY_OUTPUT_PROPERTY) {
return false;
}
//If the event is not about a new value, we don't want it
if (randrEvent->u.op.status != XCB_PROPERTY_NEW_VALUE) {
return false;
}
//If the modified property is not backlight, we don't care
if (randrEvent->u.op.atom != s_xrandrInfo.backlightAtom) {
return false;
}
Q_EMIT brightnessChanged();
return false;
}
void XRandRXCBHelper::init()
{
xcb_connection_t* c = conn();
xcb_prefetch_extension_data(c, &xcb_randr_id);
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(c, &xcb_randr_id);
if (!reply) {
s_xrandrInfo.isPresent = false;
return;
}
s_xrandrInfo.isPresent = reply->present;
s_xrandrInfo.eventBase = reply->first_event;
s_xrandrInfo.errorBase = reply->first_error;
s_xrandrInfo.eventType = s_xrandrInfo.eventBase + XCB_RANDR_NOTIFY;
s_xrandrInfo.majorOpcode = reply->major_opcode;
QByteArray backlight = QByteArrayLiteral("Backlight");
/*This is KDE5... the world of opengl and wayland (almost), I don't think we really need to
check the old BACKLIGHT atom*/
// QByteArray backlightCaps("BACKLIGHT");
// xcb_intern_atom(c, true, backlightCaps.length(), backlightCaps.constData());
xcb_intern_atom_reply_t* atomReply =
xcb_intern_atom_reply(c, xcb_intern_atom(c, true, backlight.length(), backlight.constData()), nullptr);
//If backlight atom doesn't exist, means that no driver is actually supporting it
if (!atomReply) {
return;
}
s_xrandrInfo.backlightAtom = atomReply->atom;
uint32_t rWindow = rootWindow(c, 0);
m_window = xcb_generate_id(c);
xcb_create_window(c, XCB_COPY_FROM_PARENT, m_window,
rWindow,
0, 0, 1, 1, 0, XCB_COPY_FROM_PARENT,
XCB_COPY_FROM_PARENT, 0, nullptr);
xcb_randr_select_input(c, m_window, XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY);
qApp->installNativeEventFilter(this);
s_init = true;
}
/*************************************************************************************
* 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. *
* *