glXPipe.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
00152
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 }