static bool glx_platform_make_current(struct wcore_platform *wc_self, struct wcore_display *wc_dpy, struct wcore_window *wc_window, struct wcore_context *wc_ctx) { return wrapped_glXMakeCurrent(glx_display(wc_dpy)->x11.xlib, wc_window ? glx_window(wc_window)->x11.xcb : 0, wc_ctx ? glx_context(wc_ctx)->glx : NULL); }
bool glx_window_swap_buffers(struct wcore_window *wc_self) { struct glx_window *self = glx_window(wc_self); struct glx_display *dpy = glx_display(wc_self->display); struct glx_platform *plat = glx_platform(wc_self->display->platform); wrapped_glXSwapBuffers(plat, dpy->x11.xlib, self->x11.xcb); return true; }
union waffle_native_config* glx_config_get_native(struct wcore_config *wc_self) { struct glx_config *self = glx_config(wc_self); struct glx_display *dpy = glx_display(wc_self->display); union waffle_native_config *n_config; WCORE_CREATE_NATIVE_UNION(n_config, glx); if (!n_config) return NULL; n_config->glx->xlib_display = dpy->x11.xlib; n_config->glx->glx_fbconfig = self->glx_fbconfig; return n_config; }
union waffle_native_window* glx_window_get_native(struct wcore_window *wc_self) { struct glx_window *self = glx_window(wc_self); struct glx_display *dpy = glx_display(wc_self->display); union waffle_native_window *n_window; WCORE_CREATE_NATIVE_UNION(n_window, glx); if (!n_window) return NULL; n_window->glx->xlib_display = dpy->x11.xlib; n_window->glx->xlib_window = self->x11.xcb; return n_window; }
struct wcore_window* glx_window_create(struct wcore_platform *wc_plat, struct wcore_config *wc_config, int32_t width, int32_t height, const intptr_t attrib_list[]) { struct glx_window *self; struct glx_display *dpy = glx_display(wc_config->display); struct glx_config *config = glx_config(wc_config); bool ok = true; if (width == -1 && height == -1) { width = DisplayWidth(dpy->x11.xlib, dpy->x11.screen); height = DisplayHeight(dpy->x11.xlib, dpy->x11.screen); } if (wcore_attrib_list_length(attrib_list) > 0) { wcore_error_bad_attribute(attrib_list[0]); return NULL; } self = wcore_calloc(sizeof(*self)); if (self == NULL) return NULL; ok = wcore_window_init(&self->wcore, wc_config); if (!ok) goto error; ok = x11_window_init(&self->x11, &dpy->x11, config->xcb_visual_id, width, height); if (!ok) goto error; return &self->wcore; error: glx_window_destroy(&self->wcore); return NULL; }
static bool glx_platform_make_current(struct wcore_platform *wc_self, struct wcore_display *wc_dpy, struct wcore_window *wc_window, struct wcore_context *wc_ctx) { struct glx_platform *self = glx_platform(wc_self); Display *dpy = glx_display(wc_dpy)->x11.xlib; GLXDrawable win = wc_window ? glx_window(wc_window)->x11.xcb : 0; GLXContext ctx = wc_ctx ? glx_context(wc_ctx)->glx : NULL; bool ok; ok = wrapped_glXMakeCurrent(self, dpy, win, ctx); if (!ok) { wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glXMakeCurrent failed"); } return ok; }
struct wcore_config* glx_config_choose(struct wcore_platform *wc_plat, struct wcore_display *wc_dpy, const struct wcore_config_attrs *attrs) { struct glx_config *self; struct glx_display *dpy = glx_display(wc_dpy); struct glx_platform *plat = glx_platform(wc_plat); GLXFBConfig *configs = NULL; int num_configs = 0; XVisualInfo *vi = NULL; bool ok = true; if (!glx_config_check_context_attrs(dpy, attrs)) return NULL; self = wcore_calloc(sizeof(*self)); if (self == NULL) return NULL; ok = wcore_config_init(&self->wcore, wc_dpy, attrs); if (!ok) goto error; int attrib_list[] = { // From page 12 (18 of pdf) of the GLX 1.4 spec: // // For GLXFBConfigs that correspond to a TrueColor or DirectColor // visual, GLX BUFFER SIZE is the sum of GLX RED SIZE, GLX GREEN // SIZE, GLX BLUE SIZE, and GLX ALPHA SIZE. GLX_BUFFER_SIZE, attrs->rgba_size, GLX_RED_SIZE, attrs->red_size, GLX_GREEN_SIZE, attrs->green_size, GLX_BLUE_SIZE, attrs->blue_size, GLX_ALPHA_SIZE, attrs->alpha_size, GLX_DEPTH_SIZE, attrs->depth_size, GLX_STENCIL_SIZE, attrs->stencil_size, GLX_SAMPLE_BUFFERS, attrs->sample_buffers, GLX_SAMPLES, attrs->samples, GLX_DOUBLEBUFFER, attrs->double_buffered, GLX_ACCUM_RED_SIZE, attrs->accum_buffer, GLX_ACCUM_GREEN_SIZE, attrs->accum_buffer, GLX_ACCUM_BLUE_SIZE, attrs->accum_buffer, GLX_ACCUM_ALPHA_SIZE, attrs->accum_buffer, // According to the GLX 1.4 spec Table 3.4, the default value of // GLX_DRAWABLE_TYPE is GLX_WINDOW_BIT. Explicitly set the default // here for the sake of self-documentation. GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 0, }; // Set glx_fbconfig. configs = wrapped_glXChooseFBConfig(plat, dpy->x11.xlib, dpy->x11.screen, attrib_list, &num_configs); if (!configs || num_configs == 0) { wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glXChooseFBConfig returned no matching configs"); goto error; } // Simply take the first. self->glx_fbconfig = configs[0]; // Set glx_fbconfig_id. ok = !wrapped_glXGetFBConfigAttrib(plat, dpy->x11.xlib, self->glx_fbconfig, GLX_FBCONFIG_ID, &self->glx_fbconfig_id); if (!ok) { wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glxGetFBConfigAttrib failed"); goto error; } // Set xcb_visual_id. vi = wrapped_glXGetVisualFromFBConfig(plat, dpy->x11.xlib, self->glx_fbconfig); if (!vi) { wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glXGetVisualInfoFromFBConfig failed with " "GLXFBConfigID=0x%x\n", self->glx_fbconfig_id); goto error; } self->xcb_visual_id = vi->visualid; goto cleanup; error: glx_config_destroy(&self->wcore); self = NULL; cleanup: if (configs) XFree(configs); if (vi) XFree(vi); return &self->wcore; }