aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--make/build-nativewindow.xml3
-rwxr-xr-xmake/config/jogl/glx-CustomCCode.c7
-rwxr-xr-xmake/config/nativewindow/x11-CustomCCode.c230
-rw-r--r--make/config/nativewindow/x11-CustomJavaCode.java12
-rw-r--r--make/config/nativewindow/x11-lib.cfg20
-rw-r--r--make/stub_includes/x11/window-lib.c3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java17
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java19
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java15
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java8
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java48
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java20
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java36
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java156
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java57
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java92
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java11
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java2
-rwxr-xr-xsrc/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java35
-rwxr-xr-xsrc/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java264
-rwxr-xr-xsrc/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java25
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java228
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java2
-rw-r--r--src/nativewindow/native/x11/Xmisc.c471
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/x11/X11Display.java6
-rwxr-xr-xsrc/newt/native/X11Window.c76
28 files changed, 1369 insertions, 508 deletions
diff --git a/make/build-nativewindow.xml b/make/build-nativewindow.xml
index 3a62e9733..4b726bafb 100644
--- a/make/build-nativewindow.xml
+++ b/make/build-nativewindow.xml
@@ -530,6 +530,7 @@
<patternset id="c.src.files.x11">
<include name="${rootrel.generated.c}/X11/X11*.c" if="isX11"/>
+ <include name="${rootrel.src.c}/x11/Xmisc.c" if="isX11"/>
<include name="${rootrel.src.c}/x11/XineramaHelper.c" if="isX11"/>
<!-- Xinerama supporting functions for Linux only (for now) -->
<!-- Also supported on Solaris, but works differently -->
@@ -623,6 +624,8 @@
</target>
<target name="c.build.nativewindow.windowlib.x11" if="isX11">
+ <javah destdir="${src.generated.c}/X11" classpath="${classes}" class="com.jogamp.nativewindow.impl.x11.X11Lib" />
+
<c.build c.compiler.src.files="c.src.files.x11"
output.lib.name="nativewindow_x11"
compiler.cfg.id="${compiler.cfg.id}"
diff --git a/make/config/jogl/glx-CustomCCode.c b/make/config/jogl/glx-CustomCCode.c
index 7dac53fb6..1b30a7da6 100755
--- a/make/config/jogl/glx-CustomCCode.c
+++ b/make/config/jogl/glx-CustomCCode.c
@@ -78,7 +78,7 @@ Java_com_jogamp_opengl_impl_x11_glx_GLX_glXGetVisualFromFBConfigCopied0__JJ(JNIE
jbyteCopy = (*env)->CallStaticObjectMethod(env,
clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource);
- // FIXME: remove reference/gc jbyteSource ??
+ (*env)->DeleteLocalRef(env, jbyteSource);
XFree(_res);
return jbyteCopy;
@@ -118,8 +118,7 @@ Java_com_jogamp_opengl_impl_x11_glx_GLX_glXChooseFBConfigCopied1__JILjava_lang_O
jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(GLXFBConfig));
jbyteCopy = (*env)->CallStaticObjectMethod(env,
clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource);
-
- // FIXME: remove reference/gc jbyteSource ??
+ (*env)->DeleteLocalRef(env, jbyteSource);
XFree(_res);
return jbyteCopy;
@@ -151,7 +150,7 @@ Java_com_jogamp_opengl_impl_x11_glx_GLX_glXChooseVisualCopied1__JILjava_lang_Obj
jbyteCopy = (*env)->CallStaticObjectMethod(env,
clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource);
- // FIXME: remove reference/gc jbyteSource ??
+ (*env)->DeleteLocalRef(env, jbyteSource);
XFree(_res);
return jbyteCopy;
diff --git a/make/config/nativewindow/x11-CustomCCode.c b/make/config/nativewindow/x11-CustomCCode.c
deleted file mode 100755
index 982a39f7e..000000000
--- a/make/config/nativewindow/x11-CustomCCode.c
+++ /dev/null
@@ -1,230 +0,0 @@
-#include <inttypes.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-/* Linux headers don't work properly */
-#define __USE_GNU
-#include <dlfcn.h>
-#undef __USE_GNU
-
-/* Current versions of Solaris don't expose the XF86 extensions,
- although with the recent transition to Xorg this will probably
- happen in an upcoming release */
-#if !defined(__sun) && !defined(_HPUX)
-#include <X11/extensions/xf86vmode.h>
-#else
-/* Need to provide stubs for these */
-Bool XF86VidModeGetGammaRampSize(
- Display *display,
- int screen,
- int* size)
-{
- return False;
-}
-
-Bool XF86VidModeGetGammaRamp(
- Display *display,
- int screen,
- int size,
- unsigned short *red_array,
- unsigned short *green_array,
- unsigned short *blue_array) {
- return False;
-}
-Bool XF86VidModeSetGammaRamp(
- Display *display,
- int screen,
- int size,
- unsigned short *red_array,
- unsigned short *green_array,
- unsigned short *blue_array) {
- return False;
-}
-#endif
-
-/* HP-UX doesn't define RTLD_DEFAULT. */
-#if defined(_HPUX) && !defined(RTLD_DEFAULT)
-#define RTLD_DEFAULT NULL
-#endif
-
-/* Need to expose DefaultScreen and RootWindow macros to Java */
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultScreen(JNIEnv *env, jclass _unused, jlong display) {
- return DefaultScreen((Display*) (intptr_t) display);
-}
-
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused, jlong display, jint screen) {
- return (jlong) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
-}
-
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_RootWindow(JNIEnv *env, jclass _unused, jlong display, jint screen) {
- return RootWindow((Display*) (intptr_t) display, screen);
-}
-
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_dlopen(JNIEnv *env, jclass _unused, jstring name) {
- const jbyte* chars;
- void* res;
- chars = (*env)->GetStringUTFChars(env, name, NULL);
- res = dlopen(chars, RTLD_LAZY | RTLD_GLOBAL);
- (*env)->ReleaseStringUTFChars(env, name, chars);
- return (jlong) ((intptr_t) res);
-}
-
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_dlsym(JNIEnv *env, jclass _unused, jstring name) {
- const jbyte* chars;
- void* res;
- chars = (*env)->GetStringUTFChars(env, name, NULL);
- res = dlsym(RTLD_DEFAULT, chars);
- (*env)->ReleaseStringUTFChars(env, name, chars);
- return (jlong) ((intptr_t) res);
-}
-
-/* Need to pull this in as we don't have a stub header for it */
-extern Bool XineramaEnabled(Display* display);
-
-static const char * clazzNameInternalBufferUtil = "com/jogamp/nativewindow/impl/InternalBufferUtil";
-static const char * clazzNameInternalBufferUtilStaticCstrName = "copyByteBuffer";
-static const char * clazzNameInternalBufferUtilStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;";
-static const char * clazzNameByteBuffer = "java/nio/ByteBuffer";
-static jclass clazzInternalBufferUtil = NULL;
-static jmethodID cstrInternalBufferUtil = NULL;
-static jclass clazzByteBuffer = NULL;
-
-static void _initClazzAccess(JNIEnv *env) {
- jclass c;
-
- if(NULL!=cstrInternalBufferUtil) return ;
-
- c = (*env)->FindClass(env, clazzNameInternalBufferUtil);
- if(NULL==c) {
- fprintf(stderr, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s\n", clazzNameInternalBufferUtil);
- (*env)->FatalError(env, clazzNameInternalBufferUtil);
- }
- clazzInternalBufferUtil = (jclass)(*env)->NewGlobalRef(env, c);
- if(NULL==clazzInternalBufferUtil) {
- fprintf(stderr, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s\n", clazzNameInternalBufferUtil);
- (*env)->FatalError(env, clazzNameInternalBufferUtil);
- }
- c = (*env)->FindClass(env, clazzNameByteBuffer);
- if(NULL==c) {
- fprintf(stderr, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s\n", clazzNameByteBuffer);
- (*env)->FatalError(env, clazzNameByteBuffer);
- }
- clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c);
- if(NULL==c) {
- fprintf(stderr, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s\n", clazzNameByteBuffer);
- (*env)->FatalError(env, clazzNameByteBuffer);
- }
-
- cstrInternalBufferUtil = (*env)->GetStaticMethodID(env, clazzInternalBufferUtil,
- clazzNameInternalBufferUtilStaticCstrName, clazzNameInternalBufferUtilStaticCstrSignature);
- if(NULL==cstrInternalBufferUtil) {
- fprintf(stderr, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib:: can't create %s.%s %s\n",
- clazzNameInternalBufferUtil,
- clazzNameInternalBufferUtilStaticCstrName, clazzNameInternalBufferUtilStaticCstrSignature);
- (*env)->FatalError(env, clazzNameInternalBufferUtilStaticCstrName);
- }
-}
-
-/* Java->C glue code:
- * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
- * Java method: XVisualInfo XGetVisualInfo(long arg0, long arg1, XVisualInfo arg2, java.nio.IntBuffer arg3)
- * C function: XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * );
- */
-JNIEXPORT jobject JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_XGetVisualInfoCopied1__JJLjava_nio_ByteBuffer_2Ljava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) {
- XVisualInfo * _ptr2 = NULL;
- int * _ptr3 = NULL;
- XVisualInfo * _res;
- int count;
- jobject jbyteSource;
- jobject jbyteCopy;
- if (arg2 != NULL) {
- _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0);
- }
- if (arg3 != NULL) {
- _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset);
- }
- _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
- count = _ptr3[0];
- if (arg3 != NULL) {
- (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
- }
- if (_res == NULL) return NULL;
-
- _initClazzAccess(env);
-
- jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(XVisualInfo));
- jbyteCopy = (*env)->CallStaticObjectMethod(env,
- clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource);
-
- // FIXME: remove reference/gc jbyteSource ??
- XFree(_res);
-
- return jbyteCopy;
-}
-
-
-static XIOErrorHandler origIOErrorHandler = NULL;
-
-static int displayIOErrorHandler(Display *dpy)
-{
- fprintf(stderr, "Fatal: Nativewindow X11 IOError: Display %p not available\n", dpy);
- origIOErrorHandler(dpy);
- return 0;
-}
-
-static void displayIOErrorHandlerEnable(int onoff) {
- if(onoff) {
- if(NULL==origIOErrorHandler) {
- origIOErrorHandler = XSetIOErrorHandler(displayIOErrorHandler);
- }
- } else {
- XSetIOErrorHandler(origIOErrorHandler);
- origIOErrorHandler = NULL;
- }
-}
-
-/* Java->C glue code:
- * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
- * Java method: int XCloseDisplay(long display)
- * C function: int XCloseDisplay(Display * display);
- */
-JNIEXPORT jint JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused, jlong display) {
- int _res;
- // fprintf(stderr, "X11Lib.XCloseDisplay: %p\n", (Display *) (intptr_t) display);
- displayIOErrorHandlerEnable(1);
- _res = XCloseDisplay((Display *) (intptr_t) display);
- displayIOErrorHandlerEnable(0);
- return _res;
-}
-
-/* Java->C glue code:
- * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
- * Java method: long XOpenDisplay(java.lang.String arg0)
- * C function: Display * XOpenDisplay(const char * );
- */
-JNIEXPORT jlong JNICALL
-Java_com_jogamp_nativewindow_impl_x11_X11Lib_XOpenDisplay__Ljava_lang_String_2(JNIEnv *env, jclass _unused, jstring arg0) {
- const char* _strchars_arg0 = NULL;
- Display * _res;
- if ( NULL != arg0 ) {
- _strchars_arg0 = (*env)->GetStringUTFChars(env, arg0, (jboolean*)NULL);
- if ( NULL == _strchars_arg0 ) {
- (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/OutOfMemoryError"),
- "Failed to get UTF-8 chars for argument \"arg0\" in native dispatcher for \"XOpenDisplay\"");
- return 0;
- }
- }
- _res = XOpenDisplay((char *) _strchars_arg0);
- // fprintf(stderr, "X11Lib.XOpenDisplay: %s -> %p\n", _strchars_arg0, _res);
- if ( NULL != arg0 ) {
- (*env)->ReleaseStringUTFChars(env, arg0, _strchars_arg0);
- }
- return (jlong) (intptr_t) _res;
-}
-
diff --git a/make/config/nativewindow/x11-CustomJavaCode.java b/make/config/nativewindow/x11-CustomJavaCode.java
index d631c92cb..57f37bee7 100644
--- a/make/config/nativewindow/x11-CustomJavaCode.java
+++ b/make/config/nativewindow/x11-CustomJavaCode.java
@@ -24,8 +24,16 @@
/** Entry point to C language function: <code> XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * ); </code> */
private static native java.nio.ByteBuffer XGetVisualInfoCopied1(long arg0, long arg1, java.nio.ByteBuffer arg2, Object arg3, int arg3_byte_offset);
- public static native long XOpenDisplay(String arg0);
- public static native int XCloseDisplay(long display);
+ public static native long DefaultVisualID(long display, int screen);
+
+ /**
+ public static native long CreateDummyWindow(long display, int screen_index, long visualID);
+ public static native void DestroyDummyWindow(long display, long window); */
+
public static native long dlopen(String name);
public static native long dlsym(String name);
+ public static native int XCloseDisplay(long display);
+ public static native void XUnlockDisplay(long display);
+ public static native void XLockDisplay(long display);
+
diff --git a/make/config/nativewindow/x11-lib.cfg b/make/config/nativewindow/x11-lib.cfg
index 394dd230a..cf9642398 100644
--- a/make/config/nativewindow/x11-lib.cfg
+++ b/make/config/nativewindow/x11-lib.cfg
@@ -20,25 +20,25 @@ Opaque long Display *
Opaque boolean Bool
Opaque long GLXFBConfig
-# Manually implement XOpenDisplay, XCloseDisplay, catching XIOError
-ManuallyImplement XCloseDisplay
-ManuallyImplement XOpenDisplay
-
IncludeAs CustomJavaCode X11Lib x11-CustomJavaCode.java
-IncludeAs CustomCCode x11-CustomCCode.c
+# Now resides in x11/Xmisc.c: IncludeAs CustomCCode x11-CustomCCode.c
ArgumentIsString XOpenDisplay 0
-# Need to expose DefaultScreen and RootWindow macros to Java
-CustomJavaCode X11Lib public static native int DefaultScreen(long display);
-CustomJavaCode X11Lib public static native long DefaultVisualID(long display, int screen);
-CustomJavaCode X11Lib public static native long RootWindow(long display, int screen);
-
# We have Custom code for the following
Ignore XGetVisualInfo
+ManuallyImplement XCloseDisplay
+ManuallyImplement XUnlockDisplay
+ManuallyImplement XLockDisplay
+
# Helper routine to make the ReturnedArrayLength expression below work correctly
CustomJavaCode X11Lib private static int getFirstElement(IntBuffer buf) { return buf.get(buf.position()); }
CustomJavaCode X11Lib private static int getFirstElement(int[] arr, int offset) { return arr[offset]; }
CustomJavaCode XVisualInfo public static XVisualInfo create(XVisualInfo s) { XVisualInfo d = XVisualInfo.create(); d.getBuffer().put(s.getBuffer()); d.getBuffer().rewind(); s.getBuffer().rewind(); return d; }
+
+CustomCCode #include <inttypes.h>
+CustomCCode #include <X11/Xlib.h>
+CustomCCode #include <X11/Xutil.h>
+
diff --git a/make/stub_includes/x11/window-lib.c b/make/stub_includes/x11/window-lib.c
index 3096cde4c..8fca86263 100644
--- a/make/stub_includes/x11/window-lib.c
+++ b/make/stub_includes/x11/window-lib.c
@@ -17,6 +17,9 @@ extern void XLockDisplay(Display *display);
extern void XUnlockDisplay(Display *display);
+extern Window RootWindow(Display *display, int screen_number);
+extern int DefaultScreen(Display *display);
+
extern XVisualInfo *XGetVisualInfo(
Display* /* display */,
long /* vinfo_mask */,
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
index 35810678c..616640bad 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
@@ -54,13 +54,24 @@ import java.lang.reflect.*;
public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
protected static final boolean DEBUG = Debug.debug("GLDrawableFactory");
+ private boolean isValid = false;
+
public void shutdown() {
+ validate();
+ isValid = false;
+ }
+
+ protected final void validate() {
+ if(!isValid) {
+ throw new GLException("GLDrawableFactory is already shutdown!");
+ }
}
//---------------------------------------------------------------------------
// Dispatching GLDrawable construction in respect to the NativeWindow Capabilities
//
public GLDrawable createGLDrawable(NativeWindow target) {
+ validate();
if (target == null) {
throw new IllegalArgumentException("Null target");
}
@@ -124,6 +135,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
GLCapabilitiesChooser chooser,
int width,
int height) {
+ validate();
if(height<=0 || height<=0) {
throw new GLException("Width and height of pbuffer must be positive (were (" +
width + ", " + height + "))");
@@ -139,6 +151,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
int width,
int height,
GLContext shareWith) {
+ validate();
return new GLPbufferImpl( (GLDrawableImpl) createGLPbufferDrawable(capabilities, chooser, height, height),
shareWith);
}
@@ -155,6 +168,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
GLCapabilitiesChooser chooser,
int width,
int height) {
+ validate();
if(width<=0 || height<=0) {
throw new GLException("Width and height of pbuffer must be positive (were (" +
width + ", " + height + "))");
@@ -174,6 +188,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
protected GLDrawableFactoryImpl() {
super();
+ isValid = true;
}
protected void maybeDoSingleThreadedWorkaround(Runnable action) {
@@ -279,6 +294,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* out-of-bounds
*/
public boolean setDisplayGamma(float gamma, float brightness, float contrast) throws IllegalArgumentException {
+ validate();
if ((brightness < -1.0f) || (brightness > 1.0f)) {
throw new IllegalArgumentException("Brightness must be between -1.0 and 1.0");
}
@@ -311,6 +327,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
}
public synchronized void resetDisplayGamma() {
+ validate();
if (gammaShutdownHook == null) {
throw new IllegalArgumentException("Should not call this unless setDisplayGamma called first");
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
index c8bc4fe0d..2d5154442 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
@@ -122,10 +122,11 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
if ( onscreen ) {
res = ( 0 != (val & EGL.EGL_WINDOW_BIT) ) ;
} else {
- res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) || usePBuffer ;
- }
- if ( usePBuffer ) {
- res = res && ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ;
+ if ( usePBuffer ) {
+ res = ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ;
+ } else {
+ res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) ;
+ }
}
return res;
@@ -187,17 +188,13 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
caps.setOnscreen( 0 != (val[0] & EGL.EGL_WINDOW_BIT) );
caps.setPBuffer ( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) );
} else {
- throw new GLException("EGL_SURFACE_TYPE does not match !!!");
- }
- } else {
- if(relaxed) {
if(DEBUG) {
- System.err.println("Could not determine EGL_SURFACE_TYPE !!!");
+ System.err.println("EGL_SURFACE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val[0] & EGL.EGL_WINDOW_BIT) )+", pbuffer "+( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) )+", pixmap "+( 0 != (val[0] & EGL.EGL_PIXMAP_BIT) )+")");
}
return null;
- } else {
- throw new GLException("Could not determine EGL_SURFACE_TYPE !!!");
}
+ } else {
+ throw new GLException("Could not determine EGL_SURFACE_TYPE !!!");
}
return caps;
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 5b34e40e1..aed4012a4 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -412,14 +412,16 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
if ( onscreen ) {
res = ( 0 != (val & WINDOW_BIT) ) ;
} else {
- res = ( 0 != (val & BITMAP_BIT) ) || usePBuffer ;
- }
- if ( usePBuffer ) {
- res = res && ( 0 != (val & PBUFFER_BIT) ) ;
+ if ( usePBuffer ) {
+ res = ( 0 != (val & PBUFFER_BIT) ) ;
+ } else {
+ res = ( 0 != (val & BITMAP_BIT) ) ;
+ }
}
return res;
}
+
public static GLCapabilities AttribList2GLCapabilities(GLProfile glp, int[] iattribs,
int niattribs,
int[] iresults,
@@ -433,7 +435,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
res.setOnscreen( 0 != (drawableTypeBits & WINDOW_BIT) );
res.setPBuffer ( 0 != (drawableTypeBits & PBUFFER_BIT) );
} else {
- throw new GLException("WGL DrawableType does not match !!!");
+ if(DEBUG) {
+ System.err.println("WGL DrawableType does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (drawableTypeBits & WINDOW_BIT) )+", pbuffer "+( 0 != (drawableTypeBits & PBUFFER_BIT) )+", pixmap "+( 0 != (drawableTypeBits & BITMAP_BIT))+")");
+ }
+ return null;
}
for (int i = 0; i < niattribs; i++) {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 55b30ef3a..1a375699c 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -260,9 +260,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio
}
pixelFormat = 1; // default ..
} else if ( pixelFormat > numFormats ) {
- throw new GLException("Invalid result " + pixelFormat +
- " from GLCapabilitiesChooser (should be between 1 and " +
- numFormats + ")");
+ // keep on going ..
+ if(DEBUG) {
+ System.err.println("GLCapabilitiesChooser specified invalid index (expected 1.." + numFormats + ", got "+pixelFormat+")");
+ }
+ pixelFormat = 1; // default ..
}
}
chosenCaps = availableCaps[pixelFormat-1];
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java
index 99c54332f..e3c1381f8 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java
@@ -54,13 +54,55 @@ public class GLXUtil {
/** Workaround for apparent issue with ATI's proprietary drivers
where direct contexts still send GLX tokens for GL calls */
- public static boolean isVendorATI(long display) {
+ public static String getVendorName(long display) {
try {
X11Lib.XLockDisplay(display);
- String vendor = GLX.glXGetClientString(display, GLX.GLX_VENDOR);
- return vendor != null && vendor.startsWith("ATI") ;
+ return GLX.glXGetClientString(display, GLX.GLX_VENDOR);
} finally {
X11Lib.XUnlockDisplay(display);
}
}
+
+ public static boolean isVendorNVIDIA(String vendor) {
+ return vendor != null && vendor.startsWith("NVIDIA") ;
+ }
+
+ public static boolean isVendorATI(String vendor) {
+ return vendor != null && vendor.startsWith("ATI") ;
+ }
+
+ public static boolean isVendorATI(long display) {
+ return isVendorATI(getVendorName(display));
+ }
+
+ public static boolean isVendorNVIDIA(long display) {
+ return isVendorNVIDIA(getVendorName(display));
+ }
+
+ public static void getGLXVersion(long display, int major[], int minor[]) {
+ if(0 == display) {
+ throw new GLException("null display handle");
+ }
+ if(major.length<1||minor.length<1) {
+ throw new GLException("passed int arrays size is not >= 1");
+ }
+
+ if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
+ throw new GLException("glXQueryVersion failed");
+ }
+
+ // Work around bugs in ATI's Linux drivers where they report they
+ // only implement GLX version 1.2 on the server side
+ if (major[0] == 1 && minor[0] == 2) {
+ String str = GLX.glXGetClientString(display, GLX.GLX_VERSION);
+ try {
+ // e.g. "1.3"
+ major[0] = Integer.valueOf(str.substring(0, 1)).intValue();
+ minor[0] = Integer.valueOf(str.substring(2, 3)).intValue();
+ } catch (Exception e) {
+ major[0] = 1;
+ minor[0] = 2;
+ }
+ }
+ }
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java
index 097689967..a865e91e8 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java
@@ -42,6 +42,8 @@ import com.jogamp.nativewindow.impl.x11.*;
public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
+ // private long dummyWindow = 0;
+
/**
* Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
* we cannot switch the Display as we please,
@@ -57,12 +59,17 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)nw.getGraphicsConfiguration().getNativeGraphicsConfiguration();
GLCapabilities caps = (GLCapabilities) config.getChosenCapabilities();
- long dpy = config.getScreen().getDevice().getHandle();
- int scrn = config.getScreen().getIndex();
- // System.out.println("X11DummyGLXDrawable: dpy "+toHexString(dpy)+", scrn "+scrn);
+ X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
+ long dpy = device.getHandle();
+ int scrn = screen.getIndex();
+ // long visualID = config.getVisualID();
+ // System.out.println("X11DummyGLXDrawable: dpy "+toHexString(dpy)+", scrn "+scrn+", visualID "+toHexString(visualID));
+
X11Lib.XLockDisplay(dpy);
try{
nw.setSurfaceHandle( X11Lib.RootWindow(dpy, scrn) );
+ // dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID);
+ // nw.setSurfaceHandle( dummyWindow );
} finally {
X11Lib.XUnlockDisplay(dpy);
}
@@ -80,6 +87,11 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
}
public void destroy() {
- // nothing to do, but allowed
+ /**
+ if(0!=dummyWindow) {
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ long dpy = config.getScreen().getDevice().getHandle();
+ X11Lib.DestroyDummyWindow(dpy, dummyWindow);
+ } */
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
index 055e7236c..142da672a 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
@@ -133,7 +133,7 @@ public abstract class X11GLXContext extends GLContextImpl {
}
GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities();
- isVendorATI = GLXUtil.isVendorATI(display);
+ isVendorATI = ((X11GLXDrawableFactory)(drawable.getFactoryImpl())).isVendorATI();
if(config.getFBConfigID()<0) {
// not able to use FBConfig
@@ -148,11 +148,11 @@ public abstract class X11GLXContext extends GLContextImpl {
drawable.getNativeWindow().getSurfaceHandle(),
drawableRead.getNativeWindow().getSurfaceHandle(),
context)) {
- throw new GLException("Error making temp context (old2) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable);
+ throw new GLException("Error making temp context (old2) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable);
}
setGLFunctionAvailability(true);
if(DEBUG) {
- System.err.println("X11GLXContext.createContext done (old2 ctx) 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext done (old2 ctx) "+toHexString(context));
}
} else {
@@ -167,7 +167,7 @@ public abstract class X11GLXContext extends GLContextImpl {
drawable.getNativeWindow().getSurfaceHandle(),
drawableRead.getNativeWindow().getSurfaceHandle(),
temp_context)) {
- throw new GLException("Error making temp context (old) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable);
+ throw new GLException("Error making temp context (old) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable);
}
setGLFunctionAvailability(true);
@@ -182,7 +182,7 @@ public abstract class X11GLXContext extends GLContextImpl {
// continue with temp context for GL < 3.0
context = temp_context;
if(DEBUG) {
- System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no GLX_ARB_create_context) 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no GLX_ARB_create_context) "+toHexString(context));
}
} else {
GLXExt glXExt = getGLXExt();
@@ -209,7 +209,7 @@ public abstract class X11GLXContext extends GLContextImpl {
/**
* don't stricten requirements any further, even compatible would be fine
*
- } else {
+ else {
attribs[8+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB;
attribs[8+1] = GLX.GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
}
@@ -228,7 +228,7 @@ public abstract class X11GLXContext extends GLContextImpl {
GLX.glXDestroyContext(display, context);
context = 0;
} else if(DEBUG) {
- System.err.println("X11GLXContext.createContext >= 3.2 available 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext >= 3.2 available "+toHexString(context));
}
} else {
if(DEBUG) {
@@ -261,7 +261,7 @@ public abstract class X11GLXContext extends GLContextImpl {
GLX.glXDestroyContext(display, context);
context = 0;
} else if(DEBUG) {
- System.err.println("X11GLXContext.createContext >= 3.0 available 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext >= 3.0 available "+toHexString(context));
}
} else {
if(DEBUG) {
@@ -285,10 +285,10 @@ public abstract class X11GLXContext extends GLContextImpl {
context)) {
GLX.glXMakeContextCurrent(display, 0, 0, 0);
GLX.glXDestroyContext(display, temp_context);
- throw new GLException("Error making context (old) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable);
+ throw new GLException("Error making context (old) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable);
}
if(DEBUG) {
- System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no 3.0) 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no 3.0) "+toHexString(context));
}
} else {
GLX.glXDestroyContext(display, temp_context);
@@ -296,7 +296,7 @@ public abstract class X11GLXContext extends GLContextImpl {
// need to update the GL func table ..
updateGLProcAddressTable();
if(DEBUG) {
- System.err.println("X11GLXContext.createContext done (new ctx >= 3.0) 0x"+Long.toHexString(context));
+ System.err.println("X11GLXContext.createContext done (new ctx >= 3.0) "+toHexString(context));
}
}
}
@@ -337,6 +337,8 @@ public abstract class X11GLXContext extends GLContextImpl {
}
protected int makeCurrentImplAfterLock() throws GLException {
+ long dpy = drawable.getNativeWindow().getDisplayHandle();
+
getDrawableImpl().getFactoryImpl().lockToolkit();
try {
if (drawable.getNativeWindow().getSurfaceHandle() == 0) {
@@ -356,7 +358,7 @@ public abstract class X11GLXContext extends GLContextImpl {
if (GLX.glXGetCurrentContext() != context) {
- if (!GLX.glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(),
+ if (!GLX.glXMakeContextCurrent(dpy,
drawable.getNativeWindow().getSurfaceHandle(),
drawableRead.getNativeWindow().getSurfaceHandle(),
context)) {
@@ -364,7 +366,7 @@ public abstract class X11GLXContext extends GLContextImpl {
}
if (DEBUG && (VERBOSE || created)) {
System.err.println(getThreadName() + ": glXMakeCurrent(display " +
- toHexString(drawable.getNativeWindow().getDisplayHandle()) +
+ toHexString(dpy)+
", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) +
", drawableRead " + toHexString(drawableRead.getNativeWindow().getSurfaceHandle()) +
", context " + toHexString(context) + ") succeeded");
@@ -397,10 +399,10 @@ public abstract class X11GLXContext extends GLContextImpl {
try {
if (context != 0) {
if (DEBUG) {
- System.err.println("glXDestroyContext(0x" +
- Long.toHexString(drawable.getNativeWindow().getDisplayHandle()) +
- ", 0x" +
- Long.toHexString(context) + ")");
+ System.err.println("glXDestroyContext(" +
+ toHexString(drawable.getNativeWindow().getDisplayHandle()) +
+ ", " +
+ toHexString(context) + ")");
}
GLX.glXDestroyContext(drawable.getNativeWindow().getDisplayHandle(), context);
if (DEBUG) {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
index 60ee431dc..eda480d5f 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
@@ -48,6 +48,7 @@ import com.jogamp.nativewindow.impl.NWReflection;
import com.jogamp.nativewindow.impl.x11.*;
public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements DynamicLookupHelper {
+
public X11GLXDrawableFactory() {
super();
// Must initialize GLX support eagerly in case a pbuffer is the
@@ -60,64 +61,121 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
NWReflection.createInstance("com.jogamp.opengl.impl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory",
new Object[] {});
} catch (Throwable t) { }
+
+ X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createThreadLocalDisplay(null));
+ vendorName = GLXUtil.getVendorName(sharedDevice.getHandle());
+ isVendorATI = GLXUtil.isVendorATI(vendorName);
+ isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName);
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(sharedDevice.getHandle()); // ATI hack ..
+ }
+ sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
+ if (DEBUG) {
+ System.err.println("!!! Vendor: "+vendorName+", ATI: "+isVendorATI+", NV: "+isVendorNVIDIA);
+ System.err.println("!!! SharedScreen: "+sharedScreen);
+ }
+ }
+
+ private X11GraphicsScreen sharedScreen;
+ private String vendorName;
+ private boolean isVendorATI;
+ private boolean isVendorNVIDIA;
+
+ public String getVendorName() { return vendorName; }
+ public boolean isVendorATI() { return isVendorATI; }
+ public boolean isVendorNVIDIA() { return isVendorNVIDIA; }
+
+ private X11DummyGLXDrawable sharedDrawable=null;
+ private GLContext sharedContext=null;
+
+ private void initShared() {
+ if(null==sharedDrawable) {
+ X11Lib.XLockDisplay(sharedScreen.getDevice().getHandle());
+ sharedDrawable = new X11DummyGLXDrawable(sharedScreen, this, null);
+ sharedContext = sharedDrawable.createContext(null);
+ sharedContext.makeCurrent();
+ sharedContext.release();
+ X11Lib.XUnlockDisplay(sharedScreen.getDevice().getHandle());
+ if (DEBUG) {
+ System.err.println("!!! SharedContext: "+sharedContext);
+ }
+ }
+ }
+
+ public void shutdown() {
+ super.shutdown();
+ if (DEBUG) {
+ System.err.println("!!! Shutdown Shared:");
+ System.err.println("!!! CTX : "+sharedContext);
+ System.err.println("!!! Drawable: "+sharedDrawable);
+ System.err.println("!!! Screen : "+sharedScreen);
+ Exception e = new Exception("Debug");
+ e.printStackTrace();
+ }
+ if(null!=sharedContext) {
+ sharedContext.destroy(); // implies release, if current
+ }
+ if(null!=sharedDrawable) {
+ sharedDrawable.destroy();
+ }
+ if(null!=sharedScreen) {
+ X11GraphicsDevice sharedDevice = (X11GraphicsDevice) sharedScreen.getDevice();
+ if(null!=sharedDevice) {
+ X11Util.closeThreadLocalDisplay(null);
+ }
+ sharedScreen = null;
+ }
+ X11Util.shutdown( !isVendorATI(), DEBUG );
}
public GLDrawableImpl createOnscreenDrawable(NativeWindow target) {
+ validate();
if (target == null) {
throw new IllegalArgumentException("Null target");
}
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack ..
+ }
return new X11OnscreenGLXDrawable(this, target);
}
protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack ..
+ }
+ initShared();
return new X11OffscreenGLXDrawable(this, target);
}
public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+ validate();
return glxVersionGreaterEqualThan(device, 1, 3);
}
private boolean glxVersionsQueried = false;
private int glxVersionMajor=0, glxVersionMinor=0;
public boolean glxVersionGreaterEqualThan(AbstractGraphicsDevice device, int majorReq, int minorReq) {
+ validate();
if (!glxVersionsQueried) {
if(null == device) {
- GLContext ctx = GLContext.getCurrent();
- if( null != ctx) {
- device = ctx.getGLDrawable().getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
- }
+ device = (X11GraphicsDevice) sharedScreen.getDevice();
}
if(null == device) {
- GLException gle = new GLException("FIXME: No AbstractGraphicsDevice (passed or queried via current context - Fallback to ThreadLocal Display ..");
- gle.printStackTrace();
-
- device = new X11GraphicsDevice(X11Util.getThreadLocalDisplay(null));
+ throw new GLException("FIXME: No AbstractGraphicsDevice (passed or shared-device");
}
long display = device.getHandle();
int[] major = new int[1];
int[] minor = new int[1];
- if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
- throw new GLException("glXQueryVersion failed");
- }
+ GLXUtil.getGLXVersion(display, major, minor);
if (DEBUG) {
System.err.println("!!! GLX version: major " + major[0] +
", minor " + minor[0]);
}
- // Work around bugs in ATI's Linux drivers where they report they
- // only implement GLX version 1.2 on the server side
- if (major[0] == 1 && minor[0] == 2) {
- String str = GLX.glXGetClientString(display, GLX.GLX_VERSION);
- try {
- major[0] = Integer.valueOf(str.substring(0, 1)).intValue();
- minor[0] = Integer.valueOf(str.substring(2, 3)).intValue();
- } catch (NumberFormatException nfe) {
- major[0] = 1;
- minor[0] = 2;
- }
- }
-
glxVersionMajor = major[0];
glxVersionMinor = minor[0];
glxVersionsQueried = true;
@@ -127,8 +185,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeWindow target) {
GLDrawableImpl pbufferDrawable;
- X11DummyGLXDrawable dummyDrawable=null;
- GLContext dummyContext=null;
/**
* Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
@@ -136,21 +192,20 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
* The dummy context shall also use the same Display,
* since switching Display in this regard is another ATI bug.
*/
- if( null == GLContext.getCurrent() ) {
- X11GraphicsScreen screen = (X11GraphicsScreen) target.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen();
- dummyDrawable = new X11DummyGLXDrawable(screen, this, null);
- dummyContext = dummyDrawable.createContext(null);
- dummyContext.makeCurrent();
+ boolean usedSharedContext=false;
+ if( isVendorATI() && null == GLContext.getCurrent() ) {
+ initShared();
+ sharedContext.makeCurrent();
+ usedSharedContext=true;
+ }
+ if( isVendorATI() ) {
+ X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack ..
}
try {
pbufferDrawable = new X11PbufferGLXDrawable(this, target);
} finally {
- if(null!=dummyContext) {
- dummyContext.release();
- dummyContext.destroy();
- }
- if(null!=dummyDrawable) {
- dummyDrawable.destroy();
+ if(usedSharedContext) {
+ sharedContext.release();
}
}
return pbufferDrawable;
@@ -158,25 +213,30 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
- AbstractGraphicsScreen screen = X11GraphicsScreen.createDefault();
- NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, screen));
+ X11Lib.XLockDisplay(sharedScreen.getDevice().getHandle());
+ NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, sharedScreen));
+ X11Lib.XUnlockDisplay(sharedScreen.getDevice().getHandle());
nw.setSize(width, height);
return nw;
}
public GLContext createExternalGLContext() {
+ validate();
return X11ExternalGLXContext.create(this, null);
}
public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) {
+ validate();
return canCreateGLPbuffer(device);
}
public GLDrawable createExternalGLDrawable() {
+ validate();
return X11ExternalGLXDrawable.create(this, null);
}
public void loadGLULibrary() {
+ validate();
X11Lib.dlopen("/usr/lib/libGLU.so");
}
@@ -191,6 +251,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
}
public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) {
+ validate();
return false;
}
@@ -210,9 +271,10 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
return gammaRampLength;
}
- long display = X11Util.getThreadLocalDefaultDisplay();
+ long display = sharedScreen.getDevice().getHandle();
+
+ X11Lib.XLockDisplay(display);
try {
- X11Lib.XLockDisplay(display);
int[] size = new int[1];
boolean res = X11Lib.XF86VidModeGetGammaRampSize(display,
X11Lib.DefaultScreen(display),
@@ -235,9 +297,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
rampData[i] = (short) (ramp[i] * 65535);
}
- long display = X11Util.getThreadLocalDefaultDisplay();
+ long display = sharedScreen.getDevice().getHandle();
+ X11Lib.XLockDisplay(display);
try {
- X11Lib.XLockDisplay(display);
boolean res = X11Lib.XF86VidModeSetGammaRamp(display,
X11Lib.DefaultScreen(display),
rampData.length,
@@ -262,9 +324,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
rampData.position(2 * size);
rampData.limit(3 * size);
ShortBuffer blueRampData = rampData.slice();
- long display = X11Util.getThreadLocalDefaultDisplay();
+ long display = sharedScreen.getDevice().getHandle();
+ X11Lib.XLockDisplay(display);
try {
- X11Lib.XLockDisplay(display);
boolean res = X11Lib.XF86VidModeGetGammaRamp(display,
X11Lib.DefaultScreen(display),
size,
@@ -298,9 +360,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna
rampData.position(2 * size);
rampData.limit(3 * size);
ShortBuffer blueRampData = rampData.slice();
- long display = X11Util.getThreadLocalDefaultDisplay();
+ long display = sharedScreen.getDevice().getHandle();
+ X11Lib.XLockDisplay(display);
try {
- X11Lib.XLockDisplay(display);
X11Lib.XF86VidModeSetGammaRamp(display,
X11Lib.DefaultScreen(display),
size,
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
index b3a6e5b8c..35daf0ae0 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -64,18 +64,18 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
int screen = x11Screen.getIndex();
long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
if(0==fbcfg) {
- throw new GLException("FBConfig null of 0x"+Integer.toHexString(fbcfgID));
+ throw new GLException("FBConfig null of "+toHexString(fbcfgID));
}
if(null==glp) {
glp = GLProfile.getDefault();
}
GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display));
if(null==caps) {
- throw new GLException("GLCapabilities null of 0x"+Long.toHexString(fbcfg));
+ throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
}
XVisualInfo xvi = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg);
if(null==xvi) {
- throw new GLException("XVisualInfo null of 0x"+Long.toHexString(fbcfg));
+ throw new GLException("XVisualInfo null of "+toHexString(fbcfg));
}
return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID);
}
@@ -104,6 +104,10 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
}
+ private static int nonZeroOrDontCare(int value) {
+ return value != 0 ? value : (int)GLX.GLX_DONT_CARE ;
+ }
+
public static int[] GLCapabilities2AttribList(GLCapabilities caps,
boolean forFBAttr,
boolean isMultisampleAvailable,
@@ -222,10 +226,11 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
if ( onscreen ) {
res = ( 0 != (val & GLX.GLX_WINDOW_BIT) ) ;
} else {
- res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) || usePBuffer ;
- }
- if ( usePBuffer ) {
- res = res && ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ;
+ if ( usePBuffer ) {
+ res = ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ;
+ } else {
+ res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) ;
+ }
}
return res;
@@ -237,7 +242,10 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
int val;
val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0);
if (val != GLX.GLX_RGBA_BIT) {
- throw new GLException("Visual does not support RGBA");
+ if(DEBUG) {
+ System.err.println("FBConfig ("+toHexString(fbcfg)+") does not support RGBA: "+toHexString(val));
+ }
+ return null;
}
GLCapabilities res = new GLCapabilities(glp);
@@ -249,7 +257,10 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setOnscreen( 0 != (val & GLX.GLX_WINDOW_BIT) );
res.setPBuffer ( 0 != (val & GLX.GLX_PBUFFER_BIT) );
} else {
- throw new GLException("GLX_DRAWABLE_TYPE does not match !!!");
+ if(DEBUG) {
+ System.err.println("FBConfig ("+toHexString(fbcfg)+") GLX_DRAWABLE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val & GLX.GLX_WINDOW_BIT) )+", pbuffer "+( 0 != (val & GLX.GLX_PBUFFER_BIT) )+", pixmap "+( 0 != (val & GLX.GLX_PIXMAP_BIT) )+")");
+ }
+ return null;
}
res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0);
@@ -302,7 +313,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp, tmp_offset);
if (res != 0) {
- throw new GLException("glXGetFBConfig(0x"+Long.toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res));
+ throw new GLException("glXGetFBConfig("+toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res));
}
return tmp[tmp_offset];
}
@@ -340,8 +351,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
}
if (DEBUG) {
- System.err.println("!!! Fetched XVisualInfo for visual ID 0x" + Long.toHexString(visualID));
- System.err.println("!!! Resulting XVisualInfo: visualid = 0x" + Long.toHexString(res.getVisualid()));
+ System.err.println("!!! Fetched XVisualInfo for visual ID " + toHexString(visualID));
+ System.err.println("!!! Resulting XVisualInfo: visualid = " + toHexString(res.getVisualid()));
}
return res;
}
@@ -350,11 +361,17 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
int[] tmp = new int[1];
int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
if (val == 0) {
- throw new GLException("Visual does not support OpenGL");
+ if(DEBUG) {
+ System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL");
+ }
+ return null;
}
val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0);
if (val == 0) {
- throw new GLException("Visual does not support RGBA");
+ if(DEBUG) {
+ System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA");
+ }
+ return null;
}
GLCapabilities res = new GLCapabilities(glp);
res.setOnscreen (onscreen);
@@ -399,13 +416,21 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset);
if (res != 0) {
- throw new GLException("glXGetConfig(0x"+Long.toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res));
+ throw new GLException("glXGetConfig("+toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res));
}
return tmp[tmp_offset];
}
+ public static String toHexString(int val) {
+ return "0x"+Integer.toHexString(val);
+ }
+
+ public static String toHexString(long val) {
+ return "0x"+Long.toHexString(val);
+ }
+
public String toString() {
- return "X11GLXGraphicsConfiguration["+getScreen()+", visualID 0x" + Long.toHexString(getVisualID()) + ", fbConfigID 0x" + Long.toHexString(fbConfigID) +
+ return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(fbConfigID) +
",\n\trequested " + getRequestedCapabilities()+
",\n\tchosen " + getChosenCapabilities()+
"]";
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 72551f928..477f2473c 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -79,9 +79,10 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
//
GLCapabilities capsFB = null;
long display = x11Screen.getDevice().getHandle();
+
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ X11Lib.XLockDisplay(display);
try {
- NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
- X11Lib.XLockDisplay(display);
int screen = x11Screen.getIndex();
boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
@@ -154,14 +155,14 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
x11Screen);
if(null==res) {
if(usePBuffer) {
- throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig");
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+caps2);
}
res = chooseGraphicsConfigurationXVisual((GLCapabilities) caps2,
(GLCapabilitiesChooser) chooser,
x11Screen);
}
if(null==res) {
- throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration");
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for "+caps2);
}
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic("+x11Screen+","+caps2+"): "+res);
@@ -172,6 +173,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
X11GraphicsScreen x11Screen) {
+ long recommendedFBConfig = 0;
int recommendedIndex = -1;
GLCapabilities[] caps = null;
PointerBuffer fbcfgsL = null;
@@ -186,37 +188,66 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
//
AbstractGraphicsDevice absDevice = x11Screen.getDevice();
long display = absDevice.getHandle();
+
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ X11Lib.XLockDisplay(display);
try {
- NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
- X11Lib.XLockDisplay(display);
int screen = x11Screen.getIndex();
boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, display, screen);
int[] count = { -1 };
+ // determine the recommended FBConfig ..
fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0);
if (fbcfgsL == null || fbcfgsL.limit()<1) {
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capabilities+"): "+fbcfgsL+", "+count[0]);
}
- return null;
+ } else if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: "+toHexString(fbcfgsL.get(0)));
+ }
+ } else {
+ recommendedFBConfig = fbcfgsL.get(0);
}
- if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) {
+
+ // get all, glXChooseFBConfig(.. attribs==null ..) == glXGetFBConfig(..)
+ fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, null, 0, count, 0);
+ if (fbcfgsL == null || fbcfgsL.limit()<1) {
if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: 0x"+Long.toHexString(fbcfgsL.get(0)));
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]);
}
return null;
}
- recommendedIndex = 0; // 1st match is always recommended ..
+
+ // make GLCapabilities and seek the recommendedIndex
caps = new GLCapabilities[fbcfgsL.limit()];
for (int i = 0; i < fbcfgsL.limit(); i++) {
- caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i),
- false, onscreen, usePBuffer, isMultisampleAvailable);
+ if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid: ("+x11Screen+","+capabilities+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
+ }
+ } else {
+ caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i),
+ false, onscreen, usePBuffer, isMultisampleAvailable);
+ if(caps[i]!=null && recommendedFBConfig==fbcfgsL.get(i)) {
+ recommendedIndex=i;
+ if (DEBUG) {
+ System.err.println("!!! glXChooseFBConfig recommended "+i+", "+caps[i]);
+ }
+ }
+ }
}
if(null==chooser) {
- chosen = recommendedIndex;
- } else {
+ chosen = recommendedIndex; // may still be -1 in case nothing was recommended (-1)
+ }
+
+ if (chosen < 0) {
+ if(null==chooser) {
+ // nothing recommended .. so use our default implementation
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
try {
chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex);
} catch (NativeWindowException e) {
@@ -231,9 +262,20 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first");
}
- chosen = 0; // default ..
+ // seek first available one ..
+ for(chosen = 0; chosen < caps.length && caps[chosen]==null; chosen++) ;
+ if(chosen==caps.length) {
+ // give up ..
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out");
+ }
+ return null;
+ }
} else if (chosen >= caps.length) {
- throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
+ if(DEBUG) {
+ System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ", got "+chosen+")");
+ }
+ return null;
}
retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen));
@@ -276,9 +318,10 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
AbstractGraphicsDevice absDevice = x11Screen.getDevice();
long display = absDevice.getHandle();
+
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ X11Lib.XLockDisplay(display);
try {
- NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
- X11Lib.XLockDisplay(display);
int screen = x11Screen.getIndex();
boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, display, screen);
@@ -290,7 +333,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
if (recommendedVis == null) {
System.err.println("null visual");
} else {
- System.err.println("visual id 0x" + Long.toHexString(recommendedVis.getVisualid()));
+ System.err.println("visual id " + toHexString(recommendedVis.getVisualid()));
}
}
int[] count = new int[1];
@@ -326,7 +369,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
}
if (infos[chosen] == null) {
- throw new GLException("GLCapabilitiesChooser chose an invalid visual");
+ throw new GLException("GLCapabilitiesChooser chose an invalid visual for "+caps[chosen]);
}
retXVisualInfo = XVisualInfo.create(infos[chosen]);
} finally {
@@ -335,5 +378,14 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
}
return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, 0, -1);
}
+
+ public static String toHexString(int val) {
+ return "0x"+Integer.toHexString(val);
+ }
+
+ public static String toHexString(long val) {
+ return "0x"+Long.toHexString(val);
+ }
+
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java
index ea855d28d..41f012122 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java
@@ -75,9 +75,9 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable {
int screen = aScreen.getIndex();
getFactoryImpl().lockToolkit();
+ X11Lib.XLockDisplay(dpy);
try {
- X11Lib.XLockDisplay(dpy);
- pixmap = X11Lib.XCreatePixmap(dpy, (int) X11Lib.RootWindow(dpy, screen),
+ pixmap = X11Lib.XCreatePixmap(dpy, X11Lib.RootWindow(dpy, screen),
component.getWidth(), component.getHeight(), bitsPerPixel);
if (pixmap == 0) {
throw new GLException("XCreatePixmap failed");
@@ -105,10 +105,10 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable {
NativeWindow nw = getNativeWindow();
long display = nw.getDisplayHandle();
- try {
- getFactoryImpl().lockToolkit();
- X11Lib.XLockDisplay(display);
+ getFactoryImpl().lockToolkit();
+ X11Lib.XLockDisplay(display);
+ try {
long drawable = nw.getSurfaceHandle();
if (DEBUG) {
System.err.println("Destroying pixmap " + toHexString(pixmap) +
@@ -135,11 +135,11 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable {
X11Lib.XFreePixmap(display, pixmap);
drawable = 0;
pixmap = 0;
- display = 0;
((SurfaceChangeable)nw).setSurfaceHandle(0);
} finally {
X11Lib.XUnlockDisplay(display);
getFactoryImpl().unlockToolkit();
+ display = 0;
}
}
protected void swapBuffersImpl() {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
index 63b350bd3..dc6c60664 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
@@ -92,7 +92,7 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration
try {
long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
if(0==displayHandle) {
- displayHandle = X11Util.getThreadLocalDefaultDisplay();
+ displayHandle = X11Util.createThreadLocalDefaultDisplay();
if(DEBUG) {
System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display");
}
diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
index 8603c7184..c5ded88f6 100644
--- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -89,11 +89,17 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
int windowSystemRecommendedChoice) {
GLCapabilities _desired = (GLCapabilities) desired;
GLCapabilities[] _available = (GLCapabilities[]) available;
+ int availnum = 0;
+
+ for (int i = 0; i < _available.length; i++) {
+ if(null != _available[i]) { availnum++; }
+ }
if (DEBUG) {
System.err.println("Desired: " + _desired);
+ System.err.println("Available: Valid " + availnum + "/" + _available.length);
for (int i = 0; i < _available.length; i++) {
- System.err.println("Available " + i + ": " + _available[i]);
+ System.err.println(i + ": " + _available[i]);
}
System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice);
}
@@ -132,6 +138,9 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
if (_desired.isOnscreen() != cur.isOnscreen()) {
continue;
}
+ if (_desired.isPBuffer() != cur.isPBuffer()) {
+ continue;
+ }
if (_desired.getStereo() != cur.getStereo()) {
continue;
}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 71cb3cb3b..80c2c10e2 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -216,6 +216,7 @@ public abstract class GLDrawableFactory {
/**
* Returns true if it is possible to create a GLPbuffer. Some older
* graphics cards do not have this capability.
+ * @param passing the device for the query, may be null
*/
public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
@@ -278,6 +279,7 @@ public abstract class GLDrawableFactory {
/**
* Returns true if it is possible to create an external GLDrawable
* object via {@link #createExternalGLDrawable}.
+ * @param passing the device for the query, may be null
*/
public abstract boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device);
diff --git a/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java b/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java
index fa15e3fef..5abf02b97 100755
--- a/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java
+++ b/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java
@@ -40,6 +40,8 @@ import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.After;
import org.junit.Test;
import javax.media.opengl.*;
@@ -50,21 +52,29 @@ import com.jogamp.newt.opengl.*;
public class TestDrawable01NEWT {
static GLProfile glp;
+ static GLDrawableFactory factory;
static int width, height;
GLCapabilities caps;
Window window;
GLDrawable drawable;
GLContext context;
- GLDrawableFactory factory;
@BeforeClass
public static void initClass() {
glp = GLProfile.getDefault();
Assert.assertNotNull(glp);
+ factory = GLDrawableFactory.getFactory(glp);
+ Assert.assertNotNull(factory);
width = 640;
height = 480;
}
+ @AfterClass
+ public static void releaseClass() {
+ factory.shutdown();
+ factory=null;
+ }
+
@Before
public void initTest() {
caps = new GLCapabilities(glp);
@@ -106,8 +116,6 @@ public class TestDrawable01NEWT {
Assert.assertTrue(glCaps.getDoubleBuffered()==!onscreen);
Assert.assertTrue(glCaps.getDepthBits()>4);
- factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
- Assert.assertNotNull(factory);
drawable = factory.createGLDrawable(window);
Assert.assertNotNull(drawable);
// System.out.println("Pre: "+drawable);
@@ -149,10 +157,6 @@ public class TestDrawable01NEWT {
drawable = null;
context = null;
window = null;
-
- // test code cont ..
- factory.shutdown();
- factory = null;
}
@Test
@@ -174,7 +178,22 @@ public class TestDrawable01NEWT {
}
public static void main(String args[]) {
- org.junit.runner.JUnitCore.main(TestDrawable01NEWT.class.getName());
+ String tstname = TestDrawable01NEWT.class.getName();
+ try {
+ org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
+ tstname,
+ "filtertrace=true",
+ "haltOnError=false",
+ "haltOnFailure=false",
+ "showoutput=true",
+ "outputtoformatters=true",
+ "logfailedtests=true",
+ "logtestlistenerevents=true",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } );
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
}
diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java b/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java
index 436167dbf..e5e7c4a52 100755
--- a/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java
+++ b/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java
@@ -40,6 +40,8 @@ import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.After;
import org.junit.Test;
import javax.media.opengl.*;
@@ -52,48 +54,223 @@ import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears;
import com.jogamp.test.junit.jogl.demos.es1.RedSquare;
public class TestOffscreen01NEWT {
- int width, height;
- GLProfile glp;
+ static GLProfile glp;
+ static GLDrawableFactory factory;
+ static int width, height;
GLCapabilities caps;
- @Before
- public void init() {
+ @BeforeClass
+ public static void initClass() {
glp = GLProfile.getDefault();
+ Assert.assertNotNull(glp);
+ factory = GLDrawableFactory.getFactory(glp);
+ Assert.assertNotNull(factory);
width = 640;
height = 480;
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ factory.shutdown();
+ factory=null;
+ }
+
+ @Before
+ public void init() {
caps = new GLCapabilities(glp);
}
+ private void do01OffscreenWindowPBuffer(GLCapabilities caps) {
+ Display display = NewtFactory.createDisplay(null); // local display
+ Assert.assertNotNull(display);
+ Screen screen = NewtFactory.createScreen(display, 0); // screen 0
+ Assert.assertNotNull(screen);
+ Window window = NewtFactory.createWindow(screen, caps, false /* undecorated */);
+ Assert.assertNotNull(window);
+ window.setSize(width, height);
+ GLWindow glWindow = GLWindow.create(window);
+ Assert.assertNotNull(glWindow);
+ glWindow.setVisible(true);
+ GLEventListener demo = new RedSquare();
+ WindowUtilNEWT.setDemoFields(demo, window, glWindow, false);
+
+ while ( glWindow.getTotalFrames() < 2) {
+ glWindow.display();
+ }
+
+ if(null!=glWindow) {
+ glWindow.destroy();
+ }
+ if(null!=window) {
+ window.destroy();
+ }
+ if(null!=screen) {
+ screen.destroy();
+ }
+ if(null!=display) {
+ display.destroy();
+ }
+ }
+
+ @Test
+ public void test01aOffscreenWindowPBuffer() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ do01OffscreenWindowPBuffer(caps2);
+ }
+
+ @Test
+ public void test01bOffscreenWindowPBufferStencil() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ caps2.setStencilBits(8);
+ do01OffscreenWindowPBuffer(caps2);
+ }
+
@Test
- public void test01OffscreenWindow() {
+ public void test01cOffscreenWindowPBufferStencilAlpha() {
GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ caps2.setStencilBits(8);
+ caps2.setAlphaBits(8);
+ do01OffscreenWindowPBuffer(caps2);
+ }
+
+ @Test
+ public void test01cOffscreenWindowPBuffer555() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ caps2.setRedBits(5);
+ caps2.setGreenBits(5);
+ caps2.setBlueBits(5);
+ do01OffscreenWindowPBuffer(caps2);
+ }
+
+ @Test
+ public void test02Offscreen3Windows1DisplayPBuffer() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ int winnum = 3, i;
+ Window windows[] = new Window[winnum];
+ GLWindow glWindows[] = new GLWindow[winnum];
+ GLEventListener demos[] = new GLEventListener[winnum];
Display display = NewtFactory.createDisplay(null); // local display
Assert.assertNotNull(display);
Screen screen = NewtFactory.createScreen(display, 0); // screen 0
Assert.assertNotNull(screen);
+
+ for(i=0; i<winnum; i++) {
+ System.out.println("Create Window "+i);
+ windows[i] = NewtFactory.createWindow(screen, caps2, false /* undecorated */);
+ Assert.assertNotNull(windows[i]);
+ windows[i].setSize(width, height);
+ glWindows[i] = GLWindow.create(windows[i]);
+ Assert.assertNotNull(glWindows[i]);
+ glWindows[i].setVisible(true);
+ demos[i] = new RedSquare();
+ WindowUtilNEWT.setDemoFields(demos[i], windows[i], glWindows[i], false);
+ }
+
+ while ( glWindows[0].getTotalFrames() < 2) {
+ for(i=0; i<winnum; i++) {
+ glWindows[i].display();
+ }
+ }
+
+ for(i=0; i<winnum; i++) {
+ if(null!=glWindows[i]) {
+ glWindows[i].destroy();
+ }
+ if(null!=windows[i]) {
+ windows[i].destroy();
+ }
+ }
+ if(null!=screen) {
+ screen.destroy();
+ }
+ if(null!=display) {
+ display.destroy();
+ }
+ }
+
+ @Test
+ public void test03Offscreen3Windows3DisplaysPBuffer() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ int winnum = 3, i;
+ Display displays[] = new Display[winnum];
+ Screen screens[] = new Screen[winnum];
+ Window windows[] = new Window[winnum];
+ GLWindow glWindows[] = new GLWindow[winnum];
+ GLEventListener demos[] = new GLEventListener[winnum];
+
+ for(i=0; i<winnum; i++) {
+ System.out.println("Create Window "+i);
+ displays[i] = NewtFactory.createDisplay(null); // local display
+ Assert.assertNotNull(displays[i]);
+ screens[i] = NewtFactory.createScreen(displays[i], 0); // screen 0
+ Assert.assertNotNull(screens[i]);
+ windows[i] = NewtFactory.createWindow(screens[i], caps2, false /* undecorated */);
+ Assert.assertNotNull(windows[i]);
+ windows[i].setSize(width, height);
+ glWindows[i] = GLWindow.create(windows[i]);
+ Assert.assertNotNull(glWindows[i]);
+ glWindows[i].setVisible(true);
+ demos[i] = new RedSquare();
+ WindowUtilNEWT.setDemoFields(demos[i], windows[i], glWindows[i], false);
+ }
+
+ while ( glWindows[0].getTotalFrames() < 2) {
+ for(i=0; i<winnum; i++) {
+ glWindows[i].display();
+ }
+ }
+
+ for(i=0; i<winnum; i++) {
+ if(null!=glWindows[i]) {
+ glWindows[i].destroy();
+ }
+ if(null!=windows[i]) {
+ windows[i].destroy();
+ }
+ if(null!=screens[i]) {
+ screens[i].destroy();
+ }
+ if(null!=displays[i]) {
+ displays[i].destroy();
+ }
+ }
+ }
+
+ @Test
+ public void test04OffscreenSnapshotWithDemoPBuffer() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+
+ System.out.println("Create Window 1");
+ Display display = NewtFactory.createDisplay(null); // local display
+ Assert.assertNotNull(display);
+ Screen screen = NewtFactory.createScreen(display, 0); // screen 0
+ Assert.assertNotNull(screen);
Window window = NewtFactory.createWindow(screen, caps2, false /* undecorated */);
Assert.assertNotNull(window);
window.setSize(width, height);
- GLWindow windowOffScreen = GLWindow.create(window);
- Assert.assertNotNull(windowOffScreen);
- windowOffScreen.setVisible(true);
+ GLWindow glWindow = GLWindow.create(window);
+ Assert.assertNotNull(glWindow);
+ glWindow.setVisible(true);
GLWindow windowOnScreen = null;
WindowListener wl=null;
MouseListener ml=null;
SurfaceUpdatedListener ul=null;
- WindowUtilNEWT.run(windowOffScreen, null, windowOnScreen, wl, ml, ul, 2, false /*snapshot*/, false /*debug*/);
- try {
- Thread.sleep(1000); // 1000 ms
- } catch (Exception e) {}
+ GLEventListener demo = new RedSquare();
+ Assert.assertNotNull(demo);
+
+ WindowUtilNEWT.run(glWindow, demo, windowOnScreen, wl, ml, ul, 2, true /*snapshot*/, false /*debug*/);
if(null!=windowOnScreen) {
windowOnScreen.destroy();
}
- if(null!=windowOffScreen) {
- windowOffScreen.destroy();
+ if(null!=glWindow) {
+ glWindow.destroy();
+ }
+ if(null!=window) {
+ window.destroy();
}
if(null!=screen) {
screen.destroy();
@@ -104,8 +281,8 @@ public class TestOffscreen01NEWT {
}
@Test
- public void test02OffscreenSnapshotWithDemo() {
- GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
+ public void test11OffscreenWindowPixmap() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, false, false);
Display display = NewtFactory.createDisplay(null); // local display
Assert.assertNotNull(display);
@@ -114,9 +291,45 @@ public class TestOffscreen01NEWT {
Window window = NewtFactory.createWindow(screen, caps2, false /* undecorated */);
Assert.assertNotNull(window);
window.setSize(width, height);
- GLWindow windowOffScreen = GLWindow.create(window);
- Assert.assertNotNull(windowOffScreen);
- windowOffScreen.setVisible(true);
+ GLWindow glWindow = GLWindow.create(window);
+ Assert.assertNotNull(glWindow);
+ glWindow.setVisible(true);
+ GLEventListener demo = new RedSquare();
+ WindowUtilNEWT.setDemoFields(demo, window, glWindow, false);
+
+ while ( glWindow.getTotalFrames() < 2) {
+ glWindow.display();
+ }
+
+ if(null!=glWindow) {
+ glWindow.destroy();
+ }
+ if(null!=window) {
+ window.destroy();
+ }
+ if(null!=screen) {
+ screen.destroy();
+ }
+ if(null!=display) {
+ display.destroy();
+ }
+ }
+
+ @Test
+ public void test14OffscreenSnapshotWithDemoPixmap() {
+ GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, false, false);
+
+ System.out.println("Create Window 1");
+ Display display = NewtFactory.createDisplay(null); // local display
+ Assert.assertNotNull(display);
+ Screen screen = NewtFactory.createScreen(display, 0); // screen 0
+ Assert.assertNotNull(screen);
+ Window window = NewtFactory.createWindow(screen, caps2, false /* undecorated */);
+ Assert.assertNotNull(window);
+ window.setSize(width, height);
+ GLWindow glWindow = GLWindow.create(window);
+ Assert.assertNotNull(glWindow);
+ glWindow.setVisible(true);
GLWindow windowOnScreen = null;
WindowListener wl=null;
@@ -126,16 +339,16 @@ public class TestOffscreen01NEWT {
GLEventListener demo = new RedSquare();
Assert.assertNotNull(demo);
- WindowUtilNEWT.run(windowOffScreen, demo, windowOnScreen, wl, ml, ul, 2, true /*snapshot*/, false /*debug*/);
- try {
- Thread.sleep(1000); // 1000 ms
- } catch (Exception e) {}
+ WindowUtilNEWT.run(glWindow, demo, windowOnScreen, wl, ml, ul, 2, true /*snapshot*/, false /*debug*/);
if(null!=windowOnScreen) {
windowOnScreen.destroy();
}
- if(null!=windowOffScreen) {
- windowOffScreen.destroy();
+ if(null!=glWindow) {
+ glWindow.destroy();
+ }
+ if(null!=window) {
+ window.destroy();
}
if(null!=screen) {
screen.destroy();
@@ -144,7 +357,6 @@ public class TestOffscreen01NEWT {
display.destroy();
}
}
-
public static void main(String args[]) {
String tstname = TestOffscreen01NEWT.class.getName();
try {
diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java b/src/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java
index f6a6dc4be..7afa7b1e5 100755
--- a/src/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java
+++ b/src/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java
@@ -52,22 +52,27 @@ public class WindowUtilNEWT {
return caps2;
}
+ public static void setDemoFields(GLEventListener demo, Window window, GLWindow glWindow, boolean debug) {
+ Assert.assertNotNull(demo);
+ Assert.assertNotNull(window);
+ if(debug) {
+ MiscUtils.setField(demo, "glDebug", new Boolean(true));
+ MiscUtils.setField(demo, "glTrace", new Boolean(true));
+ }
+ if(!MiscUtils.setField(demo, "window", window)) {
+ MiscUtils.setField(demo, "glWindow", glWindow);
+ }
+ }
+
public static void run(GLWindow windowOffScreen, GLEventListener demo,
GLWindow windowOnScreen, WindowListener wl, MouseListener ml,
SurfaceUpdatedListener ul, int frames, boolean snapshot, boolean debug) {
try {
Assert.assertNotNull(windowOffScreen);
+ Assert.assertNotNull(demo);
- if(debug && null!=demo) {
- MiscUtils.setField(demo, "glDebug", new Boolean(true));
- MiscUtils.setField(demo, "glTrace", new Boolean(true));
- }
- if(null!=demo) {
- if(!MiscUtils.setField(demo, "window", windowOffScreen)) {
- MiscUtils.setField(demo, "glWindow", windowOffScreen);
- }
- windowOffScreen.addGLEventListener(demo);
- }
+ setDemoFields(demo, windowOffScreen, windowOffScreen, debug);
+ windowOffScreen.addGLEventListener(demo);
if ( null != windowOnScreen ) {
if(null!=wl) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
index 95fd6c72b..41ffccc42 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
@@ -34,6 +34,9 @@ package com.jogamp.nativewindow.impl.x11;
import java.util.HashMap;
import java.util.Map;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Iterator;
import javax.media.nativewindow.*;
@@ -41,7 +44,7 @@ import com.jogamp.nativewindow.impl.*;
/**
* Contains a thread safe X11 utility to retrieve thread local display connection,<br>
- * as well as the static global discplay connection.<br>
+ * as well as the static global display connection.<br>
*
* The TLS variant is thread safe per se, but be aware of the memory leak risk
* where an application heavily utilizing this class on temporary new threads.<br>
@@ -51,27 +54,98 @@ public class X11Util {
static {
NativeLibLoaderBase.loadNativeWindow("x11");
+ installIOErrorHandler();
}
private X11Util() {}
private static ThreadLocal currentDisplayMap = new ThreadLocal();
+ // not exactly thread safe, but good enough for our purpose,
+ // which is to tag a NamedDisplay uncloseable after creation.
+ private static Object globalLock = new Object();
+ private static Collection globalNamedDisplayActive = new ArrayList();
+ private static Collection globalNamedDisplayPassive = new ArrayList();
+
+ public static final String nullDeviceName = "nil" ;
+
public static class NamedDisplay implements Cloneable {
- private String name;
- private long handle;
+ String name;
+ long handle;
+ int refCount;
+ boolean unCloseable;
protected NamedDisplay(String name, long handle) {
this.name=name;
this.handle=handle;
+ this.refCount=1;
+ this.unCloseable=false;
}
- public String getName() { return name; }
- public long getHandle() { return handle; }
+ public final String getName() { return name; }
+ public final String getNameSafe() { return null == name ? nullDeviceName : name; }
+ public final long getHandle() { return handle; }
+ public final int getRefCount() { return refCount; }
+ public final boolean isUncloseable() { return unCloseable; }
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
+
+ public String toString() {
+ return "NamedX11Display["+name+", 0x"+Long.toHexString(handle)+", refCount "+refCount+", unCloseable "+unCloseable+"]";
+ }
+ }
+
+ /** Returns the number of unclosed X11 Displays.
+ * @param realXClosePendingDisplays if true, call XCloseDisplay on the remaining ones
+ */
+ public static int shutdown(boolean realXClosePendingDisplays, boolean verbose) {
+ int num=0;
+ String msg;
+ if(DEBUG||verbose) {
+ msg = "X11Util.Display: Shutdown (active: "+globalNamedDisplayActive.size()+
+ ", passive: "+globalNamedDisplayPassive.size() + ")";
+ if(DEBUG) {
+ Exception e = new Exception(msg);
+ e.printStackTrace();
+ } else if(verbose) {
+ System.err.println(msg);
+ }
+ }
+
+ msg = realXClosePendingDisplays ? "Close" : "Keep" ;
+
+ synchronized(globalLock) {
+ // for all passive displays ..
+ Collection namedDisplays = globalNamedDisplayPassive;
+ globalNamedDisplayPassive = new ArrayList();
+ for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) {
+ NamedDisplay ndpy = (NamedDisplay)iter.next();
+ if(DEBUG||verbose) {
+ System.err.println(msg+" passive: "+ndpy);
+ }
+ if(realXClosePendingDisplays) {
+ X11Lib.XCloseDisplay(ndpy.getHandle());
+ }
+ num++;
+ }
+
+ // for all active displays ..
+ namedDisplays = globalNamedDisplayActive;
+ globalNamedDisplayActive = new ArrayList();
+ for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) {
+ NamedDisplay ndpy = (NamedDisplay)iter.next();
+ if(DEBUG||verbose) {
+ System.err.println(msg+" active: "+ndpy);
+ }
+ if(realXClosePendingDisplays) {
+ X11Lib.XCloseDisplay(ndpy.getHandle());
+ }
+ num++;
+ }
+ }
+ return num;
}
/** Returns a clone of the thread local display map, you may {@link Object#wait()} on it */
@@ -79,48 +153,120 @@ public class X11Util {
return (Map) ((HashMap)getCurrentDisplayMapImpl()).clone();
}
- /** Returns this thread current default display. If it doesn not exist, it is being created */
- public static long getThreadLocalDefaultDisplay() {
- return getThreadLocalDisplay(null);
+ /** Returns this thread current default display. If it doesn not exist, it is being created, otherwise the reference count is increased */
+ public static long createThreadLocalDefaultDisplay() {
+ return createThreadLocalDisplay(null);
}
- /** Returns this thread named display. If it doesn not exist, it is being created */
- public static long getThreadLocalDisplay(String name) {
+ /** Returns this thread named display. If it doesn not exist, it is being created, otherwise the reference count is increased */
+ public static long createThreadLocalDisplay(String name) {
NamedDisplay namedDpy = getCurrentDisplay(name);
if(null==namedDpy) {
+ synchronized(globalLock) {
+ namedDpy = getNamedDisplay(globalNamedDisplayPassive, name);
+ if(null != namedDpy) {
+ if(!globalNamedDisplayPassive.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
+ globalNamedDisplayActive.add(namedDpy);
+ addCurrentDisplay( namedDpy );
+ }
+ }
+ }
+ if(null==namedDpy) {
long dpy = X11Lib.XOpenDisplay(name);
if(0==dpy) {
throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection in Thread "+Thread.currentThread().getName());
}
namedDpy = new NamedDisplay(name, dpy);
- setCurrentDisplay( namedDpy );
+ synchronized(globalLock) {
+ globalNamedDisplayActive.add(namedDpy);
+ addCurrentDisplay( namedDpy );
+ }
if(DEBUG) {
- Exception e = new Exception("X11Util.Display: Created new TLS display("+name+") connection 0x"+Long.toHexString(dpy)+" in thread "+Thread.currentThread().getName());
+ Exception e = new Exception("X11Util.Display: Created new TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
+ e.printStackTrace();
+ }
+ } else {
+ namedDpy.refCount++;
+ if(DEBUG) {
+ Exception e = new Exception("X11Util.Display: Reused TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
e.printStackTrace();
}
}
return namedDpy.getHandle();
}
- /** Closes this thread named display. It returns the handle of the closed display or 0, if it does not exist. */
+ /** Decrease the reference count of this thread named display. If it reaches 0, close it.
+ It returns the handle of the to be closed display.
+ It throws a RuntimeException in case the named display does not exist,
+ or the reference count goes below 0.
+ */
public static long closeThreadLocalDisplay(String name) {
- NamedDisplay namedDpy = removeCurrentDisplay(name);
+ NamedDisplay namedDpy = getCurrentDisplay(name);
if(null==namedDpy) {
+ throw new RuntimeException("X11Util.Display: Display("+name+") with given handle is not mapped to TLS in thread "+Thread.currentThread().getName());
+ }
+ if(0==namedDpy.refCount) {
+ throw new RuntimeException("X11Util.Display: "+namedDpy+" has refCount already 0 in thread "+Thread.currentThread().getName());
+ }
+ long dpy = namedDpy.getHandle();
+ namedDpy.refCount--;
+ if(0==namedDpy.refCount) {
+ synchronized(globalLock) {
+ if(!globalNamedDisplayActive.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
+ if(namedDpy.isUncloseable()) {
+ globalNamedDisplayPassive.add(namedDpy);
+ } else {
+ X11Lib.XCloseDisplay(dpy);
+ }
+ removeCurrentDisplay(namedDpy);
+ }
if(DEBUG) {
- Exception e = new Exception("X11Util.Display: Display("+name+") with given handle is not mapped to TLS in thread "+Thread.currentThread().getName());
+ String type = namedDpy.isUncloseable() ? "passive" : "real" ;
+ Exception e = new Exception("X11Util.Display: Closing ( "+type+" ) TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
e.printStackTrace();
}
- return 0;
- }
- long dpy = namedDpy.getHandle();
- if(DEBUG) {
- Exception e = new Exception("X11Util.Display: Closing TLS Display("+name+") with handle 0x"+Long.toHexString(dpy)+" in thread "+Thread.currentThread().getName());
+ } else if(DEBUG) {
+ Exception e = new Exception("X11Util.Display: Keep TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
e.printStackTrace();
}
- X11Lib.XCloseDisplay(dpy);
return dpy;
}
+ public static String getThreadLocalDisplayName(long handle) {
+ NamedDisplay ndpy = getNamedDisplay(getCurrentDisplayMapImpl().values(), handle);
+ return null != ndpy ? ndpy.getName() : null;
+ }
+
+ public static boolean markThreadLocalDisplayUndeletable(long handle) {
+ NamedDisplay ndpy = getNamedDisplay(getCurrentDisplayMapImpl().values(), handle);
+ if( null != ndpy ) {
+ ndpy.unCloseable=true;
+ return true;
+ }
+ return false;
+ }
+
+ public static String getGlobalDisplayName(long handle, boolean active) {
+ String name;
+ synchronized(globalLock) {
+ NamedDisplay ndpy = getNamedDisplay(active ? globalNamedDisplayActive : globalNamedDisplayPassive, handle);
+ name = null != ndpy ? ndpy.getName() : null;
+ }
+ return name;
+ }
+
+ public static boolean markGlobalDisplayUndeletable(long handle) {
+ boolean r=false;
+ synchronized(globalLock) {
+ NamedDisplay ndpy = getNamedDisplay(globalNamedDisplayActive, handle);
+ if( null != ndpy ) {
+ ndpy.unCloseable=true;
+ r=true;
+ }
+ }
+ return r;
+ }
+
private static Map getCurrentDisplayMapImpl() {
Map displayMap = (Map) currentDisplayMap.get();
if(null==displayMap) {
@@ -132,12 +278,11 @@ public class X11Util {
/** maps the given display to the thread local display map
* and notifies all threads synchronized to this display map. */
- private static NamedDisplay setCurrentDisplay(NamedDisplay newDisplay) {
+ private static NamedDisplay addCurrentDisplay(NamedDisplay newDisplay) {
Map displayMap = getCurrentDisplayMapImpl();
NamedDisplay oldDisplay = null;
synchronized(displayMap) {
- String name = (null==newDisplay.getName())?"nil":newDisplay.getName();
- oldDisplay = (NamedDisplay) displayMap.put(name, newDisplay);
+ oldDisplay = (NamedDisplay) displayMap.put(newDisplay.getNameSafe(), newDisplay);
displayMap.notifyAll();
}
return oldDisplay;
@@ -145,22 +290,45 @@ public class X11Util {
/** removes the mapping of the given name from the thread local display map
* and notifies all threads synchronized to this display map. */
- private static NamedDisplay removeCurrentDisplay(String name) {
+ private static NamedDisplay removeCurrentDisplay(NamedDisplay ndpy) {
Map displayMap = getCurrentDisplayMapImpl();
- NamedDisplay oldDisplay = null;
synchronized(displayMap) {
- if(null==name) name="nil";
- oldDisplay = (NamedDisplay) displayMap.remove(name);
+ NamedDisplay ndpyDel = (NamedDisplay) displayMap.remove(ndpy.getNameSafe());
+ if(ndpyDel!=ndpy) {
+ throw new RuntimeException("Wrong mapping req: "+ndpy+", got "+ndpyDel);
+ }
displayMap.notifyAll();
}
- return oldDisplay;
+ return ndpy;
}
/** Returns the thread local display mapped to the given name */
private static NamedDisplay getCurrentDisplay(String name) {
- if(null==name) name="nil";
+ if(null==name) name=nullDeviceName;
Map displayMap = getCurrentDisplayMapImpl();
return (NamedDisplay) displayMap.get(name);
}
+ private static NamedDisplay getNamedDisplay(Collection namedDisplays, String name) {
+ if(null==name) name=nullDeviceName;
+ for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) {
+ NamedDisplay ndpy = (NamedDisplay)iter.next();
+ if (ndpy.getNameSafe().equals(name)) {
+ return ndpy;
+ }
+ }
+ return null;
+ }
+
+ private static NamedDisplay getNamedDisplay(Collection namedDisplays, long handle) {
+ for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) {
+ NamedDisplay ndpy = (NamedDisplay)iter.next();
+ if (ndpy.getHandle()==handle) {
+ return ndpy;
+ }
+ }
+ return null;
+ }
+
+ private static native void installIOErrorHandler();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
index 52f48660a..69ace3c52 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
@@ -57,7 +57,7 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
/** Creates a new X11GraphicsScreen using a thread local display connection */
public static AbstractGraphicsScreen createDefault() {
NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
- long display = X11Util.getThreadLocalDefaultDisplay();
+ long display = X11Util.createThreadLocalDefaultDisplay();
try {
X11Lib.XLockDisplay(display);
int scrnIdx = X11Lib.DefaultScreen(display);
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
new file mode 100644
index 000000000..4320a8f12
--- /dev/null
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2010 Sven Gothel. 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 Sven Gothel 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
+ * MICROSYSTEMS, 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
+ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+/* Linux headers don't work properly */
+#define __USE_GNU
+#include <dlfcn.h>
+#undef __USE_GNU
+
+/* Current versions of Solaris don't expose the XF86 extensions,
+ although with the recent transition to Xorg this will probably
+ happen in an upcoming release */
+#if !defined(__sun) && !defined(_HPUX)
+#include <X11/extensions/xf86vmode.h>
+#else
+/* Need to provide stubs for these */
+Bool XF86VidModeGetGammaRampSize(
+ Display *display,
+ int screen,
+ int* size)
+{
+ return False;
+}
+
+Bool XF86VidModeGetGammaRamp(
+ Display *display,
+ int screen,
+ int size,
+ unsigned short *red_array,
+ unsigned short *green_array,
+ unsigned short *blue_array) {
+ return False;
+}
+Bool XF86VidModeSetGammaRamp(
+ Display *display,
+ int screen,
+ int size,
+ unsigned short *red_array,
+ unsigned short *green_array,
+ unsigned short *blue_array) {
+ return False;
+}
+#endif /* defined(__sun) || defined(_HPUX) */
+
+/* HP-UX doesn't define RTLD_DEFAULT. */
+#if defined(_HPUX) && !defined(RTLD_DEFAULT)
+#define RTLD_DEFAULT NULL
+#endif
+
+#include "com_jogamp_nativewindow_impl_x11_X11Lib.h"
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ // Workaround for ancient compiler on Solaris/SPARC
+ // #define DBG_PRINT(args...) fprintf(stderr, args);
+ #define DBG_PRINT0(str) fprintf(stderr, str);
+ #define DBG_PRINT1(str, arg1) fprintf(stderr, str, arg1);
+ #define DBG_PRINT2(str, arg1, arg2) fprintf(stderr, str, arg1, arg2);
+ #define DBG_PRINT3(str, arg1, arg2, arg3) fprintf(stderr, str, arg1, arg2, arg3);
+ #define DBG_PRINT4(str, arg1, arg2, arg3, arg4) fprintf(stderr, str, arg1, arg2, arg3, arg4);
+ #define DBG_PRINT5(str, arg1, arg2, arg3, arg4, arg5) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5);
+ #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6);
+ #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+ #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+
+#else
+
+ // Workaround for ancient compiler on Solaris/SPARC
+ // #define DBG_PRINT(args...)
+ #define DBG_PRINT0(str)
+ #define DBG_PRINT1(str, arg1)
+ #define DBG_PRINT2(str, arg1, arg2)
+ #define DBG_PRINT3(str, arg1, arg2, arg3)
+ #define DBG_PRINT4(str, arg1, arg2, arg3, arg4)
+ #define DBG_PRINT5(str, arg1, arg2, arg3, arg4, arg5)
+ #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6)
+ #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
+
+#endif
+
+/* Need to pull this in as we don't have a stub header for it */
+extern Bool XineramaEnabled(Display* display);
+
+static void _FatalError(JNIEnv *env, const char* msg, ...)
+{
+ char buffer[512];
+ va_list ap;
+
+ va_start(ap, msg);
+ vsnprintf(buffer, sizeof(buffer), msg, ap);
+ va_end(ap);
+
+ fprintf(stderr, buffer);
+ (*env)->FatalError(env, buffer);
+}
+
+static const char * const ClazzNameInternalBufferUtil = "com/jogamp/nativewindow/impl/InternalBufferUtil";
+static const char * const ClazzNameInternalBufferUtilStaticCstrName = "copyByteBuffer";
+static const char * const ClazzNameInternalBufferUtilStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;";
+static const char * const ClazzNameByteBuffer = "java/nio/ByteBuffer";
+static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException";
+static jclass clazzInternalBufferUtil = NULL;
+static jmethodID cstrInternalBufferUtil = NULL;
+static jclass clazzByteBuffer = NULL;
+static jclass clazzRuntimeException=NULL;
+
+static void _initClazzAccess(JNIEnv *env) {
+ jclass c;
+
+ if(NULL!=clazzRuntimeException) return ;
+
+ c = (*env)->FindClass(env, ClazzNameRuntimeException);
+ if(NULL==c) {
+ _FatalError(env, "Nativewindow X11Lib: can't find %s", ClazzNameRuntimeException);
+ }
+ clazzRuntimeException = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==clazzRuntimeException) {
+ _FatalError(env, "FatalError: NEWT X11Window: can't use %s", ClazzNameRuntimeException);
+ }
+
+ c = (*env)->FindClass(env, ClazzNameInternalBufferUtil);
+ if(NULL==c) {
+ _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameInternalBufferUtil);
+ }
+ clazzInternalBufferUtil = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==clazzInternalBufferUtil) {
+ _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameInternalBufferUtil);
+ }
+ c = (*env)->FindClass(env, ClazzNameByteBuffer);
+ if(NULL==c) {
+ _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameByteBuffer);
+ }
+ clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==c) {
+ _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameByteBuffer);
+ }
+
+ cstrInternalBufferUtil = (*env)->GetStaticMethodID(env, clazzInternalBufferUtil,
+ ClazzNameInternalBufferUtilStaticCstrName, ClazzNameInternalBufferUtilStaticCstrSignature);
+ if(NULL==cstrInternalBufferUtil) {
+ _FatalError(env, "FatalError: Java_com_jogamp_nativewindow_impl_x11_X11Lib:: can't create %s.%s %s",
+ ClazzNameInternalBufferUtil, ClazzNameInternalBufferUtilStaticCstrName, ClazzNameInternalBufferUtilStaticCstrSignature);
+ }
+}
+
+static void _throwNewRuntimeException(Display * unlockDisplay, JNIEnv *env, const char* msg, ...)
+{
+ char buffer[512];
+ va_list ap;
+
+ if(NULL!=unlockDisplay) {
+ XUnlockDisplay(unlockDisplay);
+ }
+
+ _initClazzAccess(env);
+
+ va_start(ap, msg);
+ vsnprintf(buffer, sizeof(buffer), msg, ap);
+ va_end(ap);
+
+ (*env)->ThrowNew(env, clazzRuntimeException, buffer);
+}
+
+static XIOErrorHandler origIOErrorHandler = NULL;
+static JNIEnv * displayIOErrorHandlerJNIEnv = NULL;
+
+static int displayIOErrorHandler(Display *dpy)
+{
+ _FatalError(displayIOErrorHandlerJNIEnv, "Nativewindow X11 IOError: Display %p not available", dpy);
+ origIOErrorHandler(dpy);
+ return 0;
+}
+
+static void displayIOErrorHandlerEnable(int onoff, JNIEnv * env) {
+ if(onoff) {
+ if(NULL==origIOErrorHandler) {
+ displayIOErrorHandlerJNIEnv = env;
+ origIOErrorHandler = XSetIOErrorHandler(displayIOErrorHandler);
+ }
+ } else {
+ XSetIOErrorHandler(origIOErrorHandler);
+ origIOErrorHandler = NULL;
+ displayIOErrorHandlerJNIEnv = NULL;
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Util_installIOErrorHandler(JNIEnv *env, jclass _unused) {
+ displayIOErrorHandlerEnable(1, env);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_dlopen(JNIEnv *env, jclass _unused, jstring name) {
+ const jbyte* chars;
+ void* res;
+ chars = (*env)->GetStringUTFChars(env, name, NULL);
+ res = dlopen(chars, RTLD_LAZY | RTLD_GLOBAL);
+ (*env)->ReleaseStringUTFChars(env, name, chars);
+ return (jlong) ((intptr_t) res);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_dlsym(JNIEnv *env, jclass _unused, jstring name) {
+ const jbyte* chars;
+ void* res;
+ chars = (*env)->GetStringUTFChars(env, name, NULL);
+ res = dlsym(RTLD_DEFAULT, chars);
+ (*env)->ReleaseStringUTFChars(env, name, chars);
+ return (jlong) ((intptr_t) res);
+}
+
+/* Java->C glue code:
+ * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
+ * Java method: XVisualInfo XGetVisualInfo(long arg0, long arg1, XVisualInfo arg2, java.nio.IntBuffer arg3)
+ * C function: XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * );
+ */
+JNIEXPORT jobject JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_XGetVisualInfoCopied1__JJLjava_nio_ByteBuffer_2Ljava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) {
+ XVisualInfo * _ptr2 = NULL;
+ int * _ptr3 = NULL;
+ XVisualInfo * _res;
+ int count;
+ jobject jbyteSource;
+ jobject jbyteCopy;
+ if(0==arg0) {
+ _FatalError(env, "invalid display connection..");
+ }
+ if (arg2 != NULL) {
+ _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0);
+ }
+ if (arg3 != NULL) {
+ _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset);
+ }
+ _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
+ count = _ptr3[0];
+ if (arg3 != NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
+ }
+ if (_res == NULL) return NULL;
+
+ _initClazzAccess(env);
+
+ jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(XVisualInfo));
+ jbyteCopy = (*env)->CallStaticObjectMethod(env,
+ clazzInternalBufferUtil, cstrInternalBufferUtil, jbyteSource);
+
+ XFree(_res);
+
+ return jbyteCopy;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused, jlong display, jint screen) {
+ jlong r;
+ if(0==display) {
+ _FatalError(env, "invalid display connection..");
+ }
+ r = (jlong) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
+ return r;
+}
+
+/* Java->C glue code:
+ * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
+ * Java method: void XLockDisplay(long display)
+ * C function: void XLockDisplay(Display * display);
+ */
+JNIEXPORT void JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_XLockDisplay__J(JNIEnv *env, jclass _unused, jlong display) {
+ if(0==display) {
+ _FatalError(env, "invalid display connection..");
+ }
+ XLockDisplay((Display *) (intptr_t) display);
+}
+
+/* Java->C glue code:
+ * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
+ * Java method: void XUnlockDisplay(long display)
+ * C function: void XUnlockDisplay(Display * display);
+ */
+JNIEXPORT void JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_XUnlockDisplay__J(JNIEnv *env, jclass _unused, jlong display) {
+ if(0==display) {
+ _FatalError(env, "invalid display connection..");
+ }
+ XUnlockDisplay((Display *) (intptr_t) display);
+}
+
+
+/* Java->C glue code:
+ * Java package: com.jogamp.nativewindow.impl.x11.X11Lib
+ * Java method: int XCloseDisplay(long display)
+ * C function: int XCloseDisplay(Display * display);
+ */
+JNIEXPORT jint JNICALL
+Java_com_jogamp_nativewindow_impl_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused, jlong display) {
+ int _res;
+ if(0==display) {
+ _FatalError(env, "invalid display connection..");
+ }
+ _res = XCloseDisplay((Display *) (intptr_t) display);
+ return _res;
+}
+
+/*
+ * Class: com_jogamp_nativewindow_impl_x11_X11Lib
+ * Method: CreateDummyWindow
+ * Signature: (JIJ)J
+JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummyWindow
+ (JNIEnv *env, jobject obj, jlong display, jint screen_index, jlong visualID)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ int scrn_idx = (int)screen_index;
+ Window windowParent = 0;
+ Window window = 0;
+
+ XVisualInfo visualTemplate;
+ XVisualInfo *pVisualQuery = NULL;
+ Visual *visual = NULL;
+ int depth;
+
+ XSetWindowAttributes xswa;
+ unsigned long attrMask;
+ int n;
+
+ Screen* scrn;
+
+ if(NULL==dpy) {
+ _FatalError(env, "invalid display connection..");
+ return 0;
+ }
+
+ if(visualID<0) {
+ _throwNewRuntimeException(NULL, env, "invalid VisualID ..\n");
+ return 0;
+ }
+
+ XLockDisplay(dpy) ;
+
+ XSync(dpy, False);
+
+ scrn = ScreenOfDisplay(dpy, scrn_idx);
+
+ // try given VisualID on screen
+ memset(&visualTemplate, 0, sizeof(XVisualInfo));
+ visualTemplate.screen = scrn_idx;
+ visualTemplate.visualid = (VisualID)visualID;
+ pVisualQuery = XGetVisualInfo(dpy, VisualIDMask|VisualScreenMask, &visualTemplate,&n);
+ if(pVisualQuery!=NULL) {
+ visual = pVisualQuery->visual;
+ depth = pVisualQuery->depth;
+ visualID = (jlong)pVisualQuery->visualid;
+ XFree(pVisualQuery);
+ pVisualQuery=NULL;
+ }
+ DBG_PRINT5( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, windowParent, visual);
+
+ if (visual==NULL)
+ {
+ _throwNewRuntimeException(dpy, env, "could not query Visual by given VisualID, bail out!\n");
+ return 0;
+ }
+
+ if(pVisualQuery!=NULL) {
+ XFree(pVisualQuery);
+ pVisualQuery=NULL;
+ }
+
+ if(0==windowParent) {
+ windowParent = XRootWindowOfScreen(scrn);
+ }
+
+ attrMask = (CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect) ;
+
+ memset(&xswa, 0, sizeof(xswa));
+ xswa.override_redirect = True; // not decorated
+ xswa.border_pixel = 0;
+ xswa.background_pixel = 0;
+ xswa.event_mask = 0 ; // no events
+ xswa.colormap = XCreateColormap(dpy,
+ XRootWindow(dpy, scrn_idx),
+ visual,
+ AllocNone);
+
+ window = XCreateWindow(dpy,
+ windowParent,
+ 0, 0,
+ 64, 64,
+ 0, // border width
+ depth,
+ InputOutput,
+ visual,
+ attrMask,
+ &xswa);
+
+ XSync(dpy, False);
+
+ XUnlockDisplay(dpy) ;
+
+ DBG_PRINT2( "X11: [CreateWindow] created window %p on display %p\n", window, dpy);
+
+ return (jlong) window;
+}
+ */
+
+
+/*
+ * Class: com_jogamp_nativewindow_impl_x11_X11Lib
+ * Method: DestroyDummyWindow
+ * Signature: (JJ)V
+JNIEXPORT void JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_DestroyDummyWindow
+ (JNIEnv *env, jobject obj, jlong display, jlong window)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ Window w = (Window) window;
+
+ if(NULL==dpy) {
+ _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
+ return;
+ }
+ XLockDisplay(dpy) ;
+
+ XSync(dpy, False);
+ XUnmapWindow(dpy, w);
+ XSync(dpy, False);
+ XDestroyWindow(dpy, w);
+ XSync(dpy, False);
+
+ XUnlockDisplay(dpy) ;
+}
+ */
+
diff --git a/src/newt/classes/com/jogamp/newt/x11/X11Display.java b/src/newt/classes/com/jogamp/newt/x11/X11Display.java
index b8eb80b39..5fd6d9640 100755
--- a/src/newt/classes/com/jogamp/newt/x11/X11Display.java
+++ b/src/newt/classes/com/jogamp/newt/x11/X11Display.java
@@ -61,7 +61,7 @@ public class X11Display extends Display {
}
protected void createNative() {
- long handle= X11Util.getThreadLocalDisplay(name);
+ long handle= X11Util.createThreadLocalDisplay(name);
if (handle == 0 ) {
throw new RuntimeException("Error creating display: "+name);
}
@@ -75,9 +75,7 @@ public class X11Display extends Display {
}
protected void closeNative() {
- if(0==X11Util.closeThreadLocalDisplay(name)) {
- throw new NativeWindowException(this+" was not mapped");
- }
+ X11Util.closeThreadLocalDisplay(name);
}
protected void dispatchMessages() {
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 0fccc94bb..33c5324e2 100755
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -149,6 +149,19 @@ static jint X11KeySym2NewtVKey(KeySym keySym) {
return keySym;
}
+static void _FatalError(JNIEnv *env, const char* msg, ...)
+{
+ char buffer[512];
+ va_list ap;
+
+ va_start(ap, msg);
+ vsnprintf(buffer, sizeof(buffer), msg, ap);
+ va_end(ap);
+
+ fprintf(stderr, buffer);
+ (*env)->FatalError(env, buffer);
+}
+
static const char * const ClazzNameRuntimeException =
"java/lang/RuntimeException";
static jclass runtimeExceptionClz=NULL;
@@ -217,26 +230,6 @@ static void displayDispatchErrorHandlerEnable(int onoff) {
}
}
-static XIOErrorHandler origIOErrorHandler = NULL;
-
-static int displayDispatchIOErrorHandler(Display *dpy)
-{
- fprintf(stderr, "Fatal: NEWT X11 IOError: Display %p not available\n", dpy);
- return 0;
-}
-
-static void displayDispatchIOErrorHandlerEnable(int onoff) {
- if(onoff) {
- if(NULL==origIOErrorHandler) {
- origIOErrorHandler = XSetIOErrorHandler(displayDispatchIOErrorHandler);
- }
- } else {
- XSetIOErrorHandler(origIOErrorHandler);
- origIOErrorHandler = NULL;
- }
-}
-
-
/*
* Class: com_jogamp_newt_x11_X11Display
* Method: initIDs
@@ -259,28 +252,24 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_x11_X11Display_initIDs
if(NULL==newtWindowClz) {
c = (*env)->FindClass(env, ClazzNameNewtWindow);
if(NULL==c) {
- fprintf(stderr, "FatalError: NEWT X11Window: can't find %s\n", ClazzNameNewtWindow);
- return JNI_FALSE;
+ _FatalError(env, "NEWT X11Window: can't find %s", ClazzNameNewtWindow);
}
newtWindowClz = (jclass)(*env)->NewGlobalRef(env, c);
(*env)->DeleteLocalRef(env, c);
if(NULL==newtWindowClz) {
- fprintf(stderr, "FatalError: NEWT X11Window: can't use %s\n", ClazzNameNewtWindow);
- return JNI_FALSE;
+ _FatalError(env, "NEWT X11Window: can't use %s", ClazzNameNewtWindow);
}
}
if(NULL==runtimeExceptionClz) {
c = (*env)->FindClass(env, ClazzNameRuntimeException);
if(NULL==c) {
- fprintf(stderr, "FatalError: NEWT X11Window: can't find %s\n", ClazzNameRuntimeException);
- return JNI_FALSE;
+ _FatalError(env, "NEWT X11Window: can't find %s", ClazzNameRuntimeException);
}
runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c);
(*env)->DeleteLocalRef(env, c);
if(NULL==runtimeExceptionClz) {
- fprintf(stderr, "FatalError: NEWT X11Window: can't use %s\n", ClazzNameRuntimeException);
- return JNI_FALSE;
+ _FatalError(env, "NEWT X11Window: can't use %s", ClazzNameRuntimeException);
}
}
@@ -297,7 +286,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_LockDisplay
{
Display * dpy = (Display *)(intptr_t)display;
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "given display connection is NULL\n");
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;
DBG_PRINT1( "X11: LockDisplay 0x%X\n", dpy);
@@ -314,7 +303,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_UnlockDisplay
{
Display * dpy = (Display *)(intptr_t)display;
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "given display connection is NULL\n");
+ _FatalError(env, "invalid display connection..");
}
XUnlockDisplay(dpy) ;
DBG_PRINT1( "X11: UnlockDisplay 0x%X\n", dpy);
@@ -334,7 +323,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_CompleteDisplay
jlong windowDeleteAtom;
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "given display connection is NULL\n");
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;
@@ -447,8 +436,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_DispatchMessages
return;
}
- displayDispatchIOErrorHandlerEnable(1);
-
// Periodically take a break
while( num_events > 0 ) {
jobject jwindow = NULL;
@@ -462,7 +449,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_DispatchMessages
// num_events = XPending(dpy); // XEventsQueued(dpy, QueuedAfterFlush); // I/O Flush ..
// num_events = XEventsQueued(dpy, QueuedAlready); // Better, no I/O ..
if ( 0 >= XEventsQueued(dpy, QueuedAlready) ) {
- displayDispatchIOErrorHandlerEnable(0);
XUnlockDisplay(dpy) ;
return;
}
@@ -470,8 +456,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Display_DispatchMessages
XNextEvent(dpy, &evt);
num_events--;
- displayDispatchIOErrorHandlerEnable(0);
-
if( 0==evt.xany.window ) {
_throwNewRuntimeException(dpy, env, "event window NULL, bail out!\n");
return ;
@@ -606,8 +590,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_x11_X11Screen_GetScreen
Screen * scrn= NULL;
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return 0;
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy);
@@ -698,8 +681,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_x11_X11Window_CreateWindow
DBG_PRINT4( "X11: CreateWindow %x/%d %dx%d\n", x, y, width, height);
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return 0;
+ _FatalError(env, "invalid display connection..");
}
if(visualID<0) {
@@ -711,7 +693,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_x11_X11Window_CreateWindow
XSync(dpy, False);
- scrn = ScreenOfDisplay(dpy, screen_index);
+ scrn = ScreenOfDisplay(dpy, scrn_idx);
// try given VisualID on screen
memset(&visualTemplate, 0, sizeof(XVisualInfo));
@@ -809,8 +791,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Window_CloseWindow
jobject jwindow;
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return;
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;
@@ -854,8 +835,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Window_setVisible0
DBG_PRINT1( "X11: setVisible0 vis %d\n", visible);
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return;
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;
@@ -903,8 +883,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Window_setSize0
DBG_PRINT6( "X11: setSize0 %d/%d %dx%d, dec %d, vis %d\n", x, y, width, height, decorationToggle, setVisible);
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return;
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;
@@ -963,8 +942,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_x11_X11Window_setPosition0
DBG_PRINT2( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y);
if(dpy==NULL) {
- _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
- return;
+ _FatalError(env, "invalid display connection..");
}
XLockDisplay(dpy) ;