diff --git a/0001-feature-backlight-Support-brightness-modification-by.patch b/0001-feature-backlight-Support-brightness-modification-by.patch new file mode 100644 index 0000000..e6906cb --- /dev/null +++ b/0001-feature-backlight-Support-brightness-modification-by.patch @@ -0,0 +1,1619 @@ +From cc319ca0ff48a1dae64815863092f183e3058a9f Mon Sep 17 00:00:00 2001 +From: tangjie02 +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 +--- + .../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 @@ + + + ++ ++ ++ ++ ++ ++ + + + +@@ -71,7 +77,7 @@ + + + +- 30 ++ 0 + + The scale of the brightness reduction when the display changes dim. Do nothing when the value is 0. + +@@ -111,6 +117,9 @@ + Display options for the notification icon. + + +- ++ ++ 'auto' ++ Set the policy for obtaining brightness values. ++ + + +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 ++ */ ++ ++#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 ++ */ ++ ++#pragma once ++ ++#include ++ ++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>; ++ ++class PowerBacklightMonitors ++{ ++public: ++ PowerBacklightMonitors(){}; ++ virtual ~PowerBacklightMonitors(){}; ++ ++ virtual void init() = 0; ++ ++ // 获取所有显示器亮度设置对象 ++ virtual PowerBacklightAbsoluteVec get_monitors() = 0; ++ virtual sigc::signal signal_monitor_changed() = 0; ++ virtual sigc::signal 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 + */ + +-#include "plugins/power/backlight/power-backlight-monitor-x11.h" +- ++#include "plugins/power/backlight/power-backlight-monitor-x11-atom.h" + #include + + 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 + #include ++#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>; + } // 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 ++ */ ++ ++#include "plugins/power/backlight/power-backlight-monitor-x11-gamma.h" ++ ++#include ++#include ++ ++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 ++ */ ++ ++#pragma once ++ ++#include ++// ++#include ++#include ++ ++#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 + */ + +-#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(); ++ break; ++ case PowerMonitorBacklightPolicy::POWER_MONITOR_BACKLIGHT_POLICY_X11: ++ this->backlight_monitors_ = std::make_shared(); ++ break; ++ default: + { +- this->absolute_monitors_.push_back(std::make_shared()); ++ if (PowerBacklightMonitorsTool::support_backlight()) ++ { ++ this->backlight_monitors_ = std::make_shared(); ++ } ++ else ++ { ++ this->backlight_monitors_ = std::make_shared(); ++ } + } ++ } ++ ++ 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 absolute_monitor, int32_t percentage) ++bool PowerBacklightMonitorsController::set_brightness_percentage(std::shared_ptr 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 absolute_monitor) ++int32_t PowerBacklightMonitorsController::get_brightness_percentage(std::shared_ptr 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 absolute_monitor) ++bool PowerBacklightMonitorsController::brightness_value_up(std::shared_ptr absolute_monitor) + { + int32_t brightness_min = -1; + int32_t brightness_max = -1; +@@ -199,7 +205,7 @@ bool PowerBacklightMonitor::brightness_value_up(std::shared_ptrset_brightness_value(brightness_current_value); + } + +-bool PowerBacklightMonitor::brightness_value_down(std::shared_ptr absolute_monitor) ++bool PowerBacklightMonitorsController::brightness_value_down(std::shared_ptr absolute_monitor) + { + int32_t brightness_min = -1; + int32_t brightness_max = -1; +@@ -216,15 +222,14 @@ bool PowerBacklightMonitor::brightness_value_down(std::shared_ptrset_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 + +-#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 &signal_brightness_changed() override { return this->brightness_changed_; }; + + private: +- void load_absolute_monitors(); ++ void load_backlight_monitors(); + // 设置单个显示器的亮度百分比 + bool set_brightness_percentage(std::shared_ptr 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 backlight_monitors_; + + int32_t brightness_percentage_; + sigc::signal brightness_changed_; ++ ++ Glib::RefPtr 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 ++ */ ++ ++#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()); ++} ++ ++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 &file, ++ const Glib::RefPtr &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 ++ */ ++ ++#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 signal_monitor_changed() { return this->monitor_changed_; }; ++ virtual sigc::signal signal_brightness_changed() { return this->brightness_changed_; }; ++ ++private: ++ std::string get_backlight_dir(); ++ void on_brightness_changed(const Glib::RefPtr &file, ++ const Glib::RefPtr &other_file, ++ Gio::FileMonitorEvent event_type); ++ ++private: ++ sigc::signal monitor_changed_; ++ sigc::signal brightness_changed_; ++ Glib::RefPtr 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 + */ + +-#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(this->backlight_atom_, this->resources_->outputs[i]); ++ std::shared_ptr 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(this->backlight_atom_, this->resources_->outputs[i]); ++ } ++ else ++ { ++ monitor = std::make_shared(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 + */ + +-#include "plugins/power/backlight/power-backlight-monitor-x11.h" ++#include ++// ++#include ++#include ++ ++#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 signal_monitor_changed() { return this->monitor_changed_; }; ++ virtual PowerBacklightAbsoluteVec get_monitors() { return this->backlight_monitors_; } ++ virtual sigc::signal signal_monitor_changed() { return this->monitor_changed_; }; ++ virtual sigc::signal 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 monitor_changed_; ++ sigc::signal monitor_changed_; ++ sigc::signal 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(); ++ this->backlight_monitor_ = std::make_shared(); + this->backlight_kbd_ = std::make_shared(); + } + +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 + diff --git a/kiran-cc-daemon.spec b/kiran-cc-daemon.spec index 24e07ff..7964263 100644 --- a/kiran-cc-daemon.spec +++ b/kiran-cc-daemon.spec @@ -1,6 +1,6 @@ Name: kiran-cc-daemon Version: 2.4.0 -Release: 3 +Release: 4 Summary: DBus daemon for Kiran Desktop License: MulanPSL-2.0 @@ -8,6 +8,7 @@ Source0: %{name}-%{version}.tar.gz Patch0001: 0001-feature-timedate-Delete-timedate_i.h-file.patch Patch0002: 0001-fix-passwd-Fix-password-policy-inconsistencies.patch +Patch0003: 0001-feature-backlight-Support-brightness-modification-by.patch BuildRequires: cmake >= 3.2 @@ -153,7 +154,10 @@ glib-compile-schemas /usr/share/glib-2.0/schemas &> /dev/nulls || : %{_libdir}/pkgconfig/kiran-cc-daemon.pc %changelog -* Tue Nov 15 2022 tangjie02 - 2.3.0-12 +* Wed Dec 07 2022 tangjie02 - 2.4.0-4 +- KYOS-F: Support brightness modification by changing gamma value. + +* Tue Nov 15 2022 tangjie02 - 2.4.0-3 - KYOS-B: Fix password policy inconsistencies.(I60Q7P) * Fri Oct 28 2022 tangjie02 - 2.4.0-2