X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglwrap.c;h=52c6552e1f5c0c007939e62f07a31e233ba8e587;hb=03c86c2f632b642aa94f721e326787e91aa69c25;hp=68351143d31aca0567dca79c1d7051a885ced85c;hpb=27a82684df128955f6c4e1467935be14ff9bb816;p=gldbg.git diff --git a/source/glwrap.c b/source/glwrap.c index 6835114..52c6552 100644 --- a/source/glwrap.c +++ b/source/glwrap.c @@ -1,7 +1,7 @@ /* $Id$ This file is part of gldbg -Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions Distributed under the GPL */ @@ -10,38 +10,78 @@ Distributed under the GPL #include #include #include -#include -#include -#include -#include "arraysize.h" -#include "functions.h" -static inline void *glsym(const char *sym) +#define INTERNAL __attribute__((visibility("internal"))) + +INTERNAL inline const char *get_lib_names(void) +{ + const char *env = getenv("GLWRAP_LIBS"); + if(env) + return env; + return "libGL.so"; +} + +INTERNAL inline void *glsym(const char *name) { - static void *libgl = NULL; - if(!libgl) + static void **gl_libs = NULL; + unsigned i; + + if(!gl_libs) { - const char *libgl_name = getenv("GLWRAP_LIBGL"); - if(!libgl_name) - libgl_name = "libGL.so"; - libgl = dlopen(libgl_name, RTLD_NOW); - if(!libgl) + char *lib_names = strdup(get_lib_names()); + unsigned n_libs = 1; + unsigned j; + + for(i=0; lib_names[i]; ++i) + if(lib_names[i]==':') + ++n_libs; + + gl_libs = (void **)malloc((n_libs+1)*sizeof(void *)); + i = 0; + n_libs = 0; + for(j=0;; ++j) { - fprintf(stderr, "Could not open %s: %s\n", libgl_name, dlerror()); - abort(); + if(lib_names[j]==':' || lib_names[j]==0) + { + int at_end = (lib_names[j]==0); + lib_names[j] = 0; + + gl_libs[n_libs] = dlopen(lib_names+i, RTLD_NOW); + if(!gl_libs[n_libs]) + { + fprintf(stderr, "Could not open %s: %s\n", lib_names+i, dlerror()); + abort(); + } + + i = j+1; + ++n_libs; + + if(at_end) + break; + } } + + gl_libs[n_libs] = 0; + free(lib_names); } - return dlsym(libgl, sym); + for(i=0; gl_libs[i]; ++i) + { + void *sym = dlsym(gl_libs[i], name); + if(sym) + return sym; + } + + return NULL; } -static char *buffer = 0; -static char *write_pos; -static struct iovec *iovecs = 0; -static struct iovec *cur_vec; -static unsigned length; +INTERNAL char *buffer = 0; +INTERNAL char *write_pos; +INTERNAL struct iovec *iovecs = 0; +INTERNAL struct iovec *cur_vec; +INTERNAL unsigned length; -static inline void next_vec() +INTERNAL inline void next_vec(void) { if(write_pos!=cur_vec->iov_base) { @@ -52,54 +92,54 @@ static inline void next_vec() } } -static inline void write_bytes(const char *ptr, unsigned size) +INTERNAL inline void write_bytes(const char *ptr, unsigned size) { unsigned i; for(i=0; i