EGL with XCB Example
main.c:
.c
#include <stdio.h>
#include <stdlib.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <xcb/xcb.h>
int main(void) {
// Initialize XCB connection
xcb_connection_t *conn = xcb_connect(NULL, NULL);
if (xcb_connection_has_error(conn)) {
fprintf(stderr, "Cannot open display\n");
return 1;
}
// Get first screen
const xcb_setup_t *setup = xcb_get_setup(conn);
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
xcb_screen_t *screen = iter.data;
// Create window
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t values[] = {screen->white_pixel, XCB_EVENT_MASK_EXPOSURE};
xcb_window_t win = xcb_generate_id(conn);
xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, screen->root,
0, 0, 800, 600, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual, mask, values);
xcb_map_window(conn, win);
xcb_flush(conn);
// Initialize EGL
EGLDisplay egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (egl_dpy == EGL_NO_DISPLAY) {
fprintf(stderr, "eglGetDisplay failed\n");
xcb_disconnect(conn);
return 1;
}
if (!eglInitialize(egl_dpy, NULL, NULL)) {
fprintf(stderr, "eglInitialize failed\n");
xcb_disconnect(conn);
return 1;
}
// Choose EGL config
EGLint config_attrs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_NONE
};
EGLConfig egl_cfg;
EGLint num_configs;
if (!eglChooseConfig(egl_dpy, config_attrs, &egl_cfg, 1, &num_configs)) {
fprintf(stderr, "eglChooseConfig failed\n");
eglTerminate(egl_dpy);
xcb_disconnect(conn);
return 1;
}
// Create EGL surface
EGLSurface egl_surf = eglCreateWindowSurface(egl_dpy, egl_cfg, win, NULL);
if (egl_surf == EGL_NO_SURFACE) {
fprintf(stderr, "eglCreateWindowSurface failed\n");
eglTerminate(egl_dpy);
xcb_disconnect(conn);
return 1;
}
// Create EGL context
EGLint ctx_attrs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
EGLContext egl_ctx = eglCreateContext(egl_dpy, egl_cfg, EGL_NO_CONTEXT, ctx_attrs);
if (egl_ctx == EGL_NO_CONTEXT) {
fprintf(stderr, "eglCreateContext failed\n");
eglDestroySurface(egl_dpy, egl_surf);
eglTerminate(egl_dpy);
xcb_disconnect(conn);
return 1;
}
// Make context current
eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx);
// Main loop
while (1) {
xcb_generic_event_t *ev = xcb_wait_for_event(conn);
if (!ev) continue;
switch (ev->response_type & ~0x80) {
case XCB_EXPOSE:
// Clear screen
glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(egl_dpy, egl_surf);
break;
}
free(ev);
}
// Cleanup
eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(egl_dpy, egl_ctx);
eglDestroySurface(egl_dpy, egl_surf);
eglTerminate(egl_dpy);
xcb_disconnect(conn);
return 0;
}
Run Command:
cc main.c -lxcb -lEGL -lGL && ./a.out