diff options
author | Mattias Andrée <maandree@kth.se> | 2022-07-30 17:00:08 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2022-07-30 17:00:08 +0200 |
commit | 56bd57b5582ea4bbf3cf6f1a50457e64a4e295e8 (patch) | |
tree | 9b2d4d3e61e0d93ff58c41cf46c4f30226646b2f /test-visual.c | |
parent | Remove dependency on libevdev (mostly complete) + minor fixes (diff) | |
download | libgamepad-56bd57b5582ea4bbf3cf6f1a50457e64a4e295e8.tar.gz libgamepad-56bd57b5582ea4bbf3cf6f1a50457e64a4e295e8.tar.bz2 libgamepad-56bd57b5582ea4bbf3cf6f1a50457e64a4e295e8.tar.xz |
Minor improvements
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'test-visual.c')
-rw-r--r-- | test-visual.c | 106 |
1 files changed, 93 insertions, 13 deletions
diff --git a/test-visual.c b/test-visual.c index bd3a610..6e2b466 100644 --- a/test-visual.c +++ b/test-visual.c @@ -3,6 +3,8 @@ #include <sys/ioctl.h> #include <assert.h> +#include <poll.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -18,10 +20,29 @@ struct abs_axis { }; +static volatile sig_atomic_t sigwinch_received = 0; +static volatile sig_atomic_t sigint_received = 0; + + +static void +sigwinch_handler(int signo) +{ + (void) signo; + sigwinch_received = 1; +} + + +static void +sigint_handler(int signo) +{ + (void) signo; + sigint_received = 1; +} + + static const char * draw_axis(char buffer[], const struct abs_axis *axis, size_t len) { - /* TODO axis->value can actually be out of bounds */ char value_buf[sizeof(intmax_t) * 3 + 2]; size_t width, x, value_len; #ifdef __GNUC__ @@ -36,7 +57,9 @@ draw_axis(char buffer[], const struct abs_axis *axis, size_t len) value_len = (size_t)sprintf(value_buf, "%ji", axis->value); x = axis->max_len + (width - value_len) / 2; memcpy(&buffer[x], value_buf, value_len); - x = (size_t)(axis->value - axis->min) * len; + x = (size_t)(axis->value < axis->min ? 0 : /* this actually happens */ + axis->value > axis->max ? axis->max - axis->min : + axis->value - axis->min) * len; x += (size_t)(axis->max - axis->min) / 2; x /= (size_t)(axis->max - axis->min); memmove(&buffer[x + sizeof("\033[m") - 1], &buffer[x], len + 1 - x); @@ -51,35 +74,70 @@ main(int argc, char *argv[]) const struct input_absinfo *absinfo; struct libgamepad_input_event event; struct libgamepad_device gamepad; - const char **button_names = NULL; - size_t max_button_name_len = 0; + const char **button_names; + size_t max_button_name_len; size_t len, x, y, i; struct winsize size; - size_t button_columns = 0; - size_t button_rows = 0; - size_t max_abs_axis_name_len = 0; - struct abs_axis *abs_axes = NULL; + size_t button_columns; + size_t button_rows; + size_t max_abs_axis_name_len; + struct abs_axis *abs_axes; char *buffer; ssize_t saxis_len; size_t axis_len, req_axis_len; - size_t max_max_len = 0, max_min_len = 0; + size_t max_max_len, max_min_len; ssize_t r; + struct pollfd pfd; + struct sigaction action; if (argc != 2) { fprintf(stderr, "Please provide the path to the subdevice as the only command line argument\n"); return 1; } - if (libgamepad_open_device(&gamepad, AT_FDCWD, argv[1], O_RDONLY)) { + if (libgamepad_open_device(&gamepad, AT_FDCWD, argv[1], O_RDONLY | O_NONBLOCK)) { perror("libgamepad_open_device"); return 1; } - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &size)) { - perror("TIOCGWINSZ"); + pfd.fd = gamepad.fd; + pfd.events = POLLIN; + pfd.revents = 0; + + memset(&action, 0, sizeof(action)); + action.sa_handler = sigwinch_handler; + if (sigaction(SIGWINCH, &action, NULL)) { + perror("sigaction"); + return 1; + } + + memset(&action, 0, sizeof(action)); + action.sa_handler = sigint_handler; + if (sigaction(SIGINT, &action, NULL)) { + perror("sigaction"); return 1; } +redraw: + button_names = NULL; + max_button_name_len = 0; + button_columns = 0; + button_rows = 0; + max_abs_axis_name_len = 0; + abs_axes = NULL; + max_max_len = 0; + max_min_len = 0; + + while (ioctl(STDOUT_FILENO, TIOCGWINSZ, &size)) { + if (errno != EINTR) { + perror("TIOCGWINSZ"); + return 1; + } + sigwinch_received = 0; + if (sigint_received) + goto out; + } + size.ws_row = size.ws_row < 1 ? 1 : size.ws_row; size.ws_col = size.ws_col < 1 ? 1 : size.ws_col; @@ -151,11 +209,28 @@ main(int argc, char *argv[]) fflush(stdout); for (;;) { - /* TODO use nonblocking; listen for window resize */ + if (sigwinch_received) { + sigwinch_received = 0; + free(button_names); + free(abs_axes); + free(buffer); + goto redraw; + } + if (sigint_received) + break; + + if (poll(&pfd, 1, -1) < 0) { + if (errno == EINTR) + continue; + break; + } + r = libgamepad_next_event(&gamepad, &event, 1); if (r <= 0) { if (!r || errno == EINTR) continue; + if (errno == EAGAIN) + break; perror("libgamepad_next_event"); return 1; } @@ -179,5 +254,10 @@ main(int argc, char *argv[]) /* TODO add relative axis */ } +out: + free(buffer); + free(button_names); + free(abs_axes); + libgamepad_close_device(&gamepad); return 0; } |