From 94d6a544615e8c420ae1390086364c4199c60e2b Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 12 Sep 2015 03:28:10 +0200 Subject: port to c + reduce flicker + use timerfd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- .gitignore | 6 ++ COPYING | 2 +- src/mongoclock.c | 304 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 src/mongoclock.c diff --git a/.gitignore b/.gitignore index d9823b8..d623f8b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,9 @@ __pycache__/ *.pdf *.ps *.dvi +*.o +*.out +*.so +*.su +*.gch + diff --git a/COPYING b/COPYING index 392a7fb..9774072 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright © 2013 Mattias Andrée (maandree@member.fsf.org) +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 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 +#include +#include +#include +#include +#include +#include +#include + +$< +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; +} + -- cgit v1.2.3-70-g09d2