diff options
author | Mattias Andrée <maandree@operamail.com> | 2015-09-12 03:28:10 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2015-09-12 03:28:10 +0200 |
commit | 94d6a544615e8c420ae1390086364c4199c60e2b (patch) | |
tree | e6a60a47b8c681f04a6f9b1ff053fbda2f2cad08 /src/mongoclock.c | |
parent | arch does not use /libexec (diff) | |
download | mongotimer-94d6a544615e8c420ae1390086364c4199c60e2b.tar.gz mongotimer-94d6a544615e8c420ae1390086364c4199c60e2b.tar.bz2 mongotimer-94d6a544615e8c420ae1390086364c4199c60e2b.tar.xz |
port to c + reduce flicker + use timerfd
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src/mongoclock.c')
-rw-r--r-- | src/mongoclock.c | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/src/mongoclock.c b/src/mongoclock.c new file mode 100644 index 0000000..781b7b4 --- /dev/null +++ b/src/mongoclock.c @@ -0,0 +1,304 @@ +/** + * Copyright © 2013, 2015 Mattias Andrée (maandree@member.fsf.org) + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. [GNU All Permissive License] + */ +#define _GNU_SOURCE +#include <stdio.h> +#include <time.h> +#include <stddef.h> +#include <unistd.h> +#include <signal.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/timerfd.h> + +$< +d() { + echo '"'"$(echo "$1" | sed -e 's/X/ /g' -e 's/\[/\\033\[7m /g' -e 's/\]/\\033\[m /g')"'"' +} +$> + +#define DX 16 +#define DY 12 +static const char* mongo_0[] = {$(d ' [XXXX] '), + $(d ' [XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [] [XX] '), + $(d '[XX] [] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d ' [XX] [XX] '), + $(d ' [XXXX] ')}; + +static const char* mongo_1[] = {$(d ' [XX] '), + $(d ' [XXXX] '), + $(d ' [XXXXXX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XXXXXXXXXX] ')}; + +static const char* mongo_2[] = {$(d ' [XXXXXXXX] '), + $(d '[XX] [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d '[XX] '), + $(d '[XX] [XX] '), + $(d '[XXXXXXXXXXXX] ')}; + +static const char* mongo_3[] = {$(d ' [XXXXXXXX] '), + $(d '[XX] [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XXXXXX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d '[XX] [XX] '), + $(d ' [XXXXXXXX] ')}; + +static const char* mongo_4[] = {$(d ' [XX] '), + $(d ' [XXXX] '), + $(d ' [XXXXXX] '), + $(d ' [XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XXXXXXXXXXXX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XXXXXX] ')}; + +static const char* mongo_5[] = {$(d '[XXXXXXXXXXXX] '), + $(d '[XX] '), + $(d '[XX] '), + $(d '[XX] '), + $(d '[XX] '), + $(d '[XXXXXXXXXX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d '[XX] [XX] '), + $(d ' [XXXXXXXX] ')}; + +static const char* mongo_6[] = {$(d ' [XXXX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d '[XX] '), + $(d '[XX] '), + $(d '[XXXXXXXXXX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d ' [XXXXXXXX] ')}; + +static const char* mongo_7[] = {$(d '[XXXXXXXXXXXX] '), + $(d '[XX] [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] ')}; + +static const char* mongo_8[] = {$(d ' [XXXXXXXX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d ' [XXXXXXXX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d ' [XXXXXXXX] ')}; + +static const char* mongo_9[] = {$(d ' [XXXXXXXX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d '[XX] [XX] '), + $(d ' [XXXXXXXXXX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' [XXXX] ')}; + +#define DC 16 +static const char* mongo_c[] = {$(d ' '), + $(d ' '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' '), + $(d ' '), + $(d ' '), + $(d ' '), + $(d ' [XX] '), + $(d ' [XX] '), + $(d ' '), + $(d ' ')}; + +static const char** mongo_ds[] = { + mongo_0, mongo_1, mongo_2, mongo_3, mongo_4, + mongo_5, mongo_6, mongo_7, mongo_8, mongo_9}; + + +static volatile sig_atomic_t caught_sigterm = 0; +static volatile sig_atomic_t caught_sigwinch = 1; + + +#define t(...) do if ((__VA_ARGS__) < 0) goto fail; while (0) + + +static void sigterm(int signo) +{ + caught_sigterm = 1; + (void) signo; +} + +static void sigwinch(int signo) +{ + caught_sigwinch = 1; + (void) signo; +} + + +static void print_time(const char*** str, size_t y, size_t x) +{ + size_t r, c; + + fprintf(stdout, "\033[%zu;1H\033[1J", y + 1); + + for (r = 0; r < DY; r++) + { + fprintf(stdout, "\033[%zu;%zuH\033[1K", y + r + 1, x + 1); + for (c = 0; str[c] != NULL; c++) + fprintf(stdout, "%s", str[c][r]); + fprintf(stdout, "\033[0K"); + } + + fprintf(stdout, "\033[0J"); + fflush(stdout); +} + + +int main(int argc, char* argv[]) +{ + time_t now_; + struct tm* now; + const char** digits[9]; + size_t x = 0, y = 0; + struct winsize winsize; + int small = 0, fd; + struct itimerspec itimerspec; + char _buf[8]; + + fprintf(stdout, "\033[?1049h\033[?25l"); + + t (clock_gettime(CLOCK_REALTIME, &(itimerspec.it_value))); + itimerspec.it_interval.tv_sec = 1; + itimerspec.it_interval.tv_nsec = 0; + itimerspec.it_value.tv_sec += 1; + itimerspec.it_value.tv_nsec = 0; + t (fd = timerfd_create(CLOCK_REALTIME, 0)); + t (timerfd_settime(fd, TFD_TIMER_ABSTIME, &itimerspec, NULL)); + + signal(SIGTERM, sigterm); + signal(SIGQUIT, sigterm); + signal(SIGINT, sigterm); + signal(SIGWINCH, sigwinch); + + while (!caught_sigterm) + { + if (caught_sigwinch) + { + caught_sigwinch = 0; + t (TEMP_FAILURE_RETRY(ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize))); + y = winsize.ws_row; + x = winsize.ws_col; + if (y < DY) small = 2; + else if (x < 4 * DX + DC) small = 2; + else if (x < 6 * DX + 2 * DC) small = 1; + else small = 0; + y -= DY; + x -= 4 * DX + DC; + if (!small) + x -= 2 * DX + DC; + y /= 2; + x /= 2; + } + + if (small == 2) + { + fprintf(stdout, "\033[H\033[2J%s\n", "Screen is too small"); + fflush(stdout); + pause(); + continue; + } + + now_ = time(NULL); + if (now_ == -1) goto fail; + now = localtime(&now_); + if (now == NULL) goto fail; + + digits[0] = mongo_ds[now->tm_hour / 10]; + digits[1] = mongo_ds[now->tm_hour % 10]; + digits[2] = mongo_c; + digits[3] = mongo_ds[now->tm_min / 10]; + digits[4] = mongo_ds[now->tm_min % 10]; + digits[5] = small ? NULL : mongo_c; + digits[6] = mongo_ds[now->tm_sec / 10]; + digits[7] = mongo_ds[now->tm_sec % 10]; + digits[8] = NULL; + + print_time(digits, y, x); + + if (read(fd, _buf, 8) < 0) + if (errno != EINTR) + goto fail; + } + + fprintf(stdout, "\033[?25h\n\033[?1049l"); + fflush(stdout); + TEMP_FAILURE_RETRY(close(fd)); + return 0; + + fail: + perror(*argv); + fprintf(stdout, "\033[?25h\n\033[?1049l"); + fflush(stdout); + TEMP_FAILURE_RETRY(close(fd)); + return 1; + (void) argc; +} + |