From 3bedff2a8891bdadcc867d5a84e6d75006090ea3 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Sun, 21 Nov 2021 19:51:48 +0100 Subject: [PATCH] Added 2 new options for BACKLIGHT and DIMMER: 'trans_fixed'. New options let users set a fixed smooth transitions duration; the new options are off by default for now, but are most probably going to be enabled by default as I found that having a fixed transition duration (eg: 1000ms) for any backlight-related update enables a much better (and smooth) user experience. In the event that the new options will be enabled by default, it will be obviously stated in the release notes. For now, I don't really want to break existing configurations (as 'trans_step' and 'trans_timeout' become useless when 'trans_fixed' is enabled. Refs #233 Signed-off-by: Federico Di Pierro --- Extra/clight.conf | 8 +++++++ TODO.md | 1 + src/commons.h | 15 +++++++------ src/conf/config.c | 46 ++++++++++++++++++++++++++++------------ src/conf/opts.c | 42 ++++++++++++++++++------------------ src/modules/backlight.c | 18 +++++++++------- src/modules/dimmer.c | 23 ++++++++++++++------ src/modules/display.c | 25 +++++----------------- src/modules/dpms.c | 5 +++++ src/modules/gamma.c | 2 +- src/modules/interface.c | 2 +- src/public.h | 2 +- src/pubsub/validations.c | 32 ++++++++++++++++++++++++---- src/utils/log.c | 19 ++++++++++------- 14 files changed, 151 insertions(+), 89 deletions(-) diff --git a/Extra/clight.conf b/Extra/clight.conf index 37d5cc2..1fc0fa1 100644 --- a/Extra/clight.conf +++ b/Extra/clight.conf @@ -64,6 +64,10 @@ backlight: ## Transition timeout in ms # trans_timeout = 30; + + ## When > 0, use a fixed transition duration (in ms), + ## overriding trans_timeout and trans_step configs. + # trans_fixed = 1000; ## Timeouts between captures during day/night/event on AC ## Set any of these to <= 0 to disable captures @@ -285,6 +289,10 @@ dimmer: ## Transition timeout in ms. ## Entering dimmed state fade, and leaving fade # trans_timeouts = [ 30, 30 ]; + + ## When > 0, use a fixed transition duration (in ms), + ## for enter or leave, overriding trans_timeouts and trans_steps configs. + # trans_fixed = [ 1000, 1000 ]; ## Timeouts on AC/on BATT. ## Set any of these to <= 0 to disable dimmer diff --git a/TODO.md b/TODO.md index 4b09a7d..1363de8 100644 --- a/TODO.md +++ b/TODO.md @@ -7,6 +7,7 @@ - [x] Always start DISPLAY module - [x] Only hook logind.IdleHint when DIMMER is disabled (otherwise it is a secondary source for DIMMED state...useless) - [x] If DIMMER is disabled but we receive an IdleHint, do not touch backlight; just manage the new DIMMED state eventually pausing backlight and other modules +- [x] Allow to set a fixed transition duration for BACKLIGHT and DIMMER ### Interface - [x] Fixed null ptr dereference in inhibit_parse_msg() diff --git a/src/commons.h b/src/commons.h index e448935..bf5bd48 100644 --- a/src/commons.h +++ b/src/commons.h @@ -35,6 +35,13 @@ typedef struct { double fit_parameters[DEGREE]; // best-fit parameters } curve_t; +typedef struct { + int no_smooth; // disable smooth backlight changes for module + double trans_step; // every backlight transition step value (in pct), used when smooth BACKLIGHT transitions are enabled + int trans_timeout; // every backlight transition timeout value, used when smooth BACKLIGHT transitions are enabled + int trans_fixed; // fixed transitions duration +} bl_smooth_t; + typedef struct { int num_captures[SIZE_AC]; char *dev_name; @@ -46,9 +53,7 @@ typedef struct { typedef struct { int disabled; int timeout[SIZE_AC][SIZE_STATES + 1]; - int no_smooth; // disable smooth backlight changes for BACKLIGHT module - double trans_step; // every backlight transition step value (in pct), used when smooth BACKLIGHT transitions are enabled - int trans_timeout; // every backlight transition timeout value, used when smooth BACKLIGHT transitions are enabled + bl_smooth_t smooth; int no_auto_calib; // disable automatic calibration for both BACKLIGHT and GAMMA 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 @@ -85,9 +90,7 @@ typedef struct { int disabled; double dimmed_pct; // pct of max backlight to be used while dimming int timeout[SIZE_AC]; // dimmer timeout - int no_smooth[SIZE_DIM]; // disable smooth backlight changes for DIMMER module - double trans_step[SIZE_DIM]; // every backlight transition step value (in pct), used when smooth DIMMER transitions are enabled - int trans_timeout[SIZE_DIM]; // every backlight transition timeout value, used when smooth DIMMER transitions are enabled + bl_smooth_t smooth[SIZE_DIM]; } dimmer_conf_t; typedef struct { diff --git a/src/conf/config.c b/src/conf/config.c index 03a8844..fc27088 100644 --- a/src/conf/config.c +++ b/src/conf/config.c @@ -48,9 +48,10 @@ static void load_backlight_settings(config_t *cfg, bl_conf_t *bl_conf) { if (bl) { 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); + config_setting_lookup_bool(bl, "no_smooth_transition", &bl_conf->smooth.no_smooth); + config_setting_lookup_float(bl, "trans_step", &bl_conf->smooth.trans_step); + config_setting_lookup_int(bl, "trans_timeout", &bl_conf->smooth.trans_timeout); + config_setting_lookup_int(bl, "trans_fixed", &bl_conf->smooth.trans_fixed); config_setting_lookup_float(bl, "shutter_threshold", &bl_conf->shutter_threshold); config_setting_lookup_bool(bl, "no_auto_calibration", &bl_conf->no_auto_calib); config_setting_lookup_bool(bl, "pause_on_lid_closed", &bl_conf->pause_on_lid_closed); @@ -289,13 +290,13 @@ static void load_dimmer_settings(config_t *cfg, dimmer_conf_t *dim_conf) { if (dim) { config_setting_lookup_bool(dim, "disabled", &dim_conf->disabled); config_setting_lookup_float(dim, "dimmed_pct", &dim_conf->dimmed_pct); - + config_setting_t *points, *timeouts; /* Load no_smooth_dimmer options */ if ((points = config_setting_get_member(dim, "no_smooth_transition"))) { if (config_setting_length(points) == SIZE_DIM) { for (int i = 0; i < SIZE_DIM; i++) { - dim_conf->no_smooth[i] = config_setting_get_float_elem(points, i); + dim_conf->smooth[i].no_smooth = config_setting_get_float_elem(points, i); } } else { WARN("Wrong number of dimmer 'no_smooth_transition' array elements.\n"); @@ -306,7 +307,7 @@ static void load_dimmer_settings(config_t *cfg, dimmer_conf_t *dim_conf) { if ((points = config_setting_get_member(dim, "trans_steps"))) { if (config_setting_length(points) == SIZE_DIM) { for (int i = 0; i < SIZE_DIM; i++) { - dim_conf->trans_step[i] = config_setting_get_float_elem(points, i); + dim_conf->smooth[i].trans_step = config_setting_get_float_elem(points, i); } } else { WARN("Wrong number of dimmer 'trans_steps' array elements.\n"); @@ -317,13 +318,24 @@ static void load_dimmer_settings(config_t *cfg, dimmer_conf_t *dim_conf) { if ((points = config_setting_get_member(dim, "trans_timeouts"))) { if (config_setting_length(points) == SIZE_DIM) { for (int i = 0; i < SIZE_DIM; i++) { - dim_conf->trans_timeout[i] = config_setting_get_int_elem(points, i); + dim_conf->smooth[i].trans_timeout = config_setting_get_int_elem(points, i); } } else { WARN("Wrong number of dimmer 'trans_timeouts' array elements.\n"); } } + /* Load dimmer_trans_timeouts options */ + if ((points = config_setting_get_member(dim, "trans_fixed"))) { + if (config_setting_length(points) == SIZE_DIM) { + for (int i = 0; i < SIZE_DIM; i++) { + dim_conf->smooth[i].trans_fixed = config_setting_get_int_elem(points, i); + } + } else { + WARN("Wrong number of dimmer 'trans_fixed' array elements.\n"); + } + } + /* Load dimmer timeouts */ if ((timeouts = config_setting_get_member(dim, "timeouts"))) { if (config_setting_length(timeouts) == SIZE_AC) { @@ -434,13 +446,16 @@ static void store_backlight_settings(config_t *cfg, bl_conf_t *bl_conf) { 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); + config_setting_set_bool(setting, bl_conf->smooth.no_smooth); setting = config_setting_add(bl, "trans_step", CONFIG_TYPE_FLOAT); - config_setting_set_float(setting, bl_conf->trans_step); + config_setting_set_float(setting, bl_conf->smooth.trans_step); setting = config_setting_add(bl, "trans_timeout", CONFIG_TYPE_INT); - config_setting_set_int(setting, bl_conf->trans_timeout); + config_setting_set_int(setting, bl_conf->smooth.trans_timeout); + + setting = config_setting_add(bl, "trans_fixed", CONFIG_TYPE_INT); + config_setting_set_int(setting, bl_conf->smooth.trans_fixed); setting = config_setting_add(bl, "no_auto_calibration", CONFIG_TYPE_BOOL); config_setting_set_bool(setting, bl_conf->no_auto_calib); @@ -609,17 +624,22 @@ static void store_dimmer_settings(config_t *cfg, dimmer_conf_t *dim_conf) { setting = config_setting_add(dimmer, "no_smooth_transition", CONFIG_TYPE_ARRAY); for (int i = 0; i < SIZE_DIM; i++) { - config_setting_set_bool_elem(setting, -1, dim_conf->no_smooth[i]); + config_setting_set_bool_elem(setting, -1, dim_conf->smooth[i].no_smooth); } setting = config_setting_add(dimmer, "trans_steps", CONFIG_TYPE_ARRAY); for (int i = 0; i < SIZE_DIM; i++) { - config_setting_set_float_elem(setting, -1, dim_conf->trans_step[i]); + config_setting_set_float_elem(setting, -1, dim_conf->smooth[i].trans_step); } setting = config_setting_add(dimmer, "trans_timeouts", CONFIG_TYPE_ARRAY); for (int i = 0; i < SIZE_DIM; i++) { - config_setting_set_int_elem(setting, -1, dim_conf->trans_timeout[i]); + config_setting_set_int_elem(setting, -1, dim_conf->smooth[i].trans_timeout); + } + + setting = config_setting_add(dimmer, "trans_fixed", CONFIG_TYPE_ARRAY); + for (int i = 0; i < SIZE_DIM; i++) { + config_setting_set_int_elem(setting, -1, dim_conf->smooth[i].trans_fixed); } setting = config_setting_add(dimmer, "dimmed_pct", CONFIG_TYPE_FLOAT); diff --git a/src/conf/opts.c b/src/conf/opts.c index 9c2f14c..b349dea 100644 --- a/src/conf/opts.c +++ b/src/conf/opts.c @@ -42,8 +42,8 @@ static void init_backlight_opts(bl_conf_t *bl_conf) { bl_conf->timeout[ON_BATTERY][DAY] = 2 * conf.bl_conf.timeout[ON_AC][DAY]; bl_conf->timeout[ON_BATTERY][NIGHT] = 2 * conf.bl_conf.timeout[ON_AC][NIGHT]; bl_conf->timeout[ON_BATTERY][IN_EVENT] = 2 * conf.bl_conf.timeout[ON_AC][IN_EVENT]; - bl_conf->trans_step = 0.05; - bl_conf->trans_timeout = 30; + bl_conf->smooth.trans_step = 0.05; + bl_conf->smooth.trans_timeout = 30; } static void init_sens_opts(sensor_conf_t *sens_conf) { @@ -110,10 +110,10 @@ static void init_dimmer_opts(dimmer_conf_t *dim_conf) { dim_conf->timeout[ON_AC] = 45; dim_conf->timeout[ON_BATTERY] = 20; dim_conf->dimmed_pct = 0.2; - dim_conf->trans_step[ENTER] = 0.05; - dim_conf->trans_step[EXIT] = 0.05; - dim_conf->trans_timeout[ENTER] = 30; - dim_conf->trans_timeout[EXIT] = 30; + dim_conf->smooth[ENTER].trans_step = 0.05; + dim_conf->smooth[EXIT].trans_step = 0.05; + dim_conf->smooth[ENTER].trans_timeout = 30; + dim_conf->smooth[EXIT].trans_timeout = 30; } static void init_dpms_opts(dpms_conf_t *dpms_conf) { @@ -170,10 +170,10 @@ static void parse_cmd(int argc, char *const argv[], char *conf_file, size_t size const struct poptOption po[] = { {"frames", 'f', POPT_ARG_INT, NULL, 5, "Frames taken for each capture, Between 1 and 20", NULL}, {"device", 'd', POPT_ARG_STRING, &conf.sens_conf.dev_name, 100, "Path to sensor device. If empty, first matching device is used", "video0"}, - {"no-backlight-smooth", 0, POPT_ARG_NONE, &conf.bl_conf.no_smooth, 100, "Disable smooth backlight transitions", NULL}, + {"no-backlight-smooth", 0, POPT_ARG_NONE, &conf.bl_conf.smooth.no_smooth, 100, "Disable smooth backlight transitions", NULL}, {"no-gamma-smooth", 0, POPT_ARG_NONE, &conf.gamma_conf.no_smooth, 100, "Disable smooth gamma transitions", NULL}, - {"no-dimmer-smooth-enter", 0, POPT_ARG_NONE, &conf.dim_conf.no_smooth[ENTER], 100, "Disable smooth dimmer transitions while entering dimmed state", NULL}, - {"no-dimmer-smooth-exit", 0, POPT_ARG_NONE, &conf.dim_conf.no_smooth[EXIT], 100, "Disable smooth dimmer transitions while leaving dimmed state", NULL}, + {"no-dimmer-smooth-enter", 0, POPT_ARG_NONE, &conf.dim_conf.smooth[ENTER].no_smooth, 100, "Disable smooth dimmer transitions while entering dimmed state", NULL}, + {"no-dimmer-smooth-exit", 0, POPT_ARG_NONE, &conf.dim_conf.smooth[EXIT].no_smooth, 100, "Disable smooth dimmer transitions while leaving dimmed state", NULL}, {"day-temp", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &conf.gamma_conf.temp[DAY], 100, "Daily gamma temperature, between 1000 and 10000", NULL}, {"night-temp", 0, POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &conf.gamma_conf.temp[NIGHT], 100, "Nightly gamma temperature, between 1000 and 10000", NULL}, {"lat", 0, POPT_ARG_DOUBLE, &conf.day_conf.loc.lat, 100, "Your desired latitude", NULL}, @@ -283,14 +283,14 @@ static void check_clightd_features(void) { } static void check_bl_conf(bl_conf_t *bl_conf) { - if (bl_conf->trans_step <= 0.0f || bl_conf->trans_step >= 1.0f) { + if (bl_conf->smooth.trans_step <= 0.0f || bl_conf->smooth.trans_step >= 1.0f) { WARN("Wrong backlight_trans_step value. Resetting default value.\n"); - bl_conf->trans_step = 0.05; + bl_conf->smooth.trans_step = 0.05; } - if (bl_conf->trans_timeout <= 0) { + if (bl_conf->smooth.trans_timeout <= 0) { WARN("Wrong backlight_trans_timeout value. Resetting default value.\n"); - bl_conf->trans_timeout = 30; + bl_conf->smooth.trans_timeout = 30; } if (bl_conf->shutter_threshold < 0 || bl_conf->shutter_threshold >= 1) { @@ -409,22 +409,22 @@ static void check_dim_conf(dimmer_conf_t *dim_conf) { dim_conf->dimmed_pct = 0.2; } - if (dim_conf->trans_step[ENTER] <= 0.0f || dim_conf->trans_step[ENTER] >= 1.0f) { + if (dim_conf->smooth[ENTER].trans_step <= 0.0f || dim_conf->smooth[ENTER].trans_step >= 1.0f) { WARN("Wrong dimmer_trans_step[ENTER] value. Resetting default value.\n"); - dim_conf->trans_step[ENTER] = 0.05; + dim_conf->smooth[ENTER].trans_step = 0.05; } - if (dim_conf->trans_step[EXIT] <= 0.0f || dim_conf->trans_step[EXIT] >= 1.0f) { + if (dim_conf->smooth[EXIT].trans_step <= 0.0f || dim_conf->smooth[EXIT].trans_step >= 1.0f) { WARN("Wrong dimmer_trans_step[EXIT] value. Resetting default value.\n"); - dim_conf->trans_step[EXIT] = 0.05; + dim_conf->smooth[EXIT].trans_step = 0.05; } - if (dim_conf->trans_timeout[ENTER] <= 0) { + if (dim_conf->smooth[ENTER].trans_timeout <= 0) { WARN("Wrong dimmer_trans_timeout[ENTER] value. Resetting default value.\n"); - dim_conf->trans_timeout[ENTER] = 30; + dim_conf->smooth[ENTER].trans_timeout = 30; } - if (dim_conf->trans_timeout[EXIT] <= 0) { + if (dim_conf->smooth[EXIT].trans_timeout <= 0) { WARN("Wrong dimmer_trans_timeout[EXIT] value. Resetting default value.\n"); - dim_conf->trans_timeout[EXIT] = 30; + dim_conf->smooth[EXIT].trans_timeout = 30; } } diff --git a/src/modules/backlight.c b/src/modules/backlight.c index 48f4d58..c62bb15 100644 --- a/src/modules/backlight.c +++ b/src/modules/backlight.c @@ -46,9 +46,10 @@ static const sd_bus_vtable conf_bl_vtable[] = { SD_BUS_WRITABLE_PROPERTY("NoAutoCalib", "b", NULL, set_auto_calib, offsetof(bl_conf_t, no_auto_calib), 0), SD_BUS_WRITABLE_PROPERTY("InhibitOnLidClosed", "b", NULL, NULL, offsetof(bl_conf_t, pause_on_lid_closed), 0), SD_BUS_WRITABLE_PROPERTY("CaptureOnLidOpened", "b", NULL, NULL, offsetof(bl_conf_t, capture_on_lid_opened), 0), - SD_BUS_WRITABLE_PROPERTY("NoSmooth", "b", NULL, NULL, offsetof(bl_conf_t, no_smooth), 0), - SD_BUS_WRITABLE_PROPERTY("TransStep", "d", NULL, NULL, offsetof(bl_conf_t, trans_step), 0), - SD_BUS_WRITABLE_PROPERTY("TransDuration", "i", NULL, NULL, offsetof(bl_conf_t, trans_timeout), 0), + SD_BUS_WRITABLE_PROPERTY("NoSmooth", "b", NULL, NULL, offsetof(bl_conf_t, smooth.no_smooth), 0), + SD_BUS_WRITABLE_PROPERTY("TransStep", "d", NULL, NULL, offsetof(bl_conf_t, smooth.trans_step), 0), + SD_BUS_WRITABLE_PROPERTY("TransDuration", "i", NULL, NULL, offsetof(bl_conf_t, smooth.trans_timeout), 0), + SD_BUS_WRITABLE_PROPERTY("TransFixed", "i", NULL, NULL, offsetof(bl_conf_t, smooth.trans_fixed), 0), SD_BUS_WRITABLE_PROPERTY("ShutterThreshold", "d", NULL, NULL, offsetof(bl_conf_t, shutter_threshold), 0), SD_BUS_WRITABLE_PROPERTY("AcDayTimeout", "i", NULL, set_timeouts, offsetof(bl_conf_t, timeout[ON_AC][DAY]), 0), SD_BUS_WRITABLE_PROPERTY("AcNightTimeout", "i", NULL, set_timeouts, offsetof(bl_conf_t, timeout[ON_AC][NIGHT]), 0), @@ -82,6 +83,7 @@ DECLARE_MSG(amb_msg, AMBIENT_BR_UPD); DECLARE_MSG(capture_req, CAPTURE_REQ); DECLARE_MSG(sens_msg, SENS_UPD); DECLARE_MSG(calib_req, NO_AUTOCALIB_REQ); +DECLARE_MSG(bl_req, BL_REQ); API(Backlight, conf_bl_vtable, conf.bl_conf); API(Sensor, conf_sens_vtable, conf.sens_conf); @@ -92,6 +94,7 @@ static void init(void) { bls = map_new(true, free); capture_req.capture.reset_timer = true; capture_req.capture.capture_only = false; + bl_req.bl.smooth = -1; // Use conf values // Disabled while in wizard mode as it is useless and spams to stdout if (!conf.wizard) { @@ -213,7 +216,7 @@ static void receive_waiting_init(const msg_t *const msg, UNUSED const void* user * Note: set smooth field from conf to allow keyboard and gamma to react; * > if (up->smooth || conf.bl_conf.no_smooth) { ... } */ - set_backlight_level(1.0, !conf.bl_conf.no_smooth, 0, 0); + set_backlight_level(1.0, !conf.bl_conf.smooth.no_smooth, 0, 0); pause_mod(AUTOCALIB); } if (state.lid_state) { @@ -468,10 +471,9 @@ static void do_capture(bool reset_timer, bool capture_only) { static double set_new_backlight(const double perc) { sensor_conf_t *sens_conf = &conf.sens_conf; enum ac_states st = state.ac_state; - const double new_bl_pct = get_value_from_curve(perc, &sens_conf->default_curve[st]); - set_backlight_level(new_bl_pct, !conf.bl_conf.no_smooth, - conf.bl_conf.trans_step, conf.bl_conf.trans_timeout); - return new_bl_pct; + bl_req.bl.new = get_value_from_curve(perc, &sens_conf->default_curve[st]); + M_PUB(&bl_req); + return bl_req.bl.new; } static void publish_bl_upd(const double pct, const bool is_smooth, const double step, const int timeout) { diff --git a/src/modules/dimmer.c b/src/modules/dimmer.c index e783a38..a500fcb 100644 --- a/src/modules/dimmer.c +++ b/src/modules/dimmer.c @@ -1,6 +1,8 @@ #include "idler.h" #include "utils.h" +#define DIMMER_FIXED_STEP 0.01 // Dimmer fixed step is 1% backlight level + static void receive_waiting_acstate(const msg_t *msg, UNUSED const void *userdata); static void receive_paused(const msg_t *const msg, UNUSED const void* userdata); static int on_new_idle(sd_bus_message *m, void *userdata, sd_bus_error *ret_error); @@ -11,19 +13,22 @@ static sd_bus_slot *slot; static char client[PATH_MAX + 1]; static const sd_bus_vtable conf_dimmer_vtable[] = { SD_BUS_VTABLE_START(0), - SD_BUS_WRITABLE_PROPERTY("NoSmoothEnter", "b", NULL, NULL, offsetof(dimmer_conf_t, no_smooth[ENTER]), 0), - SD_BUS_WRITABLE_PROPERTY("NoSmoothExit", "b", NULL, NULL, offsetof(dimmer_conf_t, no_smooth[EXIT]), 0), + SD_BUS_WRITABLE_PROPERTY("NoSmoothEnter", "b", NULL, NULL, offsetof(dimmer_conf_t, smooth[ENTER].no_smooth), 0), + SD_BUS_WRITABLE_PROPERTY("NoSmoothExit", "b", NULL, NULL, offsetof(dimmer_conf_t, smooth[EXIT].no_smooth), 0), SD_BUS_WRITABLE_PROPERTY("DimmedPct", "d", NULL, NULL, offsetof(dimmer_conf_t, dimmed_pct), 0), - SD_BUS_WRITABLE_PROPERTY("TransStepEnter", "d", NULL, NULL, offsetof(dimmer_conf_t, trans_step[ENTER]), 0), - SD_BUS_WRITABLE_PROPERTY("TransStepExit", "d", NULL, NULL, offsetof(dimmer_conf_t, trans_step[EXIT]), 0), - SD_BUS_WRITABLE_PROPERTY("TransDurationEnter", "i", NULL, NULL, offsetof(dimmer_conf_t, trans_timeout[ENTER]), 0), - SD_BUS_WRITABLE_PROPERTY("TransDurationExit", "i", NULL, NULL, offsetof(dimmer_conf_t, trans_timeout[EXIT]), 0), + SD_BUS_WRITABLE_PROPERTY("TransStepEnter", "d", NULL, NULL, offsetof(dimmer_conf_t, smooth[ENTER].trans_step), 0), + SD_BUS_WRITABLE_PROPERTY("TransStepExit", "d", NULL, NULL, offsetof(dimmer_conf_t, smooth[EXIT].trans_step), 0), + SD_BUS_WRITABLE_PROPERTY("TransDurationEnter", "i", NULL, NULL, offsetof(dimmer_conf_t, smooth[ENTER].trans_timeout), 0), + SD_BUS_WRITABLE_PROPERTY("TransDurationExit", "i", NULL, NULL, offsetof(dimmer_conf_t, smooth[EXIT].trans_timeout), 0), + SD_BUS_WRITABLE_PROPERTY("TransFixedEnter", "i", NULL, NULL, offsetof(dimmer_conf_t, smooth[ENTER].trans_fixed), 0), + SD_BUS_WRITABLE_PROPERTY("TransFixedExit", "i", NULL, NULL, offsetof(dimmer_conf_t, smooth[EXIT].trans_fixed), 0), SD_BUS_WRITABLE_PROPERTY("AcTimeout", "i", NULL, set_timeouts, offsetof(dimmer_conf_t, timeout[ON_AC]), 0), SD_BUS_WRITABLE_PROPERTY("BattTimeout", "i", NULL, set_timeouts, offsetof(dimmer_conf_t, timeout[ON_BATTERY]), 0), SD_BUS_VTABLE_END }; DECLARE_MSG(display_req, DISPLAY_REQ); +DECLARE_MSG(bl_req, BL_REQ); API(Dimmer, conf_dimmer_vtable, conf.dim_conf); MODULE_WITH_PAUSE("DIMMER"); @@ -167,3 +172,9 @@ static void pause_dimmer(const bool pause, enum mod_pause reason) { } } } + +void dimmer_publish_bl_req(const double pct, enum dim_trans trans) { + bl_req.bl.new = pct; + bl_req.bl.smooth = -2 - trans; + M_PUB(&bl_req); +} diff --git a/src/modules/display.c b/src/modules/display.c index 29287fc..ab69278 100644 --- a/src/modules/display.c +++ b/src/modules/display.c @@ -3,17 +3,17 @@ static int hook_logind_idle_signal(void); static int on_idle_hint_changed(sd_bus_message *m, UNUSED void *userdata, UNUSED sd_bus_error *ret_error); -static void publish_bl_req(const double pct, const bool smooth, const double step, const int to); -static void set_dpms(bool enable); static sd_bus_slot *slot; DECLARE_MSG(display_msg, DISPLAY_UPD); -DECLARE_MSG(bl_req, BL_REQ); DECLARE_MSG(display_req, DISPLAY_REQ); MODULE("DISPLAY"); +extern void dimmer_publish_bl_req(const double pct, enum dim_trans trans); +extern void set_dpms(bool enable); + static void init(void) { M_SUB(DISPLAY_REQ); @@ -57,8 +57,7 @@ static void receive(const msg_t *const msg, UNUSED const void* userdata) { // Message arrives from DIMMER module (or external plugin) if (state.current_bl_pct > conf.dim_conf.dimmed_pct) { old_pct = state.current_bl_pct; - publish_bl_req(conf.dim_conf.dimmed_pct, !conf.dim_conf.no_smooth[ENTER], - conf.dim_conf.trans_step[ENTER], conf.dim_conf.trans_timeout[ENTER]); + dimmer_publish_bl_req(conf.dim_conf.dimmed_pct, ENTER); } else { DEBUG("A lower than dimmer_pct backlight level is already set. Avoid changing it.\n"); } @@ -79,8 +78,7 @@ static void receive(const msg_t *const msg, UNUSED const void* userdata) { state.display_state &= ~DISPLAY_DIMMED; DEBUG("Leaving dimmed state...\n"); if (msg->ps_msg->sender != self() && old_pct >= 0.0) { - publish_bl_req(old_pct, !conf.dim_conf.no_smooth[EXIT], - conf.dim_conf.trans_step[EXIT], conf.dim_conf.trans_timeout[EXIT]); + dimmer_publish_bl_req(old_pct, EXIT); old_pct = -1.0; } } @@ -129,16 +127,3 @@ static int on_idle_hint_changed(sd_bus_message *m, UNUSED void *userdata, UNUSED M_PUB(&display_req); return 0; } - -static void publish_bl_req(const double pct, const bool smooth, const double step, const int to) { - bl_req.bl.new = pct; - bl_req.bl.smooth = smooth; - bl_req.bl.step = step; - bl_req.bl.timeout = to; - M_PUB(&bl_req); -} - -static void set_dpms(bool enable) { - SYSBUS_ARG(args, CLIGHTD_SERVICE, "/org/clightd/clightd/Dpms", "org.clightd.clightd.Dpms", "Set"); - call(&args, "ssi", fetch_display(), fetch_env(), enable); -} diff --git a/src/modules/dpms.c b/src/modules/dpms.c index 8430498..aab9d7b 100644 --- a/src/modules/dpms.c +++ b/src/modules/dpms.c @@ -180,3 +180,8 @@ static void pause_dpms(const bool pause, enum mod_pause reason) { } } } + +void set_dpms(bool enable) { + SYSBUS_ARG(args, CLIGHTD_SERVICE, "/org/clightd/clightd/Dpms", "org.clightd.clightd.Dpms", "Set"); + call(&args, "ssi", fetch_display(), fetch_env(), enable); +} diff --git a/src/modules/gamma.c b/src/modules/gamma.c index ee63ae5..f6f23d4 100644 --- a/src/modules/gamma.c +++ b/src/modules/gamma.c @@ -233,7 +233,7 @@ static void set_temp(int temp, const time_t *now, int smooth, int step, int time static void ambient_callback(bool smooth, double new) { if (conf.gamma_conf.ambient_gamma && !state.display_state) { /* Only account for target backlight changes, ie: not step ones */ - if (smooth || conf.bl_conf.no_smooth) { + if (smooth || conf.bl_conf.smooth.no_smooth) { /* * Note that conf.temp is not constant (it can be changed through bus api), * thus we have to always compute these ones. diff --git a/src/modules/interface.c b/src/modules/interface.c index 6ccc6e3..7f5d51e 100644 --- a/src/modules/interface.c +++ b/src/modules/interface.c @@ -646,7 +646,7 @@ int set_location(sd_bus *bus, const char *path, const char *interface, const cha // Keep conf updated memcpy(&conf.day_conf.loc, &loc_req.loc.new, sizeof(loc_t)); - DEBUG("New location from BUS api: %.2lf %.2lf\n", loc_req.loc.new.lat, loc_req.loc.new.lat); + DEBUG("New location from BUS api: %.2lf %.2lf\n", loc_req.loc.new.lat, loc_req.loc.new.lon); M_PUB(&loc_req); return r; } diff --git a/src/public.h b/src/public.h index 93429f0..9c1d4b4 100644 --- a/src/public.h +++ b/src/public.h @@ -213,7 +213,7 @@ typedef struct { typedef struct { double old; // Valued in updates. Useless for requests double new; // Mandatory for requests. Valued in updates - int smooth; // Mandatory for BL_REQ requests. Valued in updates. Special value: -1 -> use conf values + int smooth; // Mandatory for BL_REQ requests. Valued in updates. Special values: -1 -> use backlight conf values; -2/-3 -> use dimmer {ENTER, EXIT} conf values int timeout; // Only useful for BL_REQ requests. Valued in updates double step; // Only useful for BL_REQ requests. Valued in updates } bl_upd; diff --git a/src/pubsub/validations.c b/src/pubsub/validations.c index 5bad0a4..4d129b7 100644 --- a/src/pubsub/validations.c +++ b/src/pubsub/validations.c @@ -1,6 +1,8 @@ #include "validations.h" #include "my_math.h" +#define BL_FIXED_STEP 0.01 // Backlight fixed step is 1% backlight level + bool validate_loc(loc_upd *up) { if (fabs(up->new.lat) < 90.0f && fabs(up->new.lon) < 180.0f && get_distance(&up->new, &state.current_loc) >= LOC_DISTANCE_THRS) { @@ -115,10 +117,32 @@ bool validate_curve(curve_upd *up) { } bool validate_backlight(bl_upd *up) { - if (up->smooth == -1) { - up->smooth = !conf.bl_conf.no_smooth; - up->step = conf.bl_conf.trans_step; - up->timeout = conf.bl_conf.trans_timeout; + bl_smooth_t *smooth = NULL; + switch (up->smooth) { + case -1: + smooth = &conf.bl_conf.smooth; + break; + case -2: + smooth = &conf.dim_conf.smooth[ENTER]; + break; + case -3: + smooth = &conf.dim_conf.smooth[EXIT]; + break; + default: + break; + } + + if (smooth) { + up->smooth = !smooth->no_smooth; + if (smooth->trans_fixed <= 0) { + up->step = smooth->trans_step; + up->timeout = smooth->trans_timeout; + } else { + up->step = BL_FIXED_STEP; + double pct_diff = fabs(state.current_bl_pct - up->new); + double n_steps = pct_diff / up->step; + up->timeout = smooth->trans_fixed / n_steps; + } } if (up->new >= 0.0 && up->new <= 1.0) { diff --git a/src/utils/log.c b/src/utils/log.c index 8aa84ac..267febe 100644 --- a/src/utils/log.c +++ b/src/utils/log.c @@ -2,6 +2,7 @@ #include #include "commons.h" +static void log_bl_smooth(bl_smooth_t *smooth, const char *prefix); static void log_bl_conf(bl_conf_t *bl_conf); static void log_sens_conf(sensor_conf_t *sens_conf); static void log_kbd_conf(kbd_conf_t *kbd_conf); @@ -41,11 +42,16 @@ void open_log(void) { ftruncate(fd, 0); } +static void log_bl_smooth(bl_smooth_t *smooth, const char *prefix) { + fprintf(log_file, "* %sSmooth trans:\t\t%s\n", prefix, smooth->no_smooth ? "Disabled" : "Enabled"); + fprintf(log_file, "* %sSmooth step:\t\t%.2lf\n", prefix, smooth->trans_step); + fprintf(log_file, "* %sSmooth timeout:\t\t%d\n", prefix, smooth->trans_timeout); + fprintf(log_file, "* %sSmooth fixed:\t\t%d\n", prefix, smooth->trans_fixed); +} + static void log_bl_conf(bl_conf_t *bl_conf) { fprintf(log_file, "\n### BACKLIGHT ###\n"); - fprintf(log_file, "* Smooth trans:\t\t%s\n", bl_conf->no_smooth ? "Disabled" : "Enabled"); - fprintf(log_file, "* Smooth steps:\t\t%.2lf\n", bl_conf->trans_step); - fprintf(log_file, "* Smooth timeout:\t\t%d\n", bl_conf->trans_timeout); + log_bl_smooth(&conf.bl_conf.smooth, ""); fprintf(log_file, "* Daily timeouts:\t\tAC %d\tBATT %d\n", bl_conf->timeout[ON_AC][DAY], bl_conf->timeout[ON_BATTERY][DAY]); fprintf(log_file, "* Nightly timeouts:\t\tAC %d\tBATT %d\n", bl_conf->timeout[ON_AC][NIGHT], bl_conf->timeout[ON_BATTERY][NIGHT]); fprintf(log_file, "* Event timeouts:\t\tAC %d\tBATT %d\n", bl_conf->timeout[ON_AC][SIZE_STATES], bl_conf->timeout[ON_BATTERY][SIZE_STATES]); @@ -97,11 +103,8 @@ static void log_daytime_conf(daytime_conf_t *day_conf) { static void log_dim_conf(dimmer_conf_t *dim_conf) { fprintf(log_file, "\n### DIMMER ###\n"); - fprintf(log_file, "* Smooth trans:\t\tENTER: %s, EXIT: %s\n", - dim_conf->no_smooth[ENTER] ? "Disabled" : "Enabled", - dim_conf->no_smooth[EXIT] ? "Disabled" : "Enabled"); - fprintf(log_file, "* Smooth steps:\t\tENTER: %.2lf, EXIT: %.2lf\n", dim_conf->trans_step[ENTER], dim_conf->trans_step[EXIT]); - fprintf(log_file, "* Smooth timeout:\t\tENTER: %d, EXIT: %d\n", dim_conf->trans_timeout[ENTER], dim_conf->trans_timeout[EXIT]); + log_bl_smooth(&conf.dim_conf.smooth[ENTER], "ENTER "); + log_bl_smooth(&conf.dim_conf.smooth[EXIT], "EXIT "); fprintf(log_file, "* Timeouts:\t\tAC %d\tBATT %d\n", dim_conf->timeout[ON_AC], dim_conf->timeout[ON_BATTERY]); fprintf(log_file, "* Backlight pct:\t\t%.2lf\n", dim_conf->dimmed_pct); }