aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2003-07-03 00:09:30 +0000
committerKenneth Russel <[email protected]>2003-07-03 00:09:30 +0000
commit93d272a0525ec57aa3cd584f15cde6cf2a637e0c (patch)
tree3d6c9f2a305539d26c7449566bbb0d72bf74b12c
parent37d90a0da397a1958fb101051170a60f871fb8cc (diff)
Added pbuffer support to JOGL on X11; HWShadowmapsSimple and
ProceduralTexturePhysics demos are now working on Linux with the appropriate hardware. Moved core GLX routines out of the public GLX interface; this allowed XVisualInfo (and the new GLXFBConfig) to be removed from the public API. Added support to GlueGen for returning arrays of pointers as arrays of StructAccessors in Java and for choosing the typedef name for a pointer-to-struct if the struct itself does not have a typedef name. Added support to GLEmitter to emit ProcAddressTables under arbitrary names and to support arbitrary mechanisms for fetching those tables. Made GLU (on all platforms) and GLX (on X11) be dynamically linked. Refactored ProcAddressTable filling to be mostly shared code. Tested changes on Linux, Mac OS X and Windows. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@17 232f8b59-042b-4e1e-8c03-345bb8c30851
-rw-r--r--make/Makefile219
-rw-r--r--make/gl-common.cfg16
-rw-r--r--make/gl-glx-common.cfg64
-rw-r--r--make/gl-glx-macosx.cfg10
-rw-r--r--make/gl-glx-x11.cfg8
-rw-r--r--make/gl-impl-macosx.cfg2
-rw-r--r--make/gl-impl-win32.cfg2
-rw-r--r--make/gl-impl-x11.cfg2
-rw-r--r--make/glu-impl-common-CustomJavaCode.java13
-rw-r--r--make/glu-impl-common.cfg5
-rw-r--r--make/glu-impl-macosx.cfg2
-rw-r--r--make/glu-impl-x11.cfg4
-rw-r--r--make/glx-x11.cfg86
-rw-r--r--make/stub_includes/opengl/GL/glu.h61
-rw-r--r--make/stub_includes/win32/windows.h1
-rw-r--r--make/stub_includes/win32/wingdi.h3
-rw-r--r--make/stub_includes/x11/X11/X.h1
-rw-r--r--make/stub_includes/x11/X11/Xutil.h5
-rw-r--r--make/stub_includes/x11/window-system.c138
-rw-r--r--make/wingdi-win32.cfg2
-rw-r--r--src/net/java/games/gluegen/CMethodBindingEmitter.java210
-rw-r--r--src/net/java/games/gluegen/DebugEmitter.java9
-rw-r--r--src/net/java/games/gluegen/GlueEmitter.java8
-rw-r--r--src/net/java/games/gluegen/GlueGen.java21
-rw-r--r--src/net/java/games/gluegen/JavaConfiguration.java28
-rw-r--r--src/net/java/games/gluegen/JavaEmitter.java69
-rw-r--r--src/net/java/games/gluegen/JavaMethodBindingEmitter.java2
-rw-r--r--src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java13
-rw-r--r--src/net/java/games/gluegen/JavaType.java55
-rw-r--r--src/net/java/games/gluegen/MethodBinding.java5
-rw-r--r--src/net/java/games/gluegen/ReferencedStructs.java13
-rw-r--r--src/net/java/games/gluegen/cgram/types/PointerType.java4
-rw-r--r--src/net/java/games/gluegen/opengl/BuildComposablePipeline.java2
-rw-r--r--src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java16
-rw-r--r--src/net/java/games/gluegen/opengl/GLEmitter.java95
-rw-r--r--src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java11
-rw-r--r--src/net/java/games/gluegen/runtime/ProcAddressHelper.java46
-rw-r--r--src/net/java/games/jogl/impl/GLContext.java48
-rw-r--r--src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java70
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsGLContext.java83
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java4
-rw-r--r--src/net/java/games/jogl/impl/x11/X11GLContext.java95
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java24
-rw-r--r--src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java338
44 files changed, 1245 insertions, 468 deletions
diff --git a/make/Makefile2 b/make/Makefile2
index cf9b6f655..91b9d6641 100644
--- a/make/Makefile2
+++ b/make/Makefile2
@@ -156,6 +156,7 @@ GG_JAVAFILES = \
$(GLUEGEN_DIR)/StructLayout.java \
$(GLUEGEN_DIR)/TypeInfo.java \
$(GLUEGEN_DIR)/runtime/BufferFactory.java \
+ $(GLUEGEN_DIR)/runtime/ProcAddressHelper.java \
$(GLUEGEN_DIR)/runtime/StructAccessor.java \
$(GLUEGEN_DIR)/opengl/ConvertFromGL4Java.java \
$(GLUEGEN_DIR)/opengl/CGLPAWrapperEmitter.java \
@@ -394,6 +395,7 @@ JOGL_JAVAFILES_WINDOWS = \
JOGL_GENERATED_JAVAFILES_WINDOWS = \
$(GENSRC_JOGL_IMPL_DIR)/windows/BITMAPINFO.java \
$(GENSRC_JOGL_IMPL_DIR)/windows/BITMAPINFOHEADER.java \
+ $(GENSRC_JOGL_IMPL_DIR)/windows/GLProcAddressTable.java \
$(GENSRC_JOGL_IMPL_DIR)/windows/JAWT_Win32DrawingSurfaceInfo.java \
$(GENSRC_JOGL_IMPL_DIR)/windows/PIXELFORMATDESCRIPTOR.java \
$(GENSRC_JOGL_IMPL_DIR)/windows/RGBQUAD.java \
@@ -408,12 +410,17 @@ JOGL_JAVAFILES_X11 = \
$(JOGL_IMPL_DIR)/x11/X11GLContext.java \
$(JOGL_IMPL_DIR)/x11/X11GLContextFactory.java \
$(JOGL_IMPL_DIR)/x11/X11OnscreenGLContext.java \
- $(JOGL_IMPL_DIR)/x11/X11OffscreenGLContext.java
+ $(JOGL_IMPL_DIR)/x11/X11OffscreenGLContext.java \
+ $(JOGL_IMPL_DIR)/x11/X11PbufferGLContext.java
JOGL_GENERATED_JAVAFILES_X11 = \
+ $(GENSRC_JOGL_IMPL_DIR)/x11/GLProcAddressTable.java \
$(GENSRC_JOGL_IMPL_DIR)/x11/GLX.java \
+ $(GENSRC_JOGL_IMPL_DIR)/x11/GLXFBConfig.java \
+ $(GENSRC_JOGL_IMPL_DIR)/x11/GLXProcAddressTable.java \
$(GENSRC_JOGL_IMPL_DIR)/x11/JAWT_X11DrawingSurfaceInfo.java \
- $(GENSRC_JOGL_IMPL_DIR)/x11/X11GLImpl.java
+ $(GENSRC_JOGL_IMPL_DIR)/x11/X11GLImpl.java \
+ $(GENSRC_JOGL_IMPL_DIR)/x11/XVisualInfo.java
JOGL_GENERATED_CFILES_X11 = \
$(GENSRC_GL_NATIVE_DIR)/GLX_JNI.c \
@@ -429,6 +436,7 @@ JOGL_JAVAFILES_MACOSX = \
JOGL_GENERATED_JAVAFILES_MACOSX = \
$(GENSRC_JOGL_IMPL_DIR)/macosx/CGL.java \
+ $(GENSRC_JOGL_IMPL_DIR)/macosx/GLProcAddressTable.java \
$(GENSRC_JOGL_IMPL_DIR)/macosx/JAWT_MacOSXDrawingSurfaceInfo.java \
$(GENSRC_JOGL_IMPL_DIR)/macosx/MacOSXGLImpl.java
@@ -478,7 +486,7 @@ JOGL_GENERATED_CFILES_PD=$(JOGL_GENERATED_CFILES_WINDOWS)
GL_DEFINES=/D "JOGL_EXPORTS" $(DEFINES)
GL_INCLUDES=/I"$(JOGL_STUB_INCLUDES_DIR_OPENGL)" $(INCLUDES)
GL_C_BUILD_OBJ_CMD=$(CC) /c $< $(CFLAGS) $(GL_INCLUDES) $(GL_DEFINES) /Fo"$@"
-JOGL_DSO_LINK_ADDITIONAL_LIBS=opengl32.lib glu32.lib jawt.lib gdi32.lib
+JOGL_DSO_LINK_ADDITIONAL_LIBS=opengl32.lib glu32.lib jawt.lib gdi32.lib kernel32.lib
GL_LINKFLAGS=$(LINKFLAGS) $(JOGL_DSO_LINK_ADDITIONAL_LIBS)
GL_C_LINK_DSO_CMD=$(LINK) /OUT:"$@" $(GL_LINKFLAGS)
endif # WIN32
@@ -551,16 +559,15 @@ JOGL_GENERATED_JAVAFILES = \
$(GENSRC_JOGL_DIR)/WGL.java \
$(GENSRC_JOGL_DIR)/GLX.java \
$(GENSRC_JOGL_DIR)/CGL.java \
- $(GENSRC_JOGL_DIR)/XVisualInfo.java \
$(GENSRC_JOGL_GLU_DIR)/GLU.java \
$(GENSRC_JOGL_GLU_DIR)/GLUquadric.java \
$(GENSRC_JOGL_GLU_IMPL_DIR)/GLUImpl.java \
+ $(GENSRC_JOGL_GLU_IMPL_DIR)/GLUProcAddressTable.java \
$(GENSRC_JOGL_IMPL_DIR)/JAWT.java \
$(GENSRC_JOGL_IMPL_DIR)/JAWTFactory.java \
$(GENSRC_JOGL_IMPL_DIR)/JAWT_DrawingSurface.java \
$(GENSRC_JOGL_IMPL_DIR)/JAWT_DrawingSurfaceInfo.java \
$(GENSRC_JOGL_IMPL_DIR)/JAWT_Rectangle.java \
- $(GENSRC_JOGL_IMPL_DIR)/ProcAddressTable.java \
$(GENSRC_JOGL_IMPL_DIR)/StaticGLInfo.java \
$(JOGL_GENERATED_JAVAFILES_PD)
@@ -878,7 +885,7 @@ $(JOGL_GENERATED_JAVAFILES) $(JOGL_GENERATED_CFILES) : $(JOGL_STUB_INCLUDES_PD)
$(JAVA) -cp "$(CLASSES_DIR)$(CP_SEPARATOR)$(CLASSPATH)" net.java.games.gluegen.GlueGen -Enet.java.games.gluegen.JavaEmitter -C$(JOGL_JAWT_CFG) $(JOGL_GLUEGEN_INCLUDES) -I"$(JAVA_INCLUDE_PATH)" "$(JAVA_INCLUDE_PATH_PD)/jawt_md.h"
# generate WGL/GLX/CGL implementation class
- $(JAVA) -cp "$(CLASSES_DIR)$(CP_SEPARATOR)$(CLASSPATH)" net.java.games.gluegen.GlueGen -Enet.java.games.gluegen.JavaEmitter -C$(JOGL_WINDOW_SYSTEM_CFG) $(JOGL_GLUEGEN_INCLUDES) -I$(JOGL_STUB_INCLUDES_DIR_OPENGL) $(JOGL_STUB_INCLUDES_DIR_PD)/window-system.c
+ $(JAVA) -cp "$(CLASSES_DIR)$(CP_SEPARATOR)$(CLASSPATH)" net.java.games.gluegen.GlueGen -Enet.java.games.gluegen.opengl.GLEmitter -C$(JOGL_WINDOW_SYSTEM_CFG) $(JOGL_GLUEGEN_INCLUDES) -I$(JOGL_STUB_INCLUDES_DIR_OPENGL) $(JOGL_STUB_INCLUDES_DIR_PD)/window-system.c
# generate StaticGLInfo class
$(JAVA) -cp "$(CLASSES_DIR)$(CP_SEPARATOR)$(CLASSPATH)" net.java.games.gluegen.opengl.BuildStaticGLInfo net.java.games.jogl.impl $(GENSRC_JOGL_IMPL_DIR) $(JOGL_HEADERS)
diff --git a/make/gl-common.cfg b/make/gl-common.cfg
index f824432d0..32664d7a0 100644
--- a/make/gl-common.cfg
+++ b/make/gl-common.cfg
@@ -7,6 +7,7 @@ RuntimeExceptionType GLException
# Imports needed by all glue code
Import java.nio.*
Import net.java.games.jogl.*
+Import net.java.games.jogl.impl.*
# Don't output #defines of GL version identifier strings as constants,
# because we don't need them java-side.
@@ -362,10 +363,6 @@ Opaque long __GLXextFuncPtr
Opaque boolean Bool
Opaque long Display *
Opaque long GLXContext
-Opaque long GLXFBConfig
-Opaque long GLXFBConfig *
-Opaque long GLXFBConfigSGIX
-Opaque long GLXFBConfigSGIX *
Opaque long Visual *
# Ignore the empty Display and Visual data structures (though made
# opaque, the references from XVisualInfo and elsewhere are still
@@ -377,3 +374,14 @@ Ignore Visual
ArgumentIsString glXGetProcAddress 0
ArgumentIsString glXGetProcAddressARB 0
ReturnsString glXQueryExtensionsString
+ReturnsString glXQueryServerString
+ReturnsString glXGetClientString
+TemporaryCVariableDeclaration glXChooseFBConfig int count;
+TemporaryCVariableAssignment glXChooseFBConfig count = _ptr3[0];
+ReturnValueLength glXChooseFBConfig count
+TemporaryCVariableDeclaration glXChooseFBConfigSGIX int count;
+TemporaryCVariableAssignment glXChooseFBConfigSGIX count = _ptr3[0];
+ReturnValueLength glXChooseFBConfigSGIX count
+TemporaryCVariableDeclaration glXGetFBConfigs int count;
+TemporaryCVariableAssignment glXGetFBConfigs count = _ptr2[0];
+ReturnValueLength glXGetFBConfigs count
diff --git a/make/gl-glx-common.cfg b/make/gl-glx-common.cfg
new file mode 100644
index 000000000..2c3a4b4dd
--- /dev/null
+++ b/make/gl-glx-common.cfg
@@ -0,0 +1,64 @@
+# This .cfg file causes the core GLX routines to be ignored from both
+# the public API as well as from the GL implementation files on
+# non-X11 platforms.
+
+# Ignore all of the core GLX routines, which are exposed only in the
+# implementation GLX class
+Ignore glXChooseVisual
+Ignore glXCreateContext
+Ignore glXDestroyContext
+Ignore glXMakeCurrent
+Ignore glXCopyContext
+Ignore glXSwapBuffers
+Ignore glXCreateGLXPixmap
+Ignore glXDestroyGLXPixmap
+Ignore glXQueryExtension
+Ignore glXQueryVersion
+Ignore glXIsDirect
+Ignore glXGetConfig
+Ignore glXGetCurrentContext
+Ignore glXGetCurrentDrawable
+Ignore glXWaitGL
+Ignore glXWaitX
+Ignore glXUseXFont
+Ignore glXQueryExtensionsString
+Ignore glXQueryServerString
+Ignore glXGetClientString
+Ignore glXGetCurrentDisplay
+Ignore glXChooseFBConfig
+Ignore glXGetFBConfigAttrib
+Ignore glXGetFBConfigs
+Ignore glXGetVisualFromFBConfig
+Ignore glXCreateWindow
+Ignore glXDestroyWindow
+Ignore glXCreatePixmap
+Ignore glXDestroyPixmap
+Ignore glXCreatePbuffer
+Ignore glXDestroyPbuffer
+Ignore glXQueryDrawable
+Ignore glXCreateNewContext
+Ignore glXMakeContextCurrent
+Ignore glXGetCurrentReadDrawable
+Ignore glXQueryContext
+Ignore glXSelectEvent
+Ignore glXGetSelectedEvent
+Ignore glXGetProcAddress
+
+# Ignore a few extensions that bring in data types we don't want to
+# expose in the public API (and that are useless anyway without
+# exposing more of the implementation)
+Ignore glXGetFBConfigAttribSGIX
+Ignore glXChooseFBConfigSGIX
+Ignore glXCreateGLXPixmapWithConfigSGIX
+Ignore glXCreateContextWithConfigSGIX
+Ignore glXGetVisualFromFBConfigSGIX
+Ignore glXGetFBConfigFromVisualSGIX
+Ignore glXCreateGLXPbufferSGIX
+Ignore glXDestroyGLXPbufferSGIX
+Ignore glXQueryGLXPbufferSGIX
+Ignore glXSelectEventSGIX
+Ignore glXGetSelectedEventSGIX
+Ignore glXCreateGLXPixmapMESA
+
+# Now we can ignore the GLXFBConfig data type in the public API
+Ignore GLXFBConfig
diff --git a/make/gl-glx-macosx.cfg b/make/gl-glx-macosx.cfg
deleted file mode 100644
index 7a6d826ce..000000000
--- a/make/gl-glx-macosx.cfg
+++ /dev/null
@@ -1,10 +0,0 @@
-# This .cfg file is used to generate the interface which contains the
-# window system-specific extensions which are exposed (via
-# inheritance) to the GL interface.
-Package net.java.games.jogl
-Style InterfaceOnly
-JavaClass MacOSXGL
-Include gl-common-macosx.cfg
-
-# Ignore everything that doesn't start with glX, GLX or XVisualInfo
-IgnoreNot ^(glX|GLX|XVisualInf).+
diff --git a/make/gl-glx-x11.cfg b/make/gl-glx-x11.cfg
index 99292615a..359e35c62 100644
--- a/make/gl-glx-x11.cfg
+++ b/make/gl-glx-x11.cfg
@@ -6,5 +6,9 @@ Style InterfaceOnly
JavaClass GLX
Include gl-common-x11.cfg
-# Ignore everything that doesn't start with glX, GLX or XVisualInfo
-IgnoreNot ^(glX|GLX|XVisualInf).+
+# Ignore everything that doesn't start with glX or GLX
+IgnoreNot ^(glX|GLX).+
+
+# Pick up ignores that must also be included in other platforms' impl
+# files
+Include gl-glx-common.cfg
diff --git a/make/gl-impl-macosx.cfg b/make/gl-impl-macosx.cfg
index 5ada8af01..5aa8ea786 100644
--- a/make/gl-impl-macosx.cfg
+++ b/make/gl-impl-macosx.cfg
@@ -6,8 +6,10 @@ JavaClass GL
ImplPackage net.java.games.jogl.impl.macosx
ImplJavaClass MacOSXGLImpl
Include gl-common-macosx.cfg
+Include gl-glx-common.cfg
EmitProcAddressTable true
+ProcAddressTableClassName GLProcAddressTable
CustomCCode #include <inttypes.h>
diff --git a/make/gl-impl-win32.cfg b/make/gl-impl-win32.cfg
index caa65180e..4891bd490 100644
--- a/make/gl-impl-win32.cfg
+++ b/make/gl-impl-win32.cfg
@@ -6,8 +6,10 @@ JavaClass GL
ImplPackage net.java.games.jogl.impl.windows
ImplJavaClass WindowsGLImpl
Include gl-common-win32.cfg
+Include gl-glx-common.cfg
EmitProcAddressTable true
+ProcAddressTableClassName GLProcAddressTable
CustomCCode #define WIN32_LEAN_AND_MEAN
CustomCCode #include <windows.h>
diff --git a/make/gl-impl-x11.cfg b/make/gl-impl-x11.cfg
index 35595e829..2ec48039e 100644
--- a/make/gl-impl-x11.cfg
+++ b/make/gl-impl-x11.cfg
@@ -6,8 +6,10 @@ JavaClass GL
ImplPackage net.java.games.jogl.impl.x11
ImplJavaClass X11GLImpl
Include gl-common-x11.cfg
+Include gl-glx-common.cfg
EmitProcAddressTable true
+ProcAddressTableClassName GLProcAddressTable
# Pick up XVisualInfo from jogl
Ignore XVisualInfo
diff --git a/make/glu-impl-common-CustomJavaCode.java b/make/glu-impl-common-CustomJavaCode.java
index 8722ea64a..04505db55 100644
--- a/make/glu-impl-common-CustomJavaCode.java
+++ b/make/glu-impl-common-CustomJavaCode.java
@@ -1,8 +1,11 @@
-/** WARNING: this function is not yet implemented! */
+/** Indicates whether the given GLU routine is available to be called. */
public boolean isFunctionAvailable(String gluFunctionName)
{
- // TODO FIXME: Implement the GLU equivalent GL.isFunctionAvailable(String)
- if (true) throw new GLException("GLU.isFunctionAvailable is not yet implemented.");
-
- return false;
+ return (gluProcAddressTable.getAddressFor(gluFunctionName) != 0);
+}
+
+private GLUProcAddressTable gluProcAddressTable;
+public GLUImpl(GLUProcAddressTable gluProcAddressTable)
+{
+ this.gluProcAddressTable = gluProcAddressTable;
}
diff --git a/make/glu-impl-common.cfg b/make/glu-impl-common.cfg
index d4fdb7911..1e6ae0699 100644
--- a/make/glu-impl-common.cfg
+++ b/make/glu-impl-common.cfg
@@ -5,9 +5,12 @@ Include glu-common.cfg
Style ImplOnly
+EmitProcAddressTable true
+ProcAddressTableClassName GLUProcAddressTable
+GetProcAddressTableExpr gluProcAddressTable
+
# Custom Java code for GLUImpl class
IncludeAs CustomJavaCode GLUImpl glu-impl-common-CustomJavaCode.java
# Custom C code for GLUImpl class
IncludeAs CustomCCode glu-impl-common-CustomCCode.c
-
diff --git a/make/glu-impl-macosx.cfg b/make/glu-impl-macosx.cfg
index cf40212d0..5e856c7ec 100644
--- a/make/glu-impl-macosx.cfg
+++ b/make/glu-impl-macosx.cfg
@@ -2,3 +2,5 @@
# Mac OS X.
Include glu-impl-common.cfg
+
+CustomCCode #include <inttypes.h>
diff --git a/make/glu-impl-x11.cfg b/make/glu-impl-x11.cfg
index 42e97a00e..3e46a73b5 100644
--- a/make/glu-impl-x11.cfg
+++ b/make/glu-impl-x11.cfg
@@ -3,8 +3,6 @@
Include glu-impl-common.cfg
-# !! FIXME: Chris doesn't have access to X11 yet, so he
-# doesn't know what CustomCCode directives to put in here.
-
+CustomCCode #include <inttypes.h>
diff --git a/make/glx-x11.cfg b/make/glx-x11.cfg
index f9a69c0b3..39098f0a8 100644
--- a/make/glx-x11.cfg
+++ b/make/glx-x11.cfg
@@ -5,13 +5,24 @@ JavaClass GLX
Style allstatic
Include gl-common-x11.cfg
+EmitProcAddressTable true
+ProcAddressTableClassName GLXProcAddressTable
+GetProcAddressTableExpr glxProcAddressTable
+# This must be present for bootstrapping
+SkipProcAddressGen glXGetProcAddressARB
+
+CustomJavaCode GLX private static GLXProcAddressTable glxProcAddressTable = new GLXProcAddressTable();
+CustomJavaCode GLX public static GLXProcAddressTable getGLXProcAddressTable() { return glxProcAddressTable; }
+CustomJavaCode GLX public static native long dlsym(String name);
+
CustomCCode #include <inttypes.h>
CustomCCode #include <X11/Xlib.h>
CustomCCode #include <X11/Xutil.h>
CustomCCode #include <GL/glx.h>
-
-# Pick up XVisualInfo from jogl
-Ignore XVisualInfo
+CustomCCode /* Linux headers don't work properly */
+CustomCCode #define __USE_GNU
+CustomCCode #include <dlfcn.h>
+CustomCCode #undef __USE_GNU
ArgumentIsString XOpenDisplay 0
@@ -26,3 +37,72 @@ CustomCCode JNIEXPORT jlong JNICALL
CustomCCode Java_net_java_games_jogl_impl_x11_GLX_RootWindow(JNIEnv *env, jclass _unused, jlong display, jint screen) {
CustomCCode return RootWindow((Display*) (intptr_t) display, screen);
CustomCCode }
+CustomCCode JNIEXPORT jlong JNICALL
+CustomCCode Java_net_java_games_jogl_impl_x11_GLX_dlsym(JNIEnv *env, jclass _unused, jstring name) {
+CustomCCode const jbyte* chars;
+CustomCCode void* res;
+CustomCCode chars = (*env)->GetStringUTFChars(env, name, NULL);
+CustomCCode res = dlsym(RTLD_DEFAULT, chars);
+CustomCCode (*env)->ReleaseStringUTFChars(env, name, chars);
+CustomCCode return (jlong) ((intptr_t) res);
+CustomCCode }
+
+# Ignore everything not in the GLX core (up through GLX 1.4) aside from glXGetProcAddress
+# FIXME: this needs to be kept in sync with the stub headers more than usual
+Ignore glXFreeContextEXT
+Ignore glXGetContextIDEXT
+Ignore glXGetCurrentDisplayEXT
+Ignore glXImportContextEXT
+Ignore glXQueryContextInfoEXT
+
+Ignore glXCopySubBufferMESA
+Ignore glXCreateGLXPixmapMESA
+Ignore glXReleaseBuffersMESA
+Ignore glXSet3DfxModeMESA
+
+Ignore glXGetSyncValuesOML
+Ignore glXGetMscRateOML
+Ignore glXSwapBuffersMscOML
+Ignore glXWaitForMscOML
+Ignore glXWaitForSbcOML
+
+Ignore glXAllocateMemoryNV
+Ignore glXFreeMemoryNV
+
+Ignore glXCushionSGI
+Ignore glXGetVideoSyncSGI
+Ignore glXWaitVideoSyncSGI
+Ignore glXSwapIntervalSGI
+Ignore glXMakeCurrentReadSGI
+Ignore glXGetCurrentReadDrawableSGI
+
+Ignore glXCreateGLXVideoSourceSGIX
+Ignore glXDestroyGLXVideoSourceSGIX
+Ignore glXGetFBConfigAttribSGIX
+Ignore glXChooseFBConfigSGIX
+Ignore glXCreateGLXPixmapWithConfigSGIX
+Ignore glXCreateContextWithConfigSGIX
+Ignore glXGetVisualFromFBConfigSGIX
+Ignore glXGetFBConfigFromVisualSGIX
+Ignore glXCreateGLXPbufferSGIX
+Ignore glXDestroyGLXPbufferSGIX
+Ignore glXQueryGLXPbufferSGIX
+Ignore glXSelectEventSGIX
+Ignore glXGetSelectedEventSGIX
+Ignore glXBindChannelToWindowSGIX
+Ignore glXChannelRectSGIX
+Ignore glXQueryChannelRectSGIX
+Ignore glXQueryChannelDeltasSGIX
+Ignore glXChannelRectSyncSGIX
+Ignore glXAssociateDMPbufferSGIX
+Ignore glXJoinSwapGroupSGIX
+Ignore glXBindSwapBarrierSGIX
+Ignore glXQueryMaxSwapBarriersSGIX
+
+Ignore glXGetTransparentIndexSUN
+
+# Ignore non-GLX GL routines and constants
+Ignore ^GL_.+
+Ignore TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB
+Ignore CLAMP_TO_EDGE_EXT
+Ignore ^gl[^X].+
diff --git a/make/stub_includes/opengl/GL/glu.h b/make/stub_includes/opengl/GL/glu.h
index 89c3f34e3..8f64238f2 100644
--- a/make/stub_includes/opengl/GL/glu.h
+++ b/make/stub_includes/opengl/GL/glu.h
@@ -330,6 +330,67 @@ GLAPI void GLAPIENTRY gluTessVertex (GLUtesselator* tess, GLdouble *location, GL
GLAPI GLint GLAPIENTRY gluUnProject (GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* objX, GLdouble* objY, GLdouble* objZ);
GLAPI GLint GLAPIENTRY gluUnProject4 (GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW);
+
+typedef void (GLAPIENTRY * PFNGLUBEGINCURVEPROC) (GLUnurbs* nurb);
+typedef void (GLAPIENTRY * PFNGLUBEGINPOLYGONPROC) (GLUtesselator* tess);
+typedef void (GLAPIENTRY * PFNGLUBEGINSURFACEPROC) (GLUnurbs* nurb);
+typedef void (GLAPIENTRY * PFNGLUBEGINTRIMPROC) (GLUnurbs* nurb);
+typedef GLint (GLAPIENTRY * PFNGLUBUILD1DMIPMAPLEVELSPROC) (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
+typedef GLint (GLAPIENTRY * PFNGLUBUILD1DMIPMAPSPROC) (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, const void *data);
+typedef GLint (GLAPIENTRY * PFNGLUBUILD2DMIPMAPLEVELSPROC) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
+typedef GLint (GLAPIENTRY * PFNGLUBUILD2DMIPMAPSPROC) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
+typedef GLint (GLAPIENTRY * PFNGLUBUILD3DMIPMAPLEVELSPROC) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
+typedef GLint (GLAPIENTRY * PFNGLUBUILD3DMIPMAPSPROC) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
+typedef GLboolean (GLAPIENTRY * PFNGLUCHECKEXTENSIONPROC) (const GLubyte *extName, const GLubyte *extString);
+typedef void (GLAPIENTRY * PFNGLUCYLINDERPROC) (GLUquadric* quad, GLdouble base, GLdouble top, GLdouble height, GLint slices, GLint stacks);
+typedef void (GLAPIENTRY * PFNGLUDELETENURBSRENDERERPROC) (GLUnurbs* nurb);
+typedef void (GLAPIENTRY * PFNGLUDELETEQUADRICPROC) (GLUquadric* quad);
+typedef void (GLAPIENTRY * PFNGLUDELETETESSPROC) (GLUtesselator* tess);
+typedef void (GLAPIENTRY * PFNGLUDISKPROC) (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops);
+typedef void (GLAPIENTRY * PFNGLUENDCURVEPROC) (GLUnurbs* nurb);
+typedef void (GLAPIENTRY * PFNGLUENDPOLYGONPROC) (GLUtesselator* tess);
+typedef void (GLAPIENTRY * PFNGLUENDSURFACEPROC) (GLUnurbs* nurb);
+typedef void (GLAPIENTRY * PFNGLUENDTRIMPROC) (GLUnurbs* nurb);
+typedef const GLubyte * (GLAPIENTRY * PFNGLUERRORSTRINGPROC) (GLenum error);
+typedef void (GLAPIENTRY * PFNGLUGETNURBSPROPERTYPROC) (GLUnurbs* nurb, GLenum property, GLfloat* data);
+typedef const GLubyte * (GLAPIENTRY * PFNGLUGETSTRINGPROC) (GLenum name);
+typedef void (GLAPIENTRY * PFNGLUGETTESSPROPERTYPROC) (GLUtesselator* tess, GLenum which, GLdouble* data);
+typedef void (GLAPIENTRY * PFNGLULOADSAMPLINGMATRICESPROC) (GLUnurbs* nurb, const GLfloat *model, const GLfloat *perspective, const GLint *view);
+typedef void (GLAPIENTRY * PFNGLULOOKATPROC) (GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ);
+typedef GLUnurbs* (GLAPIENTRY * PFNGLUNEWNURBSRENDERERPROC) (void);
+typedef GLUquadric* (GLAPIENTRY * PFNGLUNEWQUADRICPROC) (void);
+typedef GLUtesselator* (GLAPIENTRY * PFNGLUNEWTESSPROC) (void);
+typedef void (GLAPIENTRY * PFNGLUNEXTCONTOURPROC) (GLUtesselator* tess, GLenum type);
+typedef void (GLAPIENTRY * PFNGLUNURBSCALLBACKPROC) (GLUnurbs* nurb, GLenum which, _GLUfuncptr CallBackFunc);
+typedef void (GLAPIENTRY * PFNGLUNURBSCALLBACKDATAPROC) (GLUnurbs* nurb, GLvoid* userData);
+typedef void (GLAPIENTRY * PFNGLUNURBSCALLBACKDATAEXTPROC) (GLUnurbs* nurb, GLvoid* userData);
+typedef void (GLAPIENTRY * PFNGLUNURBSCURVEPROC) (GLUnurbs* nurb, GLint knotCount, GLfloat *knots, GLint stride, GLfloat *control, GLint order, GLenum type);
+typedef void (GLAPIENTRY * PFNGLUNURBSPROPERTYPROC) (GLUnurbs* nurb, GLenum property, GLfloat value);
+typedef void (GLAPIENTRY * PFNGLUNURBSSURFACEPROC) (GLUnurbs* nurb, GLint sKnotCount, GLfloat* sKnots, GLint tKnotCount, GLfloat* tKnots, GLint sStride, GLint tStride, GLfloat* control, GLint sOrder, GLint tOrder, GLenum type);
+typedef void (GLAPIENTRY * PFNGLUORTHO2DPROC) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);
+typedef void (GLAPIENTRY * PFNGLUPARTIALDISKPROC) (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops, GLdouble start, GLdouble sweep);
+typedef void (GLAPIENTRY * PFNGLUPERSPECTIVEPROC) (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
+typedef void (GLAPIENTRY * PFNGLUPICKMATRIXPROC) (GLdouble x, GLdouble y, GLdouble delX, GLdouble delY, GLint *viewport);
+typedef GLint (GLAPIENTRY * PFNGLUPROJECTPROC) (GLdouble objX, GLdouble objY, GLdouble objZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* winX, GLdouble* winY, GLdouble* winZ);
+typedef void (GLAPIENTRY * PFNGLUPWLCURVEPROC) (GLUnurbs* nurb, GLint count, GLfloat* data, GLint stride, GLenum type);
+typedef void (GLAPIENTRY * PFNGLUQUADRICCALLBACKPROC) (GLUquadric* quad, GLenum which, _GLUfuncptr CallBackFunc);
+typedef void (GLAPIENTRY * PFNGLUQUADRICDRAWSTYLEPROC) (GLUquadric* quad, GLenum draw);
+typedef void (GLAPIENTRY * PFNGLUQUADRICNORMALSPROC) (GLUquadric* quad, GLenum normal);
+typedef void (GLAPIENTRY * PFNGLUQUADRICORIENTATIONPROC) (GLUquadric* quad, GLenum orientation);
+typedef void (GLAPIENTRY * PFNGLUQUADRICTEXTUREPROC) (GLUquadric* quad, GLboolean texture);
+typedef GLint (GLAPIENTRY * PFNGLUSCALEIMAGEPROC) (GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, const void *dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut);
+typedef void (GLAPIENTRY * PFNGLUSPHEREPROC) (GLUquadric* quad, GLdouble radius, GLint slices, GLint stacks);
+typedef void (GLAPIENTRY * PFNGLUTESSBEGINCONTOURPROC) (GLUtesselator* tess);
+typedef void (GLAPIENTRY * PFNGLUTESSBEGINPOLYGONPROC) (GLUtesselator* tess, GLvoid* data);
+typedef void (GLAPIENTRY * PFNGLUTESSCALLBACKPROC) (GLUtesselator* tess, GLenum which, _GLUfuncptr CallBackFunc);
+typedef void (GLAPIENTRY * PFNGLUTESSENDCONTOURPROC) (GLUtesselator* tess);
+typedef void (GLAPIENTRY * PFNGLUTESSENDPOLYGONPROC) (GLUtesselator* tess);
+typedef void (GLAPIENTRY * PFNGLUTESSNORMALPROC) (GLUtesselator* tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ);
+typedef void (GLAPIENTRY * PFNGLUTESSPROPERTYPROC) (GLUtesselator* tess, GLenum which, GLdouble data);
+typedef void (GLAPIENTRY * PFNGLUTESSVERTEXPROC) (GLUtesselator* tess, GLdouble *location, GLvoid* data);
+typedef GLint (GLAPIENTRY * PFNGLUUNPROJECTPROC) (GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* objX, GLdouble* objY, GLdouble* objZ);
+typedef GLint (GLAPIENTRY * PFNGLUUNPROJECT4PROC) (GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW);
+
#ifdef __cplusplus
}
#endif
diff --git a/make/stub_includes/win32/windows.h b/make/stub_includes/win32/windows.h
index 24b9df4fa..fa4ae1c95 100644
--- a/make/stub_includes/win32/windows.h
+++ b/make/stub_includes/win32/windows.h
@@ -20,6 +20,7 @@ typedef HANDLE HBITMAP;
typedef HANDLE HDC;
typedef HANDLE HGDIOBJ;
typedef HANDLE HGLRC;
+typedef HANDLE HMODULE;
typedef HANDLE HPALETTE;
typedef HANDLE HWND;
typedef long LONG;
diff --git a/make/stub_includes/win32/wingdi.h b/make/stub_includes/win32/wingdi.h
index 5365a8990..3cb6f8568 100644
--- a/make/stub_includes/win32/wingdi.h
+++ b/make/stub_includes/win32/wingdi.h
@@ -115,6 +115,8 @@ typedef struct tagPIXELFORMATDESCRIPTOR
// Windows routines
WINBASEAPI DWORD WINAPI GetLastError(VOID);
+WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR lpLibFileName);
+WINBASEAPI PROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
// OpenGL-related routines
WINGDIAPI int WINAPI ChoosePixelFormat(HDC, CONST PIXELFORMATDESCRIPTOR *);
@@ -148,4 +150,3 @@ WINGDIAPI HBITMAP WINAPI CreateDIBSection(HDC, CONST BITMAPINFO *, UINT, VOID **
WINGDIAPI BOOL WINAPI DeleteDC(HDC);
WINGDIAPI BOOL WINAPI DeleteObject(HGDIOBJ);
WINGDIAPI HGDIOBJ WINAPI SelectObject(HDC, HGDIOBJ);
-
diff --git a/make/stub_includes/x11/X11/X.h b/make/stub_includes/x11/X11/X.h
index 8aa8500cb..2cd64bbf0 100644
--- a/make/stub_includes/x11/X11/X.h
+++ b/make/stub_includes/x11/X11/X.h
@@ -10,6 +10,7 @@ typedef unsigned long VisualID;
typedef XID Colormap;
typedef XID Cursor;
typedef XID Drawable;
+typedef XID Font;
typedef XID GContext;
typedef XID KeySym;
typedef XID Pixmap;
diff --git a/make/stub_includes/x11/X11/Xutil.h b/make/stub_includes/x11/X11/Xutil.h
index 017f8fb98..32c8d5be5 100644
--- a/make/stub_includes/x11/X11/Xutil.h
+++ b/make/stub_includes/x11/X11/Xutil.h
@@ -1,3 +1,6 @@
+#ifndef _XUTIL_H_
+#define _XUTIL_H_
+
#include <X11/X.h>
#include <X11/Xlib.h>
@@ -30,3 +33,5 @@ typedef struct {
#define VisualColormapSizeMask 0x80
#define VisualBitsPerRGBMask 0x100
#define VisualAllMask 0x1FF
+
+#endif /* #defined _XUTIL_H_ */
diff --git a/make/stub_includes/x11/window-system.c b/make/stub_includes/x11/window-system.c
index 55e70c7f7..6af85eeb9 100644
--- a/make/stub_includes/x11/window-system.c
+++ b/make/stub_includes/x11/window-system.c
@@ -1,140 +1,10 @@
-/*
- * Essential glX and supporting routines and data structures extracted
- * from glx.h.
- *
- * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
- */
+// Define GLX_GLXEXT_PROTOTYPES so that the OpenGL GLX extension prototypes in
+// "glxext.h" are parsed.
+#define GLX_GLXEXT_PROTOTYPES
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-
-/*
- * Tokens for glXChooseVisual and glXGetConfig:
- */
-#define GLX_USE_GL 1
-#define GLX_BUFFER_SIZE 2
-#define GLX_LEVEL 3
-#define GLX_RGBA 4
-#define GLX_DOUBLEBUFFER 5
-#define GLX_STEREO 6
-#define GLX_AUX_BUFFERS 7
-#define GLX_RED_SIZE 8
-#define GLX_GREEN_SIZE 9
-#define GLX_BLUE_SIZE 10
-#define GLX_ALPHA_SIZE 11
-#define GLX_DEPTH_SIZE 12
-#define GLX_STENCIL_SIZE 13
-#define GLX_ACCUM_RED_SIZE 14
-#define GLX_ACCUM_GREEN_SIZE 15
-#define GLX_ACCUM_BLUE_SIZE 16
-#define GLX_ACCUM_ALPHA_SIZE 17
-
-/*
- * Error codes returned by glXGetConfig:
- */
-#define GLX_BAD_SCREEN 1
-#define GLX_BAD_ATTRIBUTE 2
-#define GLX_NO_EXTENSION 3
-#define GLX_BAD_VISUAL 4
-#define GLX_BAD_CONTEXT 5
-#define GLX_BAD_VALUE 6
-#define GLX_BAD_ENUM 7
-
-/*
- * GLX 1.3 and later:
- */
-#define GLX_CONFIG_CAVEAT 0x20
-#define GLX_DONT_CARE 0xFFFFFFFF
-#define GLX_SLOW_CONFIG 0x8001
-#define GLX_NON_CONFORMANT_CONFIG 0x800D
-#define GLX_X_VISUAL_TYPE 0x22
-#define GLX_TRANSPARENT_TYPE 0x23
-#define GLX_TRANSPARENT_INDEX_VALUE 0x24
-#define GLX_TRANSPARENT_RED_VALUE 0x25
-#define GLX_TRANSPARENT_GREEN_VALUE 0x26
-#define GLX_TRANSPARENT_BLUE_VALUE 0x27
-#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
-#define GLX_MAX_PBUFFER_WIDTH 0x8016
-#define GLX_MAX_PBUFFER_HEIGHT 0x8017
-#define GLX_MAX_PBUFFER_PIXELS 0x8018
-#define GLX_PRESERVED_CONTENTS 0x801B
-#define GLX_LARGEST_PBUFFER 0x801C
-#define GLX_WIDTH 0x801D
-#define GLX_HEIGHT 0x801E
-#define GLX_EVENT_MASK 0x801F
-#define GLX_DRAWABLE_TYPE 0x8010
-#define GLX_FBCONFIG_ID 0x8013
-#define GLX_VISUAL_ID 0x800B
-#define GLX_WINDOW_BIT 0x00000001
-#define GLX_PIXMAP_BIT 0x00000002
-#define GLX_PBUFFER_BIT 0x00000004
-#define GLX_AUX_BUFFERS_BIT 0x00000010
-#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
-#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
-#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
-#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
-#define GLX_DEPTH_BUFFER_BIT 0x00000020
-#define GLX_STENCIL_BUFFER_BIT 0x00000040
-#define GLX_ACCUM_BUFFER_BIT 0x00000080
-#define GLX_DRAWABLE_TYPE 0x8010
-#define GLX_RENDER_TYPE 0x8011
-#define GLX_X_RENDERABLE 0x8012
-#define GLX_NONE 0x8000
-#define GLX_TRUE_COLOR 0x8002
-#define GLX_DIRECT_COLOR 0x8003
-#define GLX_PSEUDO_COLOR 0x8004
-#define GLX_STATIC_COLOR 0x8005
-#define GLX_GRAY_SCALE 0x8006
-#define GLX_STATIC_GRAY 0x8007
-#define GLX_TRANSPARENT_RGB 0x8008
-#define GLX_TRANSPARENT_INDEX 0x8009
-#define GLX_RGBA_TYPE 0x8014
-#define GLX_COLOR_INDEX_TYPE 0x8015
-#define GLX_COLOR_INDEX_BIT 0x00000002
-#define GLX_RGBA_BIT 0x00000001
-#define GLX_SCREEN 0x800C
-#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
-#define GLX_DAMAGED 0x8020
-#define GLX_SAVED 0x8021
-#define GLX_WINDOW 0x8022
-#define GLX_PBUFFER 0x8023
-#define GLX_PBUFFER_HEIGHT 0x8040
-#define GLX_PBUFFER_WIDTH 0x8041
-
-/*
- * GLX 1.4 and later:
- */
-#define GLX_SAMPLE_BUFFERS 0x186a0 /*100000*/
-#define GLX_SAMPLES 0x186a1 /*100001*/
-
-extern XVisualInfo* glXChooseVisual( Display *dpy, int screen,
- int *attribList );
-
-extern GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis,
- GLXContext shareList, Bool direct );
-
-extern void glXDestroyContext( Display *dpy, GLXContext ctx );
-
-extern Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable,
- GLXContext ctx);
-
-extern void glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
- unsigned long mask );
-
-extern void glXSwapBuffers( Display *dpy, GLXDrawable drawable );
-
-extern GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *visual,
- Pixmap pixmap );
-
-extern void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap );
-
-// Use ARB version for compatibility with older GLX installations
-extern __GLXextFuncPtr glXGetProcAddressARB(const GLubyte *procname);
-
-extern int glXGetConfig( Display *dpy, XVisualInfo *visual,
- int attrib, int *value );
-
-extern const char *glXQueryExtensionsString( Display *dpy, int screen );
+#include <GL/glx.h>
// Routines needed from Xlib.h and Xutil.h (placed here to avoid having
// XVisualInfo generated multiple times)
diff --git a/make/wingdi-win32.cfg b/make/wingdi-win32.cfg
index 3b0a011fa..622cef25d 100644
--- a/make/wingdi-win32.cfg
+++ b/make/wingdi-win32.cfg
@@ -10,6 +10,8 @@ Include gl-common-win32.cfg
# Implement the first argument to wglGetProcAddress as String instead
# of byte[]
ArgumentIsString wglGetProcAddress 0
+ArgumentIsString LoadLibraryA 0
+ArgumentIsString GetProcAddress 1
CustomCCode #define WIN32_LEAN_AND_MEAN
CustomCCode #include <windows.h>
diff --git a/src/net/java/games/gluegen/CMethodBindingEmitter.java b/src/net/java/games/gluegen/CMethodBindingEmitter.java
index 45035f640..763fe6695 100644
--- a/src/net/java/games/gluegen/CMethodBindingEmitter.java
+++ b/src/net/java/games/gluegen/CMethodBindingEmitter.java
@@ -50,6 +50,10 @@ public class CMethodBindingEmitter extends FunctionEmitter
{
protected static final CommentEmitter defaultCommentEmitter =
new DefaultCommentEmitter();
+
+ protected static final String arrayResLength = "_array_res_length";
+ protected static final String arrayRes = "_array_res";
+ protected static final String arrayIdx = "_array_idx";
private MethodBinding binding;
@@ -89,6 +93,12 @@ public class CMethodBindingEmitter extends FunctionEmitter
*/
private MessageFormat returnValueCapacityExpression = null;
+ /**
+ * Length of the returned array. Is ignored if
+ * binding.getJavaReturnType().isArray() is false.
+ */
+ private MessageFormat returnValueLengthExpression = null;
+
// Note: the VC++ 6.0 compiler emits hundreds of warnings when the
// (necessary) null-checking code is enabled. This appears to just
// be a compiler bug, but would be good to track down exactly why it
@@ -168,6 +178,49 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
/**
+ * Get the expression for the length of the returned array
+ */
+ public final MessageFormat getReturnValueLengthExpression()
+ {
+ return returnValueLengthExpression;
+ }
+
+ /**
+ * If this function returns an array, sets the expression for the
+ * length of the returned array.
+ *
+ * @param expression a MessageFormat which, when applied to an array
+ * of type String[] that contains each of the arguments names of the
+ * Java-side binding, returns an expression that will (when compiled
+ * by a C compiler) evaluate to an integer-valued expression. The
+ * value of this expression is the length of the array returned from
+ * this method.
+ *
+ * @throws IllegalArgumentException if the <code>
+ * binding.getJavaReturnType().isNIOBuffer() == false
+ * </code>
+ */
+ public final void setReturnValueLengthExpression(MessageFormat expression)
+ {
+ returnValueLengthExpression = expression;
+
+ if (!binding.getJavaReturnType().isArray())
+ {
+ throw new IllegalArgumentException(
+ "Cannot specify return value length for a method that does not " +
+ "return an array: \"" + binding + "\"");
+ }
+ }
+
+ /**
+ * Returns the List of Strings containing declarations for temporary
+ * C variables to be assigned to after the underlying function call.
+ */
+ public final List/*<String>*/ getTemporaryCVariableDeclarations() {
+ return temporaryCVariableDeclarations;
+ }
+
+ /**
* Sets up a List of Strings containing declarations for temporary C
* variables to be assigned to after the underlying function call. A
* null argument indicates that no manual declarations are to be made.
@@ -177,6 +230,16 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
/**
+ * Returns the List of Strings containing assignments for temporary
+ * C variables which are made after the underlying function call. A
+ * null argument indicates that no manual assignments are to be
+ * made.
+ */
+ public final List/*<String>*/ getTemporaryCVariableAssignments() {
+ return temporaryCVariableAssignments;
+ }
+
+ /**
* Sets up a List of Strings containing assignments for temporary C
* variables which are made after the underlying function call. A
* null argument indicates that no manual assignments are to be made.
@@ -340,8 +403,6 @@ public class CMethodBindingEmitter extends FunctionEmitter
Type cReturnType = binding.getCReturnType();
JavaType javaReturnType = binding.getJavaReturnType();
- String arrayResLength = "_array_res_length";
- String arrayRes = "_array_res";
String capitalizedComponentType = null;
if (!cReturnType.isVoid()) {
writer.print(" ");
@@ -349,24 +410,36 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.print(binding.getCSymbol().getReturnType().getName(true));
writer.println(" _res;");
if (javaReturnType.isArray()) {
- writer.print(" int ");
- writer.print(arrayResLength);
- writer.println(";");
+ if (javaReturnType.isNIOByteBufferArray()) {
+ writer.print(" int ");
+ writer.print(arrayResLength);
+ writer.println(";");
+ writer.print(" int ");
+ writer.print(arrayIdx);
+ writer.println(";");
+ writer.print(" jobjectArray ");
+ writer.print(arrayRes);
+ writer.println(";");
+ } else {
+ writer.print(" int ");
+ writer.print(arrayResLength);
+ writer.println(";");
- Class componentType = javaReturnType.getJavaClass().getComponentType();
- if (componentType.isArray()) {
- throw new RuntimeException("Multi-dimensional arrays not supported yet");
- }
+ Class componentType = javaReturnType.getJavaClass().getComponentType();
+ if (componentType.isArray()) {
+ throw new RuntimeException("Multi-dimensional arrays not supported yet");
+ }
- String javaTypeName = componentType.getName();
- capitalizedComponentType =
- "" + Character.toUpperCase(javaTypeName.charAt(0)) + javaTypeName.substring(1);
- String javaArrayTypeName = "j" + javaTypeName + "Array";
- writer.print(" ");
- writer.print(javaArrayTypeName);
- writer.print(" ");
- writer.print(arrayRes);
- writer.println(";");
+ String javaTypeName = componentType.getName();
+ capitalizedComponentType =
+ "" + Character.toUpperCase(javaTypeName.charAt(0)) + javaTypeName.substring(1);
+ String javaArrayTypeName = "j" + javaTypeName + "Array";
+ writer.print(" ");
+ writer.print(javaArrayTypeName);
+ writer.print(" ");
+ writer.print(arrayRes);
+ writer.println(";");
+ }
}
}
}
@@ -568,6 +641,11 @@ public class CMethodBindingEmitter extends FunctionEmitter
if (EMIT_NULL_CHECKS) {
writer.println(" }");
}
+ } else if (javaArgType.isArrayOfCompoundTypeWrappers()) {
+
+ // FIXME
+ throw new RuntimeException("Outgoing arrays of StructAccessors not yet implemented");
+
}
}
}
@@ -696,6 +774,11 @@ public class CMethodBindingEmitter extends FunctionEmitter
if (EMIT_NULL_CHECKS) {
writer.println(" }");
}
+ } else if (javaArgType.isArrayOfCompoundTypeWrappers()) {
+
+ // FIXME
+ throw new RuntimeException("Outgoing arrays of StructAccessors not yet implemented");
+
}
}
}
@@ -826,35 +909,63 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.print(" if (_res == NULL) return NULL;");
writer.println(" return (*env)->NewStringUTF(env, _res);");
} else if (javaReturnType.isArray()) {
- // FIXME: must have user provide length of array in .cfg file
- // by providing a constant value, input parameter, or
- // expression which computes the array size (already present
- // as ReturnValueCapacity, not yet implemented / tested here)
-
- throw new RuntimeException(
- "Could not emit native code for function \"" + binding +
- "\": array return values for non-char types not implemented yet");
-
- // FIXME: This is approximately what will be required here
- //
- //writer.print(" ");
- //writer.print(arrayRes);
- //writer.print(" = (*env)->New");
- //writer.print(capitalizedComponentType);
- //writer.print("Array(env, ");
- //writer.print(arrayResLength);
- //writer.println(");");
- //writer.print(" (*env)->Set");
- //writer.print(capitalizedComponentType);
- //writer.print("ArrayRegion(env, ");
- //writer.print(arrayRes);
- //writer.print(", 0, ");
- //writer.print(arrayResLength);
- //writer.println(", _res);");
- //writer.print(" return ");
- //writer.print(arrayRes);
- //writer.println(";");
-
+ if (javaReturnType.isNIOByteBufferArray()) {
+ writer.println(" if (_res == NULL) return NULL;");
+ if (returnValueLengthExpression == null) {
+ throw new RuntimeException("Error while generating C code: no length specified for array returned from function " +
+ binding);
+ }
+ String[] argumentNames = new String[binding.getNumArguments()];
+ for (int i = 0; i < binding.getNumArguments(); i++) {
+ argumentNames[i] = binding.getArgumentName(i);
+ }
+ writer.println(" " + arrayResLength + " = " + returnValueLengthExpression.format(argumentNames) + ";");
+ writer.println(" " + arrayRes + " = (*env)->NewObjectArray(env, " + arrayResLength + ", (*env)->FindClass(env, \"java/nio/ByteBuffer\"), NULL);");
+ writer.println(" for (" + arrayIdx + " = 0; " + arrayIdx + " < " + arrayResLength + "; " + arrayIdx + "++) {");
+ Type retType = binding.getCSymbol().getReturnType();
+ Type baseType;
+ if (retType.isPointer()) {
+ baseType = retType.asPointer().getTargetType().asPointer().getTargetType();
+ } else {
+ baseType = retType.asArray().getElementType().asPointer().getTargetType();
+ }
+ int sz = baseType.getSize();
+ if (sz < 0)
+ sz = 0;
+ writer.println(" (*env)->SetObjectArrayElement(env, " + arrayRes + ", " + arrayIdx +
+ ", (*env)->NewDirectByteBuffer(env, _res[" + arrayIdx + "], " + sz + "));");
+ writer.println(" }");
+ writer.println(" return " + arrayRes + ";");
+ } else {
+ // FIXME: must have user provide length of array in .cfg file
+ // by providing a constant value, input parameter, or
+ // expression which computes the array size (already present
+ // as ReturnValueCapacity, not yet implemented / tested here)
+
+ throw new RuntimeException(
+ "Could not emit native code for function \"" + binding +
+ "\": array return values for non-char types not implemented yet");
+
+ // FIXME: This is approximately what will be required here
+ //
+ //writer.print(" ");
+ //writer.print(arrayRes);
+ //writer.print(" = (*env)->New");
+ //writer.print(capitalizedComponentType);
+ //writer.print("Array(env, ");
+ //writer.print(arrayResLength);
+ //writer.println(");");
+ //writer.print(" (*env)->Set");
+ //writer.print(capitalizedComponentType);
+ //writer.print("ArrayRegion(env, ");
+ //writer.print(arrayRes);
+ //writer.print(", 0, ");
+ //writer.print(arrayResLength);
+ //writer.println(", _res);");
+ //writer.print(" return ");
+ //writer.print(arrayRes);
+ //writer.println(";");
+ }
}
}
}
@@ -1034,6 +1145,11 @@ public class CMethodBindingEmitter extends FunctionEmitter
throw new RuntimeException("Unsupported pointer type: \"" + cType.getName() + "\"");
}
}
+ else if (javaType.isArrayOfCompoundTypeWrappers())
+ {
+ // FIXME
+ throw new RuntimeException("Outgoing arrays of StructAccessors not yet implemented");
+ }
else
{
ptrTypeString = cType.getName();
diff --git a/src/net/java/games/gluegen/DebugEmitter.java b/src/net/java/games/gluegen/DebugEmitter.java
index 677c3e7e6..8618e1576 100644
--- a/src/net/java/games/gluegen/DebugEmitter.java
+++ b/src/net/java/games/gluegen/DebugEmitter.java
@@ -95,8 +95,13 @@ public class DebugEmitter implements GlueEmitter {
TypeDictionary structDictionary,
Map canonMap) {
}
- public void emitStruct(CompoundType t) {
- System.out.println("Referenced type \"" + t.getName() + "\"");
+ public void emitStruct(CompoundType t, String alternateName) {
+ String name = t.getName();
+ if (name == null && alternateName != null) {
+ name = alternateName;
+ }
+
+ System.out.println("Referenced type \"" + name + "\"");
}
public void endStructs() {}
}
diff --git a/src/net/java/games/gluegen/GlueEmitter.java b/src/net/java/games/gluegen/GlueEmitter.java
index 3d55474e0..e816ffc9d 100644
--- a/src/net/java/games/gluegen/GlueEmitter.java
+++ b/src/net/java/games/gluegen/GlueEmitter.java
@@ -93,7 +93,11 @@ public interface GlueEmitter {
public void beginStructs(TypeDictionary typedefDictionary,
TypeDictionary structDictionary,
Map canonMap) throws Exception;
- /** Emit glue code for the given CompoundType. */
- public void emitStruct(CompoundType t) throws Exception;
+ /** Emit glue code for the given CompoundType. alternateName is
+ provided when the CompoundType (e.g. "struct foo_t") has not
+ been typedefed to anything but the type of "pointer to struct
+ foo_t" has (e.g. "typedef struct foo_t {} *Foo"); in this case
+ alternateName would be set to Foo. */
+ public void emitStruct(CompoundType t, String alternateName) throws Exception;
public void endStructs() throws Exception;
}
diff --git a/src/net/java/games/gluegen/GlueGen.java b/src/net/java/games/gluegen/GlueGen.java
index 374611c81..2e5f3421a 100644
--- a/src/net/java/games/gluegen/GlueGen.java
+++ b/src/net/java/games/gluegen/GlueGen.java
@@ -241,20 +241,35 @@ public class GlueGen implements GlueEmitterControls {
System.err.println("WARNING: during forced struct emission: type \"" + name + "\" was not a struct");
} else {
type.visit(referencedStructs);
- }
+ }
}
// Lay out structs
emit.beginStructLayout();
for (Iterator iter = referencedStructs.results(); iter.hasNext(); ) {
- emit.layoutStruct((CompoundType) iter.next());
+ Type t = (Type) iter.next();
+ if (t.isCompound()) {
+ emit.layoutStruct(t.asCompound());
+ } else if (t.isPointer()) {
+ PointerType p = t.asPointer();
+ CompoundType c = p.getTargetType().asCompound();
+ emit.layoutStruct(c);
+ }
}
emit.endStructLayout();
// Emit structs
emit.beginStructs(td, sd, headerParser.getCanonMap());
for (Iterator iter = referencedStructs.results(); iter.hasNext(); ) {
- emit.emitStruct((CompoundType) iter.next());
+ Type t = (Type) iter.next();
+ if (t.isCompound()) {
+ emit.emitStruct(t.asCompound(), null);
+ } else if (t.isPointer()) {
+ PointerType p = t.asPointer();
+ CompoundType c = p.getTargetType().asCompound();
+ assert p.hasTypedefedName() && c.getName() == null : "ReferencedStructs incorrectly recorded pointer type " + p;
+ emit.emitStruct(c, p.getName());
+ }
}
emit.endStructs();
diff --git a/src/net/java/games/gluegen/JavaConfiguration.java b/src/net/java/games/gluegen/JavaConfiguration.java
index ecd953480..3950a7014 100644
--- a/src/net/java/games/gluegen/JavaConfiguration.java
+++ b/src/net/java/games/gluegen/JavaConfiguration.java
@@ -105,6 +105,7 @@ public class JavaConfiguration {
private List/*<String>*/ forcedStructs = new ArrayList();
private Map/*<String,List<Integer>>*/ mirroredArgs = new HashMap();
private Map/*<String, String>*/ returnValueCapacities = new HashMap();
+ private Map/*<String, String>*/ returnValueLengths = new HashMap();
private Map/*<String, List<String>>*/ temporaryCVariableDeclarations = new HashMap();
private Map/*<String, List<String>>*/ temporaryCVariableAssignments = new HashMap();
private Map/*<String,List<String>>*/ extendedInterfaces = new HashMap();
@@ -288,7 +289,9 @@ public class JavaConfiguration {
/** Provides a Java MessageFormat expression indicating the number
of elements in the returned array from the specified function
- name as defined by the ReturnsArray directive. */
+ name. Indicates that the given return value, which must be a
+ pointer to a CompoundType, is actually an array of the
+ CompoundType rather than a pointer to a single object. */
public String returnedArrayLength(String functionName) {
return (String) returnedArrayLengths.get(functionName);
}
@@ -378,6 +381,13 @@ public class JavaConfiguration {
return (String) returnValueCapacities.get(functionName);
}
+ /** Returns a MessageFormat string of the C expression calculating
+ the length of the array being returned from a native method, or
+ null if no expression has been specified. */
+ public String returnValueLength(String functionName) {
+ return (String) returnValueLengths.get(functionName);
+ }
+
/** Returns a List of Strings of expressions declaring temporary C
variables in the glue code for the specified function. */
public List/*<String>*/ temporaryCVariableDeclarations(String functionName) {
@@ -582,6 +592,10 @@ public class JavaConfiguration {
readReturnValueCapacity(tok, filename, lineNo);
// Warning: make sure delimiters are reset at the top of this loop
// because ReturnValueCapacity changes them.
+ } else if (cmd.equalsIgnoreCase("ReturnValueLength")) {
+ readReturnValueLength(tok, filename, lineNo);
+ // Warning: make sure delimiters are reset at the top of this loop
+ // because ReturnValueLength changes them.
} else if (cmd.equalsIgnoreCase("Include")) {
doInclude(tok, file, filename, lineNo);
} else if (cmd.equalsIgnoreCase("IncludeAs")) {
@@ -926,6 +940,18 @@ public class JavaConfiguration {
}
}
+ protected void readReturnValueLength(StringTokenizer tok, String filename, int lineNo) {
+ try {
+ String functionName = tok.nextToken();
+ String restOfLine = tok.nextToken("\n\r\f");
+ restOfLine = restOfLine.trim();
+ returnValueLengths.put(functionName, restOfLine);
+ } catch (NoSuchElementException e) {
+ throw new RuntimeException("Error parsing \"ReturnValueLength\" command at line " + lineNo +
+ " in file \"" + filename + "\"", e);
+ }
+ }
+
protected void readTemporaryCVariableDeclaration(StringTokenizer tok, String filename, int lineNo) {
try {
String functionName = tok.nextToken();
diff --git a/src/net/java/games/gluegen/JavaEmitter.java b/src/net/java/games/gluegen/JavaEmitter.java
index 228b5aff2..26e2a4f23 100644
--- a/src/net/java/games/gluegen/JavaEmitter.java
+++ b/src/net/java/games/gluegen/JavaEmitter.java
@@ -451,18 +451,26 @@ public class JavaEmitter implements GlueEmitter {
this.canonMap = canonMap;
}
- public void emitStruct(CompoundType structType) throws Exception {
- if (structType.getName() == null) {
+ public void emitStruct(CompoundType structType, String alternateName) throws Exception {
+ String name = structType.getName();
+ if (name == null && alternateName != null) {
+ name = alternateName;
+ }
+
+ if (name == null) {
System.err.println("WARNING: skipping emission of unnamed struct \"" + structType + "\"");
return;
}
- if (cfg.shouldIgnore(structType.getName())) {
+ if (cfg.shouldIgnore(name)) {
return;
}
Type containingCType = canonicalize(new PointerType(machDesc.pointerSizeInBytes(), structType, 0));
JavaType containingType = typeToJavaType(containingCType, false);
+ if (!containingType.isCompoundTypeWrapper()) {
+ return;
+ }
String containingTypeName = containingType.getName();
boolean needsNativeCode = false;
@@ -473,7 +481,7 @@ public class JavaEmitter implements GlueEmitter {
}
}
- String structClassPkg = cfg.packageForStruct(structType.getName());
+ String structClassPkg = cfg.packageForStruct(name);
PrintWriter writer = null;
PrintWriter cWriter = null;
try
@@ -534,7 +542,7 @@ public class JavaEmitter implements GlueEmitter {
for (int i = 0; i < structType.getNumFields(); i++) {
Field field = structType.getField(i);
Type fieldType = field.getType();
- if (!cfg.shouldIgnore(structType.getName() + " " + field.getName())) {
+ if (!cfg.shouldIgnore(name + " " + field.getName())) {
if (fieldType.isFunctionPointer()) {
try {
// Emit method call and associated native code
@@ -566,7 +574,7 @@ public class JavaEmitter implements GlueEmitter {
cWriter);
cEmitter.emit();
} catch (Exception e) {
- System.err.println("While processing field " + field + " of type " + structType.getName() + ":");
+ System.err.println("While processing field " + field + " of type " + name + ":");
throw(e);
}
} else if (fieldType.isCompound()) {
@@ -575,7 +583,7 @@ public class JavaEmitter implements GlueEmitter {
// a name?)
if (fieldType.getName() == null) {
throw new RuntimeException("Anonymous structs as fields not supported yet (field \"" +
- field + "\" in type \"" + structType.getName() + "\")");
+ field + "\" in type \"" + name + "\")");
}
writer.println();
@@ -586,7 +594,7 @@ public class JavaEmitter implements GlueEmitter {
// FIXME: add setter by autogenerating "copyTo" for all compound type wrappers
} else if (fieldType.isArray()) {
- System.err.println("WARNING: Array fields (field \"" + field + "\" of type \"" + structType.getName() +
+ System.err.println("WARNING: Array fields (field \"" + field + "\" of type \"" + name +
"\") not implemented yet");
} else {
JavaType javaType = null;
@@ -594,7 +602,7 @@ public class JavaEmitter implements GlueEmitter {
javaType = typeToJavaType(fieldType, false);
} catch (Exception e) {
System.err.println("Error occurred while creating accessor for field \"" +
- field.getName() + "\" in type \"" + structType.getName() + "\"");
+ field.getName() + "\" in type \"" + name + "\"");
e.printStackTrace();
throw(e);
}
@@ -629,10 +637,6 @@ public class JavaEmitter implements GlueEmitter {
writer.println(" }");
} else {
// FIXME
- String name = structType.getName();
- if (name == null) {
- name = structType.toString();
- }
System.err.println("WARNING: Complicated fields (field \"" + field + "\" of type \"" + name +
"\") not implemented yet");
// throw new RuntimeException("Complicated fields (field \"" + field + "\" of type \"" + t +
@@ -663,6 +667,7 @@ public class JavaEmitter implements GlueEmitter {
String bindingJavaClassName,
PrintWriter output) {
MessageFormat returnValueCapacityFormat = null;
+ MessageFormat returnValueLengthFormat = null;
JavaType javaReturnType = binding.getJavaReturnType();
if (javaReturnType.isNIOBuffer()) {
// See whether capacity has been specified
@@ -670,6 +675,12 @@ public class JavaEmitter implements GlueEmitter {
if (capacity != null) {
returnValueCapacityFormat = new MessageFormat(capacity);
}
+ } else if (javaReturnType.isArray()) {
+ // See whether length has been specified
+ String len = cfg.returnValueLength(binding.getName());
+ if (len != null) {
+ returnValueLengthFormat = new MessageFormat(len);
+ }
}
CMethodBindingEmitter cEmitter;
if (doingImplRoutine) {
@@ -686,6 +697,9 @@ public class JavaEmitter implements GlueEmitter {
if (returnValueCapacityFormat != null) {
cEmitter.setReturnValueCapacityExpression(returnValueCapacityFormat);
}
+ if (returnValueLengthFormat != null) {
+ cEmitter.setReturnValueLengthExpression(returnValueLengthFormat);
+ }
cEmitter.setTemporaryCVariableDeclarations(cfg.temporaryCVariableDeclarations(binding.getName()));
cEmitter.setTemporaryCVariableAssignments(cfg.temporaryCVariableAssignments(binding.getName()));
return cEmitter;
@@ -758,12 +772,21 @@ public class JavaEmitter implements GlueEmitter {
throw new RuntimeException("Arrays of compound types not handled yet");
}
// Special cases for known JNI types (in particular for converting jawt.h)
- if (cType.getName() != null &&
- cType.getName().equals("jobject")) {
+ if (t.getName() != null &&
+ t.getName().equals("jobject")) {
return javaType(java.lang.Object.class);
}
- return JavaType.createForCStruct(cfg.renameJavaType(targetType.getName()));
+ String name = targetType.getName();
+ if (name == null) {
+ // Try containing pointer type for any typedefs
+ name = t.getName();
+ if (name == null) {
+ throw new RuntimeException("Couldn't find a proper type name for pointer type " + t);
+ }
+ }
+
+ return JavaType.createForCStruct(cfg.renameJavaType(name));
} else {
throw new RuntimeException("Don't know how to convert pointer/array type \"" +
t + "\"");
@@ -775,15 +798,16 @@ public class JavaEmitter implements GlueEmitter {
// Get the target type of the target type (targetType was computer earlier
// as to be a pointer to the target type, so now we need to get its
// target type)
+ Type bottomType;
if (targetType.isPointer()) {
// t is<type>**, targetType is <type>*, we need to get <type>
- targetType = targetType.asPointer().getTargetType();
+ bottomType = targetType.asPointer().getTargetType();
} else {
// t is<type>[][], targetType is <type>[], we need to get <type>
- targetType = targetType.asArray().getElementType();
+ bottomType = targetType.asArray().getElementType();
}
- if (targetType.isInt()) {
- switch (targetType.getSize())
+ if (bottomType.isInt()) {
+ switch (bottomType.getSize())
{
case 1: return javaType(ArrayTypes.byteArrayArrayClass);
// FIXME: handle 2,4,8-byte int types here
@@ -793,10 +817,13 @@ public class JavaEmitter implements GlueEmitter {
"Java type; Currently, the only supported depth=2 " +
"pointer/array integer types are \"char**\" and \"char[][]\"");
}
+ } else if (targetType.isPointer() && (targetType.pointerDepth() == 1)) {
+ // Array of pointers; convert as array of StructAccessors
+ return JavaType.createForCArray(targetType);
} else {
throw new RuntimeException(
"Could not convert C type \"" + t + "\" " +
- "to appropriate Java type; need to add support for " +
+ "to appropriate Java type; need to add more support for " +
"depth=2 pointer/array types with non-integral target " +
"types [debug info: targetType=\"" + targetType + "\"]");
}
diff --git a/src/net/java/games/gluegen/JavaMethodBindingEmitter.java b/src/net/java/games/gluegen/JavaMethodBindingEmitter.java
index 003ea8643..850a2c701 100644
--- a/src/net/java/games/gluegen/JavaMethodBindingEmitter.java
+++ b/src/net/java/games/gluegen/JavaMethodBindingEmitter.java
@@ -122,7 +122,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
}
protected String getReturnTypeString(boolean skipArray) {
- if (skipArray || getReturnedArrayLengthExpression() == null) {
+ if (skipArray || (getReturnedArrayLengthExpression() == null && !binding.getJavaReturnType().isArrayOfCompoundTypeWrappers())) {
return binding.getJavaReturnType().getName();
}
return binding.getJavaReturnType().getName() + "[]";
diff --git a/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java b/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java
index 2357e7c38..2ec2723bd 100644
--- a/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java
+++ b/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java
@@ -113,6 +113,9 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter
returnType.isNIOByteBuffer()) {
writer.println("ByteBuffer _res;");
writer.print(" _res = ");
+ } else if (returnType.isArrayOfCompoundTypeWrappers()) {
+ writer.println("ByteBuffer[] _res;");
+ writer.print(" _res = ");
} else {
writer.print("return ");
}
@@ -205,7 +208,7 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter
writer.println(" _tmp.order(ByteOrder.nativeOrder());");
writer.println(" _res.position(0);");
writer.println(" _res.limit(_res.capacity());");
- writer.println(" _retarray[_count] = new " + returnType.getName() + "(_tmp);");
+ writer.println(" _retarray[_count] = new " + getReturnTypeString(true) + "(_tmp);");
writer.println(" }");
writer.print (" return _retarray");
}
@@ -213,6 +216,14 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter
writer.println(";");
writer.println(" if (_res == null) return null;");
writer.print(" return _res.order(ByteOrder.nativeOrder())");
+ } else if (returnType.isArrayOfCompoundTypeWrappers()) {
+ writer.println(";");
+ writer.println(" if (_res == null) return null;");
+ writer.println(" " + getReturnTypeString(false) + " _retarray = new " + getReturnTypeString(true) + "[_res.length];");
+ writer.println(" for (int _count = 0; _count < _res.length; _count++) {");
+ writer.println(" _retarray[_count] = new " + getReturnTypeString(true) + "(_res[_count]);");
+ writer.println(" }");
+ writer.print (" return _retarray");
}
writer.println(";");
}
diff --git a/src/net/java/games/gluegen/JavaType.java b/src/net/java/games/gluegen/JavaType.java
index ac42aa0f1..ea771613e 100644
--- a/src/net/java/games/gluegen/JavaType.java
+++ b/src/net/java/games/gluegen/JavaType.java
@@ -39,6 +39,10 @@
package net.java.games.gluegen;
+import java.nio.*;
+
+import net.java.games.gluegen.cgram.types.*;
+
/**
* Describes a java-side representation of a type that is used to represent
* the same data on both the Java-side and C-side during a JNI operation. Also
@@ -47,8 +51,10 @@ package net.java.games.gluegen;
public class JavaType {
private Class clazz; // Primitive types and other types representable as Class objects
private String name; // Types we're generating glue code for (i.e., C structs)
+ private Type elementType; // Element type if this JavaType represents a C array
private static JavaType nioBufferType;
private static JavaType nioByteBufferType;
+ private static JavaType nioByteBufferArrayType;
public boolean equals(Object arg) {
if ((arg == null) || (!(arg instanceof JavaType))) {
@@ -70,14 +76,28 @@ public class JavaType {
return clazz.hashCode();
}
+ /** Creates a JavaType corresponding to the given Java type. This
+ can be used to represent arrays of primitive values or Strings;
+ the emitters understand how to perform proper conversion from
+ the corresponding C type. */
public static JavaType createForClass(Class clazz) {
return new JavaType(clazz);
}
+ /** Creates a JavaType corresponding to the specified C CompoundType
+ name; for example, if "Foo" is supplied, then this JavaType
+ represents a "Foo *" by way of a StructAccessor. */
public static JavaType createForCStruct(String name) {
return new JavaType(name);
}
+ /** Creates a JavaType corresponding to an array of the given
+ element type. This is used to represent arrays of "Foo **" which
+ should be mapped to Foo[] in Java. */
+ public static JavaType createForCArray(Type elementType) {
+ return new JavaType(elementType);
+ }
+
public static JavaType createForVoidPointer() {
return new JavaType();
}
@@ -100,6 +120,14 @@ public class JavaType {
return nioByteBufferType;
}
+ public static JavaType forNIOByteBufferArrayClass() {
+ if (nioByteBufferArrayType == null) {
+ ByteBuffer[] tmp = new ByteBuffer[0];
+ nioByteBufferArrayType = createForClass(tmp.getClass());
+ }
+ return nioByteBufferArrayType;
+ }
+
/**
* Returns the Java Class corresponding to this type. Returns null if this
* object corresponds to a C "void*" type.
@@ -119,6 +147,9 @@ public class JavaType {
}
return clazz.getName();
}
+ if (elementType != null) {
+ return elementType.getName();
+ }
return name;
}
@@ -151,6 +182,10 @@ public class JavaType {
return "jobjectArray /*elements are String*/";
//return "jobjectArray";
}
+ else if (elementType == java.nio.ByteBuffer.class)
+ {
+ return "jobjectArray /*elements are ByteBuffer*/";
+ }
else if (elementType.isArray())
{
// Type is array-of-arrays-of-something
@@ -189,6 +224,10 @@ public class JavaType {
return (clazz == java.nio.ByteBuffer.class);
}
+ public boolean isNIOByteBufferArray() {
+ return (this == nioByteBufferArrayType);
+ }
+
public boolean isString() {
return (clazz == java.lang.String.class);
}
@@ -205,17 +244,16 @@ public class JavaType {
return (clazz == Void.TYPE);
}
- public boolean isObjectType() {
- // FIXME: what about char* -> String conversion?
- return (isNIOBuffer() || isArray());
- }
-
public boolean isCompoundTypeWrapper() {
return (clazz == null && name != null && !isJNIEnv());
}
+ public boolean isArrayOfCompoundTypeWrappers() {
+ return (elementType != null);
+ }
+
public boolean isVoidPointerType() {
- return (clazz == null && name == null);
+ return (clazz == null && name == null && elementType == null);
}
public boolean isJNIEnv() {
@@ -252,6 +290,11 @@ public class JavaType {
this.name = name;
}
+ /** Constructs a type representing an array of C pointers. */
+ private JavaType(Type elementType) {
+ this.elementType = elementType;
+ }
+
/**
* Default constructor; the type is initialized to the equivalent of a
* C-language "void *".
diff --git a/src/net/java/games/gluegen/MethodBinding.java b/src/net/java/games/gluegen/MethodBinding.java
index 9cdcd4b0b..b8f0eefdf 100644
--- a/src/net/java/games/gluegen/MethodBinding.java
+++ b/src/net/java/games/gluegen/MethodBinding.java
@@ -174,7 +174,8 @@ public class MethodBinding {
public boolean needsBody() {
if (!computedNeedsBody) {
if (javaReturnType.isCompoundTypeWrapper() ||
- javaReturnType.isNIOByteBuffer()) {
+ javaReturnType.isNIOByteBuffer() ||
+ javaReturnType.isArrayOfCompoundTypeWrappers()) {
// Needs wrapping and/or setting of byte order (neither of
// which can be done easily from native code)
needsBody = true;
@@ -204,6 +205,8 @@ public class MethodBinding {
binding.thisPointerIndex = thisPointerIndex;
if (javaReturnType.isCompoundTypeWrapper()) {
binding.setJavaReturnType(JavaType.forNIOByteBufferClass());
+ } else if (javaReturnType.isArrayOfCompoundTypeWrappers()) {
+ binding.setJavaReturnType(JavaType.forNIOByteBufferArrayClass());
} else {
binding.setJavaReturnType(javaReturnType);
}
diff --git a/src/net/java/games/gluegen/ReferencedStructs.java b/src/net/java/games/gluegen/ReferencedStructs.java
index 1b3b75198..4a7a8aadf 100644
--- a/src/net/java/games/gluegen/ReferencedStructs.java
+++ b/src/net/java/games/gluegen/ReferencedStructs.java
@@ -54,7 +54,18 @@ public class ReferencedStructs implements TypeVisitor {
}
public void visitType(Type t) {
- if (t.isCompound()) {
+ if (t.isPointer()) {
+ PointerType p = t.asPointer();
+ if (p.hasTypedefedName()) {
+ CompoundType c = p.getTargetType().asCompound();
+ if (c != null && c.getName() == null) {
+ // This otherwise-unnamed CompoundType is referred to by a
+ // PointerType that has a typedef name. Assume that it is
+ // referred to in the glue code and emit it.
+ results.add(p);
+ }
+ }
+ } else if (t.isCompound()) {
results.add(t);
}
}
diff --git a/src/net/java/games/gluegen/cgram/types/PointerType.java b/src/net/java/games/gluegen/cgram/types/PointerType.java
index 62bfe9c1a..64acbade4 100644
--- a/src/net/java/games/gluegen/cgram/types/PointerType.java
+++ b/src/net/java/games/gluegen/cgram/types/PointerType.java
@@ -100,6 +100,10 @@ public class PointerType extends Type {
}
}
+ public boolean hasTypedefedName() {
+ return hasTypedefedName;
+ }
+
public PointerType asPointer() { return this; }
public Type getTargetType() { return targetType; }
diff --git a/src/net/java/games/gluegen/opengl/BuildComposablePipeline.java b/src/net/java/games/gluegen/opengl/BuildComposablePipeline.java
index 47476a54c..c6ac77c7b 100644
--- a/src/net/java/games/gluegen/opengl/BuildComposablePipeline.java
+++ b/src/net/java/games/gluegen/opengl/BuildComposablePipeline.java
@@ -209,7 +209,7 @@ public class BuildComposablePipeline
{
output.print(" public ");
output.print(' ');
- output.print(m.getReturnType().getName());
+ output.print(JavaType.createForClass(m.getReturnType()).getName());
output.print(' ');
output.print(m.getName());
output.print('(');
diff --git a/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java b/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java
index cd0554dc3..2a1559e52 100644
--- a/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java
+++ b/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java
@@ -68,6 +68,15 @@ public class CGLPAWrapperEmitter extends CMethodBindingEmitter
methodToWrap.getIsJavaMethodStatic(),
methodToWrap.getDefaultOutput()
);
+
+ if (methodToWrap.getReturnValueCapacityExpression() != null) {
+ setReturnValueCapacityExpression(methodToWrap.getReturnValueCapacityExpression());
+ }
+ if (methodToWrap.getReturnValueLengthExpression() != null) {
+ setReturnValueLengthExpression(methodToWrap.getReturnValueLengthExpression());
+ }
+ setTemporaryCVariableDeclarations(methodToWrap.getTemporaryCVariableDeclarations());
+ setTemporaryCVariableAssignments (methodToWrap.getTemporaryCVariableAssignments ());
setCommentEmitter(defaultCommentEmitter);
}
@@ -192,6 +201,13 @@ public class CGLPAWrapperEmitter extends CMethodBindingEmitter
writer.println(");");
}
+ protected String jniMangle(MethodBinding binding) {
+ StringBuffer buf = new StringBuffer();
+ buf.append(super.jniMangle(binding));
+ jniMangle(Long.TYPE, buf);
+ return buf.toString();
+ }
+
/** This class emits the comment for the wrapper method */
private static class CGLPAWrapperCommentEmitter extends CMethodBindingEmitter.DefaultCommentEmitter {
protected void emitBeginning(FunctionEmitter methodEmitter, PrintWriter writer) {
diff --git a/src/net/java/games/gluegen/opengl/GLEmitter.java b/src/net/java/games/gluegen/opengl/GLEmitter.java
index 27cc07e2c..f6e26fd3b 100644
--- a/src/net/java/games/gluegen/opengl/GLEmitter.java
+++ b/src/net/java/games/gluegen/opengl/GLEmitter.java
@@ -44,6 +44,7 @@ import java.text.MessageFormat;
import java.util.*;
import net.java.games.gluegen.*;
import net.java.games.gluegen.cgram.types.*;
+import net.java.games.gluegen.runtime.*;
/**
* A subclass of JavaEmitter that modifies the normal emission of C and Java
@@ -52,11 +53,12 @@ import net.java.games.gluegen.cgram.types.*;
*/
public class GLEmitter extends JavaEmitter
{
- public static final String PROCADDRESS_VAR_PREFIX = "_addressof_";
+ public static final String PROCADDRESS_VAR_PREFIX = ProcAddressHelper.PROCADDRESS_VAR_PREFIX;
protected static final String WRAP_PREFIX = "dispatch_";
private TypeDictionary typedefDictionary;
private PrintWriter tableWriter;
- private String tableClassName = "ProcAddressTable";
+ private String tableClassPackage;
+ private String tableClassName;
private int numProcAddressEntries;
public void beginFunctions(TypeDictionary typedefDictionary,
@@ -70,7 +72,7 @@ public class GLEmitter extends JavaEmitter
cWriter().println();
}
- if (((GLConfiguration)getConfig()).emitProcAddressTable())
+ if (getGLConfig().emitProcAddressTable())
{
beginGLProcAddressTable();
}
@@ -79,7 +81,7 @@ public class GLEmitter extends JavaEmitter
public void endFunctions() throws Exception
{
- if (((GLConfiguration)getConfig()).emitProcAddressTable())
+ if (getGLConfig().emitProcAddressTable())
{
endGLProcAddressTable();
}
@@ -118,7 +120,7 @@ public class GLEmitter extends JavaEmitter
// 9 is default # expanded bindings for void*
ArrayList modifiedEmitters = new ArrayList(9);
- if (((GLConfiguration)getConfig()).emitProcAddressTable())
+ if (getGLConfig().emitProcAddressTable())
{
// emit an entry in the GL proc address table for this method.
emitGLProcAddressTableEntryForSymbol(sym);
@@ -185,7 +187,7 @@ public class GLEmitter extends JavaEmitter
return null;
return baseJavaEmitter;
}
- return new JavaGLPAWrapperEmitter(baseJavaEmitter);
+ return new JavaGLPAWrapperEmitter(baseJavaEmitter, getGLConfig().getProcAddressTableExpr());
}
private CMethodBindingEmitter generateModifiedEmitter(CMethodBindingEmitter baseCEmitter)
@@ -205,11 +207,17 @@ public class GLEmitter extends JavaEmitter
{
String symName = sym.getName();
+ GLConfiguration config = getGLConfig();
+
// We should only wrap the GL symbol if its function pointer typedef has
// been defined (most likely in glext.h).
String funcPointerTypedefName = getGLFunctionPointerTypedefName(sym);
boolean shouldWrap = typedefDictionary.containsKey(funcPointerTypedefName);
//System.err.println(funcPointerTypedefName + " defined: " + shouldWrap);
+
+ if (config.skipProcAddressGen(symName)) {
+ shouldWrap = false;
+ }
if (!shouldWrap)
{
@@ -221,26 +229,27 @@ public class GLEmitter extends JavaEmitter
private void beginGLProcAddressTable() throws Exception
{
- String implPackageName = getImplPackageName();
+ tableClassPackage = getGLConfig().tableClassPackage();
+ tableClassName = getGLConfig().tableClassName();
+
+ // Table defaults to going into the impl directory unless otherwise overridden
+ String implPackageName = tableClassPackage;
+ if (implPackageName == null) {
+ implPackageName = getImplPackageName();
+ }
String jImplRoot =
getJavaOutputDir() + File.separator +
CodeGenUtils.packageAsPath(implPackageName);
- // HACK: until we have a way to make the impl dir different from the
- // WindowsGLImpl dir and the interface dir
- //tableWriter = openFile(jImplRoot + File.separator + tableClassName + ".java");
- File tmpFile = new File(jImplRoot);
- tmpFile = tmpFile.getParentFile();
- tmpFile = new File(tmpFile, tableClassName + ".java");
- tableWriter = openFile(tmpFile.getPath());
- // tableWriter = openFile(jImplRoot + File.separator + ".." + File.separator + tableClassName + ".java");
+ tableWriter = openFile(jImplRoot + File.separator + tableClassName + ".java");
CodeGenUtils.emitAutogeneratedWarning(tableWriter, this);
- // HACK: until we have a way to make the impl dir different from the
- // WindowsGLImpl dir and the interface dir
- //tableWriter.println("package " + implPackageName + ";");
- tableWriter.println("package " + getJavaPackageName() + ".impl;");
+ tableWriter.println("package " + implPackageName + ";");
+ tableWriter.println();
+ for (Iterator iter = getConfig().imports().iterator(); iter.hasNext(); ) {
+ tableWriter.println("import " + ((String) iter.next()) + ";");
+ }
tableWriter.println();
tableWriter.println("/**");
tableWriter.println(" * This table is a cache of the native pointers to OpenGL extension");
@@ -260,9 +269,6 @@ public class GLEmitter extends JavaEmitter
private void endGLProcAddressTable() throws Exception
{
PrintWriter w = tableWriter;
- w.print(" protected static long __PROCADDRESSINDEX__LASTINDEX = ");
- w.print(numProcAddressEntries-1);
- w.println(';');
w.println();
w.println(" /**");
@@ -301,30 +307,69 @@ public class GLEmitter extends JavaEmitter
private void emitGLProcAddressTableEntryForSymbol(FunctionSymbol cFunc)
{
- tableWriter.print(" public static long ");
+ tableWriter.print(" public long ");
tableWriter.print(PROCADDRESS_VAR_PREFIX);
tableWriter.print(cFunc.getName());
tableWriter.println(";");
++numProcAddressEntries;
}
+ private GLConfiguration getGLConfig() {
+ return (GLConfiguration) getConfig();
+ }
+
protected static class GLConfiguration extends JavaConfiguration
{
private boolean emitProcAddressTable = false;
-
+ private String tableClassPackage;
+ private String tableClassName = "ProcAddressTable";
+ private Set/*<String>*/ skipProcAddressGen = new HashSet();
+ private String getProcAddressTableExpr = "context.getGLProcAddressTable()";
+
protected void dispatch(String cmd, StringTokenizer tok, File file, String filename, int lineNo) throws IOException {
if (cmd.equalsIgnoreCase("EmitProcAddressTable"))
{
emitProcAddressTable =
readBoolean("EmitProcAddressTable", tok, filename, lineNo).booleanValue();
}
+ else if (cmd.equalsIgnoreCase("ProcAddressTablePackage"))
+ {
+ tableClassPackage = readString("ProcAddressTablePackage", tok, filename, lineNo);
+ }
+ else if (cmd.equalsIgnoreCase("ProcAddressTableClassName"))
+ {
+ tableClassName = readString("ProcAddressTableClassName", tok, filename, lineNo);
+ }
+ else if (cmd.equalsIgnoreCase("SkipProcAddressGen"))
+ {
+ String sym = readString("SkipProcAddressGen", tok, filename, lineNo);
+ skipProcAddressGen.add(sym);
+ }
+ else if (cmd.equalsIgnoreCase("GetProcAddressTableExpr"))
+ {
+ getProcAddressTableExpr = readGetProcAddressTableExpr(tok, filename, lineNo);
+ }
else
{
super.dispatch(cmd,tok,file,filename,lineNo);
}
}
- public boolean emitProcAddressTable() { return emitProcAddressTable; }
+ protected String readGetProcAddressTableExpr(StringTokenizer tok, String filename, int lineNo) {
+ try {
+ String restOfLine = tok.nextToken("\n\r\f");
+ return restOfLine.trim();
+ } catch (NoSuchElementException e) {
+ throw new RuntimeException("Error parsing \"GetProcAddressTableExpr\" command at line " + lineNo +
+ " in file \"" + filename + "\"", e);
+ }
+ }
+
+ public boolean emitProcAddressTable() { return emitProcAddressTable; }
+ public String tableClassPackage() { return tableClassPackage; }
+ public String tableClassName() { return tableClassName; }
+ public boolean skipProcAddressGen (String name) { return skipProcAddressGen.contains(name); }
+ public String getProcAddressTableExpr() { return getProcAddressTableExpr; }
} // end class GLConfiguration
}
diff --git a/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java b/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java
index e0a098f2a..c3b17f6cb 100644
--- a/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java
+++ b/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java
@@ -50,10 +50,12 @@ public class JavaGLPAWrapperEmitter extends JavaMethodBindingImplEmitter
new WrappedMethodCommentEmitter();
private JavaMethodBindingEmitter emitterBeingWrapped;
+ private String getProcAddressTableExpr;
- public JavaGLPAWrapperEmitter(JavaMethodBindingEmitter methodToWrap)
+ public JavaGLPAWrapperEmitter(JavaMethodBindingEmitter methodToWrap, String getProcAddressTableExpr)
{
super(methodToWrap.getBinding(), methodToWrap.getDefaultOutput(), methodToWrap.getRuntimeExceptionType());
+ this.getProcAddressTableExpr = getProcAddressTableExpr;
if (methodToWrap.getBinding().hasContainingType())
{
@@ -119,6 +121,9 @@ public class JavaGLPAWrapperEmitter extends JavaMethodBindingImplEmitter
// Now make our binding use the original access of the wrapped method
this.addModifier(origAccess);
+ if (emitterBeingWrapped.hasModifier(STATIC)) {
+ this.addModifier(STATIC);
+ }
}
protected boolean needsBody() {
@@ -152,9 +157,7 @@ public class JavaGLPAWrapperEmitter extends JavaMethodBindingImplEmitter
String procAddressVariable =
GLEmitter.PROCADDRESS_VAR_PREFIX + wrappedBinding.getName();
- writer.print(" final long addr = context.getGLProcAddressTable().");
- writer.print(procAddressVariable);
- writer.println(';');
+ writer.println(" final long addr = " + getProcAddressTableExpr + "." + procAddressVariable + ";");
writer.println(" if (addr == 0) {");
writer.println(" throw new GLException(\"Method \\\"" + binding.getName() + "\\\" not available\");");
writer.println(" }");
diff --git a/src/net/java/games/gluegen/runtime/ProcAddressHelper.java b/src/net/java/games/gluegen/runtime/ProcAddressHelper.java
new file mode 100644
index 000000000..fec0eb366
--- /dev/null
+++ b/src/net/java/games/gluegen/runtime/ProcAddressHelper.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution 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 Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.runtime;
+
+/** Contains constants used in glue code generation. */
+
+public class ProcAddressHelper {
+ public static final String PROCADDRESS_VAR_PREFIX = "_addressof_";
+}
diff --git a/src/net/java/games/jogl/impl/GLContext.java b/src/net/java/games/jogl/impl/GLContext.java
index 98b1c6065..eb7d21988 100644
--- a/src/net/java/games/jogl/impl/GLContext.java
+++ b/src/net/java/games/jogl/impl/GLContext.java
@@ -42,6 +42,7 @@ package net.java.games.jogl.impl;
import java.awt.Component;
import java.awt.EventQueue;
import net.java.games.jogl.*;
+import net.java.games.gluegen.runtime.*;
public abstract class GLContext {
protected static final boolean DEBUG = false;
@@ -75,8 +76,10 @@ public abstract class GLContext {
// All GLU interfaces eventually route calls down to gluRoot. It can be
// static because GLU it doesn't actually need to own context, it just makes
// GL calls and assumes some context is active.
- protected static final GLU gluRoot = new GLUImpl();
- protected static GLU glu = gluRoot; // this is the context's GLU interface
+ protected static final GLUProcAddressTable gluProcAddressTable = new GLUProcAddressTable();
+ protected static final GLU gluRoot = new GLUImpl(gluProcAddressTable);
+ protected static boolean haveResetGLUProcAddressTable;
+ protected GLU glu = gluRoot; // this is the context's GLU interface
protected Thread renderingThread;
protected Runnable deferredReshapeAction;
@@ -282,6 +285,13 @@ public abstract class GLContext {
*/
protected void resetGLFunctionAvailability() {
functionAvailability.flush();
+ if (!haveResetGLUProcAddressTable) {
+ if (DEBUG) {
+ System.err.println("!!! Initializing GLU extension address table");
+ }
+ resetProcAddressTable(gluProcAddressTable);
+ haveResetGLUProcAddressTable = true; // Only need to do this once globally
+ }
}
/**
@@ -391,6 +401,40 @@ public abstract class GLContext {
conditions cause a GLException to be thrown. */
protected abstract void swapBuffers() throws GLException;
+ /** Helper routine which resets a ProcAddressTable generated by the
+ GLEmitter by looking up anew all of its function pointers. */
+ protected void resetProcAddressTable(Object table) {
+ Class tableClass = table.getClass();
+ java.lang.reflect.Field[] fields = tableClass.getDeclaredFields();
+
+ for (int i = 0; i < fields.length; ++i) {
+ String addressFieldName = fields[i].getName();
+ if (!addressFieldName.startsWith(ProcAddressHelper.PROCADDRESS_VAR_PREFIX)) {
+ // not a proc address variable
+ continue;
+ }
+ int startOfMethodName = ProcAddressHelper.PROCADDRESS_VAR_PREFIX.length();
+ String glFuncName = addressFieldName.substring(startOfMethodName);
+ try {
+ java.lang.reflect.Field addressField = tableClass.getDeclaredField(addressFieldName);
+ assert(addressField.getType() == Long.TYPE);
+ long newProcAddress = dynamicLookupFunction(glFuncName);
+ // set the current value of the proc address variable in the table object
+ addressField.setLong(table, newProcAddress);
+ if (DEBUG) {
+ System.err.println(glFuncName + " = 0x" + Long.toHexString(newProcAddress));
+ }
+ } catch (Exception e) {
+ throw new GLException("Cannot get GL proc address for method \"" +
+ glFuncName + "\": Couldn't set value of field \"" + addressFieldName +
+ "\" in class " + tableClass.getName(), e);
+ }
+ }
+ }
+
+ /** Dynamically looks up the given function. */
+ protected abstract long dynamicLookupFunction(String glFuncName);
+
//----------------------------------------------------------------------
// Internals only below this point
//
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
index 23367c045..d35392ac1 100644
--- a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
@@ -41,7 +41,7 @@ package net.java.games.jogl.impl.macosx;
import java.awt.Component;
import java.util.*;
-import net.java.games.gluegen.opengl.*; // for PROCADDRESS_VAR_PREFIX
+import net.java.games.gluegen.runtime.*; // for PROCADDRESS_VAR_PREFIX
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
@@ -49,6 +49,9 @@ public abstract class MacOSXGLContext extends GLContext
{
private static JAWT jawt;
protected long nsContext; // NSOpenGLContext
+ // Table that holds the addresses of the native C-language entry points for
+ // OpenGL functions.
+ private GLProcAddressTable glProcAddressTable;
public MacOSXGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser)
{
@@ -90,74 +93,25 @@ public abstract class MacOSXGLContext extends GLContext
protected abstract void swapBuffers() throws GLException;
+ protected long dynamicLookupFunction(String glFuncName) {
+ return CGL.getProcAddress(glFuncName);
+ }
protected void resetGLFunctionAvailability()
{
super.resetGLFunctionAvailability();
- resetGLProcAddressTable();
- }
-
- protected void resetGLProcAddressTable()
- {
if (DEBUG) {
System.err.println("!!! Initializing OpenGL extension address table");
}
-
- net.java.games.jogl.impl.ProcAddressTable table = getGLProcAddressTable();
-
- // if GL is no longer an interface, we'll have to re-implement the code
- // below so it only iterates through gl methods (a non-interface might
- // have constructors, custom methods, etc). For now we assume all methods
- // will be gl methods.
- GL gl = getGL();
-
- Class tableClass = table.getClass();
-
- java.lang.reflect.Field[] fields = tableClass.getDeclaredFields();
-
- for (int i = 0; i < fields.length; ++i) {
- String addressFieldName = fields[i].getName();
- if (!addressFieldName.startsWith(GLEmitter.PROCADDRESS_VAR_PREFIX))
- {
- // not a proc address variable
- continue;
- }
- int startOfMethodName = GLEmitter.PROCADDRESS_VAR_PREFIX.length();
- String glFuncName = addressFieldName.substring(startOfMethodName);
- try
- {
- java.lang.reflect.Field addressField = tableClass.getDeclaredField(addressFieldName);
- assert(addressField.getType() == Long.TYPE);
- // get the current value of the proc address variable in the table object
- long oldProcAddress = addressField.getLong(table);
- long newProcAddress = CGL.getProcAddress(glFuncName);
- /*
- System.err.println(
- "!!! Address=" + (newProcAddress == 0
- ? "<NULL> "
- : ("0x" +
- Long.toHexString(newProcAddress))) +
- "\tGL func: " + glFuncName);
- */
- // set the current value of the proc address variable in the table object
- addressField.setLong(gl, newProcAddress);
- } catch (Exception e) {
- throw new GLException(
- "Cannot get GL proc address for method \"" +
- glFuncName + "\": Couldn't get value of field \"" + addressFieldName +
- "\" in class " + tableClass.getName(), e);
- }
- }
-
+ resetProcAddressTable(getGLProcAddressTable());
}
- public net.java.games.jogl.impl.ProcAddressTable getGLProcAddressTable()
+ public GLProcAddressTable getGLProcAddressTable()
{
if (glProcAddressTable == null) {
// FIXME: cache ProcAddressTables by capability bits so we can
// share them among contexts with the same capabilities
- glProcAddressTable =
- new net.java.games.jogl.impl.ProcAddressTable();
+ glProcAddressTable = new GLProcAddressTable();
}
return glProcAddressTable;
}
@@ -171,10 +125,6 @@ public abstract class MacOSXGLContext extends GLContext
// Internals only below this point
//
- // Table that holds the addresses of the native C-language entry points for
- // OpenGL functions.
- private net.java.games.jogl.impl.ProcAddressTable glProcAddressTable;
-
protected JAWT getJAWT()
{
if (jawt == null)
diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
index 4575b6210..5a6021acf 100644
--- a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
+++ b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
@@ -41,7 +41,7 @@ package net.java.games.jogl.impl.windows;
import java.awt.Component;
import java.util.*;
-import net.java.games.gluegen.opengl.*; // for PROCADDRESS_VAR_PREFIX
+import net.java.games.gluegen.runtime.*; // for PROCADDRESS_VAR_PREFIX
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
@@ -53,6 +53,11 @@ public abstract class WindowsGLContext extends GLContext {
private boolean wglGetExtensionsStringEXTAvailable;
private static final Map/*<String, String>*/ functionNameMap;
private static final Map/*<String, String>*/ extensionNameMap;
+ // Table that holds the addresses of the native C-language entry points for
+ // OpenGL functions.
+ private GLProcAddressTable glProcAddressTable;
+ // Handle to GLU32.dll
+ private long hglu32;
static {
functionNameMap = new HashMap();
@@ -132,72 +137,34 @@ public abstract class WindowsGLContext extends GLContext {
protected abstract void swapBuffers() throws GLException;
+ protected long dynamicLookupFunction(String glFuncName) {
+ long res = WGL.wglGetProcAddress(glFuncName);
+ if (res == 0) {
+ // GLU routines aren't known to the OpenGL function lookup
+ if (hglu32 == 0) {
+ hglu32 = WGL.LoadLibraryA("GLU32");
+ if (hglu32 == 0) {
+ throw new GLException("Error loading GLU32.DLL");
+ }
+ }
+ res = WGL.GetProcAddress(hglu32, glFuncName);
+ }
+ return res;
+ }
protected void resetGLFunctionAvailability() {
super.resetGLFunctionAvailability();
- resetGLProcAddressTable();
- }
-
- protected void resetGLProcAddressTable() {
-
if (DEBUG) {
System.err.println("!!! Initializing OpenGL extension address table");
}
-
- net.java.games.jogl.impl.ProcAddressTable table = getGLProcAddressTable();
-
- // if GL is no longer an interface, we'll have to re-implement the code
- // below so it only iterates through gl methods (a non-interface might
- // have constructors, custom methods, etc). For now we assume all methods
- // will be gl methods.
- GL gl = getGL();
-
- Class tableClass = table.getClass();
-
- java.lang.reflect.Field[] fields = tableClass.getDeclaredFields();
-
- for (int i = 0; i < fields.length; ++i) {
- String addressFieldName = fields[i].getName();
- if (!addressFieldName.startsWith(GLEmitter.PROCADDRESS_VAR_PREFIX))
- {
- // not a proc address variable
- continue;
- }
- int startOfMethodName = GLEmitter.PROCADDRESS_VAR_PREFIX.length();
- String glFuncName = addressFieldName.substring(startOfMethodName);
- try
- {
- java.lang.reflect.Field addressField = tableClass.getDeclaredField(addressFieldName);
- assert(addressField.getType() == Long.TYPE);
- // get the current value of the proc address variable in the table object
- long oldProcAddress = addressField.getLong(table);
- long newProcAddress = WGL.wglGetProcAddress(glFuncName);
- /*
- System.err.println(
- "!!! Address=" + (newProcAddress == 0
- ? "<NULL> "
- : ("0x" +
- Long.toHexString(newProcAddress))) +
- "\tGL func: " + glFuncName);
- */
- // set the current value of the proc address variable in the table object
- addressField.setLong(gl, newProcAddress);
- } catch (Exception e) {
- throw new GLException(
- "Cannot get GL proc address for method \"" +
- glFuncName + "\": Couldn't get value of field \"" + addressFieldName +
- "\" in class " + tableClass.getName(), e);
- }
- }
-
+ resetProcAddressTable(getGLProcAddressTable());
}
- public net.java.games.jogl.impl.ProcAddressTable getGLProcAddressTable() {
+ public GLProcAddressTable getGLProcAddressTable() {
if (glProcAddressTable == null) {
// FIXME: cache ProcAddressTables by capability bits so we can
// share them among contexts with the same capabilities
- glProcAddressTable =
- new net.java.games.jogl.impl.ProcAddressTable();
+ glProcAddressTable = new GLProcAddressTable();
}
return glProcAddressTable;
}
@@ -234,10 +201,6 @@ public abstract class WindowsGLContext extends GLContext {
// Internals only below this point
//
- // Table that holds the addresses of the native C-language entry points for
- // OpenGL functions.
- private net.java.games.jogl.impl.ProcAddressTable glProcAddressTable;
-
protected JAWT getJAWT() {
if (jawt == null) {
JAWT j = new JAWT();
diff --git a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java
index 300e9cb85..484c8f8af 100644
--- a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java
+++ b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java
@@ -119,6 +119,10 @@ public class WindowsPbufferGLContext extends WindowsGLContext {
public void createPbuffer(long parentHdc, long parentHglrc) {
GL gl = getGL();
+ // Must initally grab OpenGL function pointers while parent's
+ // context is current because otherwise we don't have the wgl
+ // extensions available to us
+ resetGLFunctionAvailability();
int[] iattributes = new int [2*MAX_ATTRIBS];
float[] fattributes = new float[2*MAX_ATTRIBS];
diff --git a/src/net/java/games/jogl/impl/x11/X11GLContext.java b/src/net/java/games/jogl/impl/x11/X11GLContext.java
index 8e9804578..ec430bfe8 100644
--- a/src/net/java/games/jogl/impl/x11/X11GLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11GLContext.java
@@ -41,7 +41,7 @@ package net.java.games.jogl.impl.x11;
import java.awt.Component;
import java.util.*;
-import net.java.games.gluegen.opengl.*; // for PROCADDRESS_VAR_PREFIX
+import net.java.games.gluegen.runtime.*; // for PROCADDRESS_VAR_PREFIX
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
@@ -53,6 +53,11 @@ public abstract class X11GLContext extends GLContext {
private boolean glXQueryExtensionsStringInitialized;
private boolean glXQueryExtensionsStringAvailable;
private static final Map/*<String, String>*/ functionNameMap;
+ private boolean isGLX13;
+ // Table that holds the addresses of the native C-language entry points for
+ // OpenGL functions.
+ private GLProcAddressTable glProcAddressTable;
+ private static boolean haveResetGLXProcAddressTable;
static {
functionNameMap = new HashMap();
@@ -105,6 +110,14 @@ public abstract class X11GLContext extends GLContext {
*/
protected abstract void create();
+ public boolean isExtensionAvailable(String glExtensionName) {
+ if (glExtensionName.equals("GL_ARB_pbuffer") ||
+ glExtensionName.equals("GL_ARB_pixel_format")) {
+ return isGLX13;
+ }
+ return super.isExtensionAvailable(glExtensionName);
+ }
+
protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
boolean created = false;
if (context == 0) {
@@ -140,72 +153,44 @@ public abstract class X11GLContext extends GLContext {
protected abstract void swapBuffers() throws GLException;
+ protected long dynamicLookupFunction(String glFuncName) {
+ long res = GLX.glXGetProcAddressARB(glFuncName);
+ if (res == 0) {
+ // GLU routines aren't known to the OpenGL function lookup
+ res = GLX.dlsym(glFuncName);
+ }
+ return res;
+ }
protected void resetGLFunctionAvailability() {
super.resetGLFunctionAvailability();
- resetGLProcAddressTable();
- }
-
- protected void resetGLProcAddressTable() {
-
if (DEBUG) {
System.err.println("!!! Initializing OpenGL extension address table");
}
+ resetProcAddressTable(getGLProcAddressTable());
- net.java.games.jogl.impl.ProcAddressTable table = getGLProcAddressTable();
-
- // if GL is no longer an interface, we'll have to re-implement the code
- // below so it only iterates through gl methods (a non-interface might
- // have constructors, custom methods, etc). For now we assume all methods
- // will be gl methods.
- GL gl = getGL();
-
- Class tableClass = table.getClass();
-
- java.lang.reflect.Field[] fields = tableClass.getDeclaredFields();
-
- for (int i = 0; i < fields.length; ++i) {
- String addressFieldName = fields[i].getName();
- if (!addressFieldName.startsWith(GLEmitter.PROCADDRESS_VAR_PREFIX))
- {
- // not a proc address variable
- continue;
- }
- int startOfMethodName = GLEmitter.PROCADDRESS_VAR_PREFIX.length();
- String glFuncName = addressFieldName.substring(startOfMethodName);
- try
- {
- java.lang.reflect.Field addressField = tableClass.getDeclaredField(addressFieldName);
- assert(addressField.getType() == Long.TYPE);
- // get the current value of the proc address variable in the table object
- long oldProcAddress = addressField.getLong(table);
- long newProcAddress = GLX.glXGetProcAddressARB(glFuncName);
- /*
- System.err.println(
- "!!! Address=" + (newProcAddress == 0
- ? "<NULL> "
- : ("0x" +
- Long.toHexString(newProcAddress))) +
- "\tGL func: " + glFuncName);
- */
- // set the current value of the proc address variable in the table object
- addressField.setLong(gl, newProcAddress);
- } catch (Exception e) {
- throw new GLException(
- "Cannot get GL proc address for method \"" +
- glFuncName + "\": Couldn't get value of field \"" + addressFieldName +
- "\" in class " + tableClass.getName(), e);
- }
+ if (!haveResetGLXProcAddressTable) {
+ resetProcAddressTable(GLX.getGLXProcAddressTable());
}
+ // Figure out whether we are running GLX version 1.3 or above and
+ // therefore have pbuffer support
+ if (display == 0) {
+ throw new GLException("Expected non-null DISPLAY for querying GLX version");
+ }
+ int[] major = new int[1];
+ int[] minor = new int[1];
+ if (!GLX.glXQueryVersion(display, major, minor)) {
+ throw new GLException("glXQueryVersion failed");
+ }
+ isGLX13 = ((major[0] > 1) || (minor[0] > 2));
}
- public net.java.games.jogl.impl.ProcAddressTable getGLProcAddressTable() {
+ public GLProcAddressTable getGLProcAddressTable() {
if (glProcAddressTable == null) {
// FIXME: cache ProcAddressTables by capability bits so we can
// share them among contexts with the same capabilities
- glProcAddressTable =
- new net.java.games.jogl.impl.ProcAddressTable();
+ glProcAddressTable = new GLProcAddressTable();
}
return glProcAddressTable;
}
@@ -245,10 +230,6 @@ public abstract class X11GLContext extends GLContext {
// Internals only below this point
//
- // Table that holds the addresses of the native C-language entry points for
- // OpenGL functions.
- private net.java.games.jogl.impl.ProcAddressTable glProcAddressTable;
-
protected JAWT getJAWT() {
if (jawt == null) {
JAWT j = new JAWT();
diff --git a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
index 496e113a5..385874da7 100644
--- a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
@@ -40,6 +40,8 @@
package net.java.games.jogl.impl.x11;
import java.awt.Component;
+import java.util.*;
+
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
@@ -49,6 +51,9 @@ public class X11OnscreenGLContext extends X11GLContext {
private JAWT_DrawingSurfaceInfo dsi;
private JAWT_X11DrawingSurfaceInfo x11dsi;
+ // Variables for pbuffer support
+ List pbuffersToInstantiate = new ArrayList();
+
public X11OnscreenGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
super(component, capabilities, chooser);
}
@@ -75,14 +80,16 @@ public class X11OnscreenGLContext extends X11GLContext {
}
public boolean canCreatePbufferContext() {
- // For now say no
- return false;
+ // FIXME: should we gate this on GLX 1.3 being available?
+ return true;
}
public synchronized GLContext createPbufferContext(GLCapabilities capabilities,
int initialWidth,
int initialHeight) {
- throw new GLException("Not yet supported");
+ X11PbufferGLContext ctx = new X11PbufferGLContext(capabilities, initialWidth, initialHeight);
+ pbuffersToInstantiate.add(ctx);
+ return ctx;
}
public void bindPbufferToTexture() {
@@ -98,7 +105,16 @@ public class X11OnscreenGLContext extends X11GLContext {
if (!lockSurface()) {
return false;
}
- return super.makeCurrent(initAction);
+ boolean ret = super.makeCurrent(initAction);
+ if (ret) {
+ // Instantiate any pending pbuffers
+ while (!pbuffersToInstantiate.isEmpty()) {
+ X11PbufferGLContext ctx =
+ (X11PbufferGLContext) pbuffersToInstantiate.remove(pbuffersToInstantiate.size() - 1);
+ ctx.createPbuffer(display, context);
+ }
+ }
+ return ret;
} catch (RuntimeException e) {
try {
unlockSurface();
diff --git a/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java b/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java
new file mode 100644
index 000000000..264d60fc7
--- /dev/null
+++ b/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution 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 Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.jogl.impl.x11;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class X11PbufferGLContext extends X11GLContext {
+ private static final boolean DEBUG = false;
+
+ private int initWidth;
+ private int initHeight;
+
+ private long buffer; // GLXPbuffer
+ private GLXFBConfig fbConfig;
+ private int width;
+ private int height;
+
+ // FIXME: kept around because we create the OpenGL context lazily to
+ // better integrate with the X11GLContext framework
+ private long parentContext;
+
+ private static final int MAX_PFORMATS = 256;
+ private static final int MAX_ATTRIBS = 256;
+
+ // FIXME: figure out how to support render-to-texture and
+ // render-to-texture-rectangle (which appear to be supported, though
+ // it looks like floating-point buffers are not)
+
+ public X11PbufferGLContext(GLCapabilities capabilities, int initialWidth, int initialHeight) {
+ super(null, capabilities, null);
+ this.initWidth = initialWidth;
+ this.initHeight = initialHeight;
+ if (initWidth <= 0 || initHeight <= 0) {
+ throw new GLException("Initial width and height of pbuffer must be positive (were (" +
+ initWidth + ", " + initHeight + "))");
+ }
+ }
+
+ public boolean canCreatePbufferContext() {
+ return false;
+ }
+
+ public GLContext createPbufferContext(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ throw new GLException("Not supported");
+ }
+
+ public void bindPbufferToTexture() {
+ // FIXME: figure out how to implement this
+ throw new GLException("Not yet implemented");
+ }
+
+ public void releasePbufferFromTexture() {
+ // FIXME: figure out how to implement this
+ throw new GLException("Not yet implemented");
+ }
+
+ public void createPbuffer(long display, long parentContext) {
+ if (display == 0) {
+ throw new GLException("Null display");
+ }
+
+ if (parentContext == 0) {
+ throw new GLException("Null parentContext");
+ }
+
+ if (capabilities.getOffscreenFloatingPointBuffers()) {
+ throw new GLException("Floating-point pbuffers not supported yet on X11");
+ }
+
+ if (capabilities.getOffscreenRenderToTexture()) {
+ throw new GLException("Render-to-texture pbuffers not supported yet on X11");
+ }
+
+ if (capabilities.getOffscreenRenderToTextureRectangle()) {
+ throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11");
+ }
+
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ float[] fattributes = new float[2*MAX_ATTRIBS];
+ int nfattribs = 0;
+ int niattribs = 0;
+
+ // Since we are trying to create a pbuffer, the GLXFBConfig we
+ // request (and subsequently use) must be "p-buffer capable".
+ iattributes[niattribs++] = GL.GLX_DRAWABLE_TYPE;
+ iattributes[niattribs++] = GL.GLX_PBUFFER_BIT;
+
+ iattributes[niattribs++] = GL.GLX_RENDER_TYPE;
+ iattributes[niattribs++] = GL.GLX_RGBA_BIT;
+
+ iattributes[niattribs++] = GLX.GLX_DOUBLEBUFFER;
+ if (capabilities.getDoubleBuffered()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = GLX.GLX_DEPTH_SIZE;
+ iattributes[niattribs++] = capabilities.getDepthBits();
+
+ iattributes[niattribs++] = GLX.GLX_RED_SIZE;
+ iattributes[niattribs++] = capabilities.getRedBits();
+
+ iattributes[niattribs++] = GLX.GLX_GREEN_SIZE;
+ iattributes[niattribs++] = capabilities.getGreenBits();
+
+ iattributes[niattribs++] = GLX.GLX_BLUE_SIZE;
+ iattributes[niattribs++] = capabilities.getBlueBits();
+
+ iattributes[niattribs++] = GLX.GLX_ALPHA_SIZE;
+ iattributes[niattribs++] = capabilities.getAlphaBits();
+
+ if (capabilities.getStencilBits() > 0) {
+ iattributes[niattribs++] = GLX.GLX_STENCIL_SIZE;
+ iattributes[niattribs++] = capabilities.getStencilBits();
+ }
+
+ if (capabilities.getAccumRedBits() > 0 ||
+ capabilities.getAccumGreenBits() > 0 ||
+ capabilities.getAccumBlueBits() > 0) {
+ iattributes[niattribs++] = GLX.GLX_ACCUM_RED_SIZE;
+ iattributes[niattribs++] = capabilities.getAccumRedBits();
+ iattributes[niattribs++] = GLX.GLX_ACCUM_GREEN_SIZE;
+ iattributes[niattribs++] = capabilities.getAccumGreenBits();
+ iattributes[niattribs++] = GLX.GLX_ACCUM_BLUE_SIZE;
+ iattributes[niattribs++] = capabilities.getAccumBlueBits();
+ }
+
+ iattributes[niattribs++] = 0; // null-terminate
+
+ int screen = 0; // FIXME: provide way to specify this?
+ int[] nelementsTmp = new int[1];
+ GLXFBConfig[] fbConfigs = GLX.glXChooseFBConfig(display, screen, iattributes, nelementsTmp);
+ if (fbConfigs == null || fbConfigs.length == 0 || fbConfigs[0] == null) {
+ throw new GLException("pbuffer creation error: glXChooseFBConfig() failed");
+ }
+ // Note that we currently don't allow selection of anything but
+ // the first GLXFBConfig in the returned list
+ GLXFBConfig fbConfig = fbConfigs[0];
+ int nelements = nelementsTmp[0];
+ if (nelements <= 0) {
+ throw new GLException("pbuffer creation error: couldn't find a suitable frame buffer configuration");
+ }
+
+ if (DEBUG) {
+ System.err.println("Found " + fbConfigs.length + " matching GLXFBConfigs");
+ System.err.println("Parameters of default one:");
+ System.err.println("render type: 0x" + Integer.toHexString(queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE)));
+ System.err.println("rgba: " + ((queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE) & GLX.GLX_RGBA_BIT) != 0));
+ System.err.println("r: " + queryFBConfig(display, fbConfig, GLX.GLX_RED_SIZE));
+ System.err.println("g: " + queryFBConfig(display, fbConfig, GLX.GLX_GREEN_SIZE));
+ System.err.println("b: " + queryFBConfig(display, fbConfig, GLX.GLX_BLUE_SIZE));
+ System.err.println("a: " + queryFBConfig(display, fbConfig, GLX.GLX_ALPHA_SIZE));
+ System.err.println("depth: " + queryFBConfig(display, fbConfig, GLX.GLX_DEPTH_SIZE));
+ System.err.println("double buffered: " + queryFBConfig(display, fbConfig, GLX.GLX_DOUBLEBUFFER));
+ }
+
+ // Create the p-buffer.
+ niattribs = 0;
+
+ iattributes[niattribs++] = GL.GLX_PBUFFER_WIDTH;
+ iattributes[niattribs++] = initWidth;
+ iattributes[niattribs++] = GL.GLX_PBUFFER_HEIGHT;
+ iattributes[niattribs++] = initHeight;
+
+ iattributes[niattribs++] = 0;
+
+ int tmpBuffer = GLX.glXCreatePbuffer(display, fbConfig, iattributes);
+ if (tmpBuffer == 0) {
+ // FIXME: query X error code for detail error message
+ throw new GLException("pbuffer creation error: glXCreatePbuffer() failed");
+ }
+
+ // Set up instance variables
+ this.display = display;
+ this.parentContext = parentContext;
+ buffer = tmpBuffer;
+ this.fbConfig = fbConfig;
+
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ GLX.glXQueryDrawable(display, (int) buffer, GL.GLX_WIDTH, tmp);
+ width = tmp[0];
+ GLX.glXQueryDrawable(display, (int) buffer, GL.GLX_HEIGHT, tmp);
+ height = tmp[0];
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + width + " x " + height);
+ }
+ }
+
+ protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
+ if (buffer == 0) {
+ // pbuffer not instantiated yet
+ return false;
+ }
+
+ lockAWT();
+ try {
+ boolean created = false;
+ if (context == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println("!!! Created GL context for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ // FIXME: this cast to int would be wrong on 64-bit platforms
+ // where the argument type to glXMakeCurrent would change (should
+ // probably make GLXDrawable, and maybe XID, Opaque as long)
+ if (!GLX.glXMakeContextCurrent(display, (int) buffer, (int) buffer, context)) {
+ throw new GLException("Error making context current");
+ }
+
+ if (created) {
+ resetGLFunctionAvailability();
+ initAction.run();
+ }
+ return true;
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ protected synchronized void free() throws GLException {
+ lockAWT();
+ try {
+ if (!GLX.glXMakeContextCurrent(display, 0, 0, 0)) {
+ throw new GLException("Error freeing OpenGL context");
+ }
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ public void handleModeSwitch(long parentHdc, long parentHglrc) {
+ throw new GLException("Not yet implemented");
+ }
+
+ protected boolean isOffscreen() {
+ // FIXME: currently the only caller of this won't cause proper
+ // resizing of the pbuffer anyway.
+ return false;
+ }
+
+ public int getOffscreenContextBufferedImageType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ protected void create() {
+ if (DEBUG) {
+ System.err.println("Creating context for pbuffer " + width + " x " + height);
+ }
+
+ // Create a gl context for the p-buffer.
+ // FIXME: provide option to not share display lists with subordinate pbuffer?
+ context = GLX.glXCreateNewContext(display, fbConfig, GL.GLX_RGBA_TYPE, parentContext, true);
+ if (context == 0) {
+ throw new GLException("pbuffer creation error: glXCreateNewContext() failed");
+ }
+
+ if (DEBUG) {
+ System.err.println("Created context for pbuffer " + width + " x " + height);
+ }
+ }
+
+ protected void swapBuffers() throws GLException {
+ // FIXME: do we need to do anything if the pbuffer is double-buffered?
+ }
+
+ private int queryFBConfig(long display, GLXFBConfig fbConfig, int attrib) {
+ int[] tmp = new int[1];
+ if (GLX.glXGetFBConfigAttrib(display, fbConfig, attrib, tmp) != 0) {
+ throw new GLException("glXGetFBConfigAttrib failed");
+ }
+ return tmp[0];
+ }
+
+ // These synchronization primitives, which prevent the AWT from
+ // making requests from the X server asynchronously to this code,
+ // are required for pbuffers to work properly on X11.
+ private void lockAWT() {
+ getJAWT().Lock();
+ }
+
+ private void unlockAWT() {
+ getJAWT().Unlock();
+ }
+}