#include "../include/mgl/mgl.h" #include #include #include #define GLX_USE_GL 1 #define GLX_BUFFER_SIZE 2 #define GLX_LEVEL 3 #define GLX_RGBA 4 #define GLX_DOUBLEBUFFER 5 #define GLX_STEREO 6 #define GLX_AUX_BUFFERS 7 #define GLX_RED_SIZE 8 #define GLX_GREEN_SIZE 9 #define GLX_BLUE_SIZE 10 #define GLX_ALPHA_SIZE 11 #define GLX_DEPTH_SIZE 12 #define GLX_STENCIL_SIZE 13 #define GLX_ACCUM_RED_SIZE 14 #define GLX_ACCUM_GREEN_SIZE 15 #define GLX_ACCUM_BLUE_SIZE 16 #define GLX_ACCUM_ALPHA_SIZE 17 static mgl_context context; static int init_count = 0; static XErrorHandler prev_xerror = NULL; static int ignore_xerror(Display *display, XErrorEvent *ee) { (void)display; (void)ee; return 0; } static int glx_context_init() { const int attr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 0, GLX_STENCIL_SIZE, 0, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 0, GLX_DOUBLEBUFFER, /* TODO: Add option to turn this off? */ None }; context.visual_info = context.gl.glXChooseVisual(context.connection, DefaultScreen(context.connection), (int*)attr); if(!context.visual_info) { fprintf(stderr, "glXChooseVisual failed, no appropriate visual found\n"); return -1; } context.glx_context = context.gl.glXCreateContext(context.connection, context.visual_info, NULL, 1); if(!context.glx_context) { fprintf(stderr, "glXCreateContext failed\n"); return -1; } return 0; } static void glx_context_deinit() { if(context.glx_context) { context.gl.glXDestroyContext(context.connection, context.glx_context); context.glx_context = NULL; } if(context.visual_info) { XFree(context.visual_info); context.visual_info = NULL; } } int mgl_init(void) { ++init_count; if(init_count == 1) { context.connection = XOpenDisplay(NULL); if(!context.connection) { fprintf(stderr, "XOpenDisplay(NULL) failed\n"); mgl_deinit(); return -1; } prev_xerror = XSetErrorHandler(ignore_xerror); if(mgl_gl_load(&context.gl) != 0) { mgl_deinit(); return -1; } if(glx_context_init() != 0) { mgl_deinit(); return -1; } } return 0; } void mgl_deinit(void) { if(init_count == 1) { glx_context_deinit(); mgl_gl_unload(&context.gl); mgl_gl_unload(&context.gl); XSetErrorHandler(prev_xerror); if(context.connection) { XCloseDisplay(context.connection); context.connection = NULL; } } if(init_count > 0) --init_count; } mgl_context* mgl_get_context(void) { #ifndef NDEBUG if(init_count == 0) { fprintf(stderr, "Error: mgl_get_context was called before mgl_init\n"); abort(); } #endif return &context; }