aboutsummaryrefslogtreecommitdiffstats
path: root/c_src
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2017-12-21 23:32:18 +0100
committerLoïc Hoguin <[email protected]>2017-12-21 23:32:18 +0100
commit9a8a6bf9b8414470952b008c84515b9516ddc7f2 (patch)
treed7c69c3fc273e25a5e9f8c23e1750c42bd63d7e3 /c_src
parentb0950785e72d9d59c6fd816c01d203ecb083c663 (diff)
downloadesdl2-9a8a6bf9b8414470952b008c84515b9516ddc7f2.tar.gz
esdl2-9a8a6bf9b8414470952b008c84515b9516ddc7f2.tar.bz2
esdl2-9a8a6bf9b8414470952b008c84515b9516ddc7f2.zip
Add sdl_cursor along with all its related functions
Diffstat (limited to 'c_src')
-rw-r--r--c_src/esdl2.h15
-rw-r--r--c_src/esdl2_cursors.c96
-rw-r--r--c_src/esdl2_renderers.c4
-rw-r--r--c_src/esdl2_windows.c4
-rw-r--r--c_src/sdl_cursor.c262
-rw-r--r--c_src/sdl_mouse.c16
-rw-r--r--c_src/sdl_renderer.c2
7 files changed, 376 insertions, 23 deletions
diff --git a/c_src/esdl2.h b/c_src/esdl2.h
index ca9a424..c265110 100644
--- a/c_src/esdl2.h
+++ b/c_src/esdl2.h
@@ -139,6 +139,7 @@
#define NIF_RES_TYPE(r) SDL_ ## r
#define NIF_RESOURCES(R) \
+ R(Cursor) \
R(GLContext) \
R(Renderer) \
R(Surface) \
@@ -176,6 +177,14 @@
F(has_sse3, 0) \
F(has_sse41, 0) \
F(has_sse42, 0) \
+ /* sdl_cursor */ \
+ F(create_cursor, 6) \
+ F(create_color_cursor, 3) \
+ F(create_system_cursor, 1) \
+ F(get_cursor, 0) \
+ F(get_default_cursor, 0) \
+ F(set_cursor, 1) \
+ F(show_cursor, 1) \
/* sdl_events */ \
F(poll_event, 0) \
/* sdl_filesystem */ \
@@ -302,6 +311,12 @@ ERL_NIF_TERM esdl2_renderers_find(ErlNifEnv*, SDL_Renderer*);
void esdl2_renderers_remove(SDL_Renderer*);
void esdl2_renderers_free(void);
+void esdl2_cursors_init(void);
+void esdl2_cursors_insert(SDL_Cursor*, obj_Cursor*);
+ERL_NIF_TERM esdl2_cursors_find(ErlNifEnv*, SDL_Cursor*);
+void esdl2_cursors_remove(SDL_Cursor*);
+void esdl2_cursors_free(void);
+
ErlNifPid* get_callback_process(void);
#define sdl_error_tuple(env) \
diff --git a/c_src/esdl2_cursors.c b/c_src/esdl2_cursors.c
new file mode 100644
index 0000000..8ce576c
--- /dev/null
+++ b/c_src/esdl2_cursors.c
@@ -0,0 +1,96 @@
+// Copyright (c) 2017, 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"
+#include <sys/queue.h>
+
+struct esdl2_cursor {
+ LIST_ENTRY(esdl2_cursor) entries;
+
+ SDL_Cursor* cursor;
+ obj_Cursor* res;
+};
+
+static LIST_HEAD(esdl2_cursor_list, esdl2_cursor) cursors;
+
+void esdl2_cursors_init()
+{
+ LIST_INIT(&cursors);
+}
+
+void esdl2_cursors_insert(SDL_Cursor* cursor, obj_Cursor* res)
+{
+ struct esdl2_cursor* item;
+
+ item = malloc(sizeof(struct esdl2_cursor));
+ item->cursor = cursor;
+ item->res = res;
+
+ LIST_INSERT_HEAD(&cursors, item, entries);
+}
+
+static struct esdl2_cursor* esdl2_cursors_find_entry(SDL_Cursor* cursor)
+{
+ struct esdl2_cursor* head;
+
+ head = LIST_FIRST(&cursors);
+ while (head != NULL) {
+ if (head->cursor == cursor)
+ return head;
+
+ head = LIST_NEXT(head, entries);
+ }
+
+ return NULL;
+}
+
+ERL_NIF_TERM esdl2_cursors_find(ErlNifEnv* env, SDL_Cursor* cursor)
+{
+ struct esdl2_cursor* entry;
+ ERL_NIF_TERM term;
+
+ entry = esdl2_cursors_find_entry(cursor);
+
+ if (entry == NULL)
+ return atom_undefined;
+
+ term = enif_make_resource(env, entry->res);
+
+ return term;
+}
+
+void esdl2_cursors_remove(SDL_Cursor* cursor)
+{
+ struct esdl2_cursor* entry;
+
+ entry = esdl2_cursors_find_entry(cursor);
+
+ if (entry == NULL)
+ return;
+
+ LIST_REMOVE(entry, entries);
+}
+
+void esdl2_cursors_free()
+{
+ struct esdl2_cursor *head, *next;
+
+ head = LIST_FIRST(&cursors);
+ while (head != NULL) {
+ next = LIST_NEXT(head, entries);
+ free(head);
+ head = next;
+ }
+}
+
diff --git a/c_src/esdl2_renderers.c b/c_src/esdl2_renderers.c
index 281079c..70ef30d 100644
--- a/c_src/esdl2_renderers.c
+++ b/c_src/esdl2_renderers.c
@@ -44,9 +44,7 @@ void esdl2_renderers_insert(SDL_Renderer* renderer, obj_Renderer* res, obj_Windo
LIST_INSERT_HEAD(&renderers, item, entries);
}
-struct esdl2_renderer* esdl2_renderers_find_entry(SDL_Renderer* renderer);
-
-struct esdl2_renderer* esdl2_renderers_find_entry(SDL_Renderer* renderer)
+static struct esdl2_renderer* esdl2_renderers_find_entry(SDL_Renderer* renderer)
{
struct esdl2_renderer* head;
diff --git a/c_src/esdl2_windows.c b/c_src/esdl2_windows.c
index 8855987..bff9948 100644
--- a/c_src/esdl2_windows.c
+++ b/c_src/esdl2_windows.c
@@ -40,9 +40,7 @@ void esdl2_windows_insert(SDL_Window* window, obj_Window* res)
LIST_INSERT_HEAD(&windows, item, entries);
}
-struct esdl2_window* esdl2_windows_find_entry(SDL_Window* window);
-
-struct esdl2_window* esdl2_windows_find_entry(SDL_Window* window)
+static struct esdl2_window* esdl2_windows_find_entry(SDL_Window* window)
{
struct esdl2_window* head;
diff --git a/c_src/sdl_cursor.c b/c_src/sdl_cursor.c
new file mode 100644
index 0000000..59ad923
--- /dev/null
+++ b/c_src/sdl_cursor.c
@@ -0,0 +1,262 @@
+// Copyright (c) 2017, 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"
+
+#define SYSTEM_CURSOR_ENUM(E) \
+ E(arrow, SDL_SYSTEM_CURSOR_ARROW) \
+ E(ibeam, SDL_SYSTEM_CURSOR_IBEAM) \
+ E(wait, SDL_SYSTEM_CURSOR_WAIT) \
+ E(crosshair, SDL_SYSTEM_CURSOR_CROSSHAIR) \
+ E(wait_arrow, SDL_SYSTEM_CURSOR_WAITARROW) \
+ E(size_nwse, SDL_SYSTEM_CURSOR_SIZENWSE) \
+ E(size_nesw, SDL_SYSTEM_CURSOR_SIZENESW) \
+ E(size_we, SDL_SYSTEM_CURSOR_SIZEWE) \
+ E(size_ns, SDL_SYSTEM_CURSOR_SIZENS) \
+ E(size_all, SDL_SYSTEM_CURSOR_SIZEALL) \
+ E(no, SDL_SYSTEM_CURSOR_NO) \
+ E(hand, SDL_SYSTEM_CURSOR_HAND)
+
+static NIF_ATOM_TO_ENUM_FUNCTION(atom_to_system_cursor, int, SYSTEM_CURSOR_ENUM)
+
+void dtor_Cursor(ErlNifEnv* env, void* obj)
+{
+ SDL_Cursor* cursor = NIF_RES_GET(Cursor, obj);
+
+ SDL_FreeCursor(cursor);
+ esdl2_cursors_remove(cursor);
+}
+
+// create_cursor
+
+NIF_CALL_HANDLER(thread_create_cursor)
+{
+ SDL_Cursor* cursor;
+ obj_Cursor* res;
+ ERL_NIF_TERM term;
+ ErlNifBinary data, mask;
+
+ enif_inspect_binary(args[0], (long)args[1], &data);
+ enif_inspect_binary(args[0], (long)args[2], &mask);
+
+ cursor = SDL_CreateCursor(data.data, mask.data,
+ (long)args[3], (long)args[4], (long)args[5], (long)args[6]);
+
+ enif_free_env(args[0]);
+
+ if (!cursor)
+ return sdl_error_tuple(env);
+
+ NIF_RES_TO_PTR_AND_TERM(Cursor, cursor, res, term);
+
+ esdl2_cursors_insert(cursor, res);
+
+ return enif_make_tuple2(env,
+ atom_ok,
+ term
+ );
+}
+
+NIF_FUNCTION(create_cursor)
+{
+ ErlNifEnv* bin_env;
+ ERL_NIF_TERM data, mask;
+ int w, h, hot_x, hot_y;
+
+ BADARG_IF(!enif_is_binary(env, argv[0]));
+ BADARG_IF(!enif_is_binary(env, argv[1]));
+ BADARG_IF(!enif_get_int(env, argv[2], &w));
+ BADARG_IF(!enif_get_int(env, argv[3], &h));
+ BADARG_IF(!enif_get_int(env, argv[4], &hot_x));
+ BADARG_IF(!enif_get_int(env, argv[5], &hot_y));
+
+ // We copy the binaries to avoid copying their content.
+ bin_env = enif_alloc_env();
+ data = enif_make_copy(bin_env, argv[0]);
+ mask = enif_make_copy(bin_env, argv[1]);
+
+ return nif_thread_call(env, thread_create_cursor, 7,
+ bin_env, data, mask, w, h, hot_x, hot_y);
+}
+
+// create_color_cursor
+
+NIF_CALL_HANDLER(thread_create_color_cursor)
+{
+ SDL_Cursor* cursor;
+ obj_Cursor* res;
+ ERL_NIF_TERM term;
+
+ cursor = SDL_CreateColorCursor(args[0], (long)args[1], (long)args[2]);
+
+ if (!cursor)
+ return sdl_error_tuple(env);
+
+ NIF_RES_TO_PTR_AND_TERM(Cursor, cursor, res, term);
+
+ esdl2_cursors_insert(cursor, res);
+
+ return enif_make_tuple2(env,
+ atom_ok,
+ term
+ );
+}
+
+NIF_FUNCTION(create_color_cursor)
+{
+ void* surface_res;
+ int hot_x, hot_y;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Surface, &surface_res));
+ BADARG_IF(!enif_get_int(env, argv[1], &hot_x));
+ BADARG_IF(!enif_get_int(env, argv[2], &hot_y));
+
+ return nif_thread_call(env, thread_create_color_cursor, 3,
+ NIF_RES_GET(Surface, surface_res), hot_x, hot_y);
+}
+
+// create_system_cursor
+
+NIF_CALL_HANDLER(thread_create_system_cursor)
+{
+ SDL_Cursor* cursor;
+ obj_Cursor* res;
+ ERL_NIF_TERM term;
+
+ cursor = SDL_CreateSystemCursor((long)args[0]);
+
+ if (!cursor)
+ return sdl_error_tuple(env);
+
+ NIF_RES_TO_PTR_AND_TERM(Cursor, cursor, res, term);
+
+ esdl2_cursors_insert(cursor, res);
+
+ return enif_make_tuple2(env,
+ atom_ok,
+ term
+ );
+}
+
+NIF_FUNCTION(create_system_cursor)
+{
+ int id;
+
+ BADARG_IF(!atom_to_system_cursor(env, argv[0], &id));
+
+ return nif_thread_call(env, thread_create_system_cursor, 1, id);
+}
+
+// get_cursor
+
+NIF_CALL_HANDLER(thread_get_cursor)
+{
+ SDL_Cursor* cursor;
+ obj_Cursor* res;
+ ERL_NIF_TERM term;
+
+ cursor = SDL_GetCursor();
+
+ // There is no mouse.
+ if (!cursor)
+ return atom_undefined;
+
+ term = esdl2_cursors_find(env, cursor);
+
+ if (!enif_is_identical(term, atom_undefined))
+ return term;
+
+ // We don't know this cursor. It's probably a system cursor.
+ // We should insert it in the list to have the same reference
+ // for it while it's active.
+
+ NIF_RES_TO_PTR_AND_TERM(Cursor, cursor, res, term);
+
+ esdl2_cursors_insert(cursor, res);
+
+ return term;
+}
+
+NIF_FUNCTION(get_cursor)
+{
+ return nif_thread_call(env, thread_get_cursor, 0);
+}
+
+// get_default_cursor
+
+NIF_CALL_HANDLER(thread_get_default_cursor)
+{
+ SDL_Cursor* cursor;
+ obj_Cursor* res;
+ ERL_NIF_TERM term;
+
+ cursor = SDL_GetDefaultCursor();
+
+ // There is no mouse.
+ if (!cursor)
+ return atom_undefined;
+
+ term = esdl2_cursors_find(env, cursor);
+
+ if (!enif_is_identical(term, atom_undefined))
+ return term;
+
+ // We don't know this cursor. It's probably a system cursor.
+ // We should insert it in the list to have the same reference
+ // for it while it's active.
+
+ NIF_RES_TO_PTR_AND_TERM(Cursor, cursor, res, term);
+
+ esdl2_cursors_insert(cursor, res);
+
+ return term;
+}
+
+NIF_FUNCTION(get_default_cursor)
+{
+ return nif_thread_call(env, thread_get_default_cursor, 0);
+}
+
+// set_cursor
+
+NIF_CAST_HANDLER(thread_set_cursor)
+{
+ SDL_SetCursor(args[0]);
+}
+
+NIF_FUNCTION(set_cursor)
+{
+ void* cursor_res;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Cursor, &cursor_res));
+
+ return nif_thread_cast(env, thread_set_cursor, 1,
+ NIF_RES_GET(Cursor, cursor_res));
+}
+
+// show_cursor
+
+NIF_CALL_HANDLER(thread_show_cursor)
+{
+ return enif_make_int(env, SDL_ShowCursor((long)args[0]));
+}
+
+NIF_FUNCTION(show_cursor)
+{
+ int toggle;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &toggle));
+
+ return nif_thread_call(env, thread_show_cursor, 1, toggle);
+}
diff --git a/c_src/sdl_mouse.c b/c_src/sdl_mouse.c
index b74d088..8b36131 100644
--- a/c_src/sdl_mouse.c
+++ b/c_src/sdl_mouse.c
@@ -14,22 +14,6 @@
#include "esdl2.h"
-#define SYSTEM_CURSOR_ENUM(E) \
- E(arrow, SDL_SYSTEM_CURSOR_ARROW) \
- E(ibeam, SDL_SYSTEM_CURSOR_IBEAM) \
- E(wait, SDL_SYSTEM_CURSOR_WAIT) \
- E(crosshair, SDL_SYSTEM_CURSOR_CROSSHAIR) \
- E(wait_arrow, SDL_SYSTEM_CURSOR_WAITARROW) \
- E(size_nwse, SDL_SYSTEM_CURSOR_SIZENWSE) \
- E(size_nesw, SDL_SYSTEM_CURSOR_SIZENESW) \
- E(size_we, SDL_SYSTEM_CURSOR_SIZEWE) \
- E(size_ns, SDL_SYSTEM_CURSOR_SIZENS) \
- E(size_all, SDL_SYSTEM_CURSOR_SIZEALL) \
- E(no, SDL_SYSTEM_CURSOR_NO) \
- E(hand, SDL_SYSTEM_CURSOR_HAND)
-
-static NIF_ATOM_TO_ENUM_FUNCTION(atom_to_system_cursor, int, SYSTEM_CURSOR_ENUM)
-
#define MOUSEWHEEL_DIRECTION_ENUM(E) \
E(normal, SDL_MOUSEWHEEL_NORMAL) \
E(flipped, SDL_MOUSEWHEEL_FLIPPED)
diff --git a/c_src/sdl_renderer.c b/c_src/sdl_renderer.c
index 81e60c4..23b41ca 100644
--- a/c_src/sdl_renderer.c
+++ b/c_src/sdl_renderer.c
@@ -880,7 +880,7 @@ NIF_FUNCTION(render_set_viewport)
NIF_RES_GET(Renderer, renderer_res), x, y, w, h);
}
-// get_window_grab
+// render_target_supported
NIF_CALL_HANDLER(thread_render_target_supported)
{