s2dblocks

statusbar blocks for dwm
Log | Files | Refs

commit 8aeabf2bd7d16e6f812d9cf2e9b0d551ddbde035
Author: hhvn <dev@hhvn.uk>
Date:   Wed, 13 Apr 2022 16:12:44 +0100

Init (with bat handler + helper functions + makefile)

Diffstat:
Adwmbar.h | 17+++++++++++++++++
Ahandlers/bat.c | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahandlers/cpu.c | 15+++++++++++++++
Amisc.c | 24++++++++++++++++++++++++
Astatus2d.c | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 280 insertions(+), 0 deletions(-)

diff --git a/dwmbar.h b/dwmbar.h @@ -0,0 +1,17 @@ +#define bar_assert(expr) ((void)((expr) || (bar_assert_(#expr, __FILE__, __LINE__, __func__),0))) +#define bar_height 15 + +/* misc.c */ +void bar_assert_(const char *aval, const char *file, int line, const char *func); +void *emalloc(size_t size); +void *erealloc(void *ptr, size_t size); + +/* status2d.c */ +void s2d_reset(void); +void s2d_finish(void); +void s2d_rect(unsigned x, unsigned y, unsigned w, unsigned h); +void s2d_border(unsigned x, unsigned y, unsigned w, unsigned h, unsigned px); +void s2d_fg(char *fg); +void s2d_bg(char *bg); +void s2d_forward(unsigned px); +void s2d_print(char *fmt, ...); diff --git a/handlers/bat.c b/handlers/bat.c @@ -0,0 +1,114 @@ +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <dirent.h> +#include <string.h> +#include <sys/stat.h> +#include "../dwmbar.h" + +#define RED "#FF0000" +#define GREEN "#00FF00" +#define GREY "#888888" + +int +main(void) { + enum { s_none, s_charge, s_dcharge }; + int percent, status = s_none, w, iw, ih; +#ifdef __linux__ +#define BATDIR "/sys/class/power_supply" + struct dirent **dirent; + struct stat st; + char buf[BUFSIZ]; + char *dir = NULL; + char *sfile = NULL; + char *cfile = NULL; + size_t len; + FILE *f; + int nbats, ndir, total; + int i; + + if ((ndir = scandir(BATDIR, &dirent, 0, alphasort)) < 0) { + return 1; + } + + for (i = total = nbats = 0; i < ndir; i++) { + if (strncmp(dirent[i]->d_name, "BAT", strlen("BAT")) == 0) { + free(dir); + len = strlen(BATDIR) + strlen(dirent[i]->d_name) + 2; /* / + \0 */ + dir = emalloc(len); + snprintf(dir, len, "%s/%s", BATDIR, dirent[i]->d_name); + + if (stat(dir, &st) == -1 || !S_ISDIR(st.st_mode)) + continue; + + free(sfile); + len = strlen(dir) + 8; /* /status\0 */ + sfile = emalloc(len); + snprintf(sfile, len, "%s/status", dir); + if ((f = fopen(sfile, "r")) != NULL) { + memset(buf, '\0', sizeof(buf)); + fread(buf, sizeof(char), sizeof(buf), f); + fclose(f); + if (buf[strlen(buf) - 1] == '\n') + buf[strlen(buf) - 1] = '\0'; + /* XXX: some batteries charging, some discharging? */ + if (strcmp(buf, "Charging") == 0 && s_charge > status) + status = s_charge; + else if (strcmp(buf, "Discharging") == 0 && s_dcharge > status) + status = s_dcharge; + } + + free(cfile); + len = strlen(dir) + 10; /* /capacity\0 */ + cfile = emalloc(len); + snprintf(cfile, len, "%s/capacity", dir); + if ((f = fopen(cfile, "r")) != NULL) { + memset(buf, '\0', sizeof(buf)); + fread(buf, sizeof(char), sizeof(buf), f); + fclose(f); + if (buf[strlen(buf) - 1] == '\n') + buf[strlen(buf) - 1] = '\0'; + nbats++; + total += atoi(buf); + } + } + } + + percent = total / nbats; +#else + s2d_print("no handler for this OS"); + s2d_finish(); + return 1; +#endif + iw = 18; + ih = bar_height - 8; + w = iw * percent / 100; + + /* colour border+nose for charge indicator */ + if (status == s_dcharge) + s2d_fg(RED); + else if (status == s_charge) + s2d_fg(GREEN); + else + s2d_fg(GREY); + + /* draw nose */ + s2d_rect(2, (bar_height - 5) / 2, 1, 5); + + /* draw border for battery */ + s2d_border(3, 3, iw + 2, ih + 2, 1); + + /* fill battery */ + if (percent > 95 && status != s_dcharge) + s2d_fg(GREEN); + else if (percent < 25) + s2d_fg(RED); + else + s2d_fg(GREY); + s2d_rect(4 + iw - w, 4, w, ih); + + /* pad + finish up */ + s2d_forward(2); + s2d_finish(); + return 0; +} diff --git a/handlers/cpu.c b/handlers/cpu.c @@ -0,0 +1,15 @@ +#include <stdio.h> +#include <string.h> +#include "../dwmbar.h" + +#define MAXCORES 1024 /* moore's law, man */ +#define CPUTOKS 11 /* grep '^cpu' < /proc/stat | awk '{print NF}' */ + +long long total[MAXCORES]; +long long idle[MAXCORES]; + +void +handleline(char *str) { + char *toks + if (strlen(str) < 4 || strncmp(str, "cpu", 3) != 0 || !isdigit(*(str + 3))) +} diff --git a/misc.c b/misc.c @@ -0,0 +1,24 @@ +#include <stdio.h> +#include <stdlib.h> +#include "dwmbar.h" + +void +bar_assert_(const char *aval, const char *file, int line, const char *func) { + printf("assertion failed (%s() at %s:%d): '%s'", func, file, line, aval); + exit(EXIT_FAILURE); +} + +void * +emalloc(size_t size) { + void *mem; + mem = malloc(size); + bar_assert(mem); + return mem; +} + +void * +erealloc(void *ptr, size_t size) { + ptr = realloc(ptr, size); + bar_assert(ptr); + return ptr; +} diff --git a/status2d.c b/status2d.c @@ -0,0 +1,110 @@ +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <stdarg.h> +#include "dwmbar.h" + +static int needforwarding = 0; +static int initialized = 0; + +#define s2d_init() (initialized ? s2d_init_() : ((void)0)) + +static void +s2d_init_(void) { + s2d_reset(); +} + +void +s2d_reset(void) { + printf("^d^"); +} + +void +s2d_finish(void) { + s2d_forward(needforwarding); + s2d_reset(); +} + +void +s2d_rect(unsigned x, unsigned y, unsigned w, unsigned h) { + int maxpx = x + w; + s2d_init(); + if (!w || !h) + return; + if (maxpx > needforwarding) + needforwarding = maxpx; + printf("^r%u,%u,%u,%u^", x, y, w, h); +} + +void +s2d_border(unsigned x, unsigned y, unsigned w, unsigned h, unsigned px) { + int maxpx = x + w; + s2d_init(); + if (!w || !h) + return; + if (maxpx > needforwarding) + needforwarding = maxpx; + + s2d_rect(x, y, w, px); /* top */ + s2d_rect(x, y, px, h); /* left */ + s2d_rect(x + w - px, y, px, h); /* right */ + s2d_rect(x, y + h - px, w, px); /* bottom */ +} + +static char * +verifyhex(char *hex) { + char *p; + if (!hex) + goto inval; + if (*hex == '#') + hex++; + if (strlen(hex) != 6) + goto inval; + for (p = hex; *p; p++) + if (!(isdigit(*p) || (*p <= 'F' && *p >= 'A'))) + goto inval; + return hex; +inval: + printf("invalid colour code: '%s'", hex); + return NULL; +} + +void +s2d_fg(char *fg) { + s2d_init(); + fg = verifyhex(fg); + if (fg) + printf("^c#%s^", fg); +} + +void +s2d_bg(char *bg) { + s2d_init(); + bg = verifyhex(bg); + if (bg) + printf("^b#%s^", bg); +} + +void +s2d_forward(unsigned px) { + s2d_init(); + if (!px) + return; + if (needforwarding >= px) + needforwarding -= px; + else + needforwarding = 0; + printf("^f%u^", px); +} + +void +s2d_print(char *fmt, ...) { + va_list ap; + + s2d_init(); + s2d_forward(needforwarding); + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); +}