From 206fae5fae316c85de55e636c1f7d04b8cdc9193 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 30 Aug 2013 18:06:52 -0700 Subject: [PATCH] Initial import of glenv utility This uses Glaze to alter the OpenGL environment provided to a program. The query and extension-related options are not yet fully implemented. --- .gitignore | 3 + Makefile | 37 ++++++ configure | 321 +++++++++++++++++++++++++++++++++++++++++++++++++++++ glenv.c | 203 +++++++++++++++++++++++++++++++++ glwrap.c | 220 ++++++++++++++++++++++++++++++++++++ 5 files changed, 784 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100755 configure create mode 100644 glenv.c create mode 100644 glwrap.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e144d6c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +glenv +libglenv.so +Makefile.config diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..50e2194 --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +all: + +# Get settings from the output of configure by running it to generate +# Makefile.config if it doesn't exist yet. + +# If Makefile.config doesn't exist, then srcdir won't be +# set. Conditionally set it (assuming a plain srcdir build) so that +# the rule to generate Makefile.config can actually work. +srcdir ?= . + +include Makefile.config +Makefile.config: $(srcdir)/configure +ifeq ($(configure_options),) + @echo "" + @echo "Note: Calling ./configure with no command-line arguments. This is often fine," + @echo " but if you want to specify any arguments (such as an alternate prefix" + @echo " into which to install), call ./configure explicitly and then make again." + @echo " See \"./configure --help\" for more details." + @echo "" +endif + $(srcdir)/configure $(configure_options) + +TARGETS = glenv libglenv.so + +all: $(TARGETS) + +GLENV_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(GLAZE_CFLAGS) +GLENV_LDFLAGS = $(GLAZE_LDFLAGS) + +glenv: glenv.c + $(CC) $(GLENV_CFLAGS) $(GLENV_LDFLAGS) -o $@ $< + +libglenv.so: glwrap.c + $(CC) $(GLENV_CFLAGS) $(GLENV_LDFLAGS) -fPIC -shared -Wl,-Bsymbolic -o $@ $< + +clean: + rm -f $(TARGETS) diff --git a/configure b/configure new file mode 100755 index 0000000..7d7657c --- /dev/null +++ b/configure @@ -0,0 +1,321 @@ +#! /bin/sh + +PROJECT=glenv +PROJECT_BLURB="run an OpenGL program in a modified environment" + +srcdir=$(dirname "$0") + +# For a non-srcdir configure invocation (such as ../configure), create +# the directory structure and copy Makefiles. +if [ "$srcdir" != "." ]; then + + for dir in . $(grep "^subdirs *=" "$srcdir"/Makefile | sed -e "s/subdirs *= *//"); do + mkdir -p "$dir" + cp "$srcdir"/"$dir"/Makefile.local "$dir" + cp "$srcdir"/"$dir"/Makefile "$dir" + done +fi + +# Set several defaults (optionally specified by the user in +# environment variables) +CC=${CC:-gcc} +CFLAGS=${CFLAGS:--O2} +LDFLAGS=${LDFLAGS:-} + +# Set the defaults for values the user can specify with command-line +# options. +PREFIX=/usr/local + +usage () +{ + cat <-- Currently ignored + --host=-- Currently ignored + --infodir=DIR Currently ignored + --datadir=DIR Currently ignored + --localstatedir=DIR Currently ignored + --libexecdir=DIR Currently ignored + --disable-maintainer-mode Currently ignored + --disable-dependency-tracking Currently ignored + +EOF +} + +# Parse command-line options +for option; do + if [ "${option}" = '--help' ] ; then + usage + exit 0 + elif [ "${option%%=*}" = '--prefix' ] ; then + PREFIX="${option#*=}" + elif [ "${option%%=*}" = '--bindir' ] ; then + BINDIR="${option#*=}" + elif [ "${option%%=*}" = '--libdir' ] ; then + LIBDIR="${option#*=}" + elif [ "${option%%=*}" = '--mandir' ] ; then + MANDIR="${option#*=}" + elif [ "${option%%=*}" = '--sysconfdir' ] ; then + SYSCONFDIR="${option#*=}" + elif [ "${option%%=*}" = '--build' ] ; then + true + elif [ "${option%%=*}" = '--host' ] ; then + true + elif [ "${option%%=*}" = '--infodir' ] ; then + true + elif [ "${option%%=*}" = '--datadir' ] ; then + true + elif [ "${option%%=*}" = '--localstatedir' ] ; then + true + elif [ "${option%%=*}" = '--libexecdir' ] ; then + true + elif [ "${option}" = '--disable-maintainer-mode' ] ; then + true + elif [ "${option}" = '--disable-dependency-tracking' ] ; then + true + else + echo "Unrecognized option: ${option}" + echo "See:" + echo " $0 --help" + echo "" + exit 1 + fi +done + +printf "Checking for working C compiler (${CC})... " +printf "int main(void){return 42;}\n" > minimal.c +if ${CC} -o minimal minimal.c > /dev/null 2>&1 +then + printf "Yes.\n" +else + printf "No.\n" + cat < /dev/null 2>&1 + then + WARN_CFLAGS="${WARN_CFLAGS}${WARN_CFLAGS:+ }${flag}" + fi +done +printf "\t${WARN_CFLAGS}\n" + +rm -f minimal minimal.c + +printf "#include \nint main(void){return 0;}\n" > arch-minimal.c + +printf "Checking for machine-dependent compiler support:\n" + +printf " Compiler can create 32-bit binaries... " +have_m32=Yes +if ${CC} -m32 -o arch-minimal arch-minimal.c > /dev/null 2>&1 +then + printf "Yes.\n" +else + printf "No.\n" + have_m32=No +fi + +printf " Compiler can create 64-bit binaries... " +have_m64=Yes +if ${CC} -m64 -o arch-minimal arch-minimal.c > /dev/null 2>&1 +then + printf "Yes.\n" +else + printf "No.\n" + have_m64=No +fi + +if [ "$have_m32" = "No" ] || [ "$have_m64" = "No" ]; then + cat < /dev/null 2>&1; then + printf "Yes.\n" +else + printf "No.\n" + cat < Makefile.config < +#include +#include +#include +#include + +#include + +typedef struct options { + bool query; + char *vendor; + char *renderer; + char *version; + char *shading_language_version; + char *extensions; + char *extensions_whitelist; + char *extensions_blacklist; +} options_t; + +static void +export_options (options_t *options) +{ + if (options->query) + setenv ("GLENV_QUERY", "1", 1); + else + unsetenv ("GLENV_QUERY"); + + if (options->vendor) + setenv ("GLENV_GL_VENDOR", options->vendor, 1); + else + unsetenv ("GLENV_GL_VENDOR"); + + if (options->renderer) + setenv ("GLENV_GL_RENDERER", options->renderer, 1); + else + unsetenv ("GLENV_GL_RENDERER"); + + if (options->version) + setenv ("GLENV_GL_VERSION", options->version, 1); + else + unsetenv ("GLENV_GL_VERSION"); + + if (options->shading_language_version) + setenv ("GLENV_GL_SHADING_LANGUAGE_VERSION", + options->shading_language_version, 1); + else + unsetenv ("GLENV_GL_SHADING_LANGUAGE_VERSION"); + + if (options->extensions) + setenv ("GLENV_EXTENSIONS", options->extensions, 1); + else + unsetenv ("GLENV_EXTENSIONS"); + + if (options->extensions_whitelist) + setenv ("GLENV_EXTENSIONS_WHITELIST", options->extensions_whitelist, 1); + else + unsetenv ("GLENV_EXTENSIONS_WHITELIST"); + + if (options->extensions_blacklist) + setenv ("GLENV_EXTENSIONS_BLACKLIST", options->extensions_blacklist, 1); + else + unsetenv ("GLENV_EXTENSIONS_BLACKLIST"); +} + +static void +usage (void) +{ + printf ("Usage: glenv [OPTIONS...] [program args...]\n" + "\n" + "Execute with alternate OpenGL environment.\n" + "\n" + "Options:\n" + " -h, --help Show this help message.\n" + " -q, --query Query and report current environment\n" + " then terminate program.\n" + " --vendor=STR Set GL_VENDOR to STR.\n" + " --renderer=STR Set GL_RENDERER to STR.\n" + " --version=STR Set GL_VERSION to STR.\n" + " --shading-language-version=STR Set GL_SHADING_LANGUAGE_VERSION to STR.\n" + " --extensions=STR Set GL_EXTENSIONS to STR.\n" + " --extensions-whitelist=STR Remove from GL_EXTENSIONS all names\n" + " not appearing in STR (space-separated).\n" + " --extensions-blacklist=STR Remove from GL_EXTENSIONS any names\n" + " appearing in STR (space-separated).\n"); +} + +enum { + VENDOR_OPT = CHAR_MAX + 1, + RENDERER_OPT, + VERSION_OPT, + SHADING_LANGUAGE_VERSION_OPT, + EXTENSIONS_OPT, + EXTENSIONS_WHITELIST_OPT, + EXTENSIONS_BLACKLIST_OPT +}; + +int +main (int argc, char *argv[]) +{ + int opt; + options_t options = { + .query = false, + .vendor = NULL, + .renderer = NULL, + .version = NULL, + .shading_language_version = NULL, + .extensions = NULL, + .extensions_whitelist = NULL, + .extensions_blacklist = NULL + }; + + const char *short_options="hq"; + const struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"query", no_argument, 0, 'q'}, + {"vendor", required_argument, 0, VENDOR_OPT}, + {"renderer", required_argument, 0, RENDERER_OPT}, + {"version", required_argument, 0, VERSION_OPT}, + {"shading-language-version", required_argument, 0, SHADING_LANGUAGE_VERSION_OPT}, + {"extensions", required_argument, 0, EXTENSIONS_OPT}, + {"extensions-whitelist", required_argument, 0, EXTENSIONS_WHITELIST_OPT}, + {"extensions-blacklist", required_argument, 0, EXTENSIONS_BLACKLIST_OPT}, + {0, 0, 0, 0} + }; + + while (1) + { + opt = getopt_long (argc, argv, short_options, long_options, NULL); + if (opt == -1) + break; + + switch (opt) { + case 'h': + usage (); + return 0; + case '?': + exit (1); + break; + case 'q': + options.query = true; + break; + case VENDOR_OPT: + options.vendor = optarg; + break; + case RENDERER_OPT: + options.renderer = optarg; + break; + case VERSION_OPT: + options.version = optarg; + break; + case SHADING_LANGUAGE_VERSION_OPT: + options.shading_language_version = optarg; + break; + case EXTENSIONS_OPT: + options.extensions = optarg; + break; + case EXTENSIONS_WHITELIST_OPT: + options.extensions_whitelist = optarg; + break; + case EXTENSIONS_BLACKLIST_OPT: + options.extensions_blacklist = optarg; + break; + default: + fprintf (stderr, "Internal error: " + "unexpected getopt value: %d\n", opt); + exit (1); + } + } + + if (optind >= argc) { + fprintf (stderr, "Error: No program name provided, " + "see (glenv --help)\n"); + exit (1); + } + + export_options (&options); + + glaze_execute (argc - optind, &argv[optind], "libglenv.so"); + + /* If glaze_execute returns then something went wrong. */ + return 1; +} diff --git a/glwrap.c b/glwrap.c new file mode 100644 index 0000000..faf6a81 --- /dev/null +++ b/glwrap.c @@ -0,0 +1,220 @@ +/* Copyright © 2013, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#define GL_GLEXT_PROTOTYPES +#include + +#include + +#include +#include +#include + +static int +glenv_num_extensions (void) +{ + /* FIXME */ + return 0; +} + +static int +glenv_major_version (void) +{ + const char *version = getenv ("GLENV_GL_VERSION"); + if (version == NULL) + return 0; + + return atoi (version); +} + +static int +glenv_minor_version (void) +{ + const char *version = getenv ("GLENV_GL_VERSION"); + const char *decimal; + + if (version == NULL) + return 0; + + decimal = strchr (version, '.'); + + if (decimal == NULL) + return 0; + + return atoi (decimal + 1); +} + +void +glGetDoublev (GLenum pname, GLdouble *params) +{ + switch (pname) { + case GL_NUM_EXTENSIONS: + *params = glenv_num_extensions(); + break; + case GL_MAJOR_VERSION: + if (getenv ("GLENV_GL_VERSION")) { + *params = glenv_major_version(); + return; + } + break; + case GL_MINOR_VERSION: + if (getenv ("GLENV_GL_VERSION")) { + *params = glenv_minor_version(); + return; + } + break; + } + + GLAZE_DEFER (glGetDoublev, pname, params); +} + +void +glGetFloatv (GLenum pname, GLfloat *params) +{ + switch (pname) { + case GL_NUM_EXTENSIONS: + *params = glenv_num_extensions(); + break; + case GL_MAJOR_VERSION: + if (getenv ("GLENV_GL_VERSION")) { + *params = glenv_major_version(); + return; + } + break; + case GL_MINOR_VERSION: + if (getenv ("GLENV_GL_VERSION")) { + *params = glenv_minor_version(); + return; + } + break; + } + + GLAZE_DEFER (glGetFloatv, pname, params); +} + +void +glGetIntegerv (GLenum pname, GLint *params) +{ + switch (pname) { + case GL_NUM_EXTENSIONS: + *params = glenv_num_extensions(); + break; + case GL_MAJOR_VERSION: + if (getenv ("GLENV_GL_VERSION")) { + *params = glenv_major_version(); + return; + } + break; + case GL_MINOR_VERSION: + if (getenv ("GLENV_GL_VERSION")) { + *params = glenv_minor_version(); + return; + } + break; + } + + GLAZE_DEFER (glGetIntegerv, pname, params); +} + +void +glGetInteger64v (GLenum pname, GLint64 * params) +{ + switch (pname) { + case GL_NUM_EXTENSIONS: + *params = glenv_num_extensions(); + break; + case GL_MAJOR_VERSION: + if (getenv ("GLENV_GL_VERSION")) { + *params = glenv_major_version(); + return; + } + break; + case GL_MINOR_VERSION: + if (getenv ("GLENV_GL_VERSION")) { + *params = glenv_minor_version(); + return; + } + break; + } + + GLAZE_DEFER (glGetInteger64v, pname, params); +} + +const GLubyte * +glGetString (GLenum name) +{ + const GLubyte *ret; + + switch (name) { + case GL_VENDOR: + ret = (GLubyte *) getenv ("GLENV_GL_VENDOR"); + if (ret) + return ret; + break; + case GL_RENDERER: + ret = (GLubyte *) getenv ("GLENV_GL_RENDERER"); + if (ret) + return ret; + break; + case GL_VERSION: + ret = (GLubyte *) getenv ("GLENV_GL_VERSION"); + if (ret) + return ret; + break; + case GL_SHADING_LANGUAGE_VERSION: + ret = (GLubyte *) getenv ("GLENV_GL_SHADING_LANGUAGE_VERSION"); + if (ret) + return ret; + break; + case GL_EXTENSIONS: + ret = (GLubyte *) getenv ("GLENV_GL_EXTENSIONS"); + if (ret) + return ret; + break; + } + + GLAZE_DEFER_WITH_RETURN (ret, glGetString, name); + + return ret; +} + +const GLubyte * +glGetStringi (GLenum name, GLuint index) +{ + const GLubyte *ret; + + switch (name) { + case GL_EXTENSIONS: + /* FIXME */ + break; + case GL_SHADING_LANGUAGE_VERSION: + if (index == 0) { + ret = (GLubyte *) getenv ("GLENV_GL_SHADING_LANGUAGE_VERSION"); + if (ret) + return ret; + } + break; + } + + GLAZE_DEFER_WITH_RETURN (ret, glGetStringi, name, index); + + return ret; +} -- 2.43.0