commit e9b9d7ba59f2496ff89c85de31424d5f386a57f1 from: Benjamin Stürz date: Sun Aug 04 11:52:25 2024 UTC bedstatus: add timer 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 #include +#include #include #include #include @@ -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"