commit 8aeabf2bd7d16e6f812d9cf2e9b0d551ddbde035
Author: hhvn <dev@hhvn.uk>
Date: Wed, 13 Apr 2022 16:12:44 +0100
Init (with bat handler + helper functions + makefile)
Diffstat:
A | dwmbar.h | | | 17 | +++++++++++++++++ |
A | handlers/bat.c | | | 114 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | handlers/cpu.c | | | 15 | +++++++++++++++ |
A | misc.c | | | 24 | ++++++++++++++++++++++++ |
A | status2d.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);
+}