2014-06-01 17:55:23 +00:00
/*
* This file is part of the DXX - Rebirth project < http : //www.dxx-rebirth.com/>.
* It is copyright by its individual contributors , as recorded in the
* project ' s Git history . See COPYING . txt at the top level for license
* terms and a link to the Git history .
*/
2006-07-27 09:46:44 +00:00
/*
*
* SDL Event related stuff
*
*
*/
2006-03-20 16:43:15 +00:00
# include <stdio.h>
# include <stdlib.h>
2009-05-21 12:16:39 +00:00
# include "event.h"
2008-11-17 23:38:43 +00:00
# include "key.h"
2012-03-18 10:04:16 +00:00
# include "mouse.h"
2009-05-21 12:16:39 +00:00
# include "window.h"
2010-07-16 11:07:42 +00:00
# include "timer.h"
2010-12-28 18:11:06 +00:00
# include "config.h"
2006-03-20 16:43:15 +00:00
2013-01-03 15:37:49 +00:00
# include "joy.h"
2012-06-10 22:26:20 +00:00
# include "args.h"
2006-03-20 16:43:15 +00:00
void event_poll ( )
{
2006-07-27 09:46:44 +00:00
SDL_Event event ;
2008-11-17 23:38:43 +00:00
int clean_uniframe = 1 ;
2010-07-25 00:49:33 +00:00
window * wind = window_get_front ( ) ;
2011-01-13 04:36:19 +00:00
int idle = 1 ;
2010-07-25 00:49:33 +00:00
// If the front window changes, exit this loop, otherwise unintended behavior can occur
// like pressing 'Return' really fast at 'Difficulty Level' causing multiple games to be started
2014-07-04 03:48:47 +00:00
while ( ( wind = = window_get_front ( ) ) & & ( event = { } , SDL_PollEvent ( & event ) ) )
2010-07-25 00:49:33 +00:00
{
2006-07-27 09:46:44 +00:00
switch ( event . type ) {
2006-11-22 05:35:10 +00:00
case SDL_KEYDOWN :
case SDL_KEYUP :
2008-11-17 23:38:43 +00:00
if ( clean_uniframe )
2014-07-14 03:18:40 +00:00
unicode_frame_buffer = { } ;
2008-11-17 23:38:43 +00:00
clean_uniframe = 0 ;
2015-02-08 17:43:29 +00:00
key_handler ( & event . key ) ;
2011-01-17 04:16:05 +00:00
idle = 0 ;
2006-11-22 05:35:10 +00:00
break ;
case SDL_MOUSEBUTTONDOWN :
case SDL_MOUSEBUTTONUP :
2015-02-08 17:43:29 +00:00
mouse_button_handler ( & event . button ) ;
2011-01-17 04:16:05 +00:00
idle = 0 ;
2006-11-22 05:35:10 +00:00
break ;
case SDL_MOUSEMOTION :
2015-02-08 17:43:29 +00:00
mouse_motion_handler ( & event . motion ) ;
2011-01-17 04:16:05 +00:00
idle = 0 ;
2006-11-22 05:35:10 +00:00
break ;
case SDL_JOYBUTTONDOWN :
case SDL_JOYBUTTONUP :
2015-02-08 17:43:29 +00:00
joy_button_handler ( & event . jbutton ) ;
2011-02-02 00:36:43 +00:00
idle = 0 ;
2006-11-22 05:35:10 +00:00
break ;
case SDL_JOYAXISMOTION :
2015-02-08 17:43:29 +00:00
if ( joy_axis_handler ( & event . jaxis ) )
2011-02-02 00:36:43 +00:00
idle = 0 ;
2006-11-22 05:35:10 +00:00
break ;
case SDL_JOYHATMOTION :
2015-02-08 17:43:29 +00:00
joy_hat_handler ( & event . jhat ) ;
2011-02-02 00:36:43 +00:00
idle = 0 ;
2006-11-22 05:35:10 +00:00
break ;
case SDL_JOYBALLMOTION :
break ;
case SDL_QUIT : {
2011-07-13 21:26:42 +00:00
d_event qevent = { EVENT_QUIT } ;
2014-10-04 21:47:13 +00:00
call_default_handler ( qevent ) ;
2011-01-17 04:16:05 +00:00
idle = 0 ;
2006-11-22 05:35:10 +00:00
} break ;
}
}
2010-07-16 11:07:42 +00:00
2011-01-13 04:36:19 +00:00
// Send the idle event if there were no other events
if ( idle )
{
2011-07-13 21:26:42 +00:00
d_event ievent ;
2011-01-13 04:36:19 +00:00
2011-07-13 21:26:42 +00:00
ievent . type = EVENT_IDLE ;
2014-10-04 21:47:13 +00:00
event_send ( ievent ) ;
2011-01-13 04:36:19 +00:00
}
2012-03-18 10:04:16 +00:00
else
event_reset_idle_seconds ( ) ;
2011-01-13 04:36:19 +00:00
2010-12-28 18:11:06 +00:00
mouse_cursor_autohide ( ) ;
2006-11-22 05:35:10 +00:00
}
2006-03-20 16:43:15 +00:00
2010-07-30 17:59:21 +00:00
void event_flush ( )
{
SDL_Event event ;
while ( SDL_PollEvent ( & event ) ) ;
}
2006-03-20 16:43:15 +00:00
int event_init ( )
{
2006-07-27 09:46:44 +00:00
// We should now be active and responding to events.
return 0 ;
2006-11-22 05:35:10 +00:00
}
2009-05-21 12:16:39 +00:00
2014-10-04 21:47:13 +00:00
int ( * default_handler ) ( const d_event & event ) = NULL ;
2010-04-02 05:01:08 +00:00
2014-10-04 21:47:13 +00:00
void set_default_handler ( int ( * handler ) ( const d_event & event ) )
2010-04-02 05:01:08 +00:00
{
default_handler = handler ;
}
2014-10-04 21:47:13 +00:00
int call_default_handler ( const d_event & event )
2010-04-02 05:01:08 +00:00
{
if ( default_handler )
return ( * default_handler ) ( event ) ;
return 0 ;
}
2014-10-04 21:47:13 +00:00
void event_send ( const d_event & event )
2011-01-13 04:36:19 +00:00
{
window * wind ;
2014-08-06 02:10:49 +00:00
window_event_result handled = window_event_result : : ignored ;
2011-01-13 04:36:19 +00:00
2015-01-17 18:31:41 +00:00
for ( wind = window_get_front ( ) ; wind & & handled = = window_event_result : : ignored ; wind = window_get_prev ( * wind ) )
2011-10-09 10:31:44 +00:00
if ( window_is_visible ( wind ) )
{
2015-01-17 18:31:40 +00:00
handled = window_send_event ( * wind , event ) ;
2011-10-09 10:31:44 +00:00
2011-11-27 20:35:58 +00:00
if ( ! window_exists ( wind ) ) // break away if necessary: window_send_event() could have closed wind by now
break ;
2015-01-17 18:31:40 +00:00
if ( window_is_modal ( * wind ) )
2011-10-09 10:31:44 +00:00
break ;
}
2014-08-06 02:10:49 +00:00
if ( handled = = window_event_result : : ignored )
2011-01-13 04:36:19 +00:00
call_default_handler ( event ) ;
}
2009-05-21 12:16:39 +00:00
// Process the first event in queue, sending to the appropriate handler
// This is the new object-oriented system
2010-01-30 03:24:19 +00:00
// Uses the old system for now, but this may change
2009-05-21 12:16:39 +00:00
void event_process ( void )
{
d_event event ;
2010-08-06 06:49:45 +00:00
window * wind = window_get_front ( ) ;
2009-05-21 12:16:39 +00:00
2011-02-02 00:36:43 +00:00
timer_update ( ) ;
2010-01-30 03:24:19 +00:00
event_poll ( ) ; // send input events first
2011-01-13 04:36:19 +00:00
// Doing this prevents problems when a draw event can create a newmenu,
2010-08-06 06:49:45 +00:00
// such as some network menus when they report a problem
if ( window_get_front ( ) ! = wind )
return ;
2010-01-20 05:10:32 +00:00
event . type = EVENT_WINDOW_DRAW ; // then draw all visible windows
2011-02-12 22:58:39 +00:00
wind = window_get_first ( ) ;
while ( wind ! = NULL )
{
2015-01-17 18:31:41 +00:00
window * prev = window_get_prev ( * wind ) ;
2009-05-21 12:16:39 +00:00
if ( window_is_visible ( wind ) )
2015-01-17 18:31:40 +00:00
window_send_event ( * wind , event ) ;
2011-02-12 22:58:39 +00:00
if ( ! window_exists ( wind ) )
2011-05-26 07:41:26 +00:00
{
if ( ! prev ) // well there isn't a previous window ...
break ; // ... just bail out - we've done everything for this frame we can.
2015-01-17 18:31:41 +00:00
wind = window_get_next ( * prev ) ; // the current window seemed to be closed. so take the next one from the previous which should be able to point to the one after the current closed
2011-05-26 07:41:26 +00:00
}
2011-02-12 22:58:39 +00:00
else
2015-01-17 18:31:41 +00:00
wind = window_get_next ( * wind ) ;
2011-02-12 22:58:39 +00:00
}
2009-12-26 01:08:57 +00:00
gr_flip ( ) ;
2009-05-21 12:16:39 +00:00
}
2010-12-28 18:11:06 +00:00
2015-05-09 17:39:03 +00:00
template < bool activate_focus >
static void event_change_focus ( )
2010-12-28 18:11:06 +00:00
{
2015-05-14 02:23:13 +00:00
SDL_WM_GrabInput ( activate_focus & & GameCfg . Grabinput & & likely ( ! GameArg . DbgForbidConsoleGrab ) ? SDL_GRAB_ON : SDL_GRAB_OFF ) ;
2015-05-14 02:23:13 +00:00
mouse_toggle_cursor ( activate_focus ) ;
2010-12-28 18:11:06 +00:00
}
2015-05-09 17:39:03 +00:00
void event_enable_focus ( )
{
event_change_focus < true > ( ) ;
}
void event_disable_focus ( )
{
event_change_focus < false > ( ) ;
}
2012-03-18 10:04:16 +00:00
static fix64 last_event = 0 ;
void event_reset_idle_seconds ( )
{
last_event = timer_query ( ) ;
}
fix event_get_idle_seconds ( )
{
return ( timer_query ( ) - last_event ) / F1_0 ;
}