]> git.cworth.org Git - glaze/commitdiff
Add function glaze_set_first_gl_call_callback
authorCarl Worth <cworth@cworth.org>
Wed, 4 Sep 2013 23:44:44 +0000 (16:44 -0700)
committerCarl Worth <cworth@cworth.org>
Wed, 4 Sep 2013 23:44:44 +0000 (16:44 -0700)
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
glaze.c
glaze.h

index 453d4606f2be1320b009630bf1e041960b190afc..7248876b75da4940ee83e71430b9647f41ef801d 100644 (file)
@@ -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 a9acf746f80941c9cc3aa6475802b6ea42649c04..8377d846a149321640e8b3dfc0bcae3c0d3ed1dc 100644 (file)
--- 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 325483a86f1e480fa8f93480cc1f090d06fe12e8..198ec5b797b4ff9cf8167b625d1c529628de5ef6 100644 (file)
--- 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 */