Commit Diff


commit - ad1def98c884347fd9d1321841777ed29f994816
commit + e9b9d7ba59f2496ff89c85de31424d5f386a57f1
blob - 7046dcb753237f944fcd1c772b1a43093889d7c5
blob + 31153c068ee4a709a48d8a194869f010b4732cdb
--- Makefile
+++ Makefile
@@ -36,9 +36,11 @@ HDR_NETRIS	= netris/input.h				\
 		  netris/screen.h				\
 		  netris/tetris.h
 
+SRC_TMR		= bedstatus/timer
+
 MAN		= dwm/dwm.1 st/st.1 dmenu/dmenu.1 dmenu/stest.1 slock/slock.1 netris/netris.6
 
-all: bin/dwm bin/st bin/bedstatus bin/dmenu bin/stest bin/xbgcd bin/slock bin/pinentry-dmenu2 bin/netris
+all: bin/dwm bin/st bin/bedstatus bin/dmenu bin/stest bin/xbgcd bin/slock bin/pinentry-dmenu2 bin/netris bin/timer
 
 check:
 	find etc/common etc/$$(uname) -not -type d | awk '{a=$$0; sub(/etc\/[^\/]+/, "/etc", a); system("diff -u " $$0 " " a)}'
@@ -118,4 +120,9 @@ bin/netris: ${SRC_NETRIS} ${HDR_NETRIS}
 	@mkdir -p bin
 	${CC} -o $@ ${SRC_NETRIS} ${CFLAGS} `pkg-config --cflags --libs ncurses`
 
+bin/timer: ${SRC_TMR}
+	@mkdir -p bin
+	cp -f ${SRC_TMR} $@
+	chmod +x $@
+
 .PHONY: all clean install
blob - befa2ddf62ffac435edb529ff128c0769c09f532
blob + 596bbd3b6e2b4f19707ff97b01731a24f6d28974
--- bedstatus/bedstatus.c
+++ bedstatus/bedstatus.c
@@ -1,5 +1,6 @@
 #include <X11/Xlib.h>
 #include <unistd.h>
+#include <signal.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -27,7 +28,15 @@
 
 static size_t pos;
 static char buf[256];
+static char *timerpath;
+static int timer_ttl = 0;
 
+static void sig_reset (int sig)
+{
+	(void)sig;
+	timer_ttl = 0;
+}
+
 static void append (const char *fmt, ...)
 {
 	va_list ap;
@@ -119,6 +128,36 @@ done:
 	append ("] ");
 }
 
+static void append_duration (const time_t sec)
+{
+	time_t rem = sec;
+	struct unit {
+		char c;
+		time_t v;
+	} units[] = {
+		{ 'd',	24 * 60 * 60 },
+		{ 'h',	     60 * 60 },
+		{ 'm',	      1 * 60 },
+		{ 's',	           1 },
+		{ '\0',	           0 },
+	};
+
+	if (sec == 0) {
+		append ("0s");
+		return;
+	}
+
+	for (size_t i = 0; units[i].v != 0; ++i) {
+		const struct unit u = units[i];
+
+		if (rem < u.v)
+			continue;
+
+		append ("%u%c", rem / u.v, u.c);
+		rem %= u.v;
+	}
+}
+
 static void format_bat (const struct status *st)
 {
 	if (!st->has_bat_charging && !st->has_bat_perc && !st->has_bat_rem && !st->has_power)
@@ -150,27 +189,8 @@ static void format_bat (const struct status *st)
 	}
 
 	if (st->has_bat_rem) {
-		unsigned rem = st->bat_rem;
-		struct unit {
-			char c;
-			unsigned v;
-		} units[] = {
-			{ 'd',	24 * 60 },
-			{ 'h',	     60 },
-			{ 'm',	      1 },
-			{ '\0',	      0 },
-		};
+		append_duration (st->bat_rem * 60);
 
-		for (size_t i = 0; units[i].v != 0; ++i) {
-			const struct unit u = units[i];
-
-			if (rem < u.v)
-				continue;
-
-			append ("%u%c", rem / u.v, u.c);
-			rem %= u.v;
-		}
-
 		if (st->has_power)
 			append ("/");
 	}
@@ -187,6 +207,60 @@ static void format_bat (const struct status *st)
 	append ("] ");
 }
 
+static time_t fetch_timer (void)
+{
+	static time_t timer = 0;
+	char buf[32], *endp, *s;
+	FILE *file;
+
+	if (timer_ttl > 0) {
+		--timer_ttl;
+		return timer;
+	}
+
+	file = fopen (timerpath, "r");
+
+	if (file == NULL)
+		goto fail;
+
+	s = fgets (buf, sizeof (buf), file);
+	fclose (file);
+
+	if (s == NULL)
+		goto fail;
+
+	timer = strtoul (buf, &endp, 10);
+	if (*endp != '\0' && *endp != '\n')
+		goto fail;
+
+	timer_ttl = 30;
+	return timer;
+fail:
+	timer = 0;
+	timer_ttl = 15;
+	return 0;
+}
+
+static void format_timer (void)
+{
+	time_t now, diff, timer = fetch_timer ();
+
+	if (timer == 0)
+		return;
+
+	now = time (NULL);
+	diff = timer - now;
+	append ("[TMR ");
+
+	if (diff >= 0) {
+		append_duration (diff);
+	} else {
+		append ("ELAPSED");
+	}
+
+	append ("] ");
+}
+
 static void format_time (void)
 {
 	struct tm *tm;
@@ -202,6 +276,7 @@ static void format_status (const struct status *st)
 	format_cpu (st);
 	format_ram (st);
 	format_bat (st);
+	format_timer ();
 	format_time ();
 }
 
@@ -210,6 +285,7 @@ int main (int argc, char *argv[])
 	Display *dpy;
 	int screen;
 	unsigned long root;
+	const char *tmp;
 
 	(void)argv;
 	
@@ -225,6 +301,13 @@ int main (int argc, char *argv[])
 	screen = XDefaultScreen (dpy);
 	root = XRootWindow (dpy, screen);
 
+	tmp = getenv ("XDG_RUNTIME_DIR");
+	if (tmp == NULL)
+		tmp = "/tmp";
+
+	asprintf (&timerpath, "%s/bedstatus-timer", tmp);
+
+	signal (SIGUSR1, sig_reset);
 	init_backend ();
 
 	while (1) {
blob - /dev/null
blob + 3cee31b77f6b04aca658fb3c0a7f7706ede06435 (mode 755)
--- /dev/null
+++ bedstatus/timer
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+timerfile="${XDG_RUNTIME_DIR}/bedstatus-timer"
+
+usage() {
+	echo "Usage: timer [-r|-s duration]"
+	exit 1
+}
+
+update() {
+	pkill -USR1 bedstatus
+}
+
+set_timer() {
+	dur=$1
+	now=$(date +%s)
+	timer=$((now + dur))
+	echo "$timer" > "$timerfile"
+	update
+}
+
+args=$(getopt 'hs:r' $*)
+[ $? -ne 0 ] && usage
+
+set -- $args
+
+while true; do
+	case "$1" in
+	-r)
+		rm -f "$timerfile"
+		update
+		exit
+		;;
+	-s)
+		set_timer "$2"
+		exit
+		;;
+	--)
+		shift
+		break
+		;;
+	-*)
+		usage
+		exit 1
+		;;
+	esac
+done
+
+cat "$timerfile"