summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-03-28 15:56:30 +0200
committerMattias Andrée <maandree@kth.se>2021-03-28 15:56:30 +0200
commitc81d9bb46450ffbd7851e5bc38f7c7aabbc3b220 (patch)
treebcfbcbdb7cde6b01470fc5c68bf5104e30899d2d
parentstopwatch: do not reset when saving lap time (diff)
downloadpdatools-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--Makefile1
-rw-r--r--clock.c9
-rw-r--r--counter.c258
-rwxr-xr-xlarge.sh27
-rw-r--r--stopwatch.c2
5 files changed, 290 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index 285576d..aa7c54d 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,7 @@ HDR =\
BIN_ =\
backlight\
clock\
+ counter\
stopwatch
OBJ =\
diff --git a/clock.c b/clock.c
index c656d8f..c3040f4 100644
--- a/clock.c
+++ b/clock.c
@@ -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;
+}
diff --git a/large.sh b/large.sh
index 248f0d8..e1d2a22 100755
--- a/large.sh
+++ b/large.sh
@@ -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;