2 libgliar - a library that can fake the OpenGL context info returned by
5 Copyright (C) 2013 Canonical Ltd
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 Author: Eleni Maria Stea <elene.mst@gmail.com>
33 #ifndef GL_NUM_SHADING_LANGUAGE_VERSIONS
34 #define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
37 static int init_valid_extensions(void);
41 static const GLubyte* (*gl_get_string)(GLenum);
42 static const GLubyte* (*gl_get_stringi)(GLenum, GLuint);
43 static void (*gl_get_integerv)(GLenum, GLint*);
44 static void (*gl_get_programiv)(GLuint, GLenum, GLint*);
45 static void *(*glx_get_proc_address)(const unsigned char*);
47 /*static const void* (*gl_get_booleanv)(GLenum, GLboolean*);
48 static const void* (*gl_get_doublev)(GLenum, GLdouble*);
49 static const void* (*gl_get_floatv)(GLenum, GLfloat*);
50 static const void* (*gl_get_integer64v)(GLenum, GLint64*);
51 static const void* (*gl_get_booleani_v)(GLenum, GLuint, GLboolean*);
52 static const void* (*gl_get_doublei_v)(GLenum, GLuint, GLdouble*);
53 static const void* (*gl_get_floati_v)(GLenum, GLuint, GLfloat*);
54 static const void* (*gl_get_integeri_v)(GLenum, GLuint, GLint*);
55 static const void* (*gl_get_integer64i_v)(GLenum, GLuint, GLint64*);*/
57 static struct cfgopt *cfglist;
65 gl_get_string = dlsym(RTLD_NEXT, "glGetString");
66 gl_get_stringi = dlsym(RTLD_NEXT, "glGetStringi");
67 gl_get_integerv = dlsym(RTLD_NEXT, "glGetIntegerv");
68 gl_get_programiv = dlsym(RTLD_NEXT, "glGetProgramivARB");
69 glx_get_proc_address = dlsym(RTLD_NEXT, "glXGetProcAddress");
71 if(init_valid_extensions() == -1) {
72 fprintf(stderr, "GLIAR: failed to initialize the valid extension list, might end up with unavailable extensions!\n");
75 if(!(cfglist = gliar_load_cfg("gliar.conf"))) {
79 if((pw = getpwuid(getuid()))) {
82 homedir = getenv("HOME");
86 path = alloca(strlen(homedir) + strlen(".gliar.conf") + 2);
87 sprintf(path, "%s/.gliar.conf", homedir);
89 cfglist = gliar_load_cfg(path);
97 static int init_valid_extensions(void)
99 int i, num_ext, prev_space = 0;
100 const char *gl_ext_str;
101 char *ext_str, *tok, *ptr, **ext_table;
103 /* initialize the list of valid extensions */
104 if(!(gl_ext_str = (const char*)gl_get_string(GL_EXTENSIONS))) {
108 if(!(ext_str = malloc(strlen(gl_ext_str) + 1))) {
111 strcpy(ext_str, gl_ext_str);
113 /* count the extensions */
117 if(isspace(*ptr) && prev_space == 0) {
126 /* allocate extension table */
127 if(!(ext_table = malloc(num_ext * sizeof *ext_table))) {
132 /* setup the ext_table slots to point to the start of each substring (extension) */
133 for(i=0; i<num_ext; i++) {
134 if(!(tok = strtok(i == 0 ? ext_str : 0, " \t\v\n\r"))) {
135 fprintf(stderr, "DEBUG: strtok returned 0 at token %d\n", i);
141 gliar_value_set("extensions", ext_table, num_ext);
148 const GLubyte *glGetString(GLenum name)
151 const struct cfgopt *option;
156 fprintf(stderr, "Unable to fake the %s function. It is not supported by your OpenGL implementation.\n", __func__);
177 case GL_SHADING_LANGUAGE_VERSION:
185 if(key && (option = gliar_find_opt(cfglist, key))) {
186 return (const GLubyte*)option->conc_vals;
189 return gl_get_string(name);
192 const GLubyte *glGetStringi(GLenum name, GLuint index)
195 const struct cfgopt *option;
199 if(!gl_get_stringi) {
200 fprintf(stderr, "Unable to fake the %s function. It is not supported by your OpenGL implementation.\n", __func__);
209 case GL_SHADING_LANGUAGE_VERSION:
217 if(key && (option = gliar_find_opt(cfglist, key))) {
218 return (const GLubyte*)option->str_val[index];
221 return gl_get_stringi(name, index);
224 void glGetIntegerv(GLenum name, GLint *val)
227 const struct cfgopt *option;
231 if(!gl_get_integerv) {
232 fprintf(stderr, "Unable to fake the %s function. It is not supported by your OpenGL implementation.\n", __func__);
237 case GL_NUM_EXTENSIONS:
241 case GL_NUM_SHADING_LANGUAGE_VERSIONS:
244 if(key && (option = gliar_find_opt(cfglist, key))) {
245 *val = option->str_count;
250 case GL_MAJOR_VERSION:
251 key = "major version";
254 case GL_MINOR_VERSION:
255 key = "minor version";
258 case GL_MAX_TEXTURE_UNITS:
259 key = "max texture units";
262 case GL_MAX_TEXTURE_IMAGE_UNITS:
263 key = "max texture image units";
266 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
267 key = "max combined texture image units";
270 case GL_MAX_TEXTURE_SIZE:
271 key = "max texture size";
274 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
275 key = "max cube map texture size";
278 case GL_MAX_TEXTURE_COORDS:
279 key = "max texture coordinates";
282 case GL_MAX_VERTEX_ATTRIBS:
283 key = "max vertex attributes";
286 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
287 key = "max vertex texture image units";
290 case GL_MAX_VERTEX_UNIFORM_VECTORS:
291 key = "max vertex uniform vectors";
294 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
295 key = "max fragment uniform vectors";
298 case GL_MAX_VARYING_VECTORS:
299 key = "max varying vectors";
302 case GL_MAX_COLOR_ATTACHMENTS_EXT:
303 key = "max color attachments";
306 case GL_MAX_RENDERBUFFER_SIZE_EXT:
307 key = "max renderbuffer size ext";
314 if(key && (option = gliar_find_opt(cfglist, key)) && option->type == GLIAR_NUMBER) {
315 *val = option->num_val;
319 gl_get_integerv(name, val);
322 void glGetProgramivARB(GLuint program, GLenum pname, GLint *params)
325 const struct cfgopt *option;
329 if(!gl_get_programiv) {
330 fprintf(stderr, "Unable to fake the %s function. It is not supported by your OpenGL implementation.\n", __func__);
335 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
336 key = "max program instructions arb";
339 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
340 key = "max program native instructions arb";
343 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
344 key = "max program temporaries arb";
347 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
348 key = "max program native temporaries arb";
351 case GL_MAX_PROGRAM_PARAMETERS_ARB:
352 key = "max program parameters arb";
355 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
356 key = "max program native parameters arb";
359 case GL_MAX_PROGRAM_ATTRIBS_ARB:
360 key = "max program attribs arb";
363 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
364 key = "max program native attribs arb";
367 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
368 key = "max program address registers arb";
371 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
372 key = "max program native address registers arb";
375 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
376 key = "max program local parameters arb";
379 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
380 key = "max program env parameters arb";
383 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
384 key = "max program alu instructions arb";
387 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
388 key = "max program native alu instructions arb";
391 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
392 key = "max program tex instructions arb";
395 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
396 key = "max program native tex instructions arb";
405 if(program == GL_VERTEX_PROGRAM_ARB) {
406 sprintf(buf, "v %s", key);
408 else if(program == GL_FRAGMENT_PROGRAM_ARB) {
409 sprintf(buf, "f %s", key);
413 if((option = gliar_find_opt(cfglist, key)) && option->type == GLIAR_NUMBER) {
414 *params = option->num_val;
419 gl_get_programiv(program, pname, params);
423 void *glXGetProcAddress(const unsigned char *procname)
425 if(!glx_get_proc_address) {
426 glx_get_proc_address = dlsym(RTLD_NEXT, "glXGetProcAddress");
427 if(!glx_get_proc_address) {
432 if(!strcmp((char*)procname, "glGetProgramivARB")) {
433 char *overr_name = "gl_get_programiv";
434 return glx_get_proc_address((unsigned char*)overr_name);
437 return glx_get_proc_address(procname);