159 lines
5.4 KiB
C
159 lines
5.4 KiB
C
#include <keyboard.h>
|
|
#include <keyboard_key.h>
|
|
#include <SDL.h>
|
|
#include <stdio.h>
|
|
|
|
static void append_key(const enum keyboard_key key, struct keyboard *const k)
|
|
{
|
|
struct keyboard_combo *const c = &k->combo;
|
|
|
|
for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++)
|
|
{
|
|
enum keyboard_key *const sel = &c->keys[i];
|
|
|
|
if (*sel == KEYBOARD_KEY_NONE)
|
|
{
|
|
*sel = key;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void remove_key(const enum keyboard_key key, struct keyboard *const k)
|
|
{
|
|
struct keyboard_combo *const c = &k->combo;
|
|
|
|
for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++)
|
|
{
|
|
enum keyboard_key *const sel = &c->keys[i];
|
|
|
|
if (*sel == key)
|
|
*sel = KEYBOARD_KEY_NONE;
|
|
}
|
|
}
|
|
|
|
static void key_event(const SDL_KeyboardEvent *const ev,
|
|
struct keyboard *const k)
|
|
{
|
|
static const struct keymap
|
|
{
|
|
enum keyboard_key key;
|
|
SDLKey sdl_key;
|
|
} keymap[] =
|
|
{
|
|
{.key = KEYBOARD_KEY_BACKSPACE, .sdl_key = SDLK_BACKSPACE},
|
|
{.key = KEYBOARD_KEY_LEFT, .sdl_key = SDLK_LEFT},
|
|
{.key = KEYBOARD_KEY_RIGHT, .sdl_key = SDLK_RIGHT},
|
|
{.key = KEYBOARD_KEY_UP, .sdl_key = SDLK_UP},
|
|
{.key = KEYBOARD_KEY_DOWN, .sdl_key = SDLK_DOWN},
|
|
{.key = KEYBOARD_KEY_LCTRL, .sdl_key = SDLK_LCTRL},
|
|
{.key = KEYBOARD_KEY_RCTRL, .sdl_key = SDLK_RCTRL},
|
|
{.key = KEYBOARD_KEY_LSHIFT, .sdl_key = SDLK_LSHIFT},
|
|
{.key = KEYBOARD_KEY_RSHIFT, .sdl_key = SDLK_RSHIFT},
|
|
{.key = KEYBOARD_KEY_ESC, .sdl_key = SDLK_ESCAPE},
|
|
{.key = KEYBOARD_KEY_F11, .sdl_key = SDLK_F11},
|
|
{.key = KEYBOARD_KEY_SPACE, .sdl_key = SDLK_SPACE},
|
|
{.key = KEYBOARD_KEY_MINUS, .sdl_key = SDLK_MINUS},
|
|
{.key = KEYBOARD_KEY_SLASH, .sdl_key = SDLK_SLASH},
|
|
{.key = KEYBOARD_KEY_SLASH, .sdl_key = SDLK_KP_DIVIDE},
|
|
{.key = KEYBOARD_KEY_A, .sdl_key = SDLK_a},
|
|
{.key = KEYBOARD_KEY_B, .sdl_key = SDLK_b},
|
|
{.key = KEYBOARD_KEY_C, .sdl_key = SDLK_c},
|
|
{.key = KEYBOARD_KEY_D, .sdl_key = SDLK_d},
|
|
{.key = KEYBOARD_KEY_E, .sdl_key = SDLK_e},
|
|
{.key = KEYBOARD_KEY_F, .sdl_key = SDLK_f},
|
|
{.key = KEYBOARD_KEY_G, .sdl_key = SDLK_g},
|
|
{.key = KEYBOARD_KEY_H, .sdl_key = SDLK_h},
|
|
{.key = KEYBOARD_KEY_I, .sdl_key = SDLK_i},
|
|
{.key = KEYBOARD_KEY_J, .sdl_key = SDLK_j},
|
|
{.key = KEYBOARD_KEY_K, .sdl_key = SDLK_k},
|
|
{.key = KEYBOARD_KEY_L, .sdl_key = SDLK_l},
|
|
{.key = KEYBOARD_KEY_M, .sdl_key = SDLK_m},
|
|
{.key = KEYBOARD_KEY_N, .sdl_key = SDLK_n},
|
|
{.key = KEYBOARD_KEY_O, .sdl_key = SDLK_o},
|
|
{.key = KEYBOARD_KEY_P, .sdl_key = SDLK_p},
|
|
{.key = KEYBOARD_KEY_Q, .sdl_key = SDLK_q},
|
|
{.key = KEYBOARD_KEY_R, .sdl_key = SDLK_r},
|
|
{.key = KEYBOARD_KEY_S, .sdl_key = SDLK_s},
|
|
{.key = KEYBOARD_KEY_T, .sdl_key = SDLK_t},
|
|
{.key = KEYBOARD_KEY_U, .sdl_key = SDLK_u},
|
|
{.key = KEYBOARD_KEY_V, .sdl_key = SDLK_v},
|
|
{.key = KEYBOARD_KEY_W, .sdl_key = SDLK_w},
|
|
{.key = KEYBOARD_KEY_X, .sdl_key = SDLK_x},
|
|
{.key = KEYBOARD_KEY_Y, .sdl_key = SDLK_y},
|
|
{.key = KEYBOARD_KEY_Z, .sdl_key = SDLK_z},
|
|
{.key = KEYBOARD_KEY_0, .sdl_key = SDLK_0},
|
|
{.key = KEYBOARD_KEY_1, .sdl_key = SDLK_1},
|
|
{.key = KEYBOARD_KEY_2, .sdl_key = SDLK_2},
|
|
{.key = KEYBOARD_KEY_3, .sdl_key = SDLK_3},
|
|
{.key = KEYBOARD_KEY_4, .sdl_key = SDLK_4},
|
|
{.key = KEYBOARD_KEY_5, .sdl_key = SDLK_5},
|
|
{.key = KEYBOARD_KEY_6, .sdl_key = SDLK_6},
|
|
{.key = KEYBOARD_KEY_7, .sdl_key = SDLK_7},
|
|
{.key = KEYBOARD_KEY_8, .sdl_key = SDLK_8},
|
|
{.key = KEYBOARD_KEY_9, .sdl_key = SDLK_9},
|
|
{.key = KEYBOARD_KEY_0, .sdl_key = SDLK_KP0},
|
|
{.key = KEYBOARD_KEY_1, .sdl_key = SDLK_KP1},
|
|
{.key = KEYBOARD_KEY_2, .sdl_key = SDLK_KP2},
|
|
{.key = KEYBOARD_KEY_3, .sdl_key = SDLK_KP3},
|
|
{.key = KEYBOARD_KEY_4, .sdl_key = SDLK_KP4},
|
|
{.key = KEYBOARD_KEY_5, .sdl_key = SDLK_KP5},
|
|
{.key = KEYBOARD_KEY_6, .sdl_key = SDLK_KP6},
|
|
{.key = KEYBOARD_KEY_7, .sdl_key = SDLK_KP7},
|
|
{.key = KEYBOARD_KEY_8, .sdl_key = SDLK_KP8},
|
|
{.key = KEYBOARD_KEY_9, .sdl_key = SDLK_KP9},
|
|
{.key = KEYBOARD_KEY_DOT, .sdl_key = SDLK_PERIOD},
|
|
{.key = KEYBOARD_KEY_DOT, .sdl_key = SDLK_KP_PERIOD}
|
|
};
|
|
|
|
for (size_t i = 0; i < sizeof keymap / sizeof *keymap; i++)
|
|
{
|
|
const struct keymap *const km = &keymap[i];
|
|
|
|
if (ev->keysym.sym == km->sdl_key)
|
|
{
|
|
if (ev->state == SDL_PRESSED)
|
|
append_key(km->key, k);
|
|
else
|
|
remove_key(km->key, k);
|
|
}
|
|
}
|
|
}
|
|
|
|
void keyboard_update(struct keyboard *const k)
|
|
{
|
|
SDL_Event ev;
|
|
int n;
|
|
|
|
k->oldcombo = k->combo;
|
|
|
|
while ((n = SDL_PeepEvents(&ev, 1, SDL_GETEVENT,
|
|
SDL_KEYEVENTMASK | SDL_QUITMASK)) > 0)
|
|
{
|
|
switch (ev.type)
|
|
{
|
|
case SDL_KEYDOWN:
|
|
/* Fall through. */
|
|
case SDL_KEYUP:
|
|
key_event(&ev.key, k);
|
|
break;
|
|
|
|
case SDL_QUIT:
|
|
append_key(KEYBOARD_KEY_EXIT, k);
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "%s: unexpected SDL_Event %d\n",
|
|
__func__, ev.type);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (n < 0)
|
|
{
|
|
fprintf(stderr, "%s: SDL_PeepEvents: %s\n",
|
|
__func__, SDL_GetError());
|
|
return;
|
|
}
|
|
}
|