vtkXOpenGLRenderWindow.cxx 55.2 KB
Newer Older
Ken Martin's avatar
Ken Martin committed
1 2
/*=========================================================================

Mathieu Malaterre's avatar
Mathieu Malaterre committed
3 4
  Program:   Visualization Toolkit
  Module:    vtkXOpenGLRenderWindow.cxx
Ken Martin's avatar
Ken Martin committed
5

Mathieu Malaterre's avatar
Mathieu Malaterre committed
6 7 8
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
Ken Martin's avatar
Ken Martin committed
9

Mathieu Malaterre's avatar
Mathieu Malaterre committed
10 11 12
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.
Ken Martin's avatar
Ken Martin committed
13 14

=========================================================================*/
15

Ken Martin's avatar
Ken Martin committed
16 17 18 19 20 21 22
#include "vtkXOpenGLRenderWindow.h"
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLProperty.h"
#include "vtkOpenGLTexture.h"
#include "vtkOpenGLCamera.h"
#include "vtkOpenGLLight.h"
#include "vtkOpenGLActor.h"
23
#include "vtkXRenderWindowInteractor.h"
24 25

#include "vtkOpenGL.h"
26

27 28
// Define GLX_GLXEXT_LEGACY to prevent glx.h from including the glxext.h
// provided by the system.
29 30 31 32 33 34 35 36 37
//#define GLX_GLXEXT_LEGACY

// New Workaround:
// The GLX_GLXEXT_LEGACY definition was added to work around system glxext.h
// files that used the GLintptr and GLsizeiptr types, but did not define them.
// However, this broke multisampling (See PR#15433). Instead of using that
// define, we're just defining the missing typedefs here.
typedef ptrdiff_t GLintptr;
typedef ptrdiff_t GLsizeiptr;
38
#include "GL/glx.h"
39

40
#include "vtkgl.h"
Ken Martin's avatar
Ken Martin committed
41

42
#include "vtkToolkits.h"
43

44
#ifdef VTK_USE_OSMESA
45
# include <GL/osmesa.h>
46
#endif
47

48
#include "vtkCommand.h"
49
#include "vtkIdList.h"
50 51
#include "vtkObjectFactory.h"
#include "vtkRendererCollection.h"
52
#include "vtkOpenGLExtensionManager.h"
Ken Martin's avatar
Ken Martin committed
53

54 55
#include "vtksys/SystemTools.hxx"

56
#include <sstream>
57

58 59 60 61
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>

62 63 64 65 66 67 68 69 70
class vtkXOpenGLRenderWindow;
class vtkRenderWindow;
class vtkXOpenGLRenderWindowInternal
{
  friend class vtkXOpenGLRenderWindow;
private:
  vtkXOpenGLRenderWindowInternal(vtkRenderWindow*);

  GLXContext ContextId;
71 72 73 74

  // so we basically have 4 methods here for handling drawables
  // how about abstracting this a bit?

75 76 77 78 79
  // support for Pixmap based offscreen rendering
  Pixmap pixmap;
  GLXContext PixmapContextId;
  Window PixmapWindowId;

80

81 82 83 84
  // support for Pbuffer based offscreen rendering
  GLXContext PbufferContextId;
  vtkglX::GLXPbuffer Pbuffer;

85 86 87
  // store previous settings of on screen window
  int ScreenDoubleBuffer;
  int ScreenMapped;
88

89
#if defined( VTK_USE_OSMESA )
90 91 92
  // OffScreen stuff
  OSMesaContext OffScreenContextId;
  void *OffScreenWindow;
93
#endif
94 95 96 97 98 99
};

vtkXOpenGLRenderWindowInternal::vtkXOpenGLRenderWindowInternal(
  vtkRenderWindow *rw)
{
  this->ContextId = NULL;
100 101 102

  this->PixmapContextId = NULL;
  this->PixmapWindowId = 0;
103 104 105

  this->PbufferContextId = NULL;
  this->Pbuffer = 0;
106

107 108
  this->ScreenMapped = rw->GetMapped();
  this->ScreenDoubleBuffer = rw->GetDoubleBuffer();
109

110
  // OpenGL specific
111
#ifdef VTK_USE_OSMESA
112 113
  this->OffScreenContextId = NULL;
  this->OffScreenWindow = NULL;
Andy Cedilnik's avatar
Andy Cedilnik committed
114
#endif
115 116
}

Brad King's avatar
Brad King committed
117
vtkStandardNewMacro(vtkXOpenGLRenderWindow);
Ken Martin's avatar
Ken Martin committed
118 119 120

#define MAX_LIGHTS 8

121
#ifdef VTK_USE_OSMESA
122
// a couple of routines for offscreen rendering
123
void vtkOSMesaDestroyWindow(void *Window)
124 125 126 127
{
  free(Window);
}

128
void *vtkOSMesaCreateWindow(int width, int height)
129 130 131 132 133
{
  return malloc(width*height*4);
}
#endif

134
vtkglX::GLXFBConfig* vtkXOpenGLRenderWindowTryForFBConfig(Display *DisplayId,
135 136 137 138
                                                          int drawable_type,
                                                          int doublebuff,
                                                          int stereo,
                                                          int multisamples,
139 140
                                                          int alphaBitPlanes,
                                                          int stencil)
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
{
  int           index;
  static int    attributes[50];

  // setup the default stuff we ask for
  index = 0;
  attributes[index++] = vtkglX::DRAWABLE_TYPE;
  attributes[index++] = drawable_type;
  attributes[index++] = vtkglX::RENDER_TYPE;
  attributes[index++] = vtkglX::RGBA_BIT;
  attributes[index++] = GLX_RED_SIZE;
  attributes[index++] = 1;
  attributes[index++] = GLX_GREEN_SIZE;
  attributes[index++] = 1;
  attributes[index++] = GLX_BLUE_SIZE;
  attributes[index++] = 1;
  attributes[index++] = GLX_DEPTH_SIZE;
  attributes[index++] = 1;
  if (alphaBitPlanes)
    {
    attributes[index++] = GLX_ALPHA_SIZE;
    attributes[index++] = 1;
    }
  if (doublebuff)
    {
    attributes[index++] = GLX_DOUBLEBUFFER;
167
    attributes[index++] = True;
168
    }
169
  if (stencil)
170
    {
171 172 173
    attributes[index++] = GLX_STENCIL_SIZE;
    attributes[index++] = 8;
    }
174 175 176 177
  if (stereo)
    {
    // also try for STEREO
    attributes[index++] = GLX_STEREO;
178
    attributes[index++] = True;
179 180 181 182 183 184 185 186 187 188
    }
  if (multisamples)
    {
#ifdef GLX_SAMPLE_BUFFERS_SGIS
    attributes[index++] = GLX_SAMPLE_BUFFERS_SGIS;
    attributes[index++] = 1;
    attributes[index++] = GLX_SAMPLES_SGIS;
    attributes[index++] = multisamples;
#endif
    }
189

190 191
  attributes[index++] = None;
  int tmp;
192
  vtkglX::GLXFBConfig* fb = vtkglX::ChooseFBConfig(DisplayId,
Francois Bertel's avatar
Francois Bertel committed
193
                                                   XDefaultScreen(DisplayId),
194
                                                   attributes, &tmp);
195 196 197
  return fb;
}

Ken Martin's avatar
Ken Martin committed
198
XVisualInfo *vtkXOpenGLRenderWindowTryForVisual(Display *DisplayId,
199 200
                                                int doublebuff, int stereo,
                                                int multisamples,
201 202
                                                int alphaBitPlanes,
                                                int stencil)
Ken Martin's avatar
Ken Martin committed
203 204
{
  int           index;
205
  static int    attributes[50];
Ken Martin's avatar
Ken Martin committed
206 207 208 209 210 211 212 213 214 215 216 217

  // setup the default stuff we ask for
  index = 0;
  attributes[index++] = GLX_RGBA;
  attributes[index++] = GLX_RED_SIZE;
  attributes[index++] = 1;
  attributes[index++] = GLX_GREEN_SIZE;
  attributes[index++] = 1;
  attributes[index++] = GLX_BLUE_SIZE;
  attributes[index++] = 1;
  attributes[index++] = GLX_DEPTH_SIZE;
  attributes[index++] = 1;
218 219 220 221 222
  if (alphaBitPlanes)
    {
    attributes[index++] = GLX_ALPHA_SIZE;
    attributes[index++] = 1;
    }
Ken Martin's avatar
Ken Martin committed
223 224 225
  if (doublebuff)
    {
    attributes[index++] = GLX_DOUBLEBUFFER;
226
    attributes[index++] = True;
Ken Martin's avatar
Ken Martin committed
227
    }
228 229 230 231 232
  if (stencil)
    {
    attributes[index++] = GLX_STENCIL_SIZE;
    attributes[index++] = 8;
    }
Ken Martin's avatar
Ken Martin committed
233 234 235 236
  if (stereo)
    {
    // also try for STEREO
    attributes[index++] = GLX_STEREO;
237
    attributes[index++] = True;
Ken Martin's avatar
Ken Martin committed
238 239 240 241 242 243 244 245 246 247
    }
  if (multisamples)
    {
#ifdef GLX_SAMPLE_BUFFERS_SGIS
    attributes[index++] = GLX_SAMPLE_BUFFERS_SGIS;
    attributes[index++] = 1;
    attributes[index++] = GLX_SAMPLES_SGIS;
    attributes[index++] = multisamples;
#endif
    }
248

Ken Martin's avatar
Ken Martin committed
249 250
  attributes[index++] = None;

Francois Bertel's avatar
Francois Bertel committed
251
  return glXChooseVisual(DisplayId, XDefaultScreen(DisplayId), attributes );
Ken Martin's avatar
Ken Martin committed
252 253
}

254
vtkglX::GLXFBConfig *vtkXOpenGLRenderWindowGetDesiredFBConfig(
255 256 257
  Display *DisplayId,
  int &win_stereo,
  int &win_multisamples,
258
  int &win_doublebuffer,
259
  int &win_alphaplanes,
260 261
  int drawable_type,
  int &stencil)
262 263 264 265
{
  vtkglX::GLXFBConfig   *fbc = NULL;
  int           multi;
  int           stereo = 0;
266

267 268 269 270 271
  // try every possibility stoping when we find one that works
  for (stereo = win_stereo; !fbc && stereo >= 0; stereo--)
    {
    for (multi = win_multisamples; !fbc && multi >= 0; multi--)
      {
272
      if (fbc)
273 274 275 276
        {
        XFree(fbc);
        }
      fbc = vtkXOpenGLRenderWindowTryForFBConfig(DisplayId,
277 278 279
                                                 drawable_type,
                                                 win_doublebuffer,
                                                 stereo, multi,
280 281
                                                 win_alphaplanes,
                                                 stencil);
282 283 284 285 286 287 288 289 290 291 292
      if (fbc && win_stereo && !stereo)
        {
        // requested a stereo capable window but we could not get one
        win_stereo = 0;
        }
      }
    }
  for (stereo = win_stereo; !fbc && stereo >= 0; stereo--)
    {
    for (multi = win_multisamples; !fbc && multi >= 0; multi--)
      {
293
      if (fbc)
294 295 296 297
        {
        XFree(fbc);
        }
      fbc = vtkXOpenGLRenderWindowTryForFBConfig(DisplayId,
298
                                                 drawable_type,
299
                                                 !win_doublebuffer,
300
                                                 stereo, multi,
301 302
                                                 win_alphaplanes,
                                                 stencil);
303 304 305 306 307 308 309 310 311 312 313 314 315 316
      if (fbc)
        {
        win_doublebuffer = !win_doublebuffer;
        }
      if (fbc && win_stereo && !stereo)
        {
        // requested a stereo capable window but we could not get one
        win_stereo = 0;
        }
      }
    }
  return ( fbc );
}

Ken Martin's avatar
Ken Martin committed
317 318 319
XVisualInfo *vtkXOpenGLRenderWindow::GetDesiredVisualInfo()
{
  XVisualInfo   *v = NULL;
320
  int           alpha;
Ken Martin's avatar
Ken Martin committed
321 322
  int           multi;
  int           stereo = 0;
323 324
  int           stencil;

325
  // get the default display connection
Ken Martin's avatar
Ken Martin committed
326 327
  if (!this->DisplayId)
    {
328
    this->DisplayId = XOpenDisplay(static_cast<char *>(NULL));
329 330

    if (this->DisplayId == NULL)
Ken Martin's avatar
Ken Martin committed
331
      {
332
      vtkErrorMacro(<< "bad X server connection. DISPLAY="
333 334
        << vtksys::SystemTools::GetEnv("DISPLAY") << ". Aborting.\n");
      abort();
Ken Martin's avatar
Ken Martin committed
335
      }
336

Ken Martin's avatar
Ken Martin committed
337 338 339 340
    this->OwnDisplay = 1;
    }

  // try every possibility stoping when we find one that works
341
  for (stencil = this->StencilCapable; !v && stencil >= 0; stencil--)
Ken Martin's avatar
Ken Martin committed
342
    {
343
    for (alpha = this->AlphaBitPlanes; !v && alpha >= 0; alpha--)
Ken Martin's avatar
Ken Martin committed
344
      {
345
      for (stereo = this->StereoCapableWindow; !v && stereo >= 0; stereo--)
346
        {
347
        for (multi = this->MultiSamples; !v && multi >= 0; multi--)
348
          {
349
          if (v)
350 351 352 353
            {
            XFree(v);
            }
          v = vtkXOpenGLRenderWindowTryForVisual(this->DisplayId,
354 355
                                                 this->DoubleBuffer,
                                                 stereo, multi, alpha,
356 357 358 359 360 361 362 363
                                                 stencil);
          if (v)
            {
            this->StereoCapableWindow = stereo;
            this->MultiSamples = multi;
            this->AlphaBitPlanes = alpha;
            this->StencilCapable = stencil;
            }
364
          }
365
        }
Ken Martin's avatar
Ken Martin committed
366 367
      }
    }
368
  for (stencil = this->StencilCapable; !v && stencil >= 0; stencil--)
Ken Martin's avatar
Ken Martin committed
369
    {
370
    for (alpha = this->AlphaBitPlanes; !v && alpha >= 0; alpha--)
Ken Martin's avatar
Ken Martin committed
371
      {
372
      for (stereo = this->StereoCapableWindow; !v && stereo >= 0; stereo--)
373
        {
374
        for (multi = this->MultiSamples; !v && multi >= 0; multi--)
375
          {
376
          v = vtkXOpenGLRenderWindowTryForVisual(this->DisplayId,
377
                                                 !this->DoubleBuffer,
378 379 380 381 382 383 384 385 386 387
                                                 stereo, multi, alpha,
                                                 stencil);
          if (v)
            {
            this->DoubleBuffer = !this->DoubleBuffer;
            this->StereoCapableWindow = stereo;
            this->MultiSamples = multi;
            this->AlphaBitPlanes = alpha;
            this->StencilCapable = stencil;
            }
388
          }
389
        }
Ken Martin's avatar
Ken Martin committed
390 391
      }
    }
392
  if (!v)
Ken Martin's avatar
Ken Martin committed
393 394 395 396 397 398 399 400
    {
    vtkErrorMacro(<< "Could not find a decent visual\n");
    }
  return ( v );
}

vtkXOpenGLRenderWindow::vtkXOpenGLRenderWindow()
{
401
  this->ParentId = static_cast<Window>(NULL);
Ken Martin's avatar
Ken Martin committed
402 403 404 405
  this->ScreenSize[0] = 0;
  this->ScreenSize[1] = 0;
  this->OwnDisplay = 0;
  this->CursorHidden = 0;
406
  this->ForceMakeCurrent = 0;
407
  this->UsingHardware = 0;
408 409 410 411
  this->DisplayId = static_cast<Display *>(NULL);
  this->WindowId = static_cast<Window>(NULL);
  this->NextWindowId = static_cast<Window>(NULL);
  this->ColorMap = static_cast<Colormap>(0);
Ken Martin's avatar
Ken Martin committed
412
  this->OwnWindow = 0;
413

414
  this->Internal = new vtkXOpenGLRenderWindowInternal(this);
Ken Martin's avatar
Ken Martin committed
415

416 417 418 419 420 421 422 423 424 425
  this->XCCrosshair = 0;
  this->XCArrow     = 0;
  this->XCSizeAll   = 0;
  this->XCSizeNS    = 0;
  this->XCSizeWE    = 0;
  this->XCSizeNE    = 0;
  this->XCSizeNW    = 0;
  this->XCSizeSE    = 0;
  this->XCSizeSW    = 0;
  this->XCHand      = 0;
426 427

  this->Capabilities = 0;
428

Ken Martin's avatar
Ken Martin committed
429 430 431 432 433
}

// free up memory & close the window
vtkXOpenGLRenderWindow::~vtkXOpenGLRenderWindow()
{
434
  // close-down all system-specific drawing resources
435
  this->Finalize();
436 437 438 439 440

  vtkRenderer *ren;
  vtkCollectionSimpleIterator rit;
  this->Renderers->InitTraversal(rit);
  while ( (ren = this->Renderers->GetNextRenderer(rit)) )
441 442 443
    {
    ren->SetRenderWindow(NULL);
    }
Ken Martin's avatar
Ken Martin committed
444

445
  delete this->Internal;
Ken Martin's avatar
Ken Martin committed
446 447 448
}

// End the rendering process and display the image.
449
void vtkXOpenGLRenderWindow::Frame()
Ken Martin's avatar
Ken Martin committed
450 451
{
  this->MakeCurrent();
452 453
  if (!this->AbortRender && this->DoubleBuffer && this->SwapBuffers
      && this->WindowId!=0)
Ken Martin's avatar
Ken Martin committed
454 455 456 457
    {
    glXSwapBuffers(this->DisplayId, this->WindowId);
    vtkDebugMacro(<< " glXSwapBuffers\n");
    }
458 459 460 461
  else
    {
    glFlush();
    }
Ken Martin's avatar
Ken Martin committed
462
}
463

464 465 466 467 468 469 470 471 472
bool vtkXOpenGLRenderWindow::InitializeFromCurrentContext()
{
  GLXContext currentContext = glXGetCurrentContext();
  if (currentContext != NULL)
    {
    this->SetDisplayId((void*)glXGetCurrentDisplay());
    this->SetWindowId((void*)glXGetCurrentDrawable());
    this->Internal->ContextId = currentContext;
    this->OpenGLInit();
473
    this->OwnContext = 0;
474 475 476 477 478
    return true;
    }
  return false;
}

Ken Martin's avatar
Ken Martin committed
479 480 481 482 483 484
//
// Set the variable that indicates that we want a stereo capable window
// be created. This method can only be called before a window is realized.
//
void vtkXOpenGLRenderWindow::SetStereoCapableWindow(int capable)
{
485 486
  if (!this->Internal->ContextId && !this->Internal->PixmapContextId
      && !this->Internal->PbufferContextId
487
#if defined( VTK_USE_OSMESA )
488
      && !this->Internal->OffScreenContextId
489 490
#endif
    )
Ken Martin's avatar
Ken Martin committed
491
    {
Ken Martin's avatar
Ken Martin committed
492
    vtkOpenGLRenderWindow::SetStereoCapableWindow(capable);
Ken Martin's avatar
Ken Martin committed
493 494 495 496 497 498 499 500
    }
  else
    {
    vtkWarningMacro(<< "Requesting a StereoCapableWindow must be performed "
                    << "before the window is realized, i.e. before a render.");
    }
}

501
static int PbufferAllocFail = 0;
502
extern "C"
503
{
504
  int vtkXOGLPbufferErrorHandler(Display*, XErrorEvent*)
505 506 507 508
  {
    PbufferAllocFail = 1;
    return 1;
  }
509
}
510 511

void vtkXOpenGLRenderWindow::CreateAWindow()
Ken Martin's avatar
Ken Martin committed
512
{
513 514 515 516 517 518 519 520
  XVisualInfo  *v, matcher;
  XSetWindowAttributes  attr;
  int x, y, width, height, nItems;
  XWindowAttributes winattr;
  XSizeHints xsh;

  xsh.flags = USSize;
  if ((this->Position[0] >= 0)&&(this->Position[1] >= 0))
Ken Martin's avatar
Ken Martin committed
521
    {
522 523 524 525
    xsh.flags |= USPosition;
    xsh.x =  static_cast<int>(this->Position[0]);
    xsh.y =  static_cast<int>(this->Position[1]);
    }
526

527 528 529 530 531 532 533 534
  x = ((this->Position[0] >= 0) ? this->Position[0] : 5);
  y = ((this->Position[1] >= 0) ? this->Position[1] : 5);
  width = ((this->Size[0] > 0) ? this->Size[0] : 300);
  height = ((this->Size[1] > 0) ? this->Size[1] : 300);

  xsh.width  = width;
  xsh.height = height;

535
  // get the default display connection
536 537 538
  if (!this->DisplayId)
    {
    this->DisplayId = XOpenDisplay(static_cast<char *>(NULL));
539
    if (this->DisplayId == NULL)
540
      {
541
      vtkErrorMacro(<< "bad X server connection. DISPLAY="
542 543
        << vtksys::SystemTools::GetEnv("DISPLAY") << ". Aborting.\n");
      abort();
Ken Martin's avatar
Ken Martin committed
544
      }
545 546 547 548 549 550 551 552 553
    this->OwnDisplay = 1;
    }

  attr.override_redirect = False;
  if (this->Borders == 0.0)
    {
    attr.override_redirect = True;
    }

554
  // create our own window ?
555 556 557 558 559
  this->OwnWindow = 0;
  if (!this->WindowId)
    {
    v = this->GetDesiredVisualInfo();
    this->ColorMap = XCreateColormap(this->DisplayId,
Francois Bertel's avatar
Francois Bertel committed
560 561
                                     XRootWindow(this->DisplayId,v->screen),
                                     v->visual, AllocNone);
562

563 564 565 566
    attr.background_pixel = 0;
    attr.border_pixel = 0;
    attr.colormap = this->ColorMap;
    attr.event_mask = StructureNotifyMask | ExposureMask;
567

568 569
    // get a default parent if one has not been set.
    if (! this->ParentId)
570
      {
Francois Bertel's avatar
Francois Bertel committed
571
      this->ParentId = XRootWindow(this->DisplayId, v->screen);
572
      }
573
    this->WindowId =
574 575
      XCreateWindow(this->DisplayId,
                    this->ParentId,
Francois Bertel's avatar
Francois Bertel committed
576 577 578
                    x, y, static_cast<unsigned int>(width),
                    static_cast<unsigned int>(height), 0, v->depth,
                    InputOutput, v->visual,
579 580
                    CWBackPixel | CWBorderPixel | CWColormap |
                    CWOverrideRedirect | CWEventMask,
581 582 583 584 585 586 587 588 589 590 591 592
                    &attr);
    XStoreName(this->DisplayId, this->WindowId, this->WindowName);
    XSetNormalHints(this->DisplayId,this->WindowId,&xsh);
    this->OwnWindow = 1;
    }
  else
    {
    XChangeWindowAttributes(this->DisplayId,this->WindowId,
                            CWOverrideRedirect, &attr);
    XGetWindowAttributes(this->DisplayId,
                         this->WindowId,&winattr);
    matcher.visualid = XVisualIDFromVisual(winattr.visual);
Francois Bertel's avatar
Francois Bertel committed
593
    matcher.screen = XDefaultScreen(DisplayId);
594 595 596
    v = XGetVisualInfo(this->DisplayId, VisualIDMask | VisualScreenMask,
                       &matcher, &nItems);
    }
597

598 599 600 601 602
  if (this->OwnWindow)
    {
    // RESIZE THE WINDOW TO THE DESIRED SIZE
    vtkDebugMacro(<< "Resizing the xwindow\n");
    XResizeWindow(this->DisplayId,this->WindowId,
603
                  ((this->Size[0] > 0) ?
Francois Bertel's avatar
Francois Bertel committed
604
                   static_cast<unsigned int>(this->Size[0]) : 300),
605
                  ((this->Size[1] > 0) ?
Francois Bertel's avatar
Francois Bertel committed
606
                   static_cast<unsigned int>(this->Size[1]) : 300));
607 608 609 610
    XSync(this->DisplayId,False);
    }

  // is GLX extension is supported?
611
  if(!glXQueryExtension(this->DisplayId, NULL, NULL))
612 613 614
    {
    vtkErrorMacro("GLX not found.  Aborting.");
    if (this->HasObserver(vtkCommand::ExitEvent))
615
      {
616 617
      this->InvokeEvent(vtkCommand::ExitEvent, NULL);
      return;
618
      }
619
    else
Ken Martin's avatar
Ken Martin committed
620
      {
621 622 623 624 625 626
      abort();
      }
    }

  if (!this->Internal->ContextId)
    {
627
    this->Internal->ContextId =
628 629 630 631 632 633 634 635 636 637
      glXCreateContext(this->DisplayId, v, 0, GL_TRUE);
    }

  if(!this->Internal->ContextId)
    {
    vtkErrorMacro("Cannot create GLX context.  Aborting.");
    if (this->HasObserver(vtkCommand::ExitEvent))
      {
      this->InvokeEvent(vtkCommand::ExitEvent, NULL);
      return;
Ken Martin's avatar
Ken Martin committed
638
      }
639 640
    else
      {
641
      abort();
Mathieu Malaterre's avatar
Mathieu Malaterre committed
642
      }
643 644
    }

645
  if(this->OwnWindow && !this->OffScreenRendering)
646 647 648 649 650 651
    {
    vtkDebugMacro(" Mapping the xwindow\n");
    XMapWindow(this->DisplayId, this->WindowId);
    XSync(this->DisplayId,False);
    XGetWindowAttributes(this->DisplayId,
                         this->WindowId,&winattr);
652
    // guarantee that the window is mapped before the program continues
653 654
    // on to do the OpenGL rendering.
    while (winattr.map_state == IsUnmapped)
655
      {
656 657
      XGetWindowAttributes(this->DisplayId,
                           this->WindowId,&winattr);
658
      }
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
    }
  // free the visual info
  if (v)
    {
    XFree(v);
    }
  this->Mapped = 1;
  this->Size[0] = width;
  this->Size[1] = height;

}

void vtkXOpenGLRenderWindow::DestroyWindow()
{
  // free the cursors
  if (this->DisplayId)
    {
    if (this->WindowId)
677
      {
678 679 680 681
      // we will only have a cursor defined if a CurrentCursor has been
      // set > 0 or if the cursor has been hidden... if we undefine without
      // checking, bad things can happen (BadWindow)
      if (this->GetCurrentCursor() || this->CursorHidden)
682
        {
683
        XUndefineCursor(this->DisplayId,this->WindowId);
684
        }
685
      }
686
    if (this->XCArrow)
687
      {
688
      XFreeCursor(this->DisplayId,this->XCArrow);
689
      }
690 691 692 693
    if (this->XCCrosshair)
      {
      XFreeCursor(this->DisplayId,this->XCCrosshair);
      }
694
    if (this->XCSizeAll)
695
      {
696
      XFreeCursor(this->DisplayId,this->XCSizeAll);
697
      }
698
    if (this->XCSizeNS)
699
      {
700 701 702 703 704 705 706 707 708 709 710 711 712
      XFreeCursor(this->DisplayId,this->XCSizeNS);
      }
    if (this->XCSizeWE)
      {
      XFreeCursor(this->DisplayId,this->XCSizeWE);
      }
    if (this->XCSizeNE)
      {
      XFreeCursor(this->DisplayId,this->XCSizeNE);
      }
    if (this->XCSizeNW)
      {
      XFreeCursor(this->DisplayId,this->XCSizeNW);
713
      }
714
    if (this->XCSizeSE)
715
      {
716 717 718 719 720 721 722 723 724
      XFreeCursor(this->DisplayId,this->XCSizeSE);
      }
    if (this->XCSizeSW)
      {
      XFreeCursor(this->DisplayId,this->XCSizeSW);
      }
    if (this->XCHand)
      {
      XFreeCursor(this->DisplayId,this->XCHand);
725
      }
726
    }
727

728 729 730 731 732 733 734 735 736 737
  this->XCCrosshair = 0;
  this->XCArrow     = 0;
  this->XCSizeAll   = 0;
  this->XCSizeNS    = 0;
  this->XCSizeWE    = 0;
  this->XCSizeNE    = 0;
  this->XCSizeNW    = 0;
  this->XCSizeSE    = 0;
  this->XCSizeSW    = 0;
  this->XCHand      = 0;
738

739 740 741 742 743 744 745 746 747 748 749
  if (this->OwnContext && this->Internal->ContextId)
    {
      this->MakeCurrent();
    // tell each of the renderers that this render window/graphics context
    // is being removed (the RendererCollection is removed by vtkRenderWindow's
    // destructor)
    vtkRenderer* ren;
    this->Renderers->InitTraversal();
    for ( ren = vtkOpenGLRenderer::SafeDownCast(this->Renderers->GetNextItemAsObject());
          ren != NULL;
          ren = vtkOpenGLRenderer::SafeDownCast(this->Renderers->GetNextItemAsObject())  )
750
      {
751 752
      ren->SetRenderWindow(NULL);
      ren->SetRenderWindow(this);
753 754
      }

755
    if (this->Internal->ContextId)
756
      {
757 758
      /* first delete all the old lights */
      for (short cur_light = GL_LIGHT0; cur_light < GL_LIGHT0+MAX_LIGHTS; cur_light++)
759
        {
760
        glDisable(static_cast<GLenum>(cur_light));
761
        }
762 763 764 765

      /* now delete all textures */
      glDisable(GL_TEXTURE_2D);
      for (int i = 1; i < this->TextureResourceIds->GetNumberOfIds(); i++)
766
        {
767 768 769 770 771 772 773 774 775 776 777
        GLuint txId = static_cast<GLuint>(this->TextureResourceIds->GetId(i));
#ifdef GL_VERSION_1_1
        if (glIsTexture(txId))
          {
          glDeleteTextures(1, &txId);
          }
#else
        if (glIsList(txId))
          {
          glDeleteLists(txId,1);
          }
778
#endif
779
        }
780

781 782 783
      glFinish();
      glXDestroyContext(this->DisplayId, this->Internal->ContextId);
      }
784
    }
785
    this->Internal->ContextId = NULL;
786

787 788 789 790 791 792 793 794 795 796 797 798 799 800
  // then close the old window if we own it
  if (this->OwnWindow && this->DisplayId && this->WindowId)
    {
    XDestroyWindow(this->DisplayId,this->WindowId);
    this->WindowId = static_cast<Window>(NULL);
    }

  // if we create the display, we'll delete it
  if (this->OwnDisplay && this->DisplayId)
    {
    XCloseDisplay(this->DisplayId);
    this->DisplayId = NULL;
    }

801 802
  delete[] this->Capabilities;
  this->Capabilities = 0;
803

804 805 806
  // make sure all other code knows we're not mapped anymore
  this->Mapped = 0;

807 808
}

809 810
void vtkXOpenGLRenderWindow::CreateOffScreenWindow(int width, int height)
{
811

812
  XVisualInfo  *v;
813

814 815 816
  this->DoubleBuffer = 0;

  // always prefer OSMESA if we built with it
817
#ifdef VTK_USE_OSMESA
818
  if(1)
819
    {
820 821 822 823
    if (!this->Internal->OffScreenWindow)
      {
      this->Internal->OffScreenWindow = vtkOSMesaCreateWindow(width,height);
      this->Size[0] = width;
824
      this->Size[1] = height;
825
      this->OwnWindow = 1;
826
      }
827 828 829 830 831
    if (!this->Internal->OffScreenContextId)
      {
      this->Internal->OffScreenContextId = OSMesaCreateContext(GL_RGBA, NULL);
      }
    this->MakeCurrent();
832
    }
833 834 835
  else
#endif
    {
836
    if(!this->CreateHardwareOffScreenWindow(width,height))
837
      {
838
      // get the default display connection
839
      if (!this->DisplayId)
840
        {
841
        this->DisplayId = XOpenDisplay(static_cast<char *>(NULL));
842
        if (this->DisplayId == NULL)
843
          {
844
          vtkErrorMacro(<< "bad X server connection. DISPLAY="
845 846
            << vtksys::SystemTools::GetEnv("DISPLAY") << ". Aborting.\n");
          abort();
847 848
          }
        this->OwnDisplay = 1;
849 850
        }

851 852
      int v1, v2;
      glXQueryVersion(this->DisplayId, &v1, &v2);
853

854 855
      // check for GLX 1.3 or greater for Pbuffer offscreen support
      if(v1 > 1 || (v1 == 1 && v2 >= 3))
856
        {
857
        if(!this->Internal->PbufferContextId)
858
          {
859 860 861 862 863 864
          // Load GLX 1.3
          vtkOpenGLExtensionManager *manager=vtkOpenGLExtensionManager::New();
          int loaded = vtkgl::LoadExtension("GLX_VERSION_1_3", manager);
          manager->Delete();

          if(loaded)
865
            {
866 867 868
            // get FBConfig
            vtkglX::GLXFBConfig* fb = vtkXOpenGLRenderWindowGetDesiredFBConfig(
              this->DisplayId,this->StereoCapableWindow, this->MultiSamples,
869 870
              this->DoubleBuffer,this->AlphaBitPlanes, vtkglX::PBUFFER_BIT,
              this->StencilCapable);
871
            if(fb)
872
              {
873
              XErrorHandler previousHandler = XSetErrorHandler(vtkXOGLPbufferErrorHandler);
874
              this->Internal->PbufferContextId =
875 876
                vtkglX::CreateNewContext(this->DisplayId, fb[0],
                                         vtkglX::RGBA_TYPE, NULL, true);
877
              int atts [] =
878 879 880 881 882 883 884 885
                {
                  vtkglX::PBUFFER_WIDTH, width,
                  vtkglX::PBUFFER_HEIGHT, height,
                  0
                };
              this->Internal->Pbuffer = vtkglX::CreatePbuffer(this->DisplayId,
                                                              fb[0], atts);
              vtkglX::MakeContextCurrent( this->DisplayId,
886
                                          this->Internal->Pbuffer,
887 888 889 890
                                          this->Internal->Pbuffer,
                                          this->Internal->PbufferContextId );
              XFree(fb);
              XSetErrorHandler(previousHandler);
891

892 893 894 895 896 897 898 899 900 901 902
              // failed to allocate Pbuffer, clean up
              if(PbufferAllocFail)
                {
                //vtkglX::DestroyPbuffer(this->DisplayId, this->Internal->Pbuffer);
                this->Internal->Pbuffer = 0;
                if(this->Internal->PbufferContextId)
                  glXDestroyContext(this->DisplayId,
                                    this->Internal->PbufferContextId);
                this->Internal->PbufferContextId = NULL;
                }
              PbufferAllocFail = 0;
903 904 905 906
              }
            }
          }
        }
907

908 909 910
      // GLX 1.3 doesn't exist or failed to allocate Pbuffer
      // fallback on GLX 1.0 GLXPixmap offscreen support
      if(!this->Internal->PbufferContextId && !this->Internal->PixmapContextId)
911
        {
912 913 914
        v = this->GetDesiredVisualInfo();
        this->Internal->PixmapContextId = glXCreateContext(this->DisplayId,
                                                           v, 0, GL_FALSE);
Francois Bertel's avatar
Francois Bertel committed
915 916 917 918 919 920
        this->Internal->pixmap=
          XCreatePixmap(this->DisplayId,
                        XRootWindow(this->DisplayId,v->screen),
                        static_cast<unsigned int>(width),
                        static_cast<unsigned int>(height),
                        static_cast<unsigned int>(v->depth));
921 922 923 924 925 926 927 928 929

        this->Internal->PixmapWindowId = glXCreateGLXPixmap(this->DisplayId, v, this->Internal->pixmap);
        glXMakeCurrent(this->DisplayId,this->Internal->PixmapWindowId,
                       this->Internal->PixmapContextId);

        if(v)
          {
          XFree(v);
          }
930
        }
931
      } // if not hardware offscreen
932
    }
933
  this->Mapped = 0;
934 935
  this->Size[0] = width;
  this->Size[1] = height;
936 937


938 939 940 941
  this->MakeCurrent();

  // tell our renderers about us
  vtkRenderer* ren;
942
  for (this->Renderers->InitTraversal();
943 944 945 946 947 948 949 950 951 952 953
       (ren = this->Renderers->GetNextItem());)
    {
    ren->SetRenderWindow(0);
    ren->SetRenderWindow(this);
    }

  this->OpenGLInit();
}

void vtkXOpenGLRenderWindow::DestroyOffScreenWindow()
{
954

955 956 957 958 959 960 961 962 963 964 965
  // release graphic resources.
  vtkRenderer *ren;
  vtkCollectionSimpleIterator rit;
  this->Renderers->InitTraversal(rit);
  while ( (ren = this->Renderers->GetNextRenderer(rit)) )
    {
    ren->SetRenderWindow(NULL);
    ren->SetRenderWindow(this);
    }


966
#ifdef VTK_USE_OSMESA
967 968 969 970 971 972 973 974 975 976
  if (this->Internal->OffScreenContextId)
    {
    OSMesaDestroyContext(this->Internal->OffScreenContextId);
    this->Internal->OffScreenContextId = NULL;
    vtkOSMesaDestroyWindow(this->Internal->OffScreenWindow);
    this->Internal->OffScreenWindow = NULL;
    }
  else
#endif
    {
977
    if(this->OffScreenUseFrameBuffer)
978
      {
979
      this->DestroyHardwareOffScreenWindow();
980
      }
981
    else
982
      {
983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
      if(this->Internal->PbufferContextId)
        {
        vtkglX::DestroyPbuffer(this->DisplayId, this->Internal->Pbuffer);
        this->Internal->Pbuffer = 0;
        glXDestroyContext(this->DisplayId, this->Internal->PbufferContextId);
        this->Internal->PbufferContextId = NULL;
        }
      else if(this->Internal->PixmapContextId)
        {
        glXDestroyGLXPixmap(this->DisplayId, this->Internal->PixmapWindowId);
        this->Internal->PixmapWindowId = 0;
        XFreePixmap(this->DisplayId, this->Internal->pixmap);
        glXDestroyContext( this->DisplayId, this->Internal->PixmapContextId);
        this->Internal->PixmapContextId = NULL;
        }
998 999 1000 1001
      }
    }
}

1002
void vtkXOpenGLRenderWindow::ResizeOffScreenWindow(int width, int height)
1003 1004 1005 1006 1007 1008
{
  if(!this->OffScreenRendering)
    {
    return;
    }

1009 1010
  // Generally, we simply destroy and recreate the offscreen window/contexts.
  // However, that's totally unnecessary for OSMesa. So we avoid that.
1011
#ifdef VTK_USE_OSMESA
1012 1013 1014 1015 1016 1017 1018 1019
  if (this->Internal->OffScreenContextId && this->Internal->OffScreenWindow)
    {
    vtkOSMesaDestroyWindow(this->Internal->OffScreenWindow);
    this->Internal->OffScreenWindow = NULL;

    // allocate new one.
    this->Internal->OffScreenWindow = vtkOSMesaCreateWindow(width,height);
    this->Size[0] = width;
1020
    this->Size[1] = height;
1021 1022 1023 1024 1025
    this->OwnWindow = 1;
    return;
    }
#endif

1026
  if(this->Internal->PixmapContextId ||
1027 1028
     this->Internal->PbufferContextId ||
     this->OffScreenUseFrameBuffer
1029
    )
1030 1031
    {
    this->DestroyOffScreenWindow();
1032
    this->CreateOffScreenWindow(width, height);
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045
    }
}


// Initialize the window for rendering.
void vtkXOpenGLRenderWindow::WindowInitialize (void)
{
  this->CreateAWindow();

  this->MakeCurrent();

  // tell our renderers about us
  vtkRenderer* ren;
1046
  for (this->Renderers->InitTraversal();
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
       (ren = this->Renderers->GetNextItem());)
    {
    ren->SetRenderWindow(0);
    ren->SetRenderWindow(this);
    }

  this->OpenGLInit();
}

// Initialize the rendering window.
void vtkXOpenGLRenderWindow::Initialize (void)
{
  if(!this->OffScreenRendering && !this->Internal->ContextId)
    {
1061
    // initialize the window
1062 1063
    this->WindowInitialize();
    }
1064
  else if(this->OffScreenRendering &&
1065
          ! (this->Internal->PixmapContextId ||
1066
             this->Internal->PbufferContextId
1067
#ifdef VTK_USE_OSMESA
1068
             || this->Internal->OffScreenContextId
1069
#endif
1070 1071
             || this->OffScreenUseFrameBuffer
            ))
1072 1073 1074 1075
    {
    // initialize offscreen window
    int width = ((this->Size[0] > 0) ? this->Size[0] : 300);
    int height = ((this->Size[1] > 0) ? this->Size[1] : 300);
1076
    this->CreateOffScreenWindow(width, height);
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
    }
}

void vtkXOpenGLRenderWindow::Finalize (void)
{

  // clean up offscreen stuff
  this->SetOffScreenRendering(0);

  // clean and destroy window
  this->DestroyWindow();

}

Ken Martin's avatar
Ken Martin committed
1091 1092 1093 1094
// Change the window to fill the entire screen.
void vtkXOpenGLRenderWindow::SetFullScreen(int arg)
{
  int *temp;
1095

1096 1097 1098 1099
  if (this->OffScreenRendering)
    {
    return;
    }
1100

Ken Martin's avatar
Ken Martin committed
1101
  if (this->FullScreen == arg) return;
1102

Ken Martin's avatar
Ken Martin committed
1103 1104 1105 1106 1107 1108
  if (!this->Mapped)
    {
    this->PrefFullScreen();
    return;
    }

1109
  // set the mode
Ken Martin's avatar
Ken Martin committed
1110 1111 1112 1113 1114
  this->FullScreen = arg;
  if (this->FullScreen <= 0)
    {
    this->Position[0] = this->OldScreen[0];
    this->Position[1] = this->OldScreen[1];
1115
    this->Size[0] = this->OldScreen[2];
Ken Martin's avatar
Ken Martin committed
1116 1117 1118 1119 1120
    this->Size[1] = this->OldScreen[3];
    this->Borders = this->OldScreen[4];
    }
  else
    {
1121
    // if window already up get its values
Ken Martin's avatar
Ken Martin committed
1122 1123 1124
    if (this->WindowId)
      {
      XWindowAttributes attribs;
1125 1126 1127

      //  Find the current window size
      XGetWindowAttributes(this->DisplayId,
1128
                           this->WindowId, &attribs);
1129

Ken Martin's avatar
Ken Martin committed
1130 1131 1132
      this->OldScreen[2] = attribs.width;
      this->OldScreen[3] = attribs.height;;

1133
      temp = this->GetPosition();
Ken Martin's avatar
Ken Martin committed
1134 1135 1136 1137 1138 1139 1140
      this->OldScreen[0] = temp[0];
      this->OldScreen[1] = temp[1];

      this->OldScreen[4] = this->Borders;
      this->PrefFullScreen();
      }
    }
1141 1142

  // remap the window
Ken Martin's avatar
Ken Martin committed
1143 1144 1145 1146 1147 1148 1149 1150
  this->WindowRemap();

  this->Modified();
}

// Set the preferred window size to full screen.
void vtkXOpenGLRenderWindow::PrefFullScreen()
{
1151
  // use full screen
Ken Martin's avatar
Ken Martin committed
1152 1153 1154
  this->Position[0] = 0;
  this->Position[1] = 0;

1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
  if (this->OffScreenRendering)
    {
    this->Size[0] = 1280;
    this->Size[1] = 1024;
    }
  else
    {
    int *size;
    size = this->GetScreenSize();
    this->Size[0] = size[0];
    this->Size[1] = size[1];
    }
1167 1168

  // don't show borders
Ken Martin's avatar
Ken Martin committed
1169 1170 1171 1172 1173 1174
  this->Borders = 0;
}

// Resize the window.
void vtkXOpenGLRenderWindow::WindowRemap()
{
1175
  // shut everything down
1176
  this->Finalize();
Ken Martin's avatar
Ken Martin committed
1177

1178
  // set the default windowid
Ken Martin's avatar
Ken Martin committed
1179
  this->WindowId = this->NextWindowId;
1180
  this->NextWindowId = static_cast<Window>(NULL);
Ken Martin's avatar
Ken Martin committed
1181

1182
  // set everything up again
1183
  this->Initialize();
Ken Martin's avatar
Ken Martin committed
1184 1185 1186 1187 1188
}

// Begin the rendering process.
void vtkXOpenGLRenderWindow::Start(void)
{
1189
  this->Initialize();
Ken Martin's avatar
Ken Martin committed
1190

1191
  // set the current window
Ken Martin's avatar
Ken Martin committed
1192 1193 1194 1195 1196
  this->MakeCurrent();
}


// Specify the size of the rendering window.
1197
void vtkXOpenGLRenderWindow::SetSize(int width,int height)
Ken Martin's avatar
Ken Martin committed
1198
{
1199
  if ((this->Size[0] != width)||(this->Size[1] != height))
Ken Martin's avatar
Ken Martin committed
1200
    {
1201 1202
    this->Size[0] = width;
    this->Size[1] = height;
1203

1204 1205 1206 1207 1208
    if (this->Interactor)
      {
      this->Interactor->SetSize( width, height );
      }

1209 1210 1211 1212 1213 1214
    if(this->OffScreenRendering)
      {
      this->ResizeOffScreenWindow(width,height);
      }
    else if(this->WindowId && this->Mapped)
      {
Francois Bertel's avatar
Francois Bertel committed
1215 1216 1217
      XResizeWindow(this->DisplayId,this->WindowId,
                    static_cast<unsigned int>(width),
                    static_cast<unsigned int>(height));
1218 1219 1220 1221
      XSync(this->DisplayId,False);
      }

    this->Modified();
Ken Martin's avatar
Ken Martin committed
1222 1223 1224 1225 1226 1227 1228 1229 1230
    }
}



int vtkXOpenGLRenderWindow::GetDesiredDepth()
{
  XVisualInfo *v;
  int depth = 0;
1231 1232

  // get the default visual to use
Ken Martin's avatar
Ken Martin committed
1233
  v = this->GetDesiredVisualInfo();
1234

Ken Martin's avatar
Ken Martin committed
1235 1236
  if (v)
    {
1237
    depth = v->depth;
Ken Martin's avatar
Ken Martin committed
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
    XFree(v);
    }

  return depth;
}

// Get a visual from the windowing system.
Visual *vtkXOpenGLRenderWindow::GetDesiredVisual ()
{
  XVisualInfo *v;
1248
  Visual *vis=0;
1249 1250

  // get the default visual to use
Ken Martin's avatar
Ken Martin committed
1251 1252 1253 1254
  v = this->GetDesiredVisualInfo();

  if (v)
    {
1255
    vis = v->visual;
Ken Martin's avatar
Ken Martin committed
1256 1257
    XFree(v);
    }
1258 1259

  return vis;
Ken Martin's avatar
Ken Martin committed
1260 1261 1262 1263 1264 1265 1266
}


// Get a colormap from the windowing system.
Colormap vtkXOpenGLRenderWindow::GetDesiredColormap ()
{
  XVisualInfo *v;
1267

Ken Martin's avatar
Ken Martin committed
1268
  if (this->ColorMap) return this->ColorMap;
1269 1270

  // get the default visual to use
Ken Martin's avatar
Ken Martin committed
1271 1272 1273 1274
  v = this->GetDesiredVisualInfo();

  if (v)
    {
1275
    this->ColorMap = XCreateColormap(this->DisplayId,
Francois Bertel's avatar
Francois Bertel committed
1276 1277
                                     XRootWindow(this->DisplayId, v->screen),
                                     v->visual, AllocNone);
Ken Martin's avatar
Ken Martin committed
1278 1279 1280
    XFree(v);
    }

1281
  return this->ColorMap;
Ken Martin's avatar
Ken Martin committed
1282 1283 1284 1285
}

void vtkXOpenGLRenderWindow::PrintSelf(ostream& os, vtkIndent indent)
{
Brad King's avatar
Brad King committed
1286
  this->Superclass::PrintSelf(os,indent);
Ken Martin's avatar
Ken Martin committed
1287

1288
  os << indent << "ContextId: " << this->Internal->ContextId << "\n";
1289
#ifdef VTK_USE_OSMESA
1290
  os << indent << "OffScreenContextId: " << this->Internal->OffScreenContextId << "\n";
1291
#endif
Ken Martin's avatar
Ken Martin committed
1292 1293 1294 1295
  os << indent << "Color Map: " << this->ColorMap << "\n";
  os << indent << "Display Id: " << this->GetDisplayId() << "\n";
  os << indent << "Next Window Id: " << this->NextWindowId << "\n";
  os << indent << "Window Id: " << this->GetWindowId() << "\n";
Ken Martin's avatar
Ken Martin committed
1296 1297 1298
}

// the following can be useful for debugging XErrors
1299 1300
// When uncommented (along with the lines in MakeCurrent)
// it will cause a segfault upon an XError instead of
Ken Martin's avatar
Ken Martin committed
1301
// the normal XError handler
Bill Hoffman's avatar
Bill Hoffman committed
1302 1303 1304 1305 1306 1307
//  extern "C" {int vtkXError(Display *display, XErrorEvent *err)
//  {
//  // cause a segfault
//    *(float *)(0x01) = 1.0;
//    return 1;
//  }}
Ken Martin's avatar
Ken Martin committed
1308 1309 1310 1311

void vtkXOpenGLRenderWindow::MakeCurrent()
{
  // when debugging XErrors uncomment the following lines
Bill Hoffman's avatar
Bill Hoffman committed
1312 1313 1314 1315 1316
//    if (this->DisplayId)
//      {
//        XSynchronize(this->DisplayId,1);
//      }
//     XSetErrorHandler(vtkXError);
1317
#ifdef VTK_USE_OSMESA
1318