aboutsummaryrefslogblamecommitdiffstats
path: root/c_src/sdl_mouse.c
blob: 8b3613134371faa8283430900a51d620d29423ba (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16















                                                                           































































































































































































                                                                                              
// 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 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);
}