aboutsummaryrefslogtreecommitdiff
path: root/src/mgl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mgl.c')
-rw-r--r--src/mgl.c86
1 files changed, 83 insertions, 3 deletions
diff --git a/src/mgl.c b/src/mgl.c
index a7221d0..27d33ae 100644
--- a/src/mgl.c
+++ b/src/mgl.c
@@ -1,7 +1,26 @@
#include "../include/mgl/mgl.h"
-#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <stdlib.h>
#include <stdio.h>
+#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;
@@ -12,6 +31,46 @@ static int ignore_xerror(Display *display, XErrorEvent *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.glx.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.glx.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.glx.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) {
@@ -23,20 +82,35 @@ int mgl_init(void) {
}
prev_xerror = XSetErrorHandler(ignore_xerror);
+
if(mgl_glx_load(&context.glx) != 0) {
mgl_deinit();
return -1;
}
+
+ 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_glx_unload(&context.glx);
XSetErrorHandler(prev_xerror);
- XCloseDisplay(context.connection);
- context.connection = NULL;
+ if(context.connection) {
+ XCloseDisplay(context.connection);
+ context.connection = NULL;
+ }
}
if(init_count > 0)
@@ -44,5 +118,11 @@ void mgl_deinit(void) {
}
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;
}