diff options
Diffstat (limited to 'make/config/jogl/glx-CustomCCode.c')
-rw-r--r-- | make/config/jogl/glx-CustomCCode.c | 207 |
1 files changed, 114 insertions, 93 deletions
diff --git a/make/config/jogl/glx-CustomCCode.c b/make/config/jogl/glx-CustomCCode.c index e372e5120..7216e5b65 100644 --- a/make/config/jogl/glx-CustomCCode.c +++ b/make/config/jogl/glx-CustomCCode.c @@ -12,51 +12,35 @@ #define RTLD_DEFAULT NULL #endif +#include <string.h> + /* We expect glXGetProcAddressARB to be defined */ extern void (*glXGetProcAddressARB(const GLubyte *procname))(); -static const char * clazzNameBuffers = "com/jogamp/common/nio/Buffers"; -static const char * clazzNameBuffersStaticCstrName = "copyByteBuffer"; -static const char * clazzNameBuffersStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;"; -static const char * clazzNameByteBuffer = "java/nio/ByteBuffer"; -static jclass clazzBuffers = NULL; -static jmethodID cstrBuffers = NULL; -static jclass clazzByteBuffer = NULL; - -static void _initClazzAccess(JNIEnv *env) { - jclass c; - - if(NULL!=cstrBuffers) return ; - - c = (*env)->FindClass(env, clazzNameBuffers); - if(NULL==c) { - fprintf(stderr, "FatalError: Java_jogamp_opengl_x11_glx_GLX: can't find %s\n", clazzNameBuffers); - (*env)->FatalError(env, clazzNameBuffers); - } - clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c); - if(NULL==clazzBuffers) { - fprintf(stderr, "FatalError: Java_jogamp_opengl_x11_glx_GLX: can't use %s\n", clazzNameBuffers); - (*env)->FatalError(env, clazzNameBuffers); - } - c = (*env)->FindClass(env, clazzNameByteBuffer); - if(NULL==c) { - fprintf(stderr, "FatalError: Java_jogamp_opengl_x11_glx_GLX: can't find %s\n", clazzNameByteBuffer); - (*env)->FatalError(env, clazzNameByteBuffer); +/** + * Java->C glue code: + * Java package: jogamp.opengl.x11.glx.GLX + * Java method: int glXGetFBConfigAttributes(long dpy, long config, IntBuffer attributes, IntBuffer values) + */ +JNIEXPORT jint JNICALL +Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXGetFBConfigAttributes(JNIEnv *env, jclass _unused, jlong dpy, jlong config, jint attributeCount, jobject attributes, jint attributes_byte_offset, jobject values, jint values_byte_offset, jlong procAddress) { + typedef int (APIENTRY*_local_PFNGLXGETFBCONFIGATTRIBPROC)(Display * dpy, GLXFBConfig config, int attribute, int * value); + _local_PFNGLXGETFBCONFIGATTRIBPROC ptr_glXGetFBConfigAttrib = (_local_PFNGLXGETFBCONFIGATTRIBPROC) (intptr_t) procAddress; + assert(ptr_glXGetFBConfigAttrib != NULL); + + int err = 0; + if ( attributeCount > 0 && NULL != attributes ) { + int i; + int * attributes_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, attributes)) + attributes_byte_offset); + int * values_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, values)) + values_byte_offset); + for(i=0; 0 == err && i<attributeCount; i++) { + err = (* ptr_glXGetFBConfigAttrib) ((Display *) (intptr_t) dpy, (GLXFBConfig) (intptr_t) config, attributes_ptr[i], &values_ptr[i]); } - clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c); - if(NULL==c) { - fprintf(stderr, "FatalError: Java_jogamp_opengl_x11_glx_GLX: can't use %s\n", clazzNameByteBuffer); - (*env)->FatalError(env, clazzNameByteBuffer); - } - - cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers, - clazzNameBuffersStaticCstrName, clazzNameBuffersStaticCstrSignature); - if(NULL==cstrBuffers) { - fprintf(stderr, "FatalError: Java_jogamp_opengl_x11_glx_GLX:: can't create %s.%s %s\n", - clazzNameBuffers, - clazzNameBuffersStaticCstrName, clazzNameBuffersStaticCstrSignature); - (*env)->FatalError(env, clazzNameBuffersStaticCstrName); + if( 0 != err ) { + values_ptr[0] = i; } + } + return (jint)err; } /* Java->C glue code: @@ -69,19 +53,13 @@ Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXGetVisualFromFBConfig(JNIEnv *env, j typedef XVisualInfo* (APIENTRY*_local_PFNGLXGETVISUALFROMFBCONFIG)(Display * dpy, GLXFBConfig config); _local_PFNGLXGETVISUALFROMFBCONFIG ptr_glXGetVisualFromFBConfig; XVisualInfo * _res; - jobject jbyteSource; jobject jbyteCopy; ptr_glXGetVisualFromFBConfig = (_local_PFNGLXGETVISUALFROMFBCONFIG) (intptr_t) procAddress; assert(ptr_glXGetVisualFromFBConfig != NULL); _res = (* ptr_glXGetVisualFromFBConfig) ((Display *) (intptr_t) dpy, (GLXFBConfig) (intptr_t) config); if (_res == NULL) return NULL; - _initClazzAccess(env); - - jbyteSource = (*env)->NewDirectByteBuffer(env, _res, sizeof(XVisualInfo)); - jbyteCopy = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffers, jbyteSource); - - (*env)->DeleteLocalRef(env, jbyteSource); + jbyteCopy = JVMUtil_NewDirectByteBufferCopy(env, _res, sizeof(XVisualInfo)); XFree(_res); return jbyteCopy; @@ -89,77 +67,120 @@ Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXGetVisualFromFBConfig(JNIEnv *env, j /* Java->C glue code: * Java package: jogamp.opengl.x11.glx.GLX - * Java method: java.nio.LongBuffer glXChooseFBConfig(long dpy, int screen, java.nio.IntBuffer attribList, java.nio.IntBuffer nitems) + * Java method: com.jogamp.common.nio.PointerBuffer dispatch_glXChooseFBConfig(long dpy, int screen, java.nio.IntBuffer attribList, java.nio.IntBuffer nitems) * C function: GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int * attribList, int * nitems); */ JNIEXPORT jobject JNICALL Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXChooseFBConfig(JNIEnv *env, jclass _unused, jlong dpy, jint screen, jobject attribList, jint attribList_byte_offset, jobject nitems, jint nitems_byte_offset, jlong procAddress) { - typedef GLXFBConfig* (APIENTRY*_local_PFNGLXCHOOSEFBCONFIG)(Display * dpy, int screen, const int * attribList, int * nitems); - _local_PFNGLXCHOOSEFBCONFIG ptr_glXChooseFBConfig; - int * _ptr2 = NULL; - int * _ptr3 = NULL; + typedef GLXFBConfig * (APIENTRY*_local_PFNGLXCHOOSEFBCONFIGPROC)(Display * dpy, int screen, const int * attribList, int * nitems); + _local_PFNGLXCHOOSEFBCONFIGPROC ptr_glXChooseFBConfig; + int * _attribList_ptr = NULL; + int * _nitems_ptr = NULL; GLXFBConfig * _res; - int count; - jobject jbyteSource; + int count, i; jobject jbyteCopy; - ptr_glXChooseFBConfig = (_local_PFNGLXCHOOSEFBCONFIG) (intptr_t) procAddress; + if ( NULL != attribList ) { + _attribList_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, attribList)) + attribList_byte_offset); + } + if ( NULL != nitems ) { + _nitems_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, nitems)) + nitems_byte_offset); + } + ptr_glXChooseFBConfig = (_local_PFNGLXCHOOSEFBCONFIGPROC) (intptr_t) procAddress; assert(ptr_glXChooseFBConfig != NULL); - if (attribList != NULL) { - _ptr2 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, attribList, NULL)) + attribList_byte_offset); - } - if (nitems != NULL) { - _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, nitems, NULL)) + nitems_byte_offset); - } - _res = (*ptr_glXChooseFBConfig)((Display *) (intptr_t) dpy, (int) screen, (int *) _ptr2, (int *) _ptr3); - count = _ptr3[0]; - if (attribList != NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, attribList, _ptr2, 0); - } - if (nitems != NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, nitems, _ptr3, 0); + _res = (* ptr_glXChooseFBConfig) ((Display *) (intptr_t) dpy, (int) screen, (int *) _attribList_ptr, (int *) _nitems_ptr); + count = _nitems_ptr[0]; + if (NULL == _res) return NULL; + + /** + * Bug 961: Validate returned 'GLXFBConfig *', i.e. remove NULL pointer. + * Note: sizeof(GLXFBConfig) == sizeof(void*), a.k.a a pointer + */ + // fprintf(stderr, "glXChooseFBConfig.0: Count %d\n", count); + i=0; + while( i < count ) { + if( NULL == _res[i] ) { + if( 0 < count-i-1 ) { + memmove(_res+i, _res+i+1, (count-i-1)*sizeof(GLXFBConfig)); + } + count--; + } else { + i++; + } } - if (_res == NULL) return NULL; + // fprintf(stderr, "glXChooseFBConfig.X: Count %d\n", count); - _initClazzAccess(env); + jbyteCopy = JVMUtil_NewDirectByteBufferCopy(env, _res, count * sizeof(GLXFBConfig)); + XFree(_res); - jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(GLXFBConfig)); - jbyteCopy = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffers, jbyteSource); - (*env)->DeleteLocalRef(env, jbyteSource); + return jbyteCopy; +} + +/* Java->C glue code: + * Java package: jogamp.opengl.x11.glx.GLX + * Java method: com.jogamp.common.nio.PointerBuffer dispatch_glXGetFBConfigs(long dpy, int screen, java.nio.IntBuffer nelements) + * C function: GLXFBConfig * glXGetFBConfigs(Display * dpy, int screen, int * nelements); + */ +JNIEXPORT jobject JNICALL +Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXGetFBConfigs(JNIEnv *env, jclass _unused, jlong dpy, jint screen, jobject nelements, jint nelements_byte_offset, jlong procAddress) { + typedef GLXFBConfig * (APIENTRY*_local_PFNGLXGETFBCONFIGSPROC)(Display * dpy, int screen, int * nelements); + _local_PFNGLXGETFBCONFIGSPROC ptr_glXGetFBConfigs; + int * _nelements_ptr = NULL; + GLXFBConfig * _res; + int count, i; + jobject jbyteCopy; + if ( NULL != nelements ) { + _nelements_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, nelements)) + nelements_byte_offset); + } + ptr_glXGetFBConfigs = (_local_PFNGLXGETFBCONFIGSPROC) (intptr_t) procAddress; + assert(ptr_glXGetFBConfigs != NULL); + _res = (* ptr_glXGetFBConfigs) ((Display *) (intptr_t) dpy, (int) screen, (int *) _nelements_ptr); + count = _nelements_ptr[0]; + if (NULL == _res) return NULL; + + /** + * Bug 961: Validate returned 'GLXFBConfig *', i.e. remove NULL pointer. + * Note: sizeof(GLXFBConfig) == sizeof(void*), a.k.a a pointer + */ + i=0; + while( i < count ) { + if( NULL == _res[i] ) { + if( 0 < count-i-1 ) { + memmove(_res+i, _res+i+1, (count-i-1)*sizeof(GLXFBConfig)); + } + count--; + } else { + i++; + } + } + + jbyteCopy = JVMUtil_NewDirectByteBufferCopy(env, _res, count * sizeof(GLXFBConfig)); XFree(_res); return jbyteCopy; } + /* Java->C glue code: * Java package: jogamp.opengl.x11.glx.GLX - * Java method: XVisualInfo glXChooseVisual(long dpy, int screen, java.nio.IntBuffer attribList) + * Java method: XVisualInfo dispatch_glXChooseVisual(long dpy, int screen, java.nio.IntBuffer attribList) * C function: XVisualInfo * glXChooseVisual(Display * dpy, int screen, int * attribList); */ JNIEXPORT jobject JNICALL Java_jogamp_opengl_x11_glx_GLX_dispatch_1glXChooseVisual(JNIEnv *env, jclass _unused, jlong dpy, jint screen, jobject attribList, jint attribList_byte_offset, jlong procAddress) { - typedef XVisualInfo* (APIENTRY*_local_PFNGLXCHOOSEVISUAL)(Display * dpy, int screen, int * attribList); - _local_PFNGLXCHOOSEVISUAL ptr_glXChooseVisual; - int * _ptr2 = NULL; + typedef XVisualInfo * (APIENTRY*_local_PFNGLXCHOOSEVISUALPROC)(Display * dpy, int screen, int * attribList); + _local_PFNGLXCHOOSEVISUALPROC ptr_glXChooseVisual; + int * _attribList_ptr = NULL; XVisualInfo * _res; - jobject jbyteSource; jobject jbyteCopy; - ptr_glXChooseVisual = (_local_PFNGLXCHOOSEVISUAL) (intptr_t) procAddress; + if ( NULL != attribList ) { + _attribList_ptr = (int *) (((char*) (*env)->GetDirectBufferAddress(env, attribList)) + attribList_byte_offset); + } + ptr_glXChooseVisual = (_local_PFNGLXCHOOSEVISUALPROC) (intptr_t) procAddress; assert(ptr_glXChooseVisual != NULL); - if (attribList != NULL) { - _ptr2 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, attribList, NULL)) + attribList_byte_offset); - } - _res = (*ptr_glXChooseVisual)((Display *) (intptr_t) dpy, (int) screen, (int *) _ptr2); - if (attribList != NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, attribList, _ptr2, 0); - } - if (_res == NULL) return NULL; - - _initClazzAccess(env); - - jbyteSource = (*env)->NewDirectByteBuffer(env, _res, sizeof(XVisualInfo)); - jbyteCopy = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffers, jbyteSource); + _res = (* ptr_glXChooseVisual) ((Display *) (intptr_t) dpy, (int) screen, (int *) _attribList_ptr); + if (NULL == _res) return NULL; - (*env)->DeleteLocalRef(env, jbyteSource); + jbyteCopy = JVMUtil_NewDirectByteBufferCopy(env, _res, sizeof(XVisualInfo)); XFree(_res); return jbyteCopy; |