From b8c213eaf6183208f87bad4cd583958ae9967cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Wed, 3 Jan 2018 16:53:27 +0100 Subject: Add many sdl_keyboard functions --- c_src/esdl2.h | 9 +++ c_src/sdl_events.c | 2 +- c_src/sdl_keyboard.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++ c_src/sdl_keycode.c | 1 + 4 files changed, 184 insertions(+), 1 deletion(-) (limited to 'c_src') diff --git a/c_src/esdl2.h b/c_src/esdl2.h index 6899997..7fa237f 100644 --- a/c_src/esdl2.h +++ b/c_src/esdl2.h @@ -269,7 +269,15 @@ /* sdl_hints */ \ F(add_hint_callback, 3) \ /* sdl_keyboard */ \ + F(get_key_from_name, 1) \ + F(get_key_from_scancode, 1) \ + F(get_key_name, 1) \ + F(get_mod_state, 0) \ + F(get_scancode_from_key, 1) \ + F(get_scancode_from_name, 1) \ + F(get_scancode_name, 1) \ F(is_text_input_active, 0) \ + F(set_mod_state, 1) \ F(start_text_input, 0) \ F(stop_text_input, 0) \ /* sdl_mouse */ \ @@ -373,6 +381,7 @@ NIF_ENUM_TO_ATOM_FUNCTION_DECL(button_to_atom, Uint8) NIF_ENUM_TO_ATOM_FUNCTION_DECL(mousewheel_direction_to_atom, Uint32) NIF_ENUM_TO_ATOM_FUNCTION_DECL(window_event_to_atom, Uint8) +NIF_LIST_TO_FLAGS_FUNCTION_DECL(keymod_list_to_flags, Uint16) NIF_FLAGS_TO_LIST_FUNCTION_DECL(keymod_flags_to_list, Uint16) ERL_NIF_TERM mouse_state_to_list(ErlNifEnv*, Uint32); diff --git a/c_src/sdl_events.c b/c_src/sdl_events.c index 1d46760..653d5e1 100644 --- a/c_src/sdl_events.c +++ b/c_src/sdl_events.c @@ -101,7 +101,7 @@ static ERL_NIF_TERM keyboard_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_ enif_make_map_put(env, map, atom_scancode, enif_make_uint(env, event->key.keysym.scancode), &map); enif_make_map_put(env, map, atom_sym, - enif_make_uint(env, event->key.keysym.sym), &map); + enif_make_int(env, event->key.keysym.sym), &map); enif_make_map_put(env, map, atom_mod, keymod_flags_to_list(env, event->key.keysym.mod), &map); diff --git a/c_src/sdl_keyboard.c b/c_src/sdl_keyboard.c index f88b5ca..0e961a8 100644 --- a/c_src/sdl_keyboard.c +++ b/c_src/sdl_keyboard.c @@ -14,6 +14,161 @@ #include "esdl2.h" +// get_key_from_name + +NIF_FUNCTION(get_key_from_name) +{ + ErlNifBinary bin; + char* name; + SDL_Keycode key; + + BADARG_IF(!enif_inspect_binary(env, argv[0], &bin)); + + name = malloc(bin.size + 1); + memcpy(name, bin.data, bin.size); + name[bin.size] = '\0'; + + key = SDL_GetKeyFromName(name); + + free(name); + + if (key == SDLK_UNKNOWN) + return atom_undefined; + + return enif_make_int(env, key); +} + +// get_key_from_scancode + +NIF_FUNCTION(get_key_from_scancode) +{ + SDL_Scancode scancode; + SDL_Keycode key; + + BADARG_IF(!enif_get_uint(env, argv[0], &scancode)); + + key = SDL_GetKeyFromScancode(scancode); + + if (key == SDLK_UNKNOWN) + return atom_undefined; + + return enif_make_int(env, key); +} + +// get_key_name +// +// SDL_GetKeyName is not thread-safe as it stores the returned +// value in a static array in at least some cases. We use the +// NIF thread to avoid any issues. + +NIF_CALL_HANDLER(thread_get_key_name) +{ + const char* name; + ErlNifBinary bin; + + name = SDL_GetKeyName((long)args[0]); + + enif_alloc_binary(strlen(name), &bin); + + memcpy(bin.data, name, bin.size); + + return enif_make_binary(env, &bin); +} + +NIF_FUNCTION(get_key_name) +{ + SDL_Keycode key; + + BADARG_IF(!enif_get_int(env, argv[0], &key)); + + return nif_thread_call(env, thread_get_key_name, 1, key); +} + +// get_scancode_from_key + +NIF_FUNCTION(get_scancode_from_key) +{ + SDL_Keycode key; + SDL_Scancode scancode; + + BADARG_IF(!enif_get_int(env, argv[0], &key)); + + scancode = SDL_GetScancodeFromKey(key); + + if (scancode == SDL_SCANCODE_UNKNOWN) + return atom_undefined; + + return enif_make_uint(env, scancode); +} + +// get_scancode_from_name + +NIF_FUNCTION(get_scancode_from_name) +{ + ErlNifBinary bin; + char* name; + SDL_Scancode scancode; + + BADARG_IF(!enif_inspect_binary(env, argv[0], &bin)); + + name = malloc(bin.size + 1); + memcpy(name, bin.data, bin.size); + name[bin.size] = '\0'; + + scancode = SDL_GetScancodeFromName(name); + + free(name); + + if (scancode == SDL_SCANCODE_UNKNOWN) + return atom_undefined; + + return enif_make_uint(env, scancode); +} + +// get_scancode_name +// +// The SDL_GetScancodeName function only ever points to static +// data and is therefore thread-safe, unlike SDL_GetKeyName. + +NIF_FUNCTION(get_scancode_name) +{ + SDL_Scancode scancode; + const char* name; + ErlNifBinary bin; + + BADARG_IF(!enif_get_uint(env, argv[0], &scancode)); + + name = SDL_GetScancodeName(scancode); + + enif_alloc_binary(strlen(name), &bin); + + memcpy(bin.data, name, bin.size); + + return enif_make_binary(env, &bin); +} + +// @todo get_keyboard_focus +// @todo get_keyboard_state + +// get_mod_state + +NIF_CALL_HANDLER(thread_get_mod_state) +{ + SDL_Keymod mod; + + mod = SDL_GetModState(); + + return keymod_flags_to_list(env, mod); +} + +NIF_FUNCTION(get_mod_state) +{ + return nif_thread_call(env, thread_get_mod_state, 0); +} + +// @todo has_screen_keyboard_support +// @todo is_screen_keyboard_shown + // is_text_input_active NIF_CALL_HANDLER(thread_is_text_input_active) @@ -29,6 +184,24 @@ NIF_FUNCTION(is_text_input_active) return nif_thread_call(env, thread_is_text_input_active, 0); } +// set_mod_state + +NIF_CAST_HANDLER(thread_set_mod_state) +{ + SDL_SetModState((long)args[0]); +} + +NIF_FUNCTION(set_mod_state) +{ + Uint16 mod; + + BADARG_IF(!keymod_list_to_flags(env, argv[0], &mod)); + + return nif_thread_cast(env, thread_set_mod_state, 1, mod); +} + +// @todo set_text_input_rect + // start_text_input NIF_CAST_HANDLER(thread_start_text_input) diff --git a/c_src/sdl_keycode.c b/c_src/sdl_keycode.c index f558f83..fda2016 100644 --- a/c_src/sdl_keycode.c +++ b/c_src/sdl_keycode.c @@ -27,4 +27,5 @@ F(caps, KMOD_CAPS) \ F(mode, KMOD_MODE) +NIF_LIST_TO_FLAGS_FUNCTION(keymod_list_to_flags, Uint16, KEYMOD_FLAGS) NIF_FLAGS_TO_LIST_FUNCTION(keymod_flags_to_list, Uint16, KEYMOD_FLAGS) -- cgit v1.2.3