sbar

sbar - a suckless status bar
git clone git://ssnf.xyz/sbar
Log | Files | Refs

commit ee925c823cb1623baa256a70dfba469214120c47
Author: ssnf@ssnf.xyz <ssnf@ssnf.xyz>
Date:   Thu, 25 Feb 2021 18:51:56 +0000

Initial commit

Diffstat:
AMakefile | 15+++++++++++++++
Asbar.c | 34++++++++++++++++++++++++++++++++++
Asbar.h | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aunix.c | 162+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 272 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,15 @@ +DESTDIR=~/.local +LIBS=-lX11 +OPTS=-std=c99 -Wno-parentheses -Wpedantic -Wall -funsigned-char -D_POSIX_C_SOURCE=199309L + +SRC = sbar.c unix.c +sbar: + ${CC} -o $@ ${LIBS} ${OPTS} *.c +clean: + rm -f sbar ${OBJ} +install: + mkdir -p ${DESTDIR}/bin + chmod +x sbar + cp -f sbar ${DESTDIR}/bin +uninstall: + rm ${DESTIDIR}/bin/sbar diff --git a/sbar.c b/sbar.c @@ -0,0 +1,34 @@ +#include "sbar.h" + +Partition part[] = { + {.path = "/"}, + {.path = "/home"} +}; +Bat bat; +Ram ram; +Date date; +Title title; + +void +update() +{ + title.update = 0; + snprintf(title.text, 256, "%s %s %s %s %s", part[0].text, part[1].text, ram.text, date.text, bat.text); + Titleset(); +} + +int +main() +{ + Partinit(); + Raminit(); + Titleinit(); + for (;;) { + Partchk(); + Ramchk(); + Datechk(); + Batchk(); + if (title.update) update(); + wait(.016); + } +} diff --git a/sbar.h b/sbar.h @@ -0,0 +1,61 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#define LENGTH(a) (sizeof(a)/sizeof(a[0])) + +typedef unsigned char uchar; +typedef unsigned int uint; +typedef unsigned long ulong; +typedef struct Title Title; +typedef struct Partition Partition; +typedef struct Ram Ram; +typedef struct Date Date; +typedef struct Bat Bat; + +struct Title { + char text[256]; + uchar update; +}; +void Titleinit(); +void Titleset(); + +struct Partition { + char* path; + char text[32]; + ulong free; + float size_f; +}; +void Partinit(); +void Partchk(); + +struct Ram { + char text[24]; + ulong free; + ulong size; + uchar unit; + float size_f; +}; +void Raminit(); +void Ramchk(); + +struct Date { + char text[16]; + uint s; +}; +void Datechk(); + +struct Bat { + char text[8]; + ulong c; +}; +void Batchk(); + +void wait(double); + +extern Title title; +extern Partition part[2]; +extern Ram ram; +extern Date date; +extern Bat bat; diff --git a/unix.c b/unix.c @@ -0,0 +1,162 @@ +#include "sbar.h" + +#include <time.h> +#include <unistd.h> +#include <X11/Xlib.h> +#include <sys/statfs.h> + +void wait(double); +void Partinit(); +void Partchk(); +void Raminit(); +void Ramchk(); +void Datechk(); +void Batchk(); + +void +wait(double t) +{ + static struct timespec ts; + static double lastwait; + ulong i; + + if (t != lastwait) { + lastwait = t; + for (i = 0; t >= 1; --t, ++i); + ts.tv_sec = i; + ts.tv_nsec = t * 1000000000; + } + nanosleep(&ts, NULL); +} + +void +Partinit() +{ + struct statfs stat; + uint i, size; + + for (i = 0; i < LENGTH(part); ++i) { + statfs(part[i].path, &stat); + size = (stat.f_blocks * stat.f_bsize) >> 20; + part[i].size_f = (float)size / 1024.0f; + } +} + +void +Partchk() +{ + struct statfs stat; + uint i, free; + + for (i = 0; i < LENGTH(part); ++i) { + statfs(part[i].path, &stat); + free = (stat.f_bfree * stat.f_bsize) >> 23; + if (free != part[i].free) { + part[i].free = free; + ++title.update; + snprintf(part[i].text, 25, "%s:(%2.2fGB/%2.2fGB)", part[i].path, part[i].size_f - ((float)free / 128.0f), part[i].size_f); + } + } +} + +void +Raminit() +{ + FILE* meminfo; + char buf[32]; + ulong size; + + if (!(meminfo = fopen("/proc/meminfo", "r"))) return; + fread(buf, 32, 1, meminfo); + fclose(meminfo); + sscanf(buf, "MemTotal: %lu", &size); + ram.size = size; + ram.unit = 'M'; + if (size > 1024*1024) { + ram.unit = 'G'; + size >>= 10; + } + ram.size_f = size/1024.0f; +} + +void +Ramchk() +{ + FILE* meminfo; + char buf[1024]; + ulong i, free; + float used_f; + uchar unit; + + if (!(meminfo = fopen("/proc/meminfo", "r"))) return; + fread(buf, 1024, 1, meminfo); + fclose(meminfo); + free = 0; + sscanf(strstr(buf, "MemFree"), "MemFree: %lu", &free); + if (ram.unit == 'M' && free >> 3 == ram.free >> 3 || + ram.unit == 'G' && free >> 13 == ram.free >> 13) return; + ram.free = free; + sscanf(strstr(buf, "Buffers"), "Buffers: %lu", &i); + free += i; + sscanf(strstr(buf, "Cached"), "Cached: %lu", &i); + free += i; + sscanf(strstr(buf, "Shmem"), "Shmem: %lu", &i); + free -= i; + sscanf(strstr(buf, "SReclaimable"), "SReclaimable: %lu", &i); + free += i; + unit = 'M'; + used_f = (ram.size - free) / 1024.0f; + if (used_f > 1024) { + unit = 'G'; + used_f /= 1024.0f; + } + ++title.update; + snprintf(ram.text, 24, "R(%.02f%cB/%.02f%cB)", used_f, unit, ram.size_f, ram.unit); +} + +void +Datechk() +{ + FILE* f; + uint h, m, s, d, M; + + if (!(f = fopen("/sys/class/rtc/rtc0/time", "r"))) return; + fscanf(f, "%u:%u:%u", &h, &m, &s); + fclose(f); + if (s == date.s) return; + if (h > 12) h -= 12; + date.s = s; + if (!(f = fopen("/sys/class/rtc/rtc0/date", "r"))) return; + fscanf(f, "%*u-%u-%u", &M, &d); + fclose(f); + ++title.update; + snprintf(date.text, 16, "%u/%u %u:%02u:%02u", M, d, h, m, s); +} + +void +Batchk() +{ + FILE* f; + uint c; + + if (!(f = fopen("/sys/class/power_supply/BAT0/capacity", "r"))) return; + fscanf(f, "%u", &c); + fclose(f); + if (c == bat.c) return; + bat.c = c; + snprintf(bat.text, 19, "B(%u%%)", c); +} + +static Display* display; +void +Titleinit() +{ + display = XOpenDisplay(NULL); +} + +void +Titleset() +{ + XStoreName(display, DefaultRootWindow(display), title.text); + XFlush(display); +}