aboutsummaryrefslogtreecommitdiff
path: root/src/keyboard/sdl-1.2
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-09-27 17:03:06 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-11-01 16:26:16 +0100
commit980858186149651df5543b6fc99a4f7db0cdd089 (patch)
treed347200b0a562d84df505097651ad0642f207fdd /src/keyboard/sdl-1.2
parent39f50e601d395bbd2d78d0147ac530b756da2fff (diff)
downloadjancity-980858186149651df5543b6fc99a4f7db0cdd089.tar.gz
WIP
Diffstat (limited to 'src/keyboard/sdl-1.2')
-rw-r--r--src/keyboard/sdl-1.2/inc/keyboard/port.h21
-rw-r--r--src/keyboard/sdl-1.2/src/keyboard.c184
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;
}