From 6cfcdb728c0a088cc12bb3eb93d78b2a9915969b Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 4 Sep 2013 16:44:44 -0700 Subject: [PATCH] Add function glaze_set_first_gl_call_callback This allows the wrapper to specify a callback to be called once OpenGL is first initialized, (without the wrapper library needing to predict what the name of the first GL function called might be, nor needing to wrap all OpenGL calls just in order to intercept the first one). --- glaze-gl.c | 23 +++++++++++++++++++++++ glaze.c | 6 ++++++ glaze.h | 25 +++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/glaze-gl.c b/glaze-gl.c index 453d460..7248876 100644 --- a/glaze-gl.c +++ b/glaze-gl.c @@ -31,6 +31,8 @@ void *libgl_handle; void *wrapper_handle; +#define STRNCMP_LITERAL(str, literal) strncmp (str, literal, sizeof (literal) - 1) + static void open_libgl_handle (void) { @@ -104,8 +106,29 @@ glaze_init (void) static void * resolve (const char *name) { + static int before_first_gl_call = 1; void *symbol; + if (before_first_gl_call && + STRNCMP_LITERAL (name, "gl") == 0 && + STRNCMP_LITERAL (name, "glX") != 0) + { + char *callback_name = getenv ("GLAZE_FIRST_GL_CALL_CALLBACK"); + if (callback_name) { + void (*callback) (void) = dlsym (wrapper_handle, + callback_name); + if (callback) { + (callback) (); + } else { + fprintf (stderr, + "Error: Failed to find function %s " + "in GLAZE_WRAPPER library.\n", + callback_name); + } + } + before_first_gl_call = 0; + } + /* The wrapper gets first choice on all symbols. */ symbol = dlsym (wrapper_handle, name); if (symbol) diff --git a/glaze.c b/glaze.c index a9acf74..8377d84 100644 --- a/glaze.c +++ b/glaze.c @@ -306,3 +306,9 @@ glaze_execute (int argc, char *argv[], const char *wrapper) return; } + +void +glaze_set_first_gl_call_callback (const char *function_name) +{ + setenv ("GLAZE_FIRST_GL_CALL_CALLBACK", function_name, 1); +} diff --git a/glaze.h b/glaze.h index 325483a..198ec5b 100644 --- a/glaze.h +++ b/glaze.h @@ -100,4 +100,29 @@ glaze_lookup (char *function); void glaze_execute (int argc, char *argv[], const char *wrapper); +/* Register a callback function to be called when the first GL + * function, (not glX function) is called. + * + * It's common for Glaze-using libraries to need to do some + * initialization that can only be done once a valid OpenGL context is + * initialized. For example, the library may need to query what kind + * of context has been created. + * + * This function can be used for this purpose. It arranges for a + * function in the wrapper library to be called immediately before the + * first call to an OpenGL function by the application. Note that any + * window-system-sepecific function calls (such as glX functions) are + * not considered "an OpenGL function" for this purpose. + * + * The 'function_name' argument here should be the name of an exported + * function in the wrapper library passed to glaze_exectute, (or + * specified in the GLAZE_WRAPPER variable). The function must have a + * return type of void and must accept no arguments, so should have a + * signature such as: + * + * void function (void); + */ +void +glaze_set_first_gl_call_callback (const char *function_name); + #endif /* GLAZE_H */ -- 2.43.0