From ee220be3efaa805d1096fa0dd5f9400cc9a6ee12 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Wed, 14 Jul 2021 22:53:31 +0200 Subject: [PATCH] Added options to restore screen backlight and temperature upon clight exit. Fixes #213. --- Extra/clight.conf | 6 +++ TODO.md | 8 +++- src/commons.h | 2 + src/conf/config.c | 8 ++++ src/modules/backlight.c | 88 +++++++++++++++++++++++++++-------------- src/modules/gamma.c | 15 ++++++- src/modules/interface.c | 2 + src/utils/log.c | 2 + 8 files changed, 100 insertions(+), 31 deletions(-) diff --git a/Extra/clight.conf b/Extra/clight.conf index 06325b5..4b3485a 100644 --- a/Extra/clight.conf +++ b/Extra/clight.conf @@ -52,6 +52,9 @@ backlight: { ## Uncomment to disable # disabled = true; + + ## Uncomment to restore screen backlight on exit + # restore_on_exit = true; ## Uncomment to disable smooth transitions # no_smooth_transition = true; @@ -187,6 +190,9 @@ gamma: { ## Uncomment to disable gamma tool # disabled = true; + + ## Uncomment to restore screen temperature on exit + # restore_on_exit = true; ## Uncomment to disable gamma smooth transitions # no_smooth_transition = true; diff --git a/TODO.md b/TODO.md index 961d41b..6bdc970 100644 --- a/TODO.md +++ b/TODO.md @@ -12,15 +12,21 @@ - [x] Implement StoreCurveConf - [x] Fixed StoreCurveConf -- [x] Fix bug in lid state initialization +- [x] Allow to automatically restore screen backlight upon clight exit ### Inhibit - [x] Add back inhibit_bl conf value - [x] Add a conf opt to disable inhibit module +### Upower +- [x] Fix bug in lid state initialization + ### Conf - [x] Properly dump "disabled" bool in StoreConf for each module +### Gamma +- [x] Allow to automatically restore screen temperature upon clight exit + ## 5.x - [ ] Port to libmodule 6.0.0 (?) - [ ] Add a Dump dbus method (and a DUMP_REQ request) to allow any module to dump their state (module_dump()) to a txt file diff --git a/src/commons.h b/src/commons.h index 5068b62..2009c07 100644 --- a/src/commons.h +++ b/src/commons.h @@ -54,6 +54,7 @@ typedef struct { double shutter_threshold; // capture values below this threshold will be considered "shuttered" int pause_on_lid_closed; // whether clight should inhibit autocalibration on lid closed int capture_on_lid_opened; // whether to trigger a new capture whenever lid gets opened + int restore; // whether backlight should be restored on Clight exit } bl_conf_t; typedef struct { @@ -71,6 +72,7 @@ typedef struct { int trans_timeout; // every gamma transition timeout value, used when smooth GAMMA transitions are enabled int long_transition; // flag to enable a very long smooth transition for gamma (redshift-like) int ambient_gamma; // enable gamma adjustments based on ambient backlight + int restore; // whether gamma should be restored on Clight exit } gamma_conf_t; typedef struct { diff --git a/src/conf/config.c b/src/conf/config.c index 58c5ec6..ad78bea 100644 --- a/src/conf/config.c +++ b/src/conf/config.c @@ -48,6 +48,7 @@ static void load_backlight_settings(config_t *cfg, bl_conf_t *bl_conf) { if (bl) { const char *screendev; config_setting_lookup_bool(bl, "disabled", &bl_conf->disabled); + config_setting_lookup_bool(bl, "restore_on_exit", &bl_conf->restore); config_setting_lookup_bool(bl, "no_smooth_transition", &bl_conf->no_smooth); config_setting_lookup_float(bl, "trans_step", &bl_conf->trans_step); config_setting_lookup_int(bl, "trans_timeout", &bl_conf->trans_timeout); @@ -225,6 +226,7 @@ static void load_gamma_settings(config_t *cfg, gamma_conf_t *gamma_conf) { config_setting_t *gamma = config_lookup(cfg, "gamma"); if (gamma) { config_setting_lookup_bool(gamma, "disabled", &gamma_conf->disabled); + config_setting_lookup_bool(gamma, "restore_on_exit", &gamma_conf->restore); config_setting_lookup_bool(gamma, "no_smooth_transition", &gamma_conf->no_smooth); config_setting_lookup_int(gamma, "trans_step", &gamma_conf->trans_step); config_setting_lookup_int(gamma, "trans_timeout", &gamma_conf->trans_timeout); @@ -407,6 +409,9 @@ static void store_backlight_settings(config_t *cfg, bl_conf_t *bl_conf) { config_setting_t *setting = config_setting_add(bl, "disabled", CONFIG_TYPE_BOOL); config_setting_set_bool(setting, bl_conf->disabled); + setting = config_setting_add(bl, "restore_on_exit", CONFIG_TYPE_BOOL); + config_setting_set_bool(setting, bl_conf->restore); + setting = config_setting_add(bl, "no_smooth_transition", CONFIG_TYPE_BOOL); config_setting_set_bool(setting, bl_conf->no_smooth); @@ -521,6 +526,9 @@ static void store_gamma_settings(config_t *cfg, gamma_conf_t *gamma_conf) { config_setting_t *setting = config_setting_add(gamma, "disabled", CONFIG_TYPE_BOOL); config_setting_set_bool(setting, gamma_conf->disabled); + setting = config_setting_add(gamma, "restore_on_exit", CONFIG_TYPE_BOOL); + config_setting_set_bool(setting, gamma_conf->restore); + setting = config_setting_add(gamma, "no_smooth_transition", CONFIG_TYPE_BOOL); config_setting_set_bool(setting, gamma_conf->no_smooth); diff --git a/src/modules/backlight.c b/src/modules/backlight.c index 3e68c78..166aba5 100644 --- a/src/modules/backlight.c +++ b/src/modules/backlight.c @@ -12,6 +12,7 @@ static double get_value_from_curve(const double perc, curve_t *curve); static double set_new_backlight(const double perc); static void publish_bl_upd(const double pct, const bool is_smooth, const double step, const int timeout); static int get_and_set_each_brightness(const double pct, const bool is_smooth, const double step, const int timeout); +static void set_each_brightness(sd_bus_message *m, double pct, const bool is_smooth, const double step, const int timeout); static void set_backlight_level(const double pct, const bool is_smooth, const double step, const int timeout); static int capture_frames_brightness(void); static void upower_callback(void); @@ -30,6 +31,7 @@ static void on_lid_update(void); static void pause_mod(enum mod_pause type); static void resume_mod(enum mod_pause type); +static sd_bus_message *restore_m = NULL; static int bl_fd = -1; static sd_bus_slot *sens_slot, *bl_slot; static char *backlight_interface; @@ -62,6 +64,10 @@ static void init(void) { M_SUB(BL_REQ); M_SUB(INHIBIT_UPD); m_become(waiting_init); + + // Store current backlight to later restore them if requested + SYSBUS_ARG_REPLY(args, parse_bus_reply, &restore_m, CLIGHTD_SERVICE, "/org/clightd/clightd/Backlight", "org.clightd.clightd.Backlight", "GetAll"); + call(&args, "s", conf.bl_conf.screen_path); } static bool check(void) { @@ -82,6 +88,9 @@ static void destroy(void) { if (bl_fd >= 0) { close(bl_fd); } + if (restore_m) { + sd_bus_message_unrefp(&restore_m); + } free(backlight_interface); free(conf.bl_conf.screen_path); free(conf.sens_conf.dev_name); @@ -221,6 +230,12 @@ static void receive(const msg_t *const msg, UNUSED const void* userdata) { } break; } + case SYSTEM_UPD: + if (msg->ps_msg->type == LOOP_STOPPED && restore_m && conf.bl_conf.restore) { + set_each_brightness(restore_m, 0, false, 0, 0); + restore_m = NULL; + } + break; default: break; } @@ -286,6 +301,12 @@ static void receive_paused(const msg_t *const msg, UNUSED const void* userdata) } break; } + case SYSTEM_UPD: + if (msg->ps_msg->type == LOOP_STOPPED && restore_m && conf.bl_conf.restore) { + set_each_brightness(restore_m, 0, false, 0, 0); + restore_m = NULL; + } + break; default: break; } @@ -413,47 +434,56 @@ static void publish_bl_upd(const double pct, const bool is_smooth, const double * otherwise just sets requested backlight level (just like a SetAll) */ static int get_and_set_each_brightness(const double pct, const bool is_smooth, const double step, const int timeout) { - sensor_conf_t *sens_conf = &conf.sens_conf; - enum ac_states st = state.ac_state; - /* Get all monitors backlight; we just need to map each monitor to its specific curve indeed */ // TODO: when clightd will use different object paths for each monitor, just enumerate paths here! sd_bus_message *m = NULL; SYSBUS_ARG_REPLY(args, parse_bus_reply, &m, CLIGHTD_SERVICE, "/org/clightd/clightd/Backlight", "org.clightd.clightd.Backlight", "GetAll"); int r = call(&args, "s", conf.bl_conf.screen_path); if (r >= 0) { - r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sd)"); - while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sd") >= 0) && r >= 0) { - const char *mon_id = NULL; + set_each_brightness(m, pct, is_smooth, step, timeout); + } + return r; +} + +static void set_each_brightness(sd_bus_message *m, double pct, const bool is_smooth, const double step, const int timeout) { + const bool restoring = pct == 0; + sensor_conf_t *sens_conf = &conf.sens_conf; + enum ac_states st = state.ac_state; + + int r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sd)"); + while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sd") >= 0) && r >= 0) { + const char *mon_id = NULL; + if (!restoring) { r = sd_bus_message_read(m, "sd", &mon_id, NULL); - sd_bus_message_exit_container(m); + } else { + r = sd_bus_message_read(m, "sd", &mon_id, &pct); + } + sd_bus_message_exit_container(m); - if (r >= 0 && mon_id) { - int ok = true; + if (r >= 0 && mon_id) { + int ok = true; - /* Set backlight on monitor id */ - SYSBUS_ARG_REPLY(args, parse_bus_reply, &ok, CLIGHTD_SERVICE, "/org/clightd/clightd/Backlight", "org.clightd.clightd.Backlight", "Set"); - curve_t *c = map_get(sens_conf->specific_curves, mon_id); - if (c) { - /* Use monitor specific adjustment, properly scaling bl pct */ - int num_points = c[st].num_points; - const double real_pct = get_value_from_curve(pct * (num_points - 1), &c[st]); - DEBUG("Using specific curve for '%s': setting %.3lf pct.\n", mon_id, real_pct); - r = call(&args, "d(bdu)s", real_pct, is_smooth, step, timeout, mon_id); - } else { - DEBUG("Using default curve for '%s'\n", mon_id); - /* Use non-adjusted (default) curve value */ - r = call(&args, "d(bdu)s", pct, is_smooth, step, timeout, mon_id); - } - if (!ok) { - r = -1; - } + /* Set backlight on monitor id */ + SYSBUS_ARG_REPLY(args, parse_bus_reply, &ok, CLIGHTD_SERVICE, "/org/clightd/clightd/Backlight", "org.clightd.clightd.Backlight", "Set"); + curve_t *c = map_get(sens_conf->specific_curves, mon_id); + if (c && !restoring) { + /* Use monitor specific adjustment, properly scaling bl pct */ + int num_points = c[st].num_points; + const double real_pct = get_value_from_curve(pct * (num_points - 1), &c[st]); + DEBUG("Using specific curve for '%s': setting %.3lf pct.\n", mon_id, real_pct); + r = call(&args, "d(bdu)s", real_pct, is_smooth, step, timeout, mon_id); + } else { + DEBUG("Using default curve for '%s'\n", mon_id); + /* Use non-adjusted (default) curve value */ + r = call(&args, "d(bdu)s", pct, is_smooth, step, timeout, mon_id); + } + if (!ok) { + r = -1; } } - sd_bus_message_exit_container(m); - sd_bus_message_unref(m); } - return r; + sd_bus_message_exit_container(m); + sd_bus_message_unref(m); } static void set_backlight_level(const double pct, const bool is_smooth, const double step, const int timeout) { diff --git a/src/modules/gamma.c b/src/modules/gamma.c index 2cd648b..50c1ad5 100644 --- a/src/modules/gamma.c +++ b/src/modules/gamma.c @@ -16,6 +16,7 @@ static void interface_callback(temp_upd *req); static int on_temp_changed(sd_bus_message *m, void *userdata, sd_bus_error *ret_error); static void pause_mod(bool pause, enum mod_pause reason); +static int initial_temp; static sd_bus_slot *slot; static bool long_transitioning, should_sync_temp; static const self_t *daytime_ref; @@ -31,6 +32,10 @@ static void init(void) { M_SUB(NEXT_DAYEVT_UPD); M_SUB(SUSPEND_UPD); m_become(waiting_daytime); + + // Store current temperature to later restore it if requested + SYSBUS_ARG_REPLY(args, parse_bus_reply, &initial_temp, CLIGHTD_SERVICE, "/org/clightd/clightd/Gamma", "org.clightd.clightd.Gamma", "Get"); + call(&args, "ss", fetch_display(), fetch_env()); } static bool check(void) { @@ -102,6 +107,11 @@ static void receive(const msg_t *const msg, UNUSED const void* userdata) { case SUSPEND_UPD: pause_mod(state.suspended, SUSPEND); break; + case SYSTEM_UPD: + if (msg->ps_msg->type == LOOP_STOPPED && initial_temp && conf.gamma_conf.restore) { + set_temp(initial_temp, NULL, false, 0, 0); + } + break; default: break; } @@ -145,7 +155,10 @@ static void publish_temp_upd(int temp, int smooth, int step, int timeout) { } static int parse_bus_reply(sd_bus_message *reply, const char *member, void *userdata) { - return sd_bus_message_read(reply, "b", userdata); + if (!strcmp(member, "Get")) { + return sd_bus_message_read(reply, "i", userdata); + } + return sd_bus_message_read(reply, "b", userdata); } static void set_temp(int temp, const time_t *now, int smooth, int step, int timeout) { diff --git a/src/modules/interface.c b/src/modules/interface.c index 66d57ee..9aaea62 100644 --- a/src/modules/interface.c +++ b/src/modules/interface.c @@ -123,6 +123,7 @@ static const sd_bus_vtable conf_bl_vtable[] = { SD_BUS_WRITABLE_PROPERTY("BattDayTimeout", "i", NULL, set_timeouts, offsetof(bl_conf_t, timeout[ON_BATTERY][DAY]), 0), SD_BUS_WRITABLE_PROPERTY("BattNightTimeout", "i", NULL, set_timeouts, offsetof(bl_conf_t, timeout[ON_BATTERY][NIGHT]), 0), SD_BUS_WRITABLE_PROPERTY("BattEventTimeout", "i", NULL, set_timeouts, offsetof(bl_conf_t, timeout[ON_BATTERY][IN_EVENT]), 0), + SD_BUS_WRITABLE_PROPERTY("RestoreOnExit", "b", NULL, NULL, offsetof(bl_conf_t, restore), 0), SD_BUS_VTABLE_END }; @@ -155,6 +156,7 @@ static const sd_bus_vtable conf_gamma_vtable[] = { SD_BUS_WRITABLE_PROPERTY("DayTemp", "i", NULL, set_gamma, offsetof(gamma_conf_t, temp[DAY]), 0), SD_BUS_WRITABLE_PROPERTY("NightTemp", "i", NULL, set_gamma, offsetof(gamma_conf_t, temp[NIGHT]), 0), SD_BUS_WRITABLE_PROPERTY("LongTransition", "b", NULL, NULL, offsetof(gamma_conf_t, long_transition), 0), + SD_BUS_WRITABLE_PROPERTY("RestoreOnExit", "b", NULL, NULL, offsetof(gamma_conf_t, restore), 0), SD_BUS_VTABLE_END }; diff --git a/src/utils/log.c b/src/utils/log.c index e989084..ddb3b38 100644 --- a/src/utils/log.c +++ b/src/utils/log.c @@ -54,6 +54,7 @@ static void log_bl_conf(bl_conf_t *bl_conf) { fprintf(log_file, "* Autocalibration:\t\t%s\n", bl_conf->no_auto_calib ? "Disabled" : "Enabled"); fprintf(log_file, "* Pause on lid closed:\t\t%s\n", bl_conf->pause_on_lid_closed ? "Enabled" : "Disabled"); fprintf(log_file, "* Capture on lid opened:\t\t%s\n", bl_conf->capture_on_lid_opened ? "Enabled" : "Disabled"); + fprintf(log_file, "* Restore On Exit:\t\t%s\n", bl_conf->restore ? "Enabled" : "Disabled"); } static void log_sens_conf(sensor_conf_t *sens_conf) { @@ -79,6 +80,7 @@ static void log_gamma_conf(gamma_conf_t *gamma_conf) { fprintf(log_file, "* Nightly screen temp:\t\t%d\n", gamma_conf->temp[NIGHT]); fprintf(log_file, "* Long transition:\t\t%s\n", gamma_conf->long_transition ? "Enabled" : "Disabled"); fprintf(log_file, "* Ambient gamma:\t\t%s\n", gamma_conf->ambient_gamma ? "Enabled" : "Disabled"); + fprintf(log_file, "* Restore On Exit:\t\t%s\n", gamma_conf->restore ? "Enabled" : "Disabled"); } static void log_daytime_conf(daytime_conf_t *day_conf) {