aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-01-07 14:37:14 +0100
committerLoïc Hoguin <[email protected]>2018-01-07 14:37:14 +0100
commit0a6ef9d42ac008c7b8bf6b3d0f112ce040e3568c (patch)
tree52f56f297b9e4c9a542334c575e8f72657758bca
parent898c2ada209f3ab4e19d4b072aeef484baae27da (diff)
downloadesdl2-0a6ef9d42ac008c7b8bf6b3d0f112ce040e3568c.tar.gz
esdl2-0a6ef9d42ac008c7b8bf6b3d0f112ce040e3568c.tar.bz2
esdl2-0a6ef9d42ac008c7b8bf6b3d0f112ce040e3568c.zip
Add many sdl_video functions
-rw-r--r--README.asciidoc60
-rw-r--r--c_src/esdl2.h13
-rw-r--r--c_src/sdl_rect.c18
-rw-r--r--c_src/sdl_video.c220
-rw-r--r--ebin/esdl2.app2
-rw-r--r--src/esdl2.erl44
-rw-r--r--src/sdl_video.erl75
7 files changed, 396 insertions, 36 deletions
diff --git a/README.asciidoc b/README.asciidoc
index 163e813..52e4c1b 100644
--- a/README.asciidoc
+++ b/README.asciidoc
@@ -86,42 +86,32 @@ corresponding to the public headers.
* 'SDL_video.h': The following elements are missing:
** `SDL_WindowFlags` values SDL_WINDOW_ALWAYS_ON_TOP, SDL_WINDOW_SKIP_TASKBAR, SDL_WINDOW_UTILITY, SDL_WINDOW_TOOLTIP, SDL_WINDOW_POPUP_MENU, SDL_WINDOW_VULKAN
** `SDL_WINDOWPOS_*` values for different displays
-** `SDL_GetNumVideoDrivers`
-** `SDL_GetVideoDriver`
-** `SDL_VideoInit`
-** `SDL_VideoQuit`
-** `SDL_GetCurrentVideoDriver`
-** `SDL_GetNumVideoDisplays`
-** `SDL_GetDisplayName`
-** `SDL_GetDisplayBounds`
-** `SDL_GetDisplayDPI`
-** `SDL_GetDisplayUsableBounds`
-** `SDL_GetNumDisplayModes`
-** `SDL_GetDisplayMode`
-** `SDL_GetDesktopDisplayMode`
-** `SDL_GetCurrentDisplayMode`
-** `SDL_GetClosestDisplayMode`
-** `SDL_GetWindowDisplayIndex`
-** `SDL_SetWindowDisplayMode`
-** `SDL_GetWindowDisplayMode`
-** `SDL_GetWindowPixelFormat`
-** `SDL_CreateWindowFrom`
-** `SDL_GetWindowFromID`
+** `SDL_GetNumDisplayModes` (video)
+** `SDL_GetDisplayMode` (video)
+** `SDL_GetDesktopDisplayMode` (video)
+** `SDL_GetCurrentDisplayMode` (video)
+** `SDL_GetClosestDisplayMode` (video)
+** `SDL_GetWindowDisplayIndex` (window)
+** `SDL_SetWindowDisplayMode` (window)
+** `SDL_GetWindowDisplayMode` (window)
+** `SDL_GetWindowPixelFormat` (window)
+** `SDL_CreateWindowFrom` (window)
+** `SDL_GetWindowFromID` (window)
** 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`
-** `SDL_GetWindowData`
-** `SDL_GetWindowBordersSize`
-** `SDL_SetWindowResizable`
-** `SDL_GetWindowSurface`
-** `SDL_UpdateWindowSurface`
-** `SDL_UpdateWindowSurfaceRects`
-** `SDL_GetGrabbedWindow`
-** `SDL_SetWindowOpacity`
-** `SDL_GetWindowOpacity`
-** `SDL_SetWindowModalFor`
-** `SDL_SetWindowInputFocus`
-** `SDL_SetWindowGammaRamp`
-** `SDL_GetWindowGammaRamp`
+** `SDL_SetWindowData` (window)
+** `SDL_GetWindowData` (window)
+** `SDL_GetWindowBordersSize` (window)
+** `SDL_SetWindowResizable` (window)
+** `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_IsScreenSaverEnabled`
** `SDL_EnableScreenSaver`
diff --git a/c_src/esdl2.h b/c_src/esdl2.h
index a860b7f..6285981 100644
--- a/c_src/esdl2.h
+++ b/c_src/esdl2.h
@@ -71,6 +71,7 @@
A(crosshair) \
A(data1) \
A(data2) \
+ A(diagonal) \
A(direction) \
A(dollar_gesture) \
A(dollar_record) \
@@ -392,6 +393,17 @@
/* sdl_version */ \
F(get_version, 0) \
F(get_revision, 0) \
+ /* sdl_video */ \
+ F(get_current_video_driver, 0) \
+ F(get_display_bounds, 1) \
+ F(get_display_dpi, 1) \
+ F(get_display_name, 1) \
+ F(get_display_usable_bounds, 1) \
+ F(get_num_video_displays, 0) \
+ F(get_num_video_drivers, 0) \
+ F(get_video_driver, 1) \
+ F(video_init, 1) \
+ F(video_quit, 0) \
/* sdl_window */ \
F(create_window, 6) \
F(create_window_and_renderer, 3) \
@@ -445,6 +457,7 @@ NIF_FLAGS_TO_LIST_FUNCTION_DECL(keymod_flags_to_list, Uint16)
int map_to_point(ErlNifEnv*, ERL_NIF_TERM, SDL_Point*);
int map_to_rect(ErlNifEnv*, ERL_NIF_TERM, SDL_Rect*);
+ERL_NIF_TERM rect_to_map(ErlNifEnv*, SDL_Rect*);
ERL_NIF_TERM mouse_state_to_list(ErlNifEnv*, Uint32);
diff --git a/c_src/sdl_rect.c b/c_src/sdl_rect.c
index eb04d5b..737c920 100644
--- a/c_src/sdl_rect.c
+++ b/c_src/sdl_rect.c
@@ -55,3 +55,21 @@ int map_to_rect(ErlNifEnv* env, ERL_NIF_TERM map, SDL_Rect* rect)
return 1;
}
+
+ERL_NIF_TERM rect_to_map(ErlNifEnv* env, SDL_Rect* rect)
+{
+ ERL_NIF_TERM map;
+
+ map = enif_make_new_map(env);
+
+ enif_make_map_put(env, map, atom_x,
+ enif_make_int(env, rect->x), &map);
+ enif_make_map_put(env, map, atom_y,
+ enif_make_int(env, rect->y), &map);
+ enif_make_map_put(env, map, atom_w,
+ enif_make_int(env, rect->w), &map);
+ enif_make_map_put(env, map, atom_h,
+ enif_make_int(env, rect->h), &map);
+
+ return map;
+}
diff --git a/c_src/sdl_video.c b/c_src/sdl_video.c
new file mode 100644
index 0000000..f559583
--- /dev/null
+++ b/c_src/sdl_video.c
@@ -0,0 +1,220 @@
+// Copyright (c) 2018, Loïc Hoguin <[email protected]>
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+#include "esdl2.h"
+
+// get_current_video_driver
+
+NIF_CALL_HANDLER(thread_get_current_video_driver)
+{
+ const char* name;
+ ErlNifBinary bin;
+
+ name = SDL_GetCurrentVideoDriver();
+
+ if (!name)
+ return atom_undefined;
+
+ enif_alloc_binary(strlen(name), &bin);
+ memcpy(bin.data, name, bin.size);
+
+ return enif_make_binary(env, &bin);
+}
+
+NIF_FUNCTION(get_current_video_driver)
+{
+ return nif_thread_call(env, thread_get_current_video_driver, 0);
+}
+
+// get_display_bounds
+
+NIF_CALL_HANDLER(thread_get_display_bounds)
+{
+ SDL_Rect rect;
+
+ if (SDL_GetDisplayBounds((long)args[0], &rect))
+ return atom_undefined;
+
+ return rect_to_map(env, &rect);
+}
+
+NIF_FUNCTION(get_display_bounds)
+{
+ int index;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &index));
+
+ return nif_thread_call(env, thread_get_display_bounds, 1, index);
+}
+
+// get_display_dpi
+
+NIF_CALL_HANDLER(thread_get_display_dpi)
+{
+ float ddpi, hdpi, vdpi;
+ ERL_NIF_TERM map;
+
+ if (SDL_GetDisplayDPI((long)args[0], &ddpi, &hdpi, &vdpi))
+ return atom_undefined;
+
+ map = enif_make_new_map(env);
+
+ enif_make_map_put(env, map, atom_diagonal,
+ enif_make_double(env, ddpi), &map);
+ enif_make_map_put(env, map, atom_horizontal,
+ enif_make_double(env, hdpi), &map);
+ enif_make_map_put(env, map, atom_vertical,
+ enif_make_double(env, vdpi), &map);
+
+ return map;
+}
+
+NIF_FUNCTION(get_display_dpi)
+{
+ int index;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &index));
+
+ return nif_thread_call(env, thread_get_display_dpi, 1, index);
+}
+
+// get_display_name
+
+NIF_CALL_HANDLER(thread_get_display_name)
+{
+ const char* name;
+ ErlNifBinary bin;
+
+ name = SDL_GetDisplayName((long)args[0]);
+
+ if (!name)
+ return atom_undefined;
+
+ enif_alloc_binary(strlen(name), &bin);
+ memcpy(bin.data, name, bin.size);
+
+ return enif_make_binary(env, &bin);
+}
+
+NIF_FUNCTION(get_display_name)
+{
+ int index;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &index));
+
+ return nif_thread_call(env, thread_get_display_name, 1, index);
+}
+
+// get_display_usable_bounds
+
+NIF_CALL_HANDLER(thread_get_display_usable_bounds)
+{
+ SDL_Rect rect;
+
+ if (SDL_GetDisplayUsableBounds((long)args[0], &rect))
+ return atom_undefined;
+
+ return rect_to_map(env, &rect);
+}
+
+NIF_FUNCTION(get_display_usable_bounds)
+{
+ int index;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &index));
+
+ return nif_thread_call(env, thread_get_display_usable_bounds, 1, index);
+}
+
+// get_num_video_displays
+
+NIF_CALL_HANDLER(thread_get_num_video_displays)
+{
+ return enif_make_int(env, SDL_GetNumVideoDisplays());
+}
+
+NIF_FUNCTION(get_num_video_displays)
+{
+ return nif_thread_call(env, thread_get_num_video_displays, 0);
+}
+
+// get_num_video_drivers
+
+NIF_FUNCTION(get_num_video_drivers)
+{
+ return enif_make_int(env, SDL_GetNumVideoDrivers());
+}
+
+// get_video_driver
+
+NIF_FUNCTION(get_video_driver)
+{
+ int index;
+ const char* name;
+ ErlNifBinary bin;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &index));
+
+ name = SDL_GetVideoDriver(index);
+
+ if (!name)
+ return atom_undefined;
+
+ enif_alloc_binary(strlen(name), &bin);
+ memcpy(bin.data, name, bin.size);
+
+ return enif_make_binary(env, &bin);
+}
+
+// video_init
+
+NIF_CALL_HANDLER(thread_video_init)
+{
+ int result;
+
+ result = SDL_VideoInit(args[0]);
+
+ free(args[0]);
+
+ if (result)
+ return sdl_error_tuple(env);
+
+ return atom_ok;
+}
+
+NIF_FUNCTION(video_init)
+{
+ ErlNifBinary bin;
+ char* name;
+
+ BADARG_IF(!enif_inspect_binary(env, argv[0], &bin));
+
+ name = malloc(bin.size + 1);
+ memcpy(name, bin.data, bin.size);
+ name[bin.size] = '\0';
+
+ return nif_thread_call(env, thread_video_init, 1, name);
+}
+
+// video_quit
+
+NIF_CAST_HANDLER(thread_video_quit)
+{
+ SDL_VideoQuit();
+}
+
+NIF_FUNCTION(video_quit)
+{
+ return nif_thread_cast(env, thread_video_quit, 0);
+}
diff --git a/ebin/esdl2.app b/ebin/esdl2.app
index c2bd838..9dd11ea 100644
--- a/ebin/esdl2.app
+++ b/ebin/esdl2.app
@@ -1,7 +1,7 @@
{application, 'esdl2', [
{description, "SDL2 Erlang NIF."},
{vsn, "0.1.0"},
- {modules, ['esdl2','esdl2_app','esdl2_callbacks','esdl2_sup','sdl','sdl_blend_mode','sdl_clipboard','sdl_cpu_info','sdl_cursor','sdl_events','sdl_filesystem','sdl_gl','sdl_hints','sdl_keyboard','sdl_keycode','sdl_mouse','sdl_pixels','sdl_platform','sdl_power','sdl_rect','sdl_renderer','sdl_surface','sdl_texture','sdl_version','sdl_window']},
+ {modules, ['esdl2','esdl2_app','esdl2_callbacks','esdl2_sup','sdl','sdl_blend_mode','sdl_clipboard','sdl_cpu_info','sdl_cursor','sdl_events','sdl_filesystem','sdl_gl','sdl_hints','sdl_keyboard','sdl_keycode','sdl_mouse','sdl_pixels','sdl_platform','sdl_power','sdl_rect','sdl_renderer','sdl_surface','sdl_texture','sdl_version','sdl_video','sdl_window']},
{registered, [esdl2_sup]},
{applications, [kernel,stdlib]},
{mod, {esdl2_app, []}},
diff --git a/src/esdl2.erl b/src/esdl2.erl
index 435451b..015fd62 100644
--- a/src/esdl2.erl
+++ b/src/esdl2.erl
@@ -165,6 +165,18 @@
-export([get_version/0]).
-export([get_revision/0]).
+%% sdl_video
+-export([get_current_video_driver/0]).
+-export([get_display_bounds/1]).
+-export([get_display_dpi/1]).
+-export([get_display_name/1]).
+-export([get_display_usable_bounds/1]).
+-export([get_num_video_displays/0]).
+-export([get_num_video_drivers/0]).
+-export([get_video_driver/1]).
+-export([video_init/1]).
+-export([video_quit/0]).
+
%% sdl_window
-export([create_window/6]).
-export([create_window_and_renderer/3]).
@@ -588,6 +600,38 @@ get_version() ->
get_revision() ->
erlang:nif_error({not_loaded, ?MODULE}).
+%% sdl_video
+
+get_current_video_driver() ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+get_display_bounds(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+get_display_dpi(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+get_display_name(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+get_display_usable_bounds(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+get_num_video_displays() ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+get_num_video_drivers() ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+get_video_driver(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+video_init(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+video_quit() ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
%% sdl_window
create_window(_, _, _, _, _, _) ->
diff --git a/src/sdl_video.erl b/src/sdl_video.erl
new file mode 100644
index 0000000..37e2947
--- /dev/null
+++ b/src/sdl_video.erl
@@ -0,0 +1,75 @@
+%% Copyright (c) 2018, Loïc Hoguin <[email protected]>
+%%
+%% Permission to use, copy, modify, and/or distribute this software for any
+%% purpose with or without fee is hereby granted, provided that the above
+%% copyright notice and this permission notice appear in all copies.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-module(sdl_video).
+
+-export([get_current_driver/0]).
+-export([get_display_bounds/1]).
+-export([get_display_dpi/1]).
+-export([get_display_name/1]).
+-export([get_display_usable_bounds/1]).
+-export([get_driver/1]).
+-export([get_num_displays/0]).
+-export([get_num_drivers/0]).
+-export([start/1]).
+-export([stop/0]).
+
+-spec get_current_driver() -> binary() | undefined.
+get_current_driver() ->
+ esdl2:get_current_video_driver(),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec get_display_bounds(integer()) -> sdl_rect:rect() | undefined.
+get_display_bounds(Index) ->
+ esdl2:get_display_bounds(Index),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec get_display_dpi(integer())
+ -> #{diagonal := float(), horizontal := float(), vertical := float()}
+ | undefined.
+get_display_dpi(Index) ->
+ esdl2:get_display_dpi(Index),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec get_display_name(integer()) -> binary() | undefined.
+get_display_name(Index) ->
+ esdl2:get_display_name(Index),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec get_display_usable_bounds(integer()) -> sdl_rect:rect() | undefined.
+get_display_usable_bounds(Index) ->
+ esdl2:get_display_usable_bounds(Index),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec get_driver(integer()) -> binary() | undefined.
+get_driver(Index) ->
+ esdl2:get_video_driver(Index).
+
+-spec get_num_displays() -> integer().
+get_num_displays() ->
+ esdl2:get_num_video_displays(),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec get_num_drivers() -> integer().
+get_num_drivers() ->
+ esdl2:get_num_video_drivers().
+
+-spec start(binary()) -> ok | sdl:error().
+start(DriverName) ->
+ esdl2:video_init(DriverName),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec stop() -> ok.
+stop() ->
+ esdl2:video_quit().