From: Eleni Maria Stea Date: Mon, 11 Feb 2013 13:46:49 +0000 (+0200) Subject: added support for OpenGL extensions, vendor, version X-Git-Url: https://eleni.mutantstargoat.com/git/?p=libgliar;a=commitdiff_plain;h=b82d60137dc0b16ef451936fcc97fa8f25fe7b33 added support for OpenGL extensions, vendor, version --- b82d60137dc0b16ef451936fcc97fa8f25fe7b33 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ce94ac5 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +src = $(wildcard src/*.c) +obj = $(src:.c=.o) +lib_so = libgliar.so + +CFLAGS = -pedantic -Wall -g -fPIC -D_GNU_SOURCE + +$(lib_so): $(obj) + $(CC) -o $@ -shared $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(lib_so) diff --git a/README b/README new file mode 100644 index 0000000..e12ff82 --- /dev/null +++ b/README @@ -0,0 +1,57 @@ +# libgliar - a library that can fake the OpenGL context info returned by +# the glGet OpenGL calls +# +# authored by: Eleni Maria Stea + +For instructions on how to build the code, see the INSTALL file. + +Usage: +------ +LD_PRELOAD=./libgliar.so + +The library will read the gliar.conf file in the user's library directory or +the .gliar.conf file in the user's home directory. + +Example gliar.conf: +------------------- +[key1] +value1 +value2 +. +. +. +valueN + +[key2] +value1 +. +. +. +valueN + +[keyN] +value1 +. +. +. +valueN + +Currently supported keys: +"vendor" (the vendor string), "extensions" (the extensions string), "version" (the opengl version string) + +Example: +--------- +gliar.conf: +[vendor] +Mutant Stargoat + +[extensions] +GL_MSG_hikiko_ext +GL_MSG_test + +$ LD_PRELOAD=./libgliar glxinfo | grep -A2 "OpenGL extensions" +OpenGL extensions: + GL_MSG_hikiko_ext, GL_MSG_test + + + diff --git a/gliar.conf b/gliar.conf new file mode 100644 index 0000000..1f9c5b5 --- /dev/null +++ b/gliar.conf @@ -0,0 +1,6 @@ +[vendor] +Mutant Stargoat + +[extensions] +GL_MSG_hikiko_ext +GL_MSG_test diff --git a/src/cfg.c b/src/cfg.c new file mode 100644 index 0000000..4f317d2 --- /dev/null +++ b/src/cfg.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include "cfg.h" + +static char *stripspace(char *s); + + +struct cfgopt *gliar_load_cfg(const char *fname) +{ + FILE *fp; + char buf[512]; + struct cfgopt *optlist = 0; + struct cfgopt *opt = 0; + + if(!(fp = fopen(fname, "r"))) { + return 0; + } + + while(fgets(buf, sizeof buf, fp)) { + char *line = stripspace(buf); + + if(!*line || *line == '#') { + continue; + } + + if(*line == '[') { + char *end = strrchr(line, ']'); + if(!end) { + fprintf(stderr, "invalid config %s: %s\n", fname, line); + continue; + } + line++; + *end = 0; + + if(opt) { + opt->next = optlist; + optlist = opt; + } + + if((opt = malloc(sizeof *opt))) { + if((opt->key = malloc(strlen(line) + 1))) { + strcpy(opt->key, line); + opt->val = 0; + } else { + free(opt); + opt = 0; + } + } + } else { + char *tmp; + int prev_len = opt->val ? strlen(opt->val) : 0; + + if(opt && (tmp = realloc(opt->val, prev_len + strlen(line) + 2))) { + opt->val = tmp; + if(prev_len) { + strcat(opt->val, " "); + strcat(opt->val, line); + } else { + strcpy(opt->val, line); + } + } + } + } + + if(opt) { + opt->next = optlist; + optlist = opt; + } + + fclose(fp); + return optlist; +} + +const char *gliar_find_opt(struct cfgopt *list, const char *name) +{ + if(!list || !name) { + return 0; + } + + while(list) { + if(strcmp(list->key, name) == 0) { + return list->val; + } + list = list->next; + } + return 0; +} + +void gliar_print_opt(struct cfgopt *list) +{ + printf("OPTIONS\n"); + while(list) { + printf("\"%s\" -> \"%s\"\n", list->key, list->val); + list = list->next; + } +} + +static char *stripspace(char *s) +{ + char *end = s + strlen(s) - 1; + + while(isspace(*s)) s++; + + while(isspace(*end)) { + *end-- = 0; + } + return s; +} diff --git a/src/cfg.h b/src/cfg.h new file mode 100644 index 0000000..1f8eee2 --- /dev/null +++ b/src/cfg.h @@ -0,0 +1,17 @@ +#ifndef CFG_H_ +#define CFG_H_ + +struct cfgopt { + char *key; + char *val; + + struct cfgopt *next; +}; + +struct cfgopt *gliar_load_cfg(const char *fname); + +const char *gliar_find_opt(struct cfgopt *list, const char *name); + +void gliar_print_opt(struct cfgopt *list); + +#endif /* CFG_H_ */ diff --git a/src/gliar.c b/src/gliar.c new file mode 100644 index 0000000..38470f5 --- /dev/null +++ b/src/gliar.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +#include +#include "cfg.h" + +static int done_init; +static const GLubyte* (*gl_get_string)(GLenum); +static struct cfgopt *cfglist; + +static int init(void) +{ + if(done_init) { + return 0; + } + + if(!(cfglist = gliar_load_cfg("gliar.conf"))) { + struct passwd *pw; + char *homedir, *path; + + if((pw = getpwuid(getuid()))) { + homedir = pw->pw_dir; + } else { + homedir = getenv("HOME"); + } + + if(homedir) { + path = alloca(strlen(homedir) + strlen(".gliar.conf") + 2); + sprintf(path, "%s/.gliar.conf", homedir); + + cfglist = gliar_load_cfg(path); + } + } + + gl_get_string = dlsym(RTLD_NEXT, "glGetString"); + + done_init = 1; + return 0; +} + +const GLubyte *glGetString(GLenum name) +{ + const char *key, *value; + + init(); + + switch(name) { + case GL_VENDOR: + key = "vendor"; + break; + + case GL_VERSION: + key = "version"; + break; + + case GL_EXTENSIONS: + key = "extensions"; + break; + + default: + key = 0; + } + + if(key && (value = gliar_find_opt(cfglist, key))) { + return value; + } + + return gl_get_string(name); +}