Exemplo n.º 1
0
static Display *open_windowless_display(void)
{
	Display *display = XOpenDisplay(NULL);
	xcb_connection_t *xcb_conn;
	xcb_screen_iterator_t screen_iterator;
	xcb_screen_t *screen;
	int screen_num;

	if (!display) {
		blog(LOG_ERROR, "Unable to open new X connection!");
		return NULL;
	}

	xcb_conn = XGetXCBConnection(display);
	if (!xcb_conn) {
		blog(LOG_ERROR, "Unable to get XCB connection to main display");
		goto error;
	}

	screen_iterator = xcb_setup_roots_iterator(xcb_get_setup(xcb_conn));
	screen = screen_iterator.data;
	if (!screen) {
		blog(LOG_ERROR, "Unable to get screen root");
		goto error;
	}

	screen_num = get_screen_num_from_root(xcb_conn, screen->root);
	if (screen_num == -1) {
		blog(LOG_ERROR, "Unable to get screen number from root");
		goto error;
	}

	if (!gladLoadGLX(display, screen_num)) {
		blog(LOG_ERROR, "Unable to load GLX entry functions.");
		goto error;
	}

	return display;

error:
	if (display)
		XCloseDisplay(display);
	return NULL;
}
Exemplo n.º 2
0
struct gl_platform *gl_platform_create(device_t device,
		struct gs_init_data *info)
{
	int num_configs = 0;
	int error_base = 0, event_base = 0;
	Display *display = info->window.display;
	struct gl_platform *plat = bzalloc(sizeof(struct gl_platform));
	GLXFBConfig* configs;
	XWindowAttributes attrs;
	int screen;
	int major = 0, minor = 0;

	print_info_stuff(info);

	if (!display) {
		blog(LOG_ERROR, "Unable to find display. DISPLAY variable "
		                "may not be set correctly.");
		goto fail0;
	}

	if (!XGetWindowAttributes(display, info->window.id, &attrs)) {
		blog(LOG_ERROR, "Failed getting window attributes");
		goto fail0;
	}

	screen = XScreenNumberOfScreen(attrs.screen);

	if (!gladLoadGLX(display, screen)) {
		blog(LOG_ERROR, "Unable to load GLX entry functions.");
		goto fail0;
	}

	if (!glXQueryExtension(display, &error_base, &event_base)) {
		blog(LOG_ERROR, "GLX not supported.");
		goto fail0;
	}

	/* We require glX version 1.3 */

	glXQueryVersion(display, &major, &minor);
	if (major < 1 || (major == 1 && minor < 3)) {
		blog(LOG_ERROR, "GLX version found: %i.%i\nRequired: "
				"1.3", major, minor);
		goto fail0;
	}

	if (!GLAD_GLX_ARB_create_context) {
		blog(LOG_ERROR, "ARB_GLX_create_context not supported!");
		goto fail0;
	}

	configs = glXChooseFBConfig(display, screen,
			fb_attribs, &num_configs);

	if (!configs) {
		blog(LOG_ERROR, "Attribute list or screen is invalid.");
		goto fail0;
	}

	if (num_configs == 0) {
		XFree(configs);
		blog(LOG_ERROR, "No framebuffer configurations found.");
		goto fail0;
	}

	plat->fbcfg = configs[0];

	XFree(configs);

	handle_x_error(display, NULL);

	/* We just use the first configuration found... as it does everything
	 * we want at the very least. */
	plat->context = glXCreateContextAttribsARB(display, plat->fbcfg, NULL,
			true, ctx_attribs);
	if (!plat->context) {
		blog(LOG_ERROR, "Failed to create OpenGL context.");
		goto fail0;
	}

	if (handle_x_error(display, "Failed to create OpenGL context."))
		goto fail2;

	device->plat = plat;

	plat->swap.device               = device;
	plat->swap.info.window.id       = info->window.id;
	plat->swap.info.window.display  = display;
	plat->swap.info.format          = GS_RGBA;
	plat->swap.info.zsformat        = GS_Z24_S8;
	plat->swap.info.num_backbuffers = 1;
	plat->swap.info.adapter         = info->adapter;
	plat->swap.info.cx              = attrs.width;
	plat->swap.info.cy              = attrs.height;
	plat->swap.wi                   = gl_windowinfo_create(info);

	if (!gl_platform_init_swapchain(&plat->swap))
		goto fail2;

	if (!glXMakeCurrent(display, plat->swap.wi->glxid, plat->context)) {
		blog(LOG_ERROR, "Failed to make context current.");
		goto fail2;
	}

	if (!gladLoadGL()) {
		blog(LOG_ERROR, "Failed to load OpenGL entry functions.");
		goto fail2;
	}

	blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION));

	/* We assume later that cur_swap is already set. */
	device->cur_swap = &plat->swap;

	XSync(display, false);

	blog(LOG_INFO, "Created new platform data");

	return plat;

fail2:
	glXMakeCurrent(display, None, NULL);
	glXDestroyContext(display, plat->context);

	gl_platform_cleanup_swapchain(&plat->swap);

fail0:
	bfree(plat);
	device->plat = 0;

	return NULL;
}
Exemplo n.º 3
0
extern bool gl_platform_init_swapchain(struct gs_swap_chain *swap)
{
	Display *display = swap->device->plat->display;
	struct gs_init_data *info = &swap->info;
	xcb_connection_t *xcb_conn = XGetXCBConnection(display);
	xcb_window_t wid = xcb_generate_id(xcb_conn);
	xcb_window_t parent = swap->info.window.id;
	xcb_get_geometry_reply_t *geometry =
		get_window_geometry(xcb_conn, parent);
	bool status = false;

	int screen_num;
	int visual;
	GLXFBConfig *fb_config;

	if (!geometry) goto fail_geometry_request;

	screen_num = get_screen_num_from_root(xcb_conn, geometry->root);
	if (screen_num == -1) {
		goto fail_screen;
	}

	/* NOTE:
	 * So GLX is odd. You can have different extensions per screen,
	 * not just per video card or visual.
	 *
	 * Because of this, it makes sense to call LoadGLX everytime
	 * we open a frackin' window. In Windows, entry points can change
	 * so it makes more sense there. Here, despite it virtually never
	 * having the possibility of changing unless the user is intentionally
	 * being an asshole to cause this behavior, we still have to give it
	 * the correct screen num just out of good practice. *sigh*
	 */
	if (!gladLoadGLX(display, screen_num)) {
		blog(LOG_ERROR, "Unable to load GLX entry functions.");
		goto fail_load_glx;
	}

	/* Define our FBConfig hints for GLX... */
	const int fb_attribs[] = {
		GLX_STENCIL_SIZE, get_stencil_format_bits(info->zsformat),
		GLX_DEPTH_SIZE, get_depth_format_bits(info->zsformat),
		GLX_BUFFER_SIZE, get_color_format_bits(info->format),
		GLX_DOUBLEBUFFER, true,
		GLX_X_RENDERABLE, true,
		None
	};

	/* ...fetch the best match... */
	{
		int num_configs;
		fb_config = glXChooseFBConfig(display, screen_num,
			                      fb_attribs, &num_configs);

		if (!fb_config || !num_configs) {
			blog(LOG_ERROR, "Failed to find FBConfig!");
			goto fail_fb_config;
		}
	}

	/* ...then fetch matching visual info for xcb. */
	{
		int error = glXGetFBConfigAttrib(display, fb_config[0], GLX_VISUAL_ID, &visual);

		if (error) {
			blog(LOG_ERROR, "Bad call to GetFBConfigAttrib!");
			goto fail_visual_id;
		}
	}


	xcb_colormap_t colormap = xcb_generate_id(xcb_conn);
	uint32_t mask = XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP;
	uint32_t mask_values[] = { 0, colormap, 0 };

	xcb_create_colormap(xcb_conn,
		XCB_COLORMAP_ALLOC_NONE,
		colormap,
		parent,
		visual
	);

	xcb_create_window(
		xcb_conn, 24 /* Hardcoded? */,
		wid, parent,
		0, 0,
		geometry->width,
		geometry->height,
		0, 0,
		visual, mask, mask_values
	);

	swap->wi->config = fb_config[0];
	swap->wi->window = wid;

	xcb_map_window(xcb_conn, wid);

	XFree(fb_config);
	status = true;
	goto success;

fail_visual_id:
	XFree(fb_config);
fail_fb_config:
fail_load_glx:
fail_screen:
fail_geometry_request:
success:
	free(geometry);
	return status;
}
Exemplo n.º 4
0
void    X11OpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
{

    m_data->m_dpy = MyXOpenDisplay(NULL);

    m_data->m_glWidth = ci.m_width;
    m_data->m_glHeight = ci.m_height;

    if(m_data->m_dpy == NULL) {
        fprintf(stderr, "\n\tcannot connect to X server\n\n");
            exit(EXIT_FAILURE);
     }

    m_data->m_root = DefaultRootWindow(m_data->m_dpy);

#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS

	int res=gladLoadGLX(m_data->m_dpy,DefaultScreen(m_data->m_dpy));
	if (!res)
	{
		printf("Error in gladLoadGLX\n");
		exit(0);
	}
#endif



    if (ci.m_openglVersion < 3)
    {
        forceOpenGL3 = false;
    }

    if (forceOpenGL3)
    {
        int glxMinor, glxMajor;
        if (!glXQueryVersion(m_data->m_dpy,&glxMajor,&glxMinor) || (((glxMajor==1)&&(glxMinor<3)) || (glxMajor<1)))
        {
            fprintf(stderr, "Invalid GLX version: major %d, minor %d\n",glxMajor,glxMinor);
            exit(EXIT_FAILURE);
        }

        static int visual_attribs[] =
            {
              GLX_X_RENDERABLE    , True,
              GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
              GLX_RENDER_TYPE     , GLX_RGBA_BIT,
              GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
              GLX_RED_SIZE        , 8,
              GLX_GREEN_SIZE      , 8,
              GLX_BLUE_SIZE       , 8,
              GLX_ALPHA_SIZE      , 8,
              GLX_DEPTH_SIZE      , 24,
              GLX_STENCIL_SIZE    , 8,
              GLX_DOUBLEBUFFER    , True,
              None
            };
            int fbcount;
            GLXFBConfig* fbc = glXChooseFBConfig(m_data->m_dpy, DefaultScreen(m_data->m_dpy), visual_attribs, &fbcount);
            if (!fbc)
            {
                fprintf(stderr,  "Failed to retrieve a framebuffer config\n" );
                exit(1);
            }
///don't use highest samples, it is really slow on some NVIDIA Quadro cards
#ifdef USE_HIGHEST_SAMPLES
            int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;

            int i;
            for (i=0; i<fbcount; ++i)
            {
	            XVisualInfo *vi = glXGetVisualFromFBConfig( m_data->m_dpy, fbc[i] );
	            if ( vi )
	            {
	              int samp_buf, samples;
	              glXGetFBConfigAttrib( m_data->m_dpy, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
	              glXGetFBConfigAttrib( m_data->m_dpy, fbc[i], GLX_SAMPLES       , &samples  );

	              //printf( "  Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
	               //       " SAMPLES = %d\n",
	                //      i, vi -> visualid, samp_buf, samples );

	              if ( best_fbc < 0 || (samp_buf && (samples > best_num_samp)) )
	                best_fbc = i, best_num_samp = samples;
	              if ( worst_fbc < 0 || (!samp_buf || (samples < worst_num_samp)) )
	                worst_fbc = i, worst_num_samp = samples;
	            }
	            MyXFree( vi );
            }

            m_data->m_bestFbc = fbc[ best_fbc ];
#else
	    m_data->m_bestFbc = *fbc;
#endif
            // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
            MyXFree( fbc );

            m_data->m_vi = glXGetVisualFromFBConfig( m_data->m_dpy, m_data->m_bestFbc );


            m_data->m_swa.colormap = m_data->m_cmap = MyXCreateColormap( m_data->m_dpy,
                                                 RootWindow( m_data->m_dpy, m_data->m_vi->screen ),
                                                 m_data->m_vi->visual, AllocNone );
            m_data->m_swa.background_pixmap = None ;
            m_data->m_swa.border_pixel      = 0;
            m_data->m_swa.event_mask        = ExposureMask | KeyReleaseMask | KeyPressMask |ButtonPressMask | ButtonReleaseMask |PointerMotionMask|StructureNotifyMask;
;
            m_data->m_root =  RootWindow( m_data->m_dpy, m_data->m_vi->screen );

            m_data->m_win = MyXCreateWindow( m_data->m_dpy, m_data->m_root,
                                      0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput,
                                      m_data->m_vi->visual,
                                      CWBorderPixel|CWColormap|CWEventMask, &m_data->m_swa );

            //m_data->m_win = m_data->m_x11_XCreateWindow(m_data->m_dpy, m_data->m_root, 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput, m_data->m_vi->visual, CWColormap | CWEventMask, &m_data->m_swa);


            if (!m_data->m_win)
            {
                fprintf(stderr, "Cannot create window\n");
                exit(EXIT_FAILURE);
            }

            MyXMapWindow(m_data->m_dpy, m_data->m_win);
            MyXStoreName(m_data->m_dpy, m_data->m_win, "OpenGL3 Window");


    } else
    {
         m_data->m_vi = glXChooseVisual(m_data->m_dpy, 0, att);

				printf("4\n");

         if(m_data->m_vi == NULL) {
            fprintf(stderr, "\n\tno appropriate visual found\n\n");
                exit(EXIT_FAILURE);
         }
         else {
            printf("\n\tvisual %p selected\n", (void *)m_data->m_vi->visualid); /* %p creates hexadecimal output like in glxinfo */
         }


         m_data->m_cmap = MyXCreateColormap(m_data->m_dpy, m_data->m_root, m_data->m_vi->visual, AllocNone);
         m_data->m_swa.colormap = m_data->m_cmap;
         m_data->m_swa.event_mask = ExposureMask | KeyReleaseMask | KeyPressMask |ButtonPressMask | ButtonReleaseMask |PointerMotionMask|StructureNotifyMask;
         m_data->m_win = MyXCreateWindow(m_data->m_dpy, m_data->m_root, 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput, m_data->m_vi->visual, CWColormap | CWEventMask, &m_data->m_swa);

         MyXMapWindow(m_data->m_dpy, m_data->m_win);

         MyXStoreName(m_data->m_dpy, m_data->m_win, "OpenGL2 Window");


    }

    enableOpenGL();
}
Exemplo n.º 5
0
      bool LinuxWindowImpl::RunThread() {
        Thread::RunThread();

        // Lock our use of the display connection..
        XLockDisplay(GetDisplay());

        int screenId = DefaultScreen(GetDisplay());

        // Make sure we have glx extensions loaded.
        gladLoadGLX(GetDisplay(), screenId);

        // Make sure we've got a good version of GLX
        int majorGLX, minorGLX = 0;
        glXQueryVersion(GetDisplay(), &majorGLX, &minorGLX);
        if (majorGLX <= 1 && minorGLX < 3) {
          LOG(Log::CRITICAL) << "GLX 1.3 or greater is required.\n";
          return false;
        }
        else {
          LOG(Log::DEFAULT) << "GLX version: " << majorGLX << "." << minorGLX << '\n';
        }

        // Pick a visual info based on the context display settings.
        ::XVisualInfo* vi = GetVisualInfoFromSettings(GetDisplay(), screenId, settings);
        if (!vi) {
          LOG(Log::CRITICAL) << "Couldn't find an XVisualInfo that matches Context Settings!";
          return false;
        }

        // Open the actual window.
        XSetWindowAttributes windowAttribs;
        windowAttribs.border_pixel = BlackPixel(GetDisplay(), screenId);
        windowAttribs.background_pixel = WhitePixel(GetDisplay(), screenId);
        windowAttribs.override_redirect = True;
        windowAttribs.colormap = XCreateColormap(GetDisplay(), RootWindow(GetDisplay(), screenId), vi->visual, AllocNone);
        windowAttribs.event_mask = ExposureMask | FocusChangeMask;
        window = XCreateWindow(GetDisplay(),
                               RootWindow(GetDisplay(), screenId),
                               0, 0,
                               width, height,
                               0,
                               vi->depth,
                               InputOutput,
                               vi->visual,
                               CWBackPixel | CWColormap | CWBorderPixel | CWEventMask,
                               &windowAttribs);

        XClearWindow(GetDisplay(), window);
        XMapRaised(GetDisplay(), window);

        // Finished with the display
        XUnlockDisplay(GetDisplay());

        Wait();

        XLockDisplay(GetDisplay());

        // Have to do this ridiculousness just to capture when the window is closed...
        Atom wmDeleteMessage = XInternAtom(GetDisplay(), "WM_DELETE_WINDOW", False);
        XSetWMProtocols(GetDisplay(), window, &wmDeleteMessage, 1);

        XUnlockDisplay(GetDisplay());

        // Loop through the events dealing with them.
        running = true;
        while (running) {
          xcb_generic_event_t* event = xcb_wait_for_event(GetXCBConnection());
          switch(event->response_type & ~0x80) {
            case XCB_EXPOSE:
              break;

            case XCB_CLIENT_MESSAGE: {
              xcb_client_message_event_t* clientMessage = (xcb_client_message_event_t*)event;
              if (clientMessage->data.data32[0] == wmDeleteMessage)
                running = false;
              break;
            }

            default:
              break;
          }

          free(event);
        }

        XFree(vi);

        XLockDisplay(GetDisplay());
        XFreeColormap(LinuxWindowImpl::GetDisplay(), windowAttribs.colormap);
        XDestroyWindow(LinuxWindowImpl::GetDisplay(), window);
        XUnlockDisplay(GetDisplay());

        return true;
      }