00001 #include "OSDLVideo.h"
00002
00003 #include "OSDLImage.h"
00004 #include "OSDLSurface.h"
00005 #include "OSDLVideoRenderer.h"
00006 #include "OSDLUtils.h"
00007 #include "OSDLBasic.h"
00008
00009
00010 #include "SDL.h"
00011
00012 #include <list>
00013 using std::list ;
00014
00015 using std::string ;
00016 using std::pair ;
00017
00018
00019 using namespace Ceylan ;
00020 using namespace Ceylan::Log ;
00021
00022 using namespace OSDL::Video ;
00023 using namespace OSDL::Video::OpenGL ;
00024
00025
00026
00027 #ifdef OSDL_USES_CONFIG_H
00028 #include <OSDLConfig.h>
00029 #endif // OSDL_USES_CONFIG_H
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 const Ceylan::Flags VideoModule::SoftwareSurface = SDL_SWSURFACE ;
00040 const Ceylan::Flags VideoModule::HardwareSurface = SDL_HWSURFACE ;
00041 const Ceylan::Flags VideoModule::AsynchronousBlit = SDL_ASYNCBLIT ;
00042 const Ceylan::Flags VideoModule::AnyPixelFormat = SDL_ANYFORMAT ;
00043 const Ceylan::Flags VideoModule::ExclusivePalette = SDL_HWPALETTE ;
00044 const Ceylan::Flags VideoModule::DoubleBuffered = SDL_DOUBLEBUF ;
00045 const Ceylan::Flags VideoModule::FullScreen = SDL_FULLSCREEN ;
00046 const Ceylan::Flags VideoModule::OpenGL = SDL_OPENGL ;
00047 const Ceylan::Flags VideoModule::Resizable = SDL_RESIZABLE ;
00048 const Ceylan::Flags VideoModule::NoFrame = SDL_NOFRAME ;
00049
00050 bool VideoModule::_IsUsingOpenGL = false ;
00051 bool VideoModule::_DrawEndPoint = false ;
00052 bool VideoModule::_AntiAliasing = true ;
00053
00054
00055 const Ceylan::Uint16 VideoModule::DriverNameMaximumLength = 50 ;
00056
00057 const BitsPerPixel VideoModule::UseCurrentColorDepth = 0 ;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00068 string VideoModule::_SDLEnvironmentVariables[] =
00069 {
00070
00071 "SDL_FBACCEL",
00072 "SDL_FBDEV",
00073 "SDL_FULLSCREEN_UPDATE",
00074 "SDL_VIDEODRIVER",
00075 "SDL_VIDEO_CENTERED",
00076 "SDL_VIDEO_GL_DRIVER",
00077 "SDL_VIDEO_X11_DGAMOUSE",
00078 "SDL_VIDEO_X11_MOUSEACCEL",
00079 "SDL_VIDEO_X11_NODIRECTCOLOR",
00080 "SDL_VIDEO_X11_VISUALID",
00081 "SDL_VIDEO_YUV_DIRECT",
00082 "SDL_VIDEO_YUV_HWACCEL",
00083 "SDL_WINDOWID"
00084
00085 } ;
00086
00087
00088
00089 VideoModule::VideoModule() throw( VideoException ) :
00090 Ceylan::Module(
00091 "OSDL video module",
00092 "This is the root video module of OSDL",
00093 "http:
00094 "Olivier Boudeville",
00095 "olivier.boudeville@online.fr",
00096 OSDL::GetVersion(),
00097 "LGPL" ),
00098 _screen( 0 ),
00099 _displayInitialized( false ),
00100 _renderer( 0 ),
00101 _frameAccountingState( false ),
00102 _openGLcontext( 0 ),
00103 _drawEndPoint( false ),
00104 _antiAliasing( true )
00105 {
00106
00107 send( "Initializing video subsystem." ) ;
00108
00109 if ( SDL_InitSubSystem( CommonModule::UseVideo )
00110 != CommonModule::BackendSuccess )
00111 throw VideoException( "VideoModule constructor : "
00112 "unable to initialize video subsystem : "
00113 + Utils::getBackendLastError() ) ;
00114
00115 send( "Video subsystem initialized." ) ;
00116
00117 dropIdentifier() ;
00118
00119 }
00120
00121
00122
00123 VideoModule::~VideoModule() throw()
00124 {
00125
00126 send( "Stopping video subsystem." ) ;
00127
00128 if ( _openGLcontext != 0 )
00129 delete _openGLcontext ;
00130
00131 if ( _renderer != 0 )
00132 delete _renderer ;
00133
00134
00135 if ( _screen != 0 )
00136 delete _screen ;
00137
00138 SDL_QuitSubSystem( CommonModule::UseVideo ) ;
00139
00140 send( "Video subsystem stopped." ) ;
00141
00142 }
00143
00144
00145
00146 bool VideoModule::hasScreenSurface() const throw()
00147 {
00148
00149 return ( _screen != 0 ) ;
00150
00151 }
00152
00153
00154 Surface & VideoModule::getScreenSurface() const throw ( VideoException )
00155 {
00156
00157 if ( _screen == 0 )
00158 throw VideoException( "VideoModule::getScreenSurface : "
00159 "no available screen surface." ) ;
00160
00161 return * _screen ;
00162
00163 }
00164
00165
00166 void VideoModule::setScreenSurface( Surface & newScreenSurface )
00167 throw( VideoException )
00168 {
00169
00170 send( "Setting screen surface to " + newScreenSurface.toString(), 8 ) ;
00171
00172 if ( _screen->getDisplayType() == Surface::BackBuffer )
00173 throw VideoException(
00174 "VideoModule::setScreenSurface : from its display type, "
00175 "specified surface is not a screen surface" ) ;
00176
00177 _screen = & newScreenSurface ;
00178
00179 }
00180
00181
00182
00183 bool VideoModule::hasRenderer() const throw()
00184 {
00185 return ( _renderer != 0 ) ;
00186 }
00187
00188
00189 OSDL::Rendering::VideoRenderer & VideoModule::getRenderer() const
00190 throw( VideoException )
00191 {
00192
00193 if ( _renderer == 0 )
00194 throw VideoException(
00195 "VideoModule::getRenderer : no video renderer available." ) ;
00196
00197 return * _renderer ;
00198
00199 }
00200
00201
00202 void VideoModule::setRenderer( Rendering::VideoRenderer & newRenderer ) throw()
00203 {
00204
00205 if ( _renderer != 0 )
00206 delete _renderer ;
00207
00208 _renderer = & newRenderer ;
00209
00210 }
00211
00212
00213
00214 bool VideoModule::hasOpenGLContext() const throw()
00215 {
00216
00217 return ( _openGLcontext != 0 ) ;
00218
00219 }
00220
00221
00222 OpenGL::OpenGLContext & VideoModule::getOpenGLContext() const
00223 throw( VideoException )
00224 {
00225
00226 if ( _openGLcontext == 0 )
00227 throw VideoException(
00228 "VideoModule::getOpenGLContext : no OpenGL context available." ) ;
00229
00230 return * _openGLcontext ;
00231
00232 }
00233
00234
00235 void VideoModule::setOpenGLContext( OpenGL::OpenGLContext & newOpenGLContext )
00236 throw()
00237 {
00238
00239 if ( _openGLcontext != 0 )
00240 delete _openGLcontext ;
00241
00242 _openGLcontext = & newOpenGLContext ;
00243
00244 _IsUsingOpenGL = true ;
00245
00246 }
00247
00248
00249
00250
00251 BitsPerPixel VideoModule::getBestColorDepthForMode(
00252 Length width, Length height, BitsPerPixel askedBpp, Flags flags ) throw()
00253 {
00254
00255 return SDL_VideoModeOK( width, height, askedBpp, flags ) ;
00256
00257 }
00258
00259
00260
00261 bool VideoModule::isDisplayInitialized() const throw()
00262 {
00263
00264 return _displayInitialized ;
00265
00266 }
00267
00268
00269
00270 Ceylan::Flags VideoModule::setMode( Length width, Length height,
00271 BitsPerPixel askedBpp, Flags flags, OpenGL::Flavour flavour )
00272 throw ( VideoException )
00273 {
00274
00275 _displayInitialized = false ;
00276
00277 Flags userFlags = flags ;
00278
00279 send( "Trying to set "
00280 + Ceylan::toString( width ) + 'x'
00281 + Ceylan::toString( height ) + " video mode, with "
00282 + ( ( askedBpp == 0 ) ?
00283 string( "current screen color depth" ) :
00284 Ceylan::toString( static_cast<Ceylan::Uint16>( askedBpp ) )
00285 + " bits per pixel)" )
00286 + ", with user-defined flags. " + InterpretFlags( flags )
00287 + "The " + OpenGLContext::ToString( flavour )
00288 + " flavour is selected" ) ;
00289
00290
00291 if ( ( flags & OpenGL == 0 ) && ( flavour != OpenGL::None ) )
00292 {
00293 LogPlug::warning( "VideoModule::setMode : OpenGL flavour selected ("
00294 + OpenGLContext::ToString( flavour )
00295 + ") whereas OpenGL flag not set, adding it." ) ;
00296 flags |= OpenGL ;
00297 }
00298
00299 bool useOpenGLRequested = ( ( flags & OpenGL ) != 0 ) ;
00300
00301 if ( userFlags != flags )
00302 send( "Initializing the display with following modified flags. "
00303 + InterpretFlags( flags ) ) ;
00304 else
00305 send( "Initializing the display with unchanged user flags") ;
00306
00307 SDL_Surface * screen = SDL_SetVideoMode( width, height, askedBpp, flags ) ;
00308
00309 if ( screen == 0 )
00310 throw VideoException( "Could not set "
00311 + Ceylan::toString( width ) + 'x'
00312 + Ceylan::toString( height ) + 'x'
00313 + Ceylan::toString( askedBpp )
00314 + " with flags " + Ceylan::toString( flags, true )
00315 + " video mode : " + Utils::getBackendLastError() ) ;
00316
00317
00318
00319
00320
00321
00322
00323 switch ( flavour )
00324 {
00325
00326 case OpenGL::None:
00327 if ( useOpenGLRequested )
00328 {
00329 if ( ! hasOpenGLContext() )
00330 setOpenGLContext( * new OpenGLContext( flavour ) ) ;
00331 else
00332 _openGLcontext->selectFlavour( flavour ) ;
00333 }
00334 break ;
00335
00336 case OpenGL::OpenGLFor2D:
00337 if ( ! hasOpenGLContext() )
00338 setOpenGLContext( * new OpenGLContext( flavour ) ) ;
00339 else
00340 _openGLcontext->selectFlavour( flavour ) ;
00341 break ;
00342
00343 case OpenGL::OpenGLFor3D:
00344 if ( ! hasOpenGLContext() )
00345 setOpenGLContext( * new OpenGLContext( flavour ) ) ;
00346 else
00347 _openGLcontext->selectFlavour( flavour ) ;
00348 break ;
00349
00350 case OpenGL::Reload:
00351 if ( hasOpenGLContext() )
00352 _openGLcontext->reload() ;
00353 else
00354 throw VideoException( "VideoModule::setMode : "
00355 "reload flavour selected whereas "
00356 "no OpenGL context was set, nothing done." ) ;
00357 break ;
00358
00359 default:
00360 throw VideoException( "VideoModule::setMode : "
00361 + OpenGLContext::ToString( flavour ) + " flavour selected." ) ;
00362 break ;
00363
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 if ( useOpenGLRequested && ( flags & DoubleBuffered ) )
00380 {
00381
00382 _openGLcontext->setDoubleBufferStatus( true ) ;
00383
00384
00385
00386
00387
00388
00389
00390 flags &= ~ DoubleBuffered ;
00391
00392 }
00393
00394
00395 if ( useOpenGLRequested )
00396 {
00397 _screen = new Video::Surface( * screen,
00398 Surface::OpenGLScreenSurface ) ;
00399 }
00400 else
00401 {
00402 _screen = new Video::Surface( * screen,
00403 Surface::ClassicalScreenSurface ) ;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 if ( useOpenGLRequested )
00416 _openGLcontext->setViewPort( _screen->getWidth(),
00417 _screen->getHeight() ) ;
00418
00419
00420
00421 int bpp = _screen->getBitsPerPixel() ;
00422
00423 send( "Actual color depth is " + Ceylan::toString( bpp )
00424 + " bits per pixel." ) ;
00425
00426
00427 if ( askedBpp != bpp && askedBpp != 0 )
00428 LogPlug::warning( "Color depth is " + Ceylan::toString( bpp )
00429 + " bits per pixel (instead of the asked "
00430 + Ceylan::toString( static_cast<Ceylan::Uint16>( askedBpp ) )
00431 + " bits per pixel)." ) ;
00432
00433 _displayInitialized = true ;
00434
00435 send( "After display creation, interpreting actually obtained surface : "
00436 + _screen->toString()
00437 + "The corresponding pixel format for this screen surface is : "
00438 + Pixels::toString( _screen->getPixelFormat() ) ) ;
00439
00440 if ( _openGLcontext != 0 )
00441 send( "Current OpenGL context : " + _openGLcontext->toString() ) ;
00442
00443 return _screen->getFlags() ;
00444
00445 }
00446
00447
00448 void VideoModule::resize( Length newWidth, Length newHeight )
00449 throw( VideoException )
00450 {
00451
00452 send( "Resizing window to (" + Ceylan::toString( newWidth ) + ", "
00453 + Ceylan::toString( newHeight ) + ")." ) ;
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 if ( _screen == 0 )
00464 throw VideoException(
00465 "VideoModule::resize : video mode was not set." ) ;
00466
00467 if ( ( _openGLcontext != 0 ) && OpenGLContext::ContextIsLostOnResize )
00468 setMode( newWidth, newHeight, _screen->getBitsPerPixel(),
00469 _screen->getFlags(), OpenGL::Reload ) ;
00470 else
00471 setMode( newWidth, newHeight, _screen->getBitsPerPixel(),
00472 _screen->getFlags(), OpenGL::None ) ;
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 }
00483
00484
00485 void VideoModule::redraw() throw( VideoException )
00486 {
00487
00488 if ( _screen == 0 )
00489 throw VideoException(
00490 "VideoModule::redraw : video mode was not set." ) ;
00491
00492
00493
00494
00495
00496
00497
00498
00499 _screen->redraw() ;
00500
00501 }
00502
00503
00504 void VideoModule::toggleFullscreen() throw( VideoException )
00505 {
00506
00507 if ( _screen == 0 )
00508 throw VideoException(
00509 "VideoModule::toggleFullscreen : video mode was not set." ) ;
00510
00511 if ( SDL_WM_ToggleFullScreen( & _screen->getSDLSurface() ) == 0 )
00512 throw VideoException( "VideoModule::toggleFullscreen failed : "
00513 + Utils::getBackendLastError() ) ;
00514
00515 }
00516
00517
00518
00519 bool VideoModule::getEndPointDrawState() const throw()
00520 {
00521
00522 return _drawEndPoint ;
00523
00524 }
00525
00526
00527 void VideoModule::setEndPointDrawState( bool newState ) throw()
00528 {
00529
00530 _drawEndPoint = newState ;
00531
00532
00533 _DrawEndPoint = newState ;
00534
00535 }
00536
00537
00538
00539 bool VideoModule::getAntiAliasingState() const throw()
00540 {
00541
00542 return _antiAliasing ;
00543
00544 }
00545
00546
00547 void VideoModule::setAntiAliasingState( bool newState ) throw()
00548 {
00549
00550 _antiAliasing = newState ;
00551
00552
00553 _AntiAliasing = newState ;
00554
00555 }
00556
00557
00558 const std::string VideoModule::getDriverName() const throw()
00559 {
00560
00561 char driverName[ VideoModule::DriverNameMaximumLength + 1 ] ;
00562
00563 if ( SDL_VideoDriverName( driverName, sizeof( driverName ) ) == 0 )
00564 throw VideoException( "Video::getDriverName failed : "
00565 "video was probably not initialized." ) ;
00566
00567 return std::string( driverName ) ;
00568
00569 }
00570
00571
00572 void VideoModule::setWindowCaption( const string & newTitle,
00573 const string & newIconName ) throw()
00574 {
00575
00576 SDL_WM_SetCaption( newTitle.c_str(), newIconName.c_str() ) ;
00577
00578 }
00579
00580
00581 void VideoModule::getWindowCaption( string & title, string & iconName ) throw()
00582 {
00583
00584 char newTitle[ 50 ] ;
00585 char newIconName[ 50 ] ;
00586
00587 SDL_WM_GetCaption(
00588 reinterpret_cast<char **>( & newTitle ),
00589 reinterpret_cast<char **>( & newIconName ) ) ;
00590
00591 title = newTitle ;
00592 iconName = newIconName ;
00593
00594 }
00595
00596
00597 void VideoModule::setWindowIcon( const std::string & filename )
00598 throw( VideoException )
00599 {
00600
00601 if ( isDisplayInitialized() )
00602 throw VideoException( "VideoModule::setWindowIcon called whereas "
00603 "display was already initialized "
00604 "(VideoModule::setMode was already called)." ) ;
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 Pixels::ColorElement * mask ;
00623
00624 Surface * iconSurface ;
00625
00626 try
00627 {
00628 iconSurface = & TwoDimensional::Image::LoadIcon( filename, & mask ) ;
00629 }
00630 catch( const TwoDimensional::ImageException & e )
00631 {
00632 throw VideoException( "VideoModule::setWindowIcon : "
00633 + e.toString() ) ;
00634 }
00635
00636 LogPlug::debug( "Setting icon now" ) ;
00637
00638 SDL_WM_SetIcon( & iconSurface->getSDLSurface(), mask ) ;
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 }
00650
00651
00652 bool VideoModule::iconifyWindow() throw()
00653 {
00654
00655 return ( SDL_WM_IconifyWindow() != 0 ) ;
00656
00657 }
00658
00659
00660
00661 bool VideoModule::getFrameAccountingState() throw()
00662 {
00663
00664 return _frameAccountingState ;
00665
00666 }
00667
00668
00669 void VideoModule::setFrameAccountingState( bool newState ) throw()
00670 {
00671
00672 _frameAccountingState = newState ;
00673
00674 }
00675
00676
00677 bool VideoModule::isUsingOpenGL() const throw()
00678 {
00679
00680 return hasOpenGLContext() ;
00681
00682 }
00683
00684
00685 const string VideoModule::toString( Ceylan::VerbosityLevels level )
00686 const throw()
00687 {
00688
00689 string res = "Video module, " ;
00690
00691 if ( _screen == 0 )
00692 res += "no video mode set, " ;
00693 else
00694 res += "video mode set, " ;
00695
00696 if ( _renderer == 0 )
00697 res += "no video renderer set, " ;
00698 else
00699 res += "a video renderer is set, " ;
00700
00701 if ( _openGLcontext == 0 )
00702 res += "no available OpenGL context" ;
00703 else
00704 res += "an OpenGL context is available" ;
00705
00706 if ( level == Ceylan::low )
00707 return res ;
00708
00709 res += Ceylan::Module::toString() ;
00710
00711 if ( _screen != 0 )
00712 res += " Screen surface information : "
00713 + _screen->toString( level ) ;
00714
00715 if ( _renderer != 0 )
00716 res += ". Internal renderer : "
00717 + _renderer->toString( level ) ;
00718
00719 if ( _openGLcontext != 0 )
00720 res += ". Current OpenGL context : "
00721 + _openGLcontext->toString( level ) ;
00722
00723 return res ;
00724
00725 }
00726
00727
00728
00729
00730
00731
00732
00733
00734 bool VideoModule::IsDisplayInitialized() throw()
00735 {
00736
00737
00738
00739
00740
00741
00742
00743 if ( ! OSDL::hasExistingCommonModule() )
00744 return false ;
00745
00746
00747 CommonModule & common = OSDL::getExistingCommonModule() ;
00748
00749 if ( ! common.hasVideoModule() )
00750 return false ;
00751
00752 VideoModule & video = common.getVideoModule() ;
00753
00754 return video.isDisplayInitialized() ;
00755
00756 }
00757
00758
00759 bool VideoModule::GetEndPointDrawState() throw()
00760 {
00761
00762 #if OSDL_CACHE_OVERALL_SETTINGS
00763
00764 return _DrawEndPoint ;
00765
00766 #else // OSDL_CACHE_OVERALL_SETTINGS
00767
00768
00769
00770 if ( ! OSDL::hasExistingCommonModule() )
00771 Ceylan::emergencyShutdown(
00772 "VideoModule::GetEndPointDrawState() called "
00773 "whereas no common module available." ) ;
00774
00775
00776 CommonModule & common = OSDL::getExistingCommonModule() ;
00777
00778 if ( ! common.hasVideoModule() )
00779 Ceylan::emergencyShutdown(
00780 "VideoModule::GetEndPointDrawState() called "
00781 "whereas no video module available." ) ;
00782
00783 VideoModule & video = common.getVideoModule() ;
00784
00785 #if OSDL_DEBUG_CACHED_STATES
00786
00787 bool realState = video.getEndPointDrawState() ;
00788
00789 if ( realState != _DrawEndPoint )
00790 Ceylan::emergencyShutdown(
00791 "VideoModule::GetEndPointDrawState() inconsistency detected : "
00792 "cached value should have been "
00793 + Ceylan::toString( realState ) + "." ) ;
00794
00795 return realState ;
00796
00797 #else // OSDL_DEBUG_CACHED_STATES
00798
00799 return video.getEndPointDrawState() ;
00800
00801 #endif // OSDL_DEBUG_CACHED_STATES
00802
00803 #endif // OSDL_CACHE_OVERALL_SETTINGS
00804
00805 }
00806
00807
00808 bool VideoModule::GetAntiAliasingState() throw()
00809 {
00810
00811 #if OSDL_CACHE_OVERALL_SETTINGS
00812
00813 return _AntiAliasing ;
00814
00815 #else // OSDL_CACHE_OVERALL_SETTINGS
00816
00817 if ( ! OSDL::hasExistingCommonModule() )
00818 Ceylan::emergencyShutdown(
00819 "VideoModule::GetAntiAliasingState() called "
00820 "whereas no common module available." ) ;
00821
00822
00823 CommonModule & common = OSDL::getExistingCommonModule() ;
00824
00825 if ( ! common.hasVideoModule() )
00826 Ceylan::emergencyShutdown(
00827 "VideoModule::GetAntiAliasingState() called "
00828 "whereas no video module available." ) ;
00829
00830 VideoModule & video = common.getVideoModule() ;
00831
00832 #if OSDL_DEBUG_CACHED_STATES
00833
00834 bool realState = video.getAntiAliasingState() ;
00835
00836 if ( realState != _AntiAliasing )
00837 Ceylan::emergencyShutdown(
00838 "VideoModule::GetAntiAliasingState() inconsistency detected : "
00839 "cached value should have been "
00840 + Ceylan::toString( realState ) + "." ) ;
00841
00842 return realState ;
00843
00844 #else // OSDL_DEBUG_CACHED_STATES
00845
00846 return video.getAntiAliasingState() ;
00847
00848 #endif // OSDL_DEBUG_CACHED_STATES
00849
00850 #endif // OSDL_CACHE_OVERALL_SETTINGS
00851
00852 }
00853
00854
00855
00856 const string VideoModule::GetDriverName() throw()
00857 {
00858
00859 char driverName[ VideoModule::DriverNameMaximumLength + 1 ] ;
00860
00861 if ( SDL_VideoDriverName( driverName, sizeof( driverName ) ) == 0 )
00862 throw VideoException( "Video::GetDriverName failed : "
00863 "video was probably not initialized." ) ;
00864
00865 return std::string( driverName ) ;
00866
00867 }
00868
00869
00870 string VideoModule::InterpretFlags( Flags flags ) throw()
00871 {
00872
00873 std::list<string> res ;
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892 if ( flags & HardwareSurface )
00893 res.push_back(
00894 "Display surface requested to be created in video memory "
00895 "(HardwareSurface is set)." ) ;
00896 else
00897 res.push_back(
00898 "Display surface not requested to be created in video memory "
00899 "(HardwareSurface not set)." ) ;
00900
00901 if ( flags & AsynchronousBlit )
00902 res.push_back(
00903 "Use, if possible, asynchronous updates of the display surface "
00904 "(AsynchronousBlit is set)." ) ;
00905 else
00906 res.push_back(
00907 "Do not use asynchronous blits (AsynchronousBlit not set)." ) ;
00908
00909 if ( flags & AnyPixelFormat )
00910 res.push_back(
00911 "Display surface should use the available video surface, "
00912 "regardless of its pixel depth (AnyPixelFormat is set)." ) ;
00913 else
00914 res.push_back(
00915 "Display surface will emulate, thanks to a shadow surface, "
00916 "the specified bit-per-pixel mode if not available "
00917 "(AnyPixelFormat not set)." ) ;
00918
00919 if ( flags & ExclusivePalette )
00920 res.push_back(
00921 "Display surface is given exclusive palette access, "
00922 "in order to always have the requested colors "
00923 "(ExclusivePalette is set)." ) ;
00924 else
00925 res.push_back(
00926 "Display surface is not required to have exclusive palette access, "
00927 "some colors might be different from the requested ones "
00928 "(ExclusivePalette not set)." ) ;
00929
00930 if ( flags & DoubleBuffered )
00931 res.push_back(
00932 "Enable hardware double buffering, "
00933 "only valid with display surface in video memory "
00934 "and without OpenGL (DoubleBuffered is set)." ) ;
00935 else
00936 res.push_back( "No hardware double buffering requested, or OpenGL used "
00937 "(DoubleBuffered not set)." ) ;
00938
00939 if ( flags & FullScreen )
00940 res.push_back(
00941 "Display surface should attempt to use full screen mode. "
00942 "If a hardware resolution change is not possible "
00943 "(for whatever reason), the next higher resolution "
00944 "will be used and the display window centered "
00945 "on a black background (FullScreen is set)." ) ;
00946 else
00947 res.push_back(
00948 "No full screen mode requested (FullScreen not set)." ) ;
00949
00950 if ( flags & OpenGL )
00951 res.push_back(
00952 "Display surface should have an OpenGL rendering context, "
00953 "whose video attributes should already have been set "
00954 "(OpenGL is set)." ) ;
00955 else
00956 res.push_back(
00957 "Display surface is not requested to have an OpenGL context "
00958 "(OpenGL not set)." ) ;
00959
00960
00961
00962 if ( flags & SDL_OPENGLBLIT )
00963 res.push_back(
00964 "Display surface should have an OpenGL rendering context, "
00965 "and will allow normal blitting operations. "
00966 "This SDL_OPENGLBLIT flag is deprecated and "
00967 "should not be used for new applications." ) ;
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977 if ( flags & Resizable )
00978 res.push_back( "Requests a resizable window (Resizable is set)." ) ;
00979 else
00980 res.push_back( "No resizable window requested (Resizable not set)." ) ;
00981
00982 if ( flags & NoFrame )
00983 res.push_back(
00984 "Requests creation of a window with no title bar or "
00985 "frame decoration (NoFrame is set)" ) ;
00986 else
00987 res.push_back(
00988 "Title bar and frame decoration allowed for display window "
00989 "(NoFrame not set)." ) ;
00990
00991 return "The specified display surface mode flags, whose value is "
00992 + Ceylan::toString( flags, true )
00993 + ", mean : " + Ceylan::formatStringList( res ) ;
00994
00995 }
00996
00997
00998
00999 bool VideoModule::HardwareSurfacesCanBeCreated() throw( VideoException )
01000 {
01001
01002 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01003
01004 if ( videoInfo == 0 )
01005 throw( "VideoModule::HardwareSurfacesCanBeCreated : "
01006 "unable to retrieve video informations." ) ;
01007
01008 return static_cast<bool>( videoInfo->hw_available ) ;
01009
01010 }
01011
01012
01013 bool VideoModule::WindowManagerAvailable() throw( VideoException )
01014 {
01015
01016 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01017
01018 if ( videoInfo == 0 )
01019 throw( "VideoModule::WindowManagerAvailable : "
01020 "unable to retrieve video informations." ) ;
01021
01022 return static_cast<bool>( videoInfo->wm_available ) ;
01023
01024 }
01025
01026
01027 bool VideoModule::HardwareToHardwareBlitsAccelerated() throw( VideoException )
01028 {
01029
01030 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01031
01032 if ( videoInfo == 0 )
01033 throw( "VideoModule::HardwareToHardwareBlitsAccelerated : "
01034 "unable to retrieve video informations." ) ;
01035
01036 return static_cast<bool>( videoInfo->blit_hw ) ;
01037
01038 }
01039
01040
01041 bool VideoModule::HardwareToHardwareColorkeyBlitsAccelerated()
01042 throw( VideoException )
01043 {
01044
01045 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01046
01047 if ( videoInfo == 0 )
01048 throw( "VideoModule::HardwareToHardwareColorkeyBlitsAccelerated : "
01049 "unable to retrieve video informations." ) ;
01050
01051 return static_cast<bool>( videoInfo->blit_hw_CC ) ;
01052
01053 }
01054
01055
01056 bool VideoModule::HardwareToHardwareAlphaBlitsAccelerated()
01057 throw( VideoException )
01058 {
01059
01060 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01061
01062 if ( videoInfo == 0 )
01063 throw( "VideoModule::HardwareToHardwareAlphaBlitsAccelerated : "
01064 "unable to retrieve video informations." ) ;
01065
01066 return static_cast<bool>( videoInfo->blit_hw_A ) ;
01067
01068 }
01069
01070
01071 bool VideoModule::SoftwareToHardwareBlitsAccelerated() throw( VideoException )
01072 {
01073
01074 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01075
01076 if ( videoInfo == 0 )
01077 throw( "VideoModule::SoftwareToHardwareBlitsAccelerated : "
01078 "unable to retrieve video informations." ) ;
01079
01080 return static_cast<bool>( videoInfo->blit_sw ) ;
01081
01082 }
01083
01084
01085 bool VideoModule::SoftwareToHardwareColorkeyBlitsAccelerated()
01086 throw( VideoException )
01087 {
01088
01089 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01090
01091 if ( videoInfo == 0 )
01092 throw( "VideoModule::SoftwareToHardwareColorkeyBlitsAccelerated : "
01093 "unable to retrieve video informations." ) ;
01094
01095 return static_cast<bool>( videoInfo->blit_sw_CC ) ;
01096
01097 }
01098
01099
01100 bool VideoModule::SoftwareToHardwareAlphaBlitsAccelerated()
01101 throw( VideoException )
01102 {
01103
01104 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01105
01106 if ( videoInfo == 0 )
01107 throw( "VideoModule::SoftwareToHardwareAlphaBlitsAccelerated : "
01108 "unable to retrieve video informations." ) ;
01109
01110 return static_cast<bool>( videoInfo->blit_sw_A ) ;
01111
01112 }
01113
01114
01115 bool VideoModule::ColorFillsAccelerated() throw( VideoException )
01116 {
01117
01118 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01119
01120 if ( videoInfo == 0 )
01121 throw( "VideoModule::ColorFillsAccelerated : "
01122 "unable to retrieve video informations." ) ;
01123
01124 return static_cast<bool>( videoInfo->blit_fill ) ;
01125
01126 }
01127
01128
01129 Ceylan::Uint32 VideoModule::GetVideoMemorySize() throw( VideoException )
01130 {
01131
01132 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01133
01134 if ( videoInfo == 0 )
01135 throw( "VideoModule::GetVideoMemorySize : "
01136 "unable to retrieve video informations." ) ;
01137
01138 return static_cast<Ceylan::Uint32>( videoInfo->video_mem ) ;
01139
01140 }
01141
01142
01143 Pixels::PixelFormat VideoModule::GetVideoDevicePixelFormat()
01144 throw( VideoException )
01145 {
01146
01147 const SDL_VideoInfo * videoInfo = SDL_GetVideoInfo() ;
01148
01149 if ( videoInfo == 0 )
01150 throw( "VideoModule::GetVideoDevicePixelFormat : "
01151 "unable to retrieve video informations." ) ;
01152
01153 return * static_cast<Pixels::PixelFormat *>( videoInfo->vfmt ) ;
01154
01155 }
01156
01157
01158 string VideoModule::DescribeVideoCapabilities() throw( VideoException )
01159 {
01160
01161 string result ;
01162
01163 try
01164 {
01165 result = "Video device capabilities for "
01166 + Ceylan::Network::getMostPreciseLocalHostName()
01167 + " are :" ;
01168 }
01169 catch ( const Ceylan::Network::NetworkException & e )
01170 {
01171 LogPlug::error( "VideoModule::getVideoCapabilities : "
01172 "error when retrieving host name : "
01173 + e.toString() ) ;
01174 result = "Video device capabilities are :" ;
01175
01176 }
01177
01178 std::list<string> l ;
01179
01180 if ( HardwareSurfacesCanBeCreated() )
01181 l.push_back( "Hardware surfaces can be created." ) ;
01182 else
01183 l.push_back( "Only software surfaces can be created." ) ;
01184
01185 if ( WindowManagerAvailable() )
01186 l.push_back( "A window manager is available." ) ;
01187 else
01188 l.push_back( "No window manager available." ) ;
01189
01190
01191
01192 if ( HardwareToHardwareBlitsAccelerated() )
01193 l.push_back( "Hardware to hardware blits are accelerated." ) ;
01194 else
01195 l.push_back( "No hardware to hardware blit acceleration available." ) ;
01196
01197
01198 if ( HardwareToHardwareColorkeyBlitsAccelerated() )
01199 l.push_back( "Hardware to hardware colorkey blits are accelerated." ) ;
01200 else
01201 l.push_back(
01202 "No hardware to hardware colorkey blit acceleration available." ) ;
01203
01204
01205 if ( HardwareToHardwareAlphaBlitsAccelerated() )
01206 l.push_back( "Hardware to hardware alpha blits are accelerated." ) ;
01207 else
01208 l.push_back(
01209 "No hardware to hardware alpha blit acceleration available." ) ;
01210
01211
01212
01213 if ( SoftwareToHardwareBlitsAccelerated() )
01214 l.push_back( "Software to hardware blits are accelerated." ) ;
01215 else
01216 l.push_back(
01217 "No software to hardware blit acceleration available." ) ;
01218
01219
01220 if ( SoftwareToHardwareColorkeyBlitsAccelerated() )
01221 l.push_back( "Software to hardware colorkey blits are accelerated." ) ;
01222 else
01223 l.push_back(
01224 "No software to hardware colorkey blit acceleration available." ) ;
01225
01226
01227 if ( SoftwareToHardwareAlphaBlitsAccelerated() )
01228 l.push_back( "Software to hardware alpha blits are accelerated." ) ;
01229 else
01230 l.push_back(
01231 "No software to hardware alpha blit acceleration available." ) ;
01232
01233
01234
01235 if ( ColorFillsAccelerated() )
01236 l.push_back( "Color fills are accelerated." ) ;
01237 else
01238 l.push_back( "No color fill acceleration available." ) ;
01239
01240
01241 if ( GetVideoMemorySize() )
01242 l.push_back( "Total amount of video memory is "
01243 + Ceylan::toString( GetVideoMemorySize() ) + " kilobytes." ) ;
01244 else
01245 l.push_back( "Unable to get total amount of video memory." ) ;
01246
01247 l.push_back( Pixels::toString( GetVideoDevicePixelFormat() ) ) ;
01248
01249
01250 return result + Ceylan::formatStringList( l ) ;
01251
01252 }
01253
01254
01255 bool VideoModule::AreDefinitionsRestricted( list<Definition> & definitions,
01256 Flags flags, Pixels::PixelFormat * pixelFormat ) throw()
01257 {
01258
01259 SDL_Rect ** modes ;
01260
01261 #if OSDL_DEBUG_VIDEO
01262 LogPlug::trace( "VideoModule::AreDefinitionsRestricted : "
01263 "getting available modes.", 8 ) ;
01264 #endif // OSDL_DEBUG_VIDEO
01265
01266 modes = SDL_ListModes( pixelFormat, flags ) ;
01267
01268 if ( reinterpret_cast<int>( modes ) == 0 )
01269 {
01270 LogPlug::debug( "No screen dimensions available for format "
01271 + Pixels::toString( * pixelFormat ) + " !" ) ;
01272
01273
01274 return true ;
01275
01276 }
01277
01278
01279
01280
01281 if ( reinterpret_cast<int>( modes ) == -1 )
01282 {
01283
01284
01285 return false ;
01286
01287 }
01288
01289
01290
01291 for ( Ceylan::Uint16 i = 0 ; modes[ i ] ; i++)
01292 {
01293 definitions.push_back( pair<Length, Length>(
01294 modes[ i ]->w, modes[ i ]->h ) ) ;
01295 }
01296
01297 return true ;
01298
01299 }
01300
01301
01302 string VideoModule::DescribeAvailableDefinitions( Flags flags,
01303 Pixels::PixelFormat * pixelFormat ) throw()
01304 {
01305
01306 list<Definition> defList ;
01307
01308 #if OSDL_DEBUG_VIDEO
01309 LogPlug::trace( "VideoModule::DescribeAvailableDefinitions : "
01310 "getting available modes.", 8 ) ;
01311 #endif // OSDL_DEBUG_VIDEO
01312
01313
01314
01315 if ( ! AreDefinitionsRestricted( defList, flags, pixelFormat ) )
01316 {
01317
01318 if ( pixelFormat == 0 )
01319 return "All screen dimensions are supported for "
01320 "the best possible video mode" ;
01321 else
01322 return "All screen dimensions are supported for "
01323 "the given pixel format" ;
01324
01325 }
01326 else
01327 {
01328
01329 if ( defList.empty() )
01330 {
01331 return "No screen dimension available for "
01332 "specified format and flags" ;
01333 }
01334 else
01335 {
01336
01337 string result ;
01338
01339 list<string> l ;
01340
01341
01342
01343 if ( pixelFormat == 0 )
01344 result = "Screen dimensions supported for "
01345 "the best possible video mode are :" ;
01346 else
01347 result = "Screen dimensions supported for "
01348 "the given pixel format are :" ;
01349
01350 for ( list<Definition>::const_iterator it = defList.begin();
01351 it != defList.end(); it++ )
01352 {
01353 l.push_back( Ceylan::toString( (*it).first )
01354 + 'x' + Ceylan::toString( (*it).second ) ) ;
01355 }
01356
01357 return result + Ceylan::formatStringList( l ) ;
01358
01359 }
01360
01361 }
01362
01363 }
01364
01365
01366 string VideoModule::DescribeEnvironmentVariables() throw()
01367 {
01368
01369 Ceylan::Uint16 varCount =
01370 sizeof( _SDLEnvironmentVariables ) / sizeof (char * ) ;
01371
01372 string result = "Examining the " + Ceylan::toString( varCount )
01373 + " video-related environment variables for SDL backend :" ;
01374
01375 list<string> variables ;
01376
01377 string var, value ;
01378
01379 bool htmlFormat = Ceylan::TextDisplayable::GetOutputFormat() ;
01380
01381 for ( Ceylan::Uint16 i = 0; i < varCount; i++ )
01382 {
01383
01384 var = _SDLEnvironmentVariables[ i ] ;
01385 value = Ceylan::System::getEnvironmentVariable( var ) ;
01386
01387 if ( value.empty() )
01388 {
01389 if ( htmlFormat == TextDisplayable::html )
01390 {
01391 variables.push_back( "<em>" + var + "</em> is not set." ) ;
01392 }
01393 else
01394 {
01395 variables.push_back( var + " is not set." ) ;
01396 }
01397 }
01398 else
01399 {
01400 if ( htmlFormat == TextDisplayable::html )
01401 {
01402 variables.push_back( "<b>" + var + "</b> set to ["
01403 + value + "]." ) ;
01404 }
01405 else
01406 {
01407 variables.push_back( var + " set to [" + value + "]." ) ;
01408 }
01409 }
01410
01411 }
01412
01413 return result + Ceylan::formatStringList( variables ) ;
01414
01415 }
01416