OSDLVideo.cc

Go to the documentation of this file.
00001 #include "OSDLVideo.h"
00002 
00003 #include "OSDLImage.h"          // for ImageException
00004 #include "OSDLSurface.h"        // for Surface 
00005 #include "OSDLVideoRenderer.h"  // for VideoRenderer 
00006 #include "OSDLUtils.h"          // for getBackendLastError
00007 #include "OSDLBasic.h"          // for getExistingCommonModule, GetVersion, etc.
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>         // for OSDL_CACHE_OVERALL_SETTINGS and al 
00029 #endif // OSDL_USES_CONFIG_H
00030 
00031 
00032 /*
00033  * These flags can be used for all Surfaces <b>created by setMode</b>.
00034  *
00035  * @note They are defined relatively to SDL back-end, see SDL_video.h
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 /* @fixme Put elsewhere
00061 const Ceylan::Uint32 VideoModule::DelayBetweenFrameRateDisplay = 500 ;
00062 Point2D * VideoModule::FrameRateCounterOrigin
00063 PixelDefinition VideoModule::FrameRateCounterSpecifiedColor
00064 PixelColor VideoModule::FrameRateCounterActualColor
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://osdl.sourceforge.net",
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     // Back-end screen surface will not be deallocated here :
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, /* bit field */ true )
00315             + " video mode : " + Utils::getBackendLastError() ) ;
00316     
00317     
00318     /*
00319      * Initializes the flavours and the context since setMode has just 
00320      * been called :
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      * In all cases, if OpenGL is to be used, an OpenGL context is 
00369      * available here.
00370      *
00371      */
00372     
00373         
00374     /*
00375      * Never disable double buffering is a flavour selected it, but enable 
00376      * it if specified :
00377      *
00378      */
00379     if ( useOpenGLRequested && ( flags & DoubleBuffered ) )
00380     {
00381 
00382         _openGLcontext->setDoubleBufferStatus( true ) ;
00383         
00384         /*
00385          * Double buffering with OpenGL is not to be selected with the
00386          * DoubleBuffered flag for setMode, we therefore ensure it is
00387          * deactivated now :
00388          *
00389          */
00390         flags &= ~ DoubleBuffered ;
00391     
00392     }
00393     
00394     
00395     if ( useOpenGLRequested )
00396     {
00397         _screen = new Video::Surface( * screen, 
00398             /* display type */ Surface::OpenGLScreenSurface ) ;
00399     }       
00400     else
00401     {   
00402         _screen = new Video::Surface( * screen, 
00403             /* display type */ Surface::ClassicalScreenSurface ) ;
00404     }
00405     
00406     /*
00407      * Defines the viewport independently of flavours
00408      * (lower-left corner of the OpenGL viewport is the origin of the 
00409      * setMode window).
00410      *
00411      * By default, the viewport is chosen so that it takes all the display
00412      * window.
00413      *
00414      */
00415     if ( useOpenGLRequested ) 
00416         _openGLcontext->setViewPort( _screen->getWidth(), 
00417             _screen->getHeight() /* Origin */ ) ; 
00418         
00419 
00420     // Special case for OpenGL ?        
00421     int bpp = _screen->getBitsPerPixel() ;
00422     
00423     send( "Actual color depth is " + Ceylan::toString( bpp ) 
00424         + " bits per pixel." ) ;
00425     
00426     // A zero bit per pixel request means any depth, no warning in this case :
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     /* @fixme OpenGL : restore context (destroyed textures, glViewport etc.)
00457     if ( _renderer )
00458     {
00459         _renderer->unloadTextures() ;
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     /* @fixme Change viewport :
00476     if ( _renderer )
00477     {
00478         _renderer->viewPortResized( newWidth, newHeight ) ;
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     /* @fixme Change 
00493     if ( _renderer )
00494     {
00495         _renderer->redraw() ; or wait until next frame ?
00496     }
00497     else    
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     // Cached value :
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     // Cached value :
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      * The mask is a bitmask that describes the shape of the icon. 
00608      * - if mask is null (0), then the shape is determined by the
00609      * colorkey of icon, if any, or makes the icon rectangular 
00610      * (no transparency) otherwise.
00611      * - if mask is non-null (non 0), it has to point to a bitmap
00612      * with bits set where the corresponding pixel should be
00613      * visible. 
00614      * The format of the bitmap is as follows. 
00615      * Scanlines come in the usual top-down order. 
00616      * Each scanline consists of (width / 8) bytes, rounded up. 
00617      * The most significant bit of each byte represents the 
00618      * leftmost pixel.
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     // No error status available.
00640     
00641     /*
00642      * Do not know whether they can/should be freed :
00643      *
00644      * delete mask ;
00645      * delete iconSurface ;
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 // Static section.
00731 
00732 
00733 
00734 bool VideoModule::IsDisplayInitialized() throw()
00735 {
00736 
00737     /*
00738      * Display is initialized iff the video module says so, therefore 
00739      * video module and common module must (necessarily) already exist.
00740      *
00741      */
00742     
00743     if ( ! OSDL::hasExistingCommonModule() )
00744         return false ;
00745         
00746     // No exception should ever occur since already tested :    
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     // Retrieves the video module to read the actual official value :
00769     
00770     if ( ! OSDL::hasExistingCommonModule() )
00771         Ceylan::emergencyShutdown( 
00772             "VideoModule::GetEndPointDrawState() called "
00773             "whereas no common module available." ) ;
00774         
00775     // No exception should ever occur since already tested :    
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     // No exception should ever occur since already tested :    
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      * As the Software (SDL_SWSURFACE) flag is null (0), the test had no 
00877      * real meaning :
00878      *
00879      */
00880     
00881     /*
00882     if ( flags & SoftwareSurface )
00883         res.push_back( 
00884             "Video surface requested to be created in system memory "
00885             "(SoftwareSurface is set)." ) ;
00886     else
00887         res.push_back( 
00888             "Video surface not requested to be created in system memory "
00889             "(SoftwareSurface not set)." ) ;
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     // Deprecated flag :
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      * Not even try to advertise deprecated SDL_OPENGLBLIT :
00971      
00972     else
00973             res.push_back( "The deprecated SDL_OPENGLBLIT flag is not set "
00974                 "and this is how it should be." ) ;
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, /* bit field */ 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         // List stays empty, and restricted result is true : nothing available.
01274         return true ;
01275             
01276     }
01277 
01278     // From that point, at least one dimension will be available.    
01279     
01280     // Checking whether our resolution is restricted. 
01281     if ( reinterpret_cast<int>( modes ) == -1 ) 
01282     {
01283         
01284         // Any dimension is okay for the given format, not restricted :
01285         return false ;  
01286                     
01287     } 
01288 
01289     // In this last case, only a set of definitions is available :
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     // Checking whether there is any mode available. 
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 // definitions are restricted :
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             // Print valid modes.
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 

Generated on Fri Mar 30 14:47:00 2007 for OSDL by  doxygen 1.5.1