#include <vrj/Draw/OGL/GlWindowXWin.h>
Inheritance diagram for vrj::GlWindowXWin:


Public Member Functions | |
| GlWindowXWin () | |
| virtual | ~GlWindowXWin () |
| virtual void | swapBuffers () |
| Performs an OpenGL swap buffers command. | |
| virtual bool | open () |
| Opens the OpenGL window. | |
| virtual bool | close () |
| Closes the window given. | |
| bool | makeCurrent () |
| Sets the current OpenGL context to this window. | |
| virtual void | checkEvents () |
| Checks events. | |
| void | configWindow (vrj::Display *disp) |
| Configure the window settings based on the display information. | |
Protected Member Functions | |
| virtual void | processEvent (::XEvent event) |
| Do any extra event processing needed. | |
| XVisualInfo * | getGlxVisInfo (::Display *display, int screen) |
| void | createEmptyCursor (::Display *display,::Window root) |
Static Protected Member Functions | |
| static int | eventIsMapNotify (::Display *display, XEvent *e, XPointer window) |
| |
It holds all the information specific to dealing with a GLX window.
This class is responsbile for connecting to the X server, getting a GLX visual, opening a GL window and associated context, and handling all managment of that context.
Definition at line 74 of file GlWindowXWin.h.
| vrj::GlWindowXWin::GlWindowXWin | ( | ) |
Definition at line 70 of file GlWindowXWin.cpp.
References vrj::GlWindow::mWindowHeight, vrj::GlWindow::mWindowIsOpen, and vrj::GlWindow::mWindowWidth.
00071 : GlWindow() 00072 // , mXDisplay(NULL) 00073 , mVisualInfo(NULL) 00074 , mGlxContext(NULL) 00075 // , mXWindow(0) 00076 , mWindowName("") 00077 , mPipe(-1) 00078 , mXDisplayName(""), 00079 mEmptyCursorSet(false) 00080 { 00081 mWindowIsOpen = false; 00082 mWindowWidth = mWindowHeight = -1; 00083 00084 // XEvent processing is not blocking. 00085 mBlocking = false; 00086 }
| vrj::GlWindowXWin::~GlWindowXWin | ( | ) | [virtual] |
| void vrj::GlWindowXWin::swapBuffers | ( | ) | [virtual] |
Performs an OpenGL swap buffers command.
Reimplemented from vrj::GlWindow.
Definition at line 411 of file GlWindowXWin.cpp.
References vrj::GlWindow::swapBuffers().
00412 { 00413 GlWindow::swapBuffers(); 00414 glXSwapBuffers(mXDisplay, mXWindow); 00415 }
| bool vrj::GlWindowXWin::open | ( | ) | [virtual] |
Opens the OpenGL window.
Reimplemented from vrj::GlWindow.
Definition at line 93 of file GlWindowXWin.cpp.
References close(), createEmptyCursor(), vrj::MotifWmHints::decorations, eventIsMapNotify(), vrj::MotifWmHints::flags, getGlxVisInfo(), vrj::GlxExtensionLoader::glXBindSwapBarrierNV(), vrj::GlxExtensionLoader::glXJoinSwapGroupNV(), vrj::GlxExtensionLoader::glXQueryMaxSwapGroupsNV(), vrj::GlxExtensionLoader::hasSwapGroupNV(), makeCurrent(), vrj::GlWindow::mHasBorder, vrj::GlWindow::mHideMouse, vrj::GlWindow::mOriginX, vrj::GlWindow::mOriginY, vrj::GlWindow::mWindowHeight, vrj::GlWindow::mWindowIsOpen, vrj::GlWindow::mWindowWidth, MWM_HINTS_DECORATIONS, vrj::GlxExtensionLoader::registerExtensions(), and vrjDBG_DRAW_MGR().
00094 { 00095 /* attempts to open the glxWindow & create the gl context. Does nothing 00096 * if the window is already open (& returns true). 00097 * returns true for success, false for failure. 00098 * The newly opened window will be set as the calling proccess' 00099 * current gl context. 00100 */ 00101 00102 ::XEvent map_event; 00103 ::XSetWindowAttributes w_attrib; 00104 int screen; 00105 ::XSizeHints *sizehints; 00106 ::XClassHint *classhint; 00107 unsigned long event_mask(0); // Event masks to use 00108 bool ret_val(true); 00109 00110 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL) 00111 << "[vrj::GlWindowXWin::open()] Open window\n" << vprDEBUG_FLUSH; 00112 00113 if ( mWindowIsOpen ) 00114 { 00115 return true; 00116 } 00117 00118 if ( mWindowWidth == -1 ) 00119 { 00120 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL) 00121 << clrOutNORM(clrRED,"ERROR:") 00122 << " [vrj::GlWindowXWin::open()] Window has not been configured\n" 00123 << vprDEBUG_FLUSH; 00124 return false; 00125 } 00126 00127 if ( ! (mXDisplay = ::XOpenDisplay(mXDisplayName.c_str())) ) 00128 { 00129 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL) 00130 << clrOutNORM(clrRED,"ERROR:") 00131 << " [vrj::GlWindowXWin::open()] Unable to open display '" 00132 << mXDisplayName << "'.\n" << vprDEBUG_FLUSH; 00133 return false; 00134 } 00135 // Try initializing the window 00136 try 00137 { 00138 screen = DefaultScreen(mXDisplay); 00139 00140 // get an XVisualInfo*, which we'll need below 00141 if ( (mVisualInfo = getGlxVisInfo(mXDisplay, screen)) == NULL ) 00142 { 00143 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL) 00144 << clrOutNORM(clrRED,"ERROR:") << " Failed to get a GLX visual\n" 00145 << vprDEBUG_FLUSH; 00146 throw glwinx_OpenFailureException(); 00147 } 00148 00149 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00150 << "Visual ID: 0x" << std::hex << mVisualInfo->visualid << std::dec 00151 << std::endl << vprDEBUG_FLUSH; 00152 00153 // window attributes. 00154 w_attrib.colormap = ::XCreateColormap(mXDisplay, 00155 RootWindow(mXDisplay, screen), 00156 mVisualInfo->visual, 00157 AllocNone); 00158 00159 if ( w_attrib.colormap == 0 ) 00160 { 00161 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL) 00162 << clrOutNORM(clrRED,"ERROR:") 00163 << " vrj::GlWindowXWin: XCreateColorMap failed on '" 00164 << mXDisplayName << "'.\n" << vprDEBUG_FLUSH; 00165 throw glwinx_OpenFailureException(); 00166 } 00167 00168 event_mask = ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask | 00169 ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | 00170 PointerMotionMask | StructureNotifyMask; 00171 // event_mask = ExposureMask | StructureNotifyMask; // Don't request buttons or keys since that will be handled elsewhere 00172 w_attrib.event_mask = event_mask; 00173 w_attrib.border_pixel = 0x0; 00174 00175 // get screen dimensions for translating window origin. 00176 ::XWindowAttributes winattrs; 00177 ::XGetWindowAttributes(mXDisplay, RootWindow(mXDisplay, screen), 00178 &winattrs); 00179 00180 // create window 00181 mXWindow = ::XCreateWindow(mXDisplay, RootWindow(mXDisplay, screen), 00182 mOriginX, 00183 winattrs.height - mOriginY - mWindowHeight, 00184 mWindowWidth, mWindowHeight, 0, 00185 mVisualInfo->depth, InputOutput, 00186 mVisualInfo->visual, 00187 CWEventMask | CWColormap | CWBorderPixel, 00188 &w_attrib); 00189 00190 if ( 0 == mXWindow ) 00191 { 00192 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 00193 << clrOutNORM(clrRED,"ERROR:") 00194 << "vrj::GlWindowXWin: Couldn't create window for " << mXDisplayName 00195 << std::endl << vprDEBUG_FLUSH; 00196 throw glwinx_OpenFailureException(); 00197 } 00198 00199 createEmptyCursor(mXDisplay, mXWindow); 00200 /***************** Set Window Name/Class/Size/Pos *********************/ 00201 00202 /* Before we map the window, we need a name for it (this is also useful for 00203 * the resource cruft that'll get rid of the borders). 00204 */ 00205 classhint = ::XAllocClassHint(); 00206 classhint->res_name = (char*)mWindowName.c_str(); 00207 classhint->res_class = "VRJ GLX"; 00208 //XSetClassHint(mXDisplay, mXWindow, classhint); 00209 00210 // InSoc makes things simple 00211 // X makes things complicated 00212 ::XTextProperty w_name; 00213 ::XStringListToTextProperty(&(classhint->res_name), 1, &w_name); 00214 00215 /* guarantee window position */ 00216 sizehints = XAllocSizeHints(); 00217 sizehints->flags = USPosition; 00218 00219 ::XSetWMProperties(mXDisplay, mXWindow, &w_name, &w_name, 00220 NULL, 0, sizehints, NULL, classhint); 00221 00222 ::XFree(w_name.value); 00223 ::XFree(classhint); 00224 ::XFree(sizehints); 00225 00226 /***************** Border Stuff ***************************/ 00227 00228 /* Get rid of window border, if configured to do so. 00229 * This technique doesn't require any modifications to the .XDefaults file 00230 * or anything, but it will only work with window managers based on MWM 00231 * (the Motif window manager). That covers most cases. 00232 * Unfortunately, the generic X resources for communicating with a window 00233 * manager don't support this feature. 00234 */ 00235 if ( ! mHasBorder ) 00236 { 00237 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_HVERB_LVL) 00238 << "[vrj::GlWindowXWin::open()] Attempting to make window borderless" 00239 << std::endl << vprDEBUG_FLUSH; 00240 Atom MotifHints = XInternAtom(mXDisplay, "_MOTIF_WM_HINTS", 0); 00241 if ( MotifHints == None ) 00242 { 00243 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 00244 << clrOutNORM(clrRED,"ERROR:") 00245 << "vrj::GlWindowXWin: Could not get X atom for _MOTIF_WM_HINTS." 00246 << std::endl << vprDEBUG_FLUSH; 00247 } 00248 else 00249 { 00250 MotifWmHints hints; 00251 hints.flags = MWM_HINTS_DECORATIONS; 00252 hints.decorations = 0; 00253 XChangeProperty(mXDisplay, mXWindow, MotifHints, MotifHints, 32, 00254 PropModeReplace, (unsigned char *) &hints, 4); 00255 } 00256 } 00257 00258 /********************* Mapping Window **************************/ 00259 00260 /* Open the window, select the input events, and wait until mapped (XIfEvent) */ 00261 ::XSelectInput(mXDisplay, mXWindow, event_mask); 00262 ::XMapWindow(mXDisplay, mXWindow); 00263 ::XIfEvent(mXDisplay, &map_event, eventIsMapNotify, (XPointer)mXWindow); 00264 ::XSync(mXDisplay, 0); 00265 00266 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_VERB_LVL) << "vrj::GlWindowXWin: done mapping window\n" 00267 << vprDEBUG_FLUSH; 00268 00269 /********************* OpenGL Context Stuff *********************/ 00270 00271 mGlxContext = glXCreateContext(mXDisplay, mVisualInfo, NULL, True); 00272 if ( NULL == mGlxContext ) 00273 { 00274 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL) 00275 << clrOutNORM(clrRED,"ERROR:") << "Couldn't create GlxContext for '" 00276 << mXDisplayName << "'\n" << vprDEBUG_FLUSH; 00277 throw glwinx_OpenFailureException(); 00278 } 00279 00280 mWindowIsOpen = true; 00281 00282 if( mHideMouse ) 00283 { 00284 XDefineCursor(mXDisplay, mXWindow, mEmptyCursor); 00285 } 00286 00287 // ----------- Register this window with XEvent Device registry --------- // 00288 /* 00289 gadget::EventWindowXWin::WindowRegistry::WindowInfo xwin_info; 00290 xwin_info.displayName = mXDisplayName; 00291 xwin_info.xWindow = mXWindow; 00292 gadget::EventWindowXWin::WindowRegistry::instance()->addWindow(mVrjDisplay->getName(), xwin_info); 00293 */ 00294 00295 ret_val = true; 00296 } 00297 catch (glwinx_OpenFailureException& openFailed) 00298 { 00299 // close() is coincidentally safe to call on a partially-opened 00300 // GlWindowXWin, and will deallocate all the stuff we might have 00301 // allocated above. 00302 close(); 00303 00304 ret_val = false; 00305 } 00306 00307 // Register extensions in this window 00308 makeCurrent(); 00309 mExtensions.registerExtensions(); 00310 00311 // Check on using swap group 00312 jccl::ConfigElementPtr disp_sys_elt = 00313 DisplayManager::instance()->getDisplaySystemElement(); 00314 bool use_swap_group = disp_sys_elt->getProperty<bool>("use_swap_group"); 00315 00316 if ( use_swap_group ) 00317 { 00318 vprDEBUG_OutputGuard(vprDBG_ALL, vprDBG_CONFIG_STATUS_LVL, 00319 "Attempting to set up GLX swap group.\n", ""); 00320 00321 // Try NV swap group extension 00322 if(mExtensions.hasSwapGroupNV()) 00323 { 00324 vprDEBUG(vprDBG_ALL, vprDBG_CONFIG_STATUS_LVL) 00325 << "SwapGroupNV: " << mExtensions.hasSwapGroupNV() << std::endl 00326 << vprDEBUG_FLUSH; 00327 GLuint max_groups, max_barriers; 00328 mExtensions.glXQueryMaxSwapGroupsNV(mXDisplay, screen, &max_groups, 00329 &max_barriers); 00330 vprDEBUG(vprDBG_ALL, vprDBG_CONFIG_STATUS_LVL) 00331 << "Max groups: " << max_groups << " Max Barriers:" << max_barriers 00332 << std::endl << vprDEBUG_FLUSH; 00333 00334 vprDEBUG(vprDBG_ALL, vprDBG_CONFIG_STATUS_LVL) 00335 << "Setting up NV swap group and barrier group. " 00336 << "Group: 1, Barrier: 1\n" << vprDEBUG_FLUSH; 00337 // For now, just assume both groups are group 1 00338 // Note: In the future this code may need to be refactored to be 00339 // controlled from the GlPipe class since it is really the thing 00340 // that would correspond to the group and could group the correct 00341 // windows to a group id. 00342 mExtensions.glXJoinSwapGroupNV(mXDisplay, mXWindow, 1); 00343 mExtensions.glXBindSwapBarrierNV(mXDisplay, 1, 1); 00344 } 00345 else 00346 { 00347 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL) 00348 << "Could not detect any GLX extensions that support swap groups.\n" 00349 << vprDEBUG_FLUSH; 00350 vprDEBUG_NEXT(vprDBG_ALL, vprDBG_WARNING_LVL) 00351 << "Proceeding with no swap locking.\n" << vprDEBUG_FLUSH; 00352 } 00353 } 00354 00355 return ret_val; 00356 }
| bool vrj::GlWindowXWin::close | ( | ) | [virtual] |
Closes the window given.
Reimplemented from vrj::GlWindow.
Definition at line 362 of file GlWindowXWin.cpp.
References makeCurrent(), vrj::GlWindow::mIsEventSource, and vrj::GlWindow::mWindowIsOpen.
Referenced by open(), and ~GlWindowXWin().
00363 { 00364 00365 //vprASSERT( !mXfuncLock.test() && "Attempting to close a display window that is locked" ); 00366 // Assert that we have not impllemented correct shutdown for the case that we 00367 // are an event source as well 00368 //vprASSERT(!mIsEventSource && "Need to implement GLX window close with gadget::EventWindow"); 00369 00370 // Remove any event device from the input manager 00371 if ( true == mIsEventSource ) 00372 { 00373 gadget::Input* dev_ptr = dynamic_cast<gadget::Input*>(this); 00374 00375 // XXX: Possibly not the best way to remove this to input manager 00376 // - This will internally call stop sampling (and stupify and proxies) 00377 // Note: The stop sampling will not do anything since the event window does not own the window 00378 vrj::Kernel::instance()->getInputManager()->removeDevice(dev_ptr); 00379 } 00380 00381 if ( mGlxContext ) 00382 { 00383 makeCurrent(); // Might not need this 00384 //glFlush(); // This is done by the changing context 00385 glXMakeCurrent(mXDisplay, None, NULL); // Release the context, and don't assign a new one 00386 glXDestroyContext(mXDisplay, mGlxContext); 00387 mGlxContext = NULL; 00388 } 00389 if ( mXWindow ) 00390 { 00391 ::XDestroyWindow(mXDisplay, mXWindow); 00392 mXWindow = 0; 00393 } 00394 if ( mVisualInfo ) 00395 { 00396 ::XFree(mVisualInfo); 00397 mVisualInfo = NULL; 00398 } 00399 if ( mXDisplay ) 00400 { 00401 ::XCloseDisplay(mXDisplay); 00402 mXDisplay = NULL; 00403 } 00404 00405 mWindowIsOpen = false; // We are closed now 00406 00407 return true; 00408 00409 } /* close() */
| bool vrj::GlWindowXWin::makeCurrent | ( | ) | [virtual] |
Sets the current OpenGL context to this window.
Reimplemented from vrj::GlWindow.
Definition at line 417 of file GlWindowXWin.cpp.
References vrj::GlWindow::mWindowIsOpen.
Referenced by close(), and open().
00418 { 00419 /* returns true for success, 00420 * false for failure (eg window not open or glXMakeCurrent fails) 00421 */ 00422 if ( !mWindowIsOpen ) 00423 { 00424 return false; 00425 } 00426 00427 vprASSERT(mGlxContext != NULL); 00428 vprASSERT(mXWindow != 0); 00429 vprASSERT(mXDisplay != NULL); 00430 00431 return glXMakeCurrent(mXDisplay, mXWindow, mGlxContext); 00432 }
| void vrj::GlWindowXWin::checkEvents | ( | ) | [virtual] |
Checks events.
Processes window systems events each frame.
Reimplemented from vrj::GlWindow.
Definition at line 469 of file GlWindowXWin.cpp.
References vrj::GlWindow::mOriginX, vrj::GlWindow::mOriginY, vrj::GlWindow::setDirtyViewport(), and vrj::GlWindow::updateOriginSize().
00470 { 00471 // XXX: Move this all down sooner or later. 00472 if (NULL != mKeyboardMouseDevice) 00473 { 00474 handleEvents(); 00475 } 00476 else 00477 { 00478 XEvent event; 00479 00480 while( XPending(mXDisplay)) 00481 { 00482 XNextEvent(mXDisplay,&event); 00483 00484 switch ( event.type ) 00485 { 00486 case ConfigureNotify: 00487 updateOriginSize(vrj::GlWindow::mOriginX, vrj::GlWindow::mOriginY, 00488 event.xconfigure.width, event.xconfigure.height); 00489 vrj::GlWindow::setDirtyViewport(true); 00490 break; 00491 00492 default: 00493 break; 00494 } 00495 } 00496 } 00497 }
| void vrj::GlWindowXWin::configWindow | ( | vrj::Display * | disp | ) | [virtual] |
Configure the window settings based on the display information.
Reimplemented from vrj::GlWindow.
Definition at line 434 of file GlWindowXWin.cpp.
References vrj::GlWindow::configWindow(), vrj::Display::getConfigElement(), vrj::Display::getName(), vrj::Display::getPipe(), and vrjDBG_DRAW_MGR().
00435 { 00436 const char neg_one_string[] = "-1"; 00437 vrj::GlWindow::configWindow(disp); 00438 00439 // Get the vector of display elements. 00440 jccl::ConfigElementPtr disp_sys_elt = DisplayManager::instance()->getDisplaySystemElement(); 00441 jccl::ConfigElementPtr display_elt = disp->getConfigElement(); 00442 00443 // Get the lock and KeyboardMouseDevice information 00444 gadget::InputArea::config(display_elt); 00445 00446 mWindowName = disp->getName(); 00447 mPipe = disp->getPipe(); 00448 vprASSERT(mPipe >= 0); 00449 00450 // NOTE: ConfigElements return the default value for a property if a value is 00451 // not present. So if a pipe string is not specified for this pipe then 00452 // it gets the default value of "-1". 00453 mXDisplayName = disp_sys_elt->getProperty<std::string>("x11_pipes", mPipe); 00454 00455 if ( mXDisplayName == neg_one_string ) // Use display env 00456 { 00457 const std::string DISPLAY_str("DISPLAY"); // DISPLAY_str[] = "DISPLAY"; 00458 const char* d = getenv(DISPLAY_str.c_str()); 00459 if ( NULL != d ) 00460 { 00461 mXDisplayName = std::string( d ); 00462 } 00463 } 00464 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_VERB_LVL) 00465 << "[vrj::GlWindowXWin::config] Display name is '" << mXDisplayName 00466 << "'" << std::endl << vprDEBUG_FLUSH; 00467 }
| virtual void vrj::GlWindowXWin::processEvent | ( | ::XEvent | event | ) | [inline, protected, virtual] |
Do any extra event processing needed.
Definition at line 96 of file GlWindowXWin.h.
References vrj::GlWindow::mOriginX, vrj::GlWindow::mOriginY, vrj::GlWindow::setDirtyViewport(), and vrj::GlWindow::updateOriginSize().
00097 { 00098 switch ( event.type ) 00099 { 00100 case ConfigureNotify: 00101 updateOriginSize(vrj::GlWindow::mOriginX, vrj::GlWindow::mOriginY, 00102 event.xconfigure.width, event.xconfigure.height); 00103 vrj::GlWindow::setDirtyViewport(true); 00104 break; 00105 00106 default: 00107 break; 00108 } 00109 }
| XVisualInfo * vrj::GlWindowXWin::getGlxVisInfo | ( | ::Display * | display, | |
| int | screen | |||
| ) | [protected] |
Definition at line 502 of file GlWindowXWin.cpp.
References vrj::Display::getGlFrameBufferConfig(), vrj::Display::getName(), vrj::Display::isStereoRequested(), vrj::GlWindow::mInStereo, vrj::GlWindow::mVrjDisplay, and vrjDBG_DRAW_MGR().
Referenced by open().
00503 { 00504 /* pre: screen is a screen on the current XDisplay, and 00505 * XDisplay is already defined and valid. 00506 * post: returns a pointer to an XVisualInfo to be used for GLX. 00507 * Note that it doesn't necessarily have _all_ of the requested 00508 * features... it will attempt to get a visual in mono or 00509 * without alpha if it's virst attempts fail. 00510 * Returns NULL if it can't come up with a reasonably close 00511 * XVisualInfo, or if the display in question doesn't support 00512 * GLX 00513 */ 00514 00515 if ( !glXQueryExtension(display, NULL, NULL) ) 00516 { 00517 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL) 00518 << clrOutNORM(clrRED, "ERROR:") << " X Display '" << mXDisplayName 00519 << "' doesn't support GLX.\n" << vprDEBUG_FLUSH; 00520 return NULL; 00521 } 00522 00523 // Using 1 here requests the *largest* available size for each of these 00524 // buffers. Refer to the glXChooseVisual() manual page for more details. 00525 int visual_id(-1); 00526 int red_size(1), green_size(1), blue_size(1), alpha_size(1), db_size(1), 00527 accum_red_size(1), accum_green_size(1), accum_blue_size(1), 00528 accum_alpha_size(1), stencil_size(1); 00529 // glXChooseVisual() will return the visual with the smallest number of 00530 // auxiliary buffers that meets or exceeds the requested count. 00531 int num_aux_bufs(0); 00532 bool want_fsaa(false); 00533 00534 jccl::ConfigElementPtr gl_fb_elt = mVrjDisplay->getGlFrameBufferConfig(); 00535 00536 if ( gl_fb_elt.get() != NULL ) 00537 { 00538 if ( gl_fb_elt->getVersion() < 2 ) 00539 { 00540 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00541 << clrOutBOLD(clrYELLOW, "WARNING:") << " Display window '" 00542 << mVrjDisplay->getName() << "'" << std::endl; 00543 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00544 << "has an out of date OpenGL frame buffer configuration." 00545 << std::endl; 00546 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00547 << "Expected version 2 but found version " 00548 << gl_fb_elt->getVersion() << ".\n"; 00549 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00550 << "Default values will be used for some frame buffer settings.\n" 00551 << vprDEBUG_FLUSH; 00552 } 00553 00554 visual_id = gl_fb_elt->getProperty<int>("visual_id"); 00555 red_size = gl_fb_elt->getProperty<int>("red_size"); 00556 green_size = gl_fb_elt->getProperty<int>("green_size"); 00557 blue_size = gl_fb_elt->getProperty<int>("blue_size"); 00558 alpha_size = gl_fb_elt->getProperty<int>("alpha_size"); 00559 num_aux_bufs = gl_fb_elt->getProperty<int>("auxiliary_buffer_count"); 00560 db_size = gl_fb_elt->getProperty<int>("depth_buffer_size"); 00561 stencil_size = gl_fb_elt->getProperty<int>("stencil_buffer_size"); 00562 accum_red_size = gl_fb_elt->getProperty<int>("accum_red_size"); 00563 accum_green_size = gl_fb_elt->getProperty<int>("accum_green_size"); 00564 accum_blue_size = gl_fb_elt->getProperty<int>("accum_blue_size"); 00565 accum_alpha_size = gl_fb_elt->getProperty<int>("accum_alpha_size"); 00566 want_fsaa = gl_fb_elt->getProperty<bool>("fsaa_enable"); 00567 } 00568 00569 if ( visual_id != -1 ) 00570 { 00571 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00572 << "Requesting visual 0x" << std::hex << visual_id << std::dec 00573 << " from GLX." << std::endl << vprDEBUG_FLUSH; 00574 00575 XVisualInfo vinfo_template; 00576 long mask(VisualIDMask); 00577 int nitems; 00578 00579 vinfo_template.visualid = visual_id; 00580 00581 XVisualInfo* vi = XGetVisualInfo(display, mask, &vinfo_template, &nitems); 00582 00583 // If we got a valid visual using the requested ID, test to see if it 00584 // supports stereo. this->mInStereo needs to be set correctly based on 00585 // what is requested of the display window by the configuration and based 00586 // on what our chosen visual actually supports. 00587 if ( NULL != vi ) 00588 { 00589 int has_stereo; 00590 00591 if ( glXGetConfig(display, vi, GLX_STEREO, &has_stereo) == 0 ) 00592 { 00593 mInStereo = (mVrjDisplay->isStereoRequested() && 00594 has_stereo == True); 00595 } 00596 } 00597 // If XGetVisualInfo(3) returned NULL, print an error message. 00598 else 00599 { 00600 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL) 00601 << clrOutBOLD(clrRED, "ERROR:") 00602 << " Failed to get X11 visual info for visual ID 0x" 00603 << std::hex << visual_id << std::dec << std::endl 00604 << vprDEBUG_FLUSH; 00605 vprDEBUG_NEXT(vprDBG_ERROR, vprDBG_CRITICAL_LVL) 00606 << "Window '" << mVrjDisplay->getName() << "' cannot be opened" 00607 << std::endl << vprDEBUG_FLUSH; 00608 } 00609 00610 return vi; 00611 } 00612 else 00613 { 00614 if ( red_size < 0 ) 00615 { 00616 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00617 << clrOutBOLD(clrYELLOW, "WARNING:") 00618 << " Color buffer red channel size was negative (" 00619 << red_size << "). Setting to 1.\n" << vprDEBUG_FLUSH; 00620 red_size = 1; 00621 } 00622 00623 if ( green_size < 0 ) 00624 { 00625 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00626 << clrOutBOLD(clrYELLOW, "WARNING:") 00627 << " Color buffer green channel size was negative (" 00628 << green_size << "). Setting to 1.\n" << vprDEBUG_FLUSH; 00629 green_size = 1; 00630 } 00631 00632 if ( blue_size < 0 ) 00633 { 00634 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00635 << clrOutBOLD(clrYELLOW, "WARNING:") 00636 << " Color buffer blue channel size was negative (" 00637 << blue_size << "). Setting to 1.\n" << vprDEBUG_FLUSH; 00638 blue_size = 1; 00639 } 00640 00641 if ( alpha_size < 0 ) 00642 { 00643 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00644 << clrOutBOLD(clrYELLOW, "WARNING:") 00645 << " Color buffer alpha channel size was negative (" 00646 << alpha_size << "). Setting to 1.\n" << vprDEBUG_FLUSH; 00647 alpha_size = 1; 00648 } 00649 00650 if ( num_aux_bufs < 0 ) 00651 { 00652 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00653 << clrOutBOLD(clrYELLOW, "WARNING:") 00654 << " Auxiliary buffer count was negative (" << num_aux_bufs 00655 << "). Setting to 0.\n" << vprDEBUG_FLUSH; 00656 num_aux_bufs = 0; 00657 } 00658 00659 if ( db_size < 0 ) 00660 { 00661 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00662 << clrOutBOLD(clrYELLOW, "WARNING:") 00663 << " Depth buffer size was negative (" << db_size 00664 << "). Setting to 1.\n" << vprDEBUG_FLUSH; 00665 db_size = 1; 00666 } 00667 00668 if ( stencil_size < 0 ) 00669 { 00670 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00671 << clrOutBOLD(clrYELLOW, "WARNING:") 00672 << " Stencil buffer size was negative (" << stencil_size 00673 << "). Setting to 1.\n" << vprDEBUG_FLUSH; 00674 stencil_size = 1; 00675 } 00676 00677 if ( accum_red_size < 0 ) 00678 { 00679 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00680 << clrOutBOLD(clrYELLOW, "WARNING:") 00681 << " Accumulation buffer red channel size was negative (" 00682 << accum_red_size << "). Setting to 1.\n" << vprDEBUG_FLUSH; 00683 accum_red_size = 1; 00684 } 00685 00686 if ( accum_green_size < 0 ) 00687 { 00688 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00689 << clrOutBOLD(clrYELLOW, "WARNING:") 00690 << " Accumulation buffer green channel size was negative (" 00691 << accum_green_size << "). Setting to 1.\n" << vprDEBUG_FLUSH; 00692 accum_green_size = 1; 00693 } 00694 00695 if ( accum_blue_size < 0 ) 00696 { 00697 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00698 << clrOutBOLD(clrYELLOW, "WARNING:") 00699 << " Accumulation buffer blue channel size was negative (" 00700 << accum_blue_size << "). Setting to 1.\n" << vprDEBUG_FLUSH; 00701 accum_blue_size = 1; 00702 } 00703 00704 if ( accum_alpha_size < 0 ) 00705 { 00706 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 00707 << clrOutBOLD(clrYELLOW, "WARNING:") 00708 << " Accumulation buffer alpha channel size was negative (" 00709 << accum_alpha_size << "). Setting to 1.\n" << vprDEBUG_FLUSH; 00710 accum_alpha_size = 1; 00711 } 00712 00713 const unsigned int indent_level(2); 00714 const std::string indent_text(indent_level, ' '); 00715 const int pad_width_dot(40 - indent_level); 00716 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00717 << "OpenGL visual request settings for " << mVrjDisplay->getName() 00718 << ":\n"; 00719 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00720 << std::setiosflags(std::ios::left) << std::setfill('.') 00721 << indent_text << std::setw(pad_width_dot) 00722 << "Color buffer red size " << " " << red_size << std::endl; 00723 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00724 << std::setiosflags(std::ios::left) << std::setfill('.') 00725 << indent_text << std::setw(pad_width_dot) 00726 << "Color buffer green size " << " " << green_size << std::endl; 00727 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00728 << std::setiosflags(std::ios::left) << std::setfill('.') 00729 << indent_text << std::setw(pad_width_dot) 00730 << "Color buffer blue size " << " " << blue_size << std::endl; 00731 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00732 << std::setiosflags(std::ios::left) << std::setfill('.') 00733 << indent_text << std::setw(pad_width_dot) 00734 << "Color buffer alpha size " << " " << alpha_size << std::endl; 00735 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00736 << std::setiosflags(std::ios::left) << std::setfill('.') 00737 << indent_text << std::setw(pad_width_dot) 00738 << "Auxiliary buffer count " << " " << num_aux_bufs << std::endl; 00739 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00740 << std::setiosflags(std::ios::left) << std::setfill('.') 00741 << indent_text << std::setw(pad_width_dot) 00742 << "Depth buffer size " << " " << db_size << std::endl; 00743 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00744 << std::setiosflags(std::ios::left) << std::setfill('.') 00745 << indent_text << std::setw(pad_width_dot) 00746 << "Stencil buffer size " << " " << stencil_size << std::endl; 00747 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00748 << std::setiosflags(std::ios::left) << std::setfill('.') 00749 << indent_text << std::setw(pad_width_dot) 00750 << "Accumulation buffer red size " << " " << accum_red_size 00751 << std::endl; 00752 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00753 << std::setiosflags(std::ios::left) << std::setfill('.') 00754 << indent_text << std::setw(pad_width_dot) 00755 << "Accumulation buffer green size " << " " << accum_green_size 00756 << std::endl; 00757 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00758 << std::setiosflags(std::ios::left) << std::setfill('.') 00759 << indent_text << std::setw(pad_width_dot) 00760 << "Accumulation buffer blue size " << " " << accum_blue_size 00761 << std::endl; 00762 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00763 << std::setiosflags(std::ios::left) << std::setfill('.') 00764 << indent_text << std::setw(pad_width_dot) 00765 << "Accumulation buffer alpha size " << " " << accum_alpha_size 00766 << std::endl; 00767 vprDEBUG_CONTnl(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00768 << vprDEBUG_FLUSH; 00769 00770 // Notes on viattrib: by using 1 for GLX_RED_SIZE et.al. we ask 00771 // for the _largest_ available buffers. If this fails, we might 00772 // want to try setting alpha size to 0 (smallest possible, maybe 0) 00773 // which is required eg. for alpha on the indys. 00774 std::vector<int> viattrib; 00775 viattrib.push_back(GLX_DOUBLEBUFFER); 00776 viattrib.push_back(GLX_RGBA); 00777 viattrib.push_back(GLX_DEPTH_SIZE); viattrib.push_back(db_size); 00778 viattrib.push_back(GLX_RED_SIZE); viattrib.push_back(red_size); 00779 viattrib.push_back(GLX_GREEN_SIZE); viattrib.push_back(green_size); 00780 viattrib.push_back(GLX_BLUE_SIZE); viattrib.push_back(blue_size); 00781 00782 // Record the index for the alpha attribute using the current size of the 00783 // vector *before* the attribute is actually added. 00784 const unsigned int alpha_attrib_index = viattrib.size(); 00785 viattrib.push_back(GLX_ALPHA_SIZE); viattrib.push_back(alpha_size); 00786 00787 viattrib.push_back(GLX_AUX_BUFFERS); viattrib.push_back(num_aux_bufs); 00788 viattrib.push_back(GLX_STENCIL_SIZE); viattrib.push_back(stencil_size); 00789 00790 const unsigned int accum_red_attrib_index = viattrib.size(); 00791 viattrib.push_back(GLX_ACCUM_RED_SIZE); 00792 viattrib.push_back(accum_red_size); 00793 00794 const unsigned int accum_green_attrib_index = viattrib.size(); 00795 viattrib.push_back(GLX_ACCUM_GREEN_SIZE); 00796 viattrib.push_back(accum_green_size); 00797 00798 const unsigned int accum_blue_attrib_index = viattrib.size(); 00799 viattrib.push_back(GLX_ACCUM_BLUE_SIZE); 00800 viattrib.push_back(accum_blue_size); 00801 00802 const unsigned int accum_alpha_attrib_index = viattrib.size(); 00803 viattrib.push_back(GLX_ACCUM_ALPHA_SIZE); 00804 viattrib.push_back(accum_alpha_size); 00805 00806 // Enable full-screen anti-aliasing if it is available and it was 00807 // requested. 00808 #ifdef GLX_SAMPLES_SGIS 00809 // Save the current attribute vector size so we can try disabling FSAA if 00810 // necessary. 00811 const unsigned int fsaa_attrib_index = viattrib.size(); 00812 00813 if ( want_fsaa ) 00814 { 00815 viattrib.push_back(GLX_SAMPLES_SGIS); viattrib.push_back(1); 00816 viattrib.push_back(GLX_SAMPLE_BUFFERS_SGIS); viattrib.push_back(1); 00817 } 00818 #else 00819 if ( want_fsaa ) 00820 { 00821 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 00822 << "WARNING: Full-screen anti-aliasing is not available\n" 00823 << vprDEBUG_FLUSH; 00824 } 00825 #endif 00826 00827 // Record the index for the stereo attribute using the current size of 00828 // the vector *before* the attribute is actually added. If stereo is 00829 // not added, this variable will just be ignored. 00830 const unsigned int stereo_attrib_index = viattrib.size(); 00831 00832 if ( mVrjDisplay->isStereoRequested() ) 00833 { 00834 viattrib.push_back(GLX_STEREO); 00835 mInStereo = true; 00836 } 00837 else 00838 { 00839 mInStereo = false; 00840 } 00841 00842 // Add terminator 00843 viattrib.push_back(None); 00844 00845 XVisualInfo* vi(NULL); 00846 00847 // First, see if we can get exactly what we want. 00848 if ( (vi = glXChooseVisual(display, screen, &viattrib[0])) != NULL ) 00849 { 00850 return vi; 00851 } 00852 00853 // If we have reached this point, our first attempt to get a visual 00854 // failed. If stereo is enabled, we try disabling it and requesting 00855 // another visual. 00856 if ( mVrjDisplay->isStereoRequested() ) 00857 { 00858 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 00859 << "WARNING: Could not get an OpenGL visual for '" << mXDisplayName 00860 << "'\n"; 00861 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 00862 << "with stereo rendering enabled; trying without.\n" 00863 << vprDEBUG_FLUSH; 00864 mInStereo = false; 00865 00866 // GLX_USE_GL will be ignored by glXChooseVisual(3). 00867 viattrib[stereo_attrib_index] = GLX_USE_GL; 00868 00869 if ( (vi = glXChooseVisual(display, screen, &viattrib[0])) != NULL ) 00870 { 00871 return vi; 00872 } 00873 00874 // Stereo must not have been the problem, re-enable it. 00875 viattrib[stereo_attrib_index] = GLX_STEREO; 00876 } 00877 00878 // If we reached this point, we still do not have a usable GLX visual. 00879 // Disabling the accumulation buffer settings may give us something 00880 // usable. 00881 if ( accum_red_size > 0 || accum_green_size > 0 || 00882 accum_blue_size > 0 || accum_alpha_size > 0 ) 00883 { 00884 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 00885 << "WARNING: Could not get an OpenGL visual for '" << mXDisplayName 00886 << "'\n"; 00887 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 00888 << "with accumulation buffer settings; trying without.\n" 00889 << vprDEBUG_FLUSH; 00890 00891 viattrib[accum_red_attrib_index + 1] = 0; 00892 viattrib[accum_blue_attrib_index + 1] = 0; 00893 viattrib[accum_green_attrib_index + 1] = 0; 00894 viattrib[accum_alpha_attrib_index + 1] = 0; 00895 00896 // XXX: If this fails, should we restore the accumulation buffer 00897 // settings? 00898 if ( (vi = glXChooseVisual(display, screen, &viattrib[0])) != NULL ) 00899 { 00900 return vi; 00901 } 00902 } 00903 00904 // If we reached this point, we still do not have a usable GLX visual. 00905 // Disabling the alpha channel may give us something usable. 00906 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 00907 << "WARNING: Could not get an OpenGL visual for '" << mXDisplayName 00908 << "'\n"; 00909 vprDEBUG_NEXTnl(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 00910 << "with a color buffer alpha channel; trying without.\n" 00911 << vprDEBUG_FLUSH; 00912 00913 // There are two values in viattrib related to the alpha channel. 00914 viattrib[alpha_attrib_index ] = GLX_USE_GL; 00915 viattrib[alpha_attrib_index + 1] = GLX_USE_GL; 00916 00917 if ( (vi = glXChooseVisual(display, screen, &viattrib[0])) != NULL ) 00918 { 00919 return vi; 00920 } 00921 00922 #ifdef GLX_SAMPLES_SGIS 00923 // Last-ditch effort: try disabling FSAA if it was enabled. 00924 // XXX: It might be better to try disabling FSAA *first* instead of last. 00925 if ( want_fsaa ) 00926 { 00927 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 00928 << "WARNING: Display process for '" << mXDisplayName 00929 << "' couldn't get FSAA - trying without it.\n" << vprDEBUG_FLUSH; 00930 00931 // There are four values in viattrib related to FSAA. 00932 viattrib[fsaa_attrib_index ] = GLX_USE_GL; 00933 viattrib[fsaa_attrib_index + 1] = GLX_USE_GL; 00934 viattrib[fsaa_attrib_index + 2] = GLX_USE_GL; 00935 viattrib[fsaa_attrib_index + 3] = GLX_USE_GL; 00936 00937 if ( (vi = glXChooseVisual(display, screen, &viattrib[0])) != NULL ) 00938 { 00939 return vi; 00940 } 00941 } 00942 #endif 00943 } 00944 00945 // Failed, so return NULL 00946 return NULL; 00947 }
| int vrj::GlWindowXWin::eventIsMapNotify | ( | ::Display * | display, | |
| XEvent * | e, | |||
| XPointer | window | |||
| ) | [static, protected] |
Definition at line 955 of file GlWindowXWin.cpp.
Referenced by open().
00957 { 00958 boost::ignore_unused_variable_warning(display); 00959 return((e->type == MapNotify) && (e->xmap.window == (Window)window)); 00960 }
| void vrj::GlWindowXWin::createEmptyCursor | ( | ::Display * | display, | |
| ::Window | root | |||
| ) | [protected] |
Definition at line 962 of file GlWindowXWin.cpp.
Referenced by open().
00963 { 00964 Pixmap cursormask; 00965 XGCValues xgc; 00966 GC gc; 00967 XColor dummycolour; 00968 00969 cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); 00970 xgc.function = GXclear; 00971 gc = XCreateGC(display, cursormask, GCFunction, &xgc); 00972 XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); 00973 dummycolour.pixel = 0; 00974 dummycolour.red = 0; 00975 dummycolour.flags = 04; 00976 mEmptyCursor = XCreatePixmapCursor(display, cursormask, cursormask, 00977 &dummycolour,&dummycolour, 0,0); 00978 XFreePixmap(display,cursormask); 00979 XFreeGC(display,gc); 00980 00981 mEmptyCursorSet = true; 00982 }
1.5.1