]> git.tdb.fi Git - gldbg.git/blob - source/glwrap.c
224a0faacbfda31f33e75691d5674875aafa2302
[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 "functions.h"
17
18 static inline void *glsym(const char *sym)
19 {
20         static void *libgl = NULL;
21         if(!libgl)
22         {
23                 libgl = dlopen("libGL.so", RTLD_NOW);
24                 if(!libgl)
25                 {
26                         fprintf(stderr, "Could not open libGL: %s\n", dlerror());
27                         abort();
28                 }
29         }
30
31         return dlsym(libgl, sym);
32 }
33
34 static char *buffer = 0;
35 static char *write_pos;
36 static struct iovec *iovecs = 0;
37 static struct iovec *cur_vec;
38 static unsigned length;
39
40 static inline void next_vec()
41 {
42         if(write_pos!=cur_vec->iov_base)
43         {
44                 cur_vec->iov_len = write_pos-(char *)cur_vec->iov_base;
45                 length += cur_vec->iov_len;
46                 ++cur_vec;
47                 cur_vec->iov_base = write_pos;
48         }
49 }
50
51 static inline void write_bytes(const char *ptr, unsigned size)
52 {
53         unsigned i;
54         for(i=0; i<size; ++i)
55                 *write_pos++ = *ptr++;
56 }
57
58 static inline void write_char(char v)
59 {
60         *write_pos++ = v;
61 }
62
63 static inline void write_short(short v)
64 {
65         write_bytes((char *)&v, sizeof(short));
66 }
67
68 static inline void write_int(int v)
69 {
70         write_bytes((char *)&v, sizeof(int));
71 }
72
73 static inline void write_long(long v)
74 {
75         write_bytes((char *)&v, sizeof(long));
76 }
77
78 static inline void write_ulong(unsigned long v)
79 {
80         write_bytes((char *)&v, sizeof(unsigned long));
81 }
82
83 static inline void write_longlong(long long v)
84 {
85         write_bytes((char *)&v, sizeof(long long));
86 }
87
88 static inline void write_float(float v)
89 {
90         write_bytes((char *)&v, sizeof(float));
91 }
92
93 static inline void write_double(double v)
94 {
95         write_bytes((char *)&v, sizeof(double));
96 }
97
98 static inline void write_pointer(const void *p)
99 {
100         write_bytes((char *)&p, sizeof(void *));
101 }
102
103 static inline void write_data(const void *data, unsigned size)
104 {
105         if(data)
106         {
107                 write_int(size);
108                 next_vec();
109                 cur_vec->iov_base = (void *)data;
110                 cur_vec->iov_len = size;
111                 length += size;
112                 ++cur_vec;
113                 cur_vec->iov_base = write_pos;
114         }
115         else
116                 write_int(0);
117 }
118
119 static inline void write_string(const unsigned char *s)
120 {
121         write_data(s, strlen(s)+1);
122 }
123
124 static inline void begin_packet(int func)
125 {
126         if(!buffer)
127                 buffer = (char *)malloc(1024);
128         if(!iovecs)
129                 iovecs = (struct iovec *)malloc(16*sizeof(struct iovec));
130         write_pos = buffer;
131         cur_vec = iovecs;
132         cur_vec->iov_base = write_pos;
133         length = 0;
134         write_int(0);
135         write_short(func);
136 }
137
138 static inline void send_packet()
139 {
140         static int fd = -1;
141         if(fd<0)
142         {
143                 const char *var = getenv("GLWRAP_FD");
144                 if(var)
145                         fd = strtol(var, NULL, 0);
146                 else
147                         fd = 2;
148         }
149         next_vec();
150         write_pos = buffer;
151         write_int(length);
152         writev(fd, iovecs, cur_vec-iovecs);
153 }
154
155 static inline int typesize(GLenum type)
156 {
157         switch(type)
158         {
159         case GL_BYTE: return sizeof(GLbyte);
160         case GL_SHORT: return sizeof(GLshort);
161         case GL_INT: return sizeof(GLint);
162         case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
163         case GL_UNSIGNED_SHORT: return sizeof(GLushort);
164         case GL_UNSIGNED_INT: return sizeof(GLuint);
165         case GL_FLOAT: return sizeof(GLfloat);
166         case GL_DOUBLE: return sizeof(GLdouble);
167         // Short and byte packed types are broken
168         default: return 1;
169         }
170 }
171
172 static inline int formatsize(GLenum format)
173 {
174         switch(format)
175         {
176         case GL_COLOR_INDEX: return 1;
177         case GL_STENCIL_INDEX: return 1;
178         case GL_DEPTH_COMPONENT: return 1;
179         case GL_RED: return 1;
180         case GL_GREEN: return 1;
181         case GL_BLUE: return 1;
182         case GL_ALPHA: return 1;
183         case GL_RGB: return 3;
184         case GL_RGBA: return 4;
185         case GL_BGR: return 3;
186         case GL_BGRA: return 4;
187         case GL_LUMINANCE: return 1;
188         case GL_LUMINANCE_ALPHA: return 2;
189         default: return 1;
190         }
191 }
192
193 static inline int paramsize(GLenum pname)
194 {
195         switch(pname)
196         {
197         // Lighting and material
198         case GL_AMBIENT: return 4;
199         case GL_DIFFUSE: return 4;
200         case GL_AMBIENT_AND_DIFFUSE: return 4;
201         case GL_SPECULAR: return 4;
202         case GL_EMISSION: return 4;
203         case GL_SHININESS: return 1;
204         case GL_COLOR_INDEXES: return 3;
205         case GL_POSITION: return 4;
206         case GL_SPOT_DIRECTION: return 3;
207         case GL_SPOT_EXPONENT: return 1;
208         case GL_SPOT_CUTOFF: return 1;
209         case GL_CONSTANT_ATTENUATION: return 1;
210         case GL_LINEAR_ATTENUATION: return 1;
211         case GL_QUADRATIC_ATTENUATION: return 1;
212         case GL_LIGHT_MODEL_AMBIENT: return 4;
213         case GL_LIGHT_MODEL_LOCAL_VIEWER: return 1;
214         case GL_LIGHT_MODEL_TWO_SIDE: return 1;
215         case GL_LIGHT_MODEL_COLOR_CONTROL: return 1;
216
217         // Texture
218         case GL_TEXTURE_WRAP_S: return 1;
219         case GL_TEXTURE_WRAP_T: return 1;
220         case GL_TEXTURE_WRAP_R: return 1;
221         case GL_TEXTURE_MIN_FILTER: return 1;
222         case GL_TEXTURE_MAG_FILTER: return 1;
223         case GL_TEXTURE_BORDER_COLOR: return 4;
224         case GL_TEXTURE_MIN_LOD: return 1;
225         case GL_TEXTURE_MAX_LOD: return 1;
226         case GL_TEXTURE_BASE_LEVEL: return 1;
227         case GL_TEXTURE_MAX_LEVEL: return 1;
228         case GL_TEXTURE_LOD_BIAS: return 1;
229         case GL_DEPTH_TEXTURE_MODE: return 1;
230         case GL_TEXTURE_COMPARE_MODE: return 1;
231         case GL_TEXTURE_COMPARE_FUNC: return 1;
232         case GL_GENERATE_MIPMAP: return 1;
233         default: return 1;
234         }
235 }
236
237 static inline int mapsize(GLenum target)
238 {
239         return 1;
240 }
241
242 void (*glXGetProcAddress(const GLubyte *procname))(void)
243 {
244         void *handle = dlopen(NULL, RTLD_LAZY);
245         return dlsym(handle, (const char *)procname);
246 }
247
248 void (*glXGetProcAddressARB(const GLubyte *))(void) __attribute__((alias("glXGetProcAddress")));
249
250 #include "glwrap.funcs"