aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mgl/mgl.h3
-rw-r--r--include/mgl/window/window.h1
-rw-r--r--src/mgl.c67
-rw-r--r--src/window/window.c83
4 files changed, 79 insertions, 75 deletions
diff --git a/include/mgl/mgl.h b/include/mgl/mgl.h
index b43e4b9..f2373b7 100644
--- a/include/mgl/mgl.h
+++ b/include/mgl/mgl.h
@@ -10,9 +10,6 @@ typedef struct mgl_context mgl_context;
struct mgl_context {
mgl_connection connection;
mgl_gl gl;
- GLXFBConfig *fbconfigs;
- _XVisualInfo *visual_info;
- GLXFBConfig fbconfig;
unsigned long wm_delete_window_atom;
unsigned long net_wm_ping_atom;
unsigned long net_wm_pid_atom;
diff --git a/include/mgl/window/window.h b/include/mgl/window/window.h
index 7dd85b4..34f8cbb 100644
--- a/include/mgl/window/window.h
+++ b/include/mgl/window/window.h
@@ -52,6 +52,7 @@ typedef struct {
mgl_window_handle parent_window; /* 0 = root window */
bool hidden; /* false by default */
bool override_redirect; /* false by default */
+ bool support_alpha; /* support alpha for the window, false by default */
} mgl_window_create_params;
typedef enum {
diff --git a/src/mgl.c b/src/mgl.c
index d73e2d0..b2d2bb6 100644
--- a/src/mgl.c
+++ b/src/mgl.c
@@ -1,7 +1,6 @@
#include "../include/mgl/mgl.h"
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
-#include <X11/extensions/Xrender.h>
#include <stdio.h>
#ifndef NDEBUG
#include <stdlib.h>
@@ -23,66 +22,6 @@ static int ignore_xioerror(Display *display) {
return 0;
}
-static int glx_context_init() {
- const int attr[] = {
- GLX_RENDER_TYPE, GLX_RGBA_BIT,
- GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
- GLX_DOUBLEBUFFER, True,
- GLX_RED_SIZE, 8,
- GLX_GREEN_SIZE, 8,
- GLX_BLUE_SIZE, 8,
- GLX_ALPHA_SIZE, 8,
- GLX_DEPTH_SIZE, 0,
- None
- };
-
- context.fbconfigs = NULL;
- context.visual_info = NULL;
- context.fbconfig = NULL;
-
- int numfbconfigs = 0;
- context.fbconfigs = context.gl.glXChooseFBConfig(context.connection, DefaultScreen(context.connection), attr, &numfbconfigs);
- for(int i = 0; i < numfbconfigs; i++) {
- context.visual_info = context.gl.glXGetVisualFromFBConfig(context.connection, context.fbconfigs[i]);
- if(!context.visual_info)
- continue;
-
- XRenderPictFormat *pict_format = XRenderFindVisualFormat(context.connection, ((XVisualInfo*)context.visual_info)->visual);
- if(!pict_format) {
- XFree(context.visual_info);
- context.visual_info = NULL;
- continue;
- }
-
- context.fbconfig = context.fbconfigs[i];
- if(pict_format->direct.alphaMask > 0)
- break;
-
- XFree(context.visual_info);
- context.visual_info = NULL;
- context.fbconfig = NULL;
- }
-
- if(!context.visual_info) {
- fprintf(stderr, "mgl error: no appropriate visual found\n");
- return -1;
- }
-
- return 0;
-}
-
-static void glx_context_deinit() {
- if(context.visual_info) {
- XFree(context.visual_info);
- context.visual_info = NULL;
- }
-
- if(context.fbconfigs) {
- XFree(context.fbconfigs);
- context.fbconfigs = NULL;
- }
-}
-
int mgl_init(void) {
++init_count;
if(init_count == 1) {
@@ -111,11 +50,6 @@ int mgl_init(void) {
mgl_deinit();
return -1;
}
-
- if(glx_context_init() != 0) {
- mgl_deinit();
- return -1;
- }
}
return 0;
}
@@ -136,7 +70,6 @@ void mgl_deinit(void) {
GLX needs to be unloaded after closing the display on nvidia because
nvidia registers cleanup callbacks on exit, that uses the x11 display.
*/
- glx_context_deinit();
mgl_gl_unload(&context.gl);
}
}
diff --git a/src/window/window.c b/src/window/window.c
index eeb2e43..1817a2f 100644
--- a/src/window/window.c
+++ b/src/window/window.c
@@ -5,6 +5,7 @@
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/Xatom.h>
+#include <X11/extensions/Xrender.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@@ -68,6 +69,9 @@ typedef struct {
unsigned int prev_keycode_pressed;
bool key_was_released;
Colormap color_map;
+ GLXFBConfig *fbconfigs;
+ GLXFBConfig fbconfig;
+ XVisualInfo *visual_info;
/*
Used to stack text event on top of key press/release events and other text events.
For example pressing a key should give the user both key press and text events
@@ -79,7 +83,55 @@ typedef struct {
static void x11_context_deinit(x11_context *self);
-static int x11_context_init(x11_context *self) {
+static bool glx_context_choose(mgl_context *context, GLXFBConfig **fbconfigs, GLXFBConfig *fbconfig, XVisualInfo **visual_info, bool alpha) {
+ const int attr[] = {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_DOUBLEBUFFER, True,
+ GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8,
+ GLX_ALPHA_SIZE, alpha ? 8 : 0,
+ GLX_DEPTH_SIZE, 0,
+ None
+ };
+
+ *fbconfigs = NULL;
+ *visual_info = NULL;
+ *fbconfig = NULL;
+
+ int numfbconfigs = 0;
+ *fbconfigs = context->gl.glXChooseFBConfig(context->connection, DefaultScreen(context->connection), attr, &numfbconfigs);
+ for(int i = 0; i < numfbconfigs; i++) {
+ *visual_info = (XVisualInfo*)context->gl.glXGetVisualFromFBConfig(context->connection, (*fbconfigs)[i]);
+ if(!*visual_info)
+ continue;
+
+ XRenderPictFormat *pict_format = XRenderFindVisualFormat(context->connection, (*visual_info)->visual);
+ if(!pict_format) {
+ XFree(*visual_info);
+ *visual_info = NULL;
+ continue;
+ }
+
+ *fbconfig = (*fbconfigs)[i];
+ if((alpha && pict_format->direct.alphaMask > 0) || (!alpha && pict_format->direct.alphaMask == 0))
+ break;
+
+ XFree(*visual_info);
+ *visual_info = NULL;
+ *fbconfig = NULL;
+ }
+
+ if(!*visual_info) {
+ fprintf(stderr, "mgl error: no appropriate visual found\n");
+ return false;
+ }
+
+ return true;
+}
+
+static int x11_context_init(x11_context *self, bool alpha) {
mgl_context *context = mgl_get_context();
self->glx_context = NULL;
@@ -101,6 +153,15 @@ static int x11_context_init(x11_context *self) {
self->key_was_released = false;
self->color_map = None;
+ self->fbconfigs = NULL;
+ self->fbconfig = NULL;
+ self->visual_info = NULL;
+
+ if(!glx_context_choose(context, &self->fbconfigs, &self->fbconfig, &self->visual_info, alpha)) {
+ x11_context_deinit(self);
+ return -1;
+ }
+
self->default_cursor = XCreateFontCursor(context->connection, XC_arrow);
if(!self->default_cursor) {
x11_context_deinit(self);
@@ -157,6 +218,18 @@ void x11_context_deinit(x11_context *self) {
context->gl.glXDestroyContext(context->connection, self->glx_context);
self->glx_context = NULL;
}
+
+ if(self->visual_info) {
+ XFree(self->visual_info);
+ self->visual_info = NULL;
+ }
+
+ if(self->fbconfigs) {
+ XFree(self->fbconfigs);
+ self->fbconfigs = NULL;
+ }
+
+ self->fbconfig = NULL;
}
static bool x11_context_append_event(x11_context *self, const mgl_event *event) {
@@ -228,7 +301,7 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window
}
x11_context *x11_context = self->context;
- if(x11_context_init(x11_context) != 0) {
+ if(x11_context_init(x11_context, params ? params->support_alpha : false) != 0) {
fprintf(stderr, "mgl error: x11_context_init failed\n");
mgl_window_deinit(self);
return -1;
@@ -240,14 +313,14 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window
if(parent_window == 0)
parent_window = DefaultRootWindow(context->connection);
- x11_context->glx_context = context->gl.glXCreateNewContext(context->connection, context->fbconfig, GLX_RGBA_TYPE, 0, True);
+ x11_context->glx_context = context->gl.glXCreateNewContext(context->connection, x11_context->fbconfig, GLX_RGBA_TYPE, 0, True);
if(!x11_context->glx_context) {
fprintf(stderr, "mgl error: glXCreateContext failed\n");
mgl_window_deinit(self);
return -1;
}
- x11_context->color_map = XCreateColormap(context->connection, DefaultRootWindow(context->connection), ((XVisualInfo*)context->visual_info)->visual, AllocNone);
+ x11_context->color_map = XCreateColormap(context->connection, DefaultRootWindow(context->connection), x11_context->visual_info->visual, AllocNone);
if(!x11_context->color_map) {
fprintf(stderr, "mgl error: XCreateColormap failed\n");
mgl_window_deinit(self);
@@ -280,7 +353,7 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window
} else {
self->window = XCreateWindow(context->connection, parent_window, params->position.x, params->position.y,
window_size.x, window_size.y, 0,
- ((XVisualInfo*)context->visual_info)->depth, InputOutput, ((XVisualInfo*)context->visual_info)->visual,
+ x11_context->visual_info->depth, InputOutput, x11_context->visual_info->visual,
CWColormap | CWEventMask | CWOverrideRedirect | CWBorderPixel | CWBackPixmap, &window_attr);
if(!self->window) {
fprintf(stderr, "mgl error: XCreateWindow failed\n");