kiran-cc-daemon/0001-feature-backlight-Support-brightness-modification-by.patch
tangjie02 903681761b Support brightness modification by changing gamma value
Signed-off-by: tangjie02 <tangjie02@kylinsec.com.cn>
2022-12-07 20:22:14 +08:00

1620 lines
59 KiB
Diff

From cc319ca0ff48a1dae64815863092f183e3058a9f Mon Sep 17 00:00:00 2001
From: tangjie02 <tangjie02@kylinsec.com.cn>
Date: Wed, 7 Dec 2022 17:34:34 +0800
Subject: [PATCH] feature(backlight): Support brightness modification by
changing gamma value.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 支持通过改变gamma值来调节亮度。
Signed-off-by: tangjie02 <tangjie02@kylinsec.com.cn>
---
.../com.kylinsec.kiran.power.gschema.xml.in | 13 +-
include/power-i.h | 10 +
lib/base/base.h | 1 +
lib/base/misc-utils.cpp | 51 ++++
lib/base/misc-utils.h | 40 +++
plugins/power/CMakeLists.txt | 2 +-
...ght-base.h => power-backlight-interface.h} | 15 ++
plugins/power/backlight/power-backlight-kbd.h | 2 +-
.../backlight/power-backlight-monitor-tool.h | 2 +-
...p => power-backlight-monitor-x11-atom.cpp} | 24 +-
...1.h => power-backlight-monitor-x11-atom.h} | 10 +-
.../power-backlight-monitor-x11-gamma.cpp | 237 ++++++++++++++++++
.../power-backlight-monitor-x11-gamma.h | 60 +++++
...> power-backlight-monitors-controller.cpp} | 118 ++++-----
... => power-backlight-monitors-controller.h} | 25 +-
.../power-backlight-monitors-tool.cpp | 93 +++++++
.../backlight/power-backlight-monitors-tool.h | 48 ++++
...1.cpp => power-backlight-monitors-x11.cpp} | 64 +++--
...t-x11.h => power-backlight-monitors-x11.h} | 41 ++-
plugins/power/backlight/power-backlight.cpp | 4 +-
plugins/power/backlight/power-backlight.h | 3 +-
plugins/power/tools/main.cpp | 129 ++++++----
plugins/power/tools/power-backlight-helper.h | 1 +
23 files changed, 797 insertions(+), 196 deletions(-)
create mode 100644 lib/base/misc-utils.cpp
create mode 100644 lib/base/misc-utils.h
rename plugins/power/backlight/{power-backlight-base.h => power-backlight-interface.h} (82%)
rename plugins/power/backlight/{power-backlight-monitor-x11.cpp => power-backlight-monitor-x11-atom.cpp} (84%)
rename plugins/power/backlight/{power-backlight-monitor-x11.h => power-backlight-monitor-x11-atom.h} (78%)
create mode 100644 plugins/power/backlight/power-backlight-monitor-x11-gamma.cpp
create mode 100644 plugins/power/backlight/power-backlight-monitor-x11-gamma.h
rename plugins/power/backlight/{power-backlight-moitor.cpp => power-backlight-monitors-controller.cpp} (65%)
rename plugins/power/backlight/{power-backlight-monitor.h => power-backlight-monitors-controller.h} (80%)
create mode 100644 plugins/power/backlight/power-backlight-monitors-tool.cpp
create mode 100644 plugins/power/backlight/power-backlight-monitors-tool.h
rename plugins/power/backlight/{power-backlight-x11.cpp => power-backlight-monitors-x11.cpp} (62%)
rename plugins/power/backlight/{power-backlight-x11.h => power-backlight-monitors-x11.h} (63%)
diff --git a/data/schemas/com.kylinsec.kiran.power.gschema.xml.in b/data/schemas/com.kylinsec.kiran.power.gschema.xml.in
index 6798e3b..414939e 100644
--- a/data/schemas/com.kylinsec.kiran.power.gschema.xml.in
+++ b/data/schemas/com.kylinsec.kiran.power.gschema.xml.in
@@ -28,6 +28,12 @@
<value nick="never" value="2"/>
</enum>
+ <enum id="com.kylinsec.kiran.power.backlight-policy">
+ <value nick="auto" value="0"/>
+ <value nick="tool" value="1"/>
+ <value nick="x11" value="2"/>
+ </enum>
+
<schema id="com.kylinsec.kiran.power" path="/com/kylinsec/kiran/power/">
<key name="computer-battery-idle-time" type="i">
@@ -71,7 +77,7 @@
</key>
<key name="display-idle-dim-scale" type="i">
- <default>30</default>
+ <default>0</default>
<range min="0" max="100"/>
<description>The scale of the brightness reduction when the display changes dim. Do nothing when the value is 0.</description>
</key>
@@ -111,6 +117,9 @@
<description>Display options for the notification icon.</description>
</key>
-
+ <key name="monitor-backlight-policy" enum="com.kylinsec.kiran.power.backlight-policy">
+ <default>'auto'</default>
+ <description>Set the policy for obtaining brightness values.</description>
+ </key>
</schema>
</schemalist>
diff --git a/include/power-i.h b/include/power-i.h
index d24e3ac..12e27c8 100644
--- a/include/power-i.h
+++ b/include/power-i.h
@@ -108,6 +108,14 @@ extern "C"
POWER_TRAY_ICON_POLICY_NERVER,
};
+ enum PowerMonitorBacklightPolicy
+ {
+ // 自动
+ POWER_MONITOR_BACKLIGHT_POLICY_AUTO = 0,
+ POWER_MONITOR_BACKLIGHT_POLICY_TOOL = 1,
+ POWER_MONITOR_BACKLIGHT_POLICY_X11 = 2,
+ };
+
#define POWER_DBUS_NAME "com.kylinsec.Kiran.SessionDaemon.Power"
#define POWER_OBJECT_PATH "/com/kylinsec/Kiran/SessionDaemon/Power"
@@ -141,6 +149,8 @@ extern "C"
#define POWER_SCHEMA_BATTERY_CRITICAL_ACTION "battery-critical-action"
// 在什么情况下需要显示托盘图标
#define POWER_SCHEMA_TRAY_ICON_POLICY "tray-icon-policy"
+// 设置获取显示器亮度值的策略,'tool'是直接操作背光设备文件,'x11'是通过xrandr接口调节亮度
+#define POWER_SCHEMA_MONITOR_BACKLIGHT_POLICY "monitor-backlight-policy"
#ifdef __cplusplus
}
diff --git a/lib/base/base.h b/lib/base/base.h
index 05ed8a3..ed06a46 100644
--- a/lib/base/base.h
+++ b/lib/base/base.h
@@ -26,5 +26,6 @@
#include "lib/base/def.h"
#include "lib/base/error.h"
#include "lib/base/file-utils.h"
+#include "lib/base/misc-utils.h"
#include "lib/base/stl-helper.h"
#include "lib/base/str-utils.h"
\ No newline at end of file
diff --git a/lib/base/misc-utils.cpp b/lib/base/misc-utils.cpp
new file mode 100644
index 0000000..f52ad92
--- /dev/null
+++ b/lib/base/misc-utils.cpp
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
+ * kiran-cc-daemon is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ *
+ * Author: tangjie02 <tangjie02@kylinos.com.cn>
+ */
+
+#include "lib/base/misc-utils.h"
+#include "lib/base/base.h"
+
+namespace Kiran
+{
+MiscUtils::MiscUtils()
+{
+}
+
+Glib::OptionEntry MiscUtils::create_option_entry(const char &short_name,
+ const Glib::ustring &long_name,
+ const Glib::ustring &description,
+ const Glib::ustring &arg_description,
+ int32_t flags)
+{
+ Glib::OptionEntry result;
+ result.set_short_name(short_name);
+ result.set_long_name(long_name);
+ result.set_description(description);
+ result.set_arg_description(arg_description);
+ result.set_flags(flags);
+ return result;
+}
+
+Glib::OptionEntry MiscUtils::create_option_entry(const Glib::ustring &long_name,
+ const Glib::ustring &description,
+ const Glib::ustring &arg_description,
+ int32_t flags)
+{
+ Glib::OptionEntry result;
+ result.set_long_name(long_name);
+ result.set_description(description);
+ result.set_arg_description(arg_description);
+ result.set_flags(flags);
+ return result;
+}
+} // namespace Kiran
diff --git a/lib/base/misc-utils.h b/lib/base/misc-utils.h
new file mode 100644
index 0000000..73eaf62
--- /dev/null
+++ b/lib/base/misc-utils.h
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
+ * kiran-cc-daemon is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ *
+ * Author: tangjie02 <tangjie02@kylinos.com.cn>
+ */
+
+#pragma once
+
+#include <giomm.h>
+
+namespace Kiran
+{
+class MiscUtils
+{
+public:
+ MiscUtils();
+ virtual ~MiscUtils(){};
+
+ static Glib::OptionEntry create_option_entry(const char &short_name,
+ const Glib::ustring &long_name,
+ const Glib::ustring &description,
+ const Glib::ustring &arg_description = Glib::ustring(),
+ int32_t flags = 0);
+
+ static Glib::OptionEntry create_option_entry(const Glib::ustring &long_name,
+ const Glib::ustring &description,
+ const Glib::ustring &arg_description = Glib::ustring(),
+ int32_t flags = 0);
+
+}; // namespace KS
+
+} // namespace Kiran
diff --git a/plugins/power/CMakeLists.txt b/plugins/power/CMakeLists.txt
index f81cc09..67db9e0 100644
--- a/plugins/power/CMakeLists.txt
+++ b/plugins/power/CMakeLists.txt
@@ -7,7 +7,7 @@ file(GLOB_RECURSE POWER_CPP_FILES ./*.cpp)
# Filter tools directory list(FILTER POWER_H_FILES EXCLUDE REGEX .*tools/.*)
# list(FILTER POWER_CPP_FILES EXCLUDE REGEX .*tools/.*)
-list(FILTER POWER_CPP_FILES EXCLUDE REGEX "(.*tools/main.cpp|.*/tray/.*)")
+list(FILTER POWER_CPP_FILES EXCLUDE REGEX "(.*tools/.*|.*/tray/.*)")
gen_dbus_stub(
POWER power com.kylinsec.
diff --git a/plugins/power/backlight/power-backlight-base.h b/plugins/power/backlight/power-backlight-interface.h
similarity index 82%
rename from plugins/power/backlight/power-backlight-base.h
rename to plugins/power/backlight/power-backlight-interface.h
index 1a4aa64..fa64c13 100644
--- a/plugins/power/backlight/power-backlight-base.h
+++ b/plugins/power/backlight/power-backlight-interface.h
@@ -59,4 +59,19 @@ public:
};
using PowerBacklightAbsoluteVec = std::vector<std::shared_ptr<PowerBacklightAbsolute>>;
+
+class PowerBacklightMonitors
+{
+public:
+ PowerBacklightMonitors(){};
+ virtual ~PowerBacklightMonitors(){};
+
+ virtual void init() = 0;
+
+ // 获取所有显示器亮度设置对象
+ virtual PowerBacklightAbsoluteVec get_monitors() = 0;
+ virtual sigc::signal<void> signal_monitor_changed() = 0;
+ virtual sigc::signal<void> signal_brightness_changed() = 0;
+};
+
} // namespace Kiran
\ No newline at end of file
diff --git a/plugins/power/backlight/power-backlight-kbd.h b/plugins/power/backlight/power-backlight-kbd.h
index 88d528c..f2dc62f 100644
--- a/plugins/power/backlight/power-backlight-kbd.h
+++ b/plugins/power/backlight/power-backlight-kbd.h
@@ -14,7 +14,7 @@
#pragma once
-#include "plugins/power/backlight/power-backlight-base.h"
+#include "plugins/power/backlight/power-backlight-interface.h"
namespace Kiran
{
diff --git a/plugins/power/backlight/power-backlight-monitor-tool.h b/plugins/power/backlight/power-backlight-monitor-tool.h
index a99b0b5..24e8850 100644
--- a/plugins/power/backlight/power-backlight-monitor-tool.h
+++ b/plugins/power/backlight/power-backlight-monitor-tool.h
@@ -14,7 +14,7 @@
#pragma once
-#include "plugins/power/backlight/power-backlight-base.h"
+#include "plugins/power/backlight/power-backlight-interface.h"
namespace Kiran
{
diff --git a/plugins/power/backlight/power-backlight-monitor-x11.cpp b/plugins/power/backlight/power-backlight-monitor-x11-atom.cpp
similarity index 84%
rename from plugins/power/backlight/power-backlight-monitor-x11.cpp
rename to plugins/power/backlight/power-backlight-monitor-x11-atom.cpp
index 7e90f99..85a6ca4 100644
--- a/plugins/power/backlight/power-backlight-monitor-x11.cpp
+++ b/plugins/power/backlight/power-backlight-monitor-x11-atom.cpp
@@ -12,20 +12,19 @@
* Author: tangjie02 <tangjie02@kylinos.com.cn>
*/
-#include "plugins/power/backlight/power-backlight-monitor-x11.h"
-
+#include "plugins/power/backlight/power-backlight-monitor-x11-atom.h"
#include <X11/Xatom.h>
namespace Kiran
{
-PowerBacklightMonitorX11::PowerBacklightMonitorX11(Atom backlight_atom, RROutput output) : backlight_atom_(backlight_atom),
- output_(output)
+PowerBacklightMonitorX11Atom::PowerBacklightMonitorX11Atom(Atom backlight_atom, RROutput output) : backlight_atom_(backlight_atom),
+ output_(output)
{
this->display_ = gdk_display_get_default();
this->xdisplay_ = GDK_DISPLAY_XDISPLAY(this->display_);
}
-bool PowerBacklightMonitorX11::set_brightness_value(int32_t brightness_value)
+bool PowerBacklightMonitorX11Atom::set_brightness_value(int32_t brightness_value)
{
gdk_x11_display_error_trap_push(this->display_);
@@ -46,7 +45,7 @@ bool PowerBacklightMonitorX11::set_brightness_value(int32_t brightness_value)
return true;
}
-int32_t PowerBacklightMonitorX11::get_brightness_value()
+int32_t PowerBacklightMonitorX11Atom::get_brightness_value()
{
RETURN_VAL_IF_TRUE(this->backlight_atom_ == None, -1);
@@ -91,16 +90,17 @@ int32_t PowerBacklightMonitorX11::get_brightness_value()
return result;
}
-bool PowerBacklightMonitorX11::get_brightness_range(int32_t &min, int32_t &max)
+bool PowerBacklightMonitorX11Atom::get_brightness_range(int32_t &min, int32_t &max)
{
XRRPropertyInfo *info = NULL;
- SCOPE_EXIT({
- if (info != NULL)
+ SCOPE_EXIT(
{
- XFree(info);
- }
- });
+ if (info != NULL)
+ {
+ XFree(info);
+ }
+ });
info = XRRQueryOutputProperty(this->xdisplay_, this->output_, this->backlight_atom_);
if (info == NULL)
diff --git a/plugins/power/backlight/power-backlight-monitor-x11.h b/plugins/power/backlight/power-backlight-monitor-x11-atom.h
similarity index 78%
rename from plugins/power/backlight/power-backlight-monitor-x11.h
rename to plugins/power/backlight/power-backlight-monitor-x11-atom.h
index 6249c25..7009991 100644
--- a/plugins/power/backlight/power-backlight-monitor-x11.h
+++ b/plugins/power/backlight/power-backlight-monitor-x11-atom.h
@@ -18,17 +18,18 @@
//
#include <X11/extensions/Xrandr.h>
#include <gdk/gdkx.h>
+#include "plugins/power/backlight/power-backlight-interface.h"
-#include "plugins/power/backlight/power-backlight-base.h"
+typedef struct _XDisplay Display;
namespace Kiran
{
// 通过Xrandr扩展调节单个显示设备亮度值
-class PowerBacklightMonitorX11 : public PowerBacklightAbsolute
+class PowerBacklightMonitorX11Atom : public PowerBacklightAbsolute
{
public:
- PowerBacklightMonitorX11(Atom backlight_atom, RROutput output);
- virtual ~PowerBacklightMonitorX11(){};
+ PowerBacklightMonitorX11Atom(Atom backlight_atom, RROutput output);
+ virtual ~PowerBacklightMonitorX11Atom(){};
// 设置亮度值
virtual bool set_brightness_value(int32_t brightness_value) override;
@@ -44,5 +45,4 @@ private:
RROutput output_;
};
-using PowerBacklightMonitorX11Vec = std::vector<std::shared_ptr<PowerBacklightMonitorX11>>;
} // namespace Kiran
diff --git a/plugins/power/backlight/power-backlight-monitor-x11-gamma.cpp b/plugins/power/backlight/power-backlight-monitor-x11-gamma.cpp
new file mode 100644
index 0000000..bbaf464
--- /dev/null
+++ b/plugins/power/backlight/power-backlight-monitor-x11-gamma.cpp
@@ -0,0 +1,237 @@
+/**
+ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
+ * kiran-cc-daemon is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ *
+ * Author: tangjie02 <tangjie02@kylinos.com.cn>
+ */
+
+#include "plugins/power/backlight/power-backlight-monitor-x11-gamma.h"
+
+#include <X11/Xatom.h>
+#include <algorithm>
+
+namespace Kiran
+{
+#define GAMMA_MIN_BRIGHTNESS 0
+#define GAMMA_MAX_BRIGHTNESS 100
+
+PowerBacklightMonitorX11Gamma::PowerBacklightMonitorX11Gamma(RROutput output,
+ RRCrtc crtc) : output_(output),
+ crtc_(crtc)
+{
+ this->display_ = gdk_display_get_default();
+ this->xdisplay_ = GDK_DISPLAY_XDISPLAY(this->display_);
+}
+
+bool PowerBacklightMonitorX11Gamma::set_brightness_value(int32_t brightness_value)
+{
+ RETURN_VAL_IF_TRUE(this->crtc_ == None, false);
+
+ auto size = XRRGetCrtcGammaSize(this->xdisplay_, this->crtc_);
+
+ if (!size)
+ {
+ KLOG_WARNING("Gamma size is 0.");
+ return false;
+ }
+ else
+ {
+ KLOG_DEBUG("The gamma size is %d.", size);
+ }
+
+ /*
+ * The gamma-correction lookup table managed through XRR[GS]etCrtcGamma
+ * is 2^n in size, where 'n' is the number of significant bits in
+ * the X Color. Because an X Color is 16 bits, size cannot be larger
+ * than 2^16.
+ */
+ if (size > 65536)
+ {
+ KLOG_WARNING("Gamma correction table is impossibly large.");
+ return false;
+ }
+
+ auto crtc_gamma = XRRAllocGamma(size);
+ if (!crtc_gamma)
+ {
+ KLOG_WARNING("Gamma allocation failed.");
+ return false;
+ }
+
+ SCOPE_EXIT(
+ {
+ if (crtc_gamma)
+ {
+ XRRFreeGamma(crtc_gamma);
+ }
+ });
+
+ auto gamma_info = this->get_gamma_info();
+ auto gamma_red = 1.0 / gamma_info.red;
+ auto gamma_green = 1.0 / gamma_info.green;
+ auto gamma_blue = 1.0 / gamma_info.blue;
+ auto gamma_brightness = (double)brightness_value / 100.0;
+
+ for (int i = 0; i < size; i++)
+ {
+ if (gamma_red == 1.0 && gamma_brightness == 1.0)
+ {
+ crtc_gamma->red[i] = (double)i / (double)(size - 1) * 65535.0;
+ }
+ else
+ {
+ crtc_gamma->red[i] = std::min(pow((double)i / (double)(size - 1),
+ gamma_red) *
+ gamma_brightness,
+ (double)1.0) *
+ 65535.0;
+ }
+
+ if (gamma_green == 1.0 && gamma_brightness == 1.0)
+ {
+ crtc_gamma->green[i] = (double)i / (double)(size - 1) * 65535.0;
+ }
+ else
+ {
+ crtc_gamma->green[i] = std::min(pow((double)i / (double)(size - 1),
+ gamma_green) *
+ gamma_brightness,
+ 1.0) *
+ 65535.0;
+ }
+
+ if (gamma_blue == 1.0 && gamma_brightness == 1.0)
+ {
+ crtc_gamma->blue[i] = (double)i / (double)(size - 1) * 65535.0;
+ }
+ else
+ {
+ crtc_gamma->blue[i] = std::min(pow((double)i / (double)(size - 1),
+ gamma_blue) *
+ gamma_brightness,
+ 1.0) *
+ 65535.0;
+ }
+ }
+
+ XRRSetCrtcGamma(this->xdisplay_, this->crtc_, crtc_gamma);
+
+ return true;
+}
+
+int32_t PowerBacklightMonitorX11Gamma::get_brightness_value()
+{
+ auto gamma_info = this->get_gamma_info();
+ RETURN_VAL_IF_TRUE(gamma_info.brightness >= 1.0, 1);
+ RETURN_VAL_IF_TRUE(gamma_info.brightness <= 0.001, 0);
+ return std::min(int32_t((gamma_info.brightness * GAMMA_MAX_BRIGHTNESS) + 0.5), GAMMA_MAX_BRIGHTNESS);
+}
+
+bool PowerBacklightMonitorX11Gamma::get_brightness_range(int32_t &min, int32_t &max)
+{
+ min = GAMMA_MIN_BRIGHTNESS;
+ max = GAMMA_MAX_BRIGHTNESS;
+ return true;
+}
+
+int PowerBacklightMonitorX11Gamma::find_last_non_clamped(unsigned short array[], int size)
+{
+ int i;
+ for (i = size - 1; i > 0; i--)
+ {
+ if (array[i] < 0xffff)
+ return i;
+ }
+ return 0;
+}
+
+GammaInfo PowerBacklightMonitorX11Gamma::get_gamma_info()
+{
+ GammaInfo gamma_info;
+
+ RETURN_VAL_IF_TRUE(this->crtc_ == 0, gamma_info);
+
+ auto size = XRRGetCrtcGammaSize(this->xdisplay_, this->crtc_);
+ if (!size)
+ {
+ KLOG_WARNING("Gamma size is 0.");
+ return gamma_info;
+ }
+
+ auto crtc_gamma = XRRGetCrtcGamma(this->xdisplay_, this->crtc_);
+ if (!crtc_gamma)
+ {
+ KLOG_WARNING("Failed to get gamma for output(%d).", (int)this->output_);
+ return gamma_info;
+ }
+
+ /*
+ * Here is a bit tricky because gamma is a whole curve for each
+ * color. So, typically, we need to represent 3 * 256 values as 3 + 1
+ * values. Therefore, we approximate the gamma curve (v) by supposing
+ * it always follows the way we set it: a power function (i^g)
+ * multiplied by a brightness (b).
+ * v = i^g * b
+ * so g = (ln(v) - ln(b))/ln(i)
+ * and b can be found using two points (v1,i1) and (v2, i2):
+ * b = e^((ln(v2)*ln(i1) - ln(v1)*ln(i2))/ln(i1/i2))
+ * For the best resolution, we select i2 at the highest place not
+ * clamped and i1 at i2/2. Note that if i2 = 1 (as in most normal
+ * cases), then b = v2.
+ */
+ auto last_red = find_last_non_clamped(crtc_gamma->red, size);
+ auto last_green = find_last_non_clamped(crtc_gamma->green, size);
+ auto last_blue = find_last_non_clamped(crtc_gamma->blue, size);
+ auto best_array = crtc_gamma->red;
+ auto last_best = last_red;
+ if (last_green > last_best)
+ {
+ last_best = last_green;
+ best_array = crtc_gamma->green;
+ }
+ if (last_blue > last_best)
+ {
+ last_best = last_blue;
+ best_array = crtc_gamma->blue;
+ }
+ if (last_best == 0)
+ last_best = 1;
+
+ auto middle = last_best / 2;
+ auto i1 = (double)(middle + 1) / size;
+ auto v1 = (double)(best_array[middle]) / 65535;
+ auto i2 = (double)(last_best + 1) / size;
+ auto v2 = (double)(best_array[last_best]) / 65535;
+ if (v2 >= 0.0001)
+ {
+ if ((last_best + 1) == size)
+ {
+ gamma_info.brightness = v2;
+ }
+ else
+ {
+ gamma_info.brightness = exp((log(v2) * log(i1) - log(v1) * log(i2)) / log(i1 / i2));
+ }
+ gamma_info.red = log((double)(crtc_gamma->red[last_red / 2]) / gamma_info.brightness / 65535) / log((double)((last_red / 2) + 1) / size);
+ gamma_info.green = log((double)(crtc_gamma->green[last_green / 2]) / gamma_info.brightness / 65535) / log((double)((last_green / 2) + 1) / size);
+ gamma_info.blue = log((double)(crtc_gamma->blue[last_blue / 2]) / gamma_info.brightness / 65535) / log((double)((last_blue / 2) + 1) / size);
+ }
+
+ XRRFreeGamma(crtc_gamma);
+
+ KLOG_DEBUG("Gamma info: red(%.2f), green(%.2f), blue(%.2f), brightness(%.2f).",
+ gamma_info.red,
+ gamma_info.green,
+ gamma_info.blue,
+ gamma_info.brightness);
+ return gamma_info;
+}
+
+} // namespace Kiran
diff --git a/plugins/power/backlight/power-backlight-monitor-x11-gamma.h b/plugins/power/backlight/power-backlight-monitor-x11-gamma.h
new file mode 100644
index 0000000..85d2ed0
--- /dev/null
+++ b/plugins/power/backlight/power-backlight-monitor-x11-gamma.h
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
+ * kiran-cc-daemon is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ *
+ * Author: tangjie02 <tangjie02@kylinos.com.cn>
+ */
+
+#pragma once
+
+#include <gdkmm.h>
+//
+#include <X11/extensions/Xrandr.h>
+#include <gdk/gdkx.h>
+
+#include "plugins/power/backlight/power-backlight-interface.h"
+
+namespace Kiran
+{
+struct GammaInfo
+{
+ GammaInfo() : brightness(0.0), red(1.0), green(1.0), blue(1.0) {}
+ double brightness;
+ double red;
+ double green;
+ double blue;
+};
+
+// 通过Xrandr扩展调节crtc的gamma值来实现亮度变化
+class PowerBacklightMonitorX11Gamma : public PowerBacklightAbsolute
+{
+public:
+ PowerBacklightMonitorX11Gamma(RROutput output, RRCrtc crtc);
+ virtual ~PowerBacklightMonitorX11Gamma(){};
+
+ // 设置亮度值
+ virtual bool set_brightness_value(int32_t brightness_value) override;
+ // 获取亮度值
+ virtual int32_t get_brightness_value() override;
+ // 获取亮度最大最小值
+ virtual bool get_brightness_range(int32_t &min, int32_t &max) override;
+
+private:
+ int find_last_non_clamped(unsigned short array[], int size);
+ GammaInfo get_gamma_info();
+
+private:
+ GdkDisplay *display_;
+ Display *xdisplay_;
+ RROutput output_;
+ RRCrtc crtc_;
+};
+
+} // namespace Kiran
diff --git a/plugins/power/backlight/power-backlight-moitor.cpp b/plugins/power/backlight/power-backlight-monitors-controller.cpp
similarity index 65%
rename from plugins/power/backlight/power-backlight-moitor.cpp
rename to plugins/power/backlight/power-backlight-monitors-controller.cpp
index d73ee97..7e83f55 100644
--- a/plugins/power/backlight/power-backlight-moitor.cpp
+++ b/plugins/power/backlight/power-backlight-monitors-controller.cpp
@@ -12,50 +12,42 @@
* Author: tangjie02 <tangjie02@kylinos.com.cn>
*/
-#include "plugins/power/backlight/power-backlight-monitor-tool.h"
-#include "plugins/power/backlight/power-backlight-monitor.h"
+#include "plugins/power/backlight/power-backlight-monitors-controller.h"
+#include "plugins/power/backlight/power-backlight-monitors-tool.h"
+#include "plugins/power/backlight/power-backlight-monitors-x11.h"
namespace Kiran
{
-PowerBacklightMonitor::PowerBacklightMonitor() : brightness_percentage_(-1)
+PowerBacklightMonitorsController::PowerBacklightMonitorsController() : brightness_percentage_(-1)
{
+ this->power_settings_ = Gio::Settings::create(POWER_SCHEMA_ID);
}
-PowerBacklightMonitor::~PowerBacklightMonitor()
+PowerBacklightMonitorsController::~PowerBacklightMonitorsController()
{
}
-void PowerBacklightMonitor::init()
+void PowerBacklightMonitorsController::init()
{
- KLOG_PROFILE("");
-
- backlight_x11_.init();
- this->backlight_helper_.init();
-
- this->load_absolute_monitors();
+ this->load_backlight_monitors();
this->brightness_percentage_ = this->get_brightness();
-
- this->backlight_x11_.signal_monitor_changed().connect(sigc::mem_fun(this, &PowerBacklightMonitor::on_x11_monitor_changed));
- this->backlight_helper_.signal_brightness_changed().connect(sigc::mem_fun(this, &PowerBacklightMonitor::on_helper_brightness_changed));
}
-bool PowerBacklightMonitor::set_brightness(int32_t percentage)
+bool PowerBacklightMonitorsController::set_brightness(int32_t percentage)
{
- KLOG_PROFILE("percentage: %d.", percentage);
-
- RETURN_VAL_IF_TRUE(this->absolute_monitors_.size() == 0, false);
-
- for (auto &monitor : this->absolute_monitors_)
+ auto monitors = this->backlight_monitors_->get_monitors();
+ for (auto &monitor : monitors)
{
RETURN_VAL_IF_FALSE(this->set_brightness_percentage(monitor, percentage), false);
}
-
+ this->update_cached_brightness();
return true;
}
-int32_t PowerBacklightMonitor::get_brightness()
+int32_t PowerBacklightMonitorsController::get_brightness()
{
- for (auto &monitor : this->absolute_monitors_)
+ auto monitors = this->backlight_monitors_->get_monitors();
+ for (auto &monitor : monitors)
{
auto percentage = this->get_brightness_percentage(monitor);
RETURN_VAL_IF_TRUE(percentage >= 0, percentage);
@@ -63,43 +55,57 @@ int32_t PowerBacklightMonitor::get_brightness()
return -1;
}
-bool PowerBacklightMonitor::brightness_up()
+bool PowerBacklightMonitorsController::brightness_up()
{
- RETURN_VAL_IF_TRUE(this->absolute_monitors_.size() == 0, false);
-
- for (auto &monitor : this->absolute_monitors_)
+ auto monitors = this->backlight_monitors_->get_monitors();
+ for (auto &monitor : monitors)
{
this->brightness_value_up(monitor);
}
return true;
}
-bool PowerBacklightMonitor::brightness_down()
+bool PowerBacklightMonitorsController::brightness_down()
{
- RETURN_VAL_IF_TRUE(this->absolute_monitors_.size() == 0, false);
- for (auto &monitor : this->absolute_monitors_)
+ auto monitors = this->backlight_monitors_->get_monitors();
+ for (auto &monitor : monitors)
{
this->brightness_value_down(monitor);
}
return true;
}
-void PowerBacklightMonitor::load_absolute_monitors()
+void PowerBacklightMonitorsController::load_backlight_monitors()
{
- this->absolute_monitors_.clear();
+ auto monitor_backlight_policy = this->power_settings_->get_enum(POWER_SCHEMA_MONITOR_BACKLIGHT_POLICY);
- if (this->backlight_x11_.support_backlight_extension())
+ switch (monitor_backlight_policy)
{
- auto monitors = this->backlight_x11_.get_monitors();
- this->absolute_monitors_ = PowerBacklightAbsoluteVec(monitors.begin(), monitors.end());
- }
- else
+ case PowerMonitorBacklightPolicy::POWER_MONITOR_BACKLIGHT_POLICY_TOOL:
+ this->backlight_monitors_ = std::make_shared<PowerBacklightMonitorsTool>();
+ break;
+ case PowerMonitorBacklightPolicy::POWER_MONITOR_BACKLIGHT_POLICY_X11:
+ this->backlight_monitors_ = std::make_shared<PowerBacklightMonitorsX11>();
+ break;
+ default:
{
- this->absolute_monitors_.push_back(std::make_shared<PowerBacklightMonitorTool>());
+ if (PowerBacklightMonitorsTool::support_backlight())
+ {
+ this->backlight_monitors_ = std::make_shared<PowerBacklightMonitorsTool>();
+ }
+ else
+ {
+ this->backlight_monitors_ = std::make_shared<PowerBacklightMonitorsX11>();
+ }
}
+ }
+
+ this->backlight_monitors_->init();
+ this->backlight_monitors_->signal_monitor_changed().connect(sigc::mem_fun(this, &PowerBacklightMonitorsController::on_monitor_changed));
+ this->backlight_monitors_->signal_brightness_changed().connect(sigc::mem_fun(this, &PowerBacklightMonitorsController::update_cached_brightness));
}
-bool PowerBacklightMonitor::set_brightness_percentage(std::shared_ptr<PowerBacklightAbsolute> absolute_monitor, int32_t percentage)
+bool PowerBacklightMonitorsController::set_brightness_percentage(std::shared_ptr<PowerBacklightAbsolute> absolute_monitor, int32_t percentage)
{
int32_t brightness_min = -1;
int32_t brightness_max = -1;
@@ -161,7 +167,7 @@ bool PowerBacklightMonitor::set_brightness_percentage(std::shared_ptr<PowerBackl
return true;
}
-int32_t PowerBacklightMonitor::get_brightness_percentage(std::shared_ptr<PowerBacklightAbsolute> absolute_monitor)
+int32_t PowerBacklightMonitorsController::get_brightness_percentage(std::shared_ptr<PowerBacklightAbsolute> absolute_monitor)
{
int32_t brightness_min = -1;
int32_t brightness_max = -1;
@@ -182,7 +188,7 @@ int32_t PowerBacklightMonitor::get_brightness_percentage(std::shared_ptr<PowerBa
return percentage;
}
-bool PowerBacklightMonitor::brightness_value_up(std::shared_ptr<PowerBacklightAbsolute> absolute_monitor)
+bool PowerBacklightMonitorsController::brightness_value_up(std::shared_ptr<PowerBacklightAbsolute> absolute_monitor)
{
int32_t brightness_min = -1;
int32_t brightness_max = -1;
@@ -199,7 +205,7 @@ bool PowerBacklightMonitor::brightness_value_up(std::shared_ptr<PowerBacklightAb
return absolute_monitor->set_brightness_value(brightness_current_value);
}
-bool PowerBacklightMonitor::brightness_value_down(std::shared_ptr<PowerBacklightAbsolute> absolute_monitor)
+bool PowerBacklightMonitorsController::brightness_value_down(std::shared_ptr<PowerBacklightAbsolute> absolute_monitor)
{
int32_t brightness_min = -1;
int32_t brightness_max = -1;
@@ -216,15 +222,14 @@ bool PowerBacklightMonitor::brightness_value_down(std::shared_ptr<PowerBacklight
return absolute_monitor->set_brightness_value(brightness_current_value);
}
-int32_t PowerBacklightMonitor::brightness_discrete2percent(int32_t discrete, int32_t levels)
+int32_t PowerBacklightMonitorsController::brightness_discrete2percent(int32_t discrete, int32_t levels)
{
- // TODO: test
RETURN_VAL_IF_TRUE(discrete > levels, 100);
RETURN_VAL_IF_TRUE(levels <= 1, 0);
return (int32_t)(((double)discrete * (100.0 / (double)(levels - 1))) + 0.5);
}
-int32_t PowerBacklightMonitor::brightness_percent2discrete(int32_t percentage, int32_t levels)
+int32_t PowerBacklightMonitorsController::brightness_percent2discrete(int32_t percentage, int32_t levels)
{
RETURN_VAL_IF_TRUE(percentage > 100, levels);
RETURN_VAL_IF_TRUE(levels == 0, 0);
@@ -232,7 +237,7 @@ int32_t PowerBacklightMonitor::brightness_percent2discrete(int32_t percentage, i
return (int32_t)((((double)percentage * (double)(levels - 1)) / 100.0) + 0.5);
}
-int32_t PowerBacklightMonitor::get_brightness_step(uint32_t levels)
+int32_t PowerBacklightMonitorsController::get_brightness_step(uint32_t levels)
{
if (levels > 20)
{
@@ -241,7 +246,7 @@ int32_t PowerBacklightMonitor::get_brightness_step(uint32_t levels)
return 1;
}
-void PowerBacklightMonitor::update_cached_brightness()
+void PowerBacklightMonitorsController::update_cached_brightness()
{
auto brightness_percentage = this->get_brightness();
if (brightness_percentage != this->brightness_percentage_)
@@ -251,24 +256,7 @@ void PowerBacklightMonitor::update_cached_brightness()
}
}
-void PowerBacklightMonitor::on_x11_monitor_changed(PBXMonitorEvent x11_monitor_event)
-{
- switch (x11_monitor_event)
- {
- case PBXMonitorEvent::PBX_MONITOR_EVENT_PROPERTY_CHANGED:
- {
- this->update_cached_brightness();
- break;
- }
- case PBXMonitorEvent::PBX_MONITOR_EVENT_SCREEN_CHANGED:
- this->load_absolute_monitors();
- break;
- default:
- break;
- }
-}
-
-void PowerBacklightMonitor::on_helper_brightness_changed(int32_t brightness_value)
+void PowerBacklightMonitorsController::on_monitor_changed()
{
this->update_cached_brightness();
}
diff --git a/plugins/power/backlight/power-backlight-monitor.h b/plugins/power/backlight/power-backlight-monitors-controller.h
similarity index 80%
rename from plugins/power/backlight/power-backlight-monitor.h
rename to plugins/power/backlight/power-backlight-monitors-controller.h
index b14e7f9..d678e23 100644
--- a/plugins/power/backlight/power-backlight-monitor.h
+++ b/plugins/power/backlight/power-backlight-monitors-controller.h
@@ -18,9 +18,7 @@
//
#include <X11/Xatom.h>
-#include "plugins/power/backlight/power-backlight-base.h"
-#include "plugins/power/backlight/power-backlight-x11.h"
-#include "plugins/power/tools/power-backlight-helper.h"
+#include "plugins/power/backlight/power-backlight-interface.h"
namespace Kiran
{
@@ -28,11 +26,12 @@ namespace Kiran
台式机的显示器不一定带有背光控制器,因此可能无法通过该模块的接口调节亮度,
台式机的显示器一般可以直接通过显示器周边的按钮调节亮度 */
-class PowerBacklightMonitor : public PowerBacklightPercentage
+
+class PowerBacklightMonitorsController : public PowerBacklightPercentage
{
public:
- PowerBacklightMonitor();
- virtual ~PowerBacklightMonitor();
+ PowerBacklightMonitorsController();
+ virtual ~PowerBacklightMonitorsController();
virtual void init();
@@ -55,7 +54,7 @@ public:
virtual sigc::signal<void, int32_t> &signal_brightness_changed() override { return this->brightness_changed_; };
private:
- void load_absolute_monitors();
+ void load_backlight_monitors();
// 设置单个显示器的亮度百分比
bool set_brightness_percentage(std::shared_ptr<PowerBacklightAbsolute> absolute_monitor, int32_t percentage);
// 获取单个显示器的亮度
@@ -71,18 +70,14 @@ private:
// 更新缓存的亮度百分比并发送信号
void update_cached_brightness();
-
- void on_x11_monitor_changed(PBXMonitorEvent x11_monitor_event);
- void on_helper_brightness_changed(int32_t brightness_value);
+ void on_monitor_changed();
private:
- PowerBacklightX11 backlight_x11_;
- PowerBacklightHelper backlight_helper_;
-
- // 用于调节显示器的绝对值
- PowerBacklightAbsoluteVec absolute_monitors_;
+ std::shared_ptr<PowerBacklightMonitors> backlight_monitors_;
int32_t brightness_percentage_;
sigc::signal<void, int32_t> brightness_changed_;
+
+ Glib::RefPtr<Gio::Settings> power_settings_;
};
} // namespace Kiran
\ No newline at end of file
diff --git a/plugins/power/backlight/power-backlight-monitors-tool.cpp b/plugins/power/backlight/power-backlight-monitors-tool.cpp
new file mode 100644
index 0000000..6759e38
--- /dev/null
+++ b/plugins/power/backlight/power-backlight-monitors-tool.cpp
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
+ * kiran-cc-daemon is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ *
+ * Author: tangjie02 <tangjie02@kylinos.com.cn>
+ */
+
+#include "plugins/power/backlight/power-backlight-monitors-tool.h"
+#include "config.h"
+#include "plugins/power/backlight/power-backlight-monitor-tool.h"
+
+namespace Kiran
+{
+#define POWER_BACKLIGHT_HELPER KCC_INSTALL_BINDIR "/kiran-power-backlight-helper"
+
+PowerBacklightMonitorsTool::PowerBacklightMonitorsTool()
+{
+ auto backlight_dir = this->get_backlight_dir();
+ if (!backlight_dir.empty())
+ {
+ auto filename = Glib::build_filename(backlight_dir, "brightness");
+ this->brightness_monitor_ = FileUtils::make_monitor_file(filename,
+ sigc::mem_fun(this, &PowerBacklightMonitorsTool::on_brightness_changed),
+ Gio::FILE_MONITOR_NONE);
+ }
+}
+
+bool PowerBacklightMonitorsTool::support_backlight()
+{
+ try
+ {
+ std::string standard_output;
+ int32_t exit_status = 0;
+ auto cmdline = fmt::format("pkexec {0} --support-backlight", POWER_BACKLIGHT_HELPER);
+ Glib::spawn_command_line_sync(cmdline, &standard_output, nullptr, &exit_status);
+ RETURN_VAL_IF_TRUE(exit_status != 0, false);
+ return (std::strtol(standard_output.c_str(), nullptr, 0) == 1);
+ }
+ catch (const Glib::Error &e)
+ {
+ KLOG_WARNING("%s.", e.what().c_str());
+ }
+ return false;
+}
+
+void PowerBacklightMonitorsTool::init()
+{
+ this->backlight_monitors_.clear();
+ this->backlight_monitors_.push_back(std::make_shared<PowerBacklightMonitorTool>());
+}
+
+std::string PowerBacklightMonitorsTool::get_backlight_dir()
+{
+ try
+ {
+ std::string standard_output;
+ int32_t exit_status = 0;
+ auto cmdline = fmt::format("pkexec {0} --get-backlight-dir", POWER_BACKLIGHT_HELPER);
+ Glib::spawn_command_line_sync(cmdline, &standard_output, nullptr, &exit_status);
+ RETURN_VAL_IF_TRUE(exit_status != 0, std::string());
+ return standard_output;
+ }
+ catch (const Glib::Error &e)
+ {
+ KLOG_WARNING("%s.", e.what().c_str());
+ }
+ return std::string();
+}
+
+void PowerBacklightMonitorsTool::on_brightness_changed(const Glib::RefPtr<Gio::File> &file,
+ const Glib::RefPtr<Gio::File> &other_file,
+ Gio::FileMonitorEvent event_type)
+{
+ switch (event_type)
+ {
+ case Gio::FILE_MONITOR_EVENT_CHANGED:
+ {
+ this->brightness_changed_.emit();
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+} // namespace Kiran
\ No newline at end of file
diff --git a/plugins/power/backlight/power-backlight-monitors-tool.h b/plugins/power/backlight/power-backlight-monitors-tool.h
new file mode 100644
index 0000000..6b8a84e
--- /dev/null
+++ b/plugins/power/backlight/power-backlight-monitors-tool.h
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd.
+ * kiran-cc-daemon is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ *
+ * Author: tangjie02 <tangjie02@kylinos.com.cn>
+ */
+
+#pragma once
+
+#include "plugins/power/backlight/power-backlight-interface.h"
+
+namespace Kiran
+{
+class PowerBacklightMonitorsTool : public PowerBacklightMonitors
+{
+public:
+ PowerBacklightMonitorsTool();
+ virtual ~PowerBacklightMonitorsTool(){};
+
+ static bool support_backlight();
+
+ virtual void init();
+ // 获取所有显示器亮度设置对象
+ virtual PowerBacklightAbsoluteVec get_monitors() { return this->backlight_monitors_; };
+ virtual sigc::signal<void> signal_monitor_changed() { return this->monitor_changed_; };
+ virtual sigc::signal<void> signal_brightness_changed() { return this->brightness_changed_; };
+
+private:
+ std::string get_backlight_dir();
+ void on_brightness_changed(const Glib::RefPtr<Gio::File> &file,
+ const Glib::RefPtr<Gio::File> &other_file,
+ Gio::FileMonitorEvent event_type);
+
+private:
+ sigc::signal<void> monitor_changed_;
+ sigc::signal<void> brightness_changed_;
+ Glib::RefPtr<Gio::FileMonitor> brightness_monitor_;
+
+ PowerBacklightAbsoluteVec backlight_monitors_;
+};
+} // namespace Kiran
\ No newline at end of file
diff --git a/plugins/power/backlight/power-backlight-x11.cpp b/plugins/power/backlight/power-backlight-monitors-x11.cpp
similarity index 62%
rename from plugins/power/backlight/power-backlight-x11.cpp
rename to plugins/power/backlight/power-backlight-monitors-x11.cpp
index 9dfed20..80a15a0 100644
--- a/plugins/power/backlight/power-backlight-x11.cpp
+++ b/plugins/power/backlight/power-backlight-monitors-x11.cpp
@@ -12,15 +12,17 @@
* Author: tangjie02 <tangjie02@kylinos.com.cn>
*/
-#include "plugins/power/backlight/power-backlight-x11.h"
+#include "plugins/power/backlight/power-backlight-monitors-x11.h"
+#include "plugins/power/backlight/power-backlight-monitor-x11-atom.h"
+#include "plugins/power/backlight/power-backlight-monitor-x11-gamma.h"
namespace Kiran
{
-PowerBacklightX11::PowerBacklightX11() : event_base_(0),
- error_base_(0),
- extension_supported_(false),
- backlight_atom_(None),
- resources_(NULL)
+PowerBacklightMonitorsX11::PowerBacklightMonitorsX11() : event_base_(0),
+ error_base_(0),
+ extension_supported_(false),
+ backlight_atom_(None),
+ resources_(NULL)
{
this->display_ = gdk_display_get_default();
this->xdisplay_ = GDK_DISPLAY_XDISPLAY(this->display_);
@@ -30,24 +32,21 @@ PowerBacklightX11::PowerBacklightX11() : event_base_(0),
this->xroot_window_ = GDK_WINDOW_XID(this->root_window_);
}
-PowerBacklightX11::~PowerBacklightX11()
+PowerBacklightMonitorsX11::~PowerBacklightMonitorsX11()
{
this->clear_resource();
if (this->extension_supported_)
{
- gdk_window_remove_filter(this->root_window_, &PowerBacklightX11::window_event, this);
+ gdk_window_remove_filter(this->root_window_, &PowerBacklightMonitorsX11::window_event, this);
}
}
-void PowerBacklightX11::init()
+void PowerBacklightMonitorsX11::init()
{
RETURN_IF_FALSE(this->init_xrandr());
this->backlight_atom_ = this->get_backlight_atom();
- RETURN_IF_TRUE(this->backlight_atom_ == None);
-
- KLOG_DEBUG("Support brightness settings");
this->load_resource();
XRRSelectInput(this->xdisplay_, this->xroot_window_, RRScreenChangeNotifyMask | RROutputPropertyNotifyMask);
@@ -55,11 +54,11 @@ void PowerBacklightX11::init()
this->event_base_,
RRNotify + 1);
- gdk_window_add_filter(this->root_window_, &PowerBacklightX11::window_event, this);
+ gdk_window_add_filter(this->root_window_, &PowerBacklightMonitorsX11::window_event, this);
this->extension_supported_ = true;
}
-bool PowerBacklightX11::init_xrandr()
+bool PowerBacklightMonitorsX11::init_xrandr()
{
KLOG_PROFILE("");
@@ -84,7 +83,7 @@ bool PowerBacklightX11::init_xrandr()
return true;
}
-Atom PowerBacklightX11::get_backlight_atom()
+Atom PowerBacklightMonitorsX11::get_backlight_atom()
{
RETURN_VAL_IF_TRUE(this->xdisplay_ == NULL, false);
@@ -103,7 +102,7 @@ Atom PowerBacklightX11::get_backlight_atom()
return backlight_atom;
}
-void PowerBacklightX11::load_resource()
+void PowerBacklightMonitorsX11::load_resource()
{
this->clear_resource();
this->resources_ = XRRGetScreenResourcesCurrent(this->xdisplay_, this->xroot_window_);
@@ -111,12 +110,33 @@ void PowerBacklightX11::load_resource()
this->backlight_monitors_.clear();
for (int32_t i = 0; i < this->resources_->noutput; ++i)
{
- auto monitor = std::make_shared<PowerBacklightMonitorX11>(this->backlight_atom_, this->resources_->outputs[i]);
+ std::shared_ptr<PowerBacklightAbsolute> monitor;
+ auto output_info = XRRGetOutputInfo(this->xdisplay_, this->resources_, this->resources_->outputs[i]);
+ if (!output_info)
+ {
+ KLOG_WARNING("Not found output info for %d.", (int)this->resources_->outputs[i]);
+ continue;
+ }
+
+ if (!output_info->crtc)
+ {
+ KLOG_DEBUG("Not found crtc for output %d, ignore it.", (int)this->resources_->outputs[i]);
+ continue;
+ }
+
+ if (this->backlight_atom_ != None)
+ {
+ monitor = std::make_shared<PowerBacklightMonitorX11Atom>(this->backlight_atom_, this->resources_->outputs[i]);
+ }
+ else
+ {
+ monitor = std::make_shared<PowerBacklightMonitorX11Gamma>(this->resources_->outputs[i], output_info->crtc);
+ }
this->backlight_monitors_.push_back(monitor);
}
}
-void PowerBacklightX11::clear_resource()
+void PowerBacklightMonitorsX11::clear_resource()
{
if (this->resources_)
{
@@ -125,9 +145,9 @@ void PowerBacklightX11::clear_resource()
}
}
-GdkFilterReturn PowerBacklightX11::window_event(GdkXEvent *gdk_event, GdkEvent *event, gpointer data)
+GdkFilterReturn PowerBacklightMonitorsX11::window_event(GdkXEvent *gdk_event, GdkEvent *event, gpointer data)
{
- PowerBacklightX11 *backlight = (PowerBacklightX11 *)data;
+ PowerBacklightMonitorsX11 *backlight = (PowerBacklightMonitorsX11 *)data;
XEvent *xevent = (XEvent *)gdk_event;
RETURN_VAL_IF_FALSE(backlight, GDK_FILTER_CONTINUE);
@@ -138,12 +158,12 @@ GdkFilterReturn PowerBacklightX11::window_event(GdkXEvent *gdk_event, GdkEvent *
case RRScreenChangeNotify:
{
backlight->load_resource();
- backlight->monitor_changed_.emit(PBXMonitorEvent::PBX_MONITOR_EVENT_SCREEN_CHANGED);
+ backlight->monitor_changed_.emit();
break;
}
case RROutputPropertyNotifyMask:
{
- backlight->monitor_changed_.emit(PBXMonitorEvent::PBX_MONITOR_EVENT_PROPERTY_CHANGED);
+ backlight->brightness_changed_.emit();
break;
}
default:
diff --git a/plugins/power/backlight/power-backlight-x11.h b/plugins/power/backlight/power-backlight-monitors-x11.h
similarity index 63%
rename from plugins/power/backlight/power-backlight-x11.h
rename to plugins/power/backlight/power-backlight-monitors-x11.h
index 870389d..9be81a7 100644
--- a/plugins/power/backlight/power-backlight-x11.h
+++ b/plugins/power/backlight/power-backlight-monitors-x11.h
@@ -12,38 +12,34 @@
* Author: tangjie02 <tangjie02@kylinos.com.cn>
*/
-#include "plugins/power/backlight/power-backlight-monitor-x11.h"
+#include <gdkmm.h>
+//
+#include <X11/extensions/Xrandr.h>
+#include <gdk/gdkx.h>
+
+#include "plugins/power/backlight/power-backlight-interface.h"
namespace Kiran
{
-enum PBXMonitorEvent
-{
- // 显示器列表变化
- PBX_MONITOR_EVENT_SCREEN_CHANGED,
- // 显示器属性(亮度)可能发生变化
- PBX_MONITOR_EVENT_PROPERTY_CHANGED,
-};
-
-class PowerBacklightX11
+class PowerBacklightMonitorsX11 : public PowerBacklightMonitors
{
public:
- PowerBacklightX11();
- virtual ~PowerBacklightX11();
-
- void init();
-
- // 是否支持设置亮度
- bool support_backlight_extension() { return this->extension_supported_; };
+ PowerBacklightMonitorsX11();
+ virtual ~PowerBacklightMonitorsX11();
+ virtual void init();
// 获取所有显示器亮度设置对象
- PowerBacklightMonitorX11Vec get_monitors() { return this->backlight_monitors_; }
-
- sigc::signal<void, PBXMonitorEvent> signal_monitor_changed() { return this->monitor_changed_; };
+ virtual PowerBacklightAbsoluteVec get_monitors() { return this->backlight_monitors_; }
+ virtual sigc::signal<void> signal_monitor_changed() { return this->monitor_changed_; };
+ virtual sigc::signal<void> signal_brightness_changed() { return this->brightness_changed_; }
private:
bool init_xrandr();
Atom get_backlight_atom();
+ // 是否支持设置亮度
+ bool support_backlight_extension() { return this->extension_supported_; };
+
void load_resource();
void clear_resource();
@@ -62,8 +58,9 @@ private:
Atom backlight_atom_;
XRRScreenResources *resources_;
- PowerBacklightMonitorX11Vec backlight_monitors_;
+ PowerBacklightAbsoluteVec backlight_monitors_;
- sigc::signal<void, PBXMonitorEvent> monitor_changed_;
+ sigc::signal<void> monitor_changed_;
+ sigc::signal<void> brightness_changed_;
};
} // namespace Kiran
\ No newline at end of file
diff --git a/plugins/power/backlight/power-backlight.cpp b/plugins/power/backlight/power-backlight.cpp
index 6763842..54a27b2 100644
--- a/plugins/power/backlight/power-backlight.cpp
+++ b/plugins/power/backlight/power-backlight.cpp
@@ -15,13 +15,13 @@
#include "plugins/power/backlight/power-backlight.h"
#include "plugins/power/backlight/power-backlight-kbd.h"
-#include "plugins/power/backlight/power-backlight-monitor.h"
+#include "plugins/power/backlight/power-backlight-monitors-controller.h"
namespace Kiran
{
PowerBacklight::PowerBacklight()
{
- this->backlight_monitor_ = std::make_shared<PowerBacklightMonitor>();
+ this->backlight_monitor_ = std::make_shared<PowerBacklightMonitorsController>();
this->backlight_kbd_ = std::make_shared<PowerBacklightKbd>();
}
diff --git a/plugins/power/backlight/power-backlight.h b/plugins/power/backlight/power-backlight.h
index b8647ce..8c1ad9d 100644
--- a/plugins/power/backlight/power-backlight.h
+++ b/plugins/power/backlight/power-backlight.h
@@ -14,10 +14,9 @@
#pragma once
-#include "plugins/power/backlight/power-backlight-base.h"
+#include "plugins/power/backlight/power-backlight-interface.h"
#include "power-i.h"
-
namespace Kiran
{
// 背光设备的亮度控制管理
diff --git a/plugins/power/tools/main.cpp b/plugins/power/tools/main.cpp
index f84b397..a5bc5be 100644
--- a/plugins/power/tools/main.cpp
+++ b/plugins/power/tools/main.cpp
@@ -18,8 +18,25 @@
#include "config.h"
#include "plugins/power/tools/power-backlight-helper.h"
+struct CommandOptions
+{
+ CommandOptions() : show_version(false),
+ support_backlight(false),
+ get_backlight_direcotry(false),
+ get_brightness_value(false),
+ get_max_brightness_value(false),
+ set_brightness_value(-1) {}
+ bool show_version;
+ bool support_backlight;
+ bool get_backlight_direcotry;
+ bool get_brightness_value;
+ bool get_max_brightness_value;
+ int32_t set_brightness_value;
+};
+
int main(int argc, char* argv[])
{
+ CommandOptions options;
Kiran::PowerBacklightHelper backlight_helper;
Gio::init();
@@ -35,21 +52,59 @@ int main(int argc, char* argv[])
Glib::OptionContext context;
Glib::OptionGroup group("backlight-helper", _("power backlight helper"));
- Glib::OptionEntry entry1;
- entry1.set_long_name("get-brightness-value");
- entry1.set_flags(Glib::OptionEntry::FLAG_NO_ARG);
- entry1.set_description(N_("Get the current brightness value"));
+ group.add_entry(Kiran::MiscUtils::create_option_entry("version", N_("Output version infomation and exit.")),
+ options.show_version);
+ group.add_entry(Kiran::MiscUtils::create_option_entry("support-backlight", N_("Whether the backlight device exists.")),
+ options.support_backlight);
+ group.add_entry(Kiran::MiscUtils::create_option_entry("get-backlight-directory", N_("Get backlight monitor directory.")),
+ options.support_backlight);
+ group.add_entry(Kiran::MiscUtils::create_option_entry("get-brightness-value", N_("Get the current brightness value.")),
+ options.get_brightness_value);
+ group.add_entry(Kiran::MiscUtils::create_option_entry("get-max-brightness-value", N_("Get the max brightness value.")),
+ options.get_max_brightness_value);
+ group.add_entry(Kiran::MiscUtils::create_option_entry("set-brightness-value", N_("Set the brightness value.")),
+ options.set_brightness_value);
+
+ group.set_translation_domain(GETTEXT_PACKAGE);
+ context.set_main_group(group);
+
+ try
+ {
+ context.parse(argc, argv);
+ }
+ catch (const Glib::Exception& e)
+ {
+ KLOG_WARNING("%s", e.what().c_str());
+ return EXIT_FAILURE;
+ }
+
+ if (options.show_version)
+ {
+ fmt::print("{0}", PROJECT_VERSION);
+ return EXIT_SUCCESS;
+ }
- Glib::OptionEntry entry2;
- entry2.set_long_name("get-max-brightness-value");
- entry2.set_flags(Glib::OptionEntry::FLAG_NO_ARG);
- entry2.set_description(N_("Get the max brightness value"));
+ if (options.support_backlight)
+ {
+ fmt::print("{0}", backlight_helper.support_backlight() ? 1 : 0);
+ return EXIT_SUCCESS;
+ }
- Glib::OptionEntry entry3;
- entry3.set_long_name("set-brightness-value");
- entry3.set_description(N_("Set the brightness value"));
+ if (options.get_backlight_direcotry)
+ {
+ fmt::print("{0}", backlight_helper.get_backlight_dir());
+ return EXIT_SUCCESS;
+ }
- group.add_entry(entry1, [&backlight_helper](const Glib::ustring& option_name, const Glib::ustring&, bool) -> bool {
+ // 不支持获取和设置则直接返回
+ if (!backlight_helper.support_backlight())
+ {
+ fmt::print(stderr, "{0}", _("No backlights were found on your system"));
+ return EXIT_FAILURE;
+ }
+
+ if (options.get_brightness_value)
+ {
auto brightness_value = backlight_helper.get_brightness_value();
if (brightness_value >= 0)
{
@@ -57,13 +112,14 @@ int main(int argc, char* argv[])
}
else
{
- fmt::print("{0}", _("Could not get the value of the backlight"));
- return false;
+ fmt::print(stderr, "{0}", _("Could not get the value of the backlight"));
+ return EXIT_FAILURE;
}
- return true;
- });
+ return EXIT_SUCCESS;
+ }
- group.add_entry(entry2, [&backlight_helper](const Glib::ustring& option_name, const Glib::ustring&, bool) -> bool {
+ if (options.get_max_brightness_value)
+ {
auto brightness_value = backlight_helper.get_brightness_max_value();
if (brightness_value >= 0)
{
@@ -71,40 +127,21 @@ int main(int argc, char* argv[])
}
else
{
- fmt::print("{0}", _("Could not get the maximum value of the backlight"));
- return false;
+ fmt::print(stderr, "{0}", _("Could not get the maximum value of the backlight"));
+ return EXIT_FAILURE;
}
- return true;
- });
+ return EXIT_SUCCESS;
+ }
- group.add_entry(entry3, [&backlight_helper](const Glib::ustring& option_name, const Glib::ustring& value, bool has_value) -> bool {
+ if (options.set_brightness_value >= 0)
+ {
std::string error;
- auto brightness_value = std::strtol(value.c_str(), nullptr, 0);
- if (!backlight_helper.set_brightness_value(brightness_value, error))
+ if (!backlight_helper.set_brightness_value(options.set_brightness_value, error))
{
- fmt::print("{0}", error);
+ fmt::print(stderr, "{0}", error);
+ return EXIT_FAILURE;
}
- return true;
- });
-
- group.set_translation_domain(GETTEXT_PACKAGE);
- context.set_main_group(group);
-
- // 不支持获取和设置则直接返回
- if (!backlight_helper.support_backlight())
- {
- fmt::print("{0}", _("No backlights were found on your system"));
- return EXIT_FAILURE;
- }
-
- try
- {
- context.parse(argc, argv);
- }
- catch (const Glib::Exception& e)
- {
- KLOG_WARNING("%s", e.what().c_str());
- return EXIT_FAILURE;
+ return EXIT_SUCCESS;
}
return EXIT_SUCCESS;
diff --git a/plugins/power/tools/power-backlight-helper.h b/plugins/power/tools/power-backlight-helper.h
index d7bb069..39bcb03 100644
--- a/plugins/power/tools/power-backlight-helper.h
+++ b/plugins/power/tools/power-backlight-helper.h
@@ -28,6 +28,7 @@ public:
// 是否支持亮度设置
bool support_backlight() { return (this->brightness_value_ >= 0); };
+ std::string get_backlight_dir() { return this->backlight_dir_; };
// 获取亮度值
int32_t get_brightness_value();
--
2.33.0