#include "eruta.h" #include "event.h" #include "mode.h" #include "state.h" #include "react.h" #include "zori.h" /** Initializes the react structure so it does nothing at all in all cases. */ React * react_initempty(React * self, void * data) { if(!self) return NULL; self->data = data; self->joystick_axis = NULL; self->joystick_button_up = NULL; self->joystick_button_down = NULL; self->joystick_configuration= NULL; self->keyboard_key_down = NULL; self->keyboard_key_up = NULL; self->keyboard_key_char = NULL; self->mouse_axes = NULL; self->mouse_button_up = NULL; self->mouse_button_down = NULL; self->mouse_enter_display = NULL; self->mouse_leave_display = NULL; self->mouse_warped = NULL; self->timer = NULL; self->display_expose = NULL; self->display_resize = NULL; self->display_close = NULL; self->display_lost = NULL; self->display_found = NULL; self->display_switch_in = NULL; self->display_switch_out = NULL; self->display_orientation = NULL; return self; } #define DO_REACT(SELF, EVENT, MEMBER, HANDLER) \ do { \ if(!SELF->HANDLER) return NULL; \ return self->HANDLER(SELF, &((EVENT)->MEMBER)); \ } while(0) /** React to an allegro event. */ React * react_react(React * self, ALLEGRO_EVENT * event) { switch(event->type) { case ALLEGRO_EVENT_JOYSTICK_AXIS: DO_REACT(self, event, joystick, joystick_axis); case ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN: DO_REACT(self, event, joystick, joystick_button_down); case ALLEGRO_EVENT_JOYSTICK_BUTTON_UP: DO_REACT(self, event, joystick, joystick_button_up); case ALLEGRO_EVENT_JOYSTICK_CONFIGURATION: DO_REACT(self, event, joystick, joystick_configuration); case ALLEGRO_EVENT_KEY_DOWN: DO_REACT(self, event, keyboard, keyboard_key_down); case ALLEGRO_EVENT_KEY_CHAR: DO_REACT(self, event, keyboard, keyboard_key_char); case ALLEGRO_EVENT_KEY_UP: DO_REACT(self, event, keyboard, keyboard_key_up); case ALLEGRO_EVENT_MOUSE_AXES: DO_REACT(self, event, mouse, mouse_axes); case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: DO_REACT(self, event, mouse, mouse_button_down); case ALLEGRO_EVENT_MOUSE_BUTTON_UP: DO_REACT(self, event, mouse, mouse_button_up); case ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY: DO_REACT(self, event, mouse, mouse_enter_display); case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: DO_REACT(self, event, mouse, mouse_leave_display); case ALLEGRO_EVENT_MOUSE_WARPED: DO_REACT(self, event, mouse, mouse_warped); case ALLEGRO_EVENT_TIMER: DO_REACT(self, event, timer, timer); case ALLEGRO_EVENT_DISPLAY_EXPOSE: DO_REACT(self, event, display, display_expose); case ALLEGRO_EVENT_DISPLAY_RESIZE: DO_REACT(self, event, display, display_resize); case ALLEGRO_EVENT_DISPLAY_CLOSE: DO_REACT(self, event, display, display_close); case ALLEGRO_EVENT_DISPLAY_LOST: DO_REACT(self, event, display, display_lost); case ALLEGRO_EVENT_DISPLAY_FOUND: DO_REACT(self, event, display, display_found); case ALLEGRO_EVENT_DISPLAY_SWITCH_IN: DO_REACT(self, event, display, display_switch_in); case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: DO_REACT(self, event, display, display_switch_out); case ALLEGRO_EVENT_DISPLAY_ORIENTATION: DO_REACT(self, event, display, display_orientation); default: return NULL; } } /** Polls for allegro events and reacts to them. */ React * react_poll(React * self, void * state) { int res; ALLEGRO_EVENT * event; struct zori_console * console = state_console(state); if(!self) return NULL; // yes an assignment is fine here :) while( (event = state_pollnew((State *)state)) ) { /* Let react react first, then if that fails, send to the gui, * but only if it is active. If not active, * send the event to ruby */ if(!react_react(self, event)) { if (zori_handle_system_event(event) != ZORI_EVENT_DONE) { rh_poll_event(state_ruby(state_get()), event); } } event_free(event); // here we must free the event... } return self; }