slstatus

My fork of https://tools.suckless.org/slstatus/
git clone https://git.inz.fi/slstatus
Log | Files | Refs | README | LICENSE

commit 4c4d53c669a3f09e2e1b4b9a92736085840d6c91
parent 84a2f117a32f0796045941260cdc4b69852b41e0
Author: Santtu Lakkala <inz@inz.fi>
Date:   Wed, 23 Feb 2022 08:49:58 +0200

Multiple battery support

If a device has multiple batteries, the overall capacity is not
available directly, instead loop through batteries and add up the
energy/charge levels.

Diffstat:
Mcomponents/battery.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++--------------
Mutil.c | 2+-
Mutil.h | 2++
3 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/components/battery.c b/components/battery.c @@ -10,15 +10,21 @@ #include <unistd.h> static const char * - pick(const char *bat, const char *f1, const char *f2, char *path, - size_t length) + pick(const char *f1, const char *f2, char *path, + size_t length, ...) { - if (esnprintf(path, length, f1, bat) > 0 && + va_list a1; + va_list a2; + + va_start(a1, length); + va_copy(a2, a1); + + if (evsnprintf(path, length, f1, a1) > 0 && access(path, R_OK) == 0) { return f1; } - if (esnprintf(path, length, f2, bat) > 0 && + if (evsnprintf(path, length, f2, a2) > 0 && access(path, R_OK) == 0) { return f2; } @@ -32,12 +38,41 @@ int perc; char path[PATH_MAX]; - if (esnprintf(path, sizeof(path), - "/sys/class/power_supply/%s/capacity", bat) < 0) { - return NULL; - } - if (pscanf(path, "%d", &perc) != 1) { - return NULL; + if (bat) { + if (esnprintf(path, sizeof(path), + "/sys/class/power_supply/%s/capacity", bat) < 0) { + return NULL; + } + if (pscanf(path, "%d", &perc) != 1) { + return NULL; + } + } else { + int bi; + int ef = 0; + int en = 0; + for (bi = 0;; bi++) { + int f; + int n; + + if (!pick("/sys/class/power_supply/BAT%d/charge_full", + "/sys/class/power_supply/BAT%d/energy_full", + path, sizeof(path), bi)) + break; + if (pscanf(path, "%d", &f) != 1) + return NULL; + if (!pick("/sys/class/power_supply/BAT%d/charge_now", + "/sys/class/power_supply/BAT%d/energy_now", + path, sizeof(path), bi)) + break; + if (pscanf(path, "%d", &n) != 1) + return NULL; + + ef += f; + en += n; + } + if (ef == 0) + return NULL; + perc = (en + ef / 200) / (ef / 100); } return bprintf("%d", perc); @@ -88,17 +123,17 @@ return NULL; } - if (!pick(bat, "/sys/class/power_supply/%s/charge_now", + if (!pick("/sys/class/power_supply/%s/charge_now", "/sys/class/power_supply/%s/energy_now", path, - sizeof(path)) || + sizeof(path), bat) || pscanf(path, "%ju", &charge_now) < 0) { return NULL; } if (!strcmp(state, "Discharging")) { - if (!pick(bat, "/sys/class/power_supply/%s/current_now", + if (!pick("/sys/class/power_supply/%s/current_now", "/sys/class/power_supply/%s/power_now", path, - sizeof(path)) || + sizeof(path), bat) || pscanf(path, "%ju", &current_now) < 0) { return NULL; } diff --git a/util.c b/util.c @@ -49,7 +49,7 @@ die(const char *fmt, ...) exit(1); } -static int +int evsnprintf(char *str, size_t size, const char *fmt, va_list ap) { int ret; diff --git a/util.h b/util.h @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include <stdint.h> +#include <stdarg.h> extern char buf[1024]; @@ -10,6 +11,7 @@ extern char *argv0; void warn(const char *, ...); void die(const char *, ...); +int evsnprintf(char *str, size_t size, const char *fmt, va_list ap); int esnprintf(char *str, size_t size, const char *fmt, ...); const char *bprintf(const char *fmt, ...); const char *fmt_human(uintmax_t num, int base);