]> git.cworth.org Git - glaze/commitdiff
Implement glXGetProcAdddress (and glXGetProcAddressARB)
authorCarl Worth <cworth@cworth.org>
Sat, 21 Sep 2013 18:34:47 +0000 (11:34 -0700)
committerCarl Worth <cworth@cworth.org>
Sat, 21 Sep 2013 22:00:56 +0000 (15:00 -0700)
Since applications can use these functions to find their symbols, it's
important that Glaze intercept these and ensure that the appropriate
wrapped symbols are returned.

This implementation allows the wrapping library to optionally
implement glXGetProcAddress itself. If it does, it's responsible for
implementing it correctly.

If the wrapping library does not implement glXGetProcAddress, then
Glaze's version will return a symbol from the wrapper if any
exists. Otherwise, it will defer to the underlying glXGetProcAddress
to do whatever it needs to do.

glaze-gl.c
specs/Makefile
specs/glx.def

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 *                                                          \
index b48a944917cfee25cf1d5b2feb376c36c491cd44..ea316f10e888526cb549e2fbdb65eed9102ef50c 100644 (file)
@@ -5,5 +5,8 @@ all: $(TARGETS)
 %.def: %.xml
        ./xml2def $? > $@
 
+glx.def: glx.xml
+       ./xml2def $? | grep -v GetProcAddress > $@
+
 clean:
        rm *.def
index 90c9caa1ed143a6a404caef98c098b751e5cf8ae..fe7f6988f8fce29a307e413af6dd731d899c6e47 100644 (file)
@@ -54,8 +54,6 @@ GLAZE_API(glXGetFBConfigAttribSGIX)
 GLAZE_API(glXGetFBConfigFromVisualSGIX)
 GLAZE_API(glXGetFBConfigs)
 GLAZE_API(glXGetMscRateOML)
-GLAZE_API(glXGetProcAddress)
-GLAZE_API(glXGetProcAddressARB)
 GLAZE_API(glXGetSelectedEvent)
 GLAZE_API(glXGetSelectedEventSGIX)
 GLAZE_API(glXGetSyncValuesOML)