sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

slstatus-dyn_battery-20260218-614c275.diff (4629B)


      1 From 5f04140fe8c73a96bae2a4eba899f2b114849673 Mon Sep 17 00:00:00 2001
      2 From: Lukas Lynch <madi@mxdi.xyz>
      3 Date: Wed, 18 Feb 2026 16:20:25 -0800
      4 Subject: [PATCH] Displays status/capacity for a dynamic # of batteries
      5 
      6 ---
      7  Makefile                 |  1 +
      8  components/dyn_battery.c | 80 ++++++++++++++++++++++++++++++++++++++++
      9  config.def.h             |  1 +
     10  slstatus.h               |  3 ++
     11  4 files changed, 85 insertions(+)
     12  create mode 100644 components/dyn_battery.c
     13 
     14 diff --git a/Makefile b/Makefile
     15 index 7a18274..d1b24dd 100644
     16 --- a/Makefile
     17 +++ b/Makefile
     18 @@ -11,6 +11,7 @@ COM =\
     19  	components/cpu\
     20  	components/datetime\
     21  	components/disk\
     22 +	components/dyn_battery\
     23  	components/entropy\
     24  	components/hostname\
     25  	components/ip\
     26 diff --git a/components/dyn_battery.c b/components/dyn_battery.c
     27 new file mode 100644
     28 index 0000000..7f49122
     29 --- /dev/null
     30 +++ b/components/dyn_battery.c
     31 @@ -0,0 +1,80 @@
     32 +/* Written by Lukas Lynch <madi@mxdi.xyz> */
     33 +/* Only Linux is supported */
     34 +#include <stdio.h>
     35 +#include <string.h>
     36 +#include <dirent.h>
     37 +
     38 +/* extern char buf[n] */
     39 +#include "../util.h"
     40 +
     41 +/* See components/battery.c */
     42 +const char *battery_state(const char *);
     43 +const char *battery_perc(const char *);
     44 +
     45 +/*
     46 +* This output buffer is global so we can just return its address, instead of
     47 +* copying its contents to 'buf' (declared in slstatus.c) with bprintf().
     48 +*/
     49 +char out[sizeof(buf)];
     50 +
     51 +#if defined(__linux__)
     52 +#define BAT_PREFIX "BAT"
     53 +#define BAT_PREFIX_LEN sizeof(BAT_PREFIX)-1 // NULL byte included in sizeof()
     54 +#define BAT_DIR "/sys/class/power_supply/"
     55 +
     56 +/**
     57 +* Displays the status and capacity of a dynamic amount of batteries (i.e.
     58 +* laptops with external/secondary batteries).
     59 +*
     60 +* @param  fmt format string to use for each battery display. ordered key:
     61 +*             %u: battery number || %s: battery state || %s battery capacity
     62 +* @return address of the output buffer, which contains the status and
     63 +*         capacities of all detected batteries
     64 +*/
     65 +const char *
     66 +dyn_battery(const char *fmt) {
     67 +    *out = '\0'; // Functionally "clears" the buffer after last run
     68 +
     69 +    DIR *dirp = opendir(BAT_DIR);
     70 +    if(!dirp) {
     71 +        fprintf(stderr, "dyn_battery: Failed to open %s\n", BAT_DIR);
     72 +        return "err";
     73 +    }
     74 +
     75 +    unsigned int outp = 0, // Next free position in 'out'
     76 +                 batn = 0; // Battery # (i.e. BAT0, BAT1, ...)
     77 +    struct dirent *fp;     // Current file in 'dirp' readout
     78 +
     79 +    while((fp = readdir(dirp))) {
     80 +        char *bat = fp->d_name; // Makes following code less ugly
     81 +
     82 +        if(
     83 +            strlen(bat) > BAT_PREFIX_LEN &&
     84 +            strncmp(bat, BAT_PREFIX, BAT_PREFIX_LEN) == 0
     85 +        ) {
     86 +            outp += sprintf(
     87 +                out + outp,         // Starts after previous writes
     88 +                fmt,                // Format string specified in config.h
     89 +                batn++,             // 'batn' is decoupled from OS BAT#
     90 +                battery_state(bat), // See components/battery.c
     91 +                battery_perc(bat)   // See components/battery.c
     92 +            );
     93 +
     94 +            // Add space between battery entries
     95 +            out[outp++] = ' ';
     96 +        }
     97 +    } // end while
     98 +
     99 +    if(closedir(dirp) != 0) {
    100 +        fprintf(stderr, "dyn_battery: Failed to close %s.\n", BAT_DIR);
    101 +        return "err";
    102 +    }
    103 +
    104 +    if(*out) {
    105 +        out[--outp] = '\0'; // Remove extra space after last write
    106 +        return out;
    107 +    } else return NULL;
    108 +}
    109 +#else // #if defined(__linux__)
    110 +# error "dyn_battery: Only Linux is currently supported."
    111 +#endif
    112 \ No newline at end of file
    113 diff --git a/config.def.h b/config.def.h
    114 index 100093e..7f26909 100644
    115 --- a/config.def.h
    116 +++ b/config.def.h
    117 @@ -26,6 +26,7 @@ static const char unknown_str[] = "n/a";
    118   * disk_perc           disk usage in percent           mountpoint path (/)
    119   * disk_total          total disk space in GB          mountpoint path (/)
    120   * disk_used           used disk space in GB           mountpoint path (/)
    121 + * dyn_battery         displays the name, state and    format string (%u, %s, %s)
    122   * entropy             available entropy               NULL
    123   * gid                 GID of current user             NULL
    124   * hostname            hostname                        NULL
    125 diff --git a/slstatus.h b/slstatus.h
    126 index 394281c..6beeaec 100644
    127 --- a/slstatus.h
    128 +++ b/slstatus.h
    129 @@ -21,6 +21,9 @@ const char *disk_perc(const char *path);
    130  const char *disk_total(const char *path);
    131  const char *disk_used(const char *path);
    132  
    133 +/* dyn_battery */
    134 +const char *dyn_battery(const char *fmt);
    135 +
    136  /* entropy */
    137  const char *entropy(const char *unused);
    138  
    139 -- 
    140 2.53.0
    141