]> git.cworth.org Git - glaze/blobdiff - glaze-gl.c
Implement glXGetProcAdddress (and glXGetProcAddressARB)
[glaze] / glaze-gl.c
index 14d24d76c1bb875e4bd19a84fa39d675cf3460e1..e7dd728c058b53f31b2ba2f0f73fdb128781512d 100644 (file)
@@ -137,6 +137,84 @@ resolve (const char *name)
        return dlsym (libgl_handle, name);
 }
 
+void
+(*glXGetProcAddress (const unsigned char *name))(void);
+
+void
+(*glXGetProcAddress (const unsigned char *name))(void)
+{
+       static int first_call = 1;
+       static typeof (&glXGetProcAddress) wrapper_glXGetProcAddress;
+       static typeof (&glXGetProcAddress) libgl_glXGetProcAddress;
+       void *symbol;
+
+       /* On the first call, check if the wrapper provides an
+        * implementation of this function. */
+       if (first_call) {
+               wrapper_glXGetProcAddress = dlsym (wrapper_handle,
+                                                  "glXGetProcAddress");
+               libgl_glXGetProcAddress = dlsym (libgl_handle,
+                                                "glXGetProcAddress");
+               first_call = 0;
+       }
+
+       /* If the wrapper implements glXGetProcAddress itself, then it
+        * had better know best what to do. Just let it. */
+       if (wrapper_glXGetProcAddress)
+               return wrapper_glXGetProcAddress (name);
+
+       /* Otherwise, we need to resolve the name.
+        *
+        * The wrapper gets first choice on all symbols. */
+       symbol = dlsym (wrapper_handle, (char *) name);
+       if (symbol)
+               return symbol;
+
+       /* The wrapper doesn't care, so defer to the underlying
+        * glXGetProcAddress */
+       return libgl_glXGetProcAddress (name);
+
+}
+
+void
+(*glXGetProcAddressARB (const unsigned char *name))(void);
+
+void
+(*glXGetProcAddressARB (const unsigned char *name))(void)
+{
+       static int first_call = 1;
+       static typeof (&glXGetProcAddressARB) wrapper_glXGetProcAddressARB;
+       static typeof (&glXGetProcAddressARB) libgl_glXGetProcAddressARB;
+       void *symbol;
+
+       /* On the first call, check if the wrapper provides an
+        * implementation of this function. */
+       if (first_call) {
+               wrapper_glXGetProcAddressARB = dlsym (wrapper_handle,
+                                                     "glXGetProcAddressARB");
+               libgl_glXGetProcAddressARB = dlsym (libgl_handle,
+                                                   "glXGetProcAddressARB");
+               first_call = 0;
+       }
+
+       /* If the wrapper implements glXGetProcAddressARB itself, then
+        * it had better know best what to do. Just let it. */
+       if (wrapper_glXGetProcAddressARB)
+               return wrapper_glXGetProcAddressARB (name);
+
+       /* Otherwise, we need to resolve the name.
+        *
+        * The wrapper gets first choice on all symbols. */
+       symbol = dlsym (wrapper_handle, (char *) name);
+       if (symbol)
+               return symbol;
+
+       /* The wrapper doesn't care, so defer to the underlying
+        * glXGetProcAddressARB */
+       return libgl_glXGetProcAddressARB (name);
+
+}
+
 #define GLAZE_API(name)                                                        \
 void * name() __attribute__((ifunc(#name "_resolver")));               \
 static void *                                                          \