summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Versace <chad.versace@linux.intel.com>2013-07-09 09:44:47 -0700
committerChad Versace <chad.versace@linux.intel.com>2013-07-26 20:16:21 -0700
commit229693794eb4038d8796e1c77e43097e73ca19a6 (patch)
tree2782ecf826f3f151478466ef1646c8e6f12f85f1
parent7217987e5dbf25fcbedda42ba92769121abc5e24 (diff)
glx: Catch Xlib errors with function wrappers
This patch defines a wrapper for each GLX function called by the glx directory. Each wrapper catches any Xlib error emitted by the wrapped function. The wrapper's signature matches the wrapped. All Xlib errors generated by Waffle must be caught by Waffle. Otherwise, the Xlib error handler installed by the user will catch the error and may handle it in a way Waffle doesn't like. Or, even worse, the default Xlib error handler will catch it, which exits the process. Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
-rw-r--r--src/waffle/glx/glx_config.c21
-rw-r--r--src/waffle/glx/glx_context.c35
-rw-r--r--src/waffle/glx/glx_display.c5
-rw-r--r--src/waffle/glx/glx_platform.c7
-rw-r--r--src/waffle/glx/glx_window.c3
-rw-r--r--src/waffle/glx/glx_wrappers.h131
6 files changed, 164 insertions, 38 deletions
diff --git a/src/waffle/glx/glx_config.c b/src/waffle/glx/glx_config.c
index 1d7c059..1ea19ac 100644
--- a/src/waffle/glx/glx_config.c
+++ b/src/waffle/glx/glx_config.c
@@ -34,6 +34,7 @@
#include "glx_config.h"
#include "glx_display.h"
#include "glx_platform.h"
+#include "glx_wrappers.h"
bool
glx_config_destroy(struct wcore_config *wc_self)
@@ -198,10 +199,10 @@ glx_config_choose(struct wcore_platform *wc_plat,
};
// Set glx_fbconfig.
- configs = glXChooseFBConfig(dpy->x11.xlib,
- dpy->x11.screen,
- attrib_list,
- &num_configs);
+ configs = wrapped_glXChooseFBConfig(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");
@@ -211,18 +212,18 @@ glx_config_choose(struct wcore_platform *wc_plat,
self->glx_fbconfig = configs[0];
// Set glx_fbconfig_id.
- ok = !glXGetFBConfigAttrib(dpy->x11.xlib,
- self->glx_fbconfig,
- GLX_FBCONFIG_ID,
- &self->glx_fbconfig_id);
+ ok = !wrapped_glXGetFBConfigAttrib(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 = glXGetVisualFromFBConfig(dpy->x11.xlib,
- self->glx_fbconfig);
+ vi = wrapped_glXGetVisualFromFBConfig(dpy->x11.xlib,
+ self->glx_fbconfig);
if (!vi) {
wcore_errorf(WAFFLE_ERROR_UNKNOWN,
"glXGetVisualInfoFromFBConfig failed with "
diff --git a/src/waffle/glx/glx_context.c b/src/waffle/glx/glx_context.c
index a0563a3..e65bee3 100644
--- a/src/waffle/glx/glx_context.c
+++ b/src/waffle/glx/glx_context.c
@@ -38,6 +38,7 @@
#include "glx_context.h"
#include "glx_display.h"
#include "glx_platform.h"
+#include "glx_wrappers.h"
bool
glx_context_destroy(struct wcore_context *wc_self)
@@ -53,7 +54,7 @@ glx_context_destroy(struct wcore_context *wc_self)
dpy = glx_display(wc_self->display);
if (self->glx)
- glXDestroyContext(dpy->x11.xlib, self->glx);
+ wrapped_glXDestroyContext(dpy->x11.xlib, self->glx);
ok &= wcore_context_teardown(wc_self);
free(self);
@@ -137,11 +138,6 @@ glx_context_fill_attrib_list(struct glx_config *config,
return true;
}
-static int glx_dummy_error_handler(Display *dpy, XErrorEvent *err)
-{
- return 0;
-}
-
static GLXContext
glx_context_create_native(struct glx_config *config,
struct glx_context *share_ctx)
@@ -150,10 +146,6 @@ glx_context_create_native(struct glx_config *config,
GLXContext real_share_ctx = share_ctx ? share_ctx->glx : NULL;
struct glx_display *dpy = glx_display(config->wcore.display);
struct glx_platform *platform = glx_platform(dpy->wcore.platform);
- int (*old_error_handler)(Display *, XErrorEvent *);
-
- /* This prevents Xlib from killing the process if there's an error. */
- old_error_handler = XSetErrorHandler(glx_dummy_error_handler);
if (dpy->ARB_create_context) {
bool ok;
@@ -165,11 +157,12 @@ glx_context_create_native(struct glx_config *config,
if (!ok)
return false;
- ctx = platform->glXCreateContextAttribsARB(dpy->x11.xlib,
- config->glx_fbconfig,
- real_share_ctx,
- true /*direct?*/,
- attrib_list);
+ ctx = wrapped_glXCreateContextAttribsARB(platform,
+ dpy->x11.xlib,
+ config->glx_fbconfig,
+ real_share_ctx,
+ true /*direct?*/,
+ attrib_list);
if (!ctx) {
wcore_errorf(WAFFLE_ERROR_UNKNOWN,
"glXCreateContextAttribsARB failed");
@@ -177,19 +170,17 @@ glx_context_create_native(struct glx_config *config,
}
}
else {
- ctx = glXCreateNewContext(dpy->x11.xlib,
- config->glx_fbconfig,
- GLX_RGBA_TYPE,
- real_share_ctx,
- true /*direct?*/);
+ ctx = wrapped_glXCreateNewContext(dpy->x11.xlib,
+ config->glx_fbconfig,
+ GLX_RGBA_TYPE,
+ real_share_ctx,
+ true /*direct?*/);
if (!ctx) {
wcore_errorf(WAFFLE_ERROR_UNKNOWN, "glXCreateContext failed");
return NULL;
}
}
- XSetErrorHandler(old_error_handler);
-
return ctx;
}
diff --git a/src/waffle/glx/glx_display.c b/src/waffle/glx/glx_display.c
index a29fb3c..184438f 100644
--- a/src/waffle/glx/glx_display.c
+++ b/src/waffle/glx/glx_display.c
@@ -31,6 +31,7 @@
#include "glx_display.h"
#include "glx_platform.h"
+#include "glx_wrappers.h"
bool
glx_display_destroy(struct wcore_display *wc_self)
@@ -51,8 +52,8 @@ static bool
glx_display_set_extensions(struct glx_display *self)
{
- const char *s = glXQueryExtensionsString(self->x11.xlib,
- self->x11.screen);
+ const char *s = wrapped_glXQueryExtensionsString(self->x11.xlib,
+ self->x11.screen);
if (!s) {
wcore_errorf(WAFFLE_ERROR_UNKNOWN,
"glXQueryExtensionsString failed");
diff --git a/src/waffle/glx/glx_platform.c b/src/waffle/glx/glx_platform.c
index 658c132..8ddcfcb 100644
--- a/src/waffle/glx/glx_platform.c
+++ b/src/waffle/glx/glx_platform.c
@@ -34,6 +34,7 @@
#include "glx_display.h"
#include "glx_platform.h"
#include "glx_window.h"
+#include "glx_wrappers.h"
static const struct wcore_platform_vtbl glx_platform_vtbl;
@@ -88,9 +89,9 @@ glx_platform_make_current(struct wcore_platform *wc_self,
struct wcore_window *wc_window,
struct wcore_context *wc_ctx)
{
- return glXMakeCurrent(glx_display(wc_dpy)->x11.xlib,
- wc_window ? glx_window(wc_window)->x11.xcb : 0,
- wc_ctx ? glx_context(wc_ctx)->glx : NULL);
+ 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);
}
static void*
diff --git a/src/waffle/glx/glx_window.c b/src/waffle/glx/glx_window.c
index b1584d1..6519738 100644
--- a/src/waffle/glx/glx_window.c
+++ b/src/waffle/glx/glx_window.c
@@ -31,6 +31,7 @@
#include "glx_config.h"
#include "glx_display.h"
#include "glx_window.h"
+#include "glx_wrappers.h"
bool
glx_window_destroy(struct wcore_window *wc_self)
@@ -93,7 +94,7 @@ 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);
- glXSwapBuffers(dpy->x11.xlib, self->x11.xcb);
+ wrapped_glXSwapBuffers(dpy->x11.xlib, self->x11.xcb);
return true;
}
diff --git a/src/waffle/glx/glx_wrappers.h b/src/waffle/glx/glx_wrappers.h
new file mode 100644
index 0000000..5f53332
--- /dev/null
+++ b/src/waffle/glx/glx_wrappers.h
@@ -0,0 +1,131 @@
+// Copyright 2013 Intel Corporation
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/// @file
+/// @brief Wrappers for GLX functions
+///
+/// Each wrapper catches any Xlib error emitted by the wrapped function. The
+/// wrapper's signature matches the wrapped.
+///
+/// All Xlib error generated by Waffle must be caught by Waffle. Otherwise, the
+/// Xlib error handler installed by the user will catch the error and may
+/// handle it in a way Waffle doesn't like. Or, even worse, the default Xlib
+/// error handler will catch it, which exits the process.
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <GL/glx.h>
+
+#include "glx_platform.h"
+#include "x11_wrappers.h"
+
+static inline GLXFBConfig*
+wrapped_glXChooseFBConfig(Display *dpy, int screen,
+ const int *attribList, int *nitems)
+{
+ X11_SAVE_ERROR_HANDLER
+ GLXFBConfig *configs = glXChooseFBConfig(dpy, screen, attribList, nitems);
+ X11_RESTORE_ERROR_HANDLER
+ return configs;
+}
+
+static inline GLXContext
+wrapped_glXCreateContextAttribsARB(
+ struct glx_platform *platform, Display *dpy, GLXFBConfig config,
+ GLXContext share_context, Bool direct, const int *attrib_list)
+{
+ X11_SAVE_ERROR_HANDLER
+ GLXContext ctx = platform->glXCreateContextAttribsARB(
+ dpy, config, share_context, direct, attrib_list);
+ X11_RESTORE_ERROR_HANDLER
+ return ctx;
+}
+
+static inline GLXContext
+wrapped_glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType,
+ GLXContext shareList, Bool direct)
+{
+ X11_SAVE_ERROR_HANDLER
+ GLXContext ctx = glXCreateNewContext(dpy, config, renderType, shareList,
+ direct);
+ X11_RESTORE_ERROR_HANDLER
+ return ctx;
+}
+
+static inline int
+wrapped_glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config,
+ int attribute, int *value)
+{
+ X11_SAVE_ERROR_HANDLER
+ int error = glXGetFBConfigAttrib(dpy, config, attribute, value);
+ X11_RESTORE_ERROR_HANDLER
+ return error;
+}
+
+static inline XVisualInfo*
+wrapped_glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
+{
+ X11_SAVE_ERROR_HANDLER
+ XVisualInfo *vi = glXGetVisualFromFBConfig(dpy, config);
+ X11_RESTORE_ERROR_HANDLER
+ return vi;
+}
+
+static inline void
+wrapped_glXDestroyContext(Display *dpy, GLXContext ctx)
+{
+ X11_SAVE_ERROR_HANDLER
+ glXDestroyContext(dpy, ctx);
+ X11_RESTORE_ERROR_HANDLER
+}
+
+static inline Bool
+wrapped_glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)
+{
+ X11_SAVE_ERROR_HANDLER
+ Bool ok = glXMakeCurrent(dpy, drawable, ctx);
+ X11_RESTORE_ERROR_HANDLER
+ return ok;
+}
+
+static inline const char*
+wrapped_glXQueryExtensionsString(Display *dpy, int screen)
+{
+ X11_SAVE_ERROR_HANDLER
+ const char *s = glXQueryExtensionsString(dpy, screen);
+ X11_RESTORE_ERROR_HANDLER
+ return s;
+}
+
+static inline void
+wrapped_glXSwapBuffers(Display *dpy, GLXDrawable drawable)
+{
+ X11_SAVE_ERROR_HANDLER
+ glXSwapBuffers(dpy, drawable);
+ X11_RESTORE_ERROR_HANDLER
+}