+#ifdef HAVE_GL
+int BC_DisplayInfo::gl_fb_config()
+{
+#if 0
+// find prefered config via glxinfo: mesa_hack
+ static int attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DEPTH_SIZE, 1,
+ GLX_STENCIL_SIZE, 1,
+ GLX_ACCUM_RED_SIZE, 1,
+ GLX_ACCUM_GREEN_SIZE, 1,
+ GLX_ACCUM_BLUE_SIZE, 1,
+ GLX_ACCUM_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None
+ };
+ vis_info = glXChooseVisual(display, scrnum, attribs);
+ VisualID vis_id = vis_info ? vis_info->visualid : 0;
+ fb_cfgs = glXGetFBConfigs(display, scrnum, &ncfgs);
+ int n = !fb_cfgs ? 0 : ncfgs;
+ for( int i=0; --n>=0; ++i ) {
+ if( vis_info ) { XFree(vis_info); vis_info = 0; }
+ vis_info = glXGetVisualFromFBConfig(display, cfg=fb_cfgs[i]);
+ if( vis_info && vis_info->visualid == vis_id ) break;
+ }
+ if( n < 0 ) {
+ cfg = 0;
+ if( fb_cfgs ) { XFree(fb_cfgs); fb_cfgs = 0; }
+ if( vis_info ) { XFree(vis_info); vis_info = 0; }
+ }
+#endif
+ if( !fb_cfgs ) do {
+ int fb_attrs[] = {
+ GLX_CONFIG_CAVEAT, GLX_SLOW_CONFIG,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_PBUFFER_BIT | GLX_PIXMAP_BIT,
+ GLX_DOUBLEBUFFER, 1,
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_ACCUM_RED_SIZE, 1,
+ GLX_ACCUM_GREEN_SIZE, 1,
+ GLX_ACCUM_BLUE_SIZE, 1,
+ GLX_ACCUM_ALPHA_SIZE, 1,
+ GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8,
+ GLX_ALPHA_SIZE, 8,
+ None
+ };
+ fb_cfgs = glXChooseFBConfig(display, scrnum, fb_attrs+2, &ncfgs);
+ if( fb_cfgs && ncfgs ) break;
+ fb_cfgs = glXChooseFBConfig(display, scrnum, fb_attrs+0, &ncfgs);
+ if( fb_cfgs && ncfgs ) break;
+ fb_attrs[5] = 0;
+ fb_cfgs = glXChooseFBConfig(display, scrnum, fb_attrs+2, &ncfgs);
+ if( fb_cfgs && ncfgs ) break;
+ fb_cfgs = glXChooseFBConfig(display, scrnum, fb_attrs+0, &ncfgs);
+ } while(0);
+ if( fb_cfgs && ncfgs ) {
+ for( int i=0; !vis_info && i<ncfgs; ++i )
+ vis_info = glXGetVisualFromFBConfig(display, cfg=fb_cfgs[i]);
+ }
+ if( vis_info ) {
+ vis = vis_info->visual;
+ depth = vis_info->depth;
+ }
+ else {
+ printf("%s\n", "BC_DisplayInfo::gl_fb_config failed");
+ cfg = 0;
+ }
+ return 0;
+}
+
+int BC_DisplayInfo::gl_probe(Window win)
+{
+ GLXContext glx_ctx = !cfg ? 0 :
+ glXCreateNewContext(display, cfg, GLX_RGBA_TYPE, 0, True);
+ GLXWindow glx_win = !cfg ? 0 :
+ glXCreateWindow(display, cfg, win, 0);
+ if( glx_ctx && glx_win &&
+ glXMakeContextCurrent(display, glx_win, glx_win, glx_ctx) ) {
+ const char *shader_version = (const char *)
+ glGetString(GL_SHADING_LANGUAGE_VERSION);
+ if( shader_version )
+ strncpy(gl_shader_version, shader_version, sizeof(gl_shader_version));
+ }
+ glXMakeContextCurrent(display, None, None, 0);
+ if( glx_ctx ) glXDestroyContext(display, glx_ctx);
+ if( glx_win ) glXDestroyWindow(display, glx_win);
+ if( fb_cfgs ) XFree(fb_cfgs);
+ if( vis_info ) XFree(vis_info);
+ return 0;
+}
+#endif
+
+
+void BC_DisplayInfo::test_window(int &x_out, int &y_out, int &x_out2, int &y_out2,
+ int x_in, int y_in)