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