aboutsummaryrefslogtreecommitdiffstats
path: root/c_src/sdl_mouse.c
diff options
context:
space:
mode:
Diffstat (limited to 'c_src/sdl_mouse.c')
-rw-r--r--c_src/sdl_mouse.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/c_src/sdl_mouse.c b/c_src/sdl_mouse.c
new file mode 100644
index 0000000..b74d088
--- /dev/null
+++ b/c_src/sdl_mouse.c
@@ -0,0 +1,224 @@
+// 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)
+
+#define MOUSEWHEEL_DIRECTION_ENUM(E) \
+ E(normal, SDL_MOUSEWHEEL_NORMAL) \
+ E(flipped, SDL_MOUSEWHEEL_FLIPPED)
+
+static NIF_ATOM_TO_ENUM_FUNCTION(atom_to_mousewheel_direction, int, MOUSEWHEEL_DIRECTION_ENUM)
+
+static ERL_NIF_TERM get_mouse_state_common(ErlNifEnv* env, int x, int y, Uint32 state)
+{
+ ERL_NIF_TERM list;
+
+ list = enif_make_list(env, 0);
+
+ if (state & SDL_BUTTON_LMASK)
+ list = enif_make_list_cell(env, atom_left, list);
+ if (state & SDL_BUTTON_MMASK)
+ list = enif_make_list_cell(env, atom_middle, list);
+ if (state & SDL_BUTTON_RMASK)
+ list = enif_make_list_cell(env, atom_right, list);
+ if (state & SDL_BUTTON_X1MASK)
+ list = enif_make_list_cell(env, atom_x1, list);
+ if (state & SDL_BUTTON_X2MASK)
+ list = enif_make_list_cell(env, atom_x2, list);
+
+ return enif_make_tuple3(env,
+ enif_make_int(env, x),
+ enif_make_int(env, y),
+ list
+ );
+}
+
+// capture_mouse
+
+NIF_CALL_HANDLER(thread_capture_mouse)
+{
+ if (SDL_CaptureMouse((long)args[0]))
+ return sdl_error_tuple(env);
+
+ return atom_ok;
+}
+
+NIF_FUNCTION(capture_mouse)
+{
+ SDL_bool b;
+
+ BADARG_IF(!atom_to_bool(env, argv[0], &b));
+
+ return nif_thread_call(env, thread_capture_mouse, 1, b);
+}
+
+// get_global_mouse_state
+
+NIF_CALL_HANDLER(thread_get_global_mouse_state)
+{
+ Uint32 state;
+ int x, y;
+
+ state = SDL_GetGlobalMouseState(&x, &y);
+
+ return get_mouse_state_common(env, x, y, state);
+}
+
+NIF_FUNCTION(get_global_mouse_state)
+{
+ return nif_thread_call(env, thread_get_global_mouse_state, 0);
+}
+
+// get_mouse_focus
+
+NIF_CALL_HANDLER(thread_get_mouse_focus)
+{
+ SDL_Window* window;
+
+ window = SDL_GetMouseFocus();
+
+ if (!window)
+ return atom_undefined;
+
+ return esdl2_windows_find(env, window);
+}
+
+NIF_FUNCTION(get_mouse_focus)
+{
+ return nif_thread_call(env, thread_get_mouse_focus, 0);
+}
+
+// get_mouse_state
+
+NIF_CALL_HANDLER(thread_get_mouse_state)
+{
+ Uint32 state;
+ int x, y;
+
+ state = SDL_GetMouseState(&x, &y);
+
+ return get_mouse_state_common(env, x, y, state);
+}
+
+NIF_FUNCTION(get_mouse_state)
+{
+ return nif_thread_call(env, thread_get_mouse_state, 0);
+}
+
+// get_relative_mouse_mode
+
+NIF_CALL_HANDLER(thread_get_relative_mouse_mode)
+{
+ if (SDL_GetRelativeMouseMode())
+ return atom_true;
+
+ return atom_false;
+}
+
+NIF_FUNCTION(get_relative_mouse_mode)
+{
+ return nif_thread_call(env, thread_get_relative_mouse_mode, 0);
+}
+
+// get_relative_mouse_state
+
+NIF_CALL_HANDLER(thread_get_relative_mouse_state)
+{
+ Uint32 state;
+ int x, y;
+
+ state = SDL_GetRelativeMouseState(&x, &y);
+
+ return get_mouse_state_common(env, x, y, state);
+}
+
+NIF_FUNCTION(get_relative_mouse_state)
+{
+ return nif_thread_call(env, thread_get_relative_mouse_state, 0);
+}
+
+// set_relative_mouse_mode
+
+NIF_CALL_HANDLER(thread_set_relative_mouse_mode)
+{
+ if (SDL_SetRelativeMouseMode((long)args[0]))
+ return sdl_error_tuple(env);
+
+ return atom_ok;
+}
+
+NIF_FUNCTION(set_relative_mouse_mode)
+{
+ SDL_bool b;
+
+ BADARG_IF(!atom_to_bool(env, argv[0], &b));
+
+ return nif_thread_call(env, thread_set_relative_mouse_mode, 1, b);
+}
+
+// warp_mouse_global
+
+NIF_CALL_HANDLER(thread_warp_mouse_global)
+{
+ if (SDL_WarpMouseGlobal((long)args[0], (long)args[1]))
+ return sdl_error_tuple(env);
+
+ return atom_ok;
+}
+
+NIF_FUNCTION(warp_mouse_global)
+{
+ int x, y;
+
+ BADARG_IF(!enif_get_int(env, argv[0], &x));
+ BADARG_IF(!enif_get_int(env, argv[1], &y));
+
+ return nif_thread_call(env, thread_warp_mouse_global, 2, x, y);
+}
+
+// warp_mouse_in_window
+
+NIF_CAST_HANDLER(thread_warp_mouse_in_window)
+{
+ SDL_WarpMouseInWindow(args[0], (long)args[1], (long)args[2]);
+}
+
+NIF_FUNCTION(warp_mouse_in_window)
+{
+ void* window_res;
+ int x, y;
+
+ BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res));
+ BADARG_IF(!enif_get_int(env, argv[1], &x));
+ BADARG_IF(!enif_get_int(env, argv[2], &y));
+
+ return nif_thread_cast(env, thread_warp_mouse_in_window, 3,
+ NIF_RES_GET(Window, window_res), x, y);
+}