OSDLEvents.cc

Go to the documentation of this file.
00001 #include "OSDLEvents.h"
00002 
00003 #include "OSDLBasic.h"             // for OSDL::GetVersion
00004 #include "OSDLVideo.h"             // for resize
00005 #include "OSDLScheduler.h"         // for GetScheduler
00006 #include "OSDLRenderer.h"          // for Renderer
00007 #include "OSDLJoystickHandler.h"   // for JoystickHandler
00008 #include "OSDLKeyboardHandler.h"   // for KeyboardHandler
00009 #include "OSDLMouseHandler.h"      // for MouseHandler
00010 #include "OSDLMouseCommon.h"       // for DefaultMouse
00011 
00012 
00013 #include "Ceylan.h"                // for Flags, etc.
00014 
00015 #include <list>
00016 
00017 
00018 #ifdef OSDL_USES_CONFIG_H
00019 #include <OSDLConfig.h>            // for OSDL_DEBUG and al (private header)
00020 #endif // OSDL_USES_CONFIG_H
00021 
00022 
00023 using std::string ;
00024 
00025 using namespace Ceylan ;
00026 using namespace Ceylan::Log ;
00027 
00028 // for time units and calls (ex : Millisecond, basicSleep) :
00029 using namespace Ceylan::System ;   
00030 
00031 
00032 using namespace OSDL::Events ;
00033 using namespace OSDL::Engine ;
00034 
00035 //const Ceylan::Uint32 EventModule::FrameTimingSlots = 200 ;
00036 
00037 
00038 #if OSDL_DEBUG_EVENTS
00039 
00040 #include <iostream>
00041 #define OSDL_EVENT_LOG( message ) std::cout << "[OSDL events] " << message << std::endl ;
00042 
00043 #else // OSDL_DEBUG_EVENTS
00044 
00045 #define OSDL_EVENT_LOG( message )
00046 
00047 #endif // OSDL_DEBUG_EVENTS
00048 
00049 
00050 
00051 
00052 bool EventsModule::_EventsInitialized = false ;
00053 
00054 // @todo: wrap all SDL constants (ex : scan codes).
00055 
00056 
00057 // Basic event types :
00058     
00059 const BasicEventType EventsModule::ApplicationFocusChanged      =
00060     SDL_ACTIVEEVENT     ;
00061     
00062 const BasicEventType EventsModule::KeyPressed                   = 
00063     SDL_KEYDOWN         ;
00064     
00065 const BasicEventType EventsModule::KeyReleased                  = 
00066     SDL_KEYUP           ;
00067     
00068 const BasicEventType EventsModule::MouseMoved                   =
00069     SDL_MOUSEMOTION     ;
00070 
00071 const BasicEventType EventsModule::MouseButtonPressed           =
00072     SDL_MOUSEBUTTONDOWN ;
00073 
00074 const BasicEventType EventsModule::MouseButtonReleased          =
00075     SDL_MOUSEBUTTONUP   ;
00076 
00077 const BasicEventType EventsModule::JoystickAxisChanged          =
00078     SDL_JOYAXISMOTION   ;
00079 
00080 const BasicEventType EventsModule::JoystickTrackballChanged     =
00081     SDL_JOYBALLMOTION   ;
00082 
00083 const BasicEventType EventsModule::JoystickHatPositionChanged   =
00084     SDL_JOYHATMOTION    ;
00085 
00086 const BasicEventType EventsModule::JoystickButtonPressed        =
00087     SDL_JOYBUTTONDOWN   ;
00088 
00089 const BasicEventType EventsModule::JoystickButtonReleased       =
00090     SDL_JOYBUTTONUP     ;
00091 
00092 const BasicEventType EventsModule::UserRequestedQuit            = 
00093     SDL_QUIT            ;
00094 
00095 const BasicEventType EventsModule::SystemSpecificTriggered      = 
00096     SDL_SYSWMEVENT      ;
00097 
00098 const BasicEventType EventsModule::UserResizedVideoMode         =
00099     SDL_VIDEORESIZE     ;
00100 
00101 const BasicEventType EventsModule::ScreenNeedsRedraw            =
00102     SDL_VIDEOEXPOSE     ;
00103 
00104 
00105 /*
00106  * User events can range from FirstUserEventTriggered to 
00107  * LastUserEventTriggered :
00108  *
00109  */
00110 
00111 const BasicEventType EventsModule::FirstUserEventTriggered      = 
00112     SDL_USEREVENT       ;
00113 
00114 // No SDL_MAXEVENTS available, using SDL_NUMEVENTS instead. 
00115 const BasicEventType EventsModule::LastUserEventTriggered       = 
00116     SDL_NUMEVENTS - 1   ;
00117 
00118 
00119 
00120 // User event types :
00121 
00122 const UserEventType EventsModule::NoEvent                       = 0 ;
00123 const UserEventType EventsModule::QuitRequested                 = 1 ;
00124  
00125  
00126 // Focus flags :
00127  
00128 const Ceylan::Sint16 EventsModule::_MouseFocus       = SDL_APPMOUSEFOCUS ;
00129 const Ceylan::Sint16 EventsModule::_KeyboardFocus    = SDL_APPINPUTFOCUS ;
00130 const Ceylan::Sint16 EventsModule::_ApplicationFocus = SDL_APPACTIVE ;
00131 
00132 
00133 const string EventsModule::_MessageHeader = "[OSDL event] " ;
00134  
00135  
00136  
00138 string EventsModule::_SDLEnvironmentVariables[] = 
00139 {
00140         "SDL_MOUSE_RELATIVE",
00141         "SDL_MOUSEDEV",
00142         "SDL_MOUSEDEV_IMPS2",
00143         "SDL_MOUSEDRV",
00144         "SDL_NO_RAWKBD",
00145         "SDL_NOMOUSE",
00146         "SDL_JOYSTICK_DEVICE",
00147         "SDL_LINUX_JOYSTICK"
00148 } ;
00149 
00150 
00152 const Ceylan::Uint32 EventsModule::_MouseButtonCount = 5 ;
00153 
00154 
00155 
00156 EventsModule::EventsModule( Flags eventsFlag ) throw( EventsException ) : 
00157     Ceylan::Module( 
00158         "OSDL events module",
00159         "This is the module of OSDL dedicated to events management",
00160         "http://osdl.sourceforge.net",
00161         "Olivier Boudeville",
00162         "olivier.boudeville@online.fr",
00163         OSDL::GetVersion(),
00164         "LGPL" ),
00165     _useScheduler( false ), 
00166     _keyboardHandler( 0 ),
00167     _joystickHandler( 0 ),
00168     _mouseHandler( 0 ),
00169     _quitRequested( false ),
00170     _loopTargetedFrequency( DefaultEventLoopTargetedFrequency ),
00171     _idleCallsCount( 0 ),
00172     _loopIdleCallback( 0 ),
00173     _loopIdleCallbackData( 0 )
00174 {
00175 
00176     send( "Initializing events subsystem." ) ;
00177     
00178     
00179     // Activating selected input devices :
00180     
00181     if ( eventsFlag & CommonModule::UseJoystick )
00182     {
00183         _joystickHandler = new JoystickHandler( 
00184             /* useClassicalJoysticks */ true ) ;
00185     }   
00186 
00187     
00188     /*
00189      * No 'if ( eventsFlag & CommonModule::UseKeyboard )...' test, as even if 
00190      * the UseMouse flag is not set, we may receive mouse-related events
00191      * (motion, focus, etc.), hence we need a handler for that :
00192      *
00193      */
00194     
00195     // Keyboard comes in default state :
00196     _keyboardHandler = new KeyboardHandler( /* initialMode */ Events::rawInput,
00197         /* useSmarterDefaultKeyHandler */ false ) ;
00198         
00199     
00200     /*
00201      * No 'if ( eventsFlag & CommonModule::UseMouse )...' test, as even if 
00202      * the UseMouse flag is not set, we may receive mouse-related events
00203      * (motion, focus, etc.), hence we need a handler for that :
00204      *
00205      */
00206     _mouseHandler = new MouseHandler( /* useClassicalMice */ true ) ;
00207         
00208     
00209     /* 
00210      * Activating UseEventThread (SDL_INIT_EVENTTHREAD) :
00211      * Preferring avoiding it on Windows and OSX, not clear under GNU/Linux,
00212      * hence preferring no for all platforms, if not explicitly specified.
00213      *
00214      */
00215                 
00216     send( "Events subsystem initialized." ) ;
00217     
00218     dropIdentifier() ;
00219     
00220 }   
00221 
00222 
00223 EventsModule::~EventsModule() throw()
00224 {
00225 
00226     send( "Stopping events subsystem." ) ;
00227     
00228     if ( _joystickHandler != 0 )
00229     {
00230         delete _joystickHandler ;
00231         _joystickHandler = 0 ;
00232     }   
00233         
00234     if ( _keyboardHandler != 0 )
00235     {
00236         delete _keyboardHandler ;
00237         _keyboardHandler = 0 ;
00238     }   
00239     
00240     if ( _mouseHandler != 0 )
00241     {
00242         delete _mouseHandler ;
00243         _mouseHandler = 0 ;
00244     }   
00245     
00246     send( "Stopping and deleting any existing scheduler" ) ;
00247     Scheduler::DeleteScheduler() ;
00248     
00249     send( "Events subsystem stopped." ) ;
00250     
00251 }
00252 
00253 
00254 void EventsModule::waitForAnyKey( bool displayWaitingMessage ) const throw()
00255 {
00256 
00257 
00258     /*
00259      * No need to check that events and video are initialized, since we 
00260      * have an EventModule here.
00261      *
00262      */
00263     
00264     SDL_Event currentEvent ;
00265 
00266     if ( displayWaitingMessage )
00267     {
00268         Ceylan::display( "< Press any key on OSDL window to continue >" ) ;
00269     }
00270     
00271     /*
00272      * Simpler than integrating into the keyboard handler 
00273      * (and works without it) :
00274      *
00275      */
00276     do 
00277     {
00278     
00279         // Waiting, not polling, avoids taking 100% of the CPU for nothing :    
00280         SDL_WaitEvent( & currentEvent ) ;
00281         
00282     } 
00283     while ( currentEvent.type != KeyPressed ) ;
00284     
00285 }
00286 
00287 
00288 bool EventsModule::sleepFor( Second seconds, Microsecond micros ) 
00289     const throw( EventsException )
00290 {
00291 
00292     /*
00293      * getSchedulingGranularity has already been called in the EventsModule
00294      * constructor, no start-up overhead to fear.
00295      *
00296      */
00297     
00298     try
00299     {
00300     
00301         // Avoid owerflow for smartSleep :
00302         while ( seconds > 4100 )
00303         {
00304             Ceylan::System::smartSleep( 4100, 0 ) ;
00305             seconds -= 4100 ;
00306         }
00307             
00308         return Ceylan::System::smartSleep( seconds, micros ) ;
00309         
00310     }
00311     catch( const Ceylan::System::SystemException & e )
00312     {
00313         throw EventsException( "EventsModule::sleepFor : " + e.toString() ) ;
00314     }   
00315     
00316 }
00317 
00318 
00319 void EventsModule::useScheduler( bool on ) throw()
00320 {
00321 
00322     if ( on && ! _useScheduler )
00323     {
00324         // Force scheduler creation :
00325         Scheduler::GetScheduler() ;
00326     }   
00327     
00328     if ( ! on && _useScheduler )
00329     {
00330         // Force scheduler removal :
00331         Scheduler::DeleteScheduler() ;  
00332     }   
00333     
00334     _useScheduler = on ;
00335     
00336 }
00337 
00338 
00339 
00340 void EventsModule::setIdleCallback( 
00341         Ceylan::System::Callback idleCallback, 
00342         void * callbackData, 
00343         Ceylan::System::Microsecond callbackExpectedMaxDuration ) 
00344     throw()
00345 {
00346     
00347     
00348     if ( _useScheduler )
00349     {
00350         
00351         // Will create the scheduler if it is not already existing :
00352         Scheduler::GetScheduler().setIdleCallback( idleCallback, 
00353             callbackData, callbackExpectedMaxDuration ) ;
00354 
00355     }
00356     else // the basic event loop is used :
00357     {
00358     
00359         _loopIdleCallback            = idleCallback ;
00360         _loopIdleCallbackData        = callbackData ;
00361 
00362         if ( callbackExpectedMaxDuration != 0 )
00363             _loopIdleCallbackMaxDuration = callbackExpectedMaxDuration ;
00364         else
00365             _loopIdleCallbackMaxDuration = EvaluateCallbackduration(
00366                 idleCallback, callbackData ) ;
00367                         
00368     }
00369     
00370     
00371 }
00372 
00373 
00374 void EventsModule::setEventLoopTargetFrequency( Hertz targetFrequency ) throw()
00375 {
00376 
00377     _loopTargetedFrequency = targetFrequency ;
00378     
00379 }
00380 
00381 
00382 void EventsModule::enterMainLoop() throw( EventsException )
00383 { 
00384 
00385     if ( ! OSDL::CommonModule::IsBackendInitialized() )
00386         throw EventsException( "EventsModule::enterMainLoop called "
00387             "whereas back-end not initialized." ) ;
00388     
00389         
00390     // If a scheduler is available, delegate the task to it :
00391     if ( _useScheduler )
00392     {
00393     
00394         LogPlug::debug( 
00395             "EventsModule::enterMainLoop : delegating to scheduler." ) ;
00396         
00397         try
00398         {
00399         
00400             // Will create a scheduler if necessary :
00401             Scheduler::GetScheduler().schedule() ;
00402             
00403         }
00404         catch( const SchedulingException & e )
00405         {
00406             throw EventsException( 
00407                 "EventsModule::enterMainLoop : scheduler stopped on failure : "
00408                 + e.toString() ) ;
00409         }   
00410         
00411         LogPlug::debug( "EventsModule::enterMainLoop : scheduler returned." ) ;
00412         
00413     }
00414     else
00415     {
00416     
00417         LogPlug::debug( "EventsModule::enterMainLoop : "
00418             "no scheduler requested, using basic event loop." ) ;
00419         
00420         enterBasicMainLoop() ;  
00421             
00422         LogPlug::debug( 
00423             "EventsModule::enterMainLoop : exiting now from main loop." ) ;
00424             
00425     }   
00426 
00427 }
00428 
00429 
00430 void EventsModule::requestQuit() throw()
00431 {
00432 
00433     send( "Quit has been requested, exiting from main event loop." ) ;
00434     
00435     _quitRequested = true ;
00436     
00437     if ( _useScheduler )
00438     {
00439     
00440         try
00441         {
00442             Scheduler::GetExistingScheduler().stop() ;
00443         }
00444         catch ( const SchedulingException & e )
00445         {
00446             LogPlug::error( "EventsModule::requestQuit : "
00447                 "no scheduler found, none stopped, or stop failed : " 
00448                 + e.toString() ) ;
00449         }
00450         
00451     }   
00452     
00453 }
00454 
00455 
00456 
00457 // Handler subsection.
00458 
00459 
00460 bool EventsModule::hasKeyboardHandler() const throw()
00461 {
00462 
00463     return ( _keyboardHandler != 0 ) ;
00464     
00465 }
00466 
00467 
00468 
00469 KeyboardHandler & EventsModule::getKeyboardHandler() const 
00470     throw( EventsException )
00471 {
00472 
00473     if ( _keyboardHandler == 0 )
00474         throw EventsException( 
00475             "EventsModule::getKeyboardHandler : no handler available : "
00476             "did you specify 'CommonModule::UseKeyboard' "
00477             "at the initialization of the common module ?" ) ;
00478     
00479     return * _keyboardHandler ;
00480     
00481 }
00482 
00483 
00484 void EventsModule::setKeyboardHandler( KeyboardHandler & newHandler ) throw()
00485 {
00486 
00487     if ( _keyboardHandler != 0 )
00488         delete _keyboardHandler ;
00489         
00490     _keyboardHandler = & newHandler ;
00491     
00492 }
00493 
00494 
00495 
00496 
00497 bool EventsModule::hasJoystickHandler() const throw()
00498 {
00499 
00500     return ( _joystickHandler != 0 ) ;
00501     
00502 }
00503 
00504 
00505 JoystickHandler & EventsModule::getJoystickHandler() const 
00506     throw( EventsException )
00507 {
00508 
00509     if ( _joystickHandler == 0 )
00510         throw EventsException( 
00511             "EventsModule::getJoystickHandler : no handler available : "
00512             "did you specify 'CommonModule::UseJoystick' "
00513             "at the initialization of the common module ?" ) ;
00514     
00515     return * _joystickHandler ;
00516     
00517 }
00518 
00519 
00520 void EventsModule::setJoystickHandler( JoystickHandler & newHandler ) throw()
00521 {
00522 
00523     if ( _joystickHandler != 0 )
00524         delete _joystickHandler ;
00525         
00526     _joystickHandler = & newHandler ;
00527     
00528 }
00529 
00530 
00531 
00532 
00533 bool EventsModule::hasMouseHandler() const throw()
00534 {
00535 
00536     return ( _mouseHandler != 0 ) ;
00537     
00538 }
00539 
00540 
00541 MouseHandler & EventsModule::getMouseHandler() const 
00542     throw( EventsException )
00543 {
00544 
00545     if ( _mouseHandler == 0 )
00546         throw EventsException( 
00547             "EventsModule::getMouseHandler : no handler available : "
00548             "did you specify 'CommonModule::UseMouse' "
00549             "at the initialization of the common module ?" ) ;
00550     
00551     return * _mouseHandler ;
00552     
00553 }
00554 
00555 
00556 void EventsModule::setMouseHandler( MouseHandler & newHandler ) throw()
00557 {
00558 
00559     if ( _mouseHandler != 0 )
00560         delete _mouseHandler ;
00561         
00562     _mouseHandler = & newHandler ;
00563     
00564 }
00565 
00566 
00567 
00568 
00569 void EventsModule::updateInputState() throw()
00570 {
00571         
00572     BasicEvent currentEvent ;
00573     
00574     
00575     // Checks for all pending events :
00576 
00577     while ( SDL_PollEvent( & currentEvent ) )
00578     {
00579     
00580         switch ( currentEvent.type )
00581         {
00582 
00583 
00584             // Focus section.
00585             case ApplicationFocusChanged:
00586                 onApplicationFocusChanged( currentEvent.active ) ;
00587                 break ;
00588                     
00589             // Keyboard section.            
00590             case KeyPressed:
00591                 onKeyPressed( currentEvent.key ) ;
00592                 break ;
00593                 
00594             case KeyReleased:
00595                 onKeyReleased( currentEvent.key ) ;
00596                 break ;
00597             
00598             // Mouse section.
00599             case MouseMoved:
00600                 onMouseMotion( currentEvent.motion ) ;
00601                 break ;
00602                 
00603             case MouseButtonPressed:
00604                 onMouseButtonPressed( currentEvent.button ) ; 
00605                 break ;
00606                 
00607             case MouseButtonReleased:           
00608                 onMouseButtonReleased( currentEvent.button ) ;
00609                 break ;
00610                     
00611                         
00612             /* 
00613              * Joystick section.
00614              *
00615              * Joystick low level events should occur if and only if a 
00616              * joystick handler is used, therefore there should be no need 
00617              * for a handler check. 
00618              *
00619              */
00620             case JoystickAxisChanged:
00621                 onJoystickAxisChanged( currentEvent.jaxis ) ;
00622                 break ;
00623                 
00624             case JoystickTrackballChanged:
00625                 onJoystickTrackballChanged( currentEvent.jball ) ;
00626                 break ;
00627                 
00628             case JoystickHatPositionChanged:
00629                 onJoystickHatChanged( currentEvent.jhat ) ;
00630                 break ;
00631                 
00632             case JoystickButtonPressed:
00633                 onJoystickButtonPressed( currentEvent.jbutton ) ;
00634                 break ;
00635                 
00636             case JoystickButtonReleased:
00637                 onJoystickButtonReleased( currentEvent.jbutton ) ;
00638                 break ;         
00639             
00640             
00641             // Miscellaneous section.
00642             
00643             case UserRequestedQuit:
00644                 onQuitRequested() ;
00645                 break ;
00646             
00647             case SystemSpecificTriggered: 
00648                 onSystemSpecificWindowManagerEvent( currentEvent.syswm ) ;
00649                 break ;
00650             
00651             case UserResizedVideoMode:
00652                 onResizedWindow( currentEvent.resize ) ;
00653                 break ;
00654                 
00655             case ScreenNeedsRedraw:
00656                 onScreenNeedsRedraw() ; 
00657                 break ;
00658                 
00659             // User event and unknown section.
00660             default:
00661                 if ( currentEvent.type >= FirstUserEventTriggered 
00662                         || currentEvent.type <= LastUserEventTriggered )
00663                     onUserEvent( currentEvent.user ) ;
00664                 else
00665                     onUnknownEventType( currentEvent ) ;
00666                 break ;
00667                 
00668         }   
00669     }
00670 }
00671 
00672 
00673 const string EventsModule::toString( Ceylan::VerbosityLevels level ) 
00674     const throw()
00675 {
00676     
00677     string res = "Event module, " ;
00678     
00679     if ( _useScheduler )
00680         res += "using a scheduler, " ;
00681     else
00682         res += "not using any scheduler, " ;
00683         
00684     if ( _keyboardHandler != 0 )
00685         res += "using a keyboard handler, " ;
00686     else
00687         res += "not using any keyboard handler, " ;
00688     
00689     if ( _joystickHandler != 0 )
00690         res += "using a joystick handler, " ;
00691     else
00692         res += "not using any joystick handler, " ;
00693     
00694     if ( _mouseHandler != 0 )
00695         res += "using a mouse handler, " ;
00696     else
00697         res += "not using any mouse handler, " ;
00698     
00699     
00700     if ( _loopIdleCallback == 0 )
00701         res += "using micro-sleep idle callback" ;
00702     else
00703         res += "using user-specified idle callback" ;
00704                     
00705     if ( level == Ceylan::low )
00706         return res ;
00707     
00708     std::list<string> returned ;
00709     
00710     returned.push_back( res ) ;
00711                     
00712     returned.push_back( Ceylan::Module::toString() ) ;
00713     
00714     if ( level == Ceylan::medium)
00715         return Ceylan::formatStringList( returned ) ;
00716         
00717     if ( _keyboardHandler != 0 )
00718         returned.push_back( _keyboardHandler->toString() ) ;
00719     
00720     if ( _joystickHandler != 0 )
00721         returned.push_back( _joystickHandler->toString() ) ;
00722     
00723     if ( _mouseHandler != 0 )
00724         returned.push_back( _mouseHandler->toString() ) ;
00725     
00726     return Ceylan::formatStringList( returned ) ;
00727     
00728 }
00729 
00730 
00731 
00732 // Static section.      
00733 
00734             
00735 string EventsModule::DescribeEnvironmentVariables() throw()
00736 {
00737 
00738     Ceylan::Uint16 varCount = 
00739         sizeof( _SDLEnvironmentVariables ) / sizeof (char * ) ;
00740         
00741     string result = "Examining the " + Ceylan::toString( varCount )
00742         + " events-related environment variables for SDL backend :" ;
00743     
00744     std::list<string> variables ;
00745         
00746     string var, value ;
00747     
00748     bool htmlFormat = TextDisplayable::GetOutputFormat() ;
00749     
00750     for ( Ceylan::Uint16 i = 0; i < varCount; i++ ) 
00751     {
00752     
00753         var = _SDLEnvironmentVariables[ i ] ;
00754         value = Ceylan::System::getEnvironmentVariable( var ) ;
00755         
00756         if ( value.empty() )
00757         {
00758             if ( htmlFormat )
00759             {
00760                 variables.push_back( "<em>" + var + "</em> is not set." ) ;
00761             }
00762             else
00763             {
00764                 variables.push_back( var + " is not set." ) ;           
00765             }   
00766         }
00767         else
00768         {           
00769             if ( htmlFormat )
00770             {
00771                 variables.push_back( "<b>" + var + "</b> set to [" 
00772                     + value + "]." ) ;
00773             }
00774             else
00775             {
00776                 variables.push_back( var + " set to [" + value + "]." ) ;
00777             }   
00778         }   
00779     
00780     }
00781     
00782     return result + Ceylan::formatStringList( variables ) ;
00783     
00784 }
00785 
00786 
00787 
00788 string EventsModule::DescribeEvent( BasicEvent anEvent ) throw() 
00789 {
00790 
00791     switch( anEvent.type )
00792     {
00793     
00794         case ApplicationFocusChanged:
00795             return DescribeEvent( anEvent.active ) ;
00796             break ;
00797             
00798         case KeyPressed:
00799             return DescribeEvent( anEvent.key ) ;           
00800             break ;
00801     
00802         case KeyReleased:
00803             return DescribeEvent( anEvent.key ) ;           
00804             break ;
00805     
00806         case MouseMoved:
00807             return DescribeEvent( anEvent.motion ) ;            
00808             break ;
00809     
00810         case MouseButtonPressed:
00811             return DescribeEvent( anEvent.button ) ;            
00812             break ;
00813     
00814         case MouseButtonReleased:
00815             return DescribeEvent( anEvent.button ) ;            
00816             break ;
00817     
00818         case JoystickAxisChanged:
00819             return DescribeEvent( anEvent.jaxis ) ;         
00820             break ;
00821     
00822         case JoystickTrackballChanged:
00823             return DescribeEvent( anEvent.jball ) ;         
00824             break ;
00825     
00826         case JoystickHatPositionChanged:
00827             return DescribeEvent( anEvent.jhat ) ;          
00828             break ;
00829     
00830         case JoystickButtonPressed:
00831             return DescribeEvent( anEvent.jbutton ) ;           
00832             break ;
00833     
00834         case JoystickButtonReleased:
00835             return DescribeEvent( anEvent.jbutton ) ;           
00836             break ;
00837     
00838         case UserRequestedQuit:
00839             return DescribeEvent( anEvent.quit ) ;          
00840             break ;
00841     
00842         case SystemSpecificTriggered:
00843             return DescribeEvent( anEvent.syswm ) ;         
00844             break ;
00845     
00846         case UserResizedVideoMode:
00847             return DescribeEvent( anEvent.resize ) ;            
00848             break ;
00849         
00850         case ScreenNeedsRedraw:
00851             return DescribeEvent( anEvent.expose ) ;            
00852             break ;
00853     
00854         default:
00855             return "Unknow event type." ;
00856             break ; 
00857     }
00858      
00859     return "Unexpected event type." ;
00860 }   
00861 
00862 
00863 
00864 Millisecond EventsModule::GetMillisecondsSinceStartup() 
00865     throw( EventsException ) 
00866 {
00867 
00868     // Do not slow down too much on release mode :
00869 
00870 #if OSDL_DEBUG
00871     if ( ! OSDL::CommonModule::IsBackendInitialized() )
00872         throw EventsException( 
00873             "EventsModule::getMillisecondsSinceStartup() called "
00874             "whereas back-end not initialized." ) ;
00875 #endif // OSDL_DEBUG    
00876     
00877     return static_cast<Millisecond>( SDL_GetTicks() ) ;
00878     
00879 }
00880 
00881 
00882 
00883 
00884 // Protected section.
00885 
00886 
00887 
00888 void EventsModule::enterBasicMainLoop() throw( EventsException )
00889 {
00890 
00891     
00892     //Milliseconds * frameClock = 0 ;   
00893     Ceylan::Uint32 frameCount = 0 ;
00894     
00895     /*
00896     if ( GetFrameAccountingState() )
00897     {   
00898         frameClock = new Milliseconds[FrameTimingSlots] ;   
00899         for ( Ceylan::Uint32 i; i < FrameTimingSlots; i ++ )
00900             frameClock[i] = 0 ;
00901     }
00902     */  
00903     
00904     /*
00905      * This event loop will drive the rendering, by using the renderer 
00906      * if available, otherwise by using the video module.
00907      *
00908      */
00909      
00910     Video::VideoModule * video ;
00911      
00912     try
00913     {
00914         video = & OSDL::getExistingCommonModule().getVideoModule() ;
00915     } 
00916     catch ( const OSDL::Exception & e )
00917     {   
00918         throw EventsException( 
00919             "EventsModule::enterBasicMainLoop : no video module available ("
00920             + e.toString() ) ;
00921     }
00922     
00923     Rendering::Renderer * renderer = 0 ;
00924     
00925     if ( Rendering::Renderer::HasExistingRootRenderer() )
00926     {
00927         renderer = & Rendering::Renderer::GetExistingRootRenderer() ;
00928         LogPlug::debug( 
00929             "EventsModule::enterBasicMainLoop : using root renderer ("
00930             + renderer->toString() + ")" ) ;
00931     }
00932     else
00933     {
00934         LogPlug::debug( "EventsModule::enterBasicMainLoop : "
00935             "not using any root renderer." ) ;  
00936     }
00937         
00938     
00939     /*
00940      * No scheduler, using classical event loop.
00941      *
00942      * We believe we have a better accuracy than 'SDL_framerate' from 
00943      * SDL_gfx with that mechanism :
00944      *
00945      */
00946 
00947     _idleCallsCount = 0 ;
00948     
00949     Microsecond startedMicrosec ;
00950     Second startedSec ;
00951 
00952     Microsecond lastMicrosec ;
00953     Second lastSec ;
00954     
00955     Microsecond nowMicrosec ;
00956     Second nowSec ;
00957 
00958     
00959     try
00960     {
00961     
00962         if ( _loopIdleCallback == 0 )
00963         {
00964         
00965             /*
00966              * Force the scheduling granularity to be precomputed, to avoid
00967              * hiccups at loop start-up when needing granularity to adjust
00968              * sleeping delays in default idle callback :
00969              *
00970              * (a 10% margin is added)
00971              *
00972              */
00973             _loopIdleCallbackMaxDuration = 
00974                 static_cast<Microsecond>( 1.1 * getSchedulingGranularity() ) ;
00975             
00976         }
00977     
00978     
00979         // Compute the event loop period, in microsecond (default : 100 Hz) :
00980         Microsecond loopExpectedDuration 
00981             = static_cast<Microsecond>( 1000000.0f / _loopTargetedFrequency ) ; 
00982         
00983         // Default : 10ms, hence 10 000 microseconds :
00984         LogPlug::debug( "Loop expected duration is " 
00985             + Ceylan::toString( loopExpectedDuration ) + " microseconds, "
00986             "and idle callback expected duration is "
00987             + Ceylan::toString( _loopIdleCallbackMaxDuration ) 
00988             + " microseconds." ) ;
00989     
00990         getPreciseTime( lastSec, lastMicrosec ) ;
00991         
00992         startedSec      = lastSec ;
00993         startedMicrosec = lastMicrosec ;
00994         
00995         
00996         while ( ! _quitRequested )
00997         {
00998         
00999             // Checks for all pending events :
01000             updateInputState() ;
01001             
01002             /*
01003              * With a basic main loop, objets are expected to be event-driven,
01004              * hence updating the inputs should lead to updating their models,
01005              * then their views, so they should be now ready to be rendered.
01006              *
01007              */
01008             if ( renderer != 0 )
01009                 renderer->render() ;
01010             else
01011                 video->redraw() ;
01012         
01013             frameCount++ ;  
01014         
01015             getPreciseTime( nowSec, nowMicrosec ) ;
01016         
01017             // Do not call onIdle if it will likely make us miss the deadline :
01018             while ( getDurationBetween( lastSec, lastMicrosec, 
01019                     nowSec, nowMicrosec ) + _loopIdleCallbackMaxDuration 
01020                 < loopExpectedDuration )
01021             {
01022                 onIdle() ;
01023                 getPreciseTime( nowSec, nowMicrosec ) ;         
01024             }
01025             
01026             /*
01027              * Burn any last few microseconds with a 'soft' (thanks to 
01028              * getPreciseTime) busy wait :
01029              *
01030              */
01031             while ( getDurationBetween( lastSec, lastMicrosec, nowSec,
01032                     nowMicrosec ) < loopExpectedDuration )
01033                 getPreciseTime( nowSec, nowMicrosec ) ;         
01034             
01035             /*
01036              * Note that in all cases we stay equal or below to the requested
01037              * frequency : we can be late (if the idle callback last for too
01038              * long), but not early (we never stop before the current deadline),
01039              * so on a run we are a bit late on average.
01040              * 
01041              */
01042              
01043             // Ready for next iteration :
01044             lastSec      = nowSec ;
01045             lastMicrosec = nowMicrosec ;
01046         
01047         }
01048     
01049     } 
01050     catch ( const SystemException & e )
01051     {   
01052         throw EventsException( "EventsModule::enterBasicMainLoop : " 
01053             + e.toString() ) ;
01054     }
01055     
01056     if ( ( lastSec - startedSec ) >
01057         Ceylan::System::MaximumDurationWithMicrosecondAccuracy )
01058     {
01059     
01060         // Avoid overflow of getDurationBetween, no average FPS computed : 
01061         LogPlug::debug( "Exited from main loop after " 
01062             + Ceylan::toString( frameCount ) + " frames and about " 
01063             + Ceylan::toString( lastSec - startedSec ) 
01064             + " seconds, an average of " 
01065             + Ceylan::toString( 
01066                 static_cast<Ceylan::Float64>( _idleCallsCount ) / frameCount, 
01067                 /* precision */ 3 )
01068             + " idle calls per frame have been performed." ) ;
01069     }
01070     else
01071     {
01072         LogPlug::debug( "Exited from main loop after " 
01073             + Ceylan::toString( frameCount ) + " frames and about " 
01074             + Ceylan::toString( lastSec - startedSec ) 
01075             + " seconds, on average there were " 
01076             + Ceylan::toString( 
01077                     1000000.0f /* since microseconds */ * frameCount / 
01078                     getDurationBetween( startedSec, startedMicrosec, lastSec,
01079                         lastMicrosec ),
01080                 /* precision */ 3 )
01081             + " frames per second, an average of " 
01082             + Ceylan::toString( 
01083                 static_cast<Ceylan::Float64>( _idleCallsCount ) / frameCount, 
01084                 /* precision */ 3 )
01085             + " idle calls per frame have been performed." ) ;
01086     }       
01087 
01088 }
01089 
01090 
01091 
01092 
01093 // Keyboard section.
01094 
01095 
01096 void EventsModule::onKeyboardFocusGained(
01097     const FocusEvent & keyboardFocusEvent ) throw()
01098 {
01099 
01100     OSDL_EVENT_LOG( "Application gained keyboard focus." ) ;
01101 
01102 #if OSDL_DEBUG
01103     if ( _keyboardHandler == 0 )
01104         Ceylan::emergencyShutdown( "EventsModule::onKeyboardFocusGained called "
01105             "whereas no handler is available." ) ;
01106 #endif // OSDL_DEBUG
01107 
01108     _keyboardHandler->focusGained( keyboardFocusEvent ) ;
01109 
01110 }
01111 
01112 
01113 void EventsModule::onKeyboardFocusLost(
01114     const FocusEvent & keyboardFocusEvent ) throw()
01115 {
01116 
01117     OSDL_EVENT_LOG( "Application lost keyboard focus." ) ;
01118 
01119 #if OSDL_DEBUG
01120     if ( _keyboardHandler == 0 )
01121         Ceylan::emergencyShutdown( "EventsModule::onKeyboardFocusLost called "
01122             "whereas no handler is available." ) ;
01123 #endif // OSDL_DEBUG
01124 
01125     _keyboardHandler->focusLost( keyboardFocusEvent ) ;
01126 
01127 }
01128 
01129 
01130 void EventsModule::onKeyPressed( const KeyboardEvent & keyboardEvent ) throw()
01131 {
01132 
01133     OSDL_EVENT_LOG( "Key pressed." ) ;
01134 
01135 #if OSDL_DEBUG
01136     if ( _keyboardHandler == 0 )
01137         Ceylan::emergencyShutdown( "EventsModule::onKeyPressed called "
01138             "whereas no handler is available." ) ;
01139 #endif // OSDL_DEBUG
01140 
01141     _keyboardHandler->keyPressed( keyboardEvent ) ;
01142     
01143 }
01144 
01145 
01146 void EventsModule::onKeyReleased( const KeyboardEvent & keyboardEvent ) throw()
01147 {
01148 
01149     OSDL_EVENT_LOG( "Key released." ) ;
01150 
01151 #if OSDL_DEBUG
01152     if ( _keyboardHandler == 0 )
01153         Ceylan::emergencyShutdown( "EventsModule::onKeyReleased called "
01154             "whereas no handler is available." ) ;
01155 #endif // OSDL_DEBUG
01156 
01157     _keyboardHandler->keyReleased( keyboardEvent ) ;
01158     
01159 }
01160 
01161 
01162 
01163 // Mouse section.
01164 
01165 
01166 void EventsModule::onMouseFocusGained( 
01167     const FocusEvent & mouseFocusEvent ) throw()
01168 {
01169 
01170     OSDL_EVENT_LOG( "Application gained mouse focus." ) ;
01171 
01172 #if OSDL_DEBUG
01173     if ( _mouseHandler == 0 )
01174         Ceylan::emergencyShutdown( "EventsModule::onMouseFocusGained called "
01175             "whereas no handler is available." ) ;
01176 #endif // OSDL_DEBUG
01177 
01178     _mouseHandler->focusGained( mouseFocusEvent ) ;
01179     
01180 }
01181 
01182 
01183 void EventsModule::onMouseFocusLost( 
01184     const FocusEvent & mouseFocusEvent ) throw()
01185 {
01186 
01187     OSDL_EVENT_LOG( "Application lost mouse focus." ) ;
01188 
01189 #if OSDL_DEBUG
01190     if ( _mouseHandler == 0 )
01191         Ceylan::emergencyShutdown( "EventsModule::onMouseFocusLost called "
01192             "whereas no handler is available." ) ;
01193 #endif // OSDL_DEBUG
01194 
01195     _mouseHandler->focusLost( mouseFocusEvent ) ;
01196 
01197 }
01198 
01199 
01200 void EventsModule::onMouseMotion( const MouseMotionEvent & mouseEvent ) throw()
01201 {
01202 
01203     OSDL_EVENT_LOG( "Mouse motion." ) ;
01204 
01205 #if OSDL_DEBUG
01206     if ( _mouseHandler == 0 )
01207         Ceylan::emergencyShutdown( "EventsModule::onMouseMotion called "
01208             "whereas no handler is available." ) ;
01209 #endif // OSDL_DEBUG
01210 
01211     _mouseHandler->mouseMoved( mouseEvent ) ;
01212     
01213 }
01214 
01215 
01216 void EventsModule::onMouseButtonPressed( const MouseButtonEvent & mouseEvent )
01217     throw()
01218 {
01219 
01220     OSDL_EVENT_LOG( "Mouse button pressed." ) ;
01221 
01222 #if OSDL_DEBUG
01223     if ( _mouseHandler == 0 )
01224         Ceylan::emergencyShutdown( "EventsModule::onMouseButtonPressed called "
01225             "whereas no handler is available." ) ;
01226 #endif // OSDL_DEBUG
01227 
01228     _mouseHandler->buttonPressed( mouseEvent ) ;
01229     
01230 }
01231 
01232 
01233 void EventsModule::onMouseButtonReleased( const MouseButtonEvent & mouseEvent )
01234     throw()
01235 {
01236 
01237     OSDL_EVENT_LOG( "Mouse button released." ) ;
01238 
01239 #if OSDL_DEBUG
01240     if ( _mouseHandler == 0 )
01241         Ceylan::emergencyShutdown( "EventsModule::onMouseButtonReleased called "
01242             "whereas no handler is available." ) ;
01243 #endif // OSDL_DEBUG
01244 
01245     _mouseHandler->buttonReleased( mouseEvent ) ;
01246     
01247 }
01248 
01249 
01250 
01251 // Joystick section.
01252 
01253 
01254 void EventsModule::onJoystickAxisChanged( 
01255     const JoystickAxisEvent & joystickEvent ) throw()
01256 {
01257 
01258     OSDL_EVENT_LOG( "Joystick axis moved." ) ;
01259     
01260 #if OSDL_DEBUG
01261     if ( _joystickHandler == 0 )
01262         Ceylan::emergencyShutdown( "EventsModule::onJoystickAxisChanged called "
01263             "whereas no handler is available." ) ;
01264 #endif // OSDL_DEBUG
01265     
01266     _joystickHandler->axisChanged( joystickEvent ) ;
01267     
01268 }
01269 
01270 
01271 void EventsModule::onJoystickTrackballChanged( 
01272     const JoystickTrackballEvent & joystickEvent ) throw()
01273 {
01274 
01275     OSDL_EVENT_LOG( "Joystick trackball moved." ) ;
01276 
01277 #if OSDL_DEBUG
01278     if ( _joystickHandler == 0 )
01279         Ceylan::emergencyShutdown( 
01280             "EventsModule::onJoystickTrackballChanged called "
01281             "whereas no handler is available." ) ;
01282 #endif // OSDL_DEBUG
01283     
01284     _joystickHandler->trackballChanged( joystickEvent ) ;
01285 
01286 }
01287 
01288 
01289 void EventsModule::onJoystickHatChanged( 
01290     const JoystickHatEvent & joystickEvent ) throw()
01291 {
01292 
01293     OSDL_EVENT_LOG( "Joystick hat moved." ) ;
01294 
01295 #if OSDL_DEBUG
01296     if ( _joystickHandler == 0 )
01297         Ceylan::emergencyShutdown( "EventsModule::onJoystickHatChanged called "
01298             "whereas no handler is available." ) ;
01299 #endif // OSDL_DEBUG
01300     
01301     _joystickHandler->hatChanged( joystickEvent ) ;
01302     
01303 }
01304 
01305 
01306 void EventsModule::onJoystickButtonPressed( 
01307     const JoystickButtonEvent & joystickEvent ) throw()
01308 {
01309 
01310     OSDL_EVENT_LOG( "Joystick button pressed." ) ;
01311 
01312 #if OSDL_DEBUG
01313     if ( _joystickHandler == 0 )
01314         Ceylan::emergencyShutdown( 
01315             "EventsModule::onJoystickButtonPressed called "
01316             "whereas no handler is available." ) ;
01317 #endif // OSDL_DEBUG
01318     
01319     _joystickHandler->buttonPressed( joystickEvent ) ;
01320 
01321 }
01322 
01323 
01324 void EventsModule::onJoystickButtonReleased( 
01325     const JoystickButtonEvent & joystickEvent ) throw()
01326 {
01327 
01328     OSDL_EVENT_LOG( "Joystick button released." ) ;
01329 
01330 #if OSDL_DEBUG
01331     if ( _joystickHandler == 0 )
01332         Ceylan::emergencyShutdown( 
01333             "EventsModule::onJoystickButtonReleased called "
01334             "whereas no handler is available." ) ;
01335 #endif
01336     
01337     _joystickHandler->buttonReleased( joystickEvent ) ;
01338 
01339 }
01340 
01341 
01342 
01343 // Application-generic section.
01344 
01345         
01346 void EventsModule::onIdle() throw() 
01347 {       
01348 
01349     _idleCallsCount++ ;
01350     
01351     if ( _loopIdleCallback != 0 )
01352     {
01353         OSDL_EVENT_LOG( 
01354             "EventsModule::onIdle : calling now idle call-back." ) ;
01355         
01356         (*_loopIdleCallback)( _loopIdleCallbackData ) ;
01357         
01358         OSDL_EVENT_LOG( 
01359             "EventsModule::onIdle : returned from idle call-back." ) ;
01360         
01361     }
01362     else
01363     {
01364     
01365         /*
01366          * Issues an atomic sleep, chosen so that the minimum real
01367          * sleeping time can be performed, scheduler-wise.
01368          *
01369          */
01370          Ceylan::System::atomicSleep() ;
01371         
01372     }   
01373         
01374 }
01375 
01376 
01377 void EventsModule::onApplicationFocusChanged( 
01378     const FocusEvent & focusEvent ) throw()
01379 {
01380 
01381     OSDL_EVENT_LOG( "Application focus changed." ) ;
01382     
01383     // Maybe multiple gains or losses could be sent in one event :
01384 
01385     if ( focusEvent.state & _MouseFocus )
01386     {
01387         
01388         // DefaultMouse : only one mouse supported for the moment.
01389         
01390         if ( focusEvent.gain == 1 )
01391             onMouseFocusGained( focusEvent ) ;
01392         else
01393             onMouseFocusLost( focusEvent ) ;    
01394     }
01395     
01396     if ( focusEvent.state & _KeyboardFocus )
01397     {
01398         if ( focusEvent.gain == 1 )
01399             onKeyboardFocusGained( focusEvent ) ;
01400         else
01401             onKeyboardFocusLost( focusEvent ) ; 
01402     }
01403     
01404     if ( focusEvent.state & _ApplicationFocus )
01405     {
01406         if ( focusEvent.gain == 1 )
01407             onApplicationRestored( focusEvent ) ;
01408         else
01409             onApplicationIconified( focusEvent ) ;  
01410     }
01411         
01412 }
01413 
01414 
01415 void EventsModule::onApplicationIconified( 
01416     const FocusEvent & focusEvent ) throw()
01417 {
01418 
01419     OSDL_EVENT_LOG( "Application is iconified (no handler registered) : "
01420         + DescribeEvent( focusEvent ) ) ;
01421     
01422 }
01423 
01424 
01425 void EventsModule::onApplicationRestored( 
01426     const FocusEvent & focusEvent ) throw()
01427 {
01428 
01429     OSDL_EVENT_LOG( "Application is restored (no handler registered) : "
01430         + DescribeEvent( focusEvent ) ) ;
01431     
01432 }
01433 
01434 
01435 void EventsModule::onQuitRequested() throw()
01436 {
01437 
01438     OSDL_EVENT_LOG( "Application is requested to stop." ) ;
01439 
01440     requestQuit() ;
01441     
01442 }
01443 
01444 
01445 void EventsModule::onSystemSpecificWindowManagerEvent( 
01446     const SystemSpecificWindowManagerEvent & wmEvent ) throw()
01447 {
01448 
01449     /*
01450      * @see http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSysWMEvent to 
01451      * obtain system-specific information about the window manager, 
01452      * with SDL_GetWMInfo.
01453      *
01454      */
01455     OSDL_EVENT_LOG( "System specific window manager event received "
01456         "(no handler registered)." ) ;   
01457 
01458 }
01459     
01460                     
01461 void EventsModule::onResizedWindow( const WindowResizedEvent & resizeEvent )
01462     throw()
01463 {
01464 
01465     OSDL_EVENT_LOG( "Resizing, new width is " << resizeEvent.w 
01466         << ", new height is " << resizeEvent.h << "." ) ;
01467         
01468     try
01469     {   
01470         OSDL::getExistingCommonModule().getVideoModule().resize( 
01471             resizeEvent.w, resizeEvent.h ) ;
01472     } 
01473     catch( const Video::VideoException & e )
01474     {
01475         // Warn but continue nevertheless :
01476         LogPlug::error( 
01477             "EventsModule::onResizedWindow : error when resizing to "
01478             + Ceylan::toString( resizeEvent.w ) + ", " 
01479             + Ceylan::toString( resizeEvent.h ) + ") : "
01480             + e.toString() ) ;
01481     }
01482     
01483 }
01484 
01485 
01486 void EventsModule::onScreenNeedsRedraw() throw()
01487 {
01488 
01489     OSDL_EVENT_LOG( "Screen needs redraw." ) ;
01490 
01491     try
01492     {   
01493         OSDL::getExistingCommonModule().getVideoModule().redraw() ;
01494     } 
01495     catch( const Video::VideoException & e )
01496     {
01497         // Warn but continue nevertheless.
01498         LogPlug::error( "EventsModule::onScreenNeedsRedraw : "
01499             "error when requesting a redraw : " + e.toString() ) ;
01500     }
01501 
01502 }
01503 
01504 
01505 void EventsModule::onUserEvent( const UserEvent & userEvent ) throw() 
01506 {
01507 
01508     OSDL_EVENT_LOG( "User event received, whose type is " << userEvent.type
01509         << " (no handler registered)." ) ;
01510         
01511 }
01512         
01513                     
01514 void EventsModule::onUnknownEventType( const BasicEvent & unknownEvent ) throw()
01515 {
01516 
01517     OSDL_EVENT_LOG( "Unknown event, type is " << unknownEvent.type 
01518         << " (no handler registered)." ) ;
01519     
01520 }
01521 
01522 
01523 
01524 // Static section :
01525 
01526 string EventsModule::DescribeEvent( const FocusEvent & focusEvent )
01527 {
01528     
01529     string res = "Focus changed" ;
01530     
01531     if ( focusEvent.state & _MouseFocus )
01532     {
01533         if ( focusEvent.gain == 1 )
01534             res += ", mouse gained focus" ;
01535         else
01536             res += ", mouse lost focus" ;
01537     }
01538     
01539     if ( focusEvent.state & _KeyboardFocus )
01540     {
01541         if ( focusEvent.gain == 1 )
01542             res += ", keyboard gained focus" ;
01543         else
01544             res += ", keyboard lost focus" ;
01545     }
01546     
01547     if ( focusEvent.state & _ApplicationFocus )
01548     {
01549         if ( focusEvent.gain == 1 )
01550             res += ", application restored." ;
01551         else
01552             res += ", application iconified." ;
01553     }
01554     
01555     return res ;
01556     
01557 }
01558 
01559 
01560 string EventsModule::DescribeEvent( const KeyboardEvent & keyboardEvent )
01561 {
01562     
01563     string res = "Key " + KeyboardHandler::DescribeKey( 
01564         static_cast<KeyboardHandler::KeyIdentifier>( 
01565             keyboardEvent.keysym.sym ) ) 
01566         + ", with modifier(s) : " 
01567         + KeyboardHandler::DescribeModifier( 
01568             static_cast<KeyboardHandler::KeyModifier>( 
01569                 keyboardEvent.keysym.mod ) )
01570         + " (scancode :  " 
01571             + Ceylan::toNumericalString( keyboardEvent.keysym.scancode ) 
01572             + ") was " ;
01573     
01574     if ( keyboardEvent.type == KeyPressed )
01575         res += "pressed" ;
01576     else
01577         res += "released" ;
01578 
01579     if ( KeyboardHandler::GetMode() == textInput )
01580         res += ". " + KeyboardHandler::DescribeUnicode(
01581             keyboardEvent.keysym.unicode ) ;
01582         
01583     return res + "." ;
01584     
01585 }
01586 
01587 
01588 string EventsModule::DescribeEvent( const MouseMotionEvent & mouseMotionEvent )
01589 {
01590 
01591     string res = "Mouse moved to (" + Ceylan::toString( mouseMotionEvent.x ) 
01592         + ";"
01593         + Ceylan::toString( mouseMotionEvent.y ) 
01594         + ") after a relative movement of ("
01595         + Ceylan::toString( mouseMotionEvent.xrel ) + ";" 
01596         + Ceylan::toString( mouseMotionEvent.yrel ) + ")." ;
01597     
01598     for ( Ceylan::Uint8 i = 1; i <= _MouseButtonCount; i++ )
01599         if ( mouseMotionEvent.state & ( SDL_BUTTON( i ) ) )
01600             res += " Button #" + Ceylan::toNumericalString( i ) 
01601                 + " is pressed." ;
01602             
01603     return res ;
01604     
01605 }
01606 
01607 
01608 string EventsModule::DescribeEvent( const MouseButtonEvent & mouseButtonEvent )
01609 {
01610 
01611     string res ;
01612     
01613     switch( mouseButtonEvent.button )
01614     {
01615     
01616         case SDL_BUTTON_LEFT:
01617             res = "Left mouse button " 
01618                 + ( mouseButtonEvent.state == SDL_PRESSED ) ? 
01619                     "pressed" : "released" ;
01620             break ;
01621             
01622         case SDL_BUTTON_MIDDLE:
01623             res = "Middle mouse button " 
01624                 + ( mouseButtonEvent.state == SDL_PRESSED ) ? 
01625                     "pressed" : "released" ;
01626             break ;
01627             
01628         case SDL_BUTTON_RIGHT:
01629             res = "Right mouse button " 
01630                 + ( mouseButtonEvent.state == SDL_PRESSED ) ? 
01631                     "pressed" : "released" ;
01632             break ;
01633             
01634         case SDL_BUTTON_WHEELUP:
01635             res = "Mouse wheel up" ;
01636             break ;
01637             
01638         case SDL_BUTTON_WHEELDOWN:
01639             res = "Mouse wheel down" ;
01640             break ;
01641         
01642         default:
01643             res = "Unexpected mouse event" ;
01644             break ; 
01645     
01646     }
01647     
01648     
01649     res += " while mouse was located at (" 
01650         + Ceylan::toString( mouseButtonEvent.x ) + ";" 
01651         + Ceylan::toString( mouseButtonEvent.y ) + ")." ;
01652                     
01653     return res ;
01654 
01655 }
01656 
01657 
01658 string EventsModule::DescribeEvent( const JoystickAxisEvent & axisEvent )
01659 {
01660 
01661     return "Joystick #" + Ceylan::toNumericalString( axisEvent.which ) 
01662         + " had axis #" + Ceylan::toNumericalString( axisEvent.axis ) 
01663         + " moved to "  + Ceylan::toString( axisEvent.value ) + "." ; 
01664         
01665 }
01666 
01667 
01668 string EventsModule::DescribeEvent( const JoystickTrackballEvent & ballEvent )
01669 {
01670 
01671     return "Joystick #" + Ceylan::toNumericalString( ballEvent.which ) 
01672         + " had trackball #" + Ceylan::toNumericalString( ballEvent.ball ) 
01673         + " moved of (" 
01674         + Ceylan::toString( ballEvent.xrel ) + ";" 
01675         + Ceylan::toString( ballEvent.yrel ) + ")." ; 
01676 
01677 }
01678 
01679 
01680 string EventsModule::DescribeEvent( const JoystickHatEvent & hatEvent )
01681 {
01682 
01683     return "Joystick #" + Ceylan::toString( hatEvent.which ) + " had hat #"
01684         + Ceylan::toNumericalString( hatEvent.hat ) + " set to position " 
01685         + Ceylan::toString( hatEvent.value ) + "." ; 
01686 
01687 }
01688 
01689 
01690 string EventsModule::DescribeEvent( const JoystickButtonEvent & buttonEvent )
01691 {
01692 
01693     return "Joystick #" + Ceylan::toNumericalString( buttonEvent.which ) 
01694         + " had button #" + Ceylan::toNumericalString( buttonEvent.button ) 
01695         + ( ( buttonEvent.state == SDL_PRESSED ) ? 
01696             " pressed." : " released." ) ;
01697          
01698 }
01699 
01700 
01701 string EventsModule::DescribeEvent( const UserRequestedQuitEvent & quitEvent )  
01702 {
01703 
01704     return "User requested to quit." ;
01705     
01706 }
01707 
01708 
01709 string EventsModule::DescribeEvent( 
01710     const SystemSpecificWindowManagerEvent & windowManagerEvent ) 
01711 {
01712 
01713     /* 
01714      * @todo add int SDL_GetWMInfo(SDL_SysWMinfo *info); 
01715      * (see http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSysWMEvent)
01716      *
01717      */
01718      
01719     return "System-specific window manager event occured." ;
01720     
01721 }
01722 
01723 
01724 string EventsModule::DescribeEvent( const WindowResizedEvent & resizeEvent )
01725 {
01726 
01727     return "Window resized to (" + Ceylan::toString( resizeEvent.w )
01728         + ";" + Ceylan::toString( resizeEvent.h ) + ")." ;
01729         
01730 }
01731 
01732 
01733 string EventsModule::DescribeEvent( const ScreenExposedEvent & redrawEvent )
01734 {
01735     return "Window exposed, needs to be redrawn." ;
01736 }
01737 
01738 
01739 string EventsModule::DescribeEvent( const UserEvent & userEvent ) 
01740 {
01741     return "User-defined event occured (code #" 
01742         + Ceylan::toString( userEvent.code ) + ")." ;
01743 }
01744 
01745  
01746 bool EventsModule::IsEventsInitialized() throw()
01747 {
01748 
01749     return _EventsInitialized ;
01750     
01751 }
01752 
01753 
01754 Ceylan::System::Microsecond EventsModule::EvaluateCallbackduration(
01755     Ceylan::System::Callback callback, void * callbackData ) throw()
01756 {
01757 
01758     // Issue just a first and only run, to measure how long it takes :
01759     Microsecond startedMicrosec ;
01760     Second startedSec ;
01761         
01762     Microsecond endedMicrosec ;
01763     Second endedSec ;
01764         
01765     getPreciseTime( startedSec, startedMicrosec ) ;
01766             
01767     (*callback)( callbackData ) ;
01768         
01769     getPreciseTime( endedSec, endedMicrosec ) ;
01770             
01771     Microsecond callbackExpectedMaxDuration =
01772         static_cast<Microsecond>( 1.2 *
01773             getDurationBetween( startedSec, startedMicrosec,
01774                     endedSec, endedMicrosec ) ) ;
01775             
01776     LogPlug::debug( "EventsModule::EvaluateCallbackduration : duration for "
01777         "idle callback evaluated to " 
01778         + Ceylan::toString( callbackExpectedMaxDuration )
01779         + " microseconds." ) ;
01780     
01781     return callbackExpectedMaxDuration ;
01782 
01783 }
01784 
01785     

Generated on Fri Mar 30 14:46:59 2007 for OSDL by  doxygen 1.5.1