diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | makefile | 13 | ||||
| -rw-r--r-- | old.c | 102 | ||||
| -rw-r--r-- | plan.md | 23 | ||||
| -rw-r--r-- | sb26.c | 92 |
5 files changed, 231 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e1c829 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +sb26 diff --git a/makefile b/makefile new file mode 100644 index 0000000..c270347 --- /dev/null +++ b/makefile @@ -0,0 +1,13 @@ +CC=gcc + +LINK=-lpthread +DBGCFLAGS=-Wall -pedantic +CFLAGS=${DBGCFLAGS} -O3 -march=native + +def: sb26 + ./sb26 + +sb26: sb26.c + ${CC} ${CFLAGS} ${LINK} sb26.c -o sb26 + +.PHONY: def @@ -0,0 +1,102 @@ +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <sys/inotify.h> +#include <poll.h> +#include <unistd.h> +#include <pthread.h> +#include <libudev.h> + +static const char MONTHS[12][4] = {"Jan\0", "Feb\0", "Mar\0", + "Apr\0", "May\0", "Jun\0", + "Jul\0", "Aug\0", "Sep\0", + "Oct\0", "Nov\0", "Dec\0" +}; +static const char DAYS[7][4] = {"Sun\0", "Mon\0", "Tue\0", "Wed\0", "Thu\0", "Fri\0", "Sat\0"}; +static const char PM[2][3] = {"AM\0", "PM\0"}; + +static const char TLPS[3][4] = {"\0", "\0","\0"}; + +struct sb26 { + char *date; + unsigned char tlp_status; + unsigned short mem_used; +}; + +void *watchers(void *arg) +{ + struct sb26 *sb = (struct sb26*)arg; + FILE *tlpf = fopen("/run/tlp/last_pwr", "r"); + int inf = inotify_init(); + int tlpw = inotify_add_watch(inf, "/run/tlp/last_pwr", IN_MODIFY); + ssize_t ev_s = sizeof(struct inotify_event) + NAME_MAX + 1; + struct pollfd pfd = {inf, POLLIN, 0}; + struct inotify_event ev; + + for (;;) { + fscanf(tlpf, "%hhu", &sb->tlp_status); + fseek(tlpf, 0, SEEK_SET); + + poll(&pfd, 1, INT_MAX); + read(inf, (void *)&ev, ev_s); + if (ev.wd == tlpw) { + // TODO Handle other inotify watches + } + } + return NULL; +} + +void tmfmt(char *tmf) +{ + struct tm tm_s; + time_t tm = time(NULL); + tzset(); + localtime_r(&tm, &tm_s); + unsigned char hr = tm_s.tm_hour % 12; + if (hr == 0) hr = 12; + snprintf(tmf, 21, "%s %s %02d %02d:%02d %s", DAYS[tm_s.tm_wday], MONTHS[tm_s.tm_mon], tm_s.tm_mday, hr, tm_s.tm_min, PM[tm_s.tm_hour/12]); +} + +void *watch_mem(void *arg) +{ + struct sb26 *sb = (struct sb26*)arg; + long total, avail; + char buf[25]; + FILE *memf = fopen("/proc/meminfo", "r"); + + for (;;) { + fgets(buf, 25, memf); + /* strtol can handle arbitrary leading whitespace */ + total = strtol((buf + 15), NULL, 10); + fseek(memf, 32, SEEK_CUR); + + fgets(buf, 25, memf); + avail = strtol((buf + 15), NULL, 10); + unsigned int used = total - avail; + sb->mem_used = used >> 10; + fseek(memf, 0, SEEK_SET); + } + + fclose(memf); +} + +int main() +{ + char tmf[21]; + + struct sb26 sb = { NULL, 0 }; + pthread_t watcher; + pthread_create(&watcher, NULL, &watchers, (void *) &sb); + pthread_t mem; + pthread_create(&mem, NULL, &watch_mem , (void *) &sb); + + while (1) { + tmfmt(tmf); + printf("%d mB %s %s\n", sb.mem_used, tmf, TLPS[sb.tlp_status]); + sleep(1); + } + + pthread_join(watcher, NULL); + return 0; +} @@ -0,0 +1,23 @@ +- [ ] Date +- [ ] Battery + - [ ] Percentage + - [ ] Status (charging, discharging +- [ ] Memory usage +- [ ] Disk usage? + - [ ] IO load? +- [ ] CPU load +- [ ] Network activity +- [ ] Bluetooth? +- [ ] Sound + - [ ] Level + - [ ] Mute + - [ ] Microphone +- [ ] MPD +- [ ] TLP + +How can I efficiently run varied functions under varied circumstances? + +- Pipewire can be signal-based. +- MPD will probably use the built-in `idle` command. +- CPU, Memory, Network run every *n* seconds. +- Battery status should listen for ACPI, percentage is *n* seconds. @@ -0,0 +1,92 @@ +#include <stdio.h> +#include <string.h> +#include <time.h> + +static const char MONTHS[12][4] = {"Jan\0", "Feb\0", "Mar\0", + "Apr\0", "May\0", "Jun\0", + "Jul\0", "Aug\0", "Sep\0", + "Oct\0", "Nov\0", "Dec\0" +}; +static const char DAYS[7][4] = {"Sun\0", "Mon\0", "Tue\0", "Wed\0", "Thu\0", "Fri\0", "Sat\0"}; +static const char PM[2][3] = {"AM\0", "PM\0"}; + +static inline void +cpu_get(char *b) +{ + FILE *p = fopen("/proc/loadavg", "r"); + char c = fgetc(p); + int i; + for (i = 0; i < 7 && c != ' '; i++) { + b[i] = c; + c = fgetc(p); + } + b[i] = '\0'; + fclose(p); +} + +static inline void +bat_get(char *b) +{ + FILE *p = fopen("/sys/class/power_supply/BAT1/capacity", "r"); + fgets(b, 3, p); + fclose(p); +} + +static inline void +mem_get(char *b) +{ + /* Returns "Volume: <v> [[Muted]]" */ + FILE *p = popen("free -m | awk '/^Mem/{print $3}'", "r"); + fgets(b, 16, p); + /* Truncate trailing newline */ + b[strlen(b)-1] = '\0'; + fclose(p); +} + +static inline void +snd_get(char *b) +{ + /* Returns "Volume: <v> [[Muted]]" */ + FILE *p = popen("wpctl get-volume @DEFAULT_SINK@", "r"); + while (fgetc(p) != ' '); + fgets(b, 16, p); + /* Truncate trailing newline */ + b[strlen(b)-1] = '\0'; + fclose(p); +} + +static inline void +date_get(struct tm *tm) +{ + time_t now = time(NULL); + localtime_r(&now, tm); + + // unsigned char hr = tm.tm_hour % 12; + // if (hr == 0) hr = 12; + // snprintf(tmf, 21, "%s %s %02d %02d:%02d %s", DAYS[tm.tm_wday], MONTHS[tm.tm_mon], tm.tm_mday, hr, tm.tm_min, PM[tm.tm_hour/12]); +} + +int +main(void) +{ + static const struct timespec WAIT = { 2, 0 }; + struct tm tm; + tzset(); + char snd[16]; + char mem[16]; + char bat[3]; + char cpu[7]; + unsigned char hr = 0; + for (;;) { + date_get(&tm); + hr = tm.tm_hour % 12; + if (hr == 0) hr = 12; + + snd_get(snd); + mem_get(mem); + bat_get(bat); + cpu_get(cpu); + printf("%s | %s | %s MiB | %s%% | %s %s %02d %02d:%02d %s\n", snd, cpu, mem, bat, DAYS[tm.tm_wday], MONTHS[tm.tm_mon], tm.tm_mday, hr, tm.tm_min, PM[tm.tm_hour/12]); + nanosleep(&WAIT, NULL); + } +} |
