From 3d2f33e10e6b392e0962d50c115ad4dbc07b32ab Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 26 Apr 2004 18:38:44 +0000 Subject: [PATCH] fall back to older XVisualInfo interface if GLXFBConfig doesn't return any available options --- panda/src/glxdisplay/glxGraphicsPipe.cxx | 381 +++++++++++++++++- panda/src/glxdisplay/glxGraphicsPipe.h | 5 + .../glxdisplay/glxGraphicsStateGuardian.cxx | 6 +- .../src/glxdisplay/glxGraphicsStateGuardian.h | 3 +- panda/src/glxdisplay/glxGraphicsWindow.cxx | 59 ++- panda/src/glxdisplay/glxGraphicsWindow.h | 1 + 6 files changed, 427 insertions(+), 28 deletions(-) diff --git a/panda/src/glxdisplay/glxGraphicsPipe.cxx b/panda/src/glxdisplay/glxGraphicsPipe.cxx index 8f9ee3d988..ae9a50a2af 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.cxx +++ b/panda/src/glxdisplay/glxGraphicsPipe.cxx @@ -185,25 +185,44 @@ make_gsg(const FrameBufferProperties &properties, } FrameBufferProperties new_properties = properties; + GLXContext context = NULL; + GLXFBConfig fbconfig = choose_fbconfig(new_properties); - if (fbconfig == None) { - return NULL; + XVisualInfo *visual = NULL; + + if (fbconfig != None) { + context = + glXCreateNewContext(_display, fbconfig, GLX_RGBA_TYPE, share_context, + GL_TRUE); + } + if (context == NULL) { + // If we couldn't create a context with the fbconfig interface, + // try falling back to the older XVisual interface. + visual = choose_visual(new_properties); + + if (visual != (XVisualInfo *)NULL) { + context = glXCreateContext(_display, visual, None, GL_TRUE); + fbconfig = None; + } } - // Attempt to create a GL context. - GLXContext context = - glXCreateNewContext(_display, fbconfig, GLX_RGBA_TYPE, share_context, - GL_TRUE); if (context == NULL) { glxdisplay_cat.error() << "Could not create GL context.\n"; return NULL; } + if (visual == (XVisualInfo *)NULL) { + // If we used the fbconfig to open the context, we still need to + // get the associated XVisual. + nassertr(fbconfig != None, NULL); + visual = glXGetVisualFromFBConfig(_display, fbconfig); + } + // Now we can make a GSG. PT(glxGraphicsStateGuardian) gsg = - new glxGraphicsStateGuardian(new_properties, share_gsg, context, fbconfig, - _display, _screen); + new glxGraphicsStateGuardian(new_properties, share_gsg, context, + fbconfig, visual, _display, _screen); return gsg.p(); } @@ -282,7 +301,7 @@ choose_fbconfig(FrameBufferProperties &properties) const { // information: we don't care about that much detail. NotifySeverity show_fbconfig_severity = NS_debug; - if (fbconfig == NULL) { + if (fbconfig == None) { glxdisplay_cat.info() << "glxGraphicsWindow::choose_fbconfig() - fbconfig with requested " << "capabilities not found; trying for lesser fbconfig.\n"; @@ -308,7 +327,7 @@ choose_fbconfig(FrameBufferProperties &properties) const { fbconfig = try_for_fbconfig(frame_buffer_mode, 1, 1); } - if (fbconfig == NULL) { + if (fbconfig == None) { // Ok, not good enough. Now try to eliminate options, but keep // as many bits as we asked for. @@ -348,7 +367,7 @@ choose_fbconfig(FrameBufferProperties &properties) const { tried_masks.insert(frame_buffer_mode); int i; - for (i = 0; fbconfig == NULL && strip_properties[i] != 0; i++) { + for (i = 0; fbconfig == None && strip_properties[i] != 0; i++) { int new_frame_buffer_mode = frame_buffer_mode & ~strip_properties[i]; if (tried_masks.insert(new_frame_buffer_mode).second) { fbconfig = try_for_fbconfig(new_frame_buffer_mode, want_depth_bits, @@ -360,10 +379,10 @@ choose_fbconfig(FrameBufferProperties &properties) const { tried_masks.clear(); tried_masks.insert(frame_buffer_mode); - if (fbconfig == NULL) { + if (fbconfig == None) { // Try once more, this time eliminating all of the size // requests. - for (i = 0; fbconfig == NULL && strip_properties[i] != 0; i++) { + for (i = 0; fbconfig == None && strip_properties[i] != 0; i++) { int new_frame_buffer_mode = frame_buffer_mode & ~strip_properties[i]; if (tried_masks.insert(new_frame_buffer_mode).second) { fbconfig = try_for_fbconfig(new_frame_buffer_mode, 1, 1); @@ -372,16 +391,16 @@ choose_fbconfig(FrameBufferProperties &properties) const { } } - if (fbconfig == NULL) { + if (fbconfig == None) { // Here's our last-ditch desparation attempt: give us any GLX // fbconfig at all! fbconfig = try_for_fbconfig(0, 1, 1); } - if (fbconfig == NULL) { + if (fbconfig == None) { glxdisplay_cat.error() << "Could not get any GLX fbconfig.\n"; - return NULL; + return None; } } } @@ -389,7 +408,7 @@ choose_fbconfig(FrameBufferProperties &properties) const { glxdisplay_cat.info() << "Selected suitable GLX fbconfig.\n"; - // Now update our frambuffer_mode and bit depth appropriately. + // Now update our framebuffer_mode and bit depth appropriately. int render_mode, double_buffer, stereo, red_size, green_size, blue_size, alpha_size, ared_size, agreen_size, ablue_size, aalpha_size, depth_size, stencil_size; @@ -457,7 +476,7 @@ choose_fbconfig(FrameBufferProperties &properties) const { // Description: Attempt to get the requested fbconfig, if it is // available. It's just a wrapper around // glXChooseFBConfig(). It returns the fbconfig -// information if possible, or NULL if it is not. +// information if possible, or None if it is not. //////////////////////////////////////////////////////////////////// GLXFBConfig glxGraphicsPipe:: try_for_fbconfig(int framebuffer_mode, @@ -538,17 +557,17 @@ try_for_fbconfig(int framebuffer_mode, attrib_list[n++] = want_color_component_bits; } } -#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) + /* if (framebuffer_mode & FrameBufferProperties::FM_multisample) { glxdisplay_cat.debug(false) << " MULTISAMPLE"; attrib_list[n++] = GLX_SAMPLES_SGIS; // We decide 4 is minimum number of samples attrib_list[n++] = 4; } -#endif + */ // Terminate the list - nassertr(n < max_attrib_list, NULL); + nassertr(n < max_attrib_list, None); attrib_list[n] = (int)None; int num_configs = 0; @@ -576,6 +595,326 @@ try_for_fbconfig(int framebuffer_mode, return fbconfig; } +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsPipe::choose visual +// Access: Private +// Description: Selects an appropriate X visual for the given frame +// buffer properties. Returns the visual pointer if +// successful, or NULL otherwise. +// +// If successful, this may modify properties to reflect +// the actual visual chosen. +// +// This is an older GLX interface, replaced by the new +// fbconfig interface. However, some implementations of +// GLX may not support fbconfig, so we have to have this +// code as a fallback. +//////////////////////////////////////////////////////////////////// +XVisualInfo *glxGraphicsPipe:: +choose_visual(FrameBufferProperties &properties) const { + int frame_buffer_mode = 0; + int want_depth_bits = 0; + int want_color_bits = 0; + + if (properties.has_frame_buffer_mode()) { + frame_buffer_mode = properties.get_frame_buffer_mode(); + } + + if (properties.has_depth_bits()) { + want_depth_bits = properties.get_depth_bits(); + } + + if (properties.has_color_bits()) { + want_color_bits = properties.get_color_bits(); + } + + /* + if (frame_buffer_mode & FrameBufferProperties::FM_multisample) { + if (!glx_supports("GLX_SGIS_multisample")) { + glxdisplay_cat.info() + << "multisample not supported by this glx implementation.\n"; + frame_buffer_mode &= ~FrameBufferProperties::FM_multisample; + } + } + */ + + XVisualInfo *visual = + try_for_visual(frame_buffer_mode, want_depth_bits, want_color_bits); + + // This is the severity level at which we'll report the details of + // the visual we actually do find. Normally, it's debug-level + // information: we don't care about that much detail. + NotifySeverity show_visual_severity = NS_debug; + + if (visual == NULL) { + glxdisplay_cat.info() + << "glxGraphicsWindow::choose_visual() - visual with requested\n" + << " capabilities not found; trying for lesser visual.\n"; + + // If we're unable to get the visual we asked for, however, we + // 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 + // visual at a higher level. + show_visual_severity = NS_info; + + bool special_size_request = + (want_depth_bits != 1 || want_color_bits != 1); + + // We try to be smart about choosing a close match for the visual. + // 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 + // minimum. + + if (special_size_request) { + // Actually, first we'll eliminate all of the minimum sizes, to + // try to open a window with all of the requested options, but + // maybe not as many bits in some options as we'd like. + visual = try_for_visual(frame_buffer_mode, 1, 1); + } + + if (visual == NULL) { + // Ok, not good enough. Now try to eliminate options, but keep + // as many bits as we asked for. + + // This array keeps the bitmasks of options that we pull out of + // the requested frame_buffer_mode, in order. + + static const int strip_properties[] = { + // One esoteric option removed. + FrameBufferProperties::FM_multisample, + FrameBufferProperties::FM_stencil, + FrameBufferProperties::FM_accum, + FrameBufferProperties::FM_alpha, + FrameBufferProperties::FM_stereo, + + // Two esoteric options removed. + FrameBufferProperties::FM_stencil | FrameBufferProperties::FM_multisample, + FrameBufferProperties::FM_accum | FrameBufferProperties::FM_multisample, + FrameBufferProperties::FM_alpha | FrameBufferProperties::FM_multisample, + FrameBufferProperties::FM_stereo | FrameBufferProperties::FM_multisample, + FrameBufferProperties::FM_stencil | FrameBufferProperties::FM_accum, + FrameBufferProperties::FM_alpha | FrameBufferProperties::FM_stereo, + FrameBufferProperties::FM_stencil | FrameBufferProperties::FM_accum | FrameBufferProperties::FM_multisample, + FrameBufferProperties::FM_alpha | FrameBufferProperties::FM_stereo | FrameBufferProperties::FM_multisample, + + // All esoteric options removed. + FrameBufferProperties::FM_stencil | FrameBufferProperties::FM_accum | FrameBufferProperties::FM_alpha | FrameBufferProperties::FM_stereo | FrameBufferProperties::FM_multisample, + + // All esoteric options, plus some we'd really really prefer, + // removed. + FrameBufferProperties::FM_stencil | FrameBufferProperties::FM_accum | FrameBufferProperties::FM_alpha | FrameBufferProperties::FM_stereo | FrameBufferProperties::FM_multisample | FrameBufferProperties::FM_double_buffer, + + // A zero marks the end of the array. + 0 + }; + + pset tried_masks; + tried_masks.insert(frame_buffer_mode); + + int i; + for (i = 0; visual == NULL && strip_properties[i] != 0; i++) { + int new_frame_buffer_mode = frame_buffer_mode & ~strip_properties[i]; + if (tried_masks.insert(new_frame_buffer_mode).second) { + visual = try_for_visual(new_frame_buffer_mode, want_depth_bits, + want_color_bits); + } + } + + if (special_size_request) { + tried_masks.clear(); + tried_masks.insert(frame_buffer_mode); + + if (visual == NULL) { + // Try once more, this time eliminating all of the size + // requests. + for (i = 0; visual == NULL && strip_properties[i] != 0; i++) { + int new_frame_buffer_mode = frame_buffer_mode & ~strip_properties[i]; + if (tried_masks.insert(new_frame_buffer_mode).second) { + visual = try_for_visual(new_frame_buffer_mode, 1, 1); + } + } + } + } + + if (visual == NULL) { + // Here's our last-ditch desparation attempt: give us any GLX + // visual at all! + visual = try_for_visual(0, 1, 1); + } + + if (visual == NULL) { + glxdisplay_cat.error() + << "Could not get any GLX visual.\n"; + return NULL; + } + } + } + + glxdisplay_cat.info() + << "Got visual 0x" << hex << (int)visual->visualid << dec << ".\n"; + + // Now update our framebuffer_mode and bit depth appropriately. + int render_mode, double_buffer, stereo, red_size, green_size, blue_size, + alpha_size, ared_size, agreen_size, ablue_size, aalpha_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); + + frame_buffer_mode = 0; + if (double_buffer) { + frame_buffer_mode |= FrameBufferProperties::FM_double_buffer; + } + if (stereo) { + frame_buffer_mode |= FrameBufferProperties::FM_stereo; + } + if (!render_mode) { + frame_buffer_mode |= FrameBufferProperties::FM_index; + } + if (stencil_size != 0) { + frame_buffer_mode |= FrameBufferProperties::FM_stencil; + } + if (depth_size != 0) { + frame_buffer_mode |= FrameBufferProperties::FM_depth; + } + if (alpha_size != 0) { + frame_buffer_mode |= FrameBufferProperties::FM_alpha; + } + if (ared_size + agreen_size + ablue_size != 0) { + frame_buffer_mode |= FrameBufferProperties::FM_accum; + } + + properties.set_frame_buffer_mode(frame_buffer_mode); + properties.set_color_bits(red_size + green_size + blue_size + alpha_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 + << " RGBA: " << red_size << " " << green_size << " " << blue_size + << " " << alpha_size << endl + << " Accum RGBA: " << ared_size << " " << agreen_size << " " + << ablue_size << " " << aalpha_size << endl + << " Depth: " << depth_size << endl + << " Stencil: " << stencil_size << endl + << " DoubleBuffer? " << double_buffer << endl + << " Stereo? " << stereo << endl; + } + + return visual; +} + +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsPipe::try_for_visual +// Access: Private +// Description: Attempt to get the requested visual, if it is +// available. It's just a wrapper around +// glXChooseVisual(). It returns the visual information +// if possible, or NULL if it is not. +// +// This is an older GLX interface, replaced by the new +// fbconfig interface. However, some implementations of +// GLX may not support fbconfig, so we have to have this +// code as a fallback. +//////////////////////////////////////////////////////////////////// +XVisualInfo *glxGraphicsPipe:: +try_for_visual(int framebuffer_mode, + int want_depth_bits, int want_color_bits) const { + static const int max_attrib_list = 32; + int attrib_list[max_attrib_list]; + int n=0; + + glxdisplay_cat.debug() + << "Trying for visual with: RGB(" << want_color_bits << ")"; + + int want_color_component_bits; + if (framebuffer_mode & FrameBufferProperties::FM_alpha) { + want_color_component_bits = max(want_color_bits / 4, 1); + } else { + want_color_component_bits = max(want_color_bits / 3, 1); + } + + attrib_list[n++] = GLX_RGBA; + attrib_list[n++] = GLX_RED_SIZE; + attrib_list[n++] = want_color_component_bits; + attrib_list[n++] = GLX_GREEN_SIZE; + attrib_list[n++] = want_color_component_bits; + attrib_list[n++] = GLX_BLUE_SIZE; + attrib_list[n++] = want_color_component_bits; + + if (framebuffer_mode & FrameBufferProperties::FM_alpha) { + glxdisplay_cat.debug(false) << " ALPHA"; + attrib_list[n++] = GLX_ALPHA_SIZE; + attrib_list[n++] = want_color_component_bits; + } + if (framebuffer_mode & FrameBufferProperties::FM_double_buffer) { + glxdisplay_cat.debug(false) << " DOUBLEBUFFER"; + attrib_list[n++] = GLX_DOUBLEBUFFER; + } + if (framebuffer_mode & FrameBufferProperties::FM_stereo) { + glxdisplay_cat.debug(false) << " STEREO"; + attrib_list[n++] = GLX_STEREO; + } + if (framebuffer_mode & FrameBufferProperties::FM_depth) { + glxdisplay_cat.debug(false) << " DEPTH(" << want_depth_bits << ")"; + attrib_list[n++] = GLX_DEPTH_SIZE; + attrib_list[n++] = want_depth_bits; + } + if (framebuffer_mode & FrameBufferProperties::FM_stencil) { + glxdisplay_cat.debug(false) << " STENCIL"; + attrib_list[n++] = GLX_STENCIL_SIZE; + attrib_list[n++] = 1; + } + if (framebuffer_mode & FrameBufferProperties::FM_accum) { + glxdisplay_cat.debug(false) << " ACCUM"; + attrib_list[n++] = GLX_ACCUM_RED_SIZE; + attrib_list[n++] = want_color_component_bits; + attrib_list[n++] = GLX_ACCUM_GREEN_SIZE; + attrib_list[n++] = want_color_component_bits; + attrib_list[n++] = GLX_ACCUM_BLUE_SIZE; + attrib_list[n++] = want_color_component_bits; + if (framebuffer_mode & FrameBufferProperties::FM_alpha) { + attrib_list[n++] = GLX_ACCUM_ALPHA_SIZE; + attrib_list[n++] = want_color_component_bits; + } + } + /* + if (framebuffer_mode & FrameBufferProperties::FM_multisample) { + glxdisplay_cat.debug(false) << " MULTISAMPLE"; + attrib_list[n++] = GLX_SAMPLES_SGIS; + // We decide 4 is minimum number of samples + attrib_list[n++] = 4; + } + */ + + // Terminate the list + nassertr(n < max_attrib_list, NULL); + attrib_list[n] = (int)None; + + XVisualInfo *vinfo = glXChooseVisual(_display, _screen, attrib_list); + + if (glxdisplay_cat.is_debug()) { + if (vinfo != NULL) { + glxdisplay_cat.debug(false) << ", match found!\n"; + } else { + glxdisplay_cat.debug(false) << ", no match.\n"; + } + } + + return vinfo; +} + //////////////////////////////////////////////////////////////////// // Function: glxGraphicsPipe::make_hidden_cursor // Access: Private diff --git a/panda/src/glxdisplay/glxGraphicsPipe.h b/panda/src/glxdisplay/glxGraphicsPipe.h index bd828aaf6e..81b4bdbd99 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.h +++ b/panda/src/glxdisplay/glxGraphicsPipe.h @@ -93,6 +93,11 @@ private: GLXFBConfig choose_fbconfig(FrameBufferProperties &properties) const; GLXFBConfig try_for_fbconfig(int framebuffer_mode, int want_depth_bits, int want_color_bits) const; + + XVisualInfo *choose_visual(FrameBufferProperties &properties) const; + XVisualInfo *try_for_visual(int framebuffer_mode, + int want_depth_bits, int want_color_bits) const; + void make_hidden_cursor(); void release_hidden_cursor(); diff --git a/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx b/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx index d9b8910acb..80e8c1c4e8 100644 --- a/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx +++ b/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx @@ -30,10 +30,11 @@ glxGraphicsStateGuardian:: glxGraphicsStateGuardian(const FrameBufferProperties &properties, glxGraphicsStateGuardian *share_with, GLXContext context, GLXFBConfig fbconfig, - Display *display, int screen) : + XVisualInfo *visual, Display *display, int screen) : GLGraphicsStateGuardian(properties), _context(context), _fbconfig(fbconfig), + _visual(visual), _display(display), _screen(screen) { @@ -49,6 +50,9 @@ glxGraphicsStateGuardian(const FrameBufferProperties &properties, //////////////////////////////////////////////////////////////////// glxGraphicsStateGuardian:: ~glxGraphicsStateGuardian() { + if (_visual != (XVisualInfo *)NULL) { + XFree(_visual); + } if (_context != (GLXContext)NULL) { glXDestroyContext(_display, _context); _context = (GLXContext)NULL; diff --git a/panda/src/glxdisplay/glxGraphicsStateGuardian.h b/panda/src/glxdisplay/glxGraphicsStateGuardian.h index 40b4581337..ace5033c1b 100644 --- a/panda/src/glxdisplay/glxGraphicsStateGuardian.h +++ b/panda/src/glxdisplay/glxGraphicsStateGuardian.h @@ -34,11 +34,12 @@ public: glxGraphicsStateGuardian(const FrameBufferProperties &properties, glxGraphicsStateGuardian *share_with, GLXContext context, GLXFBConfig fbconfig, - Display *display, int screen); + XVisualInfo *visual, Display *display, int screen); virtual ~glxGraphicsStateGuardian(); GLXContext _context; GLXFBConfig _fbconfig; + XVisualInfo *_visual; Display *_display; int _screen; diff --git a/panda/src/glxdisplay/glxGraphicsWindow.cxx b/panda/src/glxdisplay/glxGraphicsWindow.cxx index 6324c14c87..5928a2839a 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.cxx +++ b/panda/src/glxdisplay/glxGraphicsWindow.cxx @@ -505,9 +505,7 @@ open_window() { glxGraphicsStateGuardian *glxgsg; DCAST_INTO_R(glxgsg, _gsg, false); - XVisualInfo *visual_info = - glXGetVisualFromFBConfig(_display, glxgsg->_fbconfig); - + XVisualInfo *visual_info = glxgsg->_visual; if (visual_info == NULL) { // No X visual for this fbconfig; how can we open the window? glxdisplay_cat.error() @@ -516,7 +514,6 @@ open_window() { } Visual *visual = visual_info->visual; int depth = visual_info->depth; - XFree(visual_info); if (!_properties.has_origin()) { @@ -528,7 +525,11 @@ open_window() { Window root_window = glx_pipe->get_root(); - setup_colormap(glxgsg->_fbconfig); + if (glxgsg->_fbconfig != None) { + setup_colormap(glxgsg->_fbconfig); + } else { + setup_colormap(visual_info); + } _event_mask = ButtonPressMask | ButtonReleaseMask | @@ -736,6 +737,54 @@ setup_colormap(GLXFBConfig fbconfig) { } } +//////////////////////////////////////////////////////////////////// +// Function: glxGraphicsWindow::setup_colormap +// Access: Private +// Description: Allocates a colormap appropriate to the visual and +// stores in in the _colormap method. +//////////////////////////////////////////////////////////////////// +void glxGraphicsWindow:: +setup_colormap(XVisualInfo *visual) { + glxGraphicsPipe *glx_pipe; + DCAST_INTO_V(glx_pipe, _pipe); + Window root_window = glx_pipe->get_root(); + + int visual_class = visual->c_class; + int rc, is_rgb; + + switch (visual_class) { + case PseudoColor: + rc = glXGetConfig(_display, visual, GLX_RGBA, &is_rgb); + if (rc == 0 && is_rgb) { + glxdisplay_cat.warning() + << "mesa pseudocolor not supported.\n"; + // this is a terrible terrible hack, but it seems to work + _colormap = (Colormap)0; + + } else { + _colormap = XCreateColormap(_display, root_window, + visual->visual, AllocAll); + } + break; + case TrueColor: + case DirectColor: + _colormap = XCreateColormap(_display, root_window, + visual->visual, AllocNone); + break; + case StaticColor: + case StaticGray: + case GrayScale: + _colormap = XCreateColormap(_display, root_window, + visual->visual, AllocNone); + break; + default: + glxdisplay_cat.error() + << "Could not allocate a colormap for visual class " + << visual_class << ".\n"; + break; + } +} + //////////////////////////////////////////////////////////////////// // Function: glxGraphicsWindow::handle_keystroke // Access: Private diff --git a/panda/src/glxdisplay/glxGraphicsWindow.h b/panda/src/glxdisplay/glxGraphicsWindow.h index 99e0b24a72..795da59737 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.h +++ b/panda/src/glxdisplay/glxGraphicsWindow.h @@ -56,6 +56,7 @@ private: void set_wm_properties(const WindowProperties &properties); void setup_colormap(GLXFBConfig fbconfig); + void setup_colormap(XVisualInfo *visual); void handle_keystroke(XKeyEvent &event); void handle_keypress(XKeyEvent &event); void handle_keyrelease(XKeyEvent &event);