]> git.tdb.fi Git - gldbg.git/blob - source/glwrap.c
Enable warnings and fix them
[gldbg.git] / source / glwrap.c
1 /* $Id$
2
3 This file is part of gldbg
4 Copyright © 2009  Mikko Rasa, Mikkosoft Productions
5 Distributed under the GPL
6 */
7
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <dlfcn.h>
12 #include <sys/uio.h>
13 #include <X11/Xlib.h>
14 #include <GL/gl.h>
15 #include <GL/glx.h>
16 #include "arraysize.h"
17 #include "functions.h"
18
19 static inline void *glsym(const char *sym)
20 {
21         static void *libgl = NULL;
22         if(!libgl)
23         {
24                 libgl = dlopen("libGL.so", RTLD_NOW);
25                 if(!libgl)
26                 {
27                         fprintf(stderr, "Could not open libGL: %s\n", dlerror());
28                         abort();
29                 }
30         }
31
32         return dlsym(libgl, sym);
33 }
34
35 static char *buffer = 0;
36 static char *write_pos;
37 static struct iovec *iovecs = 0;
38 static struct iovec *cur_vec;
39 static unsigned length;
40
41 static inline void next_vec()
42 {
43         if(write_pos!=cur_vec->iov_base)
44         {
45                 cur_vec->iov_len = write_pos-(char *)cur_vec->iov_base;
46                 length += cur_vec->iov_len;
47                 ++cur_vec;
48                 cur_vec->iov_base = write_pos;
49         }
50 }
51
52 static inline void write_bytes(const char *ptr, unsigned size)
53 {
54         unsigned i;
55         for(i=0; i<size; ++i)
56                 *write_pos++ = *ptr++;
57 }
58
59 static inline void write_char(char v)
60 {
61         *write_pos++ = v;
62 }
63
64 static inline void write_short(short v)
65 {
66         write_bytes((char *)&v, sizeof(short));
67 }
68
69 static inline void write_int(int v)
70 {
71         write_bytes((char *)&v, sizeof(int));
72 }
73
74 static inline void write_long(long v)
75 {
76         write_bytes((char *)&v, sizeof(long));
77 }
78
79 static inline void write_long_long(long long v)
80 {
81         write_bytes((char *)&v, sizeof(long long));
82 }
83
84 static inline void write_float(float v)
85 {
86         write_bytes((char *)&v, sizeof(float));
87 }
88
89 static inline void write_double(double v)
90 {
91         write_bytes((char *)&v, sizeof(double));
92 }
93
94 static inline void write_pointer(const void *p)
95 {
96         write_bytes((char *)&p, sizeof(void *));
97 }
98
99 static inline void write_data(const void *data, unsigned size)
100 {
101         if(data)
102         {
103                 write_int(size);
104                 next_vec();
105                 cur_vec->iov_base = (void *)data;
106                 cur_vec->iov_len = size;
107                 length += size;
108                 ++cur_vec;
109                 cur_vec->iov_base = write_pos;
110         }
111         else
112                 write_int(0);
113 }
114
115 static inline void write_string(const char *s)
116 {
117         write_data(s, strlen(s)+1);
118 }
119
120 static inline void write_string_array(const char **sa, unsigned size)
121 {
122         unsigned i;
123         size /= sizeof(const char *);
124         write_int(size);
125         for(i=0; i<size; ++i)
126                 write_string(sa[i]);
127 }
128
129 static inline void begin_packet(int func)
130 {
131         if(!buffer)
132                 buffer = (char *)malloc(1024);
133         if(!iovecs)
134                 iovecs = (struct iovec *)malloc(16*sizeof(struct iovec));
135         write_pos = buffer;
136         cur_vec = iovecs;
137         cur_vec->iov_base = write_pos;
138         length = 0;
139         write_int(0);
140         write_short(func);
141 }
142
143 static inline void send_packet()
144 {
145         static int fd = -1;
146         if(fd<0)
147         {
148                 const char *var = getenv("GLWRAP_FD");
149                 if(var)
150                         fd = strtol(var, NULL, 0);
151                 else
152                         fd = 2;
153         }
154         next_vec();
155         write_pos = buffer;
156         write_int(length);
157         writev(fd, iovecs, cur_vec-iovecs);
158 }
159
160 GLenum cur_error = GL_NO_ERROR;
161
162 static void check_error()
163 {
164         GLenum (*orig_glGetError)() = 0;
165         GLenum code;
166         if(!orig_glGetError)
167                 orig_glGetError = glsym("glGetError");
168         code = orig_glGetError();
169         if(code!=GL_NO_ERROR)
170         {
171                 begin_packet(FUNC_GLDERROR);
172                 write_int(code);
173                 send_packet();
174                 if(cur_error==GL_NO_ERROR)
175                         cur_error = code;
176         }
177 }
178
179 GLenum APIENTRY glGetError()
180 {
181         GLenum ret = cur_error;
182         cur_error = GL_NO_ERROR;
183         begin_packet(FUNC_GLGETERROR);
184         write_int(ret);
185         send_packet();
186         return ret;
187 }
188
189 void (*glXGetProcAddress(const GLubyte *procname))(void)
190 {
191         void *handle = dlopen(NULL, RTLD_LAZY);
192         void (*ret)() = dlsym(handle, (const char *)procname);
193         begin_packet(FUNC_GLXGETPROCADDRESS);
194         write_pointer(ret);
195         write_string(procname);
196         send_packet();
197         return ret;
198 }
199
200 void (*glXGetProcAddressARB(const GLubyte *))(void) __attribute__((alias("glXGetProcAddress")));
201
202 #include "glwrap.funcs"