aboutsummaryrefslogtreecommitdiffstats
path: root/c_src
diff options
context:
space:
mode:
Diffstat (limited to 'c_src')
-rw-r--r--c_src/esdl2.h61
-rw-r--r--c_src/sdl_events.c504
-rw-r--r--c_src/sdl_keycode.c30
-rw-r--r--c_src/sdl_mouse.c18
-rw-r--r--c_src/sdl_window.c20
5 files changed, 486 insertions, 147 deletions
diff --git a/c_src/esdl2.h b/c_src/esdl2.h
index 5a1ec99..bd80acf 100644
--- a/c_src/esdl2.h
+++ b/c_src/esdl2.h
@@ -23,8 +23,16 @@
A(accelerated) \
A(add) \
A(allow_high_dpi) \
+ A(app_did_enter_background) \
+ A(app_did_enter_foreground) \
+ A(app_low_memory) \
+ A(app_terminating) \
+ A(app_will_enter_background) \
+ A(app_will_enter_foreground) \
A(arrow) \
A(audio) \
+ A(audio_device_added) \
+ A(audio_device_removed) \
A(blend) \
A(borderless) \
A(button) \
@@ -34,10 +42,24 @@
A(charged) \
A(charging) \
A(clicks) \
+ A(clipboard_update) \
A(close) \
+ A(controller_axis_motion) \
+ A(controller_button_down) \
+ A(controller_button_up) \
+ A(controller_device_added) \
+ A(controller_device_remapped) \
+ A(controller_device_removed) \
A(crosshair) \
- A(data) \
+ A(data1) \
+ A(data2) \
A(direction) \
+ A(dollar_gesture) \
+ A(dollar_record) \
+ A(drop_begin) \
+ A(drop_complete) \
+ A(drop_file) \
+ A(drop_text) \
A(dst_alpha) \
A(dst_color) \
A(enter) \
@@ -47,6 +69,10 @@
A(everything) \
A(exposed) \
A(false) \
+ A(finger_down) \
+ A(finger_motion) \
+ A(finger_up) \
+ A(first) \
A(flipped) \
A(focus_gained) \
A(focus_lost) \
@@ -54,18 +80,29 @@
A(fullscreen) \
A(fullscreen_desktop) \
A(game_controller) \
+ A(get) \
A(h) \
A(hand) \
A(haptic) \
A(hidden) \
+ A(hit_test) \
A(horizontal) \
A(ibeam) \
A(input_focus) \
A(input_grabbed) \
A(invalid) \
+ A(joy_axis_motion) \
+ A(joy_ball_motion) \
+ A(joy_button_down) \
+ A(joy_button_up) \
+ A(joy_device_added) \
+ A(joy_device_removed) \
+ A(joy_hat_motion) \
A(joystick) \
A(key_down) \
A(key_up) \
+ A(keymap_changed) \
+ A(last) \
A(leave) \
A(left) \
A(left_alt) \
@@ -91,6 +128,7 @@
A(mouse_up) \
A(mouse_wheel) \
A(moved) \
+ A(multi_gesture) \
A(no) \
A(no_battery) \
A(none) \
@@ -99,8 +137,13 @@
A(on_battery) \
A(one) \
A(opengl) \
+ A(peek) \
A(present_vsync) \
+ A(pressed) \
A(quit) \
+ A(released) \
+ A(render_targets_reset) \
+ A(render_device_reset) \
A(repeat) \
A(resizable) \
A(resized) \
@@ -125,7 +168,11 @@
A(state) \
A(substract) \
A(sym) \
+ A(syswm) \
+ A(take_focus) \
A(target_texture) \
+ A(text_editing) \
+ A(text_input) \
A(touch) \
A(true) \
A(timer) \
@@ -206,7 +253,13 @@
F(set_cursor, 1) \
F(show_cursor, 1) \
/* sdl_events */ \
+ F(flush_event, 1) \
+ F(flush_events, 2) \
+ F(has_event, 1) \
+ F(has_events, 2) \
+ F(peep_events, 4) \
F(poll_event, 0) \
+ F(pump_events, 0) \
/* sdl_filesystem */ \
F(get_base_path, 0) \
F(get_pref_path, 2) \
@@ -316,7 +369,13 @@ NIF_FUNCTIONS(NIF_FUNCTION_H_DECL)
NIF_ATOM_TO_ENUM_FUNCTION_DECL(atom_to_bool, SDL_bool)
NIF_ATOM_TO_ENUM_FUNCTION_DECL(atom_to_blend_mode, SDL_BlendMode)
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)
+NIF_ENUM_TO_ATOM_FUNCTION_DECL(window_event_to_atom, Uint8)
+
+NIF_FLAGS_TO_LIST_FUNCTION_DECL(keymod_flags_to_list, Uint16)
+
+ERL_NIF_TERM mouse_state_to_list(ErlNifEnv*, Uint32);
// --
diff --git a/c_src/sdl_events.c b/c_src/sdl_events.c
index 9b212ce..bf91356 100644
--- a/c_src/sdl_events.c
+++ b/c_src/sdl_events.c
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2015, Loïc Hoguin <[email protected]>
+// Copyright (c) 2014-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
@@ -15,175 +15,391 @@
#include "esdl2.h"
#define EVENT_TYPE_ENUM(E) \
+ E(first, SDL_FIRSTEVENT) \
+ E(quit, SDL_QUIT) \
+ E(app_terminating, SDL_APP_TERMINATING) \
+ E(app_low_memory, SDL_APP_LOWMEMORY) \
+ E(app_will_enter_background, SDL_APP_WILLENTERBACKGROUND) \
+ E(app_did_enter_background, SDL_APP_DIDENTERBACKGROUND) \
+ E(app_will_enter_foreground, SDL_APP_WILLENTERFOREGROUND) \
+ E(app_did_enter_foreground, SDL_APP_DIDENTERFOREGROUND) \
E(window, SDL_WINDOWEVENT) \
+ E(syswm, SDL_SYSWMEVENT) \
E(key_down, SDL_KEYDOWN) \
E(key_up, SDL_KEYUP) \
+ E(text_editing, SDL_TEXTEDITING) \
+ E(text_input, SDL_TEXTINPUT) \
+ E(keymap_changed, SDL_KEYMAPCHANGED) \
E(mouse_motion, SDL_MOUSEMOTION) \
E(mouse_down, SDL_MOUSEBUTTONDOWN) \
E(mouse_up, SDL_MOUSEBUTTONUP) \
E(mouse_wheel, SDL_MOUSEWHEEL) \
- E(quit, SDL_QUIT)
+ E(joy_axis_motion, SDL_JOYAXISMOTION) \
+ E(joy_ball_motion, SDL_JOYBALLMOTION) \
+ E(joy_hat_motion, SDL_JOYHATMOTION) \
+ E(joy_button_down, SDL_JOYBUTTONDOWN) \
+ E(joy_button_up, SDL_JOYBUTTONUP) \
+ E(joy_device_added, SDL_JOYDEVICEADDED) \
+ E(joy_device_removed, SDL_JOYDEVICEREMOVED) \
+ E(controller_axis_motion, SDL_CONTROLLERAXISMOTION) \
+ E(controller_button_down, SDL_CONTROLLERBUTTONDOWN) \
+ E(controller_button_up, SDL_CONTROLLERBUTTONUP) \
+ E(controller_device_added, SDL_CONTROLLERDEVICEADDED) \
+ E(controller_device_removed, SDL_CONTROLLERDEVICEREMOVED) \
+ E(controller_device_remapped, SDL_CONTROLLERDEVICEREMAPPED) \
+ E(finger_down, SDL_FINGERDOWN) \
+ E(finger_up, SDL_FINGERUP) \
+ E(finger_motion, SDL_FINGERMOTION) \
+ E(dollar_gesture, SDL_DOLLARGESTURE) \
+ E(dollar_record, SDL_DOLLARRECORD) \
+ E(multi_gesture, SDL_MULTIGESTURE) \
+ E(clipboard_update, SDL_CLIPBOARDUPDATE) \
+ E(drop_file, SDL_DROPFILE) \
+ E(drop_text, SDL_DROPTEXT) \
+ E(drop_begin, SDL_DROPBEGIN) \
+ E(drop_complete, SDL_DROPCOMPLETE) \
+ E(audio_device_added, SDL_AUDIODEVICEADDED) \
+ E(audio_device_removed, SDL_AUDIODEVICEREMOVED) \
+ E(render_targets_reset, SDL_RENDER_TARGETS_RESET) \
+ E(render_device_reset, SDL_RENDER_DEVICE_RESET) \
+ E(last, SDL_LASTEVENT)
static NIF_ENUM_TO_ATOM_FUNCTION(event_type_to_atom, Uint32, EVENT_TYPE_ENUM)
+static NIF_ATOM_TO_ENUM_FUNCTION(atom_to_event_type, Uint32, EVENT_TYPE_ENUM)
-#define WINDOW_EVENT_ENUM(E) \
- E(shown, SDL_WINDOWEVENT_SHOWN) \
- E(hidden, SDL_WINDOWEVENT_HIDDEN) \
- E(exposed, SDL_WINDOWEVENT_EXPOSED) \
- E(moved, SDL_WINDOWEVENT_MOVED) \
- E(resized, SDL_WINDOWEVENT_RESIZED) \
- E(size_changed, SDL_WINDOWEVENT_SIZE_CHANGED) \
- E(minimized, SDL_WINDOWEVENT_MINIMIZED) \
- E(maximized, SDL_WINDOWEVENT_MAXIMIZED) \
- E(restored, SDL_WINDOWEVENT_RESTORED) \
- E(enter, SDL_WINDOWEVENT_ENTER) \
- E(leave, SDL_WINDOWEVENT_LEAVE) \
- E(focus_gained, SDL_WINDOWEVENT_FOCUS_GAINED) \
- E(focus_lost, SDL_WINDOWEVENT_FOCUS_LOST) \
- E(close, SDL_WINDOWEVENT_CLOSE)
-
-static NIF_ENUM_TO_ATOM_FUNCTION(window_event_to_atom, Uint8, WINDOW_EVENT_ENUM)
-
-#define KEYMOD_FLAGS(F) \
- F(left_shift, KMOD_LSHIFT) \
- F(right_shift, KMOD_RSHIFT) \
- F(left_ctrl, KMOD_LCTRL) \
- F(right_ctrl, KMOD_RCTRL) \
- F(left_alt, KMOD_LALT) \
- F(right_alt, KMOD_RALT) \
- F(left_gui, KMOD_LGUI) \
- F(right_gui, KMOD_RGUI) \
- F(num, KMOD_NUM) \
- F(caps, KMOD_CAPS) \
- F(mode, KMOD_MODE)
-
-static NIF_FLAGS_TO_LIST_FUNCTION(keymod_flags_to_list, Uint16, KEYMOD_FLAGS)
-
-#define BUTTON_ENUM(E) \
- E(left, SDL_BUTTON_LEFT) \
- E(middle, SDL_BUTTON_MIDDLE) \
- E(right, SDL_BUTTON_RIGHT) \
- E(x1, SDL_BUTTON_X1) \
- E(x2, SDL_BUTTON_X2)
-
-static NIF_ENUM_TO_ATOM_FUNCTION(button_to_atom, Uint8, BUTTON_ENUM)
+#define EVENT_ACTION_ENUM(E) \
+ E(add, SDL_ADDEVENT) \
+ E(peek, SDL_PEEKEVENT) \
+ E(get, SDL_GETEVENT)
-// poll_event
+static NIF_ATOM_TO_ENUM_FUNCTION(atom_to_event_action, SDL_eventaction, EVENT_ACTION_ENUM)
-NIF_CALL_HANDLER(thread_poll_event)
+// Event conversion functions.
+
+static ERL_NIF_TERM window_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_NIF_TERM map)
{
- SDL_Event event;
- ERL_NIF_TERM map;
+ enif_make_map_put(env, map, atom_window_id,
+ enif_make_uint(env, event->window.windowID), &map);
+ enif_make_map_put(env, map, atom_event,
+ window_event_to_atom(event->window.event), &map);
+ enif_make_map_put(env, map, atom_data1,
+ enif_make_int(env, event->window.data1), &map);
+ enif_make_map_put(env, map, atom_data2,
+ enif_make_int(env, event->window.data2), &map);
- if (SDL_PollEvent(&event) == 0)
- return atom_false;
+ return map;
+}
+
+static ERL_NIF_TERM keyboard_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_NIF_TERM map)
+{
+ enif_make_map_put(env, map, atom_window_id,
+ enif_make_uint(env, event->key.windowID), &map);
+ enif_make_map_put(env, map, atom_state,
+ event->key.state == SDL_RELEASED ? atom_released : atom_pressed, &map);
+ enif_make_map_put(env, map, atom_repeat,
+ event->key.repeat == 0 ? atom_false : atom_true, &map);
+ enif_make_map_put(env, map, atom_scancode,
+ enif_make_uint(env, event->key.keysym.scancode), &map);
+ enif_make_map_put(env, map, atom_sym,
+ enif_make_uint(env, event->key.keysym.sym), &map);
+ enif_make_map_put(env, map, atom_mod,
+ keymod_flags_to_list(env, event->key.keysym.mod), &map);
+
+ return map;
+}
+
+static ERL_NIF_TERM mouse_motion_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_NIF_TERM map)
+{
+ enif_make_map_put(env, map, atom_window_id,
+ enif_make_uint(env, event->motion.windowID), &map);
+ enif_make_map_put(env, map, atom_which,
+ (event->motion.which == SDL_TOUCH_MOUSEID)
+ ? atom_touch
+ : enif_make_uint(env, event->motion.which),
+ &map);
+ enif_make_map_put(env, map, atom_state,
+ mouse_state_to_list(env, event->motion.state), &map);
+ enif_make_map_put(env, map, atom_x,
+ enif_make_int(env, event->motion.x), &map);
+ enif_make_map_put(env, map, atom_y,
+ enif_make_int(env, event->motion.y), &map);
+ enif_make_map_put(env, map, atom_xrel,
+ enif_make_int(env, event->motion.xrel), &map);
+ enif_make_map_put(env, map, atom_yrel,
+ enif_make_int(env, event->motion.yrel), &map);
+
+ return map;
+}
+
+static ERL_NIF_TERM mouse_button_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_NIF_TERM map)
+{
+ enif_make_map_put(env, map, atom_window_id,
+ enif_make_uint(env, event->button.windowID), &map);
+ enif_make_map_put(env, map, atom_which,
+ (event->button.which == SDL_TOUCH_MOUSEID)
+ ? atom_touch
+ : enif_make_uint(env, event->button.which),
+ &map);
+ enif_make_map_put(env, map, atom_button,
+ button_to_atom(event->button.button), &map);
+ enif_make_map_put(env, map, atom_state,
+ event->button.state == SDL_RELEASED ? atom_released : atom_pressed, &map);
+ enif_make_map_put(env, map, atom_clicks,
+ enif_make_uint(env, event->button.clicks), &map);
+ enif_make_map_put(env, map, atom_x,
+ enif_make_int(env, event->button.x), &map);
+ enif_make_map_put(env, map, atom_y,
+ enif_make_int(env, event->button.y), &map);
+
+ return map;
+}
+
+static ERL_NIF_TERM mouse_wheel_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_NIF_TERM map)
+{
+ enif_make_map_put(env, map, atom_window_id,
+ enif_make_uint(env, event->wheel.windowID), &map);
+ enif_make_map_put(env, map, atom_which,
+ (event->wheel.which == SDL_TOUCH_MOUSEID)
+ ? atom_touch
+ : enif_make_uint(env, event->wheel.which),
+ &map);
+ enif_make_map_put(env, map, atom_x,
+ enif_make_int(env, event->wheel.x), &map);
+ enif_make_map_put(env, map, atom_y,
+ enif_make_int(env, event->wheel.y), &map);
+ enif_make_map_put(env, map, atom_direction,
+ mousewheel_direction_to_atom(event->wheel.direction), &map);
+
+ return map;
+}
+
+static ERL_NIF_TERM event_to_map(ErlNifEnv* env, SDL_Event* event)
+{
+ ERL_NIF_TERM map;
map = enif_make_new_map(env);
// All events have a type and a timestamp.
+
enif_make_map_put(env, map, atom_type,
- event_type_to_atom(event.type), &map);
+ event_type_to_atom(event->type), &map);
enif_make_map_put(env, map, atom_timestamp,
- enif_make_uint(env, event.common.timestamp), &map);
-
- // Some events have additional information.
- if (event.type == SDL_WINDOWEVENT) {
- enif_make_map_put(env, map, atom_window_id,
- enif_make_uint(env, event.window.windowID), &map);
- enif_make_map_put(env, map, atom_event,
- window_event_to_atom(event.window.event), &map);
- enif_make_map_put(env, map, atom_data,
- enif_make_tuple2(env,
- enif_make_int(env, event.window.data1),
- enif_make_int(env, event.window.data2)),
- &map);
- } else if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
- enif_make_map_put(env, map, atom_window_id,
- enif_make_uint(env, event.key.windowID), &map);
- // We don't pass the state as this information is redundant with the type.
- enif_make_map_put(env, map, atom_repeat,
- event.key.repeat == 0 ? atom_false : atom_true, &map);
- enif_make_map_put(env, map, atom_scancode,
- enif_make_uint(env, event.key.keysym.scancode), &map);
- enif_make_map_put(env, map, atom_sym,
- enif_make_uint(env, event.key.keysym.sym), &map);
- enif_make_map_put(env, map, atom_mod,
- keymod_flags_to_list(env, event.key.keysym.mod), &map);
- } else if (event.type == SDL_MOUSEMOTION) {
- enif_make_map_put(env, map, atom_window_id,
- enif_make_uint(env, event.motion.windowID), &map);
- enif_make_map_put(env, map, atom_which,
- (event.motion.which == SDL_TOUCH_MOUSEID)
- ? atom_touch
- : enif_make_uint(env, event.motion.which),
- &map);
- // @todo We may want the state value here as it's a bitmask.
- // Question is how do we represent it to the Erlang code?
- enif_make_map_put(env, map, atom_x,
- enif_make_int(env, event.motion.x), &map);
- enif_make_map_put(env, map, atom_y,
- enif_make_int(env, event.motion.y), &map);
- enif_make_map_put(env, map, atom_xrel,
- enif_make_int(env, event.motion.xrel), &map);
- enif_make_map_put(env, map, atom_yrel,
- enif_make_int(env, event.motion.yrel), &map);
- } else if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
- enif_make_map_put(env, map, atom_window_id,
- enif_make_uint(env, event.button.windowID), &map);
- enif_make_map_put(env, map, atom_which,
- (event.button.which == SDL_TOUCH_MOUSEID)
- ? atom_touch
- : enif_make_uint(env, event.button.which),
- &map);
- enif_make_map_put(env, map, atom_button,
- (event.button.button <= SDL_BUTTON_X2)
- ? button_to_atom(event.button.button)
- : enif_make_uint(env, event.button.button),
- &map);
- // We don't pass the state as this information is redundant with the type.
- enif_make_map_put(env, map, atom_clicks,
- enif_make_uint(env, event.button.clicks), &map);
- enif_make_map_put(env, map, atom_x,
- enif_make_int(env, event.button.x), &map);
- enif_make_map_put(env, map, atom_y,
- enif_make_int(env, event.button.y), &map);
- } else if (event.type == SDL_MOUSEWHEEL) {
- enif_make_map_put(env, map, atom_window_id,
- enif_make_uint(env, event.wheel.windowID), &map);
- enif_make_map_put(env, map, atom_which,
- (event.wheel.which == SDL_TOUCH_MOUSEID)
- ? atom_touch
- : enif_make_uint(env, event.wheel.which),
- &map);
- enif_make_map_put(env, map, atom_x,
- enif_make_int(env, event.wheel.x), &map);
- enif_make_map_put(env, map, atom_y,
- enif_make_int(env, event.wheel.y), &map);
- enif_make_map_put(env, map, atom_direction,
- mousewheel_direction_to_atom(event.wheel.direction), &map);
- }
+ enif_make_uint(env, event->common.timestamp), &map);
+
+ // The following event types have no additional fields:
+ //
+ // - SDL_QUIT
+ // - SDL_APP_TERMINATING
+ // - SDL_APP_LOWMEMORY
+ // - SDL_APP_WILLENTERBACKGROUND
+ // - SDL_APP_DIDENTERBACKGROUND
+ // - SDL_APP_WILLENTERFOREGROUND
+ // - SDL_APP_DIDENTERFOREGROUND
+ // - SDL_KEYMAPCHANGED
+ // - SDL_CLIPBOARDUPDATE
+ // - SDL_RENDER_TARGETS_RESET
+ // - SDL_RENDER_DEVICE_RESET
+
+ switch (event->type) {
+ case SDL_WINDOWEVENT:
+ return window_event_to_map(env, event, map);
+
+ // @todo SDL_SYSWMEVENT
+
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ return keyboard_event_to_map(env, event, map);
+
+ // @todo SDL_TEXTEDITING
+ // @todo SDL_TEXTINPUT
+
+ case SDL_MOUSEMOTION:
+ return mouse_motion_event_to_map(env, event, map);
+
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ return mouse_button_event_to_map(env, event, map);
+
+ case SDL_MOUSEWHEEL:
+ return mouse_wheel_event_to_map(env, event, map);
+
+ // @todo SDL_JOYAXISMOTION
+ // @todo SDL_JOYBALLMOTION
+ // @todo SDL_JOYHATMOTION
+ // @todo SDL_JOYBUTTONDOWN
+ // @todo SDL_JOYBUTTONUP
+ // @todo SDL_JOYDEVICEADDED
+ // @todo SDL_JOYDEVICEREMOVED
+
+ // @todo SDL_CONTROLLERAXISMOTION
+ // @todo SDL_CONTROLLERBUTTONDOWN
+ // @todo SDL_CONTROLLERBUTTONUP
+ // @todo SDL_CONTROLLERDEVICEADDED
+ // @todo SDL_CONTROLLERDEVICEREMOVED
+ // @todo SDL_CONTROLLERDEVICEREMAPPED
+
+ // @todo SDL_FINGERDOWN
+ // @todo SDL_FINGERUP
+ // @todo SDL_FINGERMOTION
+
+ // @todo SDL_DOLLARGESTURE
+ // @todo SDL_DOLLARRECORD
+ // @todo SDL_MULTIGESTURE
- // @todo SDL_TextEditingEvent
- // @todo SDL_TextInputEvent
- // @todo SDL_JoyAxisEvent
- // @todo SDL_JoyBallEvent
- // @todo SDL_JoyHatEvent
- // @todo SDL_JoyButtonEvent
- // @todo SDL_JoyDeviceEvent
- // @todo SDL_ControllerAxisEvent
- // @todo SDL_ControllerButtonEvent
- // @todo SDL_ControllerDeviceEvent
- // @todo SDL_UserEvent
- // @todo SDL_SysWMEvent
- // @todo SDL_TouchFingerEvent
- // @todo SDL_MultiGestureEvent
- // @todo SDL_DollarGestureEvent
- // @todo SDL_DropEvent
+ // @todo SDL_DROPFILE
+ // @todo SDL_DROPTEXT
+ // @todo SDL_DROPBEGIN
+ // @todo SDL_DROPCOMPLETE
+
+ // @todo SDL_AUDIODEVICEADDED
+ // @todo SDL_AUDIODEVICEREMOVED
+ }
return map;
}
+// flush_event
+
+NIF_CAST_HANDLER(thread_flush_event)
+{
+ SDL_FlushEvent((long)args[0]);
+}
+
+NIF_FUNCTION(flush_event)
+{
+ Uint32 type;
+
+ BADARG_IF(!atom_to_event_type(env, argv[0], &type));
+
+ return nif_thread_cast(env, thread_flush_event, 1, type);
+}
+
+// flush_events
+
+NIF_CAST_HANDLER(thread_flush_events)
+{
+ SDL_FlushEvents((long)args[0], (long)args[1]);
+}
+
+NIF_FUNCTION(flush_events)
+{
+ Uint32 minType, maxType;
+
+ BADARG_IF(!atom_to_event_type(env, argv[0], &minType));
+ BADARG_IF(!atom_to_event_type(env, argv[1], &maxType));
+
+ return nif_thread_cast(env, thread_flush_events, 2, minType, maxType);
+}
+
+// has_event
+
+NIF_CALL_HANDLER(thread_has_event)
+{
+ if (SDL_HasEvent((long)args[0]))
+ return atom_true;
+
+ return atom_false;
+}
+
+NIF_FUNCTION(has_event)
+{
+ Uint32 type;
+
+ BADARG_IF(!atom_to_event_type(env, argv[0], &type));
+
+ return nif_thread_call(env, thread_has_event, 1, type);
+}
+
+// has_events
+
+NIF_CALL_HANDLER(thread_has_events)
+{
+ if (SDL_HasEvents((long)args[0], (long)args[1]))
+ return atom_true;
+
+ return atom_false;
+}
+
+NIF_FUNCTION(has_events)
+{
+ Uint32 minType, maxType;
+
+ BADARG_IF(!atom_to_event_type(env, argv[0], &minType));
+ BADARG_IF(!atom_to_event_type(env, argv[1], &maxType));
+
+ return nif_thread_call(env, thread_has_events, 2, minType, maxType);
+}
+
+// peep_events
+//
+// @todo It is not currently possible to add events at the back of the queue.
+
+NIF_CALL_HANDLER(thread_peep_events)
+{
+ SDL_Event* events;
+ int i, numEvents;
+ ERL_NIF_TERM list;
+
+ events = malloc(sizeof(SDL_Event) * (long)args[1]);
+
+ numEvents = SDL_PeepEvents(events, (long)args[1],
+ (long)args[0], (long)args[2], (long)args[3]);
+
+ if (numEvents < 0)
+ return sdl_error_tuple(env);
+
+ list = enif_make_list(env, 0);
+
+ for (i = 0; i < numEvents; i++)
+ list = enif_make_list_cell(env, event_to_map(env, &events[i]), list);
+
+ free(events);
+
+ return enif_make_tuple2(env, atom_ok, list);
+}
+
+NIF_FUNCTION(peep_events)
+{
+ SDL_eventaction action;
+ int numEvents;
+ Uint32 minType, maxType;
+
+ BADARG_IF(enif_is_identical(atom_add, argv[0]));
+
+ BADARG_IF(!atom_to_event_action(env, argv[0], &action));
+ BADARG_IF(!enif_get_int(env, argv[1], &numEvents));
+ BADARG_IF(!atom_to_event_type(env, argv[2], &minType));
+ BADARG_IF(!atom_to_event_type(env, argv[3], &maxType));
+
+ return nif_thread_call(env, thread_peep_events, 4,
+ action, numEvents, minType, maxType);
+}
+
+// poll_event
+
+NIF_CALL_HANDLER(thread_poll_event)
+{
+ SDL_Event event;
+
+ if (SDL_PollEvent(&event) == 0)
+ return atom_false;
+
+ return event_to_map(env, &event);
+}
+
NIF_FUNCTION(poll_event)
{
return nif_thread_call(env, thread_poll_event, 0);
}
+
+// pump_events
+
+NIF_CAST_HANDLER(thread_pump_events)
+{
+ SDL_PumpEvents();
+}
+
+NIF_FUNCTION(pump_events)
+{
+ return nif_thread_cast(env, thread_pump_events, 0);
+}
diff --git a/c_src/sdl_keycode.c b/c_src/sdl_keycode.c
new file mode 100644
index 0000000..539accd
--- /dev/null
+++ b/c_src/sdl_keycode.c
@@ -0,0 +1,30 @@
+// Copyright (c) 2014-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 KEYMOD_FLAGS(F) \
+ F(left_shift, KMOD_LSHIFT) \
+ F(right_shift, KMOD_RSHIFT) \
+ F(left_ctrl, KMOD_LCTRL) \
+ F(right_ctrl, KMOD_RCTRL) \
+ F(left_alt, KMOD_LALT) \
+ F(right_alt, KMOD_RALT) \
+ F(left_gui, KMOD_LGUI) \
+ F(right_gui, KMOD_RGUI) \
+ F(num, KMOD_NUM) \
+ F(caps, KMOD_CAPS) \
+ F(mode, KMOD_MODE)
+
+NIF_FLAGS_TO_LIST_FUNCTION(keymod_flags_to_list, Uint16, KEYMOD_FLAGS)
diff --git a/c_src/sdl_mouse.c b/c_src/sdl_mouse.c
index eb2af39..018b44c 100644
--- a/c_src/sdl_mouse.c
+++ b/c_src/sdl_mouse.c
@@ -20,7 +20,16 @@
NIF_ENUM_TO_ATOM_FUNCTION(mousewheel_direction_to_atom, Uint32, MOUSEWHEEL_DIRECTION_ENUM)
-static ERL_NIF_TERM get_mouse_state_common(ErlNifEnv* env, int x, int y, Uint32 state)
+#define BUTTON_ENUM(E) \
+ E(left, SDL_BUTTON_LEFT) \
+ E(middle, SDL_BUTTON_MIDDLE) \
+ E(right, SDL_BUTTON_RIGHT) \
+ E(x1, SDL_BUTTON_X1) \
+ E(x2, SDL_BUTTON_X2)
+
+NIF_ENUM_TO_ATOM_FUNCTION(button_to_atom, Uint8, BUTTON_ENUM)
+
+ERL_NIF_TERM mouse_state_to_list(ErlNifEnv* env, Uint32 state)
{
ERL_NIF_TERM list;
@@ -37,10 +46,15 @@ static ERL_NIF_TERM get_mouse_state_common(ErlNifEnv* env, int x, int y, Uint32
if (state & SDL_BUTTON_X2MASK)
list = enif_make_list_cell(env, atom_x2, list);
+ return list;
+}
+
+static ERL_NIF_TERM get_mouse_state_common(ErlNifEnv* env, int x, int y, Uint32 state)
+{
return enif_make_tuple3(env,
enif_make_int(env, x),
enif_make_int(env, y),
- list
+ mouse_state_to_list(env, state)
);
}
diff --git a/c_src/sdl_window.c b/c_src/sdl_window.c
index 4ac3604..36ddcc2 100644
--- a/c_src/sdl_window.c
+++ b/c_src/sdl_window.c
@@ -49,6 +49,26 @@ static NIF_FLAGS_TO_LIST_FUNCTION(window_flags_to_list, Uint32, WINDOW_FLAGS)
static NIF_ATOM_TO_ENUM_FUNCTION(atom_to_window_pos, int, WINDOW_POS_ENUM)
+#define WINDOW_EVENT_ENUM(E) \
+ E(shown, SDL_WINDOWEVENT_SHOWN) \
+ E(hidden, SDL_WINDOWEVENT_HIDDEN) \
+ E(exposed, SDL_WINDOWEVENT_EXPOSED) \
+ E(moved, SDL_WINDOWEVENT_MOVED) \
+ E(resized, SDL_WINDOWEVENT_RESIZED) \
+ E(size_changed, SDL_WINDOWEVENT_SIZE_CHANGED) \
+ E(minimized, SDL_WINDOWEVENT_MINIMIZED) \
+ E(maximized, SDL_WINDOWEVENT_MAXIMIZED) \
+ E(restored, SDL_WINDOWEVENT_RESTORED) \
+ E(enter, SDL_WINDOWEVENT_ENTER) \
+ E(leave, SDL_WINDOWEVENT_LEAVE) \
+ E(focus_gained, SDL_WINDOWEVENT_FOCUS_GAINED) \
+ E(focus_lost, SDL_WINDOWEVENT_FOCUS_LOST) \
+ E(close, SDL_WINDOWEVENT_CLOSE) \
+ E(take_focus, SDL_WINDOWEVENT_TAKE_FOCUS) \
+ E(hit_test, SDL_WINDOWEVENT_HIT_TEST)
+
+NIF_ENUM_TO_ATOM_FUNCTION(window_event_to_atom, Uint8, WINDOW_EVENT_ENUM)
+
#define WINDOW_FULLSCREEN_ENUM(E) \
E(fullscreen, SDL_WINDOW_FULLSCREEN) \
E(fullscreen_desktop, SDL_WINDOW_FULLSCREEN_DESKTOP) \