aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--Makefile25
-rw-r--r--README.md35
-rw-r--r--config.def.mk32
-rw-r--r--dwmclock.c120
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;
+}