glXPipe.cpp

00001 
00002 /* Copyright (c) 2005-2009, Stefan Eilemann <eile@equalizergraphics.com>
00003                           , Makhinya Maxim
00004  *
00005  * This library is free software; you can redistribute it and/or modify it under
00006  * the terms of the GNU Lesser General Public License version 2.1 as published
00007  * by the Free Software Foundation.
00008  *  
00009  * This library is distributed in the hope that it will be useful, but WITHOUT
00010  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00012  * details.
00013  * 
00014  * You should have received a copy of the GNU Lesser General Public License
00015  * along with this library; if not, write to the Free Software Foundation, Inc.,
00016  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00017  */
00018 
00019 #include "glXPipe.h"
00020 
00021 #include "glXEventHandler.h"
00022 #include "global.h"
00023 #include "log.h"
00024 #include "pipe.h"
00025 
00026 #include <sstream>
00027 
00028 using namespace eq::base;
00029 using namespace std;
00030 
00031 namespace eq
00032 {
00033 
00034 GLXPipe::GLXPipe( Pipe* parent )
00035         : OSPipe( parent )
00036         , _xDisplay( 0 )
00037         , _eventHandler( 0 )
00038 {
00039 }
00040 
00041 GLXPipe::~GLXPipe( )
00042 {
00043 }
00044 
00045 //---------------------------------------------------------------------------
00046 // GLX init
00047 //---------------------------------------------------------------------------
00048 bool GLXPipe::configInit( )
00049 {
00050 #ifdef GLX
00051     const std::string displayName  = _getXDisplayString();
00052     const char*       cDisplayName = ( displayName.length() == 0 ? 
00053                                        0 : displayName.c_str( ));
00054     Display*          xDisplay     = XOpenDisplay( cDisplayName );
00055             
00056     if( !xDisplay )
00057     {
00058         ostringstream msg;
00059         msg << "Can't open display: " << XDisplayName( displayName.c_str( ));
00060         setErrorMessage( msg.str( ));
00061         return false;
00062     }
00063 
00064     _setXDisplay( xDisplay );
00065     EQINFO << "Opened X display " << xDisplay << ", device "
00066            << _pipe->getDevice() << endl;
00067     return true;
00068 #else
00069     setErrorMessage( "Client library compiled without GLX support" );
00070     return false;
00071 #endif
00072 }
00073 
00074 
00075 void GLXPipe::configExit()
00076 {
00077 #ifdef GLX
00078     Display* xDisplay = getXDisplay();
00079     if( !xDisplay )
00080         return;
00081 
00082     _setXDisplay( 0 );
00083     XCloseDisplay( xDisplay );
00084     EQINFO << "Closed X display " << xDisplay << endl;
00085 #endif
00086 }
00087 
00088 
00089 std::string GLXPipe::_getXDisplayString()
00090 {
00091     ostringstream  stringStream;
00092     
00093     const uint32_t port   = _pipe->getPort();
00094     const uint32_t device = _pipe->getDevice();
00095 
00096     if( port != EQ_UNDEFINED_UINT32 )
00097     { 
00098         if( device == EQ_UNDEFINED_UINT32 )
00099             stringStream << ":" << port;
00100         else
00101             stringStream << ":" << port << "." << device;
00102     }
00103     else if( device != EQ_UNDEFINED_UINT32 )
00104         stringStream << ":0." << device;
00105     else if( !getenv( "DISPLAY" ))
00106         stringStream <<  ":0";
00107 
00108     return stringStream.str();
00109 }
00110 
00111 
00112 void GLXPipe::_setXDisplay( Display* display )
00113 {
00114 #ifdef GLX
00115     if( _xDisplay == display )
00116         return;
00117 
00118     if( _xDisplay )
00119         exitEventHandler();
00120     _xDisplay = display; 
00121 
00122     if( display )
00123     {
00124         initEventHandler();
00125 #ifndef NDEBUG
00126         // somewhat reduntant since it is a global handler
00127         XSetErrorHandler( eq::GLXPipe::XErrorHandler );
00128 #endif
00129 
00130         string       displayString = DisplayString( display );
00131         const size_t colonPos      = displayString.find( ':' );
00132         if( colonPos != string::npos )
00133         {
00134             const string displayNumberString = displayString.substr(colonPos+1);
00135             const uint32_t displayNumber = atoi( displayNumberString.c_str( ));
00136             const uint32_t port          = _pipe->getPort();
00137             const uint32_t device        = _pipe->getDevice();
00138             
00139             if( port != EQ_UNDEFINED_UINT32 && displayNumber != port )
00140                 EQWARN << "Display mismatch: provided display connection uses"
00141                    << " display " << displayNumber
00142                    << ", but pipe has port " << port << endl;
00143 
00144             if( device != EQ_UNDEFINED_UINT32 &&
00145                 DefaultScreen( display ) != (int)device )
00146                 
00147                 EQWARN << "Screen mismatch: provided display connection uses"
00148                        << " default screen " << DefaultScreen( display ) 
00149                        << ", but pipe has screen " << device << endl;
00150             
00151             //port = displayNumber;
00152             //device  = DefaultScreen( display );
00153         }
00154     }
00155 
00156     PixelViewport pvp = _pipe->getPixelViewport();
00157     if( pvp.isValid( ))
00158         return;
00159 
00160     if( display )
00161     {
00162         pvp.x    = 0;
00163         pvp.y    = 0;
00164         pvp.w = DisplayWidth(  display, DefaultScreen( display ));
00165         pvp.h = DisplayHeight( display, DefaultScreen( display ));
00166     }
00167     else
00168         pvp.invalidate();
00169 
00170     _pipe->setPixelViewport( pvp );
00171 #endif
00172 }
00173 
00174 
00175 int GLXPipe::XErrorHandler( Display* display, XErrorEvent* event )
00176 {
00177 #ifdef GLX
00178     EQERROR << disableFlush;
00179     EQERROR << "X Error occured: " << disableHeader << indent;
00180 
00181     char buffer[256];
00182     XGetErrorText( display, event->error_code, buffer, 256);
00183 
00184     EQERROR << buffer << endl;
00185     EQERROR << "Major opcode: " << (int)event->request_code << endl;
00186     EQERROR << "Minor opcode: " << (int)event->minor_code << endl;
00187     EQERROR << "Error code: " << (int)event->error_code << endl;
00188     EQERROR << "Request serial: " << event->serial << endl;
00189     EQERROR << "Current serial: " << NextRequest( display ) - 1 << endl;
00190 
00191     switch( event->error_code )
00192     {
00193         case BadValue:
00194             EQERROR << "  Value: " << event->resourceid << endl;
00195             break;
00196 
00197         case BadAtom:
00198             EQERROR << "  AtomID: " << event->resourceid << endl;
00199             break;
00200 
00201         default:
00202             EQERROR << "  ResourceID: " << event->resourceid << endl;
00203             break;
00204     }
00205     EQERROR << enableFlush << exdent << enableHeader;
00206 
00207 #ifndef NDEBUG
00208     if( getenv( "EQ_ABORT_WAIT" ))
00209     {
00210         EQERROR << "Caught X Error, entering infinite loop for debugging" 
00211                 << endl;
00212         while( true ) ;
00213     }
00214 #endif
00215 
00216 #endif // GLX
00217 
00218     return 0;
00219 }
00220 
00221 void GLXPipe::initEventHandler()
00222 {
00223     EQASSERT( !_eventHandler );
00224     _eventHandler = new GLXEventHandler( this );
00225 }
00226 
00227 void GLXPipe::exitEventHandler()
00228 {
00229     delete _eventHandler;
00230     _eventHandler = 0;
00231 }
00232 
00233 
00234 }
Generated on Mon Aug 10 18:58:39 2009 for Equalizer 0.9 by  doxygen 1.5.8