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