* THE SOFTWARE.
*/
-#define _GNU_SOURCE
-#include <dlfcn.h>
-
#include <stdio.h>
#include <stdlib.h>
+#include <getopt.h>
+#include <limits.h>
-void *libgl_handle;
+#include <glaze.h>
static void
-open_libgl_handle (void)
+usage (void)
{
- const char *path;
+ printf ("Usage: glaze --wrapper=<wrapper> <program> [program args...]\n"
+ "\n"
+ "Execute <program> with <wrapper> providing alternate OpenGL functions.\n");
+}
- if (libgl_handle)
- return;
+enum {
+ WRAPPER_OPT = CHAR_MAX + 1
+};
- path = getenv ("GLAZE_LIBGL");
- if (path == NULL) {
- fprintf (stderr, "GLAZE_LIBGL unset. Please set to path of real libGL.so under glaze.\n");
- exit (1);
+int
+main (int argc, char *argv[])
+{
+ const char *wrapper = NULL;
+ int opt;
+
+ /* The initial '+' means that getopt will stop looking for
+ * options after the first non-option argument. This means
+ * that a command such as:
+ *
+ * glaze glenv --renderer=Foo glxgears
+ *
+ * Will do what is intended, (namely, have glaze invoke "glenv
+ * --renderer=Foo glxgears" rather than trying to interpret
+ * --renderer=Foo as an option to glaze itself.
+ */
+ const char *short_options="+h";
+ const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"wrapper", required_argument, 0, WRAPPER_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 WRAPPER_OPT:
+ wrapper = optarg;
+ break;
+ default:
+ fprintf (stderr, "Internal error: "
+ "unexpected getopt value: %d\n", opt);
+ exit (1);
+ }
}
- libgl_handle = dlopen (path, RTLD_LAZY | RTLD_GLOBAL);
- if (libgl_handle == NULL) {
- fprintf (stderr, "Error: Failed to dlopen %s\n", path);
+ if (optind >= argc) {
+ fprintf (stderr, "Error: No program name provided, "
+ "see (glaze --help)\n");
exit (1);
}
-}
-static void
-glaze_init (void) __attribute__((constructor));
-
-static void
-glaze_init (void)
-{
- open_libgl_handle ();
-}
+ glaze_execute (argc - optind, &argv[optind], wrapper);
-static void *
-resolve (const char *name)
-{
- return dlsym (libgl_handle, name);
+ /* If glaze_execute returns then something went wrong. */
+ return 1;
}
-
-#define GLAZE_API(name) \
-void * name() __attribute__((ifunc(#name "_resolver"))); \
-static void * \
-name ## _resolver (void) { return resolve (#name); }
-
-#include "specs/gl.def"