浏览代码

use GLXFBConfig instead of XVisualInfo

David Rose 22 年之前
父节点
当前提交
3517fa4bf9

+ 81 - 67
panda/src/glxdisplay/glxGraphicsPipe.cxx

@@ -23,8 +23,6 @@
 #include "frameBufferProperties.h"
 #include "frameBufferProperties.h"
 #include "mutexHolder.h"
 #include "mutexHolder.h"
 
 
-#include <GL/glx.h>
-
 TypeHandle glxGraphicsPipe::_type_handle;
 TypeHandle glxGraphicsPipe::_type_handle;
 
 
 bool glxGraphicsPipe::_error_handlers_installed = false;
 bool glxGraphicsPipe::_error_handlers_installed = false;
@@ -164,14 +162,17 @@ make_gsg(const FrameBufferProperties &properties) {
   }
   }
   
   
   FrameBufferProperties new_properties = properties;
   FrameBufferProperties new_properties = properties;
-  XVisualInfo *visual = choose_visual(new_properties);
+  GLXFBConfig fbconfig = choose_fbconfig(new_properties);
+  if (fbconfig == None) {
+    return NULL;
+  }
 
 
   // Attempt to create a GL context.
   // Attempt to create a GL context.
-  GLXContext context = glXCreateContext(_display, visual, None, GL_TRUE);
+  GLXContext context = 
+    glXCreateNewContext(_display, fbconfig, GLX_RGBA_TYPE, NULL, GL_TRUE);
   if (context == NULL) {
   if (context == NULL) {
     glxdisplay_cat.error()
     glxdisplay_cat.error()
       << "Could not create GL context.\n";
       << "Could not create GL context.\n";
-    XFree(visual);
     return NULL;
     return NULL;
   }
   }
 
 
@@ -179,7 +180,7 @@ make_gsg(const FrameBufferProperties &properties) {
   PT(glxGraphicsStateGuardian) gsg = 
   PT(glxGraphicsStateGuardian) gsg = 
     new glxGraphicsStateGuardian(new_properties);
     new glxGraphicsStateGuardian(new_properties);
   gsg->_context = context;
   gsg->_context = context;
-  gsg->_visual = visual;
+  gsg->_fbconfig = fbconfig;
   gsg->_display = _display;
   gsg->_display = _display;
 
 
   return gsg.p();
   return gsg.p();
@@ -200,17 +201,17 @@ make_window(GraphicsStateGuardian *gsg) {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: glxGraphicsPipe::choose visual
+//     Function: glxGraphicsPipe::choose_fbconfig
 //       Access: Private
 //       Access: Private
-//  Description: Selects an appropriate X visual for the given frame
-//               buffer properties.  Returns the visual pointer if
-//               successful, or NULL otherwise.
+//  Description: Selects an appropriate GLXFBConfig for the given
+//               frame buffer properties.  Returns the selected
+//               fbconfig if successful, or None otherwise.
 //
 //
 //               If successful, this may modify properties to reflect
 //               If successful, this may modify properties to reflect
 //               the actual visual chosen.
 //               the actual visual chosen.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-XVisualInfo *glxGraphicsPipe::
-choose_visual(FrameBufferProperties &properties) const {
+GLXFBConfig glxGraphicsPipe::
+choose_fbconfig(FrameBufferProperties &properties) const {
   int frame_buffer_mode = 0;
   int frame_buffer_mode = 0;
   int want_depth_bits = 0;
   int want_depth_bits = 0;
   int want_color_bits = 0;
   int want_color_bits = 0;
@@ -237,29 +238,29 @@ choose_visual(FrameBufferProperties &properties) const {
   }
   }
   */
   */
 
 
-  XVisualInfo *visual = 
-    try_for_visual(frame_buffer_mode, want_depth_bits, want_color_bits);
+  GLXFBConfig fbconfig = 
+    try_for_fbconfig(frame_buffer_mode, want_depth_bits, want_color_bits);
 
 
   // This is the severity level at which we'll report the details of
   // This is the severity level at which we'll report the details of
-  // the visual we actually do find.  Normally, it's debug-level
+  // the fbconfig we actually do find.  Normally, it's debug-level
   // information: we don't care about that much detail.
   // information: we don't care about that much detail.
-  NotifySeverity show_visual_severity = NS_debug;
+  NotifySeverity show_fbconfig_severity = NS_debug;
 
 
-  if (visual == NULL) {
+  if (fbconfig == NULL) {
     glxdisplay_cat.info()
     glxdisplay_cat.info()
-      << "glxGraphicsWindow::choose_visual() - visual with requested\n"
-      << "   capabilities not found; trying for lesser visual.\n";
+      << "glxGraphicsWindow::choose_fbconfig() - fbconfig with requested "
+      << "capabilities not found; trying for lesser fbconfig.\n";
 
 
-    // If we're unable to get the visual we asked for, however, we
+    // If we're unable to get the fbconfig we asked for, however, we
     // probably *do* care to know the details about what we actually
     // probably *do* care to know the details about what we actually
     // got, even if we don't have debug mode set.  So we'll report the
     // got, even if we don't have debug mode set.  So we'll report the
-    // visual at a higher level.
-    show_visual_severity = NS_info;
+    // fbconfig at a higher level.
+    show_fbconfig_severity = NS_info;
 
 
     bool special_size_request =
     bool special_size_request =
       (want_depth_bits != 1 || want_color_bits != 1);
       (want_depth_bits != 1 || want_color_bits != 1);
 
 
-    // We try to be smart about choosing a close match for the visual.
+    // We try to be smart about choosing a close match for the fbconfig.
     // First, we'll eliminate some of the more esoteric options one at
     // First, we'll eliminate some of the more esoteric options one at
     // a time, then two at a time, and finally we'll try just the bare
     // a time, then two at a time, and finally we'll try just the bare
     // minimum.
     // minimum.
@@ -268,10 +269,10 @@ choose_visual(FrameBufferProperties &properties) const {
       // Actually, first we'll eliminate all of the minimum sizes, to
       // Actually, first we'll eliminate all of the minimum sizes, to
       // try to open a window with all of the requested options, but
       // try to open a window with all of the requested options, but
       // maybe not as many bits in some options as we'd like.
       // maybe not as many bits in some options as we'd like.
-      visual = try_for_visual(frame_buffer_mode, 1, 1);
+      fbconfig = try_for_fbconfig(frame_buffer_mode, 1, 1);
     }
     }
 
 
-    if (visual == NULL) {
+    if (fbconfig == NULL) {
       // Ok, not good enough.  Now try to eliminate options, but keep
       // Ok, not good enough.  Now try to eliminate options, but keep
       // as many bits as we asked for.
       // as many bits as we asked for.
 
 
@@ -311,11 +312,11 @@ choose_visual(FrameBufferProperties &properties) const {
       tried_masks.insert(frame_buffer_mode);
       tried_masks.insert(frame_buffer_mode);
 
 
       int i;
       int i;
-      for (i = 0; visual == NULL && strip_properties[i] != 0; i++) {
+      for (i = 0; fbconfig == NULL && strip_properties[i] != 0; i++) {
         int new_frame_buffer_mode = frame_buffer_mode & ~strip_properties[i];
         int new_frame_buffer_mode = frame_buffer_mode & ~strip_properties[i];
         if (tried_masks.insert(new_frame_buffer_mode).second) {
         if (tried_masks.insert(new_frame_buffer_mode).second) {
-          visual = try_for_visual(new_frame_buffer_mode, want_depth_bits,
-                                  want_color_bits);
+          fbconfig = try_for_fbconfig(new_frame_buffer_mode, want_depth_bits,
+                                      want_color_bits);
         }
         }
       }
       }
 
 
@@ -323,53 +324,53 @@ choose_visual(FrameBufferProperties &properties) const {
         tried_masks.clear();
         tried_masks.clear();
         tried_masks.insert(frame_buffer_mode);
         tried_masks.insert(frame_buffer_mode);
 
 
-        if (visual == NULL) {
+        if (fbconfig == NULL) {
           // Try once more, this time eliminating all of the size
           // Try once more, this time eliminating all of the size
           // requests.
           // requests.
-          for (i = 0; visual == NULL && strip_properties[i] != 0; i++) {
+          for (i = 0; fbconfig == NULL && strip_properties[i] != 0; i++) {
             int new_frame_buffer_mode = frame_buffer_mode & ~strip_properties[i];
             int new_frame_buffer_mode = frame_buffer_mode & ~strip_properties[i];
             if (tried_masks.insert(new_frame_buffer_mode).second) {
             if (tried_masks.insert(new_frame_buffer_mode).second) {
-              visual = try_for_visual(new_frame_buffer_mode, 1, 1);
+              fbconfig = try_for_fbconfig(new_frame_buffer_mode, 1, 1);
             }
             }
           }
           }
         }
         }
       }
       }
 
 
-      if (visual == NULL) {
+      if (fbconfig == NULL) {
         // Here's our last-ditch desparation attempt: give us any GLX
         // Here's our last-ditch desparation attempt: give us any GLX
-        // visual at all!
-        visual = try_for_visual(0, 1, 1);
+        // fbconfig at all!
+        fbconfig = try_for_fbconfig(0, 1, 1);
       }
       }
 
 
-      if (visual == NULL) {
+      if (fbconfig == NULL) {
         glxdisplay_cat.error()
         glxdisplay_cat.error()
-          << "Could not get any GLX visual.\n";
+          << "Could not get any GLX fbconfig.\n";
         return NULL;
         return NULL;
       }
       }
     }
     }
   }
   }
 
 
   glxdisplay_cat.info()
   glxdisplay_cat.info()
-    << "Got visual 0x" << hex << (int)visual->visualid << dec << ".\n";
+    << "Selected suitable GLX fbconfig.\n";
 
 
   // Now update our frambuffer_mode and bit depth appropriately.
   // Now update our frambuffer_mode and bit depth appropriately.
   int render_mode, double_buffer, stereo, red_size, green_size, blue_size,
   int render_mode, double_buffer, stereo, red_size, green_size, blue_size,
     alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
     alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
     depth_size, stencil_size;
     depth_size, stencil_size;
   
   
-  glXGetConfig(_display, visual, GLX_RGBA, &render_mode);
-  glXGetConfig(_display, visual, GLX_DOUBLEBUFFER, &double_buffer);
-  glXGetConfig(_display, visual, GLX_STEREO, &stereo);
-  glXGetConfig(_display, visual, GLX_RED_SIZE, &red_size);
-  glXGetConfig(_display, visual, GLX_GREEN_SIZE, &green_size);
-  glXGetConfig(_display, visual, GLX_BLUE_SIZE, &blue_size);
-  glXGetConfig(_display, visual, GLX_ALPHA_SIZE, &alpha_size);
-  glXGetConfig(_display, visual, GLX_ACCUM_RED_SIZE, &ared_size);
-  glXGetConfig(_display, visual, GLX_ACCUM_GREEN_SIZE, &agreen_size);
-  glXGetConfig(_display, visual, GLX_ACCUM_BLUE_SIZE, &ablue_size);
-  glXGetConfig(_display, visual, GLX_ACCUM_ALPHA_SIZE, &aalpha_size);
-  glXGetConfig(_display, visual, GLX_DEPTH_SIZE, &depth_size);
-  glXGetConfig(_display, visual, GLX_STENCIL_SIZE, &stencil_size);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_RGBA, &render_mode);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_DOUBLEBUFFER, &double_buffer);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_STEREO, &stereo);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_RED_SIZE, &red_size);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_GREEN_SIZE, &green_size);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_BLUE_SIZE, &blue_size);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_ALPHA_SIZE, &alpha_size);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_ACCUM_RED_SIZE, &ared_size);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_ACCUM_GREEN_SIZE, &agreen_size);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_ACCUM_BLUE_SIZE, &ablue_size);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_ACCUM_ALPHA_SIZE, &aalpha_size);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_DEPTH_SIZE, &depth_size);
+  glXGetFBConfigAttrib(_display, fbconfig, GLX_STENCIL_SIZE, &stencil_size);
 
 
   frame_buffer_mode = 0;
   frame_buffer_mode = 0;
   if (double_buffer) {
   if (double_buffer) {
@@ -398,9 +399,9 @@ choose_visual(FrameBufferProperties &properties) const {
   properties.set_color_bits(red_size + green_size + blue_size + alpha_size);
   properties.set_color_bits(red_size + green_size + blue_size + alpha_size);
   properties.set_depth_bits(depth_size);
   properties.set_depth_bits(depth_size);
 
 
-  if (glxdisplay_cat.is_on(show_visual_severity)) {
-    glxdisplay_cat.out(show_visual_severity)
-      << "GLX Visual Info (# bits of each):" << endl
+  if (glxdisplay_cat.is_on(show_fbconfig_severity)) {
+    glxdisplay_cat.out(show_fbconfig_severity)
+      << "GLX Fbconfig Info (# bits of each):" << endl
       << " RGBA: " << red_size << " " << green_size << " " << blue_size
       << " RGBA: " << red_size << " " << green_size << " " << blue_size
       << " " << alpha_size << endl
       << " " << alpha_size << endl
       << " Accum RGBA: " << ared_size << " " << agreen_size << " "
       << " Accum RGBA: " << ared_size << " " << agreen_size << " "
@@ -411,26 +412,26 @@ choose_visual(FrameBufferProperties &properties) const {
       << " Stereo? " << stereo << endl;
       << " Stereo? " << stereo << endl;
   }
   }
 
 
-  return visual;
+  return fbconfig;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: glxGraphicsPipe::try_for_visual
+//     Function: glxGraphicsPipe::try_for_fbconfig
 //       Access: Private
 //       Access: Private
-//  Description: Attempt to get the requested visual, if it is
+//  Description: Attempt to get the requested fbconfig, if it is
 //               available.  It's just a wrapper around
 //               available.  It's just a wrapper around
-//               glXChooseVisual().  It returns the visual information
-//               if possible, or NULL if it is not.
+//               glXChooseFBConfig().  It returns the fbconfig
+//               information if possible, or NULL if it is not.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-XVisualInfo *glxGraphicsPipe::
-try_for_visual(int framebuffer_mode,
-               int want_depth_bits, int want_color_bits) const {
+GLXFBConfig glxGraphicsPipe::
+try_for_fbconfig(int framebuffer_mode,
+                 int want_depth_bits, int want_color_bits) const {
   static const int max_attrib_list = 32;
   static const int max_attrib_list = 32;
   int attrib_list[max_attrib_list];
   int attrib_list[max_attrib_list];
   int n=0;
   int n=0;
 
 
   glxdisplay_cat.debug()
   glxdisplay_cat.debug()
-    << "Trying for visual with: RGB(" << want_color_bits << ")";
+    << "Trying for fbconfig with: RGB(" << want_color_bits << ")";
 
 
   int want_color_component_bits;
   int want_color_component_bits;
   if (framebuffer_mode & FrameBufferProperties::FM_alpha) {
   if (framebuffer_mode & FrameBufferProperties::FM_alpha) {
@@ -439,7 +440,6 @@ try_for_visual(int framebuffer_mode,
     want_color_component_bits = max(want_color_bits / 3, 1);
     want_color_component_bits = max(want_color_bits / 3, 1);
   }
   }
 
 
-  attrib_list[n++] = GLX_RGBA;
   attrib_list[n++] = GLX_RED_SIZE;
   attrib_list[n++] = GLX_RED_SIZE;
   attrib_list[n++] = want_color_component_bits;
   attrib_list[n++] = want_color_component_bits;
   attrib_list[n++] = GLX_GREEN_SIZE;
   attrib_list[n++] = GLX_GREEN_SIZE;
@@ -455,10 +455,12 @@ try_for_visual(int framebuffer_mode,
   if (framebuffer_mode & FrameBufferProperties::FM_double_buffer) {
   if (framebuffer_mode & FrameBufferProperties::FM_double_buffer) {
     glxdisplay_cat.debug(false) << " DOUBLEBUFFER";
     glxdisplay_cat.debug(false) << " DOUBLEBUFFER";
     attrib_list[n++] = GLX_DOUBLEBUFFER;
     attrib_list[n++] = GLX_DOUBLEBUFFER;
+    attrib_list[n++] = true;
   }
   }
   if (framebuffer_mode & FrameBufferProperties::FM_stereo) {
   if (framebuffer_mode & FrameBufferProperties::FM_stereo) {
     glxdisplay_cat.debug(false) << " STEREO";
     glxdisplay_cat.debug(false) << " STEREO";
     attrib_list[n++] = GLX_STEREO;
     attrib_list[n++] = GLX_STEREO;
+    attrib_list[n++] = true;
   }
   }
   if (framebuffer_mode & FrameBufferProperties::FM_depth) {
   if (framebuffer_mode & FrameBufferProperties::FM_depth) {
     glxdisplay_cat.debug(false) << " DEPTH(" << want_depth_bits << ")";
     glxdisplay_cat.debug(false) << " DEPTH(" << want_depth_bits << ")";
@@ -496,17 +498,29 @@ try_for_visual(int framebuffer_mode,
   nassertr(n < max_attrib_list, NULL);
   nassertr(n < max_attrib_list, NULL);
   attrib_list[n] = (int)None;
   attrib_list[n] = (int)None;
 
 
-  XVisualInfo *vinfo = glXChooseVisual(_display, _screen, attrib_list);
+  int num_configs = 0;
+  GLXFBConfig *configs = 
+    glXChooseFBConfig(_display, _screen, attrib_list, &num_configs);
 
 
   if (glxdisplay_cat.is_debug()) {
   if (glxdisplay_cat.is_debug()) {
-    if (vinfo != NULL) {
-      glxdisplay_cat.debug(false) << ", match found!\n";
+    if (configs != NULL) {
+      glxdisplay_cat.debug(false) 
+        << ", " << num_configs << " matches found!\n";
     } else {
     } else {
       glxdisplay_cat.debug(false) << ", no match.\n";
       glxdisplay_cat.debug(false) << ", no match.\n";
     }
     }
   }
   }
 
 
-  return vinfo;
+  if (configs == NULL || num_configs == 0) {
+    return None;
+  }
+
+  // Pick the first matching fbconfig; this will be the "best" one
+  // according to the GLX specifics.
+  GLXFBConfig fbconfig = configs[0];
+  XFree(configs);
+
+  return fbconfig;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 19 - 4
panda/src/glxdisplay/glxGraphicsPipe.h

@@ -23,7 +23,6 @@
 #include "graphicsWindow.h"
 #include "graphicsWindow.h"
 #include "graphicsPipe.h"
 #include "graphicsPipe.h"
 
 
-class glxGraphicsWindow;
 class FrameBufferProperties;
 class FrameBufferProperties;
 
 
 #ifdef CPPPARSER
 #ifdef CPPPARSER
@@ -32,6 +31,8 @@ typedef int Display;
 typedef int Window;
 typedef int Window;
 typedef int XErrorEvent;
 typedef int XErrorEvent;
 typedef int XVisualInfo;
 typedef int XVisualInfo;
+typedef int GLXFBConfig;
+typedef int GLXPbuffer;
 typedef int Atom;
 typedef int Atom;
 typedef int XIM;
 typedef int XIM;
 typedef int XIC;
 typedef int XIC;
@@ -40,6 +41,20 @@ typedef int XIC;
 #include <GL/glx.h>
 #include <GL/glx.h>
 #endif  // CPPPARSER
 #endif  // CPPPARSER
 
 
+#ifndef GLX_VERSION_1_3
+  // Pre-glx 1.3, these GLXFBConfig definitions might have been
+  // defined as SGI extensions.
+  #define GLX_RGBA_TYPE GLX_RGBA_TYPE_SGIX
+  #define GLXFBConfig GLXFBConfigSGIX
+  #define glXChooseFBConfig glXChooseFBConfigSGIX
+  #define glXCreateNewContext glXCreateContextWithConfigSGIX
+  #define glXGetVisualFromFBConfig glXGetVisualFromFBConfigSGIX
+  #define glXGetFBConfigAttrib glXGetFBConfigAttribSGIX
+  #define glXCreatePbuffer glXCreateGLXPbufferSGIX
+  #define glXDestroyPbuffer glXDestroyGLXPbufferSGIX
+#endif // GLX_VERSION_1_3
+
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : glxGraphicsPipe
 //       Class : glxGraphicsPipe
 // Description : This graphics pipe represents the interface for
 // Description : This graphics pipe represents the interface for
@@ -66,9 +81,9 @@ protected:
   virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg);
   virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg);
 
 
 private:
 private:
-  XVisualInfo *choose_visual(FrameBufferProperties &properties) const;
-  XVisualInfo *try_for_visual(int framebuffer_mode,
-                              int want_depth_bits, int want_color_bits) const;
+  GLXFBConfig choose_fbconfig(FrameBufferProperties &properties) const;
+  GLXFBConfig try_for_fbconfig(int framebuffer_mode,
+                               int want_depth_bits, int want_color_bits) const;
 
 
   static void install_error_handlers();
   static void install_error_handlers();
   static int error_handler(Display *display, XErrorEvent *error);
   static int error_handler(Display *display, XErrorEvent *error);

+ 0 - 6
panda/src/glxdisplay/glxGraphicsStateGuardian.cxx

@@ -31,7 +31,6 @@ glxGraphicsStateGuardian(const FrameBufferProperties &properties) :
   GLGraphicsStateGuardian(properties)
   GLGraphicsStateGuardian(properties)
 {
 {
   _context = (GLXContext)NULL;
   _context = (GLXContext)NULL;
-  _visual = (XVisualInfo *)NULL;
   _display = NULL;
   _display = NULL;
 }
 }
 
 
@@ -42,11 +41,6 @@ glxGraphicsStateGuardian(const FrameBufferProperties &properties) :
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 glxGraphicsStateGuardian::
 glxGraphicsStateGuardian::
 ~glxGraphicsStateGuardian() {
 ~glxGraphicsStateGuardian() {
-  if (_visual != (XVisualInfo *)NULL) {
-    XFree(_visual);
-    _visual = (XVisualInfo *)NULL;
-  }
-
   if (_context != (GLXContext)NULL) {
   if (_context != (GLXContext)NULL) {
     glXDestroyContext(_display, _context);
     glXDestroyContext(_display, _context);
     _context = (GLXContext)NULL;
     _context = (GLXContext)NULL;

+ 2 - 4
panda/src/glxdisplay/glxGraphicsStateGuardian.h

@@ -22,9 +22,7 @@
 #include "pandabase.h"
 #include "pandabase.h"
 
 
 #include "glGraphicsStateGuardian.h"
 #include "glGraphicsStateGuardian.h"
-
-#include <X11/Xlib.h>
-#include <GL/glx.h>
+#include "glxGraphicsPipe.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : glxGraphicsStateGuardian
 //       Class : glxGraphicsStateGuardian
@@ -37,7 +35,7 @@ public:
   virtual ~glxGraphicsStateGuardian();
   virtual ~glxGraphicsStateGuardian();
 
 
   GLXContext _context;
   GLXContext _context;
-  XVisualInfo *_visual;
+  GLXFBConfig _fbconfig;
   Display *_display;
   Display *_display;
 
 
 public:
 public:

+ 35 - 16
panda/src/glxdisplay/glxGraphicsWindow.cxx

@@ -406,6 +406,24 @@ open_window() {
     return false;
     return false;
   }
   }
 
 
+  glxGraphicsPipe *glx_pipe;
+  DCAST_INTO_R(glx_pipe, _pipe, false);
+  glxGraphicsStateGuardian *glxgsg;
+  DCAST_INTO_R(glxgsg, _gsg, false);
+
+  XVisualInfo *visual_info = 
+    glXGetVisualFromFBConfig(_display, glxgsg->_fbconfig);
+  if (visual_info == NULL) {
+    // No X visual for this fbconfig; how can we open the window?
+    glxdisplay_cat.error()
+      << "Cannot open window without an X visual.\n";
+    return false;
+  }
+  Visual *visual = visual_info->visual;
+  int depth = visual_info->depth;
+  XFree(visual_info);
+
+
   if (!_properties.has_origin()) {
   if (!_properties.has_origin()) {
     _properties.set_origin(0, 0);
     _properties.set_origin(0, 0);
   }
   }
@@ -413,14 +431,9 @@ open_window() {
     _properties.set_size(100, 100);
     _properties.set_size(100, 100);
   }
   }
 
 
-  glxGraphicsPipe *glx_pipe;
-  DCAST_INTO_R(glx_pipe, _pipe, false);
-  glxGraphicsStateGuardian *glxgsg;
-  DCAST_INTO_R(glxgsg, _gsg, false);
-
   Window root_window = glx_pipe->get_root();
   Window root_window = glx_pipe->get_root();
 
 
-  setup_colormap(glxgsg->_visual);
+  setup_colormap(glxgsg->_fbconfig);
 
 
   _event_mask =
   _event_mask =
     ButtonPressMask | ButtonReleaseMask |
     ButtonPressMask | ButtonReleaseMask |
@@ -444,9 +457,7 @@ open_window() {
     (_display, root_window,
     (_display, root_window,
      _properties.get_x_origin(), _properties.get_y_origin(),
      _properties.get_x_origin(), _properties.get_y_origin(),
      _properties.get_x_size(), _properties.get_y_size(),
      _properties.get_x_size(), _properties.get_y_size(),
-     0,
-     glxgsg->_visual->depth, InputOutput, glxgsg->_visual->visual, 
-     attrib_mask, &wa);
+     0, depth, InputOutput, visual, attrib_mask, &wa);
 
 
   if (_xwindow == (Window)0) {
   if (_xwindow == (Window)0) {
     glxdisplay_cat.error()
     glxdisplay_cat.error()
@@ -565,21 +576,29 @@ set_wm_properties(const WindowProperties &properties) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: glxGraphicsWindow::setup_colormap
 //     Function: glxGraphicsWindow::setup_colormap
 //       Access: Private
 //       Access: Private
-//  Description: Allocates a colormap appropriate to the visual and
+//  Description: Allocates a colormap appropriate to the fbconfig and
 //               stores in in the _colormap method.
 //               stores in in the _colormap method.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void glxGraphicsWindow::
 void glxGraphicsWindow::
-setup_colormap(XVisualInfo *visual) {
+setup_colormap(GLXFBConfig fbconfig) {
+  XVisualInfo *visual_info = glXGetVisualFromFBConfig(_display, fbconfig);
+  if (visual_info == NULL) {
+    // No X visual; no need to set up a colormap.
+    return;
+  }
+  int visual_class = visual_info->c_class;
+  Visual *visual = visual_info->visual;
+  XFree(visual_info);
+
   glxGraphicsPipe *glx_pipe;
   glxGraphicsPipe *glx_pipe;
   DCAST_INTO_V(glx_pipe, _pipe);
   DCAST_INTO_V(glx_pipe, _pipe);
   Window root_window = glx_pipe->get_root();
   Window root_window = glx_pipe->get_root();
 
 
-  int visual_class = visual->c_class;
   int rc, is_rgb;
   int rc, is_rgb;
 
 
   switch (visual_class) {
   switch (visual_class) {
     case PseudoColor:
     case PseudoColor:
-      rc = glXGetConfig(_display, visual, GLX_RGBA, &is_rgb);
+      rc = glXGetFBConfigAttrib(_display, fbconfig, GLX_RGBA, &is_rgb);
       if (rc == 0 && is_rgb) {
       if (rc == 0 && is_rgb) {
         glxdisplay_cat.warning()
         glxdisplay_cat.warning()
           << "mesa pseudocolor not supported.\n";
           << "mesa pseudocolor not supported.\n";
@@ -588,19 +607,19 @@ setup_colormap(XVisualInfo *visual) {
 
 
       } else {
       } else {
         _colormap = XCreateColormap(_display, root_window,
         _colormap = XCreateColormap(_display, root_window,
-                                    visual->visual, AllocAll);
+                                    visual, AllocAll);
       }
       }
       break;
       break;
     case TrueColor:
     case TrueColor:
     case DirectColor:
     case DirectColor:
       _colormap = XCreateColormap(_display, root_window,
       _colormap = XCreateColormap(_display, root_window,
-                                  visual->visual, AllocNone);
+                                  visual, AllocNone);
       break;
       break;
     case StaticColor:
     case StaticColor:
     case StaticGray:
     case StaticGray:
     case GrayScale:
     case GrayScale:
       _colormap = XCreateColormap(_display, root_window,
       _colormap = XCreateColormap(_display, root_window,
-                                  visual->visual, AllocNone);
+                                  visual, AllocNone);
       break;
       break;
     default:
     default:
       glxdisplay_cat.error()
       glxdisplay_cat.error()

+ 2 - 6
panda/src/glxdisplay/glxGraphicsWindow.h

@@ -21,14 +21,10 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 
 
+#include "glxGraphicsPipe.h"
 #include "graphicsWindow.h"
 #include "graphicsWindow.h"
 #include "buttonHandle.h"
 #include "buttonHandle.h"
 
 
-#include <X11/Xlib.h>
-#include <GL/glx.h>
-
-class glxGraphicsPipe;
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : glxGraphicsWindow
 //       Class : glxGraphicsWindow
 // Description : An interface to the glx system for managing GL
 // Description : An interface to the glx system for managing GL
@@ -55,7 +51,7 @@ protected:
 private:
 private:
   void set_wm_properties(const WindowProperties &properties);
   void set_wm_properties(const WindowProperties &properties);
 
 
-  void setup_colormap(XVisualInfo *visual);
+  void setup_colormap(GLXFBConfig fbconfig);
   void handle_keystroke(XKeyEvent &event);
   void handle_keystroke(XKeyEvent &event);
   void handle_keypress(XKeyEvent &event);
   void handle_keypress(XKeyEvent &event);
   void handle_keyrelease(XKeyEvent &event);
   void handle_keyrelease(XKeyEvent &event);