diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Makefile | 25 | ||||
-rw-r--r-- | README.md | 35 | ||||
-rw-r--r-- | config.def.mk | 32 | ||||
-rw-r--r-- | dwmclock.c | 120 |
5 files changed, 216 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d06a542 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +*.swp +/dwmclock +/config.mk diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9aa9a59 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +include config.mk + +MAIN=dwmclock +SRC=dwmclock.c +OBJ=$(SRC:.c=.o) + +all: $(SRC) $(MAIN) + +$(MAIN): $(OBJ) + $(CC) $(LDFLAGS) -o $@ $(OBJ) + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ + +clean: + -rm -f $(MAIN) $(OBJ) + +install: $(MAIN) + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp $(MAIN) $(DESTDIR)$(PREFIX)/bin/$(MAIN) + +uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/$(MAIN) + +.PHONY: all clean install uninstall diff --git a/README.md b/README.md new file mode 100644 index 0000000..7761fd4 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +dwmclock +======== + +Show the time and current battery charge in the X root window name + +Requirements +------------ + +- Xlib headers + + +Installation +------------ + +Copy `config.def.mk` to `config.mk` and edit it to match your setup. + +Compile it: + + make + +Install dwmclock (needs to be run as root if installing to `/usr` or `/usr/local`): + + make instal + +Install dwmclock to ~/bin: + + make DESTDIR=$HOME PREFIX= install + + +Usage +----- + +Amp it off in your ~/.xinitrc: + + dwmclock & diff --git a/config.def.mk b/config.def.mk new file mode 100644 index 0000000..a01d057 --- /dev/null +++ b/config.def.mk @@ -0,0 +1,32 @@ +# dwmclock settings + +# enable battery charge display +CFLAGS+=-DBATTERY + +# set this to the correct path for your current system +CFLAGS+=-DENERGY_FULL=\"/sys/class/power_supply/BAT0/energy_full\" +CFLAGS+=-DENERGY_NOW=\"/sys/class/power_supply/BAT0/energy_now\" + +# possible alternative on some systems +#CFLAGS+=-DENERGY_FULL=\"/sys/class/power_supply/BAT0/charge_full\" +#CFLAGS+=-DENERGY_NOW=\"/sys/class/power_supply/BAT0/charge_now\" + +# every how many seconds to refresh the battery charge display +CFLAGS+=-DBAT_REFRESH_SECONDS=60 + +# this is here for legacy reasons, ignore it +CFLAGS+=-DMUL=1 + + +# make settings + +# default compiler +CC?=gcc + +# compiler flags +CFLAGS+=-std=c99 -Wall -Wextra -pedantic -O2 $(shell pkg-config --cflags x11) +LDFLAGS+=$(shell pkg-config --libs x11) + +# default paths +DESTDIR?=/ +PREFIX?=/usr/local diff --git a/dwmclock.c b/dwmclock.c new file mode 100644 index 0000000..cc4b5b2 --- /dev/null +++ b/dwmclock.c @@ -0,0 +1,120 @@ +#define _GNU_SOURCE + +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#include <X11/Xlib.h> + + +int stop = 0; + +#ifdef BATTERY +int getnum(char *fn) +{ + char buf[1024]; + FILE *f; + int len; + + f = fopen(fn, "r"); + if (!f) { + return -1; + } + len = fread(buf, 1, 1023, f); + if (ferror(f)) { + return -1; + } + fclose(f); + if (len > 1022 || len < 1) { + return -1; + } + buf[1023] = '\0'; + + return atoi(buf); +} +#endif + +void handler(int sig) +{ + stop = sig; +} + +int main(void) +{ + struct tm *tm; + time_t now; +#ifdef BATTERY + long long curr, max, a=-1, b=-1, i; + char name[8 + 9]; /* (p)pp.pp% hh:mm:ss\0 */ + char *perc = name; + char *clock = name + 8; +#else + char name[9]; /* hh:mm:ss\0 */ + char *clock = name; +#endif + struct sigaction act; + Display *disp; + int screen; + Window root; + + act.sa_handler = handler; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + sigaction(SIGHUP, &act, NULL); + sigaction(SIGINT, &act, NULL); + sigaction(SIGQUIT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + + + disp = XOpenDisplay(NULL); +#ifdef BATTERY + for (i=0; !stop; ++i) { +#else + while (!stop) { +#endif + if (!disp) { + puts("Cannot open display!"); + return 1; + } + screen = DefaultScreen(disp); + root = RootWindow(disp, screen); +#ifdef BATTERY + if (i % (BAT_REFRESH_SECONDS) == 0) { + curr = getnum(ENERGY_NOW) * MUL; + max = getnum(ENERGY_FULL); + if (curr < 0 || max < 1) { + a = b = -1; + } else { + a = curr * 10000 / max; + b = a % 100; + a /= 100; + } + } + + if (a < 0 || b < 0) { + snprintf(perc, 8, "NO BAT "); + } else if (a < 0 || a > 999999 || b < 0 || b > 99) { + snprintf(perc, 8, "INVALID"); + } else if (a > 999) { + snprintf(perc, 8, "%6lld%%", a); + } else { + snprintf(perc, 8, "%3lld.%02lld%%", a, b); + } + perc[7] = ' '; +#endif + + now = time(NULL); + tm = localtime(&now); + strftime(clock, 9, "%H:%M:%S", tm); + + XStoreName(disp, root, name); + XFlush(disp); + sleep(1); + } + XCloseDisplay(disp); + + + return 0; +} |