#include <string.h>
#include <dlfcn.h>
#include <sys/uio.h>
+#include <X11/Xlib.h>
#include <GL/gl.h>
+#include <GL/glx.h>
#include "functions.h"
static inline void *glsym(const char *sym)
{
- static void *libgl=NULL;
+ static void *libgl = NULL;
if(!libgl)
{
- libgl=dlopen("libGL.so", RTLD_NOW);
+ libgl = dlopen("libGL.so", RTLD_NOW);
if(!libgl)
{
fprintf(stderr, "Could not open libGL: %s\n", dlerror());
return dlsym(libgl, sym);
}
-char *buffer=0;
-char *write_pos;
-struct iovec *iovecs=0;
-struct iovec *cur_vec;
+static char *buffer = 0;
+static char *write_pos;
+static struct iovec *iovecs = 0;
+static struct iovec *cur_vec;
+static unsigned length;
static inline void next_vec()
{
if(write_pos!=cur_vec->iov_base)
{
- cur_vec->iov_len=write_pos-(char *)cur_vec->iov_base;
+ cur_vec->iov_len = write_pos-(char *)cur_vec->iov_base;
+ length += cur_vec->iov_len;
++cur_vec;
- cur_vec->iov_base=write_pos;
+ cur_vec->iov_base = write_pos;
}
}
{
unsigned i;
for(i=0; i<size; ++i)
- *write_pos++=*ptr++;
+ *write_pos++ = *ptr++;
}
static inline void write_char(char v)
{
- *write_pos++=v;
+ *write_pos++ = v;
}
static inline void write_short(short v)
write_bytes((char *)&v, sizeof(float));
}
-static inline void write_double(float v)
+static inline void write_double(double v)
{
write_bytes((char *)&v, sizeof(double));
}
static inline void write_data(const void *data, unsigned size)
{
- write_int(size);
- next_vec();
- cur_vec->iov_base=(void *)data;
- cur_vec->iov_len=size;
- ++cur_vec;
- cur_vec->iov_base=write_pos;
+ if(data)
+ {
+ write_int(size);
+ next_vec();
+ cur_vec->iov_base = (void *)data;
+ cur_vec->iov_len = size;
+ length += size;
+ ++cur_vec;
+ cur_vec->iov_base = write_pos;
+ }
+ else
+ write_int(0);
}
static inline void write_string(const unsigned char *s)
{
- write_data(s, strlen(s));
- /*int len=strlen(s);
- write_int(len);
- write_bytes(s, len);*/
+ write_data(s, strlen(s)+1);
}
static inline void begin_packet(int func)
{
if(!buffer)
- buffer=(char *)malloc(1024);
+ buffer = (char *)malloc(1024);
if(!iovecs)
- iovecs=(struct iovec *)malloc(16*sizeof(struct iovec));
- write_pos=buffer;
- cur_vec=iovecs;
- cur_vec->iov_base=write_pos;
+ iovecs = (struct iovec *)malloc(16*sizeof(struct iovec));
+ write_pos = buffer;
+ cur_vec = iovecs;
+ cur_vec->iov_base = write_pos;
+ length = 0;
+ write_int(0);
write_short(func);
}
static inline void send_packet()
{
- static int fd=-1;
+ static int fd = -1;
if(fd<0)
{
- const char *var=getenv("GLWRAP_FD");
+ const char *var = getenv("GLWRAP_FD");
if(var)
- fd=strtol(var, NULL, 0);
+ fd = strtol(var, NULL, 0);
else
- fd=2;
+ fd = 2;
}
next_vec();
+ write_pos = buffer;
+ write_int(length);
writev(fd, iovecs, cur_vec-iovecs);
}
return 1;
}
+GLenum cur_error = GL_NO_ERROR;
+
+static void check_error()
+{
+ GLenum (*orig_glGetError)() = 0;
+ GLenum code;
+ if(!orig_glGetError)
+ orig_glGetError = glsym("glGetError");
+ code = orig_glGetError();
+ if(code!=GL_NO_ERROR)
+ {
+ begin_packet(FUNC_GLDERROR);
+ write_int(code);
+ send_packet();
+ if(cur_error==GL_NO_ERROR)
+ cur_error = code;
+ }
+}
+
+GLenum APIENTRY glGetError()
+{
+ GLenum ret = cur_error;
+ cur_error = GL_NO_ERROR;
+ begin_packet(FUNC_GLGETERROR);
+ write_int(ret);
+ send_packet();
+ return ret;
+}
+
+void (*glXGetProcAddress(const GLubyte *procname))(void)
+{
+ void *handle = dlopen(NULL, RTLD_LAZY);
+ void (*ret)() = dlsym(handle, (const char *)procname);
+ begin_packet(FUNC_GLXGETPROCADDRESS);
+ write_pointer(ret);
+ write_string(procname);
+ send_packet();
+ return ret;
+}
+
+void (*glXGetProcAddressARB(const GLubyte *))(void) __attribute__((alias("glXGetProcAddress")));
+
#include "glwrap.funcs"