diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-09-27 17:03:06 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-11-01 16:26:16 +0100 |
| commit | 980858186149651df5543b6fc99a4f7db0cdd089 (patch) | |
| tree | d347200b0a562d84df505097651ad0642f207fdd /src/keyboard/sdl-1.2 | |
| parent | 39f50e601d395bbd2d78d0147ac530b756da2fff (diff) | |
| download | jancity-980858186149651df5543b6fc99a4f7db0cdd089.tar.gz | |
WIP
Diffstat (limited to 'src/keyboard/sdl-1.2')
| -rw-r--r-- | src/keyboard/sdl-1.2/inc/keyboard/port.h | 21 | ||||
| -rw-r--r-- | src/keyboard/sdl-1.2/src/keyboard.c | 184 |
2 files changed, 125 insertions, 80 deletions
diff --git a/src/keyboard/sdl-1.2/inc/keyboard/port.h b/src/keyboard/sdl-1.2/inc/keyboard/port.h new file mode 100644 index 0000000..69628f1 --- /dev/null +++ b/src/keyboard/sdl-1.2/inc/keyboard/port.h @@ -0,0 +1,21 @@ +#ifndef KEYBOARD_SDL_1_2_H +#define KEYBOARD_SDL_1_2_H + +#include <keyboard.h> +#include <SDL_keyboard.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct keyboard_port +{ + Uint8 scancodes[KEYBOARD_MAX_COMBO_KEYS]; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* KEYBOARD_SDL_1_2_H */ diff --git a/src/keyboard/sdl-1.2/src/keyboard.c b/src/keyboard/sdl-1.2/src/keyboard.c index 78056e1..87ae808 100644 --- a/src/keyboard/sdl-1.2/src/keyboard.c +++ b/src/keyboard/sdl-1.2/src/keyboard.c @@ -1,38 +1,67 @@ #include <keyboard.h> -#include <keyboard_key.h> +#include <keyboard/port.h> +#include <keyboard/key.h> #include <SDL.h> +#include <ctype.h> +#include <stddef.h> #include <stdio.h> -static void append_key(const enum keyboard_key key, struct keyboard *const k) +static void append_key(const enum keyboard_key key, const char ch, + const Uint8 scancode, struct keyboard *const k) { - struct keyboard_combo *const c = &k->combo; + struct keyboard_combo *const c = &k->input.combo; for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++) { enum keyboard_key *const sel = &c->keys[i]; + char *const pch = &k->input.chars.c[i]; + Uint8 *const sc = &k->port.scancodes[i]; - if (*sel == KEYBOARD_KEY_NONE) + if (*sel == KEYBOARD_KEY_NONE && !*pch) { *sel = key; + *pch = ch; + *sc = scancode; break; } } } -static void remove_key(const enum keyboard_key key, struct keyboard *const k) +static enum keyboard_key char_to_key(const char ch) { - struct keyboard_combo *const c = &k->combo; - - for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++) + if (ch >= 'a' && ch <= 'b') + return KEYBOARD_KEY_A + (ch - 'a'); + else if (ch >= 'A' && ch <= 'Z') + return KEYBOARD_KEY_A + (ch - 'A'); + else if (ch >= '0' && ch <= '9') + return KEYBOARD_KEY_0 + (ch - '0'); + else { - enum keyboard_key *const sel = &c->keys[i]; + static const struct map + { + enum keyboard_key key; + char ch; + } map[] = + { + {.key = KEYBOARD_KEY_DOT, .ch = '.'}, + {.key = KEYBOARD_KEY_SPACE, .ch = ' '}, + {.key = KEYBOARD_KEY_MINUS, .ch = '-'}, + {.key = KEYBOARD_KEY_SLASH, .ch = '/'} + }; - if (*sel == key) - *sel = KEYBOARD_KEY_NONE; + for (size_t i = 0; i < sizeof map / sizeof *map; i++) + { + const struct map *const m = &map[i]; + + if (ch == m->ch) + return m->key; + } } + + return KEYBOARD_KEY_NONE; } -static void key_event(const SDL_KeyboardEvent *const ev, +static void on_pressed(const SDL_KeyboardEvent *const ev, struct keyboard *const k) { static const struct keymap @@ -46,86 +75,79 @@ static void key_event(const SDL_KeyboardEvent *const ev, {.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_ESC, .sdl_key = SDLK_ESCAPE}, + {.key = KEYBOARD_KEY_F11, .sdl_key = SDLK_F11}, {.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} + {.key = KEYBOARD_KEY_RETURN, .sdl_key = SDLK_KP_ENTER}, + {.key = KEYBOARD_KEY_RETURN, .sdl_key = SDLK_RETURN} }; - for (size_t i = 0; i < sizeof keymap / sizeof *keymap; i++) + const char ch = ev->keysym.unicode; + + /* According to the man page for isprint(3): + * The standards require that the argument c for these functions is + * either EOF or a value that is representable in the type unsigned + * char. If the argument is of type char, it must be cast to + * unsigned char. */ + if (isprint((unsigned char)ch)) + append_key(char_to_key(ch), ch, ev->keysym.scancode, k); + else { - const struct keymap *const km = &keymap[i]; + 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->keysym.sym == km->sdl_key) + { + append_key(km->key, '\0', ev->keysym.scancode, k); + break; + } + } + } +} + +static void remove_key(const Uint8 scancode, struct keyboard *const k) +{ + struct keyboard_port *const p = &k->port; + + for (size_t i = 0; i < sizeof p->scancodes / sizeof *p->scancodes; i++) + { + Uint8 *const sc = &p->scancodes[i]; + + if (*sc == scancode) { - if (ev->state == SDL_PRESSED) - append_key(km->key, k); - else - remove_key(km->key, k); + struct keyboard_combo *const c = &k->input.combo; + struct keyboard_chars *const ch = &k->input.chars; + + c->keys[i] = KEYBOARD_KEY_NONE; + ch->c[i] = '\0'; + *sc = 0; + break; } } } +static void key_event(const SDL_KeyboardEvent *const ev, + struct keyboard *const k) +{ + if (ev->state == SDL_PRESSED) + on_pressed(ev, k); + else + /* SDL allows reading Unicode only for pressed events. + * In order to know whether a Unicode was released, its + * corresponding scancode must be inspected. */ + remove_key(ev->keysym.scancode, k); +} + void keyboard_update(struct keyboard *const k) { SDL_Event ev; int n; - k->oldcombo = k->combo; + k->oldinput = k->input; while ((n = SDL_PeepEvents(&ev, 1, SDL_GETEVENT, SDL_KEYEVENTMASK | SDL_QUITMASK)) > 0) @@ -139,7 +161,7 @@ void keyboard_update(struct keyboard *const k) break; case SDL_QUIT: - append_key(KEYBOARD_KEY_EXIT, k); + append_key(KEYBOARD_KEY_EXIT, '\0', 0, k); break; default: @@ -150,9 +172,11 @@ void keyboard_update(struct keyboard *const k) } if (n < 0) - { - fprintf(stderr, "%s: SDL_PeepEvents: %s\n", - __func__, SDL_GetError()); - return; - } + fprintf(stderr, "%s: SDL_PeepEvents: %s\n", __func__, SDL_GetError()); +} + +bool keyboard_available(void) +{ + /* Keyboard availability is always assumed in SDL. */ + return true; } |
