From f9c196d049a29f0e56485f3dd9b43fd99dbec0d2 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 2 Dec 2015 16:44:02 +0100 Subject: center the text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/rq.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/src/rq.c b/src/rq.c index ee546e7..7e9b882 100644 --- a/src/rq.c +++ b/src/rq.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -40,7 +41,9 @@ /** * The default word rate. */ -#define DEFAULT_RATE 120 /* 2 hz */ +#ifndef DEFAULT_RATE +# define DEFAULT_RATE 120 /* 2 hz */ +#endif @@ -50,6 +53,56 @@ static const char *argv0; +/** + * Have the terminal been resized? + */ +static volatile sig_atomic_t caught_sigwinch = 1; + +/** + * The width of the terminal. + */ +static size_t width = 80; + +/** + * The height of the terminal. + */ +static size_t height = 30; + + + +/** + * Signal handler for SIGWINCH. + * Invoked when the terminal resizes. + */ +static void sigwinch(int signo) +{ + signal(signo, sigwinch); + caught_sigwinch = 1; +} + + + +/** + * Get the size of the terminal. + */ +static void get_terminal_size(void) +{ + struct winsize winsize; + + if (!caught_sigwinch) + return; + + caught_sigwinch = 0; + + while (ioctl(STDOUT_FILENO, (unsigned long)TIOCGWINSZ, &winsize) < 0) + if (errno != EINTR) + return; + + height = winsize.ws_row; + width = winsize.ws_col; +} + + /** * Get the selected word rate by reading @@ -96,6 +149,27 @@ static long get_word_rate(void) +/** + * Count the number of character in a string. + * + * Possible improvement: + * Figure out how many columns the terminal is + * likely to used to display the each character, + * and sum it. + * + * @param s The string. + * @return The number of characters in `s`. + */ +static size_t display_len(const char *s) +{ + size_t r = 0; + for (; *s; s++) + r += (((int)*s & 0xC0) != 0x80); + return r; +} + + + /** * Display a file word by word. * @@ -135,13 +209,15 @@ static int display_file(int fd, int ttyfd, long rate) /* Present file. */ for (s = buffer; *s; s = end) { + get_terminal_size(); while (isspace(*s)) s++; end = strpbrk(s, " \f\n\r\t\v"); if (end == NULL) end = strchr(s, '\0'); c = *end, *end = '\0'; - t (fprintf(stdout, "\033[H\033[2J%s", s) < 0); + t (fprintf(stdout, "\033[H\033[2J\033[%zu;%zuH%s", + (height + 1) / 2, (width - display_len(s)) / 2 + 1, s) < 0); t (fflush(stdout)); sleep(1); *end = c; @@ -217,6 +293,7 @@ int main(int argc, char *argv[]) tty_configured = 1; /* Display file. */ + signal(SIGWINCH, sigwinch); t (display_file(fd, ttyfd, rate)); /* Restore terminal configurations. */ -- cgit v1.2.3-70-g09d2