X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbcdisplayinfo.C;h=489d1314a6242e49c79195a3fd7776a6c0f6b823;hp=5bbe991ce925492b454fbc2fc58c0d59e9ac34ef;hb=59e74f262d7b6be235f2bbfaac35ef4274f52dc9;hpb=7fd85fb66168f6b518c5f2d73e04036e87faa0e1 diff --git a/cinelerra-5.1/guicast/bcdisplayinfo.C b/cinelerra-5.1/guicast/bcdisplayinfo.C index 5bbe991c..489d1314 100644 --- a/cinelerra-5.1/guicast/bcdisplayinfo.C +++ b/cinelerra-5.1/guicast/bcdisplayinfo.C @@ -41,16 +41,27 @@ int BC_DisplayInfo::bottom_border = -1; 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; + vis = 0; + depth = 0; + scrnum = -1; + xinerama_screens = -1; + xinerama_info = 0; init_window(display_name, show_error); +#ifdef HAVE_GL + ncfgs = 0; + fb_cfgs = 0; + cfg = 0; + vis_info = 0; +#endif } BC_DisplayInfo::~BC_DisplayInfo() { + if( xinerama_info ) XFree(xinerama_info); #ifndef SINGLE_THREAD XCloseDisplay(display); #endif @@ -62,6 +73,47 @@ void BC_DisplayInfo::parse_geometry(char *geom, int *x, int *y, int *width, int 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 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; @@ -86,32 +138,128 @@ static void get_top_coords(Display *display, Window win, int &px,int &py, int &t } -void BC_DisplayInfo::test_window(int &x_out, - int &y_out, - int &x_out2, - int &y_out2, - int x_in, - int y_in) +#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 && ivisual; + 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) { #ifdef SINGLE_THREAD BC_Display::lock_display("BC_DisplayInfo::test_window"); #endif - +#ifdef HAVE_GL + gl_fb_config(); +#endif x_out = 0; y_out = 0; - int x_out1 = 0; - int y_out1 = 0; + int x_out1 = 0; + int y_out1 = 0; x_out2 = 0; y_out2 = 0; - unsigned long mask = CWEventMask | CWWinGravity | CWBackPixel; + unsigned long mask = CWEventMask | CWWinGravity | CWBackPixel | CWColormap; XSetWindowAttributes attr; attr.event_mask = StructureNotifyMask; attr.win_gravity = SouthEastGravity; - attr.background_pixel = BlackPixel(display,screen); + attr.background_pixel = BlackPixel(display, scrnum); + attr.colormap = XCreateColormap(display, rootwin, vis, AllocNone); Window win = XCreateWindow(display, rootwin, x_in, y_in, TEST_SIZE, TEST_SIZE, - 0, default_depth, InputOutput, + 0, depth, InputOutput, vis, mask, &attr); XSizeHints size_hints; XGetNormalHints(display, win, &size_hints); @@ -125,7 +273,6 @@ void BC_DisplayInfo::test_window(int &x_out, XClearWindow(display, win); XMapWindow(display, win); XFlush(display); XSync(display, 0); usleep(100000); - XEvent event; int state = 0; @@ -172,6 +319,9 @@ void BC_DisplayInfo::test_window(int &x_out, // x_out,y_out, x_out1,y_out1, x_out2,y_out2); //printf("\nx_in,y_in=%d,%d\n", x_in,y_in); +#ifdef HAVE_GL + gl_probe(win); +#endif XDestroyWindow(display, win); XFlush(display); XSync(display, 0); @@ -223,6 +373,12 @@ int BC_DisplayInfo::get_bottom_border() 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; @@ -241,7 +397,7 @@ void BC_DisplayInfo::init_window(const char *display_name, int show_error) fprintf(stderr,_("BC_DisplayInfo::init_window: cannot open display \"%s\".\n"), display_name ? display_name : ""); if(getenv("DISPLAY") == NULL) - fprintf(stderr, _("'DISPLAY' environment variable not set.\n")); + fprintf(stderr, _("'DISPLAY' environment variable not set.\n")); if((display = XOpenDisplay(0)) == NULL) { fprintf(stderr,_("BC_DisplayInfo::init_window: cannot connect to X server.\n")); exit(1); @@ -252,10 +408,10 @@ void BC_DisplayInfo::init_window(const char *display_name, int show_error) #ifdef SINGLE_THREAD BC_Display::lock_display("BC_DisplayInfo::init_window"); #endif - screen = DefaultScreen(display); - rootwin = RootWindow(display, screen); - vis = DefaultVisual(display, screen); - default_depth = DefaultDepth(display, screen); + scrnum = DefaultScreen(display); + rootwin = RootWindow(display, scrnum); + vis = DefaultVisual(display, scrnum); + depth = DefaultDepth(display, scrnum); #ifdef SINGLE_THREAD BC_Display::unlock_display(); #endif // SINGLE_THREAD @@ -297,15 +453,8 @@ int BC_DisplayInfo::get_abs_cursor_x() #ifdef SINGLE_THREAD BC_Display::lock_display("BC_DisplayInfo::get_abs_cursor_x"); #endif - XQueryPointer(display, - rootwin, - &temp_win, - &temp_win, - &abs_x, - &abs_y, - &win_x, - &win_y, - &temp_mask); + XQueryPointer(display, rootwin, &temp_win, &temp_win, + &abs_x, &abs_y, &win_x, &win_y, &temp_mask); #ifdef SINGLE_THREAD BC_Display::unlock_display(); #endif @@ -321,15 +470,8 @@ int BC_DisplayInfo::get_abs_cursor_y() #ifdef SINGLE_THREAD BC_Display::lock_display("BC_DisplayInfo::get_abs_cursor_y"); #endif - XQueryPointer(display, - rootwin, - &temp_win, - &temp_win, - &abs_x, - &abs_y, - &win_x, - &win_y, - &temp_mask); + XQueryPointer(display, rootwin, &temp_win, &temp_win, + &abs_x, &abs_y, &win_x, &win_y, &temp_mask); #ifdef SINGLE_THREAD BC_Display::unlock_display(); #endif