From 494a804a08dac1ab5b2c79650a9bbb0924b59b4e Mon Sep 17 00:00:00 2001 From: andeston <17421805+andeston@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:32:29 -0500 Subject: [PATCH 1/3] Moved `PLUS` and `MINUS` into `delta_type` --- brightnessctl.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/brightnessctl.c b/brightnessctl.c index 52e17ed..c58a77f 100644 --- a/brightnessctl.c +++ b/brightnessctl.c @@ -76,8 +76,7 @@ struct device { }; enum value_type { ABSOLUTE, RELATIVE }; -enum delta_type { DIRECT, DELTA }; -enum sign { PLUS, MINUS }; +enum delta_type { DIRECT, PLUS, MINUS }; struct value { union { @@ -86,7 +85,6 @@ struct value { }; enum value_type v_type; enum delta_type d_type; - enum sign sign; }; enum operation { INFO, GET, MAX, SET, RESTORE }; @@ -138,7 +136,7 @@ int main(int argc, char **argv) { int ret = 0; int n, c, phelp = 0; p.exponent = 1; - p.min = (struct value){ .val = 0, .v_type = ABSOLUTE, .d_type = DIRECT, .sign = PLUS }; + p.min = (struct value){ .val = 0, .v_type = ABSOLUTE, .d_type = DIRECT }; while ((c = getopt_long(argc, argv, "lqpmPn::e::srhVc:d:", options, NULL)) >= 0) { switch (c) { case 'l': @@ -164,10 +162,10 @@ int main(int argc, char **argv) { break; case 'n': if (optarg) { - if (!parse_value(&p.min, optarg) || p.min.sign == MINUS) + if (!parse_value(&p.min, optarg) || p.min.d_type == MINUS) fail("Invalid min-value given\n"); } else if (NULL != argv[optind] && '-' != argv[optind][0]) { - if (!parse_value(&p.min, argv[optind++]) || p.min.sign == MINUS) + if (!parse_value(&p.min, argv[optind++]) || p.min.d_type == MINUS) fail("Invalid min-value given\n"); } else { p.min.val = 1; @@ -325,12 +323,10 @@ bool parse_value(struct value *val, char *str) { errno = 0; val->v_type = ABSOLUTE; val->d_type = DIRECT; - val->sign = PLUS; if (!str || !*str) return false; if (*str == '+' || *str == '-') { - val->sign = *str == '+' ? PLUS : MINUS; - val->d_type = DELTA; + val->d_type = *str == '+' ? PLUS : MINUS; str++; } n = strtod(str, &buf); @@ -338,12 +334,10 @@ bool parse_value(struct value *val, char *str) { return false; while ((c = *(buf++))) switch(c) { case '+': - val->sign = PLUS; - val->d_type = DELTA; + val->d_type = PLUS; break; case '-': - val->sign = MINUS; - val->d_type = DELTA; + val->d_type = MINUS; break; case '%': val->v_type = RELATIVE; @@ -401,14 +395,13 @@ unsigned int calc_value(struct device *d, struct value *val) { new = val->v_type == ABSOLUTE ? val->val : percent_to_val(val->percentage, d); goto apply; } - int sign_mod = val->sign == MINUS ? -1 : 1; - long mod; + long mod = val->val; + if (val->d_type == MINUS) + mod *= -1; if (val->v_type == RELATIVE) { - mod = percent_to_val(val_to_percent(d->curr_brightness, d, false) + val->percentage * sign_mod, d) - d->curr_brightness; - if (val->percentage != 0 && mod == 0) - mod = val->sign == PLUS ? 1 : -1; - } else { - mod = val->val * sign_mod; + mod = percent_to_val(val_to_percent(d->curr_brightness, d, false) + mod, d) - d->curr_brightness; + if (val->val != 0 && mod == 0) + mod = val->d_type == PLUS ? 1 : -1; } new += mod; apply: From 2189d08705657b460855a1d29ca3691203723e00 Mon Sep 17 00:00:00 2001 From: andeston <17421805+andeston@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:45:15 -0500 Subject: [PATCH 2/3] Renamed `RELATIVE` to `PERCENT` --- brightnessctl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/brightnessctl.c b/brightnessctl.c index c58a77f..d91359e 100644 --- a/brightnessctl.c +++ b/brightnessctl.c @@ -75,7 +75,7 @@ struct device { bool matches; }; -enum value_type { ABSOLUTE, RELATIVE }; +enum value_type { ABSOLUTE, PERCENT }; enum delta_type { DIRECT, PLUS, MINUS }; struct value { @@ -340,10 +340,10 @@ bool parse_value(struct value *val, char *str) { val->d_type = MINUS; break; case '%': - val->v_type = RELATIVE; + val->v_type = PERCENT; break; } - if (val->v_type == RELATIVE) { + if (val->v_type == PERCENT) { val->percentage = n; } else { val->val = labs((long) n) % LONG_MAX; @@ -398,14 +398,14 @@ unsigned int calc_value(struct device *d, struct value *val) { long mod = val->val; if (val->d_type == MINUS) mod *= -1; - if (val->v_type == RELATIVE) { + if (val->v_type == PERCENT) { mod = percent_to_val(val_to_percent(d->curr_brightness, d, false) + mod, d) - d->curr_brightness; if (val->val != 0 && mod == 0) mod = val->d_type == PLUS ? 1 : -1; } new += mod; apply: - if (p.min.v_type == RELATIVE) { + if (p.min.v_type == PERCENT) { p.min.val = percent_to_val(p.min.percentage, d); p.min.v_type = ABSOLUTE; } From a2de52bb5de8254556136b0f6a9412e6cf946d3d Mon Sep 17 00:00:00 2001 From: andeston <17421805+andeston@users.noreply.github.com> Date: Wed, 18 Dec 2024 21:00:07 -0500 Subject: [PATCH 3/3] Bias toward whole percentages --- brightnessctl.c | 60 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/brightnessctl.c b/brightnessctl.c index d91359e..a54a96c 100644 --- a/brightnessctl.c +++ b/brightnessctl.c @@ -67,6 +67,18 @@ static bool ensure_dev_dir(struct device *); static bool logind_set_brightness(struct device *); #endif +#define min(a, b) ({ \ + __auto_type _a = (a); \ + __auto_type _b = (b); \ + _a < _b ? _a : _b; }) + +#define max(a, b) ({ \ + __auto_type _a = (a); \ + __auto_type _b = (b); \ + _a > _b ? _a : _b; }) + +#define clamp(val, lo, hi) min(max(val, lo), hi) + struct device { char *class; char *id; @@ -391,30 +403,40 @@ void print_device(struct device *dev) { unsigned int calc_value(struct device *d, struct value *val) { long new = d->curr_brightness; - if (val->d_type == DIRECT) { - new = val->v_type == ABSOLUTE ? val->val : percent_to_val(val->percentage, d); - goto apply; - } - long mod = val->val; - if (val->d_type == MINUS) - mod *= -1; - if (val->v_type == PERCENT) { - mod = percent_to_val(val_to_percent(d->curr_brightness, d, false) + mod, d) - d->curr_brightness; - if (val->val != 0 && mod == 0) - mod = val->d_type == PLUS ? 1 : -1; + if (val->v_type == ABSOLUTE) { + switch (val->d_type) { + case DIRECT: + new = val->val; + break; + case PLUS: + new = d->curr_brightness + val->val; + break; + case MINUS: + new = d->curr_brightness - val->val; + break; + } + } else { + float curr_pct = val_to_percent(d->curr_brightness, d, false); + float bias = curr_pct + val->percentage > roundf(curr_pct + val->percentage) ? + -1.0f / d->max_brightness : + 1.0f / d->max_brightness; + switch (val->d_type) { + case DIRECT: + new = percent_to_val(val->percentage, d); + break; + case PLUS: + new = percent_to_val(curr_pct + val->percentage + bias, d); + break; + case MINUS: + new = percent_to_val(curr_pct - val->percentage + bias, d); + break; + } } - new += mod; -apply: if (p.min.v_type == PERCENT) { p.min.val = percent_to_val(p.min.percentage, d); p.min.v_type = ABSOLUTE; } - if (new < (long)p.min.val) - new = p.min.val; - if (new < 0) - new = 0; - if (new > d->max_brightness) - new = d->max_brightness; + new = clamp(new, (long)p.min.val, (long)d->max_brightness); return new; }