From 5a9e707ee2eefe04316c9d1b30b4f00e7ebe0f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Fri, 2 Feb 2018 00:46:13 +0100 Subject: Add utf-8 support for the window title --- README.asciidoc | 1 - c_src/sdl_window.c | 38 ++++++++++++++++++++++---------------- src/sdl_window.erl | 6 +++--- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/README.asciidoc b/README.asciidoc index fdc4c10..073dbb6 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -83,7 +83,6 @@ corresponding to the public headers. * 'SDL_version.h': `SDL_GetRevisionNumber` must be implemented. The macros may also be useful. * 'SDL_video.h': The following elements are missing: ** `SDL_WINDOWPOS_*` values for different displays -** We currently do not support UTF-8. We should probably switch to binaries as input/output to support it for `SDL_SetWindowTitle`, `SDL_GetWindowTitle` and `SDL_CreateWindow`. ** `SDL_GetWindowSurface` (window) ** `SDL_UpdateWindowSurface` (window) ** `SDL_UpdateWindowSurfaceRects` (window) diff --git a/c_src/sdl_window.c b/c_src/sdl_window.c index 6f910ed..d6c8a47 100644 --- a/c_src/sdl_window.c +++ b/c_src/sdl_window.c @@ -123,7 +123,7 @@ NIF_CALL_HANDLER(thread_create_window) NIF_FUNCTION(create_window) { - unsigned int len; + ErlNifBinary bin; char* title; int x, y, w, h; Uint32 flags = 0; @@ -146,13 +146,11 @@ NIF_FUNCTION(create_window) // Getting the title last to simplify the code due to memory allocation. - BADARG_IF(!enif_get_list_length(env, argv[0], &len)); - title = (char*)enif_alloc(len + 1); + BADARG_IF(!enif_inspect_binary(env, argv[0], &bin)); - if (!enif_get_string(env, argv[0], title, len + 1, ERL_NIF_LATIN1)) { - enif_free(title); - return enif_make_badarg(env); - } + title = enif_alloc(bin.size + 1); + memcpy(title, bin.data, bin.size); + title[bin.size] = '\0'; return nif_thread_call(env, thread_create_window, 6, title, x, y, w, h, flags); @@ -568,7 +566,18 @@ NIF_FUNCTION(get_window_size) NIF_CALL_HANDLER(thread_get_window_title) { - return enif_make_string(env, SDL_GetWindowTitle(args[0]), ERL_NIF_LATIN1); + ErlNifBinary bin; + const char* title; + + title = SDL_GetWindowTitle(args[0]); + + if (!title) + return sdl_error_tuple(env); + + enif_alloc_binary(strlen(title), &bin); + memcpy(bin.data, title, bin.size); + + return enif_make_binary(env, &bin); } NIF_FUNCTION(get_window_title) @@ -1268,18 +1277,15 @@ NIF_CAST_HANDLER(thread_set_window_title) NIF_FUNCTION(set_window_title) { void* window_res; - unsigned int len; + ErlNifBinary bin; char* title; BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res)); + BADARG_IF(!enif_inspect_binary(env, argv[1], &bin)); - BADARG_IF(!enif_get_list_length(env, argv[1], &len)); - title = (char*)enif_alloc(len + 1); - - if (!enif_get_string(env, argv[1], title, len + 1, ERL_NIF_LATIN1)) { - enif_free(title); - return enif_make_badarg(env); - } + title = enif_alloc(bin.size + 1); + memcpy(title, bin.data, bin.size); + title[bin.size] = '\0'; return nif_thread_cast(env, thread_set_window_title, 2, NIF_RES_GET(Window, window_res), title); diff --git a/src/sdl_window.erl b/src/sdl_window.erl index 24a4622..919c828 100644 --- a/src/sdl_window.erl +++ b/src/sdl_window.erl @@ -76,7 +76,7 @@ %% It must be a list of 256 elements. -type gamma_ramp() :: [0..65535]. --spec create(string(), window_pos(), window_pos(), integer(), integer(), [window_flag()]) +-spec create(binary(), window_pos(), window_pos(), integer(), integer(), [window_flag()]) -> {ok, window()} | sdl:error(). create(Title, X, Y, W, H, Flags) -> esdl2:create_window(Title, X, Y, W, H, Flags), @@ -179,7 +179,7 @@ get_size(Window) -> esdl2:get_window_size(Window), receive {'_nif_thread_ret_', Ret} -> Ret end. --spec get_title(window()) -> string(). +-spec get_title(window()) -> binary(). get_title(Window) -> esdl2:get_window_title(Window), receive {'_nif_thread_ret_', Ret} -> Ret end. @@ -279,7 +279,7 @@ set_resizable(Window, Resizable) -> set_size(Window, W, H) -> esdl2:set_window_size(Window, W, H). --spec set_title(window(), string()) -> ok. +-spec set_title(window(), binary()) -> ok. set_title(Window, Title) -> esdl2:set_window_title(Window, Title). -- cgit v1.2.3