int BC_DisplayInfo::right_border = -1;
int BC_DisplayInfo::auto_reposition_x = -1;
int BC_DisplayInfo::auto_reposition_y = -1;
-
+char BC_DisplayInfo::gl_shader_version[64] = { 0, };
BC_DisplayInfo::BC_DisplayInfo(const char *display_name, int show_error)
{
screen = -1;
+ xinerama_screens = -1;
+ xinerama_info = 0;
init_window(display_name, show_error);
}
BC_DisplayInfo::~BC_DisplayInfo()
{
+ if( xinerama_info ) XFree(xinerama_info);
#ifndef SINGLE_THREAD
XCloseDisplay(display);
#endif
XParseGeometry(geom, x, y, (unsigned int*)width, (unsigned int*)height);
}
+
+int BC_DisplayInfo::get_xinerama_screens()
+{
+ if( xinerama_screens < 0 ) {
+ xinerama_screens = 0;
+ if( XineramaIsActive(display) )
+ xinerama_info = XineramaQueryScreens(display, &xinerama_screens);
+ }
+ return xinerama_screens;
+}
+
+int BC_DisplayInfo::xinerama_geometry(int screen, int &x, int &y, int &w, int &h)
+{
+ int screens = get_xinerama_screens();
+ if( !screens ) return 1;
+ if( screen >= 0 ) {
+ int k = screens;
+ while( --k >= 0 && xinerama_info[k].screen_number != screen );
+ if( k < 0 ) return 1;
+ x = xinerama_info[k].x_org; w = xinerama_info[k].width;
+ y = xinerama_info[k].y_org; h = xinerama_info[k].height;
+ }
+ else {
+ int sx0 = INT_MAX, sx1 = INT_MIN;
+ int sy0 = INT_MAX, sy1 = INT_MIN;
+ for( int i=0; i<screens; ++i ) {
+ int x0 = xinerama_info[i].x_org;
+ int x1 = x0 + xinerama_info[i].width;
+ if( sx0 > x0 ) sx0 = x0;
+ if( sx1 < x1 ) sx1 = x1;
+ int y0 = xinerama_info[i].y_org;
+ int y1 = y0 + xinerama_info[i].height;
+ if( sy0 > y0 ) sy0 = y0;
+ if( sy1 < y1 ) sy1 = y1;
+ }
+ x = sx0; w = sx1 - sx0;
+ y = sy0; h = sy1 - sy0;
+ }
+ return 0;
+}
+
static void get_top_coords(Display *display, Window win, int &px,int &py, int &tx,int &ty)
{
Window *pcwin = 0; unsigned int ncwin = 0;
}
-void BC_DisplayInfo::test_window(int &x_out,
- int &y_out,
- int &x_out2,
- int &y_out2,
- int x_in,
- int y_in)
+int BC_DisplayInfo::gl_probe(Display *dpy, Window win)
+{
+#ifdef HAVE_GL
+ int fbAttribSingle[] = {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER, False,
+ None };
+ int fbAttribDouble[] = {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER, True,
+ None };
+ int scrnum = DefaultScreen(dpy);
+ int n_fb_cfgs = 0;
+ GLXFBConfig *fb_cfgs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &n_fb_cfgs);
+ if( !fb_cfgs )
+ fb_cfgs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &n_fb_cfgs);
+ if( !fb_cfgs )
+ return 1;
+ XVisualInfo *vis_info = 0;
+ GLXFBConfig glx_fb_config = 0;
+ for( int i=0; !vis_info && i<n_fb_cfgs; ++i ) {
+ if( vis_info ) { XFree(vis_info); vis_info = 0; }
+ glx_fb_config = fb_cfgs[i];
+ vis_info = glXGetVisualFromFBConfig(dpy, glx_fb_config);
+ }
+ if( !vis_info )
+ return 1;
+ XFree(vis_info);
+ GLXWindow glx_win = glXCreateWindow(dpy, glx_fb_config, win, 0);
+ if( !glx_win ) return 1;
+ GLXContext glx_ctxt = glXCreateNewContext(dpy, glx_fb_config, GLX_RGBA_TYPE, 0, True);
+ if( glx_ctxt ) {
+ if( glXMakeContextCurrent(dpy, glx_win, glx_win, glx_ctxt) ) {
+ 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(dpy, 0, 0, 0);
+ }
+ glXDestroyContext(dpy, glx_ctxt);
+ }
+ glXDestroyWindow(dpy, glx_win);
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+
+void BC_DisplayInfo::test_window(int &x_out, int &y_out, int &x_out2, int &y_out2,
+ int x_in, int y_in)
{
#ifdef SINGLE_THREAD
BC_Display::lock_display("BC_DisplayInfo::test_window");
x_in, y_in, TEST_SIZE, TEST_SIZE,
0, default_depth, InputOutput,
vis, mask, &attr);
+ gl_probe(display, win);
XSizeHints size_hints;
XGetNormalHints(display, win, &size_hints);
size_hints.flags = PPosition | PSize;
return bottom_border;
}
+const char *BC_DisplayInfo::get_gl_shader_version()
+{
+ init_borders();
+ return gl_shader_version;
+}
+
void BC_DisplayInfo::init_window(const char *display_name, int show_error)
{
if(display_name && display_name[0] == 0) display_name = NULL;