diff --git a/build.xml b/build.xml
index 9cf6d7df..d8158a98 100644
--- a/build.xml
+++ b/build.xml
@@ -239,6 +239,7 @@
+
@@ -253,6 +254,7 @@
+
@@ -267,6 +269,7 @@
+
@@ -281,6 +284,7 @@
+
@@ -295,6 +299,7 @@
+
@@ -309,6 +314,7 @@
+
@@ -323,6 +329,7 @@
+
@@ -337,6 +344,7 @@
+
@@ -352,6 +360,7 @@
+
diff --git a/src/java/org/lwjgl/BufferChecks.java b/src/java/org/lwjgl/BufferChecks.java
index c28230bc..ca4eef5a 100644
--- a/src/java/org/lwjgl/BufferChecks.java
+++ b/src/java/org/lwjgl/BufferChecks.java
@@ -58,6 +58,15 @@ public class BufferChecks {
*/
private static final int DEFAULT_BUFFER_SIZE = 4;
+ /**
+ * Helper methods to ensure a function pointer is not-null (0)
+ */
+ public static void checkFunctionAddress(long pointer) {
+ if (pointer == 0) {
+ throw new IllegalStateException("Function is unsupported");
+ }
+ }
+
/**
* Helper methods to ensure a ByteBuffer is null-terminated
*/
diff --git a/src/java/org/lwjgl/generator/AutoResultSize.java b/src/java/org/lwjgl/generator/AutoResultSize.java
new file mode 100644
index 00000000..4a515fa5
--- /dev/null
+++ b/src/java/org/lwjgl/generator/AutoResultSize.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'LWJGL' nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.lwjgl.generator;
+
+/**
+ * $Id$
+ *
+ * AutoResultSize specifies that a parameter should determine
+ * the size of a Buffer result.
+ *
+ * @author elias_naur
+ * @version $Revision$
+ */
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Target(ElementType.PARAMETER)
+public @interface AutoResultSize {
+}
diff --git a/src/java/org/lwjgl/generator/ContextCapabilitiesGenerator.java b/src/java/org/lwjgl/generator/ContextCapabilitiesGenerator.java
index 5c3f1390..7dea9423 100644
--- a/src/java/org/lwjgl/generator/ContextCapabilitiesGenerator.java
+++ b/src/java/org/lwjgl/generator/ContextCapabilitiesGenerator.java
@@ -55,23 +55,19 @@ import java.lang.annotation.Annotation;
* @version $Revision$
*/
public class ContextCapabilitiesGenerator {
- public final static String CONTEXT_CAPS_CLASS_NAME = "ContextCapabilities";
+ private final static String ALL_INIT_METHOD_NAME = "initAllStubs";
+ private final static String POINTER_INITIALIZER_POSTFIX = "_initNativeFunctionAddresses";
private final static String CACHED_EXTS_VAR_NAME = "supported_extensions";
private final static String EXTENSION_PREFIX = "GL_";
private final static String CORE_PREFIX = "Open";
public static void generateClassPrologue(PrintWriter writer) {
- writer.println("public class " + CONTEXT_CAPS_CLASS_NAME + " {");
+ writer.println("public class " + Utils.CONTEXT_CAPS_CLASS_NAME + " {");
}
public static void generateInitializerPrologue(PrintWriter writer) {
-// writer.println("\t\t/*");
-// writer.println("\t\t * Special case: initialize GL11 unconditionally,");
-// writer.println("\t\t * and let exceptions abort the constructor");
-// writer.println("\t\t */");
-
-// writer.println("\t\tGL11.initNativeStubs();");*/
- writer.println("\t" + CONTEXT_CAPS_CLASS_NAME + "(Set " + CACHED_EXTS_VAR_NAME + ") {");
+ writer.println("\t" + Utils.CONTEXT_CAPS_CLASS_NAME + "() throws LWJGLException {");
+ writer.println("\t\tSet " + CACHED_EXTS_VAR_NAME + " = " + ALL_INIT_METHOD_NAME + "();");
}
private static String translateFieldName(String interface_name) {
@@ -98,9 +94,19 @@ public class ContextCapabilitiesGenerator {
writer.println(";");
}
- public static void generateInitStubsPrologue(PrintWriter writer) {
- writer.println("\tstatic Set initAllStubs() throws LWJGLException {");
- writer.println("\t\torg.lwjgl.opengl.GL11.initNativeStubs();");
+ private static String getAddressesInitializerName(String class_name) {
+ return class_name + POINTER_INITIALIZER_POSTFIX;
+ }
+
+ public static void generateInitStubsPrologue(PrintWriter writer, boolean context_specific) {
+ writer.println("\tprivate Set " + ALL_INIT_METHOD_NAME + "() throws LWJGLException {");
+ if (!context_specific) {
+ writer.println("\t\torg.lwjgl.opengl.GL11.initNativeStubs();");
+ } else {
+ writer.println("\t\tif (!" + getAddressesInitializerName("GL11") + "())");
+ writer.println("\t\t\tthrow new LWJGLException(\"GL11 not supported\");");
+ }
+ writer.println("\t\tGLContext.setCapabilities(this);");
writer.println("\t\tSet " + CACHED_EXTS_VAR_NAME + " = GLContext.getSupportedExtensions();");
}
@@ -116,10 +122,18 @@ public class ContextCapabilitiesGenerator {
}
}
- public static void generateInitStubs(PrintWriter writer, InterfaceDeclaration d) {
+ public static void generateInitStubs(PrintWriter writer, InterfaceDeclaration d, boolean context_specific) {
if (d.getMethods().size() > 0) {
- writer.print("\t\tGLContext.initNativeStubs(" + Utils.getSimpleClassName(d));
- writer.println(".class, supported_extensions, \"" + translateFieldName(d.getSimpleName()) + "\");");
+ if (context_specific) {
+ writer.print("\t\tif (" + CACHED_EXTS_VAR_NAME + ".contains(\"");
+ writer.print(translateFieldName(d.getSimpleName()) + "\")");
+ writer.println(" && !" + getAddressesInitializerName(d.getSimpleName()) + "())");
+ writer.print("\t\t\t" + CACHED_EXTS_VAR_NAME + ".remove(\"");
+ writer.println(translateFieldName(d.getSimpleName()) + "\");");
+ } else {
+ writer.print("\t\tGLContext.initNativeStubs(" + Utils.getSimpleClassName(d));
+ writer.println(".class, supported_extensions, \"" + translateFieldName(d.getSimpleName()) + "\");");
+ }
}
}
@@ -128,12 +142,30 @@ public class ContextCapabilitiesGenerator {
writer.println(translateFieldName(d.getSimpleName()) + "\");");
}
-/* public static void generateSymbolPointers(PrintWriter writer, InterfaceDeclaration d) {
- for (MethodDeclaration method : d.getMethods()) {
- writer.println("\tlong " + d.getSimpleName() + "_" + method.getSimpleName() + ";");
+ public static void generateAddressesInitializers(PrintWriter writer, InterfaceDeclaration d) {
+ Iterator extends MethodDeclaration> methods = d.getMethods().iterator();
+ if (methods.hasNext()) {
+ writer.println("\tprivate boolean " + getAddressesInitializerName(d.getSimpleName()) + "() {");
+ writer.println("\t\treturn ");
+ while (methods.hasNext()) {
+ MethodDeclaration method = methods.next();
+ writer.print("\t\t\t(" + Utils.getFunctionAddressName(d, method) + " = GLContext.getFunctionAddress(\"");
+ writer.print(method.getSimpleName() + "\")) != 0");
+ if (methods.hasNext())
+ writer.println(" &&");
+ }
+ writer.println(";");
+ writer.println("\t}");
+ writer.println();
}
}
-*/
+
+ public static void generateSymbolAddresses(PrintWriter writer, InterfaceDeclaration d) {
+ for (MethodDeclaration method : d.getMethods()) {
+ writer.println("\tlong " + Utils.getFunctionAddressName(d, method) + ";");
+ }
+ }
+
public static void generateField(PrintWriter writer, InterfaceDeclaration d) {
writer.println("\tpublic final boolean " + translateFieldName(d.getSimpleName()) + ";");
}
diff --git a/src/java/org/lwjgl/generator/ContextGeneratorProcessorFactory.java b/src/java/org/lwjgl/generator/ContextGeneratorProcessorFactory.java
index d4a87c6b..c69006e9 100644
--- a/src/java/org/lwjgl/generator/ContextGeneratorProcessorFactory.java
+++ b/src/java/org/lwjgl/generator/ContextGeneratorProcessorFactory.java
@@ -72,7 +72,7 @@ public class ContextGeneratorProcessorFactory implements AnnotationProcessorFact
}
public Collection supportedOptions() {
- return Collections.emptySet();
+ return unmodifiableCollection(Arrays.asList("-Acontextspecific"));
}
public void roundComplete(RoundCompleteEvent event) {
@@ -96,15 +96,17 @@ public class ContextGeneratorProcessorFactory implements AnnotationProcessorFact
}
public void process() {
+ Map options = env.getOptions();
+ boolean context_specific = options.containsKey("-Acontextspecific");
try {
- generateContextCapabilitiesSource();
+ generateContextCapabilitiesSource(context_specific);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
- private void generateContextCapabilitiesSource() throws IOException {
- PrintWriter writer = env.getFiler().createSourceFile("org.lwjgl.opengl." + ContextCapabilitiesGenerator.CONTEXT_CAPS_CLASS_NAME);
+ private void generateContextCapabilitiesSource(boolean context_specific) throws IOException {
+ PrintWriter writer = env.getFiler().createSourceFile("org.lwjgl.opengl." + Utils.CONTEXT_CAPS_CLASS_NAME);
writer.println("/* MACHINE GENERATED FILE, DO NOT EDIT */");
writer.println();
writer.println("package org.lwjgl.opengl;");
@@ -121,7 +123,16 @@ public class ContextGeneratorProcessorFactory implements AnnotationProcessorFact
ContextCapabilitiesGenerator.generateField(writer, interface_decl);
}
writer.println();
- ContextCapabilitiesGenerator.generateInitStubsPrologue(writer);
+ for (TypeDeclaration typedecl : interface_decls) {
+ InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
+ ContextCapabilitiesGenerator.generateSymbolAddresses(writer, interface_decl);
+ }
+ writer.println();
+ for (TypeDeclaration typedecl : interface_decls) {
+ InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
+ ContextCapabilitiesGenerator.generateAddressesInitializers(writer, interface_decl);
+ }
+ ContextCapabilitiesGenerator.generateInitStubsPrologue(writer, context_specific);
for (TypeDeclaration typedecl : interface_decls) {
InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
if (!Utils.isFinal(interface_decl))
@@ -132,21 +143,18 @@ public class ContextGeneratorProcessorFactory implements AnnotationProcessorFact
String simple_name = interface_decl.getSimpleName();
if (simple_name.equals("GL11"))
continue;
- ContextCapabilitiesGenerator.generateInitStubs(writer, interface_decl);
+ ContextCapabilitiesGenerator.generateInitStubs(writer, interface_decl, context_specific);
}
ContextCapabilitiesGenerator.generateInitStubsEpilogue(writer);
writer.println();
writer.println("\tstatic void unloadAllStubs() {");
- for (TypeDeclaration typedecl : interface_decls) {
- InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
- ContextCapabilitiesGenerator.generateUnloadStubs(writer, interface_decl);
+ if (!context_specific) {
+ for (TypeDeclaration typedecl : interface_decls) {
+ InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
+ ContextCapabilitiesGenerator.generateUnloadStubs(writer, interface_decl);
+ }
}
writer.println("\t}");
-/* writer.println();
- for (TypeDeclaration typedecl : interface_decls) {
- InterfaceDeclaration interface_decl = (InterfaceDeclaration)typedecl;
- ContextCapabilitiesGenerator.generateSymbolPointers(writer, interface_decl);
- }*/
writer.println();
ContextCapabilitiesGenerator.generateInitializerPrologue(writer);
for (TypeDeclaration typedecl : interface_decls) {
diff --git a/src/java/org/lwjgl/generator/GeneratorProcessorFactory.java b/src/java/org/lwjgl/generator/GeneratorProcessorFactory.java
index 736de90b..103f8c74 100644
--- a/src/java/org/lwjgl/generator/GeneratorProcessorFactory.java
+++ b/src/java/org/lwjgl/generator/GeneratorProcessorFactory.java
@@ -60,7 +60,7 @@ public class GeneratorProcessorFactory implements AnnotationProcessorFactory, Ro
unmodifiableCollection(Arrays.asList("*"));
private static final Collection supportedOptions =
- unmodifiableCollection(Arrays.asList("-Atypemap", "-Ageneratechecks"));
+ unmodifiableCollection(Arrays.asList("-Atypemap", "-Ageneratechecks", "-Acontextspecific"));
public Collection supportedAnnotationTypes() {
return supportedAnnotations;
@@ -93,15 +93,14 @@ public class GeneratorProcessorFactory implements AnnotationProcessorFactory, Ro
public void process() {
Map options = env.getOptions();
String typemap_classname = null;
- boolean generate_error_checks = false;
+ boolean generate_error_checks = options.containsKey("-Ageneratechecks");
+ boolean context_specific = options.containsKey("-Acontextspecific");
for (String k : options.keySet()) {
int delimiter = k.indexOf('=');
if (delimiter != -1) {
if (k.startsWith("-Atypemap")) {
typemap_classname = k.substring(delimiter + 1);
}
- } else if ( "-Ageneratechecks".equals(k)) {
- generate_error_checks = true;
}
}
if (typemap_classname == null)
@@ -109,7 +108,7 @@ public class GeneratorProcessorFactory implements AnnotationProcessorFactory, Ro
try {
TypeMap type_map = (TypeMap)(Class.forName(typemap_classname).newInstance());
for (TypeDeclaration typedecl : env.getSpecifiedTypeDeclarations()) {
- typedecl.accept(getDeclarationScanner(new GeneratorVisitor(env, type_map, generate_error_checks), NO_OP));
+ typedecl.accept(getDeclarationScanner(new GeneratorVisitor(env, type_map, generate_error_checks, context_specific), NO_OP));
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
diff --git a/src/java/org/lwjgl/generator/GeneratorVisitor.java b/src/java/org/lwjgl/generator/GeneratorVisitor.java
index 6768d081..8f287815 100644
--- a/src/java/org/lwjgl/generator/GeneratorVisitor.java
+++ b/src/java/org/lwjgl/generator/GeneratorVisitor.java
@@ -57,11 +57,13 @@ public class GeneratorVisitor extends SimpleDeclarationVisitor {
private final AnnotationProcessorEnvironment env;
private final TypeMap type_map;
private final boolean generate_error_checks;
+ private final boolean context_specific;
- public GeneratorVisitor(AnnotationProcessorEnvironment env, TypeMap type_map, boolean generate_error_checks) {
+ public GeneratorVisitor(AnnotationProcessorEnvironment env, TypeMap type_map, boolean generate_error_checks, boolean context_specific) {
this.env = env;
this.type_map = type_map;
this.generate_error_checks = generate_error_checks;
+ this.context_specific = context_specific;
}
private void validateMethods(InterfaceDeclaration d) {
@@ -153,7 +155,7 @@ public class GeneratorVisitor extends SimpleDeclarationVisitor {
}
private static void generateMethodNativePointers(PrintWriter writer, MethodDeclaration method) {
- writer.println("static " + method.getSimpleName() + TypedefsGenerator.TYPEDEF_POSTFIX + " " + method.getSimpleName() + ";");
+ writer.println("static " + Utils.getTypedefName(method) + " " + method.getSimpleName() + ";");
}
private void generateJavaSource(InterfaceDeclaration d) throws IOException {
@@ -190,7 +192,7 @@ public class GeneratorVisitor extends SimpleDeclarationVisitor {
}
if (d.getMethods().size() > 0)
java_writer.println("\tstatic native void " + Utils.STUB_INITIALIZER_NAME + "() throws LWJGLException;");
- JavaMethodsGenerator.generateMethodsJava(env, type_map, java_writer, d, generate_error_checks);
+ JavaMethodsGenerator.generateMethodsJava(env, type_map, java_writer, d, generate_error_checks, context_specific);
java_writer.println("}");
java_writer.close();
String qualified_interface_name = Utils.getQualifiedClassName(d);
@@ -204,23 +206,29 @@ public class GeneratorVisitor extends SimpleDeclarationVisitor {
native_writer.println("/* MACHINE GENERATED FILE, DO NOT EDIT */");
native_writer.println();
native_writer.println("#include ");
+ if (context_specific)
+ native_writer.println("#include ");
type_map.printNativeIncludes(native_writer);
native_writer.println();
TypedefsGenerator.generateNativeTypedefs(type_map, native_writer, d.getMethods());
native_writer.println();
- generateMethodsNativePointers(native_writer, d.getMethods());
- native_writer.println();
- NativeMethodStubsGenerator.generateNativeMethodStubs(env, type_map, native_writer, d, generate_error_checks);
- native_writer.print("JNIEXPORT void JNICALL " + Utils.getQualifiedNativeMethodName(qualified_interface_name, Utils.STUB_INITIALIZER_NAME));
- native_writer.println("(JNIEnv *env, jclass clazz) {");
- native_writer.println("\tJavaMethodAndExtFunction functions[] = {");
- RegisterStubsGenerator.generateMethodsNativeStubBind(native_writer, d, generate_error_checks);
- native_writer.println("\t};");
- native_writer.println("\tint num_functions = NUMFUNCTIONS(functions);");
- native_writer.print("\t");
- native_writer.print(type_map.getRegisterNativesFunctionName());
- native_writer.println("(env, clazz, num_functions, functions);");
- native_writer.println("}");
+ if (!context_specific) {
+ generateMethodsNativePointers(native_writer, d.getMethods());
+ native_writer.println();
+ }
+ NativeMethodStubsGenerator.generateNativeMethodStubs(env, type_map, native_writer, d, generate_error_checks, context_specific);
+ if (!context_specific) {
+ native_writer.print("JNIEXPORT void JNICALL " + Utils.getQualifiedNativeMethodName(qualified_interface_name, Utils.STUB_INITIALIZER_NAME));
+ native_writer.println("(JNIEnv *env, jclass clazz) {");
+ native_writer.println("\tJavaMethodAndExtFunction functions[] = {");
+ RegisterStubsGenerator.generateMethodsNativeStubBind(native_writer, d, generate_error_checks, context_specific);
+ native_writer.println("\t};");
+ native_writer.println("\tint num_functions = NUMFUNCTIONS(functions);");
+ native_writer.print("\t");
+ native_writer.print(type_map.getRegisterNativesFunctionName());
+ native_writer.println("(env, clazz, num_functions, functions);");
+ native_writer.println("}");
+ }
native_writer.close();
env.getMessager().printNotice("Generated C source " + qualified_interface_name);
}
diff --git a/src/java/org/lwjgl/generator/JavaMethodsGenerator.java b/src/java/org/lwjgl/generator/JavaMethodsGenerator.java
index 19e8c956..b2d43556 100644
--- a/src/java/org/lwjgl/generator/JavaMethodsGenerator.java
+++ b/src/java/org/lwjgl/generator/JavaMethodsGenerator.java
@@ -50,46 +50,51 @@ import java.util.*;
import java.nio.*;
public class JavaMethodsGenerator {
- public static void generateMethodsJava(AnnotationProcessorEnvironment env, TypeMap type_map, PrintWriter writer, InterfaceDeclaration interface_decl, boolean generate_error_checks) {
+ public static void generateMethodsJava(AnnotationProcessorEnvironment env, TypeMap type_map, PrintWriter writer, InterfaceDeclaration interface_decl, boolean generate_error_checks, boolean context_specific) {
for (MethodDeclaration method : interface_decl.getMethods())
- generateMethodJava(env, type_map, writer, interface_decl, method, generate_error_checks);
+ generateMethodJava(env, type_map, writer, interface_decl, method, generate_error_checks, context_specific);
}
- private static void generateMethodJava(AnnotationProcessorEnvironment env, TypeMap type_map, PrintWriter writer, InterfaceDeclaration interface_decl, MethodDeclaration method, boolean generate_error_checks) {
+ private static void generateMethodJava(AnnotationProcessorEnvironment env, TypeMap type_map, PrintWriter writer, InterfaceDeclaration interface_decl, MethodDeclaration method, boolean generate_error_checks, boolean context_specific) {
writer.println();
- if (Utils.isMethodIndirect(generate_error_checks, method)) {
+ if (Utils.isMethodIndirect(generate_error_checks, context_specific, method)) {
if (method.getAnnotation(GenerateAutos.class) != null) {
- printMethodWithMultiType(env, type_map, writer, interface_decl, method, TypeInfo.getDefaultTypeInfoMap(method), Mode.AUTOS, generate_error_checks);
+ printMethodWithMultiType(env, type_map, writer, interface_decl, method, TypeInfo.getDefaultTypeInfoMap(method), Mode.AUTOS, generate_error_checks, context_specific);
}
Collection