diff --git a/build.sh b/build.sh index c27767d..0093132 100755 --- a/build.sh +++ b/build.sh @@ -8,4 +8,4 @@ defs="-D_POSIX_C_SOURCE=200809L" $cc $flags $libs $defs \ -o asteroids \ - fb.c main.c renderer.c + fb.c input.c main.c renderer.c diff --git a/input.c b/input.c new file mode 100644 index 0000000..09ff76e --- /dev/null +++ b/input.c @@ -0,0 +1,56 @@ +#include "input.h" + +#include +#include +#include +#include +#include + +enum { + RELEASE = 0, + PRESS = 1, + REPEAT = 2, + NCALLBACKS, +}; + +static int input_fd; +static input_callback_t callbacks[NCALLBACKS]; + +int input_init() +{ + input_fd = open("/dev/input/event0", O_RDONLY); + assert(input_fd != -1); + memset(callbacks, 0, sizeof(callbacks)); + return input_fd; +} + +void input_cleanup() +{ + close(input_fd); +} + +void input_on_press(input_callback_t cb) +{ + callbacks[PRESS] = cb; +} + +void input_on_release(input_callback_t cb) +{ + callbacks[RELEASE] = cb; +} + +void input_on_repeat(input_callback_t cb) +{ + callbacks[REPEAT] = cb; +} + +void input_handle() +{ + struct input_event ev; + const int len = read(input_fd, &ev, sizeof(ev)); + assert(len == sizeof(ev)); + if (ev.type == EV_KEY && 0 <= ev.value && ev.value < NCALLBACKS) { + if (callbacks[ev.value] != nullptr) + callbacks[ev.value](ev.code); + } +} diff --git a/input.h b/input.h new file mode 100644 index 0000000..f06495e --- /dev/null +++ b/input.h @@ -0,0 +1,15 @@ +#ifndef INPUT_H +#define INPUT_H + +typedef void (*input_callback_t)(int key); + +int input_init(); +void input_cleanup(); + +void input_on_press(input_callback_t cb); +void input_on_release(input_callback_t cb); +void input_on_repeat(input_callback_t cb); + +void input_handle(); + +#endif diff --git a/main.c b/main.c index a7fa5bd..63aac51 100644 --- a/main.c +++ b/main.c @@ -1,46 +1,47 @@ +#include "input.h" #include "renderer.h" -#include -#include -#include +#include #include -#include #define MAX(a, b) ((a) < (b) ? (b) : (a)) +static bool quit = false; + +static void key_press_callback(int key) +{ + switch (key) { + case KEY_Q: + quit = true; + break; + + default: + break; + } +} + int main() { - int err; - - const int input_fd = open("/dev/input/event0", O_RDONLY); - assert(input_fd != -1); + const int input_fd = input_init(); + input_on_press(key_press_callback); const renderer_params_t renderer_params = renderer_init(); const int drm_fd = renderer_params.drm_fd; - renderer_clear(); renderer_swap(); const int max_fd = MAX(input_fd, drm_fd); fd_set set; - bool running = true; - while (running) { + + while (!quit) { FD_ZERO(&set); FD_SET(input_fd, &set); FD_SET(drm_fd, &set); select(max_fd + 1, &set, nullptr, nullptr, nullptr); - if (FD_ISSET(input_fd, &set)) { - struct input_event ev; - const int len = read(input_fd, &ev, sizeof(ev)); - assert(len == sizeof(ev)); - - if (ev.type == EV_KEY && ev.value >= 0 && ev.value <= 2) { - if (ev.code == KEY_Q && ev.value == 1) - running = false; - } - } + if (FD_ISSET(input_fd, &set)) + input_handle(); if (FD_ISSET(drm_fd, &set)) { renderer_handle(); @@ -50,7 +51,7 @@ int main() } renderer_cleanup(); - close(input_fd); + input_cleanup(); return 0; }