diff options
Diffstat (limited to 'blkshowr.c')
| -rw-r--r-- | blkshowr.c | 85 |
1 files changed, 55 insertions, 30 deletions
@@ -42,6 +42,7 @@ static size_t term_width; static size_t term_height; static int exiting = 0; static int interrupt_deferred = 0; +static int deferred_redraw = 0; static size_t selected_block = 0u; static size_t first_visible_block = 0u; @@ -93,6 +94,8 @@ do_redraw(void) size_t right_pad; size_t text_top, text_bottom; + deferred_redraw = 0; + if (current_block_off != blocks[selected_block]) { off_t off; ssize_t r; @@ -456,7 +459,6 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input) return; /* TODO optimise redraw to only affected areas */ - /* TODO defer redraw until all repeations have been processed */ if (input->keypress.key == LIBTERMINPUT_UP) { if (selected_block > 0u) { @@ -464,7 +466,7 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input) line_count = 0u; selected_block -= 1u; ensure_selected_block_visible(); - do_redraw(); + deferred_redraw |= input->keypress.times <= 1u; } } else if (input->keypress.key == LIBTERMINPUT_DOWN) { @@ -473,7 +475,7 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input) line_count = 0u; selected_block += 1u; ensure_selected_block_visible(); - do_redraw(); + deferred_redraw |= input->keypress.times <= 1u; } } else if (input->keypress.key == LIBTERMINPUT_HOME) { @@ -482,7 +484,8 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input) line_count = 0u; selected_block = 0u; ensure_selected_block_visible(); - do_redraw(); + if (input->keypress.times <= 1u) + do_redraw(); } } else if (input->keypress.key == LIBTERMINPUT_END) { @@ -491,7 +494,8 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input) line_count = 0u; selected_block = nblocks - 1u; ensure_selected_block_visible(); - do_redraw(); + if (input->keypress.times <= 1u) + do_redraw(); } } else if (input->keypress.key == LIBTERMINPUT_PRIOR) { @@ -500,14 +504,16 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input) line_count = 0u; if (selected_block != first_visible_block) { selected_block = first_visible_block; - do_redraw(); + if (input->keypress.times <= 1u) + do_redraw(); } else { if (selected_block > term_height - 2u) selected_block -= term_height - 2u; else selected_block = 0u; ensure_selected_block_visible(); - do_redraw(); + if (input->keypress.times <= 1u) + do_redraw(); } } @@ -518,14 +524,16 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input) line_count = 0u; if (selected_block != last) { selected_block = last; - do_redraw(); + if (input->keypress.times <= 1u) + do_redraw(); } else { if (term_height - 2u > nblocks - 1u - selected_block) selected_block = nblocks - 1u; else selected_block += term_height - 2u; ensure_selected_block_visible(); - do_redraw(); + if (input->keypress.times <= 1u) + do_redraw(); } } } @@ -539,33 +547,34 @@ handle_keyboard_input_to_block_display(union libterminput_input *input) return; /* TODO optimise redraw to only affected areas */ - /* TODO defer redraw until all repeations have been processed */ if (input->keypress.key == LIBTERMINPUT_UP) { if (first_visible_line > 0u) { first_visible_line -= 1u; - do_redraw(); + deferred_redraw |= input->keypress.times <= 1u; } } else if (input->keypress.key == LIBTERMINPUT_DOWN) { if (line_count > first_visible_line && term_height > 2u) { if (term_height - 2u < line_count - first_visible_line) { first_visible_line += 1; - do_redraw(); + deferred_redraw |= input->keypress.times <= 1u; } } } else if (input->keypress.key == LIBTERMINPUT_HOME) { if (first_visible_line != 0u) { first_visible_line = 0u; - do_redraw(); + if (input->keypress.times <= 1u) + do_redraw(); } } else if (input->keypress.key == LIBTERMINPUT_END) { if (line_count && term_height > 2u && line_count > term_height - 1u) { if (first_visible_line != line_count - (term_height - 2u)) { first_visible_line = line_count - (term_height - 2u); - do_redraw(); + if (input->keypress.times <= 1u) + do_redraw(); } } @@ -575,7 +584,8 @@ handle_keyboard_input_to_block_display(union libterminput_input *input) first_visible_line = 0u; else first_visible_line -= term_height - 2u; - do_redraw(); + if (input->keypress.times <= 1u) + do_redraw(); } } else if (input->keypress.key == LIBTERMINPUT_NEXT) { @@ -589,7 +599,8 @@ handle_keyboard_input_to_block_display(union libterminput_input *input) first_visible_line = 0u; } if (first_visible_line != prev) - do_redraw(); + if (input->keypress.times <= 1u) + do_redraw(); } } } @@ -855,7 +866,7 @@ main(int argc, char *argv[]) struct libterminput_state input_ctx; union libterminput_input input; const char *listpath, *env; - int listfd; + int listfd, ttyfd_nb, fd; ARGBEGIN { case 'b': @@ -884,6 +895,13 @@ main(int argc, char *argv[]) eprintf("open /dev/tty O_RDWR:"); if (getpgrp() != tcgetpgrp(ttyfd)) eprintf("process not running in the foreground"); + /* O_NONBLOCK is on open file descriptor level and preadv2(2) (with RWF_NOWAIT) + * do not support TTYs (how knows why, pipes are supports, ...) */ + ttyfd_nb = open("/dev/tty", O_RDWR | O_NONBLOCK); + if (ttyfd_nb < 0) + eprintf("open /dev/tty O_RDWR|O_NONBLOCK:"); + if (getpgrp() != tcgetpgrp(ttyfd_nb)) + eprintf("process not running in the foreground"); /* Open block list */ listfd = get_fd(listpath); @@ -939,24 +957,31 @@ main(int argc, char *argv[]) } } - switch (libterminput_read(ttyfd, &input, &input_ctx)) { - case 1: - handle_keyboard_input(&input); - break; - case 0: - exiting = 1; - break; - default: - if (errno == EINTR) - interrupt_deferred = 1; - else - eprintf("libterminput_read /dev/tty:"); - break; + for (fd = ttyfd;; fd = ttyfd_nb) { + switch (libterminput_read(fd, &input, &input_ctx)) { + case 1: + handle_keyboard_input(&input); + break; + case 0: + exiting = 1; + goto read_blocked; + default: + if (errno == EINTR) + interrupt_deferred = 1; + else if (errno != EAGAIN) + eprintf("libterminput_read /dev/tty:"); + goto read_blocked; + } } + + read_blocked: + if (deferred_redraw) + do_redraw(); } while (!exiting); libterminput_destroy(&input_ctx); close(textfd); + close(ttyfd_nb); free(current_block_text); free(line_map); return 0; |
