diff options
| author | Mattias Andrée <maandree@kth.se> | 2021-03-28 15:56:30 +0200 |
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2021-03-28 15:56:30 +0200 |
| commit | c81d9bb46450ffbd7851e5bc38f7c7aabbc3b220 (patch) | |
| tree | bcfbcbdb7cde6b01470fc5c68bf5104e30899d2d | |
| parent | stopwatch: do not reset when saving lap time (diff) | |
| download | pdatools-c81d9bb46450ffbd7851e5bc38f7c7aabbc3b220.tar.gz pdatools-c81d9bb46450ffbd7851e5bc38f7c7aabbc3b220.tar.bz2 pdatools-c81d9bb46450ffbd7851e5bc38f7c7aabbc3b220.tar.xz | |
Add counter
Signed-off-by: Mattias Andrée <maandree@kth.se>
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | clock.c | 9 | ||||
| -rw-r--r-- | counter.c | 258 | ||||
| -rwxr-xr-x | large.sh | 27 | ||||
| -rw-r--r-- | stopwatch.c | 2 |
5 files changed, 290 insertions, 7 deletions
@@ -10,6 +10,7 @@ HDR =\ BIN_ =\ backlight\ clock\ + counter\ stopwatch OBJ =\ @@ -5,6 +5,7 @@ USAGE("[-u | -v | -w] [-2s]"); +#define INCLUDE_LARGE_COLON #include "large.h" @@ -152,7 +153,7 @@ display_clock(int timerfd) printf("\033[H"); - if (x >= 6 * LARGE_XD + 2 * LARGE_XC && y > LARGE_Y + 1) { + if (x >= 6 * LARGE_X + 2 * LARGE_XC && y > LARGE_Y + 1) { if (y > LARGE_Y + 6) printf("\033[K\n"); digits[0] = large_digits[now->tm_hour / 10]; @@ -163,11 +164,11 @@ display_clock(int timerfd) digits[5] = large_colon; digits[6] = large_digits[now->tm_sec / 10]; digits[7] = large_digits[now->tm_sec % 10]; - width = 6 * LARGE_XD + 2 * LARGE_XC; + width = 6 * LARGE_X + 2 * LARGE_XC; print_time(digits, (x - width) / 2, LARGE_Y); printf("\033[K\n"); r = LARGE_Y + 1; - } else if (with_small && x >= 6 * SMALL_XD + 2 * SMALL_XC && y > SMALL_Y + 1) { + } else if (with_small && x >= 6 * SMALL_X + 2 * SMALL_XC && y > SMALL_Y + 1) { if (y > SMALL_Y + 6) printf("\033[K\n"); digits[0] = small_digits[now->tm_hour / 10]; @@ -178,7 +179,7 @@ display_clock(int timerfd) digits[5] = small_colon; digits[6] = small_digits[now->tm_sec / 10]; digits[7] = small_digits[now->tm_sec % 10]; - width = 6 * SMALL_XD + 2 * SMALL_XC; + width = 6 * SMALL_X + 2 * SMALL_XC; print_time(digits, (x - width) / 2, SMALL_Y); printf("\033[K\n"); r = SMALL_Y + 1; diff --git a/counter.c b/counter.c new file mode 100644 index 0000000..df9c3f2 --- /dev/null +++ b/counter.c @@ -0,0 +1,258 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +/* TODO add buttons */ + +USAGE("[-2s]"); + + +#define INCLUDE_LARGE_MINUS +#include "large.h" + + +static volatile sig_atomic_t caught_sigterm = 0; +static volatile sig_atomic_t caught_sigwinch = 1; +static volatile sig_atomic_t caught_sigio = 1; +static int with_small = 0; +static int with_quad = 0; + +static const char **large_digits[] = { + large_0, large_1, large_2, large_3, large_4, + large_5, large_6, large_7, large_8, large_9 +}; + +static const char **small_digits[] = { + small_0, small_1, small_2, small_3, small_4, + small_5, small_6, small_7, small_8, small_9 +}; + + + +static void +sigterm(int signo) +{ + caught_sigterm = 1; + (void) signo; +} + +static void +sigwinch(int signo) +{ + caught_sigwinch = 1; + (void) signo; +} + +static void +sigio(int signo) +{ + caught_sigio = 1; + (void) signo; +} + + +static void +print_number(const char ***str, int left, size_t height) +{ + size_t r, c; + + for (r = 0;;) { + printf("%*.s", left, ""); + for (c = 0; str[c]; c++) + fprintf(stdout, "%s", str[c][r]); + if (++r == height) { + fprintf(stdout, "\033[K"); + break; + } else { + fprintf(stdout, "\033[K\n"); + } + } +} + + +static int +display_counter(void) +{ + char buf[sizeof(intmax_t) * 3 + 2]; + const char **digits[sizeof(intmax_t) * 3 + 2]; + intmax_t counter = {0}; + int r, i, x = 0, y = 0, was_quad = 0, len, width; + struct winsize winsize; + char c; + ssize_t rd; + + while (!caught_sigterm) { + if (caught_sigwinch) { + if (ioctl(STDOUT_FILENO, (unsigned long)TIOCGWINSZ, &winsize) < 0) { + if (errno == EINTR) + continue; + goto fail; + } + caught_sigwinch = 0; + y = winsize.ws_row; + x = winsize.ws_col; + if (was_quad) { + was_quad = 0; + for (r = 0; r < y; r++) + printf("%s\033#5", r ? "\n" : "\033[H"); + } + } + + if (caught_sigio) { + caught_sigio = 0; + for (;;) { + rd = read(STDIN_FILENO, &c, 1); + if (rd <= 0) { + if (!rd) + goto out; + if (errno == EAGAIN) + break; + if (errno == EINTR) + continue; + goto fail; + } + if (c == 'q') + goto out; + else if (c == 'r') + counter = 0; + else if (c == '+' || c == 'C') + counter += 1; + else if (c == '-' || c == 'D') + counter -= 1; + } + } + + len = sprintf(buf, "%ji", counter); + + printf("\033[H"); + + if (x >= (width = len * LARGE_X + (counter < 0 ? LARGE_XM - LARGE_X : 0)) && y >= LARGE_Y) { + for (r = 0; r < (y - LARGE_Y) / 2; r++) + printf("\033[K\n"); + for (i = 0; i < len; i++) { + if (isdigit(buf[i])) + digits[i] = large_digits[buf[i] & 15]; + else + digits[i] = large_minus; + } + digits[i] = NULL; + print_number(digits, (x - width) / 2, LARGE_Y); + } else if (with_small && x >= (width = len * SMALL_X + (counter < 0 ? SMALL_XM - SMALL_X : 0)) && y > SMALL_Y + 1) { + for (r = 0; r < (y - SMALL_Y) / 2; r++) + printf("\033[K\n"); + for (i = 0; i < len; i++) { + if (isdigit(buf[i])) + digits[i] = small_digits[buf[i] & 15]; + else + digits[i] = small_minus; + } + digits[i] = NULL; + print_number(digits, (x - width) / 2, SMALL_Y); + } else if (with_quad && x > len * 2 && y > 2) { + printf("\033#3%*.s%s\033[K\n", (x / 2 - len) / 2, "", buf); + printf("\033#4%*.s%s\033[K\n", (x / 2 - len) / 2, "", buf); + printf("\033#5"); + was_quad = 1; + } else { + printf("%*.s%s\033[K", (x - len) / 2, "", buf); + } + + printf("\033[J"); + fflush(stdout); + + pause(); + } + +out: + return 0; + +fail: + return -1; +} + + +int +main(int argc, char *argv[]) +{ + int tcset = 0, old_flags = -1, old_sig = 0, owner_set = 0; + struct sigaction sigact; + struct termios stty, saved_stty; + struct f_owner_ex old_owner, new_owner; + + ARGBEGIN { + case '2': + with_quad = 1; + break; + case 's': + with_small = 1; + break; + default: + usage(); + } ARGEND; + + if (argc) + usage(); + + tzset(); + + fprintf(stdout, "\033[?1049h\033[?25l"); + + memset(&sigact, 0, sizeof(sigact)); + + sigact.sa_handler = sigterm; + sigaction(SIGTERM, &sigact, NULL); + sigaction(SIGQUIT, &sigact, NULL); + sigaction(SIGINT, &sigact, NULL); + + sigact.sa_handler = sigwinch; + sigaction(SIGWINCH, &sigact, NULL); + + sigact.sa_handler = sigio; + sigaction(SIGIO, &sigact, NULL); + sigaction(SIGURG, &sigact, NULL); + + if (fcntl(STDIN_FILENO, F_GETOWN_EX, &old_owner)) + goto fail; + memset(&new_owner, 0, sizeof(new_owner)); + new_owner.type = F_OWNER_PID; + new_owner.pid = getpid(); + if (fcntl(STDIN_FILENO, F_SETOWN_EX, &new_owner)) + goto fail; + owner_set = 1; + old_flags = fcntl(STDIN_FILENO, F_GETFL); + fcntl(STDIN_FILENO, F_SETFL, old_flags | FASYNC | O_NONBLOCK); + fcntl(STDIN_FILENO, F_GETSIG, &old_sig); + if (old_sig) + fcntl(STDIN_FILENO, F_SETSIG, 0); + + if (!tcgetattr(STDIN_FILENO, &stty)) { + saved_stty = stty; + stty.c_lflag &= (tcflag_t)~(ECHO | ICANON); + tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty); + tcset = 1; + } + + if (display_counter()) + goto fail; + + fprintf(stdout, "\033[?25h\n\033[?1049l"); + fflush(stdout); + fcntl(STDIN_FILENO, F_SETOWN_EX, &old_owner); + fcntl(STDIN_FILENO, F_SETFL, old_flags); + fcntl(STDIN_FILENO, F_SETSIG, old_sig); + tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty); + return 0; + +fail: + perror(argv0 ? argv0 : "counter"); + fprintf(stdout, "\033[?25h\n\033[?1049l"); + fflush(stdout); + if (owner_set) + fcntl(STDIN_FILENO, F_SETOWN_EX, &old_owner); + if (old_flags != -1) + fcntl(STDIN_FILENO, F_SETFL, old_flags); + if (old_sig) + fcntl(STDIN_FILENO, F_SETSIG, old_sig); + if (tcset) + tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty); + return 1; +} @@ -121,15 +121,33 @@ large_colon() { ' ' } +large_minus() { + printf '%s\n' \ + ' ' \ + ' ' \ + ' ' \ + '[XXXXXX] ' \ + ' ' \ + ' ' \ + ' ' +} + printf '#define LARGE_Y %i\n' $(large_0 | wc -l) -printf '#define LARGE_XD %i\n' $(large_0 | head -n 1 | tr -d '\n' | wc -c) +printf '#define LARGE_X %i\n' $(large_0 | head -n 1 | tr -d '\n' | wc -c) printf '#define LARGE_XC %i\n' $(large_colon | head -n 1 | tr -d '\n' | wc -c) +printf '#define LARGE_XM %i\n' $(large_minus | head -n 1 | tr -d '\n' | wc -c) printf '#define SMALL_Y %i\n' $(expr \( $(large_0 | wc -l) + 1 \) / 2) -printf '#define SMALL_XD %i\n' $(expr \( $(large_0 | head -n 1 | tr -d '\n' | wc -c) + 1 \) / 2) +printf '#define SMALL_X %i\n' $(expr \( $(large_0 | head -n 1 | tr -d '\n' | wc -c) + 1 \) / 2) printf '#define SMALL_XC %i\n' $(expr \( $(large_colon | head -n 1 | tr -d '\n' | wc -c) + 1 \) / 2) +printf '#define SMALL_XM %i\n' $(expr \( $(large_minus | head -n 1 | tr -d '\n' | wc -c) + 1 \) / 2) -for c in 0 1 2 3 4 5 6 7 8 9 colon; do +for c in 0 1 2 3 4 5 6 7 8 9 colon minus; do + if test $c = colon; then + printf '%s\n' '#ifdef INCLUDE_LARGE_COLON' + elif test $c = minus; then + printf '%s\n' '#ifdef INCLUDE_LARGE_MINUS' + fi printf 'static const char *large_%s[] = {\n' $c large_$c | \ sed -e 's/X/ /g' -e 's/\[/\\033\[7m /g' -e 's/\]/ \\033\[m/g' | \ @@ -191,4 +209,7 @@ for c in 0 1 2 3 4 5 6 7 8 9 colon; do printf '\n' done | sed -e 's/^/"/' -e 's/$/",/' | sed '$s/,$//' printf '};\n' + if test $c = colon || test $c = minus; then + printf '%s\n' '#endif' + fi done diff --git a/stopwatch.c b/stopwatch.c index b978753..5bfa69c 100644 --- a/stopwatch.c +++ b/stopwatch.c @@ -1,6 +1,8 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" +/* TODO add clickable buttons */ + USAGE("[-2]"); static volatile sig_atomic_t caught_sigterm = 0; |
