aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-01-10 00:47:49 +0100
committerLoïc Hoguin <[email protected]>2018-01-10 00:47:49 +0100
commit44f95f2faaa552fa1a748df4316844e18b047b60 (patch)
treec4fd2901358c672f5ead27549eed4985f9cc96cf
parentc7af14020953fd7187af7d93f64cf94ff2e4d6f3 (diff)
downloadesdl2-44f95f2faaa552fa1a748df4316844e18b047b60.tar.gz
esdl2-44f95f2faaa552fa1a748df4316844e18b047b60.tar.bz2
esdl2-44f95f2faaa552fa1a748df4316844e18b047b60.zip
Add most remaining window functions
-rw-r--r--README.asciidoc17
-rw-r--r--c_src/esdl2.h11
-rw-r--r--c_src/sdl_window.c258
-rw-r--r--src/esdl2.erl36
-rw-r--r--src/sdl_window.erl64
5 files changed, 373 insertions, 13 deletions
diff --git a/README.asciidoc b/README.asciidoc
index c522841..bd6e8e5 100644
--- a/README.asciidoc
+++ b/README.asciidoc
@@ -87,21 +87,12 @@ corresponding to the public headers.
** `SDL_WINDOWPOS_*` values for different displays
** `SDL_CreateWindowFrom` (unclear if we need it)
** We currently do not support UTF-8. We should probably switch to binaries as input/output to support it for `SDL_SetWindowTitle` and `SDL_GetWindowTitle`
-** `SDL_SetWindowData` (window)
-** `SDL_GetWindowData` (window)
-** `SDL_GetWindowBordersSize` (window)
-** `SDL_SetWindowResizable` (window)
+** `SDL_SetWindowData` (unclear if we need it)
+** `SDL_GetWindowData` (unclear if we need it)
** `SDL_GetWindowSurface` (window)
** `SDL_UpdateWindowSurface` (window)
** `SDL_UpdateWindowSurfaceRects` (window)
-** `SDL_GetGrabbedWindow` (window)
-** `SDL_SetWindowOpacity` (window)
-** `SDL_GetWindowOpacity` (window)
-** `SDL_SetWindowModalFor` (window)
-** `SDL_SetWindowInputFocus` (window)
-** `SDL_SetWindowGammaRamp` (window)
-** `SDL_GetWindowGammaRamp` (window)
-** `SDL_SetWindowHitTest` and the related callback `SDL_HitTestResult`
+** `SDL_SetWindowHitTest` and the related callback `SDL_HitTestResult` (unclear if we need it and whether we can make it efficient enough)
** `SDL_IsScreenSaverEnabled`
** `SDL_EnableScreenSaver`
** `SDL_DisableScreenSaver`
@@ -119,6 +110,8 @@ corresponding to the public headers.
** `SDL_GL_SetSwapInterval`
** `SDL_GL_GetSwapInterval`
+The code sometimes uses `malloc`. Use `enif_alloc` everywhere instead.
+
== To be implemented
* 'SDL_audio.h'
diff --git a/c_src/esdl2.h b/c_src/esdl2.h
index 0740ab4..8ab4e32 100644
--- a/c_src/esdl2.h
+++ b/c_src/esdl2.h
@@ -54,6 +54,7 @@
A(bgrx8888) \
A(blend) \
A(borderless) \
+ A(bottom) \
A(button) \
A(callback) \
A(caps) \
@@ -224,6 +225,7 @@
A(timer) \
A(timestamp) \
A(tooltip) \
+ A(top) \
A(touch) \
A(true) \
A(type) \
@@ -420,15 +422,19 @@
/* sdl_window */ \
F(create_window, 6) \
F(create_window_and_renderer, 3) \
+ F(get_grabbed_window, 0) \
+ F(get_window_borders_size, 1) \
F(get_window_brightness, 1) \
F(get_window_display_index, 1) \
F(get_window_display_mode, 1) \
F(get_window_flags, 1) \
F(get_window_from_id, 1) \
+ F(get_window_gamma_ramp, 1) \
F(get_window_grab, 1) \
F(get_window_id, 1) \
F(get_window_maximum_size, 1) \
F(get_window_minimum_size, 1) \
+ F(get_window_opacity, 1) \
F(get_window_pixel_format, 1) \
F(get_window_position, 1) \
F(get_window_size, 1) \
@@ -442,11 +448,16 @@
F(set_window_brightness, 2) \
F(set_window_display_mode, 2) \
F(set_window_fullscreen, 2) \
+ F(set_window_gamma_ramp, 4) \
F(set_window_grab, 2) \
F(set_window_icon, 2) \
+ F(set_window_input_focus, 1) \
F(set_window_maximum_size, 3) \
F(set_window_minimum_size, 3) \
+ F(set_window_modal_for, 2) \
+ F(set_window_opacity, 2) \
F(set_window_position, 3) \
+ F(set_window_resizable, 2) \
F(set_window_size, 3) \
F(set_window_title, 2) \
F(show_window, 1)
diff --git a/c_src/sdl_window.c b/c_src/sdl_window.c
index 28b769e..8122479 100644
--- a/c_src/sdl_window.c
+++ b/c_src/sdl_window.c
@@ -178,6 +178,59 @@ NIF_FUNCTION(create_window_and_renderer)
w, h, flags);
}
+// get_grabbed_window
+
+NIF_CALL_HANDLER(thread_get_grabbed_window)
+{
+ SDL_Window* window;
+
+ window = SDL_GetGrabbedWindow();
+
+ if (!window)
+ return atom_undefined;
+
+ return esdl2_windows_find(env, window);
+}
+
+NIF_FUNCTION(get_grabbed_window)
+{
+ return nif_thread_call(env, thread_get_grabbed_window, 0);
+}
+
+// get_window_borders_size
+
+NIF_CALL_HANDLER(thread_get_window_borders_size)
+{
+ int top, left, bottom, right;
+ ERL_NIF_TERM map;
+
+ if (SDL_GetWindowBordersSize(args[0], &top, &left, &bottom, &right))
+ return atom_undefined;
+
+ map = enif_make_new_map(env);
+
+ enif_make_map_put(env, map, atom_top,
+ enif_make_int(env, top), &map);
+ enif_make_map_put(env, map, atom_left,
+ enif_make_int(env, left), &map);
+ enif_make_map_put(env, map, atom_bottom,
+ enif_make_int(env, bottom), &map);
+ enif_make_map_put(env, map, atom_right,
+ enif_make_int(env, right), &map);
+
+ return map;
+}
+
+NIF_FUNCTION(get_window_borders_size)
+{
+ void* window_res;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res));
+
+ return nif_thread_call(env, thread_get_window_borders_size, 1,
+ NIF_RES_GET(Window, window_res));
+}
+
// get_window_brightness
NIF_CALL_HANDLER(thread_get_window_brightness)
@@ -285,6 +338,39 @@ NIF_FUNCTION(get_window_from_id)
return nif_thread_call(env, thread_get_window_from_id, 1, windowID);
}
+// get_window_gamma_ramp
+
+NIF_CALL_HANDLER(thread_get_window_gamma_ramp)
+{
+ Uint16 gamma[256 * 3];
+ ERL_NIF_TERM list[3];
+ int i, j;
+
+ if (SDL_GetWindowGammaRamp(args[0], gamma, gamma + 256, gamma + 512))
+ return sdl_error_tuple(env);
+
+ for (i = 0; i < 3; i++) {
+ list[i] = enif_make_list(env, 0);
+ for (j = 255; j >= 0; j--) {
+ list[i] = enif_make_list_cell(env,
+ enif_make_uint(env, gamma[i * 256 + j]),
+ list[i]);
+ }
+ }
+
+ return enif_make_tuple3(env, list[0], list[1], list[2]);
+}
+
+NIF_FUNCTION(get_window_gamma_ramp)
+{
+ void* window_res;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res));
+
+ return nif_thread_call(env, thread_get_window_gamma_ramp, 1,
+ NIF_RES_GET(Window, window_res));
+}
+
// get_window_grab
NIF_CALL_HANDLER(thread_get_window_grab)
@@ -370,6 +456,31 @@ NIF_FUNCTION(get_window_minimum_size)
NIF_RES_GET(Window, window_res));
}
+// get_window_opacity
+
+NIF_CALL_HANDLER(thread_get_window_opacity)
+{
+ float opacity;
+
+ if (SDL_GetWindowOpacity(args[0], &opacity))
+ return sdl_error_tuple(env);
+
+ return enif_make_tuple2(env,
+ atom_ok,
+ enif_make_double(env, opacity)
+ );
+}
+
+NIF_FUNCTION(get_window_opacity)
+{
+ void* window_res;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res));
+
+ return nif_thread_call(env, thread_get_window_opacity, 1,
+ NIF_RES_GET(Window, window_res));
+}
+
// get_window_pixel_format
NIF_CALL_HANDLER(thread_get_window_pixel_format)
@@ -651,6 +762,60 @@ NIF_FUNCTION(set_window_fullscreen)
NIF_RES_GET(Window, window_res), flags);
}
+// set_window_gamma_ramp
+
+NIF_CALL_HANDLER(thread_set_window_gamma_ramp)
+{
+ int ret = SDL_SetWindowGammaRamp(args[0], args[1],
+ ((Uint16*)args[1]) + 256,
+ ((Uint16*)args[1]) + 512);
+
+ enif_free(args[1]);
+
+ if (ret != 0)
+ return sdl_error_tuple(env);
+
+ return atom_ok;
+}
+
+NIF_FUNCTION(set_window_gamma_ramp)
+{
+ void* window_res;
+ Uint16 *gamma;
+ ERL_NIF_TERM list, head;
+ int i, j;
+ unsigned int value;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res));
+
+ gamma = enif_alloc(sizeof(Uint16) * 256 * 3);
+
+ for (i = 0; i < 3; i++) {
+ list = argv[i + 1];
+
+ for (j = 0; j < 256; j++) {
+ if (!enif_get_list_cell(env, list, &head, &list))
+ goto set_window_gamma_ramp_badarg;
+
+ if (!enif_get_uint(env, head, &value))
+ goto set_window_gamma_ramp_badarg;
+
+ if (value > 65535)
+ goto set_window_gamma_ramp_badarg;
+
+ gamma[i * 256 + j] = value;
+ }
+ }
+
+ return nif_thread_call(env, thread_set_window_gamma_ramp, 2,
+ NIF_RES_GET(Window, window_res), gamma);
+
+set_window_gamma_ramp_badarg:
+ enif_free(gamma);
+
+ return enif_make_badarg(env);
+}
+
// set_window_grab
NIF_CAST_HANDLER(thread_set_window_grab)
@@ -695,6 +860,26 @@ NIF_FUNCTION(set_window_icon)
NIF_RES_GET(Window, window_res), NIF_RES_GET(Surface, surface_res));
}
+// set_window_input_focus
+
+NIF_CALL_HANDLER(thread_set_window_input_focus)
+{
+ if (SDL_SetWindowInputFocus(args[0]))
+ return sdl_error_tuple(env);
+
+ return atom_ok;
+}
+
+NIF_FUNCTION(set_window_input_focus)
+{
+ void* window_res;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res));
+
+ return nif_thread_call(env, thread_set_window_input_focus, 1,
+ NIF_RES_GET(Window, window_res));
+}
+
// set_window_maximum_size
NIF_CAST_HANDLER(thread_set_window_maximum_size)
@@ -735,6 +920,60 @@ NIF_FUNCTION(set_window_minimum_size)
NIF_RES_GET(Window, window_res), w, h);
}
+// set_window_modal_for
+
+NIF_CALL_HANDLER(thread_set_window_modal_for)
+{
+ if (SDL_SetWindowModalFor(args[0], args[1]))
+ return sdl_error_tuple(env);
+
+ return atom_ok;
+}
+
+NIF_FUNCTION(set_window_modal_for)
+{
+ void* modal_window_res;
+ void* parent_window_res;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &modal_window_res));
+ BADARG_IF(!enif_get_resource(env, argv[1], res_Window, &parent_window_res));
+
+ return nif_thread_call(env, thread_set_window_modal_for, 2,
+ NIF_RES_GET(Window, modal_window_res),
+ NIF_RES_GET(Window, parent_window_res));
+}
+
+// set_window_opacity
+
+NIF_CALL_HANDLER(thread_set_window_opacity)
+{
+ int ret = SDL_SetWindowOpacity(args[0], *((double*)args[1]));
+
+ enif_free(args[1]);
+
+ if (ret != 0)
+ return sdl_error_tuple(env);
+
+ return atom_ok;
+}
+
+NIF_FUNCTION(set_window_opacity)
+{
+ void* window_res;
+ double *opacityPtr;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res));
+
+ opacityPtr = (double*)enif_alloc(sizeof(double));
+ if (!enif_get_double(env, argv[1], opacityPtr)) {
+ enif_free(opacityPtr);
+ return enif_make_badarg(env);
+ }
+
+ return nif_thread_call(env, thread_set_window_opacity, 2,
+ NIF_RES_GET(Window, window_res), opacityPtr);
+}
+
// set_window_position
NIF_CAST_HANDLER(thread_set_window_position)
@@ -755,6 +994,25 @@ NIF_FUNCTION(set_window_position)
NIF_RES_GET(Window, window_res), x, y);
}
+// set_window_resizable
+
+NIF_CAST_HANDLER(thread_set_window_resizable)
+{
+ SDL_SetWindowResizable(args[0], (long)args[1]);
+}
+
+NIF_FUNCTION(set_window_resizable)
+{
+ void* window_res;
+ SDL_bool b;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res));
+ BADARG_IF(!atom_to_bool(env, argv[1], &b));
+
+ return nif_thread_cast(env, thread_set_window_resizable, 2,
+ NIF_RES_GET(Window, window_res), b);
+}
+
// set_window_size
NIF_CAST_HANDLER(thread_set_window_size)
diff --git a/src/esdl2.erl b/src/esdl2.erl
index defcebc..69885c6 100644
--- a/src/esdl2.erl
+++ b/src/esdl2.erl
@@ -185,15 +185,19 @@
%% sdl_window
-export([create_window/6]).
-export([create_window_and_renderer/3]).
+-export([get_grabbed_window/0]).
+-export([get_window_borders_size/1]).
-export([get_window_brightness/1]).
-export([get_window_display_index/1]).
-export([get_window_display_mode/1]).
-export([get_window_flags/1]).
-export([get_window_from_id/1]).
+-export([get_window_gamma_ramp/1]).
-export([get_window_grab/1]).
-export([get_window_id/1]).
-export([get_window_maximum_size/1]).
-export([get_window_minimum_size/1]).
+-export([get_window_opacity/1]).
-export([get_window_pixel_format/1]).
-export([get_window_position/1]).
-export([get_window_size/1]).
@@ -207,11 +211,16 @@
-export([set_window_brightness/2]).
-export([set_window_display_mode/2]).
-export([set_window_fullscreen/2]).
+-export([set_window_gamma_ramp/4]).
-export([set_window_grab/2]).
-export([set_window_icon/2]).
+-export([set_window_input_focus/1]).
-export([set_window_maximum_size/3]).
-export([set_window_minimum_size/3]).
+-export([set_window_modal_for/2]).
+-export([set_window_opacity/2]).
-export([set_window_position/3]).
+-export([set_window_resizable/2]).
-export([set_window_size/3]).
-export([set_window_title/2]).
-export([show_window/1]).
@@ -664,6 +673,12 @@ create_window(_, _, _, _, _, _) ->
create_window_and_renderer(_, _, _) ->
erlang:nif_error({not_loaded, ?MODULE}).
+get_grabbed_window() ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+get_window_borders_size(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
get_window_brightness(_) ->
erlang:nif_error({not_loaded, ?MODULE}).
@@ -679,6 +694,9 @@ get_window_flags(_) ->
get_window_from_id(_) ->
erlang:nif_error({not_loaded, ?MODULE}).
+get_window_gamma_ramp(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
get_window_grab(_) ->
erlang:nif_error({not_loaded, ?MODULE}).
@@ -691,6 +709,9 @@ get_window_maximum_size(_) ->
get_window_minimum_size(_) ->
erlang:nif_error({not_loaded, ?MODULE}).
+get_window_opacity(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
get_window_pixel_format(_) ->
erlang:nif_error({not_loaded, ?MODULE}).
@@ -730,21 +751,36 @@ set_window_display_mode(_, _) ->
set_window_fullscreen(_, _) ->
erlang:nif_error({not_loaded, ?MODULE}).
+set_window_gamma_ramp(_, _, _, _) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
set_window_grab(_, _) ->
erlang:nif_error({not_loaded, ?MODULE}).
set_window_icon(_, _) ->
erlang:nif_error({not_loaded, ?MODULE}).
+set_window_input_focus(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
set_window_maximum_size(_, _, _) ->
erlang:nif_error({not_loaded, ?MODULE}).
set_window_minimum_size(_, _, _) ->
erlang:nif_error({not_loaded, ?MODULE}).
+set_window_modal_for(_, _) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+set_window_opacity(_, _) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
set_window_position(_, _, _) ->
erlang:nif_error({not_loaded, ?MODULE}).
+set_window_resizable(_, _) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
set_window_size(_, _, _) ->
erlang:nif_error({not_loaded, ?MODULE}).
diff --git a/src/sdl_window.erl b/src/sdl_window.erl
index ce74fce..802e20c 100644
--- a/src/sdl_window.erl
+++ b/src/sdl_window.erl
@@ -16,14 +16,19 @@
-export([create/6]).
-export([create_window_and_renderer/3]).
+-export([focus_input/1]).
+-export([get_borders_size/1]).
-export([get_brightness/1]).
-export([get_display_index/1]).
-export([get_display_mode/1]).
-export([get_flags/1]).
-export([get_from_id/1]).
+-export([get_gamma_ramp/1]).
+-export([get_grabbed_window/0]).
-export([get_id/1]).
-export([get_max_size/1]).
-export([get_min_size/1]).
+-export([get_opacity/1]).
-export([get_pixel_format/1]).
-export([get_pos/1]).
-export([get_size/1]).
@@ -39,10 +44,14 @@
-export([set_brightness/2]).
-export([set_display_mode/2]).
-export([set_fullscreen/2]).
+-export([set_gamma_ramp/4]).
-export([set_icon/2]).
-export([set_max_size/3]).
-export([set_min_size/3]).
+-export([set_modal/2]).
+-export([set_opacity/2]).
-export([set_pos/3]).
+-export([set_resizable/2]).
-export([set_size/3]).
-export([set_title/2]).
-export([show/1]).
@@ -62,6 +71,9 @@
| focus_gained | focus_lost | close | take_focus | hit_test.
-export_type([window_event_type/0]).
+%% It must be a list of 256 elements.
+-type gamma_ramp() :: [0..65535].
+
-spec create(string(), window_pos(), window_pos(), integer(), integer(), [window_flag()])
-> {ok, window()} | sdl:error().
create(Title, X, Y, W, H, Flags) ->
@@ -74,6 +86,18 @@ create_window_and_renderer(W, H, Flags) ->
esdl2:create_window_and_renderer(W, H, Flags),
receive {'_nif_thread_ret_', Ret} -> Ret end.
+-spec focus_input(window()) -> ok | sdl:error().
+focus_input(Window) ->
+ esdl2:set_window_input_focus(Window),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec get_borders_size(window())
+ -> #{top := integer(), left := integer(), bottom := integer(), right := integer()}
+ | undefined.
+get_borders_size(Window) ->
+ esdl2:get_window_borders_size(Window),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
-spec get_brightness(window()) -> float().
get_brightness(Window) ->
esdl2:get_window_brightness(Window),
@@ -100,11 +124,21 @@ get_flags(Window) ->
esdl2:get_window_flags(Window),
receive {'_nif_thread_ret_', Ret} -> Ret end.
--spec get_from_id(non_neg_integer()) -> window().
+-spec get_from_id(non_neg_integer()) -> window() | undefined.
get_from_id(WindowID) ->
esdl2:get_window_from_id(WindowID),
receive {'_nif_thread_ret_', Ret} -> Ret end.
+-spec get_gamma_ramp(window()) -> {gamma_ramp(), gamma_ramp(), gamma_ramp()}.
+get_gamma_ramp(Window) ->
+ esdl2:get_window_gamma_ramp(Window),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec get_grabbed_window() -> window() | undefined.
+get_grabbed_window() ->
+ esdl2:get_grabbed_window(),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
-spec get_id(window()) -> non_neg_integer().
get_id(Window) ->
esdl2:get_window_id(Window),
@@ -120,6 +154,14 @@ get_min_size(Window) ->
esdl2:get_window_minimum_size(Window),
receive {'_nif_thread_ret_', Ret} -> Ret end.
+-spec get_opacity(window()) -> float().
+get_opacity(Window) ->
+ esdl2:get_window_opacity(Window),
+ receive {'_nif_thread_ret_', Ret} ->
+ {ok, Opacity} = Ret,
+ Opacity
+ end.
+
-spec get_pixel_format(window()) -> sdl_pixels:pixel_format().
get_pixel_format(Window) ->
esdl2:get_window_pixel_format(Window),
@@ -189,6 +231,12 @@ set_fullscreen(Window, Flag) ->
esdl2:set_window_fullscreen(Window, Flag),
receive {'_nif_thread_ret_', Ret} -> Ret end.
+-spec set_gamma_ramp(window(), gamma_ramp(), gamma_ramp(), gamma_ramp())
+ -> ok | sdl:error().
+set_gamma_ramp(Window, Red, Green, Blue) ->
+ esdl2:set_window_gamma_ramp(Window, Red, Green, Blue),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
-spec set_icon(window(), sdl_surface:surface()) -> ok.
set_icon(Window, Surface) ->
esdl2:set_window_icon(Window, Surface),
@@ -202,10 +250,24 @@ set_max_size(Window, W, H) ->
set_min_size(Window, W, H) ->
esdl2:set_window_minimum_size(Window, W, H).
+-spec set_modal(window(), window()) -> ok | sdl:error().
+set_modal(ModalWindow, ParentWindow) ->
+ esdl2:set_window_modal_for(ModalWindow, ParentWindow),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec set_opacity(window(), float()) -> ok | sdl:error().
+set_opacity(Window, Opacity) ->
+ esdl2:set_window_opacity(Window, Opacity),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
-spec set_pos(window(), integer(), integer()) -> ok.
set_pos(Window, X, Y) ->
esdl2:set_window_position(Window, X, Y).
+-spec set_resizable(window(), boolean()) -> ok.
+set_resizable(Window, Resizable) ->
+ esdl2:set_window_resizable(Window, Resizable).
+
-spec set_size(window(), integer(), integer()) -> ok.
set_size(Window, W, H) ->
esdl2:set_window_size(Window, W, H).