00001 #include "OSDLBasic.h"
00002
00003 #include "OSDLEvents.h"
00004 #include "OSDLVideo.h"
00005 #include "OSDLCDROMDriveHandler.h"
00006
00007 #include "OSDLAudio.h"
00008
00009 #include "OSDLUtils.h"
00010
00011
00012 #include "SDL.h"
00013
00014 #include <list>
00015
00016
00017 #ifdef OSDL_USES_CONFIG_H
00018 #include <OSDLConfig.h>
00019 #endif // OSDL_USES_CONFIG_H
00020
00021
00022
00023 using std::string ;
00024
00025 using namespace Ceylan ;
00026 using namespace Ceylan::Log ;
00027
00028 using namespace OSDL ;
00029
00030
00031
00032
00033 const CommonModule::BackendReturnCode CommonModule::BackendSuccess = 0 ;
00034 const CommonModule::BackendReturnCode CommonModule::BackendError = -1 ;
00035
00036
00037
00038 bool CommonModule::_BackendInitialized = false ;
00039
00040
00041
00042 #define OSDL_DEBUG_VERSION 0
00043
00044 const Ceylan::LibtoolVersion & OSDL::GetVersion() throw()
00045 {
00046
00047
00048 #if OSDL_DEBUG_VERSION
00049
00050
00051
00052 Ceylan::LibtoolVersion * ceylanVersion ;
00053
00054 try
00055 {
00056 osdlVersion = new Ceylan::LibtoolVersion( OSDL_LIBTOOL_VERSION ) ;
00057 }
00058 catch( const Ceylan::Exception & e )
00059 {
00060 Ceylan::emergencyShutdown( "OSDL::GetVersion failed : "
00061 + e.toString() ) ;
00062 }
00063
00064 return *osdlVersion ;
00065
00066
00067 #else // OSDL_DEBUG_VERSION
00068
00069 static Ceylan::LibtoolVersion osdlVersion( OSDL_LIBTOOL_VERSION ) ;
00070 return osdlVersion ;
00071
00072 #endif // OSDL_DEBUG_VERSION
00073
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 const Ceylan::Flags CommonModule::UseTimer = SDL_INIT_TIMER ;
00092 const Ceylan::Flags CommonModule::UseAudio = SDL_INIT_AUDIO ;
00093 const Ceylan::Flags CommonModule::UseVideo = SDL_INIT_VIDEO ;
00094 const Ceylan::Flags CommonModule::UseCDROM = SDL_INIT_CDROM ;
00095 const Ceylan::Flags CommonModule::UseJoystick = SDL_INIT_JOYSTICK ;
00096 const Ceylan::Flags CommonModule::UseKeyboard = 0x4000 ;
00097 const Ceylan::Flags CommonModule::UseMouse = 0x8000 ;
00098 const Ceylan::Flags CommonModule::UseEverything = SDL_INIT_EVERYTHING ;
00099 const Ceylan::Flags CommonModule::NoParachute = SDL_INIT_NOPARACHUTE ;
00100 const Ceylan::Flags CommonModule::UseEventThread = SDL_INIT_EVENTTHREAD ;
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 CommonModule * CommonModule::_CurrentCommonModule = 0 ;
00122
00123
00125 string CommonModule::_SDLEnvironmentVariables[] =
00126 {
00127 "SDL_DEBUG",
00128 "SDL_CDROM"
00129 } ;
00130
00131
00132 CommonModule::CommonModule( Flags flags ) throw ( OSDL::Exception ) :
00133 Ceylan::Module(
00134 "OSDL common module",
00135 "This is the root module of OSDL",
00136 "http://osdl.sourceforge.net",
00137 "Olivier Boudeville",
00138 "olivier.boudeville@online.fr",
00139 OSDL::GetVersion(),
00140 "LGPL" ),
00141 _video( 0 ),
00142 _events( 0 ),
00143 _audio( 0 ),
00144 _flags( flags ),
00145 _cdromHandler( 0 )
00146 {
00147
00148
00149 send( "Starting OSDL version " + OSDL::GetVersion().toString() + ". "
00150 + InterpretFlags( flags ) ) ;
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 if ( flags & UseTimer )
00162 {
00163 send( "Initializing timer subsystem" ) ;
00164 if ( SDL_InitSubSystem( UseTimer ) != BackendSuccess )
00165 throw OSDL::Exception( "CommonModule constructor : "
00166 "unable to initialize timer subsystem : "
00167 + Utils::getBackendLastError() ) ;
00168 send( "Timer subsystem initialized" ) ;
00169 }
00170
00171
00172 if ( flags & UseCDROM )
00173 {
00174 _cdromHandler = new OSDL::CDROMDriveHandler() ;
00175 }
00176
00177
00178 if ( flags & NoParachute )
00179 {
00180 send( "Disabling SDL parachute" ) ;
00181 if ( SDL_InitSubSystem( NoParachute ) != BackendSuccess )
00182 throw OSDL::Exception( "CommonModule constructor : "
00183 "unable to disable SDL parachute : "
00184 + Utils::getBackendLastError() ) ;
00185 send( "SDL parachute initialized" ) ;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 if ( flags & UseVideo )
00201 {
00202 _video = new Video::VideoModule() ;
00203 send( "Video support demanded, adding Events support" ) ;
00204 _events = new Events::EventsModule( flags ) ;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213 if ( flags & UseAudio )
00214 {
00215 _audio = new Audio::AudioModule() ;
00216 }
00217
00218
00219 _BackendInitialized = true ;
00220
00221 send( "OSDL successfully initialized" ) ;
00222
00223 dropIdentifier() ;
00224
00225 }
00226
00227
00228 CommonModule::~CommonModule() throw ()
00229 {
00230
00231 send( "Stopping OSDL" ) ;
00232
00233 if ( _cdromHandler != 0 )
00234 {
00235 delete _cdromHandler ;
00236 _cdromHandler = 0 ;
00237 }
00238
00239 if ( _audio != 0 )
00240 {
00241 delete _audio ;
00242 _audio = 0 ;
00243 }
00244
00245 if ( _events != 0 )
00246 {
00247 delete _events ;
00248 _events = 0 ;
00249 }
00250
00251 if ( _video != 0 )
00252 {
00253 delete _video ;
00254 _video = 0 ;
00255 }
00256
00257 SDL_Quit() ;
00258
00259 send( "OSDL successfully stopped" ) ;
00260
00261 }
00262
00263
00264 string CommonModule::InterpretFlags( Flags flags ) throw()
00265 {
00266
00267 std::list<string> res ;
00268
00269 if ( flags & UseTimer )
00270 res.push_back( "Timer requested (UseTimer is set)." ) ;
00271 else
00272 res.push_back( "No timer requested (UseTimer is not set)." ) ;
00273
00274 if ( flags & UseAudio)
00275 res.push_back( "Audio requested (UseAudio is set)." ) ;
00276 else
00277 res.push_back( "No audio requested (UseAudio is not set)." ) ;
00278
00279 if ( flags & UseVideo )
00280 res.push_back( "Video requested (UseVideo is set)." ) ;
00281 else
00282 res.push_back( "No video requested (UseVideo is not set)." ) ;
00283
00284 if ( flags & UseCDROM )
00285 res.push_back( "CD-ROM support requested (UseCDROM is set)." ) ;
00286 else
00287 res.push_back( "No CD-ROM support requested "
00288 "(UseCDROM is not set)." ) ;
00289
00290
00291 if ( flags & UseJoystick )
00292 res.push_back( "Joystick support requested (UseJoystick is set)." ) ;
00293 else
00294 res.push_back( "No joystick support requested "
00295 "(UseJoystick is not set)." ) ;
00296
00297 if ( flags & UseKeyboard )
00298 res.push_back( "Keyboard support requested (UseKeyboard is set)." ) ;
00299 else
00300 res.push_back( "No keyboard support requested "
00301 "(UseKeyboard is not set)." ) ;
00302
00303 if ( flags & UseMouse )
00304 res.push_back( "Mouse support requested (UseMouse is set)." ) ;
00305 else
00306 res.push_back( "No mouse support requested (UseMouse is not set)." ) ;
00307
00308
00309 if ( ( flags & UseEverything ) == UseEverything )
00310 res.push_back( "Every subsystem is requested "
00311 "(UseEverything is set)." ) ;
00312 else
00313 res.push_back( "Not all subsystems are requested "
00314 "(UseEverything is not set)." ) ;
00315
00316 if ( flags & NoParachute )
00317 res.push_back( "No catching of fatal signals requested "
00318 "(NoParachute is set)." ) ;
00319 else
00320 res.push_back( "Fatal signal will be caught "
00321 "(NoParachute is not set)." ) ;
00322
00323 if ( flags & UseEventThread )
00324 res.push_back( "Event thread requested (UseEventThread is set)." ) ;
00325 else
00326 res.push_back( "No event thread requested "
00327 "(UseEventThread is not set)." ) ;
00328
00329
00330 return "The specified flags for Common module, whose value is "
00331 + Ceylan::toString( flags, true )
00332 + ", mean : " + Ceylan::formatStringList( res ) ;
00333
00334 }
00335
00336
00337 bool CommonModule::hasVideoModule() const throw()
00338 {
00339 return ( _video != 0 ) ;
00340 }
00341
00342
00343 Video::VideoModule & CommonModule::getVideoModule() const
00344 throw( OSDL::Exception )
00345 {
00346
00347 if ( _video == 0 )
00348 throw OSDL::Exception(
00349 "CommonModule::getVideoModule : no video module available." ) ;
00350
00351 return * _video ;
00352
00353 }
00354
00355
00356
00357 bool CommonModule::hasEventsModule() const throw()
00358 {
00359 return ( _events != 0 ) ;
00360 }
00361
00362
00363 Events::EventsModule & CommonModule::getEventsModule() const
00364 throw( OSDL::Exception )
00365 {
00366
00367 if ( _events == 0 )
00368 throw OSDL::Exception(
00369 "CommonModule::getEventsModule : no events module available." ) ;
00370
00371 return * _events ;
00372
00373 }
00374
00375
00376
00377 bool CommonModule::hasAudioModule() const throw()
00378 {
00379 return ( _audio != 0 ) ;
00380 }
00381
00382
00383 Audio::AudioModule & CommonModule::getAudioModule() const
00384 throw( OSDL::Exception )
00385 {
00386
00387 if ( _audio == 0 )
00388 throw OSDL::Exception(
00389 "CommonModule::getAudioModule : no audio module available." ) ;
00390
00391 return * _audio ;
00392
00393 }
00394
00395
00396
00397 Flags CommonModule::getFlags() const throw()
00398 {
00399 return _flags ;
00400 }
00401
00402
00403
00404 bool CommonModule::hasCDROMDriveHandler() const throw()
00405 {
00406 return ( _cdromHandler != 0 ) ;
00407 }
00408
00409
00410 CDROMDriveHandler & CommonModule::getCDROMDriveHandler()
00411 const throw( OSDL::Exception )
00412 {
00413
00414 if ( _cdromHandler == 0 )
00415 throw OSDL::Exception( "CommonModule::getCDROMDriveHandler : "
00416 "no CD-ROM handler available." ) ;
00417
00418 return * _cdromHandler ;
00419
00420 }
00421
00422
00423 const string CommonModule::toString( Ceylan::VerbosityLevels level )
00424 const throw()
00425 {
00426
00427 string res = "Common root module, with currently video module " ;
00428
00429 if ( _video != 0 )
00430 res += "enabled" ;
00431 else
00432 res += "disabled" ;
00433
00434 res += ", with event module " ;
00435
00436 if ( _events != 0 )
00437 res += "enabled" ;
00438 else
00439 res += "disabled" ;
00440
00441 res += ", with audio module " ;
00442
00443 if ( _audio != 0 )
00444 res += "enabled" ;
00445 else
00446 res += "disabled" ;
00447
00448 res += ", using " ;
00449
00450 if ( _cdromHandler != 0 )
00451 res += "a" ;
00452 else
00453 res += "no" ;
00454
00455 res += " CD-ROM handler" ;
00456
00457 if ( level == Ceylan::low )
00458 return res ;
00459
00460
00461 res += ". " + InterpretFlags( _flags ) ;
00462
00463 if ( level == Ceylan::medium )
00464 return res ;
00465
00466 std::list<string> completeMessage ;
00467
00468 completeMessage.push_back( res ) ;
00469
00470 completeMessage.push_back( Ceylan::Module::toString() ) ;
00471
00472 completeMessage.push_back(
00473 "The version of the Ceylan library currently linked is "
00474 + Ceylan::GetVersion().toString() + "." ) ;
00475
00476 completeMessage.push_back(
00477 "The version of the OSDL library currently linked is "
00478 + OSDL::GetVersion().toString() + "." ) ;
00479
00480 return Ceylan::formatStringList( completeMessage ) ;
00481
00482 }
00483
00484
00485 string CommonModule::DescribeEnvironmentVariables() throw()
00486 {
00487
00488 Ceylan::Uint16 varCount = sizeof( _SDLEnvironmentVariables )
00489 / sizeof (char * ) ;
00490
00491 string result = "Examining the " + Ceylan::toString( varCount )
00492 + " general-purpose environment variables for SDL backend :" ;
00493
00494 std::list<string> variables ;
00495
00496 string var, value ;
00497
00498 bool htmlFormat = Ceylan::TextDisplayable::GetOutputFormat() ;
00499
00500 for ( Ceylan::Uint16 i = 0; i < varCount; i++ )
00501 {
00502
00503 var = _SDLEnvironmentVariables[ i ] ;
00504 value = Ceylan::System::getEnvironmentVariable( var ) ;
00505
00506 if ( value.empty() )
00507 {
00508 if ( htmlFormat == Ceylan::TextDisplayable::html )
00509 {
00510 variables.push_back( "<em>" + var + "</em> is not set." ) ;
00511 }
00512 else
00513 {
00514 variables.push_back( var + " is not set." ) ;
00515 }
00516 }
00517 else
00518 {
00519 if ( htmlFormat == Ceylan::TextDisplayable::html )
00520 {
00521 variables.push_back( "<b>" + var + "</b> set to ["
00522 + value + "]." ) ;
00523 }
00524 else
00525 {
00526 variables.push_back( var + " set to [" + value + "]." ) ;
00527 }
00528 }
00529
00530 }
00531
00532 return result + Ceylan::formatStringList( variables ) ;
00533
00534 }
00535
00536
00537 bool CommonModule::IsBackendInitialized() throw()
00538 {
00539
00540 return _BackendInitialized ;
00541
00542 }
00543
00544
00545 Flags CommonModule::AutoCorrectFlags( Flags inputFlags ) throw()
00546 {
00547
00548
00549
00550
00551
00552
00553
00554
00555 if ( ! ( inputFlags & UseVideo ) )
00556 {
00557
00558
00559
00560 if ( inputFlags & ( UseJoystick | UseKeyboard | UseMouse ) )
00561 {
00562
00563
00564
00565
00566
00567
00568
00569 LogPlug::warning( "CommonModule::AutoCorrectFlags : "
00570 "at least one input device was selected, "
00571 "hence event support was requested, "
00572 "whereas video was not specifically set. "
00573 "Since the event loop needs video, "
00574 "the video subsystem has been automatically enabled." ) ;
00575
00576 inputFlags |= UseVideo ;
00577
00578 }
00579
00580 }
00581
00582 return inputFlags ;
00583
00584 }
00585
00586
00587
00588
00589
00590
00591 CommonModule & OSDL::getCommonModule( Flags flags ) throw()
00592 {
00593
00594
00595 flags = CommonModule::AutoCorrectFlags( flags ) ;
00596
00597 LogPlug::info( "Retrieving basic common module for OSDL" ) ;
00598
00599 if ( CommonModule::_CurrentCommonModule == 0 )
00600 {
00601
00602
00603 LogPlug::info(
00604 "OSDL was not running yet, launching basic OSDL with flags "
00605 + Ceylan::toString( flags, true ) ) ;
00606 CommonModule::_CurrentCommonModule = new CommonModule( flags ) ;
00607 return * CommonModule::_CurrentCommonModule ;
00608
00609 }
00610 else
00611 {
00612
00613
00614 LogPlug::info( "OSDL is already running, comparing demanded flags "
00615 "with flags of the running version." ) ;
00616
00617 if ( flags == CommonModule::_CurrentCommonModule->getFlags() )
00618 {
00619
00620
00621
00622
00623
00624
00625
00626 LogPlug::info( "Flags are matching, "
00627 "returning already launched basic OSDL module" ) ;
00628
00629 return * CommonModule::_CurrentCommonModule ;
00630
00631 }
00632 else
00633 {
00634
00635
00636
00637
00638
00639
00640 LogPlug::info( "Flags do not match, "
00641 "stopping already launched OSDL root module, "
00642 "restarting with new flags, returning this new instance" ) ;
00643
00644 delete CommonModule::_CurrentCommonModule ;
00645
00646 CommonModule::_CurrentCommonModule = new CommonModule( flags ) ;
00647
00648 return * CommonModule::_CurrentCommonModule ;
00649
00650 }
00651 }
00652
00653 }
00654
00655
00656 bool OSDL::hasExistingCommonModule() throw()
00657 {
00658
00659 return ( CommonModule::_CurrentCommonModule != 0 ) ;
00660
00661 }
00662
00663
00664 CommonModule & OSDL::getExistingCommonModule() throw()
00665 {
00666
00667 if ( CommonModule::_CurrentCommonModule == 0 )
00668 Ceylan::emergencyShutdown(
00669 "OSDL::getExistingCommonModule : no common module available." ) ;
00670
00671 return * CommonModule::_CurrentCommonModule ;
00672
00673 }
00674
00675
00676 void OSDL::stop() throw()
00677 {
00678
00679 if ( CommonModule::_CurrentCommonModule == 0 )
00680 {
00681 LogPlug::error(
00682 "OSDL::stop has been called whereas OSDL was not running" ) ;
00683 }
00684 else
00685 {
00686 LogPlug::info( "Stopping launched OSDL module" ) ;
00687 delete CommonModule::_CurrentCommonModule ;
00688 CommonModule::_CurrentCommonModule = 0 ;
00689 }
00690
00691 }
00692