aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-01-07 17:06:24 +0100
committerLoïc Hoguin <[email protected]>2018-01-07 17:06:24 +0100
commit66a56fe7634f6c2cceda4128ef2e746ad2619af3 (patch)
treecd439dc7bcfaa0328b29e6fe92488ee54848c502
parent0a6ef9d42ac008c7b8bf6b3d0f112ce040e3568c (diff)
downloadesdl2-66a56fe7634f6c2cceda4128ef2e746ad2619af3.tar.gz
esdl2-66a56fe7634f6c2cceda4128ef2e746ad2619af3.tar.bz2
esdl2-66a56fe7634f6c2cceda4128ef2e746ad2619af3.zip
Add the display mode query functions
-rw-r--r--README.asciidoc5
-rw-r--r--c_src/esdl2.h10
-rw-r--r--c_src/sdl_pixels.c1
-rw-r--r--c_src/sdl_video.c146
-rw-r--r--src/esdl2.erl20
-rw-r--r--src/sdl_video.erl37
6 files changed, 213 insertions, 6 deletions
diff --git a/README.asciidoc b/README.asciidoc
index 52e4c1b..c48986c 100644
--- a/README.asciidoc
+++ b/README.asciidoc
@@ -86,11 +86,6 @@ 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_GetNumDisplayModes` (video)
-** `SDL_GetDisplayMode` (video)
-** `SDL_GetDesktopDisplayMode` (video)
-** `SDL_GetCurrentDisplayMode` (video)
-** `SDL_GetClosestDisplayMode` (video)
** `SDL_GetWindowDisplayIndex` (window)
** `SDL_SetWindowDisplayMode` (window)
** `SDL_GetWindowDisplayMode` (window)
diff --git a/c_src/esdl2.h b/c_src/esdl2.h
index 6285981..f8215cf 100644
--- a/c_src/esdl2.h
+++ b/c_src/esdl2.h
@@ -97,6 +97,7 @@
A(focus_gained) \
A(focus_lost) \
A(foreign) \
+ A(format) \
A(fullscreen) \
A(fullscreen_desktop) \
A(game_controller) \
@@ -172,6 +173,7 @@
A(present_vsync) \
A(pressed) \
A(quit) \
+ A(refresh_rate) \
A(released) \
A(render_device_reset) \
A(render_targets_reset) \
@@ -394,11 +396,16 @@
F(get_version, 0) \
F(get_revision, 0) \
/* sdl_video */ \
+ F(get_closest_display_mode, 2) \
+ F(get_current_display_mode, 1) \
F(get_current_video_driver, 0) \
+ F(get_desktop_display_mode, 1) \
F(get_display_bounds, 1) \
F(get_display_dpi, 1) \
+ F(get_display_mode, 2) \
F(get_display_name, 1) \
F(get_display_usable_bounds, 1) \
+ F(get_num_display_modes, 1) \
F(get_num_video_displays, 0) \
F(get_num_video_drivers, 0) \
F(get_video_driver, 1) \
@@ -444,8 +451,9 @@ NIF_FUNCTIONS(NIF_FUNCTION_H_DECL)
// Utility functions used across different files.
-NIF_ATOM_TO_ENUM_FUNCTION_DECL(atom_to_bool, SDL_bool)
NIF_ATOM_TO_ENUM_FUNCTION_DECL(atom_to_blend_mode, SDL_BlendMode)
+NIF_ATOM_TO_ENUM_FUNCTION_DECL(atom_to_bool, SDL_bool)
+NIF_ATOM_TO_ENUM_FUNCTION_DECL(atom_to_pixel_format, Uint32)
NIF_ENUM_TO_ATOM_FUNCTION_DECL(blend_mode_to_atom, SDL_BlendMode)
NIF_ENUM_TO_ATOM_FUNCTION_DECL(button_to_atom, Uint8)
NIF_ENUM_TO_ATOM_FUNCTION_DECL(mousewheel_direction_to_atom, Uint32)
diff --git a/c_src/sdl_pixels.c b/c_src/sdl_pixels.c
index 08c9a61..aa22329 100644
--- a/c_src/sdl_pixels.c
+++ b/c_src/sdl_pixels.c
@@ -59,3 +59,4 @@
E(nv21, SDL_PIXELFORMAT_NV21)
NIF_ENUM_TO_ATOM_FUNCTION(pixel_format_to_atom, Uint32, PIXEL_FORMAT_ENUM)
+NIF_ATOM_TO_ENUM_FUNCTION(atom_to_pixel_format, Uint32, PIXEL_FORMAT_ENUM)
diff --git a/c_src/sdl_video.c b/c_src/sdl_video.c
index f559583..3287e6e 100644
--- a/c_src/sdl_video.c
+++ b/c_src/sdl_video.c
@@ -14,6 +14,92 @@
#include "esdl2.h"
+static ERL_NIF_TERM display_mode_to_map(ErlNifEnv* env, SDL_DisplayMode* mode)
+{
+ ERL_NIF_TERM map;
+
+ map = enif_make_new_map(env);
+
+ enif_make_map_put(env, map, atom_format,
+ pixel_format_to_atom(mode->format), &map);
+ enif_make_map_put(env, map, atom_w,
+ enif_make_int(env, mode->w), &map);
+ enif_make_map_put(env, map, atom_h,
+ enif_make_int(env, mode->h), &map);
+ enif_make_map_put(env, map, atom_refresh_rate,
+ enif_make_int(env, mode->refresh_rate), &map);
+
+ // There is also a driverdata field but it is unclear whether it has any use.
+
+ return map;
+}
+
+// get_closest_display_mode
+
+NIF_CALL_HANDLER(thread_get_closest_display_mode)
+{
+ SDL_DisplayMode mode, closest;
+
+ mode.format = (long)args[1];
+ mode.w = (long)args[2];
+ mode.h = (long)args[3];
+ mode.refresh_rate = (long)args[4];
+
+ if (!SDL_GetClosestDisplayMode((long)args[0], &mode, &closest))
+ return atom_undefined;
+
+ return display_mode_to_map(env, &closest);
+}
+
+NIF_FUNCTION(get_closest_display_mode)
+{
+ int displayIndex;
+ ERL_NIF_TERM term;
+ Uint32 format = 0;
+ int w = 0, h = 0, refresh_rate = 0;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &displayIndex));
+ BADARG_IF(!enif_is_map(env, argv[1]));
+
+ // We default to 0 when a field is missing.
+
+ if (enif_get_map_value(env, argv[1], atom_format, &term))
+ BADARG_IF(!atom_to_pixel_format(env, term, &format));
+
+ if (enif_get_map_value(env, argv[1], atom_w, &term))
+ BADARG_IF(!enif_get_int(env, term, &w));
+
+ if (enif_get_map_value(env, argv[1], atom_h, &term))
+ BADARG_IF(!enif_get_int(env, term, &h));
+
+ if (enif_get_map_value(env, argv[1], atom_refresh_rate, &term))
+ BADARG_IF(!enif_get_int(env, term, &refresh_rate));
+
+ return nif_thread_call(env, thread_get_closest_display_mode, 5,
+ displayIndex, format, w, h, refresh_rate);
+}
+
+// get_current_display_mode
+
+NIF_CALL_HANDLER(thread_get_current_display_mode)
+{
+ SDL_DisplayMode mode;
+
+ if (SDL_GetCurrentDisplayMode((long)args[0], &mode))
+ return atom_undefined;
+
+ return display_mode_to_map(env, &mode);
+}
+
+NIF_FUNCTION(get_current_display_mode)
+{
+ int displayIndex;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &displayIndex));
+
+ return nif_thread_call(env, thread_get_current_display_mode, 1, displayIndex);
+}
+
// get_current_video_driver
NIF_CALL_HANDLER(thread_get_current_video_driver)
@@ -37,6 +123,27 @@ NIF_FUNCTION(get_current_video_driver)
return nif_thread_call(env, thread_get_current_video_driver, 0);
}
+// get_desktop_display_mode
+
+NIF_CALL_HANDLER(thread_get_desktop_display_mode)
+{
+ SDL_DisplayMode mode;
+
+ if (SDL_GetDesktopDisplayMode((long)args[0], &mode))
+ return atom_undefined;
+
+ return display_mode_to_map(env, &mode);
+}
+
+NIF_FUNCTION(get_desktop_display_mode)
+{
+ int displayIndex;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &displayIndex));
+
+ return nif_thread_call(env, thread_get_desktop_display_mode, 1, displayIndex);
+}
+
// get_display_bounds
NIF_CALL_HANDLER(thread_get_display_bounds)
@@ -89,6 +196,29 @@ NIF_FUNCTION(get_display_dpi)
return nif_thread_call(env, thread_get_display_dpi, 1, index);
}
+// get_display_mode
+
+NIF_CALL_HANDLER(thread_get_display_mode)
+{
+ SDL_DisplayMode mode;
+
+ if (SDL_GetDisplayMode((long)args[0], (long)args[1], &mode))
+ return atom_undefined;
+
+ return display_mode_to_map(env, &mode);
+}
+
+NIF_FUNCTION(get_display_mode)
+{
+ int displayIndex, index;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &displayIndex));
+ BADARG_IF(!enif_get_int(env, argv[1], &index));
+
+ return nif_thread_call(env, thread_get_display_mode, 2,
+ displayIndex, index);
+}
+
// get_display_name
NIF_CALL_HANDLER(thread_get_display_name)
@@ -137,6 +267,22 @@ NIF_FUNCTION(get_display_usable_bounds)
return nif_thread_call(env, thread_get_display_usable_bounds, 1, index);
}
+// get_num_display_modes
+
+NIF_CALL_HANDLER(thread_get_num_display_modes)
+{
+ return enif_make_int(env, SDL_GetNumDisplayModes((long)args[0]));
+}
+
+NIF_FUNCTION(get_num_display_modes)
+{
+ int displayIndex;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &displayIndex));
+
+ return nif_thread_call(env, thread_get_num_display_modes, 1, displayIndex);
+}
+
// get_num_video_displays
NIF_CALL_HANDLER(thread_get_num_video_displays)
diff --git a/src/esdl2.erl b/src/esdl2.erl
index 015fd62..8216ab1 100644
--- a/src/esdl2.erl
+++ b/src/esdl2.erl
@@ -166,11 +166,16 @@
-export([get_revision/0]).
%% sdl_video
+-export([get_closest_display_mode/2]).
+-export([get_current_display_mode/1]).
-export([get_current_video_driver/0]).
+-export([get_desktop_display_mode/1]).
-export([get_display_bounds/1]).
-export([get_display_dpi/1]).
+-export([get_display_mode/2]).
-export([get_display_name/1]).
-export([get_display_usable_bounds/1]).
+-export([get_num_display_modes/1]).
-export([get_num_video_displays/0]).
-export([get_num_video_drivers/0]).
-export([get_video_driver/1]).
@@ -602,21 +607,36 @@ get_revision() ->
%% sdl_video
+get_closest_display_mode(_, _) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
+get_current_display_mode(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
get_current_video_driver() ->
erlang:nif_error({not_loaded, ?MODULE}).
+get_desktop_display_mode(_) ->
+ 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_mode(_, _) ->
+ 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_display_modes(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+
get_num_video_displays() ->
erlang:nif_error({not_loaded, ?MODULE}).
diff --git a/src/sdl_video.erl b/src/sdl_video.erl
index 37e2947..06849c2 100644
--- a/src/sdl_video.erl
+++ b/src/sdl_video.erl
@@ -14,22 +14,49 @@
-module(sdl_video).
+-export([get_closest_display_mode/2]).
+-export([get_current_display_mode/1]).
-export([get_current_driver/0]).
+-export([get_desktop_display_mode/1]).
-export([get_display_bounds/1]).
-export([get_display_dpi/1]).
+-export([get_display_mode/2]).
-export([get_display_name/1]).
-export([get_display_usable_bounds/1]).
-export([get_driver/1]).
+-export([get_num_display_modes/1]).
-export([get_num_displays/0]).
-export([get_num_drivers/0]).
-export([start/1]).
-export([stop/0]).
+-type display_mode() :: #{
+ format => sdl_pixels:pixel_format(),
+ w => integer(),
+ h => integer(),
+ refresh_rate => integer()
+}.
+
+-spec get_closest_display_mode(integer(), display_mode()) -> display_mode() | undefined.
+get_closest_display_mode(DisplayIndex, Mode) ->
+ esdl2:get_closest_display_mode(DisplayIndex, Mode),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
+-spec get_current_display_mode(integer()) -> display_mode() | undefined.
+get_current_display_mode(DisplayIndex) ->
+ esdl2:get_current_display_mode(DisplayIndex),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
-spec get_current_driver() -> binary() | undefined.
get_current_driver() ->
esdl2:get_current_video_driver(),
receive {'_nif_thread_ret_', Ret} -> Ret end.
+-spec get_desktop_display_mode(integer()) -> display_mode() | undefined.
+get_desktop_display_mode(DisplayIndex) ->
+ esdl2:get_desktop_display_mode(DisplayIndex),
+ 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),
@@ -42,6 +69,11 @@ get_display_dpi(Index) ->
esdl2:get_display_dpi(Index),
receive {'_nif_thread_ret_', Ret} -> Ret end.
+-spec get_display_mode(integer(), integer()) -> display_mode() | undefined.
+get_display_mode(DisplayIndex, Index) ->
+ esdl2:get_display_mode(DisplayIndex, Index),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
-spec get_display_name(integer()) -> binary() | undefined.
get_display_name(Index) ->
esdl2:get_display_name(Index),
@@ -56,6 +88,11 @@ get_display_usable_bounds(Index) ->
get_driver(Index) ->
esdl2:get_video_driver(Index).
+-spec get_num_display_modes(integer()) -> integer().
+get_num_display_modes(DisplayIndex) ->
+ esdl2:get_num_display_modes(DisplayIndex),
+ receive {'_nif_thread_ret_', Ret} -> Ret end.
+
-spec get_num_displays() -> integer().
get_num_displays() ->
esdl2:get_num_video_displays(),