DisplayManager.cpp

Go to the documentation of this file.
00001 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
00002  *
00003  * VR Juggler is (C) Copyright 1998-2005 by Iowa State University
00004  *
00005  * Original Authors:
00006  *   Allen Bierbaum, Christopher Just,
00007  *   Patrick Hartling, Kevin Meinert,
00008  *   Carolina Cruz-Neira, Albert Baker
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Library General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Library General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Library General Public
00021  * License along with this library; if not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00023  * Boston, MA 02111-1307, USA.
00024  *
00025  * -----------------------------------------------------------------
00026  * File:          $RCSfile$
00027  * Date modified: $Date: 2006-05-17 10:48:47 -0500 (Wed, 17 May 2006) $
00028  * Version:       $Revision: 18839 $
00029  * -----------------------------------------------------------------
00030  *
00031  *************** <auto-copyright.pl END do not edit this line> ***************/
00032 
00033 #include <vrj/vrjConfig.h>
00034 #include <boost/concept_check.hpp>
00035 #include <jccl/Config/ConfigElement.h>
00036 #include <jccl/RTRC/ConfigManager.h>
00037 #include <vrj/Display/Display.h>
00038 #include <vrj/Display/SurfaceViewport.h>
00039 #include <vrj/Display/SimViewport.h>
00040 #include <vrj/Draw/DrawManager.h>
00041 #include <vrj/Kernel/Kernel.h>
00042 #include <vrj/Display/DisplayManager.h>
00043 
00044 
00045 namespace vrj
00046 {
00047 
00048 //vjDisplayManager* DisplayManager::_instance = NULL;
00049 vprSingletonImp(DisplayManager);
00050 
00051 std::vector<Display*> DisplayManager::getAllDisplays()
00052 {
00053    std::vector<Display*> ret_val;
00054    ret_val.insert(ret_val.end(), mActiveDisplays.begin(), mActiveDisplays.end());
00055    ret_val.insert(ret_val.end(), mInactiveDisplays.begin(), mInactiveDisplays.end());
00056    return ret_val;
00057 }
00058 
00059 jccl::ConfigElementPtr DisplayManager::getDisplaySystemElement()
00060 {
00061    jccl::ConfigManager* cfg_mgr = jccl::ConfigManager::instance();
00062 
00063    if ( mDisplaySystemElement.get() == NULL )
00064    {
00065       cfg_mgr->lockActive();
00066       {
00067          std::vector<jccl::ConfigElementPtr>::iterator i;
00068          for (i = cfg_mgr->getActiveBegin() ; i != cfg_mgr->getActiveEnd() ; ++i)
00069          {
00070             if ( (*i)->getID() == std::string("display_system") )
00071             {
00072                mDisplaySystemElement = *i;
00073                break;         // This guarantees that we get the first displaySystem element.
00074             }
00075          }
00076       }
00077       cfg_mgr->unlockActive();
00078    }
00079 
00080    // XXX: We should never have to ask the pending list for the display_system element because
00081    //      it should always be loaded first, and already in the active list. If for some reason
00082    //      we have to look at the pending list it is possible to have a deadlock. This happens
00083    //      when we call DisplaySystem::getDisplaySystemElement() while we are configuring anything
00084    //      device in the system.
00085    // XXX: This could be fixed in the furute using better dependancy managment so that we can ensure
00086    //      that the display_system is always in the active list before configuring anythin that
00087    //      calls this function while getting configured.
00088 
00089    // If display_system element was not found in the active list.
00090    if ( mDisplaySystemElement.get() == NULL )
00091    {   
00092       cfg_mgr->lockPending();
00093       {
00094          std::list<jccl::ConfigManager::PendingElement>::iterator i;
00095          for (i = cfg_mgr->getPendingBegin() ; i != cfg_mgr->getPendingEnd() ; ++i)
00096          {
00097             if ( (*i).mElement->getID() == std::string("display_system") )
00098             {
00099                mDisplaySystemElement = (*i).mElement;
00100                break;         // This guarantees that we get the first displaySystem element.
00101             }
00102          }
00103       }
00104       cfg_mgr->unlockPending();
00105 //      vprASSERT(mDisplaySystemElement.get() != NULL && "No Display Manager config element found!");
00106    }
00107 
00108    return mDisplaySystemElement;
00109 }
00110 
00111 void DisplayManager::setDrawManager(DrawManager* drawMgr)
00112 {
00113    vprDEBUG(vrjDBG_DISP_MGR, vprDBG_STATE_LVL) << "vjDisplayManager: Setting draw manager.\n" << vprDEBUG_FLUSH;
00114 
00115    // set the draw manager
00116    mDrawManager = drawMgr;
00117 
00118    // Alert the draw manager about all the active windows currently configured
00119    if (mDrawManager != NULL)
00120    {
00121       for (unsigned int i=0;i<mActiveDisplays.size();i++)
00122       {
00123          mDrawManager->addDisplay(mActiveDisplays[i]);
00124       }
00125    }
00126 }
00127 
00132 bool DisplayManager::configAdd(jccl::ConfigElementPtr element)
00133 {
00134    vprASSERT(configCanHandle(element));
00135 
00136    const std::string element_type(element->getID());
00137 
00138    if ( (element_type == std::string("surfaceDisplay")) ||
00139         (element_type == std::string("simDisplay")) )
00140    {
00141       vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00142          << "Element of type: " << element_type
00143          << " is no longer supported.  Use display_window type instead.\n"
00144          << vprDEBUG_FLUSH;
00145       return false;
00146    }
00147    else if ( (element_type == std::string("display_window")))
00148    {
00149       return configAddDisplay(element);
00150    }
00151    else if (element_type == std::string("display_system"))
00152    {
00153       // XXX: Put signal here to tell draw manager to lookup new stuff
00154       mDisplaySystemElement = element; // Keep track of the display system element
00155       return true;                     // We successfully configured.
00156                                        // This tell processPending to add it to the active config
00157    }
00158 
00159    return false;
00160 }
00161 
00166 bool DisplayManager::configRemove(jccl::ConfigElementPtr element)
00167 {
00168    vprASSERT(configCanHandle(element));
00169 
00170    const std::string element_type(element->getID());
00171 
00172    if ( (element_type == std::string("surfaceDisplay")) ||
00173         (element_type == std::string("simDisplay")) )
00174    {
00175       vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00176          << "Element of type: " << element_type
00177          << " is no longer supported.  Use display_window type instead.\n"
00178          << vprDEBUG_FLUSH;
00179       return false;
00180    }
00181    else if (element_type == std::string("display_window"))
00182    {
00183       return configRemoveDisplay(element);
00184    }
00185    else if (element_type == std::string("display_system"))
00186    {
00187       // XXX: Put signal here to tell draw manager to lookup new stuff
00188       mDisplaySystemElement.reset();   // Keep track of the display system element
00189       return true;                     // We successfully configured.
00190                                        // This tell processPending to remove it to the active config
00191    }
00192    else
00193    {
00194       return false;
00195    }
00196 
00197 }
00198 
00199 
00205 bool DisplayManager::configCanHandle(jccl::ConfigElementPtr element)
00206 {
00207    return (    (element->getID() == std::string("surfaceDisplay"))
00208             || (element->getID() == std::string("simDisplay"))
00209             || (element->getID() == std::string("display_system"))
00210             || (element->getID() == std::string("display_window"))
00211            );
00212 }
00213 
00222 bool DisplayManager::configAddDisplay(jccl::ConfigElementPtr element)
00223 {
00224    vprASSERT(configCanHandle(element)); // We must be able to handle it first of all
00225 
00226    vprDEBUG_BEGIN(vrjDBG_DISP_MGR,vprDBG_STATE_LVL) << "------- DisplayManager::configAddDisplay -------\n" << vprDEBUG_FLUSH;
00227 
00228    // Find out if we already have a window of this name
00229    // If so, then close it before we open a new one of the same name
00230    // This basically allows re-configuration of a window
00231    Display* cur_disp = findDisplayNamed(element->getName());
00232    if (cur_disp != NULL)                         // We have an old display
00233    {
00234       vprDEBUG(vrjDBG_DISP_MGR,vprDBG_CONFIG_LVL) << "Removing old window: " << cur_disp->getName().c_str() << vprDEBUG_FLUSH;
00235       closeDisplay(cur_disp,true);              // Close the display and notify the draw manager to close the window
00236    }
00237 
00238    // --- Add a display (of the correct type) ---- //
00239    if (element->getID() == std::string("display_window"))       // Display window
00240    {
00241       Display* newDisp = new Display();        // Create the display
00242       newDisp->config(element);
00243       addDisplay(newDisp,true);                    // Add it
00244       vprDEBUG(vrjDBG_DISP_MGR,vprDBG_STATE_LVL) << "Adding display: " << newDisp->getName().c_str() << std::endl << vprDEBUG_FLUSH;
00245       vprDEBUG(vrjDBG_DISP_MGR,vprDBG_STATE_LVL) << "Display: "  << newDisp << std::endl << vprDEBUG_FLUSH;
00246    }
00247 
00248    vprDEBUG_END(vrjDBG_DISP_MGR,vprDBG_STATE_LVL) << "------- DisplayManager::configAddDisplay Done. --------\n" << vprDEBUG_FLUSH;
00249    return true;
00250 }
00251 
00258 bool DisplayManager::configRemoveDisplay(jccl::ConfigElementPtr element)
00259 {
00260    vprASSERT(configCanHandle(element)); // We must be able to handle it first of all
00261 
00262    vprDEBUG_BEGIN(vrjDBG_DISP_MGR,vprDBG_STATE_LVL) << "------- DisplayManager::configRemoveDisplay -------\n" << vprDEBUG_FLUSH;
00263 
00264    bool success_flag(false);
00265 
00266    if (element->getID() == std::string("display_window"))      // It is a display
00267    {
00268       Display* remove_disp = findDisplayNamed(element->getName());
00269       if (remove_disp != NULL)
00270       {
00271          closeDisplay(remove_disp, true);                            // Remove it
00272          success_flag = true;
00273       }
00274    }
00275 
00276    vprDEBUG_END(vrjDBG_DISP_MGR,vprDBG_STATE_LVL) << "------- DisplayManager::configRemoveDisplay done. --------\n" << vprDEBUG_FLUSH;
00277    return success_flag;
00278 }
00279 
00280 
00281 
00282 
00283 // notifyDrawMgr = 0; Defaults to 0
00284 int DisplayManager::addDisplay(Display* disp, bool notifyDrawMgr)
00285 {
00286    vprDEBUG(vrjDBG_DISP_MGR, vprDBG_VERB_LVL) << "vjDisplayManager::addDisplay \n" << vprDEBUG_FLUSH;
00287 
00288    // Test if active or not, to determine correct list
00289    // The place it in the list
00290    // --- Update Local Display structures
00291    if (disp->isActive())
00292    {
00293       mActiveDisplays.push_back(disp);
00294    }
00295    else
00296    {
00297       mInactiveDisplays.push_back(disp);
00298    }
00299 
00300    // If we are supposed to notify about, and valid draw mgr, and disp is active
00301    if ((notifyDrawMgr) && (mDrawManager != NULL) && (disp->isActive()))
00302    {
00303       mDrawManager->addDisplay(disp);;    // Tell Draw Manager to add dislay;
00304    }
00305 
00306    return 1;
00307 }
00308 
00317 int DisplayManager::closeDisplay(Display* disp, bool notifyDrawMgr)
00318 {
00319    vprASSERT(isMemberDisplay(disp));       // Make sure that display actually exists
00320 
00321    vprDEBUG(vrjDBG_DISP_MGR,vprDBG_STATE_LVL) << "closeDisplay: Closing display named: " << disp->getName() << std::endl<< vprDEBUG_FLUSH;
00322 
00323    // Notify the draw manager to get rid of it
00324    // Note: if it is not active, then the draw manager doesn't know about it
00325    if ((notifyDrawMgr) && (mDrawManager != NULL) && (disp->isActive()))
00326    {
00327       mDrawManager->removeDisplay(disp);
00328    }
00329 
00330    // Remove it from local data structures
00331    size_t num_before_close = mActiveDisplays.size() + mInactiveDisplays.size();
00332    mActiveDisplays.erase( std::remove(mActiveDisplays.begin(), mActiveDisplays.end(), disp),
00333                           mActiveDisplays.end());
00334    mInactiveDisplays.erase( std::remove(mInactiveDisplays.begin(), mInactiveDisplays.end(), disp),
00335                             mInactiveDisplays.end());
00336    vprASSERT(num_before_close == (1+mActiveDisplays.size() + mInactiveDisplays.size()));
00337    boost::ignore_unused_variable_warning(num_before_close);
00338 
00339    // Delete the object
00340    // XXX: Memory leak.  Can't delete display here because the draw manager
00341    //      may need access to it when the draw manager closes the window up.
00342    // ex: the glDrawManager window has ref to the display to get current user, etc.
00343    //XXX//delete disp;
00344 
00345    return 1;
00346 }
00347 
00348 
00349 // Is the display a member of the display manager
00350 bool DisplayManager::isMemberDisplay(Display* disp)
00351 {
00352    std::vector<Display*>::iterator i;
00353 
00354    i = std::find(mActiveDisplays.begin(),mActiveDisplays.end(),disp);
00355    if (i != mActiveDisplays.end())
00356    {
00357       return true;
00358    }
00359 
00360    i = std::find(mInactiveDisplays.begin(),mInactiveDisplays.end(),disp);
00361    if (i != mInactiveDisplays.end())
00362    {
00363       return true;
00364    }
00365 
00366    return false;  // Didn't find any
00367 }
00368 
00373 Display* DisplayManager::findDisplayNamed(std::string name)
00374 {
00375    std::vector<Display*>::iterator i;
00376 
00377    for (i = mActiveDisplays.begin();i!=mActiveDisplays.end();i++)
00378    {
00379       if ((*i)->getName() == name)
00380       {
00381          return (*i);
00382       }
00383    }
00384 
00385    for (i = mInactiveDisplays.begin();i!=mInactiveDisplays.end();i++)
00386    {
00387       if ((*i)->getName() == name)
00388       {
00389          return (*i);
00390       }
00391    }
00392 
00393    return NULL;  // Didn't find any
00394 }
00395 
00396 
00397 void DisplayManager::updateProjections(const float scaleFactor)
00398 {
00399    // for (all displays) update the projections
00400    for (std::vector<Display*>::iterator i = mActiveDisplays.begin();
00401         i != mActiveDisplays.end(); i++)
00402    {
00403       (*i)->updateProjections(scaleFactor);
00404    }
00405 
00406    for (std::vector<Display*>::iterator j = mInactiveDisplays.begin();
00407         j != mInactiveDisplays.end(); j++)
00408    {
00409       (*j)->updateProjections(scaleFactor);
00410    }
00411 }
00412 
00413 };

Generated on Thu Jan 4 10:56:51 2007 for VR Juggler by  doxygen 1.5.1