s2dblocks

statusbar blocks for dwm
Log | Files | Refs

commit b3883e5aa0d29fb37555765d66d54cac87f856ea
parent d97223bffcc3a887453ab12e6e979f204b7ce589
Author: hhvn <dev@hhvn.uk>
Date:   Wed, 13 Apr 2022 17:35:29 +0100

cpu handler

Diffstat:
Mdwmbar.h | 4+++-
Mhandlers/cpu.c | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mstatus2d.c | 26+++++++++++++++++++++++---
3 files changed, 159 insertions(+), 10 deletions(-)

diff --git a/dwmbar.h b/dwmbar.h @@ -11,7 +11,9 @@ 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_bar(char *bordercol, unsigned x, unsigned y, unsigned w, unsigned h, unsigned px, + char *incolour, unsigned percent); void s2d_fg(char *fg); void s2d_bg(char *bg); -void s2d_forward(unsigned px); +void s2d_forward(int px); /* negative to advance past drawn objects */ void s2d_print(char *fmt, ...); diff --git a/handlers/cpu.c b/handlers/cpu.c @@ -1,15 +1,142 @@ #include <stdio.h> +#include <errno.h> +#include <ctype.h> #include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/stat.h> #include "../dwmbar.h" #define MAXCORES 1024 /* moore's law, man */ +#define RED "#AA2222" +#define ORANGE "#AA7700" +#define GREEN "#00AA00" + +#ifdef __linux__ #define CPUTOKS 11 /* grep '^cpu' < /proc/stat | awk '{print NF}' */ +static FILE * +statopen(void) { + FILE *ret; + if ((ret = fopen("/proc/stat", "r")) == NULL) { + s2d_print("%s: %s", strerror(errno)); + s2d_finish(); + exit(EXIT_FAILURE); + } + return ret; +} +#endif /* __linux__ */ + +int +main(void) { + int percent[MAXCORES]; + int temp[MAXCORES]; + int cores = 0; + char *col; + memset(percent, 0, sizeof(percent)); + +#ifdef __linux__ + long long unsigned total[MAXCORES]; + long long unsigned idle[MAXCORES]; + long long unsigned ltotal, lidle, used, diff; + struct stat st; + FILE *f; + char buf[BUFSIZ]; + char *toks[CPUTOKS]; + char *p; + int i, j; + + memset(total, 0, sizeof(total)); + memset(idle, 0, sizeof(idle)); + + f = statopen(); + while ((fgets(buf, sizeof(buf), f)) != NULL) { + buf[strlen(buf) - 1] = '\0'; /* remove \n */ + if (strncmp(buf, "cpu", 3) == 0 && isdigit(*(buf+3))) { + for (j = 0; j < CPUTOKS; j++) + toks[j] = strtok(j ? NULL : buf, " "); + p = toks[0]; + p += 3; /* "cpu" */ + i = strtoll(p, NULL, 10); + if (i >= MAXCORES) { + s2d_print("MAXCORES exceeded"); + s2d_finish(); + return 1; + } + if (i + 1 > cores) + cores = i + 1; + for (j = 1; j < CPUTOKS; j++) + total[i] += strtoll(toks[j], NULL, 10); + idle[i] = strtoll(toks[4], NULL, 10); + } + } + fclose(f); + + sleep(1); -long long total[MAXCORES]; -long long idle[MAXCORES]; + f = statopen(); + while ((fgets(buf, sizeof(buf), f)) != NULL) { + buf[strlen(buf) - 1] = '\0'; + if (strncmp(buf, "cpu", 3) == 0 && isdigit(*(buf+3))) { + for (j = 0; j < CPUTOKS; j++) + toks[j] = strtok(j ? NULL : buf, " "); + p = toks[0]; + p += 3; /* "cpu" */ + i = strtoll(p, NULL, 10); + if (i >= MAXCORES) { + s2d_print("MAXCORES exceeded"); + s2d_finish(); + return 1; + } + if (i + 1 > cores) + cores = i + 1; + for (j = 1, ltotal = 0; j < CPUTOKS; j++) + ltotal += strtoll(toks[j], NULL, 10); + diff = ltotal - total[i]; + lidle = strtoll(toks[4], NULL, 10) - idle[i]; + used = 100 * (diff - lidle); + percent[i] = used / diff; + } + } + fclose(f); -void -handleline(char *str) { - char *toks - if (strlen(str) < 4 || strncmp(str, "cpu", 3) != 0 || !isdigit(*(str + 3))) + for (i = 0; i < MAXCORES && i < cores; i++) { + snprintf(buf, sizeof(buf), "/sys/class/thermal/thermal_zone%d/temp", i); + if (stat(buf, &st) == -1) + continue; + if (!S_ISREG(st.st_mode)) + continue; + if ((f = fopen(buf, "r")) == NULL) + continue; + fread(buf, sizeof(char), BUFSIZ, f); + buf[5] = '\0'; + temp[i] = strtol(buf, NULL, 10) / 1000; + fclose(f); + } +#else + s2d_print("no handler for this OS"); + s2d_finish(); + return 1; +#endif + for (i = 0; percent[i] && i < MAXCORES; i++) { + if (percent[i] > 80) + col = RED: + else if (percent[i] > 50) + col = ORANGE; + else + col = GREEN; + s2d_bar("#000000", 0, 1, 5, bar_height - 2, 1, col, percent[i]); + if (temp[i]) { + if (temp[i] >= 70) + col = RED; + else if (temp[i] >= 60) + col = ORANGE; + else + col = GREEN; + s2d_fg(col); + s2d_print("%d°", temp[i]); + } else { + s2d_forward(-1); + s2d_forward(2); + } + } } diff --git a/status2d.c b/status2d.c @@ -21,7 +21,7 @@ s2d_reset(void) { void s2d_finish(void) { - s2d_forward(needforwarding); + s2d_forward(-1); s2d_reset(); } @@ -51,6 +51,24 @@ s2d_border(unsigned x, unsigned y, unsigned w, unsigned h, unsigned px) { s2d_rect(x, y + h - px, w, px); /* bottom */ } +void +s2d_bar(char *bordercol, unsigned x, unsigned y, unsigned w, unsigned h, unsigned px, + char *incol, unsigned percent) { + int maxpx = x + w; + int iw = w - 2 * px, ih = h - 2 * px; + int fh = ih * percent / 100; + s2d_init(); + if (!w || !h) + return; + if (maxpx > needforwarding) + needforwarding = maxpx; + + s2d_fg(bordercol); + s2d_border(x, y, w, h, px); + s2d_fg(incol); + s2d_rect(x + px, y + px + ih - fh, iw, fh); +} + static char * verifyhex(char *hex) { char *p; @@ -86,10 +104,12 @@ s2d_bg(char *bg) { } void -s2d_forward(unsigned px) { +s2d_forward(int px) { s2d_init(); if (!px) return; + if (px < 0) + px = needforwarding; if (needforwarding >= px) needforwarding -= px; else @@ -102,7 +122,7 @@ s2d_print(char *fmt, ...) { va_list ap; s2d_init(); - s2d_forward(needforwarding); + s2d_forward(-1); va_start(ap, fmt); vprintf(fmt, ap);