commit b3883e5aa0d29fb37555765d66d54cac87f856ea
parent d97223bffcc3a887453ab12e6e979f204b7ce589
Author: hhvn <dev@hhvn.uk>
Date: Wed, 13 Apr 2022 17:35:29 +0100
cpu handler
Diffstat:
M | dwmbar.h | | | 4 | +++- |
M | handlers/cpu.c | | | 139 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
M | status2d.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);