From 176f4cb9d1b66e943bd829d7a733b386ab84ef65 Mon Sep 17 00:00:00 2001 From: Yann MAGNIN Date: Thu, 25 Aug 2022 20:11:32 +0200 Subject: [PATCH] VxKernel 0.6.0-23 : Add SDL2 support (fake board) (WIP) + update keyboard API @add <> board/sdl2 | [board] add keyboard module support <> src/driver/mpu/x86/sdl2 | [keyboard] add fake keyboard driver @update <> include/vhex/keyboard | new keyboard API based on SDL2 event handling <> src/driver/mpu/sh/sh7305 | [keysc] update keysc API @fix <> include/vhex/keyboard | fix type collision with key_t --- board/sdl2/board.toml | 5 +- include/vhex/driver/mpu/sh/sh7305/keysc.h | 14 +-- include/vhex/keyboard/getkey.h | 10 +- include/vhex/keyboard/interface.h | 12 +- include/vhex/keyboard/keycache.h | 8 +- include/vhex/keyboard/keycode.h | 108 +++++++++--------- include/vhex/keyboard/keydown.h | 10 +- include/vhex/keyboard/keyvent.h | 17 +-- include/vhex/keyboard/types.h | 18 +-- src/driver/mpu/sh/sh7305/keysc/handler.c | 4 +- src/driver/mpu/sh/sh7305/keysc/keycache.c | 101 +++++++++-------- src/driver/mpu/sh/sh7305/keysc/keysc.c | 2 +- src/driver/mpu/x86/sdl2/keyboard.c | 129 ++++++++++++++++++++++ src/keyboard/keycache.c | 22 ++-- src/keyboard/keydown.c | 14 +-- src/keyboard/keyvent.c | 22 ++-- 16 files changed, 309 insertions(+), 187 deletions(-) create mode 100644 src/driver/mpu/x86/sdl2/keyboard.c diff --git a/board/sdl2/board.toml b/board/sdl2/board.toml index 51eced5..731cda7 100644 --- a/board/sdl2/board.toml +++ b/board/sdl2/board.toml @@ -1,12 +1,13 @@ [meta] -description = "Fake board for the DSL support" +description = "Fake board for the SDL2 support" author = 'Yann MAGNIN' [config] modules = [ 'display', 'hypervisor', - 'timer' + 'timer', + 'keyboard' ] [drivers] diff --git a/include/vhex/driver/mpu/sh/sh7305/keysc.h b/include/vhex/driver/mpu/sh/sh7305/keysc.h index dd25280..a7cfa72 100644 --- a/include/vhex/driver/mpu/sh/sh7305/keysc.h +++ b/include/vhex/driver/mpu/sh/sh7305/keysc.h @@ -80,24 +80,24 @@ struct __sh7305_keysc_s #include /* sh7305_keycache_init() : initialise the keycache information */ -extern void sh7305_keycache_init(void); +extern int sh7305_keycache_init(void); /* sh7305_keycache_add_key() : involved by the interrupt handler */ -extern void sh7305_keycache_update(key_t key, int status); +extern void sh7305_keycache_update(vkey_t key, int status); /* sh7305_keycache_quit() : quit the keycache */ -extern void sh7305_keycache_quit(void); +extern int sh7305_keycache_quit(void); /* sh7305_keycache_keydown() : return the key status */ -extern int sh7305_keycache_keydown(key_t key); +extern int sh7305_keycache_keydown(vkey_t key); /* sh7305_keycache_event_wait() : wait event or timeout != 0 */ -extern void sh7305_keycache_event_wait(key_event_t *e, volatile int *timeout); +extern int sh7305_keycache_event_wait(vkey_event_t *e, volatile int *timeout); /* sh7305_keycache_event_push() : pop event from the keycache */ -extern void sh7305_keycache_event_pop(key_event_t *event); +extern int sh7305_keycache_event_pop(vkey_event_t *event); /* sh7305_keycache_event_push() : push event on the keycache */ -extern void sh7305_keycache_event_push(key_event_t *event); +extern int sh7305_keycache_event_push(vkey_event_t *event); #endif /* __VHEX_ARCH_SH7305_KEYSC__ */ diff --git a/include/vhex/keyboard/getkey.h b/include/vhex/keyboard/getkey.h index cc5036e..ed35423 100644 --- a/include/vhex/keyboard/getkey.h +++ b/include/vhex/keyboard/getkey.h @@ -12,7 +12,7 @@ This function mimics the behavior of the fxlib GetKey(). It returns a key_event_t object where [mod=1], and where [shift] and [alpha] indicate whether SHIFT or ALPHA was pressed before the key was hit. [event] is - KEYEV_DOWN when a new key is pressed and KEYEV_HOLD in case of repeats. + VKEYEV_DOWN when a new key is pressed and VKEYEV_HOLD in case of repeats. Similarities with GetKey() include: - Wait for a key to be pressed *after* the call (held keys don't count) @@ -22,7 +22,7 @@ - Controls backlight on models that have a back-lit screen getkey() is equivalent to getkey_opt(GETKEY_DEFAULT, NULL). */ -extern key_event_t getkey(void); +extern vkey_event_t getkey(void); /* The following are the option bits for getkey_opt(). */ enum { @@ -53,7 +53,7 @@ typedef int (*getkey_profile_t)(int key, int duration, int count); /* getkey_feature_t: Custom feature function See getkey_set_feature_function() for details. */ -typedef bool (*getkey_feature_t)(key_event_t event); +typedef bool (*getkey_feature_t)(vkey_event_t event); /* getkey_opt(): Enhanced getkey() @@ -79,8 +79,8 @@ typedef bool (*getkey_feature_t)(key_event_t event); @options An or-combination of values from the GETKEY_* enumeration @timeout Optional pointer to a timeout value - Returns a key event of type KEYEV_DOWN or KEYEV_HOLD with [mod=1]. */ -extern key_event_t getkey_opt(int options, volatile int *timeout); + Returns a key event of type VKEYEV_DOWN or VKEYEV_HOLD with [mod=1]. */ +extern vkey_event_t getkey_opt(int options, volatile int *timeout); /* getkey_repeat(): Set repeat delays for getkey() diff --git a/include/vhex/keyboard/interface.h b/include/vhex/keyboard/interface.h index b4b1aeb..4fd6312 100644 --- a/include/vhex/keyboard/interface.h +++ b/include/vhex/keyboard/interface.h @@ -6,12 +6,12 @@ /* keyboard_drv_interface - driver interface */ struct keyboard_drv_interface { - void (*keycache_init)(void); - int (*keycache_keydown)(key_t key); - void (*keycache_event_wait)(key_event_t *event, volatile int *timeout); - void (*keycache_event_pop)(key_event_t *event); - void (*keycache_event_push)(key_event_t *event); - void (*keycache_quit)(void); + int (*keycache_init)(void); + int (*keycache_keydown)(vkey_t key); + int (*keycache_event_wait)(vkey_event_t *event, volatile int *timeout); + int (*keycache_event_push)(vkey_event_t *event); + int (*keycache_event_pop) (vkey_event_t *event); + int (*keycache_quit)(void); }; #endif /* __VHEX_KEYBOARD_INTERFACE__ */ diff --git a/include/vhex/keyboard/keycache.h b/include/vhex/keyboard/keycache.h index 2bcffeb..1d69ac6 100644 --- a/include/vhex/keyboard/keycache.h +++ b/include/vhex/keyboard/keycache.h @@ -7,16 +7,16 @@ extern void keycache_init(void); /* keycache_keydown() : check the current key state */ -extern int keycache_keydown(key_t key); +extern int keycache_keydown(vkey_t key); /* keycache_event_wait() : wait until the next event or the timeout != 0 */ -extern void keycache_event_wait(key_event_t *event, volatile int *timeout); +extern int keycache_event_wait(vkey_event_t *event, volatile int *timeout); /* keycache_event_pop() : pop the first key event in the cache */ -extern void keycache_event_pop(key_event_t * event); +extern int keycache_event_pop(vkey_event_t *event); /* keycache_event_push() : push a key event in the cache */ -extern void keycache_event_push(key_event_t * event); +extern int keycache_event_push(vkey_event_t *event); /* keycache_init() : uninit the keycache */ extern void keycache_quit(void); diff --git a/include/vhex/keyboard/keycode.h b/include/vhex/keyboard/keycode.h index 716d503..7fd69de 100644 --- a/include/vhex/keyboard/keycode.h +++ b/include/vhex/keyboard/keycode.h @@ -1,73 +1,73 @@ #ifndef __VHEX_KEYBOARD_KEYCODE__ # define __VHEX_KEYBOARD_KEYCODE__ -/* KEYSCODE_GEN() : generate keycode */ -#define KEYCODE_GEN(row, column) \ +/* VKEYSCODE_GEN() : generate keycode */ +#define VKEYCODE_GEN(row, column) \ (((row & 0x0f) << 4) | ((column & 0x0f) << 0)) /* Define all keycode */ typedef enum { - KEY_F1 = 0x41, - KEY_F2 = 0x42, - KEY_F3 = 0x43, - KEY_F4 = 0x44, - KEY_F5 = 0x45, - KEY_F6 = 0x46, + VKEY_F1 = 0x41, + VKEY_F2 = 0x42, + VKEY_F3 = 0x43, + VKEY_F4 = 0x44, + VKEY_F5 = 0x45, + VKEY_F6 = 0x46, - KEY_SHIFT = 0x49, - KEY_OPTN = 0x4a, - KEY_VARS = 0x4b, - KEY_MENU = 0x4c, - KEY_LEFT = 0x4d, - KEY_UP = 0x4e, + VKEY_SHIFT = 0x49, + VKEY_OPTN = 0x4a, + VKEY_VARS = 0x4b, + VKEY_MENU = 0x4c, + VKEY_LEFT = 0x4d, + VKEY_UP = 0x4e, - KEY_ALPHA = 0x31, - KEY_SQUARE = 0x32, - KEY_POWER = 0x33, - KEY_EXIT = 0x34, - KEY_DOWN = 0x35, - KEY_RIGHT = 0x36, + VKEY_ALPHA = 0x31, + VKEY_SQUARE = 0x32, + VKEY_POWER = 0x33, + VKEY_EXIT = 0x34, + VKEY_DOWN = 0x35, + VKEY_RIGHT = 0x36, - KEY_XOT = 0x39, - KEY_LOG = 0x3a, - KEY_LN = 0x3b, - KEY_SIN = 0x3c, - KEY_COS = 0x3d, - KEY_TAN = 0x3e, + VKEY_XOT = 0x39, + VKEY_LOG = 0x3a, + VKEY_LN = 0x3b, + VKEY_SIN = 0x3c, + VKEY_COS = 0x3d, + VKEY_TAN = 0x3e, - KEY_FRAC = 0x21, - KEY_FD = 0x22, - KEY_LEFTP = 0x23, - KEY_RIGHTP = 0x24, - KEY_COMMA = 0x25, - KEY_ARROW = 0x26, + VKEY_FRAC = 0x21, + VKEY_FD = 0x22, + VKEY_LEFTP = 0x23, + VKEY_RIGHTP = 0x24, + VKEY_COMMA = 0x25, + VKEY_ARROW = 0x26, - KEY_7 = 0x29, - KEY_8 = 0x2a, - KEY_9 = 0x2b, - KEY_DEL = 0x2c, + VKEY_7 = 0x29, + VKEY_8 = 0x2a, + VKEY_9 = 0x2b, + VKEY_DEL = 0x2c, - KEY_4 = 0x11, - KEY_5 = 0x12, - KEY_6 = 0x13, - KEY_MUL = 0x14, - KEY_DIV = 0x15, + VKEY_4 = 0x11, + VKEY_5 = 0x12, + VKEY_6 = 0x13, + VKEY_MUL = 0x14, + VKEY_DIV = 0x15, - KEY_1 = 0x19, - KEY_2 = 0x1a, - KEY_3 = 0x1b, - KEY_PLUS = 0x1c, - KEY_MINUS = 0x1d, + VKEY_1 = 0x19, + VKEY_2 = 0x1a, + VKEY_3 = 0x1b, + VKEY_PLUS = 0x1c, + VKEY_MINUS = 0x1d, - KEY_0 = 0x01, - KEY_DOT = 0x02, - KEY_EXP = 0x03, - KEY_NEG = 0x04, - KEY_EXE = 0x05, + VKEY_0 = 0x01, + VKEY_DOT = 0x02, + VKEY_EXP = 0x03, + VKEY_NEG = 0x04, + VKEY_EXE = 0x05, - KEY_UNUSED = 0xff, - KEY_NONE = 0xfe, -} key_t; + VKEY_UNUSED = 0xff, + VKEY_NONE = 0xfe, +} vkey_t; #endif /* __VHEX_KEYBOARD_KEYCODE__ */ diff --git a/include/vhex/keyboard/keydown.h b/include/vhex/keyboard/keydown.h index b544312..93c04f7 100644 --- a/include/vhex/keyboard/keydown.h +++ b/include/vhex/keyboard/keydown.h @@ -11,17 +11,17 @@ /* keydown(): Current key state This function returns zero if the specified key is currently up (according to the last events that have been processed) and non-zero if it is down. */ -extern int keydown(key_t key); +extern int keydown(vkey_t key); /* keydown_all(): Check a set of keys for simultaneous input Returns non-zero if all provided keys are down. The list should end with - KEY_NONE as terminator. */ -extern int keydown_all(key_t key1, ...); + VKEY_NONE as terminator. */ +extern int keydown_all(vkey_t key1, ...); /* keydown_any(): Check a set of keys for any input Returns nonzero if any one of the specified keys is currently pressed. The - sequence should be terminated by KEY_NONE. */ -extern int keydown_any(key_t key1, ...); + sequence should be terminated by VKEY_NONE. */ +extern int keydown_any(vkey_t key1, ...); diff --git a/include/vhex/keyboard/keyvent.h b/include/vhex/keyboard/keyvent.h index 8047912..6bb3976 100644 --- a/include/vhex/keyboard/keyvent.h +++ b/include/vhex/keyboard/keyvent.h @@ -8,20 +8,23 @@ //--- /* keyvent_poll(): Poll the next keyboard event - This function returns the next event from the event queue, chronologically. - If no event is available, it returns a dummy event with type=KEYEV_NONE - and time set to the current driver time. This function always returns events - with mod=0. */ -extern key_event_t keyvent_poll(void); + This function pop the next event from the event queue, chronologically. + If no event is available, it will set a dummy event with type=VKEYEV_NONE + and time set to the current driver time. + + This function always returns: + <> positive value if there is always pending event + <> zero if there is no more pending event + <> negative value if error */ +extern int keyvent_poll(vkey_event_t *event); /* waitevent(): Wait for the next keyboard event This function works as pollevent() but waits if no event is available. When timeout=NULL, it waits indefinitely. Otherwise, it waits until *timeout becomes non-zero (by using a timer for exemple). */ -extern key_event_t keyvent_wait(volatile int *timeout); +extern int keyvent_wait(vkey_event_t *event, volatile int *timeout); /* clearevents(): Clear all events waiting in the queue */ extern void keyvent_clear(void); - #endif /* __VHEX_KEYBOARD_KEYVENT__ */ diff --git a/include/vhex/keyboard/types.h b/include/vhex/keyboard/types.h index f6d4e89..f1849f2 100644 --- a/include/vhex/keyboard/types.h +++ b/include/vhex/keyboard/types.h @@ -16,7 +16,7 @@ getkey() returns enriched events with [mod=1], in whic ase [shift] and [alpha] indicate whether the key has been modified. Only key press events returned by getkey() have [mod=1]. Note that you can't have, e.g. - [key=KEY_SHIFT] and [mod=1] at the same time. + [key=VKEY_SHIFT] and [mod=1] at the same time. The [time] attribute indicates when the event occurred. It is a snapshot of a time counter that increases at each keyboard scan and *wraps around every @@ -37,23 +37,23 @@ typedef struct uint type :2; /* Type of key event */ uint key :8; /* Hit key */ -} VPACKED(4) key_event_t; +} VPACKED(4) vkey_event_t; /* Keyboard event types, as in the [type] field of key_event_t */ enum { - KEYEV_NONE = 0, /* No event available (poll() only) */ - KEYEV_DOWN = 1, /* Key was pressed */ - KEYEV_UP = 2, /* Key was released */ - KEYEV_HOLD = 3, /* A key that was pressed has been held down */ + VKEYEV_NONE = 0, /* No event available (poll() only) */ + VKEYEV_DOWN = 1, /* Key was pressed */ + VKEYEV_UP = 2, /* Key was released */ + VKEYEV_HOLD = 3, /* A key that was pressed has been held down */ }; /* keyboard repetition type */ enum { - KEYEV_REP_NONE = 0, - KEYEV_REP_FIRST = 1, - KEYEV_REP_NEXT = 2, + VKEYEV_REP_NONE = 0, + VKEYEV_REP_FIRST = 1, + VKEYEV_REP_NEXT = 2, }; diff --git a/src/driver/mpu/sh/sh7305/keysc/handler.c b/src/driver/mpu/sh/sh7305/keysc/handler.c index 3dc9cec..5eb0da0 100644 --- a/src/driver/mpu/sh/sh7305/keysc/handler.c +++ b/src/driver/mpu/sh/sh7305/keysc/handler.c @@ -3,14 +3,14 @@ #include -extern void sh7305_keycache_update(key_t key, int status); +extern void sh7305_keycache_update(vkey_t key, int status); /* sh7305_keysc_int_handler() : SH7305 KEYSC interrupt handler */ void sh7305_keysc_int_handler(void) { int intlevel; int column; - key_t key; + vkey_t key; int row; /* Block / disable KEYSC interrupt (otherwise the module will crash) */ diff --git a/src/driver/mpu/sh/sh7305/keysc/keycache.c b/src/driver/mpu/sh/sh7305/keysc/keycache.c index 4ef5afa..00805d7 100644 --- a/src/driver/mpu/sh/sh7305/keysc/keycache.c +++ b/src/driver/mpu/sh/sh7305/keysc/keycache.c @@ -8,9 +8,9 @@ #include struct { - key_event_t keycache[96]; + vkey_event_t keycache[96]; struct { - key_event_t *list; + vkey_event_t *list; int nb_evt_max; int idx; } queue; @@ -31,11 +31,11 @@ static int __sh7305_keycache_keyframe(volatile uint16_t *counter) } /* sh7305_keycache_init() : initialise the keycache information */ -void sh7305_keycache_init(void) +int sh7305_keycache_init(void) { for (int i = 0; i < 96 ; ++i) { - keyinfo.keycache[i].rep_type = KEYEV_REP_NONE; - keyinfo.keycache[i].type = KEYEV_UP; + keyinfo.keycache[i].rep_type = VKEYEV_REP_NONE; + keyinfo.keycache[i].type = VKEYEV_UP; keyinfo.keycache[i].key = i; } @@ -43,7 +43,7 @@ void sh7305_keycache_init(void) keyinfo.queue.nb_evt_max = 16; keyinfo.queue.list = calloc( keyinfo.queue.nb_evt_max, - sizeof(key_event_t) + sizeof(vkey_event_t) ); keyinfo.timer.id = sh7305_tmu_configure( @@ -56,22 +56,8 @@ void sh7305_keycache_init(void) sh7305_tmu_start(keyinfo.timer.id); } -/* sh7305_keycache_update() : involved by the interrupt handler - - Note : this function SHOULD be involved with atomic context !! */ -void sh7305_keycache_update(key_t key, int status) -{ - status = (status != 0) ? KEYEV_DOWN : KEYEV_UP; - - if (keyinfo.keycache[key].type == status) - return; - - keyinfo.keycache[key].type = status; - sh7305_keycache_event_push(&keyinfo.keycache[key]); -} - /* sh7305_keycache_quit() : quit the keycache */ -void sh7305_keycache_quit(void) +int sh7305_keycache_quit(void) { sh7305_tmu_stop(keyinfo.timer.id); free(keyinfo.queue.list); @@ -85,7 +71,7 @@ void sh7305_keycache_quit(void) //--- /* sh7305_keycache_keydown() : return the key status */ -int sh7305_keycache_keydown(key_t key) +int sh7305_keycache_keydown(vkey_t key) { int info; @@ -93,33 +79,12 @@ int sh7305_keycache_keydown(key_t key) info = keyinfo.keycache[key].type; cpu_atomic_end(); - return info == KEYEV_DOWN; + return info == VKEYEV_DOWN; } -/* sh7305_keycache_event_wait() : wait event or timeout != 0 */ -void sh7305_keycache_event_wait(key_event_t *event, volatile int *timeout) -{ - key_event_t e; - - do { - sh7305_keycache_event_pop(&e); - if (e.type != KEYEV_NONE) { - event->time = e.time; - event->type = e.type; - event->key = e.key; - return; - } - if (timeout != NULL && timeout != 0) { - event->type = KEYEV_NONE; - event->key = KEY_NONE; - return; - } - __asm__("sleep"); - } while (1); -} /* sh7305_keycache_event_push() : push event on the keycache */ -void sh7305_keycache_event_push(key_event_t *event) +int sh7305_keycache_event_push(vkey_event_t *event) { cpu_atomic_start(); @@ -129,7 +94,7 @@ void sh7305_keycache_event_push(key_event_t *event) keyinfo.queue.list = reallocarray( keyinfo.queue.list, keyinfo.queue.nb_evt_max, - sizeof(key_event_t) + sizeof(vkey_event_t) ); } @@ -138,16 +103,20 @@ void sh7305_keycache_event_push(key_event_t *event) keyinfo.queue.list[keyinfo.queue.idx].key = event->key; cpu_atomic_end(); + return 0; } /* sh7305_keycache_event_push() : pop event from the keycache */ -void sh7305_keycache_event_pop(key_event_t *event) +int sh7305_keycache_event_pop(vkey_event_t *event) { + int ret; + cpu_atomic_start(); if (keyinfo.queue.idx < 0) { - event->key = KEY_NONE; - event->type = KEYEV_NONE; + event->key = VKEY_NONE; + event->type = VKEYEV_NONE; + ret = 0; } else { event->time = keyinfo.queue.list[0].time; event->type = keyinfo.queue.list[0].type; @@ -156,12 +125,42 @@ void sh7305_keycache_event_pop(key_event_t *event) memcpy( &keyinfo.queue.list[0], &keyinfo.queue.list[1], - sizeof(key_event_t) * keyinfo.queue.idx + sizeof(vkey_event_t) * keyinfo.queue.idx ); keyinfo.queue.idx -= 1; + ret = 1; } - cpu_atomic_end(); + return ret; +} + +/* sh7305_keycache_event_wait() : wait event or timeout != 0 */ +int sh7305_keycache_event_wait(vkey_event_t *e, volatile int *timeout) +{ + do { + if (sh7305_keycache_event_pop(e)) + return 1; + if (timeout != NULL && timeout != 0) { + e->type = VKEYEV_NONE; + e->key = VKEY_NONE; + return 0; + } + __asm__("sleep"); + } while (1); +} + +/* sh7305_keycache_update() : involved by the interrupt handler + + Note : this function SHOULD be involved with atomic context !! */ +void sh7305_keycache_update(vkey_t key, int status) +{ + status = (status != 0) ? VKEYEV_DOWN : VKEYEV_UP; + + if (keyinfo.keycache[key].type == status) + return; + + keyinfo.keycache[key].type = status; + sh7305_keycache_event_push(&keyinfo.keycache[key]); } diff --git a/src/driver/mpu/sh/sh7305/keysc/keysc.c b/src/driver/mpu/sh/sh7305/keysc/keysc.c index f390d18..1145a22 100644 --- a/src/driver/mpu/sh/sh7305/keysc/keysc.c +++ b/src/driver/mpu/sh/sh7305/keysc/keysc.c @@ -56,7 +56,7 @@ static void __keysc_configure(struct keysc_ctx *ctx) ctx->keysc.KIUMODEREG._2 = 1; /* configure the interrupt setting - This part is wierd because I cannot explain why this configurates + This part is wierd because I cannot explain why this configuration generate the whanted behaviour (generate interrupt when a falling or a pressed or a rising edge is detected on any keys). diff --git a/src/driver/mpu/x86/sdl2/keyboard.c b/src/driver/mpu/x86/sdl2/keyboard.c new file mode 100644 index 0000000..9ca67be --- /dev/null +++ b/src/driver/mpu/x86/sdl2/keyboard.c @@ -0,0 +1,129 @@ +#include +#include +#include +#include + +//--- +// fake interrupt handler +//--- + +#define __SDL2_KEYCODE_SUPPORTED 16 + +static struct { + vkey_event_t keycache[__SDL2_KEYCODE_SUPPORTED]; + struct { + vkey_event_t *list; + int nb_evt_max; + int idx; + } queue; +} keyinfo; + +static struct { + int sdl2_id; + int vhex_id; +} key_translation[16] = { + { .sdl2_id = 49, .vhex_id = VKEY_F1 }, // 1 + { .sdl2_id = 50, .vhex_id = VKEY_F2 }, // 2 + { .sdl2_id = 51, .vhex_id = VKEY_F3 }, // 3 + { .sdl2_id = 52, .vhex_id = VKEY_F4 }, // 4 + { .sdl2_id = 53, .vhex_id = VKEY_F5 }, // 5 + { .sdl2_id = 54, .vhex_id = VKEY_F6 }, // 6 + { .sdl2_id = 0x4000004f, .vhex_id = VKEY_RIGHT }, // right arrow + { .sdl2_id = 0x40000050, .vhex_id = VKEY_LEFT }, // left arrow + { .sdl2_id = 0x40000051, .vhex_id = VKEY_DOWN }, // down arrow + { .sdl2_id = 0x40000052, .vhex_id = VKEY_UP }, // up arrow + { .sdl2_id = 13, .vhex_id = VKEY_EXE }, // enter + { .sdl2_id = 0x400000e0, .vhex_id = VKEY_ALPHA }, // shift + { .sdl2_id = 0x400000e1, .vhex_id = VKEY_SHIFT }, // ctrl + { .sdl2_id = 27, .vhex_id = VKEY_EXIT }, // echap + { .sdl2_id = 8, .vhex_id = VKEY_DEL }, // backspace + { .sdl2_id = 9, .vhex_id = VKEY_MENU }, // tab +}; + + + + +//--- +// keycache primitives +//--- + +static int sdl_keycache_event_pop(vkey_event_t *event) +{ + SDL_Event evt; + int ret; + + if (event == NULL) + return -1; + + while (1) + { + ret = SDL_PollEvent(&evt); + if (ret == 0) { + event->key = VKEY_NONE; + return 0; + } + + if (evt.type == SDL_QUIT) + exit(0); + if (evt.type != SDL_KEYDOWN && evt.type != SDL_KEYUP) + continue; + + for (int i = 0; i < __SDL2_KEYCODE_SUPPORTED ; ++i) { + if (evt.key.keysym.sym != key_translation[i].sdl2_id) + continue; + + event->time = 0; + event->type = (evt.type == SDL_KEYDOWN) ? VKEYEV_DOWN : VKEYEV_UP; + event->key = key_translation[i].vhex_id; + return 1; + } + } +} + +//--- +// Internal fake driver definition +//--- + + +/* __keysc_configure() : configure the keyboard module */ +static void __keysc_configure(void) +{ + // Nothing to do, this is a fake driver + ; +} + +/* __keysc_hsave() : save hardware information */ +static void __keysc_hsave(void) +{ + // Nothing to do, this is a fake driver + ; +} + +/* __keysc_hrestore() : restore hadware information */ +static void __keysc_hrestore(void) +{ + // Nothing to do, this is a fake driver + ; +} + +struct vhex_driver drv_keysc = { + .name = "SDL2 Keyboard", + .hsave = (void*)&__keysc_hsave, + .hrestore = (void*)&__keysc_hrestore, + .configure = (void*)&__keysc_configure, + .state_size = 4, + .flags = { + .KEYBOARD = 1, + .SHARED = 0, + .UNUSED = 0, + }, + .module_data = &(struct keyboard_drv_interface){ + .keycache_init = NULL, + .keycache_keydown = NULL, + .keycache_event_wait = NULL, + .keycache_event_pop = &sdl_keycache_event_pop, + .keycache_event_push = NULL, + .keycache_quit = NULL, + } +}; +VHEX_DECLARE_DRIVER(03, drv_keysc); diff --git a/src/keyboard/keycache.c b/src/keyboard/keycache.c index 18b9097..02dcdac 100644 --- a/src/keyboard/keycache.c +++ b/src/keyboard/keycache.c @@ -8,11 +8,6 @@ #include #include - -/* Internal cache, used like chained list. - @note: - The KEYSC have 6 key data 16-bits registers this is why we used 6 * 16 = 96 - cache slots. */ struct { struct keyboard_drv_interface driver; } keyboard_info; @@ -52,7 +47,7 @@ void keycache_quit(void) //--- /* keycache_keydown() : check the current key state */ -int keycache_keydown(key_t key) +int keycache_keydown(vkey_t key) { if (keyboard_info.driver.keycache_keydown != NULL) return keyboard_info.driver.keycache_keydown(key); @@ -60,22 +55,25 @@ int keycache_keydown(key_t key) } /* keycache_event_wait() : wait until the next event or the timeout != 0 */ -void keycache_event_wait(key_event_t *event, volatile int *timeout) +int keycache_event_wait(vkey_event_t *event, volatile int *timeout) { if (keyboard_info.driver.keycache_event_wait != NULL) - keyboard_info.driver.keycache_event_wait(event, timeout); + return keyboard_info.driver.keycache_event_wait(event, timeout); + return 0; } /* keycache_event_pop() : pop the first key event in the cache */ -void keycache_event_pop(key_event_t * event) +int keycache_event_pop(vkey_event_t *event) { if (keyboard_info.driver.keycache_event_pop != NULL) - keyboard_info.driver.keycache_event_pop(event); + return keyboard_info.driver.keycache_event_pop(event); + return 0; } /* keycache_event_push() : push a key event in the cache */ -void keycache_event_push(key_event_t * event) +int keycache_event_push(vkey_event_t *event) { if (keyboard_info.driver.keycache_event_push != NULL) - keyboard_info.driver.keycache_event_push(event); + return keyboard_info.driver.keycache_event_push(event); + return 0; } diff --git a/src/keyboard/keydown.c b/src/keyboard/keydown.c index f20c6af..46d6f9a 100644 --- a/src/keyboard/keydown.c +++ b/src/keyboard/keydown.c @@ -4,13 +4,13 @@ /* keydown(): Current key state */ -int keydown(key_t key) +int keydown(vkey_t key) { return keycache_keydown(key); } /* keydown_all(): Check a set of keys for simultaneous input */ -int keydown_all(key_t key1, ...) +int keydown_all(vkey_t key1, ...) { int key; va_list ap; @@ -21,15 +21,15 @@ int keydown_all(key_t key1, ...) do { if (keycache_keydown(key) == 0) return 0; - key = va_arg(ap, key_t); - } while (key != KEY_NONE); + key = va_arg(ap, vkey_t); + } while (key != VKEY_NONE); va_end(ap); return 1; } /* keydown_any(): Check a set of keys for any input */ -int keydown_any(key_t key1, ...) +int keydown_any(vkey_t key1, ...) { int key; va_list ap; @@ -40,8 +40,8 @@ int keydown_any(key_t key1, ...) do { if (keycache_keydown(key) != 0) return 1; - key = va_arg(ap, key_t); - } while (key != KEY_NONE); + key = va_arg(ap, vkey_t); + } while (key != VKEY_NONE); va_end(ap); return 0; diff --git a/src/keyboard/keyvent.c b/src/keyboard/keyvent.c index 7ad0445..c07d33b 100644 --- a/src/keyboard/keyvent.c +++ b/src/keyboard/keyvent.c @@ -2,31 +2,23 @@ #include /* keyvent_poll(): Poll the next keyboard event */ -key_event_t keyvent_poll(void) +int keyvent_poll(vkey_event_t *evt) { - key_event_t e; - - keycache_event_pop(&e); - return e; + return keycache_event_pop(evt); } /* waitevent(): Wait for the next keyboard event */ -key_event_t keyvent_wait(volatile int *timeout) +int keyvent_wait(vkey_event_t *evt, volatile int *timeout) { - key_event_t e; - - keycache_event_wait(&e, timeout); - return e; + return keycache_event_wait(evt, timeout); } /* clearevents(): Clear all events waiting in the queue */ void keyvent_clear(void) { - key_event_t e; + vkey_event_t evt; - while (1) { - e = keyvent_poll(); - if (e.type == KEYEV_NONE) - break; + while (keyvent_poll(&evt)) { + ; } }