summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrhatcher <[email protected]>2012-12-06 11:48:05 -0600
committerrhatcher <[email protected]>2012-12-06 11:48:05 -0600
commit603609c54139ccb1791b10bef5672f22f030d6a4 (patch)
treeb0c68726a4e6ecf45e1623c7f275b382725c567c
parent811e3791b98fea0dfa3b7d301cb532c54df8dc82 (diff)
parent7a6f6b7a5b028e918a843de9fe16c38da75edba9 (diff)
Merge branch 'master' of https://github.com/sgothel/jogl
-rwxr-xr-xetc/profile.jogl4
-rwxr-xr-xetc/test_dbg.sh2
-rw-r--r--make/build-common.xml1
-rw-r--r--make/build-newt.xml2
-rw-r--r--make/config/nativewindow/x11-CustomJavaCode.java5
-rw-r--r--make/lib/swt/gtk-freebsd-x86_64/README.txt1
-rw-r--r--make/lib/swt/gtk-solaris-x86/README.txt9
-rw-r--r--make/lib/swt/gtk-solaris-x86/swt-debug.jarbin2297932 -> 2276780 bytes
-rwxr-xr-xmake/scripts/java-win64-dbg.bat1
-rwxr-xr-xmake/scripts/tests-x32.sh2
-rwxr-xr-xmake/scripts/tests-x64.bat5
-rwxr-xr-xmake/scripts/tests.sh7
-rw-r--r--src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java381
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableHelper.java53
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java427
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java4
-rw-r--r--src/nativewindow/native/x11/Xmisc.c123
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java12
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java95
-rw-r--r--src/newt/classes/com/jogamp/newt/util/EDTUtil.java5
-rw-r--r--src/newt/classes/jogamp/newt/DefaultEDTUtil.java119
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java33
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java81
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java37
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java14
-rw-r--r--src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java (renamed from src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java)41
-rw-r--r--src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java249
-rw-r--r--src/newt/native/WindowsWindow.c19
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java23
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java343
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java45
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java4
-rw-r--r--www/index.html1038
-rw-r--r--www/media/Java3d.pngbin0 -> 8675 bytes
-rw-r--r--www/media/ardor3d.pngbin0 -> 3007 bytes
-rw-r--r--www/media/dyn4j.pngbin0 -> 5373 bytes
-rw-r--r--www/media/jmonkeyengine.pngbin0 -> 38087 bytes
-rw-r--r--www/media/nifty-logo-new.pngbin0 -> 10305 bytes
-rw-r--r--www/media/ticket2ride_picture4.jpgbin0 -> 71952 bytes
40 files changed, 2241 insertions, 952 deletions
diff --git a/etc/profile.jogl b/etc/profile.jogl
index 7dd51919d..413c0538d 100755
--- a/etc/profile.jogl
+++ b/etc/profile.jogl
@@ -24,6 +24,10 @@ function concat_jogl_list()
}
ARCH=`uname -m`
+if [ "$ARCH" = "i86pc" ] ; then
+ ARCH="x86"
+fi
+
KERNEL=`uname -s | awk ' { printf "%s",tolower($0) ; } '`
if [ "$KERNEL" = "sunos" ] ; then
KERNEL="solaris"
diff --git a/etc/test_dbg.sh b/etc/test_dbg.sh
index f7d0fd2b3..72b2b3fcf 100755
--- a/etc/test_dbg.sh
+++ b/etc/test_dbg.sh
@@ -12,7 +12,7 @@ echo LIBGL_DRIVERS_PATH: $LIBGL_DRIVERS_PATH 2>&1 | tee -a $logfile
echo LIBGL_DEBUG: $LIBGL_DEBUG 2>&1 | tee -a $logfile
echo java $X_ARGS $D_ARGS $* 2>&1 | tee -a $logfile
-CLASSPATH=jar/gluegen-rt.jar:jar/jogl.all.jar
+CLASSPATH=jar/gluegen-rt.jar:jar/jogl-all.jar
export CLASSPATH
echo CLASSPATH: $CLASSPATH
diff --git a/make/build-common.xml b/make/build-common.xml
index a718ae09a..414b0eba2 100644
--- a/make/build-common.xml
+++ b/make/build-common.xml
@@ -428,6 +428,7 @@
<property name="jogl-all-android.jar" value="${jar}/jogl-all-android.jar" />
<property name="jogl-all-android.apk" value="${jar}/jogl-all-android-${android.abi}.apk" />
+ <!-- NativeWindow Compilation .. -->
<path id="swt_gluegen.classpath">
<pathelement location="${gluegen-rt.jar}" />
<pathelement location="${swt.jar}" />
diff --git a/make/build-newt.xml b/make/build-newt.xml
index 7b9a51863..c3b51141f 100644
--- a/make/build-newt.xml
+++ b/make/build-newt.xml
@@ -112,7 +112,7 @@
value="com/jogamp/newt/awt/** com/jogamp/newt/event/awt/** jogamp/newt/awt/** ${java.part.driver.awt}"/>
<property name="java.part.swt"
- value="com/jogamp/newt/swt/**"/>
+ value="com/jogamp/newt/swt/** jogamp/newt/swt/**"/>
<property name="java.part.driver.linux"
value="jogamp/newt/driver/linux/**"/>
diff --git a/make/config/nativewindow/x11-CustomJavaCode.java b/make/config/nativewindow/x11-CustomJavaCode.java
index 8e5da3b2d..4240c5e2f 100644
--- a/make/config/nativewindow/x11-CustomJavaCode.java
+++ b/make/config/nativewindow/x11-CustomJavaCode.java
@@ -28,8 +28,9 @@
public static native int DefaultVisualID(long display, int screen);
- public static native long CreateDummyWindow(long display, int screen_index, int visualID, int width, int height);
- public static native void DestroyDummyWindow(long display, long window);
+ public static native long CreateWindow(long parent, long display, int screen_index, int visualID, int width, int height, boolean input, boolean visible);
+ public static native void DestroyWindow(long display, long window);
+ public static native void SetWindowPosSize(long display, long window, int x, int y, int width, int height);
public static Point GetRelativeLocation(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y) {
return (Point) GetRelativeLocation0(display, screen_index, src_win, dest_win, src_x, src_y);
diff --git a/make/lib/swt/gtk-freebsd-x86_64/README.txt b/make/lib/swt/gtk-freebsd-x86_64/README.txt
new file mode 100644
index 000000000..9380cdd00
--- /dev/null
+++ b/make/lib/swt/gtk-freebsd-x86_64/README.txt
@@ -0,0 +1 @@
+version 3.7.1
diff --git a/make/lib/swt/gtk-solaris-x86/README.txt b/make/lib/swt/gtk-solaris-x86/README.txt
new file mode 100644
index 000000000..bee0fbcb4
--- /dev/null
+++ b/make/lib/swt/gtk-solaris-x86/README.txt
@@ -0,0 +1,9 @@
+Version 4.2.0
+ Note: Version 4.3.0 M3 201210312000 fails to work on OpenIndiana,
+ OS.GTK_WIDGET_WINDOW (handle) returns 0 !
+ javax.media.nativewindow.NativeWindowException: Null gtk-window-handle of SWT handle 0x8490000
+ at com.jogamp.nativewindow.swt.SWTAccessor.gdk_widget_get_window(SWTAccessor.java:308)
+ at com.jogamp.nativewindow.swt.SWTAccessor.getDevice(SWTAccessor.java:335)
+ at com.jogamp.newt.swt.NewtCanvasSWT.<init>(NewtCanvasSWT.java:124)
+ at com.jogamp.newt.swt.NewtCanvasSWT$1.run(NewtCanvasSWT.java:99)
+
diff --git a/make/lib/swt/gtk-solaris-x86/swt-debug.jar b/make/lib/swt/gtk-solaris-x86/swt-debug.jar
index ed0b55ce9..cec0b9ed1 100644
--- a/make/lib/swt/gtk-solaris-x86/swt-debug.jar
+++ b/make/lib/swt/gtk-solaris-x86/swt-debug.jar
Binary files differ
diff --git a/make/scripts/java-win64-dbg.bat b/make/scripts/java-win64-dbg.bat
index c7e8ea599..7ececa5e4 100755
--- a/make/scripts/java-win64-dbg.bat
+++ b/make/scripts/java-win64-dbg.bat
@@ -46,6 +46,7 @@ REM set D_ARGS="-Djogl.debug.DebugGL" "-Djogl.debug.GLDebugMessageHandler" "-Djo
REM set D_ARGS="-Djogl.debug.GLContext" "-Dnewt.debug=all"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnativewindow.debug.TraceLock"
REM set D_ARGS="-Dnativewindow.debug.TraceLock"
+REM set D_ARGS="-Dnewt.debug.Display" "-Dnewt.debug.EDT" "-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.debug.EDT" "-Djogl.debug.GLContext"
REM set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.EDT" "-Dnativewindow.debug=all"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.test.Window.reparent.incompatible=true"
diff --git a/make/scripts/tests-x32.sh b/make/scripts/tests-x32.sh
index a3aed84c3..858ed5fd8 100755
--- a/make/scripts/tests-x32.sh
+++ b/make/scripts/tests-x32.sh
@@ -6,6 +6,8 @@ if [ -e $SDIR/../../../gluegen/make/scripts/setenv-build-jogl-x86.sh ] ; then
. $SDIR/../../../gluegen/make/scripts/setenv-build-jogl-x86.sh
fi
+export SWT_CLASSPATH=`pwd`/lib/swt/gtk-linux-x86/swt-debug.jar
+
. $SDIR/tests.sh `which java` -d32 ../build-x86 $*
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat
index 0266f2bb7..db7e27264 100755
--- a/make/scripts/tests-x64.bat
+++ b/make/scripts/tests-x64.bat
@@ -54,9 +54,10 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestP
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn %*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
+scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn %*
-scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTBug628ResizeDeadlock %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTBug628ResizeDeadlock %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTBug643AsyncExec %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestWindows01NEWT
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index a732d78fa..628ab706b 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -113,7 +113,7 @@ function jrun() {
#D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile"
#D_ARGS="-Djogl.debug.GLProfile"
#D_ARGS="-Dnativewindow.debug.NativeWindow"
- #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT"
+ D_ARGS="-Djogl.debug.GLCanvas -Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT -Djogl.debug.Animator"
#D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Window -Djogl.debug.GLContext"
#D_ARGS="-Dnativewindow.debug.X11Util.XErrorStackDump -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Dnativewindow.debug.X11Util"
#D_ARGS="-Dnativewindow.debug.X11Util -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnewt.debug=all"
@@ -370,9 +370,10 @@ function testawtswt() {
#
#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTEclipseGLCanvas01GLn $*
#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn $*
-#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
+testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn $*
-testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTBug628ResizeDeadlock $*
+#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTBug628ResizeDeadlock $*
+#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTBug643AsyncExec $*
#
# newt.awt (testawt)
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index e80079c20..0320c63ae 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -29,10 +29,16 @@ package com.jogamp.opengl.swt;
import java.util.List;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.UpstreamSurfaceHook;
+import javax.media.nativewindow.VisualIDHolder;
+import javax.media.nativewindow.VisualIDHolder.VIDType;
import javax.media.opengl.GL;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
@@ -48,21 +54,20 @@ import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
import javax.media.opengl.Threading;
+import jogamp.nativewindow.x11.X11Util;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableHelper;
import jogamp.opengl.GLDrawableImpl;
import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import com.jogamp.common.GlueGenVersion;
@@ -71,13 +76,14 @@ import com.jogamp.common.util.VersionUtil;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.nativewindow.swt.SWTAccessor;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.opengl.JoglVersion;
/**
* Native SWT Canvas implementing GLAutoDrawable
- *
- * <p>Note: To employ custom GLCapabilities, NewtCanvasSWT shall be used instead.</p>
- *
+ * <p>
+ * Implementation allows use of custom {@link GLCapabilities}.
+ * </p>
*/
public class GLCanvas extends Canvas implements GLAutoDrawable {
private static final boolean DEBUG = Debug.debug("GLCanvas");
@@ -101,11 +107,15 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final GLCapabilitiesImmutable capsRequested;
private final GLCapabilitiesChooser capsChooser;
+ private volatile Rectangle clientArea;
private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
- private GLContextImpl context;
+ private volatile GLContextImpl context;
/* Native window surface */
- private AbstractGraphicsDevice device;
+ private final boolean useX11GTK;
+ private volatile long gdkWindow; // either GDK child window ..
+ private volatile long x11Window; // .. or X11 child window (for GL rendering)
+ private final AbstractGraphicsScreen screen;
/* Construction parameters stored for GLAutoDrawable accessor methods */
private int additionalCtxCreationFlags = 0;
@@ -133,7 +143,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public void run() {
if (sendReshape) {
- helper.reshape(GLCanvas.this, 0, 0, getWidth(), getHeight());
+ helper.reshape(GLCanvas.this, 0, 0, clientArea.width, clientArea.height);
sendReshape = false;
}
helper.display(GLCanvas.this);
@@ -141,13 +151,15 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
};
/* Action to make specified context current prior to running displayAction */
- private final Runnable makeCurrentAndDisplayOnEDTAction = new Runnable() {
+ private final Runnable makeCurrentAndDisplayOnGLAction = new Runnable() {
@Override
public void run() {
final RecursiveLock _lock = lock;
_lock.lock();
- try {
- helper.invokeGL(drawable, context, displayAction, initAction);
+ try {
+ if( !GLCanvas.this.isDisposed() ) {
+ helper.invokeGL(drawable, context, displayAction, initAction);
+ }
} finally {
_lock.unlock();
}
@@ -155,13 +167,14 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
};
/* Swaps buffers, assuming the GLContext is current */
- private final Runnable swapBuffersOnEDTAction = new Runnable() {
+ private final Runnable swapBuffersOnGLAction = new Runnable() {
@Override
public void run() {
final RecursiveLock _lock = lock;
_lock.lock();
try {
- if(null != drawable) {
+ final boolean drawableOK = null != drawable && drawable.isRealized();
+ if( drawableOK && !GLCanvas.this.isDisposed() ) {
drawable.swapBuffers();
}
} finally {
@@ -193,7 +206,11 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
// Catch dispose GLExceptions by GLEventListener, just 'print' them
// so we can continue with the destruction.
try {
- helper.disposeGL(GLCanvas.this, context);
+ if( !GLCanvas.this.isDisposed() ) {
+ helper.disposeGL(GLCanvas.this, context);
+ } else {
+ context.destroy();
+ }
} catch (GLException gle) {
gle.printStackTrace();
}
@@ -204,13 +221,14 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
drawable.setRealized(false);
drawable = null;
}
- // SWT is owner of the device handle, not us.
- // Hence close() operation is a NOP.
- if (null != device) {
- device.close();
- device = null;
+ if( 0 != x11Window) {
+ SWTAccessor.destroyX11Window(screen.getDevice(), x11Window);
+ x11Window = 0;
+ } else if( 0 != gdkWindow) {
+ SWTAccessor.destroyGDKWindow(gdkWindow);
+ gdkWindow = 0;
}
- SWTAccessor.setRealized(GLCanvas.this, false); // unrealize ..
+ screen.getDevice().close();
if (animatorPaused) {
animator.resume();
@@ -235,18 +253,15 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
final RecursiveLock _lock = lock;
_lock.lock();
try {
- listener = helper.disposeGLEventListener(GLCanvas.this, drawable, context, listener, remove);
+ if( !GLCanvas.this.isDisposed() ) {
+ listener = helper.disposeGLEventListener(GLCanvas.this, drawable, context, listener, remove);
+ }
} finally {
_lock.unlock();
}
}
};
- /**
- * Storage for the client area rectangle so that it may be accessed from outside of the SWT thread.
- */
- private volatile Rectangle clientArea;
-
/**
* Creates an instance using {@link #GLCanvas(Composite, int, GLCapabilitiesImmutable, GLCapabilitiesChooser, GLContext)}
* on the SWT thread.
@@ -286,61 +301,80 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
* @param style
* Optional SWT style bit-field. The {@link SWT#NO_BACKGROUND} bit is set before passing this up to the
* Canvas constructor, so OpenGL handles the background.
- * @param caps
+ * @param capsReqUser
* Optional GLCapabilities. If not provided, the default capabilities for the default GLProfile for the
* graphics device determined by the parent Composite are used. Note that the GLCapabilities that are
* actually used may differ based on the capabilities of the graphics device.
- * @param chooser
+ * @param capsChooser
* Optional GLCapabilitiesChooser to customize the selection of the used GLCapabilities based on the
* requested GLCapabilities, and the available capabilities of the graphics device.
* @param shareWith
* Optional GLContext to share state (textures, vbos, shaders, etc.) with.
*/
- public GLCanvas(final Composite parent, final int style, GLCapabilitiesImmutable caps,
- final GLCapabilitiesChooser chooser, final GLContext shareWith) {
+ public GLCanvas(final Composite parent, final int style, GLCapabilitiesImmutable capsReqUser,
+ final GLCapabilitiesChooser capsChooser, final GLContext shareWith) {
/* NO_BACKGROUND required to avoid clearing bg in native SWT widget (we do this in the GL display) */
super(parent, style | SWT.NO_BACKGROUND);
GLProfile.initSingleton(); // ensure JOGL is completly initialized
SWTAccessor.setRealized(this, true);
-
+
clientArea = GLCanvas.this.getClientArea();
/* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite).
* Note: SWT is owner of the native handle, hence closing operation will be a NOP. */
- device = SWTAccessor.getDevice(this);
+ final AbstractGraphicsDevice swtDevice = SWTAccessor.getDevice(this);
+
+ useX11GTK = SWTAccessor.useX11GTK();
+ if(useX11GTK) {
+ // Decoupled X11 Device/Screen allowing X11 display lock-free off-thread rendering
+ final long x11DeviceHandle = X11Util.openDisplay(swtDevice.getConnection());
+ if( 0 == x11DeviceHandle ) {
+ throw new RuntimeException("Error creating display(EDT): "+swtDevice.getConnection());
+ }
+ final AbstractGraphicsDevice x11Device = new X11GraphicsDevice(x11DeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
+ screen = SWTAccessor.getScreen(x11Device, -1 /* default */);
+ } else {
+ screen = SWTAccessor.getScreen(swtDevice, -1 /* default */);
+ }
/* Select default GLCapabilities if none was provided, otherwise clone provided caps to ensure safety */
- if(null == caps) {
- caps = new GLCapabilities(GLProfile.getDefault(device));
+ if(null == capsReqUser) {
+ capsReqUser = new GLCapabilities(GLProfile.getDefault(screen.getDevice()));
}
- this.capsRequested = caps;
- this.capsChooser = chooser;
+
+ this.capsRequested = capsReqUser;
+ this.capsChooser = capsChooser;
this.shareWith = shareWith;
// post create .. when ready
+ gdkWindow = 0;
+ x11Window = 0;
drawable = null;
context = null;
- /* Register SWT listeners (e.g. PaintListener) to render/resize GL surface. */
- /* TODO: verify that these do not need to be manually de-registered when destroying the SWT component */
- addPaintListener(new PaintListener() {
- @Override
- public void paintControl(final PaintEvent arg0) {
- if ( !helper.isAnimatorAnimatingOnOtherThread() ) {
- display(); // checks: null != drawable
- }
- }
- });
-
- addControlListener(new ControlAdapter() {
- @Override
- public void controlResized(final ControlEvent arg0) {
- updateSizeCheck();
- }
- });
+ final Listener listener = new Listener () {
+ @Override
+ public void handleEvent (Event event) {
+ switch (event.type) {
+ case SWT.Paint:
+ displayIfNoAnimatorNoCheck();
+ break;
+ case SWT.Resize:
+ updateSizeCheck();
+ break;
+ case SWT.Dispose:
+ GLCanvas.this.dispose();
+ break;
+ }
+ }
+ };
+ addListener (SWT.Resize, listener);
+ addListener (SWT.Paint, listener);
+ addListener (SWT.Dispose, listener);
}
+
private final UpstreamSurfaceHook swtCanvasUpStreamHook = new UpstreamSurfaceHook() {
@Override
public final void create(ProxySurface s) { /* nop */ }
@@ -372,11 +406,13 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
) {
clientArea = nClientArea; // write back new value
- GLDrawableImpl _drawable = drawable;
- if( null != _drawable ) {
- if(DEBUG) {
- System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.width+"x"+nClientArea.height+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
- }
+ final GLDrawableImpl _drawable = drawable;
+ final boolean drawableOK = null != _drawable && _drawable.isRealized();
+ if(DEBUG) {
+ final long dh = drawableOK ? _drawable.getHandle() : 0;
+ System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.x+"/"+nClientArea.y+" "+nClientArea.width+"x"+nClientArea.height+" - drawableHandle 0x"+Long.toHexString(dh));
+ }
+ if( drawableOK ) {
if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
final RecursiveLock _lock = lock;
_lock.lock();
@@ -389,66 +425,154 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
} finally {
_lock.unlock();
}
- sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
- }
- }
+ }
+ }
+ if(0 != x11Window) {
+ SWTAccessor.resizeX11Window(screen.getDevice(), clientArea, x11Window);
+ } else if(0 != gdkWindow) {
+ SWTAccessor.resizeGDKWindow(clientArea, gdkWindow);
+ }
+ sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
}
}
- @Override
- public void display() {
- if( null != drawable || validateDrawableAndContext() ) {
- runInGLThread(makeCurrentAndDisplayOnEDTAction);
- }
+ private boolean isValidAndVisibleOnEDTActionResult;
+ private final Runnable isValidAndVisibleOnEDTAction = new Runnable() {
+ @Override
+ public void run() {
+ isValidAndVisibleOnEDTActionResult = !GLCanvas.this.isDisposed() && GLCanvas.this.isVisible();
+ } };
+
+ private final boolean isValidAndVisibleOnEDT() {
+ synchronized(isValidAndVisibleOnEDTAction) {
+ runOnEDTIfAvail(true, isValidAndVisibleOnEDTAction);
+ return isValidAndVisibleOnEDTActionResult;
+ }
}
-
- /** assumes drawable == null ! */
- protected final boolean validateDrawableAndContext() {
- if( GLCanvas.this.isDisposed() ) {
+ /** assumes drawable == null || !drawable.isRealized() ! Checks of !isDispose() and isVisible() */
+ protected final boolean validateDrawableAndContextWithCheck() {
+ if( !isValidAndVisibleOnEDT() ) {
return false;
}
+ return validateDrawableAndContextPostCheck();
+ }
+
+ /** assumes drawable == null || !drawable.isRealized() ! No check of !isDispose() and isVisible() */
+ protected final boolean validateDrawableAndContextPostCheck() {
final Rectangle nClientArea = clientArea;
if(0 >= nClientArea.width || 0 >= nClientArea.height) {
return false;
}
+ final boolean res;
final RecursiveLock _lock = lock;
_lock.lock();
try {
- final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(capsRequested.getGLProfile());
-
- /* Native handle for the control, used to associate with GLContext */
- final long nativeWindowHandle = SWTAccessor.getWindowHandle(this);
-
- /* Create a NativeWindow proxy for the SWT canvas */
- ProxySurface proxySurface = null;
- try {
- proxySurface = glFactory.createProxySurface(device, 0 /* screenIdx */, nativeWindowHandle,
- capsRequested, capsChooser, swtCanvasUpStreamHook);
- } catch (GLException gle) {
- // not ready yet ..
- if(DEBUG) { System.err.println(gle.getMessage()); }
+ if(null == drawable) {
+ createDrawableAndContext();
}
-
- if(null != proxySurface) {
- /* Associate a GL surface with the proxy */
- drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
+ if(null != drawable) {
drawable.setRealized(true);
-
- context = (GLContextImpl) drawable.createContext(shareWith);
+ res = drawable.isRealized();
+ } else {
+ res = false;
}
} finally {
_lock.unlock();
+ }
+
+ if(res) {
+ sendReshape = true;
+ if(DEBUG) {
+ System.err.println("SWT GLCanvas realized! "+this+", "+drawable);
+ // Thread.dumpStack();
+ }
}
- final boolean res = null != drawable;
- if(DEBUG && res) {
- System.err.println("SWT GLCanvas realized! "+this+", "+drawable);
- Thread.dumpStack();
- }
- return res;
+ return res;
}
+ private final void createDrawableAndContext() {
+ final AbstractGraphicsDevice device = screen.getDevice();
+ device.open();
+
+ final long nativeWindowHandle;
+ if( useX11GTK ) {
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(device, capsRequested);
+ final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capsChooser, screen, VisualIDHolder.VID_UNDEFINED);
+ if(DEBUG) {
+ System.err.println("SWT.GLCanvas.X11 factory: "+factory+", chosen config: "+cfg);
+ }
+ if (null == cfg) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+ final int visualID = cfg.getVisualID(VIDType.NATIVE);
+ if( VisualIDHolder.VID_UNDEFINED != visualID ) {
+ // gdkWindow = SWTAccessor.createCompatibleGDKChildWindow(this, visualID, clientArea.width, clientArea.height);
+ // nativeWindowHandle = SWTAccessor.gdk_window_get_xwindow(gdkWindow);
+ x11Window = SWTAccessor.createCompatibleX11ChildWindow(screen, this, visualID, clientArea.width, clientArea.height);
+ nativeWindowHandle = x11Window;
+ } else {
+ throw new GLException("Could not choose valid visualID: 0x"+Integer.toHexString(visualID)+", "+this);
+ }
+ } else {
+ nativeWindowHandle = SWTAccessor.getWindowHandle(this);
+ }
+ final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(capsRequested.getGLProfile());
+
+ // Create a NativeWindow proxy for the SWT canvas
+ ProxySurface proxySurface = glFactory.createProxySurface(device, screen.getIndex(), nativeWindowHandle,
+ capsRequested, capsChooser, swtCanvasUpStreamHook);
+ // Associate a GL surface with the proxy
+ drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setContextCreationFlags(additionalCtxCreationFlags);
+ }
+
+ @Override
+ public void update() {
+ // don't paint background etc .. nop avoids flickering
+ // super.update();
+ }
+
+ /**
+ @Override
+ public boolean forceFocus() {
+ final boolean r = super.forceFocus();
+ if(r && 0 != gdkWindow) {
+ SWTGTKUtil.focusGDKWindow(gdkWindow);
+ }
+ return r;
+ } */
+
+ @Override
+ public void dispose() {
+ runInGLThread(disposeOnEDTGLAction);
+ super.dispose();
+ }
+
+ private final void displayIfNoAnimatorNoCheck() {
+ if ( !helper.isAnimatorAnimatingOnOtherThread() ) {
+ final boolean drawableOK = null != drawable && drawable.isRealized();
+ if( drawableOK || validateDrawableAndContextPostCheck() ) {
+ runInGLThread(makeCurrentAndDisplayOnGLAction);
+ }
+ }
+ }
+
+ //
+ // GL[Auto]Drawable
+ //
+
+ @Override
+ public void display() {
+ final boolean drawableOK = null != drawable && drawable.isRealized();
+ if( drawableOK || validateDrawableAndContextWithCheck() ) {
+ runInGLThread(makeCurrentAndDisplayOnGLAction);
+ }
+ }
+
@Override
public final Object getUpstreamWidget() {
return this;
@@ -674,18 +798,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public void swapBuffers() throws GLException {
- runInGLThread(swapBuffersOnEDTAction);
- }
-
- @Override
- public void update() {
- // don't paint background etc .. nop avoids flickering
- }
-
- @Override
- public void dispose() {
- runInGLThread(disposeOnEDTGLAction);
- super.dispose();
+ runInGLThread(swapBuffersOnGLAction);
}
/**
@@ -694,24 +807,66 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
* <li>Mac OSX
* <ul>
* <!--li>AWT EDT: In case AWT is available, the AWT EDT is the OSX UI main thread</li-->
- * <li><i>Main Thread</i>: Run on OSX UI main thread.</li>
+ * <!--li><i>Main Thread</i>: Run on OSX UI main thread.</li-->
+ * <li>Current thread</li>
* </ul></li>
* <li>Linux, Windows, ..
* <ul>
- * <li>Use {@link Threading#invokeOnOpenGLThread(boolean, Runnable)}</li>
+ * <!--li>Use {@link Threading#invokeOnOpenGLThread(boolean, Runnable)}</li-->
+ * <li>Current thread</li>
* </ul></li>
* </ul>
+ * The current thread seems to be valid for all platforms,
+ * since no SWT lifecycle tasks are being performed w/ this call.
+ * Only GL task, which are independent from the SWT threading model.
+ *
* @see Platform#AWT_AVAILABLE
* @see Platform#getOSType()
*/
- private static void runInGLThread(final Runnable action) {
+ private void runInGLThread(final Runnable action) {
+ /**
if(Platform.OSType.MACOS == Platform.OS_TYPE) {
SWTAccessor.invoke(true, action);
} else {
Threading.invokeOnOpenGLThread(true, action);
- }
+ } */
+ /**
+ if( !isDisposed() ) {
+ final Display d = getDisplay();
+ if( d.getThread() == Thread.currentThread() ) {
+ action.run();
+ } else {
+ d.syncExec(action);
+ }
+ } */
+ action.run();
+ }
+
+ private void runOnEDTIfAvail(boolean wait, final Runnable action) {
+ final Display d = isDisposed() ? null : getDisplay();
+ if( null == d || d.isDisposed() || d.getThread() == Thread.currentThread() ) {
+ action.run();
+ } else if(wait) {
+ d.syncExec(action);
+ } else {
+ d.asyncExec(action);
+ }
}
+ @Override
+ public String toString() {
+ final GLDrawable _drawable = drawable;
+ final int dw = (null!=_drawable) ? _drawable.getWidth() : -1;
+ final int dh = (null!=_drawable) ? _drawable.getHeight() : -1;
+
+ return "SWT-GLCanvas[Realized "+isRealized()+
+ ",\n\t"+((null!=_drawable)?_drawable.getClass().getName():"null-drawable")+
+ ",\n\tFactory "+getFactory()+
+ ",\n\thandle 0x"+Long.toHexString(getHandle())+
+ ",\n\tDrawable size "+dw+"x"+dh+
+ ",\n\tSWT size "+getWidth()+"x"+getHeight()+"]";
+ }
+
public static void main(final String[] args) {
System.err.println(VersionUtil.getPlatformInfo());
System.err.println(GlueGenVersion.getInstance());
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index 1a18b3432..0f8b6b816 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -890,35 +890,38 @@ public class GLDrawableHelper {
}
}
int res = GLContext.CONTEXT_NOT_CURRENT;
-
+
try {
- res = context.makeCurrent();
- if (GLContext.CONTEXT_NOT_CURRENT != res) {
- perThreadInitAction.set(initAction);
- if (GLContext.CONTEXT_CURRENT_NEW == res) {
- if (DEBUG) {
- System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running initAction");
- }
- initAction.run();
- }
- runnable.run();
- if ( autoSwapBufferMode ) {
- drawable.swapBuffers();
+ res = context.makeCurrent();
+ if (GLContext.CONTEXT_NOT_CURRENT != res) {
+ try {
+ perThreadInitAction.set(initAction);
+ if (GLContext.CONTEXT_CURRENT_NEW == res) {
+ if (DEBUG) {
+ System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running initAction");
+ }
+ initAction.run();
+ }
+ runnable.run();
+ if ( autoSwapBufferMode ) {
+ drawable.swapBuffers();
+ }
+ } finally {
+ try {
+ context.release();
+ } catch (Exception e) {
+ System.err.println("Catched: "+e.getMessage());
+ e.printStackTrace();
+ }
+ }
}
- }
} finally {
- try {
- context.release();
- } catch (Exception e) {
- System.err.println("Catched: "+e.getMessage());
- e.printStackTrace();
- }
- if (lastContext != null) {
- final int res2 = lastContext.makeCurrent();
- if (null != lastInitAction && res2 == GLContext.CONTEXT_CURRENT_NEW) {
- lastInitAction.run();
+ if (lastContext != null) {
+ final int res2 = lastContext.makeCurrent();
+ if (null != lastInitAction && res2 == GLContext.CONTEXT_CURRENT_NEW) {
+ lastInitAction.run();
+ }
}
- }
}
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index fca132f3f..eba26c7d3 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -34,6 +34,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import org.eclipse.swt.graphics.GCData;
+import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import javax.media.nativewindow.AbstractGraphicsScreen;
@@ -44,6 +45,7 @@ import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.VisualIDHolder;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
@@ -53,53 +55,93 @@ import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.nativewindow.x11.X11Lib;
public class SWTAccessor {
- static final Field swt_control_handle;
- static final boolean swt_uses_long_handles;
+ private static final boolean DEBUG = true;
+
+ private static final Field swt_control_handle;
+ private static final boolean swt_uses_long_handles;
+
+ private static Object swt_osx_init = new Object();
+ private static Field swt_osx_control_view = null;
+ private static Field swt_osx_view_id = null;
+
+ private static final String nwt;
+ private static final boolean isOSX;
+ private static final boolean isWindows;
+ private static final boolean isX11;
+ private static final boolean isX11GTK;
// X11/GTK, Windows/GDI, ..
- static final String str_handle = "handle";
+ private static final String str_handle = "handle";
// OSX/Cocoa
- static final String str_view = "view"; // OSX
- static final String str_id = "id"; // OSX
+ private static final String str_osx_view = "view"; // OSX
+ private static final String str_osx_id = "id"; // OSX
// static final String str_NSView = "org.eclipse.swt.internal.cocoa.NSView";
- static final Method swt_control_internal_new_GC;
- static final Method swt_control_internal_dispose_GC;
- static final String str_internal_new_GC = "internal_new_GC";
- static final String str_internal_dispose_GC = "internal_dispose_GC";
+ private static final Method swt_control_internal_new_GC;
+ private static final Method swt_control_internal_dispose_GC;
+ private static final String str_internal_new_GC = "internal_new_GC";
+ private static final String str_internal_dispose_GC = "internal_dispose_GC";
- static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS";
- static final Class<?> OS_gtk_class;
- static final Method OS_gtk_widget_realize;
- static final Method OS_gtk_widget_unrealize; // optional (removed in SWT 4.3)
- static final Method OS_GTK_WIDGET_WINDOW;
- static final Method OS_gdk_x11_drawable_get_xdisplay;
- static final Method OS_gdk_x11_drawable_get_xid;
- static final String str_gtk_widget_realize = "gtk_widget_realize";
- static final String str_gtk_widget_unrealize = "gtk_widget_unrealize";
- static final String str_GTK_WIDGET_WINDOW = "GTK_WIDGET_WINDOW";
- static final String str_gdk_x11_drawable_get_xdisplay = "gdk_x11_drawable_get_xdisplay";
- static final String str_gdk_x11_drawable_get_xid = "gdk_x11_drawable_get_xid";
+ private static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS";
+ public static final Class<?> OS_gtk_class;
+ private static final String str_OS_gtk_version = "GTK_VERSION";
+ public static final VersionNumber OS_gtk_version;
+
+ private static final Method OS_gtk_widget_realize;
+ private static final Method OS_gtk_widget_unrealize; // optional (removed in SWT 4.3)
+ private static final Method OS_GTK_WIDGET_WINDOW;
+ private static final Method OS_gtk_widget_get_window;
+ private static final Method OS_gdk_x11_drawable_get_xdisplay;
+ private static final Method OS_gdk_x11_display_get_xdisplay;
+ private static final Method OS_gdk_window_get_display;
+ private static final Method OS_gdk_x11_drawable_get_xid;
+ private static final Method OS_gdk_x11_window_get_xid;
+ private static final Method OS_gdk_window_set_back_pixmap;
+
+ private static final String str_gtk_widget_realize = "gtk_widget_realize";
+ private static final String str_gtk_widget_unrealize = "gtk_widget_unrealize";
+ private static final String str_GTK_WIDGET_WINDOW = "GTK_WIDGET_WINDOW";
+ private static final String str_gtk_widget_get_window = "gtk_widget_get_window";
+ private static final String str_gdk_x11_drawable_get_xdisplay = "gdk_x11_drawable_get_xdisplay";
+ private static final String str_gdk_x11_display_get_xdisplay = "gdk_x11_display_get_xdisplay";
+ private static final String str_gdk_window_get_display = "gdk_window_get_display";
+ private static final String str_gdk_x11_drawable_get_xid = "gdk_x11_drawable_get_xid";
+ private static final String str_gdk_x11_window_get_xid = "gdk_x11_window_get_xid";
+ private static final String str_gdk_window_set_back_pixmap = "gdk_window_set_back_pixmap";
+
+ private static final VersionNumber GTK_VERSION_2_14_0 = new VersionNumber(2, 14, 0);
+ private static final VersionNumber GTK_VERSION_2_24_0 = new VersionNumber(2, 24, 0);
+ private static final VersionNumber GTK_VERSION_3_0_0 = new VersionNumber(3, 0, 0);
+
+ private static VersionNumber GTK_VERSION(int version) {
+ // return (major << 16) + (minor << 8) + micro;
+ final int micro = ( version ) & 0x0f;
+ final int minor = ( version >> 8 ) & 0x0f;
+ final int major = ( version >> 16 ) & 0x0f;
+ return new VersionNumber(major, minor, micro);
+ }
static {
- Field f = null;
-
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
NativeWindowFactory.initSingleton(); // last resort ..
return null;
} } );
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
-
- if(NativeWindowFactory.TYPE_MACOSX != nwt ) {
+ nwt = NativeWindowFactory.getNativeWindowType(false);
+ isOSX = NativeWindowFactory.TYPE_MACOSX == nwt;
+ isWindows = NativeWindowFactory.TYPE_WINDOWS == nwt;
+ isX11 = NativeWindowFactory.TYPE_X11 == nwt;
+
+ Field f = null;
+ if( !isOSX ) {
try {
f = Control.class.getField(str_handle);
} catch (Exception ex) {
throw new NativeWindowException(ex);
}
- }
+ }
swt_control_handle = f; // maybe null !
boolean ulh;
@@ -131,17 +173,34 @@ public class SWTAccessor {
}
swt_control_internal_dispose_GC = m;
- Class<?> c=null;
- Method m1=null, m2=null, m3=null, m4=null, m5=null;
- Class<?> handleType = swt_uses_long_handles ? long.class : int.class ;
- if( NativeWindowFactory.TYPE_X11 == nwt ) {
+ Class<?> c=null;
+ VersionNumber _gtk_version = new VersionNumber(0, 0, 0);
+ Method m1=null, m2=null, m3=null, m4=null, m5=null, m6=null, m7=null, m8=null, m9=null, ma=null;
+ final Class<?> handleType = swt_uses_long_handles ? long.class : int.class ;
+ if( isX11 ) {
// mandatory
try {
c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader());
+ Field field_OS_gtk_version = c.getField(str_OS_gtk_version);
+ _gtk_version = GTK_VERSION(field_OS_gtk_version.getInt(null));
m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType);
- m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType);
- m4 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType);
- m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType);
+ if (_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) {
+ m4 = c.getDeclaredMethod(str_gtk_widget_get_window, handleType);
+ } else {
+ m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType);
+ }
+ if (_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0) {
+ m6 = c.getDeclaredMethod(str_gdk_x11_display_get_xdisplay, handleType);
+ m7 = c.getDeclaredMethod(str_gdk_window_get_display, handleType);
+ } else {
+ m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType);
+ }
+ if (_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0) {
+ m9 = c.getDeclaredMethod(str_gdk_x11_window_get_xid, handleType);
+ } else {
+ m8 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType);
+ }
+ ma = c.getDeclaredMethod(str_gdk_window_set_back_pixmap, handleType, handleType, boolean.class);
} catch (Exception ex) { throw new NativeWindowException(ex); }
// optional
try {
@@ -149,25 +208,41 @@ public class SWTAccessor {
} catch (Exception ex) { }
}
OS_gtk_class = c;
+ OS_gtk_version = _gtk_version;
OS_gtk_widget_realize = m1;
OS_gtk_widget_unrealize = m2;
OS_GTK_WIDGET_WINDOW = m3;
- OS_gdk_x11_drawable_get_xdisplay = m4;
- OS_gdk_x11_drawable_get_xid = m5;
+ OS_gtk_widget_get_window = m4;
+ OS_gdk_x11_drawable_get_xdisplay = m5;
+ OS_gdk_x11_display_get_xdisplay = m6;
+ OS_gdk_window_get_display = m7;
+ OS_gdk_x11_drawable_get_xid = m8;
+ OS_gdk_x11_window_get_xid = m9;
+ OS_gdk_window_set_back_pixmap = ma;
+
+ isX11GTK = isX11 && null != OS_gtk_class;
+
+ if(DEBUG) {
+ System.err.println("SWTAccessor.<init>: GTK Version: "+OS_gtk_version);
+ }
}
-
- static Object getIntOrLong(long arg) {
+
+ private static Number getIntOrLong(long arg) {
if(swt_uses_long_handles) {
return new Long(arg);
}
return new Integer((int) arg);
}
- static void callStaticMethodL2V(Method m, long arg) {
+ private static void callStaticMethodL2V(Method m, long arg) {
ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) });
}
- static long callStaticMethodL2L(Method m, long arg) {
+ private static void callStaticMethodLLZ2V(Method m, long arg0, long arg1, boolean arg3) {
+ ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg0), getIntOrLong(arg1), Boolean.valueOf(arg3) });
+ }
+
+ private static long callStaticMethodL2L(Method m, long arg) {
Object o = ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) });
if(o instanceof Number) {
return ((Number)o).longValue();
@@ -175,33 +250,114 @@ public class SWTAccessor {
throw new InternalError("SWT method "+m.getName()+" didn't return int or long but "+o.getClass());
}
}
-
+
+ //
+ // Public properties
+ //
+
public static boolean isUsingLongHandles() {
return swt_uses_long_handles;
}
- public static long getHandle(Control swtControl) {
+ public static boolean useX11GTK() { return isX11GTK; }
+ public static VersionNumber GTK_VERSION() { return OS_gtk_version; }
+
+ //
+ // Common GTK
+ //
+
+ public static long gdk_widget_get_window(long handle) {
+ final long window;
+ if (OS_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) {
+ window = callStaticMethodL2L(OS_gtk_widget_get_window, handle);
+ } else {
+ window = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
+ }
+ if(0 == window) {
+ throw new NativeWindowException("Null gtk-window-handle of SWT handle 0x"+Long.toHexString(handle));
+ }
+ return window;
+ }
+
+ public static long gdk_window_get_xdisplay(long window) {
+ final long xdisplay;
+ if (OS_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0) {
+ final long display = callStaticMethodL2L(OS_gdk_window_get_display, window);
+ if(0 == display) {
+ throw new NativeWindowException("Null display-handle of gtk-window-handle 0x"+Long.toHexString(window));
+ }
+ xdisplay = callStaticMethodL2L(OS_gdk_x11_display_get_xdisplay, display);
+ } else {
+ xdisplay = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, window);
+ }
+ if(0 == xdisplay) {
+ throw new NativeWindowException("Null x11-display-handle of gtk-window-handle 0x"+Long.toHexString(window));
+ }
+ return xdisplay;
+ }
+
+ public static long gdk_window_get_xwindow(long window) {
+ final long xWindow;
+ if (OS_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0) {
+ xWindow = callStaticMethodL2L(OS_gdk_x11_window_get_xid, window);
+ } else {
+ xWindow = callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, window);
+ }
+ if(0 == xWindow) {
+ throw new NativeWindowException("Null x11-window-handle of gtk-window-handle 0x"+Long.toHexString(window));
+ }
+ return xWindow;
+ }
+
+ public static void gdk_window_set_back_pixmap(long window, long pixmap, boolean parent_relative) {
+ callStaticMethodLLZ2V(OS_gdk_window_set_back_pixmap, window, pixmap, parent_relative);
+ }
+
+ //
+ // Common any toolkit
+ //
+
+ /**
+ * @param swtControl the SWT Control to retrieve the native widget-handle from
+ * @return the native widget-handle
+ * @throws NativeWindowException if the widget handle is null
+ */
+ public static long getHandle(Control swtControl) throws NativeWindowException {
long h = 0;
- if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ if( isOSX ) {
+ synchronized(swt_osx_init) {
+ try {
+ if(null == swt_osx_view_id) {
+ swt_osx_control_view = Control.class.getField(str_osx_view);
+ Object view = swt_osx_control_view.get(swtControl);
+ swt_osx_view_id = view.getClass().getField(str_osx_id);
+ h = swt_osx_view_id.getLong(view);
+ } else {
+ h = swt_osx_view_id.getLong( swt_osx_control_view.get(swtControl) );
+ }
+ } catch (Exception ex) {
+ throw new NativeWindowException(ex);
+ }
+ }
+ } else {
try {
- Field fView = Control.class.getField(str_view);
- Object view = fView.get(swtControl);
- Field fId = view.getClass().getField(str_id);
- return fId.getLong(view);
+ h = swt_control_handle.getLong(swtControl);
} catch (Exception ex) {
throw new NativeWindowException(ex);
- }
+ }
}
-
- try {
- h = swt_control_handle.getLong(swtControl);
- } catch (Exception ex) {
- throw new NativeWindowException(ex);
+ if(0 == h) {
+ throw new NativeWindowException("Null widget-handle of SWT "+swtControl.getClass().getName()+": "+swtControl.toString());
}
return h;
}
- public static void setRealized(final Control swtControl, final boolean realize) {
+ public static void setRealized(final Control swtControl, final boolean realize)
+ throws NativeWindowException
+ {
+ if(!realize && swtControl.isDisposed()) {
+ return;
+ }
final long handle = getHandle(swtControl);
if(null != OS_gtk_class) {
@@ -216,55 +372,77 @@ public class SWTAccessor {
});
}
}
-
- public static AbstractGraphicsDevice getDevice(Control swtControl) {
- long handle = getHandle(swtControl);
- if( null != OS_gtk_class ) {
- long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
- long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle);
- return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false /* owner */);
+
+ /**
+ * @param swtControl the SWT Control to retrieve the native device handle from
+ * @return the AbstractGraphicsDevice w/ the native device handle
+ * @throws NativeWindowException if the widget handle is null
+ * @throws UnsupportedOperationException if the windowing system is not supported
+ */
+ public static AbstractGraphicsDevice getDevice(Control swtControl) throws NativeWindowException, UnsupportedOperationException {
+ final long handle = getHandle(swtControl);
+ if( isX11GTK ) {
+ final long xdisplay0 = gdk_window_get_xdisplay( gdk_widget_get_window( handle ) );
+ return new X11GraphicsDevice(xdisplay0, AbstractGraphicsDevice.DEFAULT_UNIT, false /* owner */);
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
+ if( isWindows ) {
return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if( isOSX ) {
return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
- public static AbstractGraphicsScreen getScreen(AbstractGraphicsDevice device, int screen) {
- if( null != OS_gtk_class ) {
- return new X11GraphicsScreen((X11GraphicsDevice)device, screen);
+
+ /**
+ *
+ * @param device
+ * @param screen -1 is default screen of the given device, e.g. maybe 0 or determined by native API. >= 0 is specific screen
+ * @return
+ * @throws UnsupportedOperationException
+ */
+ public static AbstractGraphicsScreen getScreen(AbstractGraphicsDevice device, int screen) throws UnsupportedOperationException {
+ if( isX11 ) {
+ X11GraphicsDevice x11Device = (X11GraphicsDevice)device;
+ if(0 > screen) {
+ screen = x11Device.getDefaultScreen();
+ }
+ return new X11GraphicsScreen(x11Device, screen);
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
- NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if(0 > screen) {
+ screen = 0; // FIXME: Needs native API utilization
+ }
+ if( isWindows || isOSX ) {
return new DefaultGraphicsScreen(device, screen);
}
throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
+
public static int getNativeVisualID(AbstractGraphicsDevice device, long windowHandle) {
- if( null != OS_gtk_class ) {
+ if( isX11 ) {
return X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
- NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if( isWindows || isOSX ) {
return VisualIDHolder.VID_UNDEFINED;
}
throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
- public static long getWindowHandle(Control swtControl) {
- long handle = getHandle(swtControl);
- if( null != OS_gtk_class ) {
- long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
- return callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, widgedHandle);
+ /**
+ * @param swtControl the SWT Control to retrieve the native window handle from
+ * @return the native window handle
+ * @throws NativeWindowException if the widget handle is null
+ * @throws UnsupportedOperationException if the windowing system is not supported
+ */
+ public static long getWindowHandle(Control swtControl) throws NativeWindowException, UnsupportedOperationException {
+ final long handle = getHandle(swtControl);
+ if(0 == handle) {
+ throw new NativeWindowException("Null SWT handle of SWT control "+swtControl);
+ }
+ if( isX11GTK ) {
+ return gdk_window_get_xwindow( gdk_widget_get_window( handle ) );
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
- NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if( isWindows || isOSX ) {
return handle;
}
throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
@@ -283,7 +461,7 @@ public class SWTAccessor {
throw new InternalError("SWT internal_new_GC did not return int or long but "+o[0].getClass());
}
}
-
+
public static void disposeGC(final Control swtControl, final long gc, final GCData gcData) {
invoke(true, new Runnable() {
public void run() {
@@ -313,7 +491,7 @@ public class SWTAccessor {
* @see Platform#getOSType()
*/
public static void invoke(boolean wait, Runnable runnable) {
- if( Platform.OS_TYPE == Platform.OSType.MACOS ) {
+ if( isOSX ) {
// Use SWT main thread! Only reliable config w/ -XStartOnMainThread !?
OSXUtil.RunOnMainThread(wait, runnable);
} else {
@@ -321,4 +499,85 @@ public class SWTAccessor {
}
}
+ //
+ // Specific X11 GTK ChildWindow - Using plain X11 native parenting (works well)
+ //
+
+ public static long createCompatibleX11ChildWindow(AbstractGraphicsScreen screen, Control swtControl, int visualID, int width, int height) {
+ final long handle = getHandle(swtControl);
+ final long parentWindow = gdk_widget_get_window( handle );
+ gdk_window_set_back_pixmap (parentWindow, 0, false);
+
+ final long x11ParentHandle = gdk_window_get_xwindow(parentWindow);
+ final long x11WindowHandle = X11Lib.CreateWindow(x11ParentHandle, screen.getDevice().getHandle(), screen.getIndex(), visualID, width, height, true, true);
+
+ return x11WindowHandle;
+ }
+
+ public static void resizeX11Window(AbstractGraphicsDevice device, Rectangle clientArea, long x11Window) {
+ X11Lib.SetWindowPosSize(device.getHandle(), x11Window, clientArea.x, clientArea.y, clientArea.width, clientArea.height);
+ }
+ public static void destroyX11Window(AbstractGraphicsDevice device, long x11Window) {
+ X11Lib.DestroyWindow(device.getHandle(), x11Window);
+ }
+
+ //
+ // Specific X11 SWT/GTK ChildWindow - Using SWT/GTK native parenting (buggy - sporadic resize flickering, sporadic drop of rendering)
+ //
+ // FIXME: Need to use reflection for 32bit access as well !
+ //
+
+ // public static final int GDK_WA_TYPE_HINT = 1 << 9;
+ // public static final int GDK_WA_VISUAL = 1 << 6;
+
+ public static long createCompatibleGDKChildWindow(Control swtControl, int visualID, int width, int height) {
+ return 0;
+ /**
+ final long handle = SWTAccessor.getHandle(swtControl);
+ final long parentWindow = gdk_widget_get_window( handle );
+
+ final long screen = OS.gdk_screen_get_default ();
+ final long gdkvisual = OS.gdk_x11_screen_lookup_visual (screen, visualID);
+
+ final GdkWindowAttr attrs = new GdkWindowAttr();
+ attrs.width = width > 0 ? width : 1;
+ attrs.height = height > 0 ? height : 1;
+ attrs.event_mask = OS.GDK_KEY_PRESS_MASK | OS.GDK_KEY_RELEASE_MASK |
+ OS.GDK_FOCUS_CHANGE_MASK | OS.GDK_POINTER_MOTION_MASK |
+ OS.GDK_BUTTON_PRESS_MASK | OS.GDK_BUTTON_RELEASE_MASK |
+ OS.GDK_ENTER_NOTIFY_MASK | OS.GDK_LEAVE_NOTIFY_MASK |
+ OS.GDK_EXPOSURE_MASK | OS.GDK_VISIBILITY_NOTIFY_MASK |
+ OS.GDK_POINTER_MOTION_HINT_MASK;
+ attrs.window_type = OS.GDK_WINDOW_CHILD;
+ attrs.visual = gdkvisual;
+
+ final long childWindow = OS.gdk_window_new (parentWindow, attrs, OS.GDK_WA_VISUAL|GDK_WA_TYPE_HINT);
+ OS.gdk_window_set_user_data (childWindow, handle);
+ OS.gdk_window_set_back_pixmap (parentWindow, 0, false);
+
+ OS.gdk_window_show (childWindow);
+ OS.gdk_flush();
+ return childWindow; */
+ }
+
+ public static void showGDKWindow(long gdkWindow) {
+ /* OS.gdk_window_show (gdkWindow);
+ OS.gdk_flush(); */
+ }
+ public static void focusGDKWindow(long gdkWindow) {
+ /*
+ OS.gdk_window_show (gdkWindow);
+ OS.gdk_window_focus(gdkWindow, 0);
+ OS.gdk_flush(); */
+ }
+ public static void resizeGDKWindow(Rectangle clientArea, long gdkWindow) {
+ /**
+ OS.gdk_window_move (gdkWindow, clientArea.x, clientArea.y);
+ OS.gdk_window_resize (gdkWindow, clientArea.width, clientArea.height);
+ OS.gdk_flush(); */
+ }
+
+ public static void destroyGDKWindow(long gdkWindow) {
+ // OS.gdk_window_destroy (gdkWindow);
+ }
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
index 67a33e55c..827862002 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
@@ -37,7 +37,7 @@ public class X11DummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize
s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
}
if( 0 == s.getSurfaceHandle() ) {
- final long windowHandle = X11Lib.CreateDummyWindow(device.getHandle(), screen.getIndex(), cfg.getXVisualID(), 64, 64);
+ final long windowHandle = X11Lib.CreateWindow(0, device.getHandle(), screen.getIndex(), cfg.getXVisualID(), 64, 64, false, false);
if(0 == windowHandle) {
throw new NativeWindowException("Creating dummy window failed w/ "+cfg);
}
@@ -59,7 +59,7 @@ public class X11DummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize
}
device.lock();
try {
- X11Lib.DestroyDummyWindow(device.getHandle(), s.getSurfaceHandle());
+ X11Lib.DestroyWindow(device.getHandle(), s.getSurfaceHandle());
s.setSurfaceHandle(0);
s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
} finally {
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index c73952693..a8d45f288 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -31,6 +31,8 @@
#include "jogamp_nativewindow_x11_X11Lib.h"
#include "jogamp_nativewindow_x11_X11Util.h"
+#include <X11/Xatom.h>
+
// #define VERBOSE_ON 1
#ifdef VERBOSE_ON
@@ -85,6 +87,8 @@ Bool XF86VidModeSetGammaRamp(
#define RTLD_DEFAULT NULL
#endif
+#define X11_MOUSE_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask)
+
static const char * const ClazzNameBuffers = "com/jogamp/common/nio/Buffers";
static const char * const ClazzNameBuffersStaticCstrName = "copyByteBuffer";
static const char * const ClazzNameBuffersStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;";
@@ -436,17 +440,62 @@ Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused
return _res;
}
+static void NativewindowX11_setNormalWindowEWMH (Display *dpy, Window w) {
+ Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False );
+ Atom types[1]={0};
+ types[0] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False );
+ XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, 1);
+ XSync(dpy, False);
+}
+
+#define DECOR_USE_MWM 1 // works for known WMs
+// #define DECOR_USE_EWMH 1 // haven't seen this to work (NORMAL->POPUP, never gets undecorated)
+
+/* see <http://tonyobryan.com/index.php?article=9> */
+#define MWM_HINTS_DECORATIONS (1L << 1)
+#define PROP_MWM_HINTS_ELEMENTS 5
+
+static void NativewindowX11_setDecorations (Display *dpy, Window w, Bool decorated) {
+
+#ifdef DECOR_USE_MWM
+ unsigned long mwmhints[PROP_MWM_HINTS_ELEMENTS] = { MWM_HINTS_DECORATIONS, 0, decorated, 0, 0 }; // flags, functions, decorations, input_mode, status
+ Atom _MOTIF_WM_HINTS = XInternAtom( dpy, "_MOTIF_WM_HINTS", False );
+#endif
+
+#ifdef DECOR_USE_EWMH
+ Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False );
+ Atom types[3]={0};
+ int ntypes=0;
+ if(True==decorated) {
+ types[ntypes++] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False );
+ } else {
+ types[ntypes++] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_POPUP_MENU", False );
+ }
+#endif
+
+#ifdef DECOR_USE_MWM
+ XChangeProperty( dpy, w, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char *)&mwmhints, PROP_MWM_HINTS_ELEMENTS);
+#endif
+
+#ifdef DECOR_USE_EWMH
+ XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes);
+#endif
+
+ XSync(dpy, False);
+}
+
/*
* Class: jogamp_nativewindow_x11_X11Lib
- * Method: CreateDummyWindow
- * Signature: (JIIII)J
+ * Method: CreateWindow
+ * Signature: (JJIIIIZZ)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
- (JNIEnv *env, jclass unused, jlong display, jint screen_index, jint visualID, jint width, jint height)
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateWindow
+ (JNIEnv *env, jclass unused, jlong parent, jlong display, jint screen_index, jint visualID, jint width, jint height, jboolean input, jboolean visible)
{
Display * dpy = (Display *)(intptr_t)display;
int scrn_idx = (int)screen_index;
- Window windowParent = 0;
+ Window root = RootWindow(dpy, scrn_idx);
+ Window windowParent = (Window) parent;
Window window = 0;
XVisualInfo visualTemplate;
@@ -473,6 +522,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, 0, 0);
scrn = ScreenOfDisplay(dpy, scrn_idx);
+ if(0==windowParent) {
+ windowParent = root;
+ }
// try given VisualID on screen
memset(&visualTemplate, 0, sizeof(XVisualInfo));
@@ -500,9 +552,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
pVisualQuery=NULL;
}
- if(0==windowParent) {
- windowParent = XRootWindowOfScreen(scrn);
- }
attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap |
CWBorderPixel | CWColormap | CWOverrideRedirect ) ;
@@ -514,15 +563,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */
xswa.backing_planes=0; /* planes to be preserved if possible */
xswa.backing_pixel=0; /* value to use in restoring planes */
+ if( input ) {
+ xswa.event_mask = X11_MOUSE_EVENT_MASK;
+ xswa.event_mask |= KeyPressMask | KeyReleaseMask ;
+ }
+ if( visible ) {
+ xswa.event_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask ;
+ }
xswa.colormap = XCreateColormap(dpy,
- XRootWindow(dpy, scrn_idx),
+ windowParent,
visual,
AllocNone);
window = XCreateWindow(dpy,
windowParent,
- 0, 0,
+ 0, 0, // only a hint, WM most likely will override
width, height,
0, // border width
depth,
@@ -530,9 +586,25 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
visual,
attrMask,
&xswa);
+ if(0==window) {
+ NativewindowCommon_throwNewRuntimeException(env, "could not create Window, bail out!");
+ return 0;
+ }
+
+ NativewindowX11_setNormalWindowEWMH(dpy, window);
+ NativewindowX11_setDecorations(dpy, window, False);
+
+ if( visible ) {
+ XEvent event;
+
+ XMapWindow(dpy, window);
+ }
+
XSync(dpy, False);
- XSelectInput(dpy, window, 0); // no events
+ if( !input ) {
+ XSelectInput(dpy, window, 0); // no events
+ }
// NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0, 1);
@@ -544,10 +616,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
/*
* Class: jogamp_nativewindow_x11_X11Lib
- * Method: DestroyDummyWindow
+ * Method: DestroyWindow
* Signature: (JJ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyWindow
(JNIEnv *env, jclass unused, jlong display, jlong window)
{
Display * dpy = (Display *)(intptr_t)display;
@@ -559,12 +631,37 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow
}
NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, 0, 0);
+ XSelectInput(dpy, w, 0);
XUnmapWindow(dpy, w);
XSync(dpy, False);
XDestroyWindow(dpy, w);
// NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0, 1);
}
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_SetWindowPosSize
+ (JNIEnv *env, jclass unused, jlong display, jlong window, jint x, jint y, jint width, jint height) {
+ Display * dpy = (Display *)(intptr_t)display;
+ Window w = (Window) window;
+ XWindowChanges xwc;
+ int flags = 0;
+
+ memset(&xwc, 0, sizeof(XWindowChanges));
+
+ if(0<=x && 0<=y) {
+ flags |= CWX | CWY;
+ xwc.x=x;
+ xwc.y=y;
+ }
+
+ if(0<width && 0<height) {
+ flags |= CWWidth | CWHeight;
+ xwc.width=width;
+ xwc.height=height;
+ }
+ XConfigureWindow(dpy, w, flags, &xwc);
+ XSync(dpy, False);
+}
+
/*
* Class: jogamp_nativewindow_x11_X11Lib
* Method: GetRelativeLocation
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index e97dec88d..993aa33eb 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -158,19 +158,15 @@ public abstract class Display {
* </p>
* <p>
* If a previous one exists and it differs from the new one,
- * it's being stopped, wait-until-idle and reset to allow restart.
+ * it's being stopped, wait-until-idle and reset to allow a restart at a later time.
* </p>
* <p>
* If <code>newEDTUtil</code> is not null and equals the previous one,
- * <code>null</code> is returned and no change is being made.
+ * no change is being made.
* </p>
* <p>
- * Note that <code>newEDTUtil</code> will not be started if not done so already,
- * to do so you may issue {@link EDTUtil#invoke(boolean, Runnable) invoke}
- * on the new EDTUtil:
- * <pre>
- * newEDTUtil.invoke(true, new Runnable() { public void run() { } } );
- * </pre>
+ * Note that <code>newEDTUtil</code> will be started by this method,
+ * if it is not running yet.
* </p>
*/
public abstract EDTUtil setEDTUtil(EDTUtil newEDTUtil);
diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
index 525225804..dbe7c0d98 100644
--- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
+++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
@@ -26,7 +26,6 @@
* or implied, of JogAmp Community.
*/
-
package com.jogamp.newt.swt;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
@@ -44,18 +43,18 @@ import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
+import javax.media.opengl.GLCapabilities;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.newt.Debug;
+import jogamp.newt.swt.SWTEDTUtil;
import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.newt.Display;
@@ -65,6 +64,9 @@ import com.jogamp.newt.util.EDTUtil;
/**
* SWT {@link Canvas} containing a NEWT {@link Window} using native parenting.
+ * <p>
+ * Implementation allows use of custom {@link GLCapabilities}.
+ * </p>
*/
public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("Window");
@@ -77,6 +79,8 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
private volatile SWTNativeWindow nativeWindow;
private volatile Window newtChild = null;
+ private volatile boolean newtChildReady = false; // ready if SWTEDTUtil is set and newtChild parented
+ private volatile boolean postSetSize = false; // pending resize
/**
* Creates an instance using {@link #NewtCanvasSWT(Composite, int, Window)}
@@ -122,45 +126,51 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
clientArea = getClientArea();
final AbstractGraphicsDevice device = SWTAccessor.getDevice(this);
- screen = SWTAccessor.getScreen(device, 0);
+ screen = SWTAccessor.getScreen(device, -1 /* default */);
nativeWindow = null;
if(null != child) {
setNEWTChild(child);
}
-
- /* Register SWT listeners (e.g. PaintListener) to render/resize GL surface. */
- /* TODO: verify that these do not need to be manually de-registered when destroying the SWT component */
- addPaintListener(new PaintListener() {
+
+ final Listener listener = new Listener () {
@Override
- public void paintControl(final PaintEvent arg0) {
- if( null != nativeWindow || validateNative() ) {
- if( null !=newtChild ) {
- newtChild.windowRepaint(0, 0, clientArea.width, clientArea.height);
+ public void handleEvent (Event event) {
+ switch (event.type) {
+ case SWT.Paint:
+ if( null != nativeWindow || validateNative() ) {
+ if( newtChildReady ) {
+ if( postSetSize ) {
+ newtChild.setSize(clientArea.width, clientArea.height);
+ postSetSize = false;
+ }
+ newtChild.windowRepaint(0, 0, clientArea.width, clientArea.height);
+ }
}
+ break;
+ case SWT.Resize:
+ updateSizeCheck();
+ break;
+ case SWT.Dispose:
+ NewtCanvasSWT.this.dispose();
+ break;
}
}
- });
-
- addControlListener(new ControlAdapter() {
- @Override
- public void controlResized(final ControlEvent arg0) {
- updateSizeCheck();
- }
- });
+ };
+ addListener (SWT.Resize, listener);
+ addListener (SWT.Paint, listener);
+ addListener (SWT.Dispose, listener);
}
/** assumes nativeWindow == null ! */
protected final boolean validateNative() {
- if( isDisposed() ) {
- return false;
- }
updateSizeCheck();
final Rectangle nClientArea = clientArea;
if(0 >= nClientArea.width || 0 >= nClientArea.height) {
return false;
}
-
+ screen.getDevice().open();
+
/* Native handle for the control, used to associate with GLContext */
final long nativeWindowHandle = SWTAccessor.getWindowHandle(this);
final int visualID = SWTAccessor.getNativeVisualID(screen.getDevice(), nativeWindowHandle);
@@ -196,12 +206,18 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
( nClientArea.width != oClientArea.width || nClientArea.height != oClientArea.height )
) {
clientArea = nClientArea; // write back new value
- if( null != newtChild ) {
+ if(DEBUG) {
+ final long nsh = newtChildReady ? newtChild.getSurfaceHandle() : 0;
+ System.err.println("NewtCanvasSWT.sizeChanged: ("+Thread.currentThread().getName()+"): newtChildReady "+newtChildReady+", "+nClientArea.x+"/"+nClientArea.y+" "+nClientArea.width+"x"+nClientArea.height+" - surfaceHandle 0x"+Long.toHexString(nsh));
+ }
+ if( newtChildReady ) {
newtChild.setSize(clientArea.width, clientArea.height);
+ } else {
+ postSetSize = true;
}
}
}
-
+
@Override
public void update() {
// don't paint background etc .. nop avoids flickering
@@ -230,6 +246,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
newtChild.destroy();
newtChild = null;
}
+ screen.getDevice().close();
nativeWindow = null;
super.dispose();
}
@@ -238,11 +255,11 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
public NativeWindow getNativeWindow() { return nativeWindow; }
public WindowClosingMode getDefaultCloseOperation() {
- return newtChildCloseOp; // FIXME
+ return newtChildCloseOp; // TODO: implement ?!
}
public WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) {
- return newtChildCloseOp = op; // FIXME
+ return newtChildCloseOp = op; // TODO: implement ?!
}
@@ -299,7 +316,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
}
/* package */ void configureNewtChild(boolean attach) {
-
+ newtChildReady = attach;
if( null != newtChild ) {
newtChild.setKeyboardFocusHandler(null);
if(attach) {
@@ -324,23 +341,21 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
updateSizeCheck();
final int w = clientArea.width;
final int h = clientArea.height;
-
+
// set SWT EDT and start it
{
final Display newtDisplay = newtChild.getScreen().getDisplay();
- final EDTUtil edt = new SWTEDTUtil(newtDisplay, getDisplay());
- newtDisplay.setEDTUtil(edt);
- edt.invoke(true, new Runnable() { public void run() { } } ); // start EDT
+ newtDisplay.setEDTUtil( new SWTEDTUtil(newtDisplay, getDisplay()) );
}
- newtChild.setSize(w, h);
+ newtChild.setSize(w, h);
newtChild.reparentWindow(nativeWindow);
newtChild.setVisible(true);
- configureNewtChild(true);
+ configureNewtChild(true);
newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
-
+
// force this SWT Canvas to be focus-able,
- // since this it is completely covered by the newtChild (z-order).
+ // since it is completely covered by the newtChild (z-order).
setEnabled(true);
} else {
configureNewtChild(false);
@@ -353,7 +368,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
}
private final void requestFocusNEWTChild() {
- if( null != newtChild ) {
+ if( newtChildReady ) {
newtChild.setFocusAction(null);
newtChild.requestFocus();
}
diff --git a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
index 7e19d9de5..0183da592 100644
--- a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
@@ -113,7 +113,8 @@ public interface EDTUtil {
/**
* Append the final task to the EDT task queue,
- * signals EDT to stop and wait until stopped.<br>
+ * signals EDT to stop and wait until stopped.<br/>
+ * <code>task</code> maybe <code>null</code><br/>
* Due to the nature of this method:
* <ul>
* <li>All previous queued tasks will be finished.</li>
@@ -125,7 +126,7 @@ public interface EDTUtil {
public void invokeStop(Runnable finalTask);
/**
- * Shall start the thread if not running.<br>
+ * Shall start the thread if not running, <code>task</code> maybe null for this purpose.<br>
* Append task to the EDT task queue.<br>
* Wait until execution is finished if <code>wait == true</code>.<br>
* Can be issued from within EDT, ie from within an enqueued task.<br>
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
index 98987ef96..d8d04e79f 100644
--- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
@@ -81,10 +81,10 @@ public class DefaultEDTUtil implements EDTUtil {
waitUntilStopped();
if(DEBUG) {
if(edt.tasks.size()>0) {
- System.err.println(Thread.currentThread()+": EDT reset, remaining tasks: "+edt.tasks.size()+" - "+edt);
+ System.err.println(Thread.currentThread()+": Default-EDT reset, remaining tasks: "+edt.tasks.size()+" - "+edt);
// Thread.dumpStack();
}
- System.err.println(Thread.currentThread()+": EDT reset - edt: "+edt);
+ System.err.println(Thread.currentThread()+": Default-EDT reset - edt: "+edt);
}
this.edt = new EventDispatchThread(threadGroup, name);
this.edt.setDaemon(true); // don't stop JVM from shutdown ..
@@ -93,13 +93,13 @@ public class DefaultEDTUtil implements EDTUtil {
private final void startImpl() {
if(edt.isAlive()) {
- throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
+ throw new RuntimeException("Default-EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
}
start_iter++;
edt.setName(name+start_iter);
edt.shouldStop = false;
if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT START - edt: "+edt);
+ System.err.println(Thread.currentThread()+": Default-EDT START - edt: "+edt);
// Thread.dumpStack();
}
edt.start();
@@ -135,10 +135,12 @@ public class DefaultEDTUtil implements EDTUtil {
invokeImpl(wait, task, false);
}
+ private static Runnable nullTask = new Runnable() {
+ @Override
+ public void run() { }
+ };
+
private void invokeImpl(boolean wait, Runnable task, boolean stop) {
- if(task == null) {
- throw new RuntimeException("Null Runnable");
- }
Throwable throwable = null;
RunnableTask rTask = null;
Object rTaskLock = new Object();
@@ -147,45 +149,57 @@ public class DefaultEDTUtil implements EDTUtil {
if( edt.shouldStop ) {
// drop task ..
if(DEBUG) {
- System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+edt);
+ System.err.println(Thread.currentThread()+": Warning: Default-EDT about (1) to stop, won't enqueue new task: "+edt);
Thread.dumpStack();
}
return;
}
// System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
// Thread.dumpStack();
- if(stop) {
- edt.shouldStop = true;
- if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - tasks: "+edt.tasks.size()+" - "+edt);
- // Thread.dumpStack();
- }
- }
if( isCurrentThreadEDT() ) {
- task.run();
+ if(null != task) {
+ task.run();
+ }
wait = false; // running in same thread (EDT) -> no wait
- if(stop && edt.tasks.size()>0) {
- System.err.println("Warning: EDT about (2) to stop, having remaining tasks: "+edt.tasks.size()+" - "+edt);
- if(DEBUG) {
- Thread.dumpStack();
+ if(stop) {
+ edt.shouldStop = true;
+ if( edt.tasks.size()>0 ) {
+ System.err.println(Thread.currentThread()+": Warning: Default-EDT about (2) to stop, task executed. Remaining tasks: "+edt.tasks.size()+" - "+edt);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
}
}
} else {
- // start if should not stop && not started yet
- if( !stop && !edt.isRunning() ) {
- startImpl();
+ if( !edt.isRunning() ) {
+ if( !stop ) {
+ startImpl();
+ } else {
+ // drop task and don't wait
+ task = null;
+ System.err.println(Thread.currentThread()+": Warning: Default-EDT is about (3) to stop and stopped already, dropping task. Remaining tasks: "+edt.tasks.size()+" - "+edt);
+ if(true || DEBUG) {
+ Thread.dumpStack();
+ }
+ }
+ } else if(stop && null == task) {
+ task = nullTask;
}
- synchronized(edt.tasks) {
- wait = wait && edt.isRunning();
- rTask = new RunnableTask(task,
- wait ? rTaskLock : null,
- true /* always catch and report Exceptions, don't disturb EDT */);
- if(stop) {
- rTask.setAttachment(new Boolean(true)); // mark final task
+
+ if(null != task) {
+ synchronized(edt.tasks) {
+ rTask = new RunnableTask(task,
+ wait ? rTaskLock : null,
+ true /* always catch and report Exceptions, don't disturb EDT */);
+ if(stop) {
+ rTask.setAttachment(new Boolean(true)); // mark final task, will imply shouldStop:=true
+ }
+ // append task ..
+ edt.tasks.add(rTask);
+ edt.tasks.notifyAll();
}
- // append task ..
- edt.tasks.add(rTask);
- edt.tasks.notifyAll();
+ } else {
+ wait = false;
}
}
}
@@ -207,7 +221,7 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
if(DEBUG && stop) {
- System.err.println(Thread.currentThread()+": EDT signal STOP X edt: "+edt);
+ System.err.println(Thread.currentThread()+": Default-EDT signal STOP X edt: "+edt);
}
}
@@ -282,7 +296,7 @@ public class DefaultEDTUtil implements EDTUtil {
@Override
final public void run() {
if(DEBUG) {
- System.err.println(getName()+": EDT run() START "+ getName());
+ System.err.println(getName()+": Default-EDT run() START "+ getName());
}
validateNoRecursiveLocksHold();
RuntimeException error = null;
@@ -307,6 +321,9 @@ public class DefaultEDTUtil implements EDTUtil {
if(tasks.size()>0) {
task = tasks.remove(0);
tasks.notifyAll();
+ if( null != task.getAttachment() ) {
+ shouldStop = true;
+ }
}
}
if(null!=task) {
@@ -324,41 +341,19 @@ public class DefaultEDTUtil implements EDTUtil {
if(t instanceof RuntimeException) {
error = (RuntimeException) t;
} else {
- error = new RuntimeException("Within EDT", t);
+ error = new RuntimeException("Within Default-EDT", t);
}
} finally {
if(DEBUG) {
RunnableTask rt = ( tasks.size() > 0 ) ? tasks.get(0) : null ;
- System.err.println(getName()+": EDT run() END "+ getName()+", tasks: "+tasks.size()+", "+rt+", "+error);
+ System.err.println(getName()+": Default-EDT run() END "+ getName()+", tasks: "+tasks.size()+", "+rt+", "+error);
}
synchronized(edtLock) {
- if(null==error) {
- synchronized(tasks) {
- // drain remaining tasks (stop not on EDT),
- // while having tasks and no previous-task, or previous-task is non final
- RunnableTask task = null;
- while ( ( null == task || task.getAttachment() == null ) && tasks.size() > 0 ) {
- task = tasks.remove(0);
- task.run();
- tasks.notifyAll();
- }
- if(DEBUG) {
- if(null!=task && task.getAttachment()==null) {
- System.err.println(getName()+" Warning: EDT exit: Last task Not Final: "+tasks.size()+", "+task+" - "+edt);
- } else if(tasks.size()>0) {
- System.err.println(getName()+" Warning: EDT exit: Remaining tasks Post Final: "+tasks.size());
- }
- Thread.dumpStack();
- }
- }
- }
- isRunning = !shouldStop;
- if(!isRunning) {
- edtLock.notifyAll();
- }
+ isRunning = false;
+ edtLock.notifyAll();
}
if(DEBUG) {
- System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error);
+ System.err.println(getName()+": Default-EDT run() EXIT "+ getName()+", exception: "+error);
}
if(null!=error) {
throw error;
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index 317535805..20b915cae 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -84,9 +84,8 @@ public abstract class DisplayImpl extends Display {
display.hashCode = display.fqname.hashCode();
displayList.add(display);
}
- if(null == display.edtUtil) {
- display.setEDTUtil(null); // device's default if EDT is used, or null
- }
+ display.setEDTUtil(display.edtUtil); // device's default if EDT is used, or null
+
if(DEBUG) {
System.err.println("Display.create() NEW: "+display+" "+getThreadName());
}
@@ -166,20 +165,24 @@ public abstract class DisplayImpl extends Display {
@Override
public EDTUtil setEDTUtil(EDTUtil newEDTUtil) {
+ final EDTUtil oldEDTUtil = edtUtil;
if(null == newEDTUtil) {
- newEDTUtil = createEDTUtil();
- } else if( newEDTUtil == edtUtil ) {
if(DEBUG) {
- System.err.println("Display.setEDTUtil: "+newEDTUtil+" - keep!");
+ System.err.println("Display.setEDTUtil(default): "+oldEDTUtil+" -> "+newEDTUtil);
+ }
+ edtUtil = createEDTUtil();
+ } else if( newEDTUtil != edtUtil ) {
+ if(DEBUG) {
+ System.err.println("Display.setEDTUtil(custom): "+oldEDTUtil+" -> "+newEDTUtil);
}
- return null; // no change
+ removeEDT( null );
+ edtUtil = newEDTUtil;
+ } else if( DEBUG ) {
+ System.err.println("Display.setEDTUtil: "+newEDTUtil+" - keep!");
}
- final EDTUtil oldEDTUtil = edtUtil;
- if(DEBUG) {
- System.err.println("Display.setEDTUtil: "+oldEDTUtil+" -> "+newEDTUtil);
+ if( !edtUtil.isRunning() ) { // start EDT if not running yet
+ edtUtil.invoke(true, null);
}
- removeEDT( new Runnable() { public void run() {} } );
- edtUtil = newEDTUtil;
return oldEDTUtil;
}
@@ -209,11 +212,7 @@ public abstract class DisplayImpl extends Display {
public boolean validateEDT() {
if(0==refCount && null==aDevice && null != edtUtil && edtUtil.isRunning()) {
- removeEDT( new Runnable() {
- public void run() {
- // nop
- }
- } );
+ removeEDT( null );
return true;
}
return false;
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 4f8eb3d3a..a9294c1ff 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -173,7 +173,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
window.parentWindowHandle = parentWindowHandle;
window.screen = (ScreenImpl) screen;
window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable();
- window.setUndecorated(0!=parentWindowHandle);
window.instantiationFinished();
return window;
} catch (Throwable t) {
@@ -573,6 +572,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
+ surfaceLockCount--;
_wlock.unlock();
}
}
@@ -729,8 +729,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
} else if(WindowImpl.this.visible != visible) {
if(isNativeValid()) {
setVisibleImpl(visible, getX(), getY(), getWidth(), getHeight());
- WindowImpl.this.waitForVisible(visible, true);
+ WindowImpl.this.waitForVisible(visible, false);
madeVisible = visible;
+ } else {
+ WindowImpl.this.visible = true;
}
}
@@ -804,11 +806,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
} else if ( visible && !isNativeValid() && 0 < width && 0 < height ) {
visibleAction = 2; // visible (create)
defineSize(width, height);
- } else if ( isNativeValid() ) {
+ } else if ( visible && isNativeValid() ) {
visibleAction = 0;
// this width/height will be set by windowChanged, called by the native implementation
reconfigureWindowImpl(getX(), getY(), width, height, getReconfigureFlags(0, isVisible()));
+ WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW);
} else {
+ // invisible or invalid w/ 0 size
visibleAction = 0;
defineSize(width, height);
}
@@ -1045,8 +1049,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(null!=newParentWindowNEWT) {
setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
} else {
- Screen newScreen = NewtFactory.createCompatibleScreen(newParentWindow, getScreen());
- if( getScreen() != newScreen ) {
+ final Screen newScreen = NewtFactory.createCompatibleScreen(newParentWindow, screen);
+ if( screen != newScreen ) {
// auto destroy on-the-fly created Screen/Display
setScreen( (ScreenImpl) newScreen );
}
@@ -1056,14 +1060,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
} else {
operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING;
}
- } else if ( forceDestroyCreate || !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) {
+ } else if ( forceDestroyCreate || !NewtFactory.isScreenCompatible(newParentWindow, screen) ) {
// Destroy this window, may create a new compatible Screen/Display,
// and mark it for creation.
destroy();
if(null!=newParentWindowNEWT) {
setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
} else {
- setScreen( (ScreenImpl) NewtFactory.createCompatibleScreen(newParentWindow, getScreen()) );
+ setScreen( (ScreenImpl) NewtFactory.createCompatibleScreen(newParentWindow, screen) );
}
operation = ReparentOperation.ACTION_NATIVE_CREATION;
} else {
@@ -1078,7 +1082,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( null != parentWindow ) {
// child -> top
// put client to current parent+child position
- Point p = getLocationOnScreen(null);
+ final Point p = getLocationOnScreen(null);
x = p.getX();
y = p.getY();
}
@@ -1134,13 +1138,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
if( ReparentOperation.ACTION_NATIVE_REPARENTING == operation ) {
- DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ final DisplayImpl display = (DisplayImpl) screen.getDisplay();
display.dispatchMessagesNative(); // status up2date
if(wasVisible) {
setVisibleImpl(false, x, y, width, height);
- WindowImpl.this.waitForVisible(false, true);
- // some composite WM behave slacky .. give 'em chance to change state -> invisible,
+ WindowImpl.this.waitForVisible(false, false);
+ // FIXME: Some composite WM behave slacky .. give 'em chance to change state -> invisible,
// even though we do exactly that (KDE+Composite)
try { Thread.sleep(100); } catch (InterruptedException e) { }
display.dispatchMessagesNative(); // status up2date
@@ -1166,6 +1170,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
parentWindowLocked.unlockSurface();
}
}
+ definePosition(x, y); // position might not get updated by WM events (SWT parent apparently)
// set visible again
if(ok) {
@@ -1173,7 +1178,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(wasVisible) {
setVisibleImpl(true, x, y, width, height);
ok = WindowImpl.this.waitForVisible(true, false);
- display.dispatchMessagesNative(); // status up2date
if(ok) {
ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW);
}
@@ -1202,7 +1206,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.reparentWindow: END-1 ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+x+"/"+y+" "+width+"x"+height);
+ System.err.println("Window.reparentWindow: END-1 ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight());
}
} finally {
_lock.unlock();
@@ -1223,7 +1227,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.reparentWindow: END-X ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+x+"/"+y+" "+width+"x"+height);
+ System.err.println("Window.reparentWindow: END-X ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight());
}
}
}
@@ -1557,7 +1561,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
for (int i = 0; i < keyListeners.size(); i++ ) {
sb.append(keyListeners.get(i)+", ");
}
- sb.append("], windowLock "+windowLock+"]");
+ sb.append("], windowLock "+windowLock+", surfaceLockCount "+surfaceLockCount+"]");
return sb.toString();
}
@@ -1566,15 +1570,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public void runOnEDTIfAvail(boolean wait, final Runnable task) {
- if(windowLock.isOwner(Thread.currentThread())) {
+ if( windowLock.isOwner( Thread.currentThread() ) ) {
task.run();
} else {
- Screen scrn = getScreen();
- if(null==scrn) {
- throw new RuntimeException("Null screen of inner class: "+this);
- }
- DisplayImpl d = (DisplayImpl) scrn.getDisplay();
- d.runOnEDTIfAvail(wait, task);
+ ( (DisplayImpl) screen.getDisplay() ).runOnEDTIfAvail(wait, task);
}
}
@@ -1899,7 +1898,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
if(isNativeValid()) {
- ((DisplayImpl)getScreen().getDisplay()).enqueueEvent(wait, event);
+ ((DisplayImpl)screen.getDisplay()).enqueueEvent(wait, event);
}
}
@@ -1914,7 +1913,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
repaintQueued=true;
final boolean discardTO = QUEUED_EVENT_TO <= System.currentTimeMillis()-e.getWhen();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.consumeEvent: "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO);
+ System.err.println("Window.consumeEvent: REPAINT "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO);
// Thread.dumpStack();
}
return discardTO; // discardTO:=true -> consumed
@@ -1930,7 +1929,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( null != windowLock.getOwner() ) {
final boolean discardTO = QUEUED_EVENT_TO <= System.currentTimeMillis()-e.getWhen();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.consumeEvent: "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO);
+ System.err.println("Window.consumeEvent: RESIZED "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO);
// Thread.dumpStack();
}
return discardTO; // discardTO:=true -> consumed
@@ -2430,10 +2429,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
private boolean waitForVisible(boolean visible, boolean failFast, long timeOut) {
- DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ final DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ display.dispatchMessagesNative(); // status up2date
for(long sleep = timeOut; 0<sleep && this.visible != visible; sleep-=10 ) {
- display.dispatchMessagesNative(); // status up2date
try { Thread.sleep(10); } catch (InterruptedException ie) {}
+ display.dispatchMessagesNative(); // status up2date
}
if(this.visible != visible) {
final String msg = "Visibility not reached as requested within "+timeOut+"ms : requested "+visible+", is "+this.visible;
@@ -2441,9 +2441,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
throw new NativeWindowException(msg);
} else if (DEBUG_IMPLEMENTATION) {
System.err.println(msg);
+ Thread.dumpStack();
}
+ return false;
+ } else {
+ return true;
}
- return this.visible == visible;
}
/** Triggered by implementation's WM events to update the client-area size w/o insets/decorations. */
@@ -2467,18 +2470,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
private boolean waitForSize(int w, int h, boolean failFast, long timeOut) {
- DisplayImpl display = (DisplayImpl) screen.getDisplay();
- boolean reached = false;
- for(long sleep = timeOut; !reached && 0<sleep; sleep-=10 ) {
- if( w==getWidth() && h==getHeight() ) {
- // reached pos/size
- reached = true;
- } else {
- display.dispatchMessagesNative(); // status up2date
- try { Thread.sleep(10); } catch (InterruptedException ie) {}
- }
+ final DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ display.dispatchMessagesNative(); // status up2date
+ long sleep;
+ for(sleep = timeOut; 0<sleep && w!=getWidth() && h!=getHeight(); sleep-=10 ) {
+ try { Thread.sleep(10); } catch (InterruptedException ie) {}
+ display.dispatchMessagesNative(); // status up2date
}
- if(!reached) {
+ if(0 >= sleep) {
final String msg = "Size/Pos not reached as requested within "+timeOut+"ms : requested "+w+"x"+h+", is "+getWidth()+"x"+getHeight();
if(failFast) {
throw new NativeWindowException(msg);
@@ -2486,8 +2485,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
System.err.println(msg);
Thread.dumpStack();
}
+ return false;
+ } else {
+ return true;
}
- return reached;
}
/** Triggered by implementation's WM events to update the position. */
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
index 2175f2190..27d0f3506 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
@@ -72,7 +72,7 @@ public class AWTEDTUtil implements EDTUtil {
synchronized(edtLock) {
waitUntilStopped();
if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt);
+ System.err.println(Thread.currentThread()+": AWT-EDT reset - edt: "+nedt);
}
this.nedt = new NewtEventDispatchThread(threadGroup, name);
this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
@@ -81,13 +81,13 @@ public class AWTEDTUtil implements EDTUtil {
private final void startImpl() {
if(nedt.isAlive()) {
- throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
+ throw new RuntimeException("AWT-EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
}
start_iter++;
nedt.setName(name+start_iter);
nedt.shouldStop = false;
if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT START - edt: "+nedt);
+ System.err.println(Thread.currentThread()+": AWT-EDT START - edt: "+nedt);
// Thread.dumpStack();
}
nedt.start();
@@ -124,9 +124,6 @@ public class AWTEDTUtil implements EDTUtil {
}
private void invokeImpl(boolean wait, Runnable task, boolean stop) {
- if(task == null) {
- throw new RuntimeException("Null Runnable");
- }
Throwable throwable = null;
RunnableTask rTask = null;
Object rTaskLock = new Object();
@@ -135,7 +132,7 @@ public class AWTEDTUtil implements EDTUtil {
if( nedt.shouldStop ) {
// drop task ..
if(DEBUG) {
- System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
+ System.err.println(Thread.currentThread()+": Warning: AWT-EDT about (1) to stop, won't enqueue new task: "+nedt);
Thread.dumpStack();
}
return;
@@ -143,20 +140,24 @@ public class AWTEDTUtil implements EDTUtil {
// System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
// Thread.dumpStack();
if(stop) {
- nedt.shouldStop = true;
+ synchronized(nedt.sync) {
+ nedt.shouldStop = true;
+ nedt.sync.notifyAll(); // stop immediate if waiting (poll freq)
+ }
if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
+ System.err.println(Thread.currentThread()+": AWT-EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
// Thread.dumpStack();
}
+ } else if( !nedt.isRunning() ) {
+ // start if should not stop && not started yet
+ startImpl();
}
- if( isCurrentThreadEDT() ) {
+ if( null == task ) {
+ wait = false;
+ } else if( isCurrentThreadEDT() ) {
task.run();
wait = false; // running in same thread (EDT) -> no wait
} else {
- // start if should not stop && not started yet
- if( !stop && !nedt.isRunning() ) {
- startImpl();
- }
rTask = new RunnableTask(task,
wait ? rTaskLock : null,
true /* always catch and report Exceptions, don't disturb EDT */);
@@ -239,7 +240,7 @@ public class AWTEDTUtil implements EDTUtil {
@Override
final public void run() {
if(DEBUG) {
- System.err.println(getName()+": EDT run() START "+ getName());
+ System.err.println(getName()+": AWT-EDT run() START "+ getName());
}
RuntimeException error = null;
try {
@@ -269,11 +270,11 @@ public class AWTEDTUtil implements EDTUtil {
if(t instanceof RuntimeException) {
error = (RuntimeException) t;
} else {
- error = new RuntimeException("Within EDT", t);
+ error = new RuntimeException("Within AWT-EDT", t);
}
} finally {
if(DEBUG) {
- System.err.println(getName()+": EDT run() END "+ getName()+", "+error);
+ System.err.println(getName()+": AWT-EDT run() END "+ getName()+", "+error);
}
synchronized(edtLock) {
isRunning = !shouldStop;
@@ -282,7 +283,7 @@ public class AWTEDTUtil implements EDTUtil {
}
}
if(DEBUG) {
- System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error);
+ System.err.println(getName()+": AWT-EDT run() EXIT "+ getName()+", exception: "+error);
}
if(null!=error) {
throw error;
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
index 6aac8617c..2ec88852c 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
@@ -71,13 +71,15 @@ public class WindowDriver extends WindowImpl {
if (0 != hdc) {
throw new InternalError("surface not released");
}
- hdc = GDI.GetDC(getWindowHandle());
- hmon = MonitorFromWindow0(getWindowHandle());
+ final long hWnd = getWindowHandle();
+ hdc = GDI.GetDC(hWnd);
// return ( 0 == hdc ) ? LOCK_SURFACE_NOT_READY : ( hdc_old != hdc ) ? LOCK_SURFACE_CHANGED : LOCK_SUCCESS ;
if( 0 == hdc ) {
return LOCK_SURFACE_NOT_READY;
- }
+ }
+ hmon = MonitorFromWindow0(hWnd);
+
if( hdc_old == hdc ) {
return LOCK_SUCCESS;
}
@@ -217,14 +219,14 @@ public class WindowDriver extends WindowImpl {
@Override
protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
- final Boolean[] res = new Boolean[] { Boolean.FALSE };
+ final boolean[] res = new boolean[] { false };
this.runOnEDTIfAvail(true, new Runnable() {
public void run() {
- res[0] = Boolean.valueOf(setPointerVisible0(getWindowHandle(), pointerVisible));
+ res[0] = setPointerVisible0(getWindowHandle(), pointerVisible);
}
});
- return res[0].booleanValue();
+ return res[0];
}
@Override
diff --git a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
index 42e1c9be5..7297e5858 100644
--- a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
@@ -25,9 +25,7 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-package com.jogamp.newt.swt;
-
-import java.awt.EventQueue;
+package jogamp.newt.swt;
import javax.media.nativewindow.NativeWindowException;
@@ -83,7 +81,7 @@ public class SWTEDTUtil implements EDTUtil {
synchronized(edtLock) {
waitUntilStopped();
if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt);
+ System.err.println(Thread.currentThread()+": SWT-EDT reset - edt: "+nedt);
}
this.nedt = new NewtEventDispatchThread(threadGroup, name);
this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
@@ -92,13 +90,13 @@ public class SWTEDTUtil implements EDTUtil {
private final void startImpl() {
if(nedt.isAlive()) {
- throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
+ throw new RuntimeException("SWT-EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
}
start_iter++;
nedt.setName(name+start_iter);
nedt.shouldStop = false;
if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT START - edt: "+nedt);
+ System.err.println(Thread.currentThread()+": SWT-EDT START - edt: "+nedt);
// Thread.dumpStack();
}
nedt.start();
@@ -136,9 +134,6 @@ public class SWTEDTUtil implements EDTUtil {
}
private void invokeImpl(boolean wait, Runnable task, boolean stop) {
- if(task == null) {
- throw new RuntimeException("Null Runnable");
- }
Throwable throwable = null;
RunnableTask rTask = null;
Object rTaskLock = new Object();
@@ -147,7 +142,7 @@ public class SWTEDTUtil implements EDTUtil {
if( nedt.shouldStop ) {
// drop task ..
if(DEBUG) {
- System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
+ System.err.println(Thread.currentThread()+": Warning: SWT-EDT about (1) to stop, won't enqueue new task: "+nedt);
Thread.dumpStack();
}
return;
@@ -155,22 +150,26 @@ public class SWTEDTUtil implements EDTUtil {
// System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
// Thread.dumpStack();
if(stop) {
- nedt.shouldStop = true;
+ synchronized(nedt.sync) {
+ nedt.shouldStop = true;
+ nedt.sync.notifyAll(); // stop immediate if waiting (poll freq)
+ }
if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
+ System.err.println(Thread.currentThread()+": SWT-EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
// Thread.dumpStack();
}
+ } else if( !nedt.isRunning() ) {
+ // start if should not stop && not started yet
+ startImpl();
}
- if( isCurrentThreadEDT() ) {
+ if( null == task ) {
+ wait = false;
+ } else if( isCurrentThreadEDT() ) {
task.run();
wait = false; // running in same thread (EDT) -> no wait
} else if( swtDisplay.isDisposed() ) {
wait = false; // drop task, SWT disposed
} else {
- // start if should not stop && not started yet
- if( !stop && !nedt.isRunning() ) {
- startImpl();
- }
rTask = new RunnableTask(task,
wait ? rTaskLock : null,
true /* always catch and report Exceptions, don't disturb EDT */);
@@ -255,7 +254,7 @@ public class SWTEDTUtil implements EDTUtil {
@Override
final public void run() {
if(DEBUG) {
- System.err.println(getName()+": EDT run() START "+ getName());
+ System.err.println(getName()+": SWT-EDT run() START "+ getName());
}
RuntimeException error = null;
try {
@@ -289,11 +288,11 @@ public class SWTEDTUtil implements EDTUtil {
if(t instanceof RuntimeException) {
error = (RuntimeException) t;
} else {
- error = new RuntimeException("Within EDT", t);
+ error = new RuntimeException("Within SWT-EDT", t);
}
} finally {
if(DEBUG) {
- System.err.println(getName()+": EDT run() END "+ getName()+", "+error);
+ System.err.println(getName()+": SWT-EDT run() END "+ getName()+", "+error);
}
synchronized(edtLock) {
isRunning = !shouldStop;
@@ -302,7 +301,7 @@ public class SWTEDTUtil implements EDTUtil {
}
}
if(DEBUG) {
- System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error);
+ System.err.println(getName()+": SWT-EDT run() EXIT "+ getName()+", exception: "+error);
}
if(null!=error) {
throw error;
diff --git a/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java b/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java
new file mode 100644
index 000000000..e238f5d9e
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java
@@ -0,0 +1,249 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.newt.swt.event;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.newt.event.InputEvent;
+
+/**
+ * SWT event translator to NEWT, inclusive dispatch listener.
+ * <p>
+ * <b>Disclaimer:</b> This code is merely tested and subject to change.
+ * </p>
+ */
+public class SWTNewtEventFactory {
+
+ protected static final IntIntHashMap eventTypeSWT2NEWT;
+
+ static {
+ IntIntHashMap map = new IntIntHashMap();
+ map.setKeyNotFoundValue(0xFFFFFFFF);
+
+ // map.put(SWT.MouseXXX, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED);
+ map.put(SWT.MouseDown, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED);
+ map.put(SWT.MouseUp, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED);
+ map.put(SWT.MouseMove, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_MOVED);
+ map.put(SWT.MouseEnter, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_ENTERED);
+ map.put(SWT.MouseExit, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_EXITED);
+ // map.put(SWT.MouseXXX, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED);
+ map.put(SWT.MouseVerticalWheel, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_WHEEL_MOVED);
+
+ map.put(SWT.KeyDown, com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED);
+ map.put(SWT.KeyUp, com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED);
+ // map.put(SWT.KeyXXX, com.jogamp.newt.event.KeyEvent.EVENT_KEY_TYPED);
+
+ eventTypeSWT2NEWT = map;
+ }
+
+ public static final int swtModifiers2Newt(int awtMods, boolean mouseHint) {
+ int newtMods = 0;
+ if ((awtMods & SWT.SHIFT) != 0) newtMods |= com.jogamp.newt.event.InputEvent.SHIFT_MASK;
+ if ((awtMods & SWT.CTRL) != 0) newtMods |= com.jogamp.newt.event.InputEvent.CTRL_MASK;
+ if ((awtMods & SWT.ALT) != 0) newtMods |= com.jogamp.newt.event.InputEvent.ALT_MASK;
+ return newtMods;
+ }
+
+ public static final com.jogamp.newt.event.InputEvent createInputEvent(org.eclipse.swt.widgets.Event event, Object source) {
+ com.jogamp.newt.event.InputEvent res = createMouseEvent(event, source);
+ if(null == res) {
+ res = createKeyEvent(event, source);
+ }
+ return res;
+ }
+
+ public static final com.jogamp.newt.event.MouseEvent createMouseEvent(org.eclipse.swt.widgets.Event event, Object source) {
+ switch(event.type) {
+ case SWT.MouseDown:
+ case SWT.MouseUp:
+ case SWT.MouseMove:
+ case SWT.MouseEnter:
+ case SWT.MouseExit:
+ case SWT.MouseVerticalWheel:
+ break;
+ default:
+ return null;
+ }
+ int type = eventTypeSWT2NEWT.get(event.type);
+ if(0xFFFFFFFF != type) {
+ int rotation = 0;
+ if (SWT.MouseVerticalWheel == event.type) {
+ // SWT/NEWT rotation is reversed - AWT +1 is down, NEWT +1 is up.
+ // rotation = -1 * (int) event.rotation;
+ rotation = (int) event.rotation;
+ }
+
+ int mods = swtModifiers2Newt(event.stateMask, true);
+
+ if( source instanceof com.jogamp.newt.Window) {
+ final com.jogamp.newt.Window newtSource = (com.jogamp.newt.Window)source;
+ if(newtSource.isPointerConfined()) {
+ mods |= InputEvent.CONFINED_MASK;
+ }
+ if(!newtSource.isPointerVisible()) {
+ mods |= InputEvent.INVISIBLE_MASK;
+ }
+ }
+
+ return new com.jogamp.newt.event.MouseEvent(
+ type, (null==source)?(Object)event.data:source, (0xFFFFFFFFL & (long)event.time),
+ mods, event.x, event.y, event.count, event.button, rotation);
+ }
+ return null; // no mapping ..
+ }
+
+ public static final com.jogamp.newt.event.KeyEvent createKeyEvent(org.eclipse.swt.widgets.Event event, Object source) {
+ switch(event.type) {
+ case SWT.KeyDown:
+ case SWT.KeyUp:
+ break;
+ default:
+ return null;
+ }
+ int type = eventTypeSWT2NEWT.get(event.type);
+ if(0xFFFFFFFF != type) {
+ return new com.jogamp.newt.event.KeyEvent(
+ type, (null==source)?(Object)event.data:source, (0xFFFFFFFFL & (long)event.time),
+ swtModifiers2Newt(event.stateMask, false),
+ event.keyCode, event.character);
+ }
+ return null; // no mapping ..
+ }
+
+ //
+ //
+ //
+
+ int dragButtonDown = 0;
+
+ public SWTNewtEventFactory() {
+ resetButtonsDown();
+ }
+
+ final void resetButtonsDown() {
+ dragButtonDown = 0;
+ }
+
+ public final boolean dispatchMouseEvent(org.eclipse.swt.widgets.Event event, Object source, com.jogamp.newt.event.MouseListener l) {
+ com.jogamp.newt.event.MouseEvent res = createMouseEvent(event, source);
+ if(null != res) {
+ if(null != l) {
+ switch(event.type) {
+ case SWT.MouseDown:
+ dragButtonDown = event.button;
+ l.mousePressed(res); break;
+ case SWT.MouseUp:
+ dragButtonDown = 0;
+ l.mouseReleased(res);
+ {
+ final com.jogamp.newt.event.MouseEvent res2 = new com.jogamp.newt.event.MouseEvent(
+ com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED,
+ res.getSource(),
+ res.getWhen(), res.getModifiers(),
+ res.getX(), res.getY(), res.getClickCount(),
+ res.getButton(), res.getWheelRotation() );
+ l.mouseClicked(res2);
+ }
+ break;
+ case SWT.MouseMove:
+ if( 0 < dragButtonDown ) {
+ final com.jogamp.newt.event.MouseEvent res2 = new com.jogamp.newt.event.MouseEvent(
+ com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED,
+ res.getSource(),
+ res.getWhen(), res.getModifiers(),
+ res.getX(), res.getY(), res.getClickCount(),
+ dragButtonDown, res.getWheelRotation() );
+ l.mouseDragged( res2 );
+ } else {
+ l.mouseMoved(res);
+ }
+ break;
+ case SWT.MouseEnter:
+ l.mouseEntered(res);
+ break;
+ case SWT.MouseExit:
+ resetButtonsDown();
+ l.mouseExited(res);
+ break;
+ case SWT.MouseVerticalWheel:
+ l.mouseWheelMoved(res);
+ break;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public final boolean dispatchKeyEvent(org.eclipse.swt.widgets.Event event, Object source, com.jogamp.newt.event.KeyListener l) {
+ com.jogamp.newt.event.KeyEvent res = createKeyEvent(event, source);
+ if(null != res) {
+ if(null != l) {
+ switch(event.type) {
+ case SWT.KeyDown:
+ l.keyPressed(res);
+ break;
+ case SWT.KeyUp:
+ l.keyReleased(res);
+ l.keyTyped(res);
+ break;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public final void attachDispatchListener(final org.eclipse.swt.widgets.Control ctrl, final Object source,
+ final com.jogamp.newt.event.MouseListener ml,
+ final com.jogamp.newt.event.KeyListener kl) {
+ final Listener listener = new Listener () {
+ @Override
+ public void handleEvent (Event event) {
+ if( dispatchMouseEvent( event, source, ml ) ) {
+ return;
+ }
+ if( dispatchKeyEvent( event, source, kl ) ) {
+ return;
+ }
+ } };
+ ctrl.addListener(SWT.MouseDown, listener);
+ ctrl.addListener(SWT.MouseUp, listener);
+ ctrl.addListener(SWT.MouseMove, listener);
+ ctrl.addListener(SWT.MouseEnter, listener);
+ ctrl.addListener(SWT.MouseExit, listener);
+ ctrl.addListener(SWT.MouseVerticalWheel, listener);
+ ctrl.addListener(SWT.KeyDown, listener);
+ ctrl.addListener(SWT.KeyUp, listener);
+ }
+}
+
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index e3d5cffa0..e7b454580 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -1034,23 +1034,22 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
case WM_PAINT: {
RECT r;
useDefWindowProc = 0;
- if (GetUpdateRect(wnd, &r, TRUE /* erase background */)) {
- /*
- jint width = r.right-r.left;
- jint height = r.bottom-r.top;
- if (width > 0 && height > 0) {
- (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, r.left, r.top, width, height);
- }
- ValidateRect(wnd, &r);
- */
+ if (GetUpdateRect(wnd, &r, FALSE /* do not erase background */)) {
+ // clear the whole client area and issue repaint for it, w/o looping through erase background
+ ValidateRect(wnd, NULL); // clear all!
+ (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
+ } else {
+ // shall not happen ?
+ ValidateRect(wnd, NULL); // clear all!
}
+ // return 0 == done
break;
}
case WM_ERASEBKGND:
// ignore erase background
(*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
useDefWindowProc = 0;
- res = 1; // OpenGL, etc .. erases the background, hence we claim to have just done this
+ res = 1; // return 1 == done, OpenGL, etc .. erases the background, hence we claim to have just done this
break;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
index e9fe9b401..a3023538f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
@@ -60,8 +60,8 @@ public class GearsES2 implements GLEventListener {
private int swapInterval = 0;
private boolean pmvUseBackingArray = true; // the default for PMVMatrix now, since it's faster
// private MouseListener gearsMouse = new TraceMouseAdapter(new GearsMouseAdapter());
- private MouseListener gearsMouse = new GearsMouseAdapter();
- private KeyListener gearsKeys = new GearsKeyAdapter();
+ public MouseListener gearsMouse = new GearsMouseAdapter();
+ public KeyListener gearsKeys = new GearsKeyAdapter();
private int prevMouseX, prevMouseY;
private boolean doRotate = true;
@@ -352,6 +352,10 @@ public class GearsES2 implements GLEventListener {
window = (Window) source;
width=window.getWidth();
height=window.getHeight();
+ } else if (source instanceof GLAutoDrawable) {
+ GLAutoDrawable glad = (GLAutoDrawable) source;
+ width = glad.getWidth();
+ height = glad.getHeight();
} else if (GLProfile.isAWTAvailable() && source instanceof java.awt.Component) {
java.awt.Component comp = (java.awt.Component) source;
width=comp.getWidth();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java
index 9c0762c12..1f3bf3156 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java
@@ -65,7 +65,7 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
- static int duration = 1000;
+ static int duration = 500;
static class BigFlashingX implements GLEventListener
{
@@ -262,7 +262,7 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
shell = new Shell( display );
Assert.assertNotNull( shell );
shell.setLayout( new FillLayout() );
- composite = new Composite( shell, SWT.NONE );
+ composite = new Composite( shell, SWT.NO_BACKGROUND );
composite.setLayout( new FillLayout() );
Assert.assertNotNull( composite );
}});
@@ -301,10 +301,9 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
dsc.init();
final GLWindow glWindow;
- final NewtCanvasSWT canvas;
{
final GLProfile gl2Profile = GLProfile.get( GLProfile.GL2 ) ;
- GLCapabilities caps = new GLCapabilities( gl2Profile ) ;
+ final GLCapabilities caps = new GLCapabilities( gl2Profile ) ;
glWindow = GLWindow.create( caps ) ;
glWindow.addGLEventListener( new BigFlashingX() ) ;
glWindow.addKeyListener(new KeyAdapter() {
@@ -314,7 +313,7 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
glWindow.display();
}
});
- canvas = NewtCanvasSWT.create( dsc.composite, 0, glWindow ) ;
+ NewtCanvasSWT.create( dsc.composite, 0, glWindow ) ;
}
dsc.display.syncExec( new Runnable() {
@@ -342,7 +341,7 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
}
{
- new Thread(new Runnable() {
+ final Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
@@ -360,13 +359,16 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
} catch( InterruptedException e ) { }
shallStop = true;
dsc.display.wake();
- } } ).start();
+ } } );
+ t.setDaemon(true);
+ t.start();
}
try {
while( !shallStop && !dsc.display.isDisposed() ) {
- if( !dsc.display.readAndDispatch() ) {
- dsc.display.sleep();
+ if( !dsc.display.readAndDispatch() && !shallStop ) {
+ // blocks on linux .. dsc.display.sleep();
+ Thread.sleep(10);
}
}
} catch (Exception e0) {
@@ -374,8 +376,7 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
Assert.assertTrue("Deadlock @ dispatch: "+e0, false);
}
- System.err.println("NewtCanvasAWT Dispose");
- canvas.dispose();
+ // canvas is disposed implicit, due to it's disposed listener !
dsc.dispose();
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java
new file mode 100644
index 000000000..97b3ab243
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java
@@ -0,0 +1,343 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.swt;
+
+import java.awt.AWTException;
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.swt.SWT ;
+
+import org.eclipse.swt.layout.FillLayout ;
+
+import org.eclipse.swt.widgets.Composite ;
+import org.eclipse.swt.widgets.Display ;
+import org.eclipse.swt.widgets.Shell ;
+import org.junit.Assume;
+import org.junit.Test;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities ;
+import javax.media.opengl.GLProfile;
+
+import jogamp.newt.swt.SWTEDTUtil;
+import jogamp.newt.swt.event.SWTNewtEventFactory;
+import junit.framework.Assert;
+
+import com.jogamp.nativewindow.swt.SWTAccessor;
+import com.jogamp.newt.opengl.GLWindow ;
+import com.jogamp.newt.swt.NewtCanvasSWT ;
+import com.jogamp.opengl.swt.GLCanvas;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+public class TestSWTBug643AsyncExec extends UITestCase {
+
+ static int duration = 500;
+ static boolean useAnimator = false;
+
+ ////////////////////////////////////////////////////////////////////////////////
+
+ static void resetSWTAndNEWTEDTCounter() {
+ synchronized(swtCountSync) {
+ swtCount=0;
+ }
+ synchronized(edtCountSync) {
+ edtCount=0;
+ }
+ }
+ static int incrSWTCount() {
+ synchronized(swtCountSync) {
+ swtCount++;
+ return swtCount;
+ }
+ }
+ static int getSWTCount() {
+ synchronized(swtCountSync) {
+ return swtCount;
+ }
+ }
+ static int incrNEWTCount() {
+ synchronized(edtCountSync) {
+ edtCount++;
+ return edtCount;
+ }
+ }
+ static int getNEWTCount() {
+ synchronized(edtCountSync) {
+ return edtCount;
+ }
+ }
+ static Object swtCountSync = new Object();
+ static int swtCount = 0;
+ static Object edtCountSync = new Object();
+ static int edtCount = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////
+
+ static class AsyncExecEDTFeederThread extends Thread {
+ volatile boolean shallStop = false;
+ private Display swtDisplay ;
+ private jogamp.newt.DisplayImpl newtDisplay;
+ private int swtN, newtN ;
+
+ public AsyncExecEDTFeederThread( Display swtDisplay, com.jogamp.newt.Display newtDisplay )
+ {
+ super();
+ this.swtDisplay = swtDisplay ;
+ this.newtDisplay = (jogamp.newt.DisplayImpl)newtDisplay;
+ }
+
+ final Runnable swtAsyncAction = new Runnable() {
+ public void run()
+ {
+ ++swtN ; incrSWTCount();
+ System.err.println("[SWT A-i shallStop "+shallStop+"]: Counter[loc "+swtN+", glob: "+getSWTCount()+"]");
+ } };
+
+ final Runnable newtAsyncAction = new Runnable() {
+ public void run()
+ {
+ ++newtN ; incrNEWTCount();
+ System.err.println("[NEWT A-i shallStop "+shallStop+"]: Counter[loc "+newtN+", glob: "+getNEWTCount()+"]");
+ } };
+
+ public void run()
+ {
+ System.err.println("[A-0 shallStop "+shallStop+"]");
+
+ while( !shallStop && !swtDisplay.isDisposed() )
+ {
+ try
+ {
+ swtDisplay.asyncExec( swtAsyncAction );
+ if(null != newtDisplay && newtDisplay.isNativeValid() && newtDisplay.getEDTUtil().isRunning()) {
+ // only perform async exec on valid and already running NEWT EDT!
+ newtDisplay.runOnEDTIfAvail(false, newtAsyncAction);
+ }
+ Thread.sleep( 50L ) ;
+ } catch( InterruptedException e ) {
+ break ;
+ }
+ }
+ System.err.println("*R-Exit* shallStop "+shallStop);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+
+ private volatile boolean shallStop = false;
+
+ static class SWT_DSC {
+ Display display;
+ Shell shell;
+ Composite composite;
+
+ public void init() {
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ display = new Display();
+ Assert.assertNotNull( display );
+ }});
+
+ display.syncExec(new Runnable() {
+ public void run() {
+ shell = new Shell( display );
+ Assert.assertNotNull( shell );
+ shell.setLayout( new FillLayout() );
+ composite = new Composite( shell, SWT.NO_BACKGROUND );
+ composite.setLayout( new FillLayout() );
+ Assert.assertNotNull( composite );
+ }});
+ }
+
+ public void dispose() {
+ Assert.assertNotNull( display );
+ Assert.assertNotNull( shell );
+ Assert.assertNotNull( composite );
+ try {
+ display.syncExec(new Runnable() {
+ public void run() {
+ composite.dispose();
+ shell.dispose();
+ }});
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ display.dispose();
+ }});
+ }
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ display = null;
+ shell = null;
+ composite = null;
+ }
+ }
+
+ private void testImpl(boolean useJOGLGLCanvas, boolean useNewtCanvasSWT, boolean glWindowPreVisible) throws InterruptedException, AWTException, InvocationTargetException {
+ resetSWTAndNEWTEDTCounter();
+
+ final SWT_DSC dsc = new SWT_DSC();
+ dsc.init();
+
+ final com.jogamp.newt.Display newtDisplay;
+ {
+ final GLProfile gl2Profile = GLProfile.get( GLProfile.GL2 ) ;
+ final GLCapabilities caps = new GLCapabilities( gl2Profile ) ;
+
+ final GLAutoDrawable glad;
+ if( useJOGLGLCanvas ) {
+ final GearsES2 demo = new GearsES2();
+ final GLCanvas glc = GLCanvas.create(dsc.composite, 0, caps, null, null);
+ final SWTNewtEventFactory swtNewtEventFactory = new SWTNewtEventFactory();
+ swtNewtEventFactory.attachDispatchListener(glc, glc, demo.gearsMouse, demo.gearsKeys);
+ glc.addGLEventListener( demo ) ;
+ glad = glc;
+ newtDisplay = null;
+ } else if( useNewtCanvasSWT ) {
+ final GLWindow glWindow = GLWindow.create( caps ) ;
+ glWindow.addGLEventListener( new GearsES2() ) ;
+ newtDisplay = glWindow.getScreen().getDisplay();
+ if( glWindowPreVisible ) {
+ newtDisplay.setEDTUtil(new SWTEDTUtil(newtDisplay, dsc.display)); // Especially Windows requires creation access via same thread!
+ glWindow.setVisible(true);
+ AWTRobotUtil.waitForRealized(glWindow, true);
+ Thread.sleep(120); // let it render a bit, before consumed by SWT
+ }
+ glad = glWindow;
+ NewtCanvasSWT.create( dsc.composite, 0, glWindow ) ;
+ } else {
+ throw new InternalError("XXX");
+ }
+ if(useAnimator) {
+ Animator animator = new Animator(glad);
+ animator.start();
+ }
+ }
+
+ System.err.println("**** Pre Shell Open");
+ dsc.display.syncExec( new Runnable() {
+ public void run() {
+ dsc.shell.setText( "NewtCanvasSWT Resize Bug Demo" ) ;
+ dsc.shell.setSize( 400, 450 ) ;
+ dsc.shell.open() ;
+ } } );
+ System.err.println("**** Post Shell Open");
+
+ shallStop = false;
+
+ final int[] counterBeforeExit = new int[] { 0 /* SWT */, 0 /* NEWT */ };
+
+ final AsyncExecEDTFeederThread asyncExecFeeder;
+ {
+ asyncExecFeeder = new AsyncExecEDTFeederThread(dsc.display, newtDisplay) ;
+ asyncExecFeeder.start() ;
+ }
+
+ {
+ final Thread t = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(duration);
+ } catch (InterruptedException e) {}
+
+ counterBeforeExit[0] = getSWTCount();
+ counterBeforeExit[1] = getNEWTCount();
+ asyncExecFeeder.shallStop = true;
+ try
+ {
+ asyncExecFeeder.join();
+ } catch( InterruptedException e ) { }
+ shallStop = true;
+ dsc.display.wake();
+ } } );
+ t.setDaemon(true);
+ t.start();
+ }
+
+ try {
+ final Display d = dsc.display;
+ while( !shallStop && !d.isDisposed() ) {
+ if( !d.readAndDispatch() && !shallStop ) {
+ // blocks on linux .. dsc.display.sleep();
+ Thread.sleep(10);
+ }
+ }
+ } catch (Exception e0) {
+ e0.printStackTrace();
+ Assert.assertTrue("Deadlock @ dispatch: "+e0, false);
+ }
+
+ // canvas is disposed implicit, due to it's disposed listener !
+
+ dsc.dispose();
+
+ System.err.println("EDT Counter before exit: SWT " + counterBeforeExit[0] + ", NEWT "+counterBeforeExit[1]);
+ Assert.assertTrue("SWT EDT Counter not greater zero before dispose!", 0 < counterBeforeExit[0]);
+ if( null != newtDisplay ) {
+ Assert.assertTrue("NEWT EDT Counter not greater zero before dispose!", 0 < counterBeforeExit[1]);
+ }
+ }
+
+ @Test
+ public void test01JOGLGLCanvas() throws InterruptedException, AWTException, InvocationTargetException {
+ testImpl(true /* useJOGLGLCanvas */, false /* useNewtCanvasSWT */, false /* glWindowPreVisible */);
+ }
+
+ @Test
+ public void test02NewtCanvasSWTSimple() throws InterruptedException, AWTException, InvocationTargetException {
+ testImpl(false /* useJOGLGLCanvas */, true /* useNewtCanvasSWT */, false /* glWindowPreVisible */);
+ }
+
+ @Test
+ public void test02NewtCanvasSWTPreVisible() throws InterruptedException, AWTException, InvocationTargetException {
+ testImpl(false /* useJOGLGLCanvas */, true /* useNewtCanvasSWT */, true /* glWindowPreVisible */);
+ }
+
+ public static void main( String[] args ) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ duration = MiscUtils.atoi(args[++i], duration);
+ } else if(args[i].equals("-anim")) {
+ useAnimator = true;
+ }
+ }
+ System.out.println("durationPerTest: "+duration);
+ org.junit.runner.JUnitCore.main(TestSWTBug643AsyncExec.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
index 6d9e2219c..1822d2eaf 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
@@ -50,17 +50,18 @@ import org.junit.Test;
import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.opengl.swt.GLCanvas;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2;
import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLReadBufferUtil;
import com.jogamp.opengl.util.texture.TextureIO;
/**
* Tests that a basic SWT app can open without crashing under different GL profiles.
* <p>
- * Uses JOGL's new SWT GLCanvas.
- * </p>
- * <p>
- * Note: To employ custom GLCapabilities, NewtCanvasSWT shall be used.
+ * Uses JOGL's new SWT GLCanvas,
+ * which allows utilizing custom GLCapability settings,
+ * independent from the already instantiated SWT visual.
* </p>
* <p>
* Note that {@link SWTAccessor#invoke(boolean, Runnable)} is still used to comply w/
@@ -71,7 +72,8 @@ import com.jogamp.opengl.util.texture.TextureIO;
public class TestSWTJOGLGLCanvas01GLn extends UITestCase {
static int duration = 250;
-
+ static boolean doAnimation = true;
+
static final int iwidth = 640;
static final int iheight = 480;
@@ -90,10 +92,13 @@ public class TestSWTJOGLGLCanvas01GLn extends UITestCase {
public void run() {
display = new Display();
Assert.assertNotNull( display );
+ }});
+ display.syncExec(new Runnable() {
+ public void run() {
shell = new Shell( display );
Assert.assertNotNull( shell );
shell.setLayout( new FillLayout() );
- composite = new Composite( shell, SWT.NONE );
+ composite = new Composite( shell, SWT.NO_BACKGROUND );
composite.setLayout( new FillLayout() );
Assert.assertNotNull( composite );
}});
@@ -105,10 +110,13 @@ public class TestSWTJOGLGLCanvas01GLn extends UITestCase {
Assert.assertNotNull( shell );
Assert.assertNotNull( composite );
try {
- SWTAccessor.invoke(true, new Runnable() {
+ display.syncExec(new Runnable() {
public void run() {
composite.dispose();
shell.dispose();
+ }});
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
display.dispose();
}});
}
@@ -140,13 +148,19 @@ public class TestSWTJOGLGLCanvas01GLn extends UITestCase {
public void dispose(final GLAutoDrawable drawable) { }
});
- SWTAccessor.invoke(true, new Runnable() {
+ display.syncExec(new Runnable() {
public void run() {
shell.setText( getSimpleTestName(".") );
shell.setSize( 640, 480 );
shell.open();
} } );
+ Animator anim = new Animator();
+ if(doAnimation) {
+ anim.add(canvas);
+ anim.start();
+ }
+
long lStartTime = System.currentTimeMillis();
long lEndTime = lStartTime + duration;
try {
@@ -160,7 +174,10 @@ public class TestSWTJOGLGLCanvas01GLn extends UITestCase {
throwable.printStackTrace();
Assume.assumeNoException( throwable );
}
- SWTAccessor.invoke(true, new Runnable() {
+
+ anim.stop();
+
+ display.syncExec(new Runnable() {
public void run() {
canvas.dispose();
} } );
@@ -171,6 +188,14 @@ public class TestSWTJOGLGLCanvas01GLn extends UITestCase {
runTestAGL( new GLCapabilities(GLProfile.getGL2ES2()), new GearsES2() );
}
+ @Test
+ public void test_MultisampleAndAlpha() throws InterruptedException {
+ GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(2);
+ runTestAGL( caps, new MultisampleDemoES2(true) );
+ }
+
static int atoi(String a) {
int i=0;
try {
@@ -183,6 +208,8 @@ public class TestSWTJOGLGLCanvas01GLn extends UITestCase {
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
duration = atoi(args[++i]);
+ } else if(args[i].equals("-still")) {
+ doAnimation = false;
}
}
System.out.println("durationPerTest: "+duration);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java
index c9450c2d6..e4867e3fe 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java
@@ -89,7 +89,7 @@ public class TestDisplayLifecycle01NEWT extends UITestCase {
Assert.assertEquals(0,display.getReferenceCount());
Assert.assertEquals(false,display.isNativeValid());
Assert.assertNotNull(display.getEDTUtil());
- Assert.assertEquals(false,display.getEDTUtil().isRunning());
+ Assert.assertEquals(true,display.getEDTUtil().isRunning());
Assert.assertEquals(0,screen.getReferenceCount());
Assert.assertEquals(false,screen.isNativeValid());
@@ -201,6 +201,8 @@ public class TestDisplayLifecycle01NEWT extends UITestCase {
Assert.assertEquals(false,display.isNativeValid());
Assert.assertNotNull(display.getEDTUtil());
Assert.assertEquals(false,display.getEDTUtil().isRunning());
+ display.getEDTUtil().invoke(true, null);
+ Assert.assertEquals(true,display.getEDTUtil().isRunning());
Assert.assertEquals(0,screen.getReferenceCount());
Assert.assertEquals(false,screen.isNativeValid());
diff --git a/www/index.html b/www/index.html
index e01abd5f9..acc88a154 100644
--- a/www/index.html
+++ b/www/index.html
@@ -50,6 +50,7 @@
<h3>Presentations</h3>
<ul>
<li><a href="../../doc/gpunurbs2011/graphicon2011-slides.pdf">NURBS @ GPU</a></li>
+ <li><a href="../../doc/siggraph2012/jogamp-siggraph2012.pdf">Siggraph 2012</a></li>
<li><a href="../../doc/siggraph2011/jogamp-siggraph2011.pdf">Siggraph 2011</a></li>
<li><a href="../../doc/siggraph2010/jogamp-siggraph2010.pdf">Siggraph 2010</a></li>
<li><a href="BOF-3908-JOGL-slides.pdf"> JavaOne 2007 BOF Slides</a></li>
@@ -102,477 +103,596 @@
<p>
The following are a few examples of projects and products using
JOGL. To have your project featured here, please email the
- <a href="../../wiki/index.php/Maintainer_and_Contacts">project maintainers</a>.
+ <a href="../../wiki/index.php/Maintainer_and_Contacts">project maintainers</a>.<br/>
+
+ <i>Sections:</i> <a href="#feat_apps">Applications</a>, <a href="#feat_utils">Utilities</a>, <a href="#feat_games">Games</a> and
+ <a href="#feat_old">Old</a>.
</p>
-
- <table border="0" cellpadding="0" cellspacing="1" width="100%">
+ <table border="0" cellpadding="5" cellspacing="1" width="100%">
<tbody>
<tr>
- <td valign="top" width="100%">
- <table border="0" cellpadding="5" cellspacing="1" width="100%">
+ <th colspan="1"><a id="feat_apps">Applications (Content, Simulations, CAD, Scientific, ..)</a></th>
+ </tr>
+ <tr>
+ <td >
+ <table border="0" cellspacing="15">
<tbody>
<tr>
+ <td width="50%">
+ <a href="http://processing.org/"><img src="media/processing.jpg" width="160" height="158" align="left" alt="Processing"></img>
+ Processing</a> is an open
+ source programming language and environment for people who want to
+ program images, animation, and sound. It is used by students, artists,
+ designers, architects, researchers, and hobbyists for learning,
+ prototyping, and production. Processing is developed by artists and
+ designers as an alternative to proprietary software tools in the same
+ domain. It uses JOGL for its hardware accelerated 3D rendering
+ support.
+ </td>
+ <td width="50%">
+ <a href="http://projects.hepforge.org/frog/ "><img src="media/Frog-Craft3_2.160w.png"
+ width="160" height="120" align="left" alt="FROG"></img>FROG</a>
+ is a fast OpenGL event display tool mainly developed for visualization of data
+ in the field of high energy physics. FROG is mostly used to visualized/animate data
+ from proton/proton collision produced in the CMS experiment at the LHC, CERN, Switzerland.
+ Animations produced by this tools are frequently used to share the progress of the
+ CMS experiment with the media of the world
+ (animations are often visible on scientific website or even on TV).
+
+ FROG has recently been ported to Java and is now using JOGL
+ and also offers an
+ <a href="http://projects.hepforge.org/frog/Downloads/jfrog/jfrog_web.jnlp ">online demonstration</a>.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://c3d.com"><img src="media/c3d-studio.jpg"
+ width="160" height="107" align="left" alt="C3D"></img>C3D</a>'s
+ <a href="http://c3d.com/index.php?option=com_content&amp;view=section&amp;layout=blog&amp;id=5&amp;Itemid=65">product palette</a>
+ includes <i>C3D Studio</i> and <i>C3D Viewer</i>.
+ <a href="http://c3d.com/index.php?option=com_content&amp;view=article&amp;id=46:c3dstudio&amp;catid=34:generalproducts&amp;Itemid=65">C3D Studio</a>
+ is a 3D based visual framework for developing visual project control solutions for construction projects.
+ C3D Studio provides a dynamic link between the 3D model of the project and the back-end data.
+ <a href="http://c3d.com/index.php?option=com_content&amp;view=article&amp;id=47:c3dviewer&amp;catid=34:generalproducts&amp;Itemid=65">C3D Viewer</a>
+ is the visualization tool for the 3D Model and related data. The user can either manually load 3D models and connect
+ them to data sources, or execute Studio designed rich clients ( timelines) Where 3D and related data are loaded,
+ linked and displayed for navigation and updates.
+ </td>
+
<td >
- <table border="0" cellspacing="15">
- <tbody>
- <tr>
- <td width="50%">
- <a href="http://processing.org/"><img src="media/processing.jpg" width="160" height="158" align="left" alt="Processing"></img>
- Processing</a> is an open
- source programming language and environment for people who want to
- program images, animation, and sound. It is used by students, artists,
- designers, architects, researchers, and hobbyists for learning,
- prototyping, and production. Processing is developed by artists and
- designers as an alternative to proprietary software tools in the same
- domain. It uses JOGL for its hardware accelerated 3D rendering
- support.
- </td>
- <td width="50%">
- <a href="http://projects.hepforge.org/frog/ "><img src="media/Frog-Craft3_2.160w.png"
- width="160" height="120" align="left" alt="FROG"></img>FROG</a>
- is a fast OpenGL event display tool mainly developed for visualization of data
- in the field of high energy physics. FROG is mostly used to visualized/animate data
- from proton/proton collision produced in the CMS experiment at the LHC, CERN, Switzerland.
- Animations produced by this tools are frequently used to share the progress of the
- CMS experiment with the media of the world
- (animations are often visible on scientific website or even on TV).
-
- FROG has recently been ported to Java and is now using JOGL
- and also offers an
- <a href="http://projects.hepforge.org/frog/Downloads/jfrog/jfrog_web.jnlp ">online demonstration</a>.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://c3d.com"><img src="media/c3d-studio.jpg"
- width="160" height="107" align="left" alt="C3D"></img>C3D</a>'s <a href="http://c3d.com/index.php?option=com_content&amp;view=section&amp;layout=blog&amp;id=5&amp;Itemid=65">product palette</a> includes <i>C3D Studio</i> and <i>C3D Viewer</i>.<a href="http://c3d.com/index.php?option=com_content&amp;view=article&amp;id=46:c3dstudio&amp;catid=34:generalproducts&amp;Itemid=65">C3D Studio</a> is a 3D based visual framework for developing visual project control solutions for construction projects. C3D Studio provides a dynamic link between the 3D model of the project and the back-end data. <a href="http://c3d.com/index.php?option=com_content&amp;view=article&amp;id=47:c3dviewer&amp;catid=34:generalproducts&amp;Itemid=65">C3D Viewer</a> is the visualization tool for the 3D Model and related data. The user can either manually load 3D models and connect them to data sources, or execute Studio designed rich clients ( timelines) Where 3D and related data are loaded, linked and displayed for navigation and updates.
- </td>
-
- <td >
- <a href="http://www3.math.tu-berlin.de/jreality/index.php?article_id=1"><img src="media/jreality-logo-discreteksurfaces.png"
- width="160" height="105" align="left" alt="jReality"></img>jReality</a>
- is a Java based, open-source, full-featured 3D scene graph package designed for 3D visualization and specialized in mathematical visualization. It provides several backends, including a JOGL one for Java based OpenGL rendering. JReality is thread-safe, has a flexible shading model based on an attribute-inheritance mechanism in the scene graph, device-independent user interaction and support for 3D audio (JACK). It has a plugin system for assembling custom viewers, <a href="http://www3.math.tu-berlin.de/jreality/phpbb/">an active forum</a> and a growing set of <a href="http://www3.math.tu-berlin.de/jreality/mediawiki/index.php/Developer_Tutorial">tutorial examples</a> to help developers interested in using jReality to solve their Java 3D problems. For further information please look <a href="http://www3.math.tu-berlin.de/jreality/index.php?article_id=29">here</a>.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://www.scilab.org/"><img src="media/scilab.png" width="160" height="159" align="left" alt="Scilab"></img>
- Scilab</a> is a free scientific software
- package for numerical computations providing a powerful open computing
- environment for engineering and scientific applications. It has
- sophisticated data structures, an interpreter and a high level
- programming language. It also integrates a 2-D and 3-D plotting module
- designed to visually represent and understand complex data. Fully
- integrated within the Scilab's Swing UI, the plotting module is based
- on JOGL, allowing it to take advantage of the OpenGL accelerated
- graphics.
- </td>
-
- <td width="50%">
- <a href="http://www.brightideassoftware.com/Pebbles/PebblesHome.aspx">
- <img src="media/pebbles.png" width="200" align="left" alt="OneStone Pebbles"></img>
- OneStone&reg; Pebbles</a> are a new series of calculus visualization tools developed
- by <a href="http://www.brightideassoftware.com/">Bright Ideas Software&reg;</a>.
- Each 'Pebble' in the series is a stand-alone
- program designed to illustrate a specific topic in the calculus
- syllabus. While the topic of each Pebble is different, the experience
- of using each remains as constant as possible, and features several
- elements identified as contributing to the development of a deeper
- understanding of dynamic covariant relationships. The Pebbles use JOGL
- for their interactive 3D rendering. Try the
- <a href="http://www.brightideassoftware.com/Pebbles/CurveFamilies.aspx"> Curve Families</a> and
- <a href="http://www.brightideassoftware.com/Pebbles/SurfacesOfRevolution.aspx">Surfaces of Revolution</a> examples!
- </td>
-
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://code.google.com/p/jzy3d/">
- <img src="http://martin.pernollet.free.fr/cv/projects/jzy3d/demo_ring_surface.jpg" width="160" height="120" align="left" alt="Jzy3D"></img>
- Jzy3d</a>
- stands for Java Easy 3d, and allows a rapid display of 3d scientific
- data. User can define z=f(x,y) functions binded to (customizable)
- colormaps, as well as rendering predefined simple 3d shapes
- programmaticaly or from csv files.
- One can moreover add pre/post renderers for adding java2d layers
- to the 3d scene. Jzy3d provides a simple bridge to AWT, SWT, or
- Swing, and has already been integrated in Eclipse RCP
- and Swing applications. The API releases one of the burden
- of working with OpenGL,
- 3d polygon ordering and transparency management.
- </td>
-
- <td width="50%">
- <a href="http://gephi.org/"><img src="media/gephi.jpg" width="160" height="102" align="left" alt="Gephi"></img>
- Gephi</a> is a tool for people that have to explore and understand graphs. Like Photoshop but for data, the user interacts with the representation, manipulate the structures, shapes and colors to reveal hidden properties. The goal is to help data analysts to make hypothesis, intuitively discover patterns, isolate structure singularities or faults during data sourcing. It is a complementary tool to traditional statistics, as visual thinking with interactive interfaces is now recognized to facilitate reasoning. This is a software for Exploratory Data Analysis, a paradigm appeared in the Visual Analytics field of research.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://jebgl.com/"><img src="media/JebGL_logo.160w.png"
- width="160" height="87" align="left" alt="JebGL"></img>JebGL</a>
- is a piece of Javascript which lets you run your WebGL apps in browsers lacking WebGL support without having to modify your existing code! Behind the scenes JebGL uses a fallback Java applet to emulate the WebGL canvas if needed, and the Java applet runs hardware accelerated on all platforms using JOGL.
- JebGL is open source, released under the MIT license.
- </td>
-
- <td width="50%">
- <a href="http://brandonborkholder.github.com/glg2d/"><img src="media/glg2d-demo.png" width="200" align="left" alt="GLG2D"></img>
- GLG2D</a> is a Graphics2D implementation that uses OpenGL to implement basic Java2D drawing functionality. We currently use the fixed function pipeline, with the GL2 profile for most functionality. But a shader implementation is in the pipeline (so to speak). See <a href="http://brandonborkholder.github.com/glg2d/implementationstatus.html">implementation status</a> for which features are fully implemented.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://www.everplanes.com/"><img src="media/EverplanesLogo_160x160.png" width="122" height="122" align="left" alt="Everplanes"></img>
- Everplanes</a> is a game of exploration, building, survival and strategy.
- It introduces new gameplay, resources and challenges in the updates.
- Each time the game is started, it automatically downloads the latest updates.
- The game includes a built-in server for LAN or Internet play.
- You can run an open server, or configure various levels of access control.
- Everplanes features a built-in server browser and also includes global chat facility.
- Everplanes is available for Mac OS X 10.4+, Windows XP/Vista/7 and Linux.
- </td>
- <td width="50%">
- <a href="http://www.codefrontiers.com/page/elflight-engine/"><img src="media/elflightengine-160x122.png" width="160" height="122" align="left" alt="Elflight Engine"></img>
- The Elflight Engine</a> is a games engine designed for the web.
- It supports hardware accelerated 3D games and applications in a web browser,
- with the ability to import assets from major 3D packages such as Maya and 3D Studio.
- The focus of the engine's architecture is minimal startup time, fast streaming, local
- caching and collaborative real-time editing. The Elflight Engine is multi-user and so
- lends itself to the development of virtual worlds and MMOs.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <b>On the brink ...</b>
- </td>
- <td width="50%">
- <b>.. to use JOGL Version 2.</b>
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://worldwind.arc.nasa.gov/java/"><img src="media/worldwind.jpg"
- width="160" align="left" alt="World Wind"></img>NASA World Wind
- Java</a> provides next-generation 3-D virtual globe technology for
- applications written in the Java programming language. It supplies a
- suite of open-source components that developers include in their own
- applications, providing virtual globe functionality to any application
- that can benefit from it. World Wind Java's components perform as well
- as, or better than, any other known implementation and utilize the
- OpenGL API for 3-D graphics via JOGL. See WWJ Technical Lead Tom
- Gaskins' <a href="http://developers.sun.com/learning/javaoneonline/j1sessn.jsp?sessn=TS-3489&amp;yr=2007&amp;track=2">JavaOne
- 2007</a> presentation on World Wind Java and the DiSTI Corporation's
- <a href="http://www.disti.com/Products/demonstrations/java.html">F-16 flight simulator</a>
- built using World Wind Java.
- </td>
-
- <td width="50%">
- <a href="http://www.geogebra.org/"><img src="media/geogebra-screenshot-tangents.png" width="200" align="left" alt="GeoGebra"></img>GeoGebra</a> is free and multi-platform dynamic mathematics software for all levels of education that joins geometry, algebra, tables, graphing, statistics and calculus in one easy-to-use package. It has received several educational software awards in Europe and the USA. <a href="http://www.geogebra.org/forum/viewtopic.php?f=52&amp;t=19846">GeoGebra 5.0</a> has experimental 3D support utilizing JOGL. Misc resources: <a href="https://dev.geogebra.org/trac">Developer Wiki</a>, <a href="http://dev.geogebra.org/svn">SVN Repository</a>.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <b>Older projects ...</b>
- </td>
- <td width="50%">
- <b>.. may use JOGL Version 1.</b>
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://volumeviewer.kenai.com/">
- <img src="http://volumeviewer.kenai.com/thumbnail.png" width="160" height="120" align="left" alt="Volume Viewer"></img>Volume Viewer</a>
- is an open source renderer for 3D volumetric data. It provides tools for coloring your model,
- cutting away pieces, and viewing it from any angle. It can cast shadows within the model for extra realism.
- You can even upload your own volumetric data and view it in real time.
- </td>
- <td >
- <a href="http://bytonic.de/html/jake2.html">
- <img src="media/jake2.jpg" width="160" height="128" align="left" alt="Jake2"></img>Jake2</a> is a port
- of id Software's GPL'd Quake II engine from C to Java done by <a
- href="http://bytonic.de/">bytonic software</a>. You can run the game
- via <a href="http://bytonic.de/html/jake2_webstart.html">Java Web
- Start</a> with <b>no manual installation</b> on all of JOGL's
- supported platforms.
- </td>
-
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://www.fusion-laboratory.de/"><img
- src="media/fusion-laboratory.jpg" width="160" height="160" align="left"
- alt="Fusion Laboratory"></img>The Fusion Framework</a> enables Swing
- components to be extended with 3D content via JOGL. In general the 3D
- content will show up in layers on top of the corresponding Swing
- component. Many utility functions are integrated to help the developer
- build components. For example, the 3D content may be calibrated to the
- corresponding component's bounds. In addition, the system provides a
- simple scenegraph, Swing-like mouse interaction, and low-level
- animation support, as well as GLSL shaders and .obj file loading. The
- demo page contains several Java Web Start applications which
- demonstrate the abilities of the framework; please fill out the web
- form to help evaluate the components' usefulness.
- </td>
-
- <td width="50%">
- <a href="http://3d-alignment.eu"><img src="media/strap.jpg" width="160" height="118" align="left" alt="STRAP"></img></a>
- With <a href="http://3d-alignment.eu">STRAP</a> you can align your proteins by
- sequence and 3D-structure. STRAP simultaneously displays
- 3d-structures, amino acid sequence alignment and nucleotide sequences.
- It has powerful annotation features.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://www.artofillusion.org/"><img src="media/artofillusion.jpg" width="160" height="117" align="left" alt="Art Of Illusion"></img>
- Art of Illusion</a> is a free, open source 3D modelling and rendering
- studio. Many of its capabilities rival those found in commercial
- programs. Some of the highlights include subdivision surface based
- modelling tools, skeleton based animation, and a graphical language
- for designing procedural textures and materials. It uses JOGL for
- real-time OpenGL rendering in its modeling views.
- </td>
-
- <td width="50%">
- <a href="http://impact.sourceforge.net/"><img src="media/impact.jpg" width="160" height="129" align="left" alt="Impact"></img>
- Impact</a> is a
- complete finite element suite including preprocessor, solver and
- postprocessor which is useable for simulating dynamic events such as
- car crashes or stamping of metal sheets. The suite allows 3D
- modelling, solving and viewing of simulation results, all in OpenGL
- accelerated graphics through the use of JOGL.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://www.sculpteo.com"><img src="media/sculpteo_3_robot_72dpi_sm.jpg" width="160" height="120" align="left" alt="Sculpteo"></img>
- Sculpteo</a> offers a 3D printing service, fast and available for everyone.
- Starting from a 3D design, Sculpteo makes a specific object : interior decoration, characters, robots, miniatures, models, mechanic objects...
- </td>
- <td width="50%">
- <a href="http://www.fenggui.org/"><img src="media/fenggui.jpg" width="160" height="127" align="left" alt="FengGUI"></img>
- FengGUI</a> is a graphical
- user interface (GUI) application programming interface (API) based on
- OpenGL. FengGUI provides all typical GUI components like buttons,
- sliders, trees, text areas, frames, tabs, etc. which are required to
- build a complete GUI system. Since it is based on OpenGL, FengGUI fits
- well in multimedia and game environments.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://mbt.sdsc.edu/"><img src="media/mbt.jpg" width="160" height="122" align="left" alt="Molecular Biology Toolkit"></img></a>The
- <a href="http://mbt.sdsc.edu/">Molecular Biology Toolkit</a> is a
- Java-based protein visualization and analysis toolkit. The toolkit
- provides classes for efficiently loading, managing and manipulating
- protein structure and sequence data. The MBT also provides a rich set
- of graphical 3D and 2D visualization components which can be easily
- "plugged together" to produce applications having sophisticated
- graphical user interfaces. Some MBT-based visualization tools are <a
- href="http://www.pdb.org/">ProteinWorkshop</a> (<a
- href="http://spdc.sdsc.edu/iedb/protein_workshop/viewer7.php">webstart
- demo</a>), <a href="http://www.immuneepitope.org/">EpitopeViewer</a>
- (<a href="http://spdc.sdsc.edu/iedb/epitopeViewer/viewer_jogl333.php">webstart demo</a>), and <a href="http://sirius.sdsc.edu/">Sirius</a>.
- </td>
-
- <td width="50%">
- <a href="http://www.specknet.org/dev/specksim"><img src="media/specksim.jpg" width="160" height="117" align="left" alt="SpeckSim"></img>
- SpeckSim</a> is a
- behaviour-level simulator for networks of small, resource-constrained
- devices with sensing, computation and communication
- capabilities. Intended as a testbed for distributed algorithms, the
- main design goal was ease of extension. To this end, almost all aspect
- of the simulator can be customised: Node behaviour, communication
- characteristics, placement and motion; visualisation rendering and
- interaction and statistic generation.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://www.insightmachines.com/en/vehicleDynamicsEngine.shtml">
- <img src="media/vehicle.jpg" width="160" height="160" align="left" alt="Vehicle Dynamics Engine Demo"></img>Vehicle Dynamics Engine Demo</a>
- is a Java Web Start demonstration of a 3D physics engine developed by
- <a href="http://www.insightmachines.com/">Insight Machines</a>. The
- engine is designed especially for car games. The demo uses JOGL and
- employs such techniques like shadow casting using the stencil buffer.
- </td>
-
- <td width="50%">
-
- <a href="http://chronotext.org/"><img src="media/chronotext.jpg" width="160" height="120" align="left" alt="chronotext"></img>
- chronotext</a> is a series
- of visual design experiments involving animated text and 3D objects
- and surfaces. Several examples can be run on-line via <a
- href="http://chronotext.org/scriptorium/behind/index.htm">Java Web
- Start</a>. See the <a href="http://www.chronotext.org/mapping/">latest
- experiments</a> of mapping text on to real 3D surfaces.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://www.avengina.org/"><img src="media/avengina.jpg" alt="Avengina" align="left" height="99" width="160"></img>Avengina</a> is a
- realtime 3D graphics engine which is designed for the execution as a
- Java applet. Alternatively it can be launched as a Java Webstart
- application outside the browserwindow. The software provides the
- possibility to exhibit texts and images in virtual
- galleries. Regarding the control and behaviour of the avatar it's
- redolent of a game engine. The graphics rendering system bases on
- per-pixel lighting and supports normal mapping, specular lighting and
- stencil volume shadows. Avengina uses JOGL for realtime rendering.
- </td>
-
- <td >
- <a href="http://netbeans-opengl-pack.dev.java.net/">
- <img src="media/NetBeansOpenGLPackLogo160.png" width="160" height="159" align="left" alt="NOGL Pack logo"></img>
- The NetBeans OpenGL Pack</a> provides an easy to use OpenGL development
- environment integrated into NetBeans. It supplies modules like an GLSL
- shader editor, hardware compiler/linker integration and tools for
- displaying hardware information. The pack ships ready to run JOGL (JSR
- 231) demo projects and all OpenGL samples of the OpenGL Programming
- Guide (also known as the Red Book).
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://www.nascar.com/trackpass/about/raceview/"><img src="media/raceview.jpg" width="160" height="92" align="left" alt="RaceView"></img>
- RaceView</a> from NASCAR / NEXTEL, part of the <a
- href="http://www.nascar.com/trackpass/">TrackPass</a> package, puts
- you in the race. Control the virtual camera angle, listen to the
- driver and team, and see crucial statistics and times, all in real
- time as the race goes on. RaceView uses JOGL for its 3D rendering.
- </td>
-
- <td width="50%">
- <a href="http://www.insparia.com/"><img src="media/insparia.jpg" width="160" height="160" align="left" alt="Insparia"></img>
- Insparia</a> was created to help people
- easily visualize, construct and track information about a 3d
- environment online. Shape and texture importing as well as a robust
- renderer will be available in the final commercial version. Insparia
- uses JOGL to allow the user to construct and interact with their 3d
- environment in real-time. Please note that Insparia is in alpha
- testing. Feedback is appreciated.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <b>Discontinued ..</b>
- </td>
- <td width="50%">
- <b>.. projects</b>
- </td>
- </tr>
- <tr>
- <td width="50%">
- <a href="http://www.madlix.com"><img src="media/madlix.png" width="160"
- height="160" align="left" alt="Madlix"></img>MADLIX</a> lets users insert
- 3D-content in web pages, blogs, Google pages, community presentations
- and more. MADLIX is JOGL-powered and runs smoothly inside all
- Java-enabled browsers, with no need for custom plug-ins or application
- installation. The <a href="http://www.madlix.com">on-line gallery</a>
- features high-quality content ready for insertion. MADLIX is
- accompanied by the MADLIX exporter tool enabling 3D artists to
- directly export their 3D artwork from Autodesk Maya to the MADLIX
- gallery. The exporter features pre-view functionality as well as a
- standalone viewer, supporting the MADLIX file format and the open
- standard file format COLLADA.
-
- </td>
- <td width="50%">
- <a href="https://zg3d.dev.java.net/"><img src="media/zg3d.png" width="160" height="160" align="left" alt="ZG3D"></img>
- ZG3D</a> is an open source project that uses
- JOGL for visualizing 3D geometries with the emphasis of plotting
- scientific data in a web application. Geometry objects in an XML file
- or string can be dynamically loaded and removed. An HTML document may
- call ZG3D functions through JavaScript and may define JavaScript
- functions to receive messages from ZG3D, which makes it very easy and
- flexible to embed interactive 3D web visualization. The software is
- developed at the <a
- href="http://www-cger.nies.go.jp/index.html">Center for Global
- Environmental Research</a>, Japan, for the advanced data visualization
- of the <a href="http://db.cger.nies.go.jp/g3db/ggtu/trajectory.html">Global Greenhouse Gases Database</a>.
- </td>
- </tr>
-
- <tr>
- <td width="50%">
- <a href="http://www.simulation.com/products/glstudio/glstudio.html"><img
- src="media/glstudio.jpg" width="160" height="135" align="left" alt="GL Studio"></img>
- GL Studio</a> is an object oriented rapid application
- development tool that allows a user to graphically combine
- photographs, 3D models and behavior logic to create advanced 2D and 3D
- human machine interfaces. GL Studio generates Java or C++ source code
- which can then be integrated into the user’s application as a user
- interface. <a
- href="http://www.simulation.com/products/glstudio/java/java.html">Java
- code</a> generated with GL Studio can be deployed using
- javax.swing.JPanel, java.awt.Canvas and JavaBeans. GL Studio uses
- OpenGL for rendering and GL Studio for Java uses the JOGL API.
-
- </td>
-
- <td width="50%">
- <a href="http://www.vlsolutions.com/">
- <img src="media/vldocking.jpg" width="160" height="113" align="left" alt="VLDocking"></img>VLDocking</a> is
- a set of Java components that helps the Swing developer to build
- applications with Docking capabilities, and even raise existing
- applications to higher standards. It supports docking via drag and
- drop, enhanced toolbars, closable tabs, and more. It fully supports
- heavyweight components such as JOGL's GLCanvas in a docking
- environment.
- </td>
- </tr>
-
- <!--- abandoned JOGL ..
- <tr>
- <td >
- <a href="http://openendedgroup.com/field"><img src="media/field.png"
- width="160" height="159" align="left" alt="Field"></img>Field</a> is an
- open-source development environment for digital art and experimental
- code writing. Built around the needs of programmers that manipulate
- images, make animations and compose music, Field seeks to tie
- text-based programming with ad hoc visual metaphors. Field uses Python
- and other programming languages and wants to be integrated into your
- own personal code-base. And it comes with special support for the <a
- href="http://processing.org/">Processing</a> environment. Field uses
- JOGL for its UI and its built-in drawing system; it provides a
- JOGL-based scene-graph library for 3D visualization.
- </td>
- </tr>
- <td width="50%">
- <a href="http://www.eclipse.org/gef3d/"><img src="http://wiki.eclipse.org/images/thumb/b/be/Gef3d_sample_ecore3D.png/800px-Gef3d_sample_ecore3D.png" width="160" height="94" align="left" alt="GEF3d"></img>
- GEF3D</a> is an Eclipse GEF extension bringing 3D to diagram editing.
- That is with GEF3D you can create 3D diagrams, 2D diagrams and combine
- 3D with 2D diagrams. GEF3D extends GEF by providing 3D enabled draw and
- controller classes. Instead of drawing 2D figures, you can now draw 3D figures.
- Existing GEF-based 2D editors can be embedded into 3D editors with minimal effort.
- </td>
- -->
-
- </tbody>
- </table>
+ <a href="http://www3.math.tu-berlin.de/jreality/index.php?article_id=1"><img src="media/jreality-logo-discreteksurfaces.png"
+ width="160" height="105" align="left" alt="jReality"></img>jReality</a>
+ is a Java based, open-source, full-featured 3D scene graph package designed for 3D visualization and specialized in mathematical visualization.
+ It provides several backends, including a JOGL one for Java based OpenGL rendering. JReality is thread-safe,
+ has a flexible shading model based on an attribute-inheritance mechanism in the scene graph, device-independent user interaction and support
+ for 3D audio (JACK). It has a plugin system for assembling custom viewers,
+ <a href="http://www3.math.tu-berlin.de/jreality/phpbb/">an active forum</a> and a growing set of
+ <a href="http://www3.math.tu-berlin.de/jreality/mediawiki/index.php/Developer_Tutorial">tutorial examples</a>
+ to help developers interested in using jReality to solve their Java 3D problems.
+ For further information please look <a href="http://www3.math.tu-berlin.de/jreality/index.php?article_id=29">here</a>.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://www.scilab.org/"><img src="media/scilab.png" width="160" height="159" align="left" alt="Scilab"></img>
+ Scilab</a> is a free scientific software
+ package for numerical computations providing a powerful open computing
+ environment for engineering and scientific applications. It has
+ sophisticated data structures, an interpreter and a high level
+ programming language. It also integrates a 2-D and 3-D plotting module
+ designed to visually represent and understand complex data. Fully
+ integrated within the Scilab's Swing UI, the plotting module is based
+ on JOGL, allowing it to take advantage of the OpenGL accelerated
+ graphics.
+ </td>
+
+ <td width="50%">
+ <a href="http://www.brightideassoftware.com/Pebbles/PebblesHome.aspx">
+ <img src="media/pebbles.png" width="160" align="left" alt="OneStone Pebbles"></img>
+ OneStone&reg; Pebbles</a> are a new series of calculus visualization tools developed
+ by <a href="http://www.brightideassoftware.com/">Bright Ideas Software&reg;</a>.
+ Each 'Pebble' in the series is a stand-alone
+ program designed to illustrate a specific topic in the calculus
+ syllabus. While the topic of each Pebble is different, the experience
+ of using each remains as constant as possible, and features several
+ elements identified as contributing to the development of a deeper
+ understanding of dynamic covariant relationships. The Pebbles use JOGL
+ for their interactive 3D rendering. Try the
+ <a href="http://www.brightideassoftware.com/Pebbles/CurveFamilies.aspx"> Curve Families</a> and
+ <a href="http://www.brightideassoftware.com/Pebbles/SurfacesOfRevolution.aspx">Surfaces of Revolution</a> examples!
+ </td>
+
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://www.geogebra.org/"><img src="media/geogebra-screenshot-tangents.png" width="160" align="left" alt="GeoGebra"></img>GeoGebra</a>
+ is free and multi-platform dynamic mathematics software for all levels of education that joins geometry, algebra,
+ tables, graphing, statistics and calculus in one easy-to-use package.
+ It has received several educational software awards in Europe and the USA.
+ <a href="http://www.geogebra.org/forum/viewtopic.php?f=52&amp;t=19846">GeoGebra 5.0</a> has experimental 3D support utilizing JOGL.
+ Misc resources: <a href="https://dev.geogebra.org/trac">Developer Wiki</a>, <a href="http://dev.geogebra.org/svn">SVN Repository</a>.
+ </td>
+
+ <td width="50%">
+ <a href="http://gephi.org/"><img src="media/gephi.jpg" width="160" height="102" align="left" alt="Gephi"></img>
+ Gephi</a> is a tool for people that have to explore and understand graphs. Like Photoshop but for data,
+ the user interacts with the representation, manipulate the structures, shapes and colors to reveal hidden properties.
+ The goal is to help data analysts to make hypothesis, intuitively discover patterns, isolate structure singularities or
+ faults during data sourcing. It is a complementary tool to traditional statistics,
+ as visual thinking with interactive interfaces is now recognized to facilitate reasoning.
+ This is a software for Exploratory Data Analysis, a paradigm appeared in the Visual Analytics field of research.
+ </td>
+ </tr>
+ <tr>
+ <td width="50%">
+ <a href="http://code.google.com/p/jzy3d/">
+ <img src="http://martin.pernollet.free.fr/cv/projects/jzy3d/demo_ring_surface.jpg" width="160" height="120" align="left" alt="Jzy3D"></img>
+ Jzy3d</a>
+ stands for Java Easy 3d, and allows a rapid display of 3d scientific
+ data. User can define z=f(x,y) functions binded to (customizable)
+ colormaps, as well as rendering predefined simple 3d shapes
+ programmaticaly or from csv files.
+ One can moreover add pre/post renderers for adding java2d layers
+ to the 3d scene. Jzy3d provides a simple bridge to AWT, SWT, or
+ Swing, and has already been integrated in Eclipse RCP
+ and Swing applications. The API releases one of the burden
+ of working with OpenGL,
+ 3d polygon ordering and transparency management.
+ </td>
+ <td width="50%">
+ <a href="http://volumeviewer.kenai.com/">
+ <img src="http://volumeviewer.kenai.com/thumbnail.png" width="160" height="120" align="left" alt="Volume Viewer"></img>Volume Viewer</a>
+ is an open source renderer for 3D volumetric data. It provides tools for coloring your model,
+ cutting away pieces, and viewing it from any angle. It can cast shadows within the model for extra realism.
+ You can even upload your own volumetric data and view it in real time.
+ </td>
+ </tr>
+ <tr>
+ <td width="50%">
+ <a href="http://www.insparia.com/"><img src="media/insparia.jpg" width="160" height="160" align="left" alt="Insparia"></img>
+ Insparia</a> was created to help people
+ easily visualize, construct and track information about a 3d
+ environment online. Shape and texture importing as well as a robust
+ renderer will be available in the final commercial version. Insparia
+ uses JOGL to allow the user to construct and interact with their 3d
+ environment in real-time. Please note that Insparia is in alpha
+ testing. Feedback is appreciated.
+ </td>
+ <td width="50%">
</td>
</tr>
</tbody>
</table>
</td>
</tr>
+ <tr>
+ <th colspan="1"><a id="feat_utils">Utilities, Libraries, Building blocks</a></th>
+ </tr>
+ <tr>
+ <td >
+ <table border="0" cellspacing="15">
+ <tbody>
+ <tr>
+ <td width="50%">
+ <a href="http://jmonkeyengine.org/"><img src="media/jmonkeyengine.png"
+ width="160" align="left" alt="jMonkeyEngine"></img>jMonkeyEngine</a>
+ is a game engine made for developers who want to create 3D games following modern technology standards.
+ The framework is programmed entirely in Java aimed at wide accessibility and quick deployment to desktop, web, and mobile platforms.<br/>
+ Currently <a href="http://jogamp.org/wiki/index.php/Maintainer_and_Contacts#Julien_Gouesse">Julien Gouesse</a>
+ develops a <a href="http://jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/jogl-support-jogl2-that-is/">JOGL backend for jME3</a>
+ with support of the jME team. <i>NEWT support</i> is also underway, which will allow jME3 to run <i>on mobile devices</i> as long
+ proper <a href="http://jogamp.org/jogl/doc/Overview-OpenGL-Evolution-And-JOGL.html">JOGL/OpenGL</a>
+ <a href="http://jogamp.org/jogl/doc/bouml/html-svg/fig128069.svg">profile separation</a> is being used.
+ </td>
+
+ <td width="50%">
+ <a href="http://ardor3d.com/"><img src="media/ardor3d.png"
+ width="160" align="left" alt="Ardor3D"></img>Ardor3D</a>
+ is a professionally oriented, open source, Java based 3D engine brought to you by <a href="http://www.ardorlabs.com/">Ardor Labs</a>.<br/>
+ <a href="http://jogamp.org/wiki/index.php/Maintainer_and_Contacts#Julien_Gouesse">Julien Gouesse</a> started the new JOGL backend development,
+ which is now merged into the official trunk.
+ </td>
+ </tr>
+ <tr>
+ <td width="50%">
+ <a href="http://en.wikipedia.org/wiki/Java_3D"><img src="media/Java3d.png" width="160" align="left" alt="Ardor3D"></img>Java3D</a>
+ <a href="http://gouessej.wordpress.com/2012/08/01/java-3d-est-de-retour-java-3d-is-back/">is back</a>.
+ It is maintained by <a href="https://jogamp.org/wiki/index.php/Maintainer_and_Contacts#Harvey_Harrison">Harvey Harrison</a> and initially ported to
+ our current JOGL version by <a href="http://jogamp.org/wiki/index.php/Maintainer_and_Contacts#Julien_Gouesse">Julien Gouesse</a>.<br/>
+ Source available via this <a href="https://github.com/hharrison/java3d-core">git repository</a>
+ and JAR files can <a href="https://github.com/hharrison/java3d-core/downloads">be downloaded here</a>.
+ Our <a href="http://forum.jogamp.org/java3d-f3728156.html">forum</a> may help you with your questions.
+ </td>
+
+ <td width="50%">
+ <a href="http://www.dyn4j.org/"><img src="media/dyn4j.png"
+ width="160" align="left" alt="dyn4j"></img>dyn4j</a>
+ is a 100% Java 2D collision detection and physics engine. Designed to be fast, stable, extensible, and easy to use.
+ dyn4j is free for use in commercial and non-commercial applications and licensed under the New BSD License.
+ The project comprises hundreds of JUnit test cases, Sandbox: a GUI test application, two example applications (ExampleGraphics2D and ExampleJOGL),
+ Javadocs, wiki, forum, and more!
+ </td>
+ </tr>
+ <tr>
+ <td width="50%">
+ <a href="http://brandonborkholder.github.com/glg2d/"><img src="media/glg2d-demo.png" width="160" align="left" alt="GLG2D"></img>
+ GLG2D</a> is a Graphics2D implementation that uses OpenGL to implement basic Java2D drawing functionality.
+ We currently use the fixed function pipeline, with the GL2 profile for most functionality.
+ But a shader implementation is in the pipeline (so to speak).
+ See <a href="http://brandonborkholder.github.com/glg2d/implementationstatus.html">implementation status</a>
+ for which features are fully implemented.
+ </td>
+ <td width="50%">
+ <a href="http://nifty-gui.lessvoid.com/"><img src="media/nifty-logo-new.png" width="160" align="left" alt="Nifty GUI"></img>
+ Nifty GUI</a> is a Java Library that supports the building of interactive user interfaces for games or similar applications.
+ The configuration of the GUI is stored in xml files with little supporting Java code.
+ In short Nifty helps you to layout stuff, display it in a cool way and interact with it :)<br/>
+ Source code is available in this <a href="https://github.com/void256/nifty-gui">git repository</a>.
+ JOGL is one renderer backend besides others.
+ </td>
+ </tr>
+ <tr>
+ <td width="50%">
+ <a href="http://jebgl.com/"><img src="media/JebGL_logo.160w.png"
+ width="160" height="87" align="left" alt="JebGL"></img>JebGL</a>
+ is a piece of Javascript which lets you run your WebGL apps in browsers lacking WebGL support without having to modify your existing code!
+ Behind the scenes JebGL uses a fallback Java applet to emulate the WebGL canvas if needed, and the Java applet runs hardware accelerated
+ on all platforms using JOGL.
+ JebGL is open source, released under the MIT license.
+ </td>
+
+ <td width="50%">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th colspan="1"><a id="feat_games">Games</a></th>
+ </tr>
+ <tr>
+ <td >
+ <table border="0" cellspacing="15">
+ <tbody>
+ <tr>
+ <td width="50%">
+ <a href="http://store.steampowered.com/app/108200/"><img src="media/ticket2ride_picture4.jpg"
+ width="160" align="left" alt="Ticket to Ride"></img>Ticket to Ride</a>
+ and <a href="http://store.steampowered.com/app/108210/">Memoir '44</a> are boardgames published by
+ <a href="http://www.daysofwonder.com/">Days of Wonder</a>.
+ They also make digital versions of these games since 2006. These are available on all desktops computers (Windows, MacOS and Linux),
+ thanks to the use of Java and JOGL.
+ This has proven to be the best solution to create the same gaming experience on all desktop computers with a single code base.
+ The games are available on Steam. Days of Wonder is currently porting their engine to JOGL2, allowing the inclusion of Android devices.
+ </td>
+
+ <td width="50%">
+ <a href="http://www.everplanes.com/"><img src="media/EverplanesLogo_160x160.png" width="122" height="122" align="left" alt="Everplanes"></img>
+ Everplanes</a> is a game of exploration, building, survival and strategy.
+ It introduces new gameplay, resources and challenges in the updates.
+ Each time the game is started, it automatically downloads the latest updates.
+ The game includes a built-in server for LAN or Internet play.
+ You can run an open server, or configure various levels of access control.
+ Everplanes features a built-in server browser and also includes global chat facility.
+ Everplanes is available for Mac OS X 10.4+, Windows XP/Vista/7 and Linux.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://www.codefrontiers.com/page/elflight-engine/"><img src="media/elflightengine-160x122.png" width="160" height="122" align="left" alt="Elflight Engine"></img>
+ The Elflight Engine</a> is a games engine designed for the web.
+ It supports hardware accelerated 3D games and applications in a web browser,
+ with the ability to import assets from major 3D packages such as Maya and 3D Studio.
+ The focus of the engine's architecture is minimal startup time, fast streaming, local
+ caching and collaborative real-time editing. The Elflight Engine is multi-user and so
+ lends itself to the development of virtual worlds and MMOs.
+ </td>
+
+ <td width="50%">
+ <a href="http://bytonic.de/html/jake2.html">
+ <img src="media/jake2.jpg" width="160" height="128" align="left" alt="Jake2"></img>Jake2</a> is a port
+ of id Software's GPL'd Quake II engine from C to Java done by <a
+ href="http://bytonic.de/">bytonic software</a>.<br/>
+ Jake2 has been ported to the current JOGL version for desktop OpenGL and mobile OpenGL ES1 and ES2 use
+ including dropping AWT in favor of NEWT.
+ You can run the game <a href="http://jogamp.org/deployment/test/jake2/">online</a>
+ with <b>no manual installation</b> on all of JOGL's supported platforms.<br/>
+ You can find the current source code in this
+ <a href="http://jogamp.org/git/?p=users/sgothel/jake2.git;a=summary">git repository</a>.
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th colspan="1"><a id="feat_old">Older projects ...</a></th>
+ </tr>
+ <tr>
+ <td >
+ <table border="0" cellspacing="15">
+ <tbody>
+ <tr>
+ <td width="50%">
+ <a href="http://www.fusion-laboratory.de/"><img
+ src="media/fusion-laboratory.jpg" width="160" height="160" align="left"
+ alt="Fusion Laboratory"></img>The Fusion Framework</a> enables Swing
+ components to be extended with 3D content via JOGL. In general the 3D
+ content will show up in layers on top of the corresponding Swing
+ component. Many utility functions are integrated to help the developer
+ build components. For example, the 3D content may be calibrated to the
+ corresponding component's bounds. In addition, the system provides a
+ simple scenegraph, Swing-like mouse interaction, and low-level
+ animation support, as well as GLSL shaders and .obj file loading. The
+ demo page contains several Java Web Start applications which
+ demonstrate the abilities of the framework; please fill out the web
+ form to help evaluate the components' usefulness.
+ </td>
+
+ <td width="50%">
+ <a href="http://worldwind.arc.nasa.gov/java/"><img src="media/worldwind.jpg"
+ width="160" align="left" alt="World Wind"></img>NASA World Wind
+ Java</a> provides next-generation 3-D virtual globe technology for
+ applications written in the Java programming language. It supplies a
+ suite of open-source components that developers include in their own
+ applications, providing virtual globe functionality to any application
+ that can benefit from it. World Wind Java's components perform as well
+ as, or better than, any other known implementation and utilize the
+ OpenGL API for 3-D graphics via JOGL. See WWJ Technical Lead Tom
+ Gaskins' <a href="http://developers.sun.com/learning/javaoneonline/j1sessn.jsp?sessn=TS-3489&amp;yr=2007&amp;track=2">JavaOne
+ 2007</a> presentation on World Wind Java and the DiSTI Corporation's
+ <a href="http://www.disti.com/Products/demonstrations/java.html">F-16 flight simulator</a>
+ built using World Wind Java.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://www.artofillusion.org/"><img src="media/artofillusion.jpg" width="160" height="117" align="left" alt="Art Of Illusion"></img>
+ Art of Illusion</a> is a free, open source 3D modelling and rendering
+ studio. Many of its capabilities rival those found in commercial
+ programs. Some of the highlights include subdivision surface based
+ modelling tools, skeleton based animation, and a graphical language
+ for designing procedural textures and materials. It uses JOGL for
+ real-time OpenGL rendering in its modeling views.
+ </td>
+
+ <td width="50%">
+ <a href="http://3d-alignment.eu"><img src="media/strap.jpg" width="160" height="118" align="left" alt="STRAP"></img></a>
+ With <a href="http://3d-alignment.eu">STRAP</a> you can align your proteins by
+ sequence and 3D-structure. STRAP simultaneously displays
+ 3d-structures, amino acid sequence alignment and nucleotide sequences.
+ It has powerful annotation features.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://www.sculpteo.com"><img src="media/sculpteo_3_robot_72dpi_sm.jpg" width="160" height="120" align="left" alt="Sculpteo"></img>
+ Sculpteo</a> offers a 3D printing service, fast and available for everyone.
+ Starting from a 3D design, Sculpteo makes a specific object : interior decoration, characters, robots, miniatures, models, mechanic objects...
+ </td>
+ <td width="50%">
+ <a href="http://www.fenggui.org/"><img src="media/fenggui.jpg" width="160" height="127" align="left" alt="FengGUI"></img>
+ FengGUI</a> is a graphical
+ user interface (GUI) application programming interface (API) based on
+ OpenGL. FengGUI provides all typical GUI components like buttons,
+ sliders, trees, text areas, frames, tabs, etc. which are required to
+ build a complete GUI system. Since it is based on OpenGL, FengGUI fits
+ well in multimedia and game environments.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://mbt.sdsc.edu/"><img src="media/mbt.jpg" width="160" height="122" align="left" alt="Molecular Biology Toolkit"></img></a>The
+ <a href="http://mbt.sdsc.edu/">Molecular Biology Toolkit</a> is a
+ Java-based protein visualization and analysis toolkit. The toolkit
+ provides classes for efficiently loading, managing and manipulating
+ protein structure and sequence data. The MBT also provides a rich set
+ of graphical 3D and 2D visualization components which can be easily
+ "plugged together" to produce applications having sophisticated
+ graphical user interfaces. Some MBT-based visualization tools are <a
+ href="http://www.pdb.org/">ProteinWorkshop</a> (<a
+ href="http://spdc.sdsc.edu/iedb/protein_workshop/viewer7.php">webstart
+ demo</a>), <a href="http://www.immuneepitope.org/">EpitopeViewer</a>
+ (<a href="http://spdc.sdsc.edu/iedb/epitopeViewer/viewer_jogl333.php">webstart demo</a>), and <a href="http://sirius.sdsc.edu/">Sirius</a>.
+ </td>
+
+ <td width="50%">
+ <a href="http://impact.sourceforge.net/"><img src="media/impact.jpg" width="160" height="129" align="left" alt="Impact"></img>
+ Impact</a> is a
+ complete finite element suite including preprocessor, solver and
+ postprocessor which is useable for simulating dynamic events such as
+ car crashes or stamping of metal sheets. The suite allows 3D
+ modelling, solving and viewing of simulation results, all in OpenGL
+ accelerated graphics through the use of JOGL.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://www.insightmachines.com/en/vehicleDynamicsEngine.shtml">
+ <img src="media/vehicle.jpg" width="160" height="160" align="left" alt="Vehicle Dynamics Engine Demo"></img>Vehicle Dynamics Engine Demo</a>
+ is a Java Web Start demonstration of a 3D physics engine developed by
+ <a href="http://www.insightmachines.com/">Insight Machines</a>. The
+ engine is designed especially for car games. The demo uses JOGL and
+ employs such techniques like shadow casting using the stencil buffer.
+ </td>
+
+ <td width="50%">
+
+ <a href="http://chronotext.org/"><img src="media/chronotext.jpg" width="160" height="120" align="left" alt="chronotext"></img>
+ chronotext</a> is a series
+ of visual design experiments involving animated text and 3D objects
+ and surfaces. Several examples can be run on-line via <a
+ href="http://chronotext.org/scriptorium/behind/index.htm">Java Web
+ Start</a>. See the <a href="http://www.chronotext.org/mapping/">latest
+ experiments</a> of mapping text on to real 3D surfaces.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://www.avengina.org/"><img src="media/avengina.jpg" alt="Avengina" align="left" height="99" width="160"></img>Avengina</a> is a
+ realtime 3D graphics engine which is designed for the execution as a
+ Java applet. Alternatively it can be launched as a Java Webstart
+ application outside the browserwindow. The software provides the
+ possibility to exhibit texts and images in virtual
+ galleries. Regarding the control and behaviour of the avatar it's
+ redolent of a game engine. The graphics rendering system bases on
+ per-pixel lighting and supports normal mapping, specular lighting and
+ stencil volume shadows. Avengina uses JOGL for realtime rendering.
+ </td>
+
+ <td >
+ <a href="http://netbeans-opengl-pack.dev.java.net/">
+ <img src="media/NetBeansOpenGLPackLogo160.png" width="160" height="159" align="left" alt="NOGL Pack logo"></img>
+ The NetBeans OpenGL Pack</a> provides an easy to use OpenGL development
+ environment integrated into NetBeans. It supplies modules like an GLSL
+ shader editor, hardware compiler/linker integration and tools for
+ displaying hardware information. The pack ships ready to run JOGL (JSR
+ 231) demo projects and all OpenGL samples of the OpenGL Programming
+ Guide (also known as the Red Book).
+ </td>
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://www.nascar.com/trackpass/about/raceview/"><img src="media/raceview.jpg" width="160" height="92" align="left" alt="RaceView"></img>
+ RaceView</a> from NASCAR / NEXTEL, part of the <a
+ href="http://www.nascar.com/trackpass/">TrackPass</a> package, puts
+ you in the race. Control the virtual camera angle, listen to the
+ driver and team, and see crucial statistics and times, all in real
+ time as the race goes on. RaceView uses JOGL for its 3D rendering.
+ </td>
+
+ <td width="50%">
+ </td>
+ </tr>
+
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th colspan="1">Discontinued projects</th>
+ </tr>
+ <tr>
+ <td >
+ <table border="0" cellspacing="15">
+ <tbody>
+ <tr>
+ <td width="50%">
+ <a href="http://www.specknet.org/dev/specksim"><img src="media/specksim.jpg" width="160" height="117" align="left" alt="SpeckSim"></img>
+ SpeckSim</a> is a
+ behaviour-level simulator for networks of small, resource-constrained
+ devices with sensing, computation and communication
+ capabilities. Intended as a testbed for distributed algorithms, the
+ main design goal was ease of extension. To this end, almost all aspect
+ of the simulator can be customised: Node behaviour, communication
+ characteristics, placement and motion; visualisation rendering and
+ interaction and statistic generation.
+ </td>
+ <td width="50%">
+ </td>
+ </tr>
+ <tr>
+ <td width="50%">
+ <a href="http://www.madlix.com"><img src="media/madlix.png" width="160"
+ height="160" align="left" alt="Madlix"></img>MADLIX</a> lets users insert
+ 3D-content in web pages, blogs, Google pages, community presentations
+ and more. MADLIX is JOGL-powered and runs smoothly inside all
+ Java-enabled browsers, with no need for custom plug-ins or application
+ installation. The <a href="http://www.madlix.com">on-line gallery</a>
+ features high-quality content ready for insertion. MADLIX is
+ accompanied by the MADLIX exporter tool enabling 3D artists to
+ directly export their 3D artwork from Autodesk Maya to the MADLIX
+ gallery. The exporter features pre-view functionality as well as a
+ standalone viewer, supporting the MADLIX file format and the open
+ standard file format COLLADA.
+
+ </td>
+ <td width="50%">
+ <a href="https://zg3d.dev.java.net/"><img src="media/zg3d.png" width="160" height="160" align="left" alt="ZG3D"></img>
+ ZG3D</a> is an open source project that uses
+ JOGL for visualizing 3D geometries with the emphasis of plotting
+ scientific data in a web application. Geometry objects in an XML file
+ or string can be dynamically loaded and removed. An HTML document may
+ call ZG3D functions through JavaScript and may define JavaScript
+ functions to receive messages from ZG3D, which makes it very easy and
+ flexible to embed interactive 3D web visualization. The software is
+ developed at the <a
+ href="http://www-cger.nies.go.jp/index.html">Center for Global
+ Environmental Research</a>, Japan, for the advanced data visualization
+ of the <a href="http://db.cger.nies.go.jp/g3db/ggtu/trajectory.html">Global Greenhouse Gases Database</a>.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="50%">
+ <a href="http://www.simulation.com/products/glstudio/glstudio.html"><img
+ src="media/glstudio.jpg" width="160" height="135" align="left" alt="GL Studio"></img>
+ GL Studio</a> is an object oriented rapid application
+ development tool that allows a user to graphically combine
+ photographs, 3D models and behavior logic to create advanced 2D and 3D
+ human machine interfaces. GL Studio generates Java or C++ source code
+ which can then be integrated into the user’s application as a user
+ interface. <a
+ href="http://www.simulation.com/products/glstudio/java/java.html">Java
+ code</a> generated with GL Studio can be deployed using
+ javax.swing.JPanel, java.awt.Canvas and JavaBeans. GL Studio uses
+ OpenGL for rendering and GL Studio for Java uses the JOGL API.
+
+ </td>
+
+ <td width="50%">
+ <a href="http://www.vlsolutions.com/">
+ <img src="media/vldocking.jpg" width="160" height="113" align="left" alt="VLDocking"></img>VLDocking</a> is
+ a set of Java components that helps the Swing developer to build
+ applications with Docking capabilities, and even raise existing
+ applications to higher standards. It supports docking via drag and
+ drop, enhanced toolbars, closable tabs, and more. It fully supports
+ heavyweight components such as JOGL's GLCanvas in a docking
+ environment.
+ </td>
+ </tr>
+
+ <!--- abandoned JOGL ..
+ <tr>
+ <td >
+ <a href="http://openendedgroup.com/field"><img src="media/field.png"
+ width="160" height="159" align="left" alt="Field"></img>Field</a> is an
+ open-source development environment for digital art and experimental
+ code writing. Built around the needs of programmers that manipulate
+ images, make animations and compose music, Field seeks to tie
+ text-based programming with ad hoc visual metaphors. Field uses Python
+ and other programming languages and wants to be integrated into your
+ own personal code-base. And it comes with special support for the <a
+ href="http://processing.org/">Processing</a> environment. Field uses
+ JOGL for its UI and its built-in drawing system; it provides a
+ JOGL-based scene-graph library for 3D visualization.
+ </td>
+ </tr>
+ <td width="50%">
+ <a href="http://www.eclipse.org/gef3d/"><img src="http://wiki.eclipse.org/images/thumb/b/be/Gef3d_sample_ecore3D.png/800px-Gef3d_sample_ecore3D.png" width="160" height="94" align="left" alt="GEF3d"></img>
+ GEF3D</a> is an Eclipse GEF extension bringing 3D to diagram editing.
+ That is with GEF3D you can create 3D diagrams, 2D diagrams and combine
+ 3D with 2D diagrams. GEF3D extends GEF by providing 3D enabled draw and
+ controller classes. Instead of drawing 2D figures, you can now draw 3D figures.
+ Existing GEF-based 2D editors can be embedded into 3D editors with minimal effort.
+ </td>
+ -->
+
+ </tbody>
+ </table>
+ </td>
+ </tr>
</tbody>
</table>
</div>
diff --git a/www/media/Java3d.png b/www/media/Java3d.png
new file mode 100644
index 000000000..ea7ea1bcd
--- /dev/null
+++ b/www/media/Java3d.png
Binary files differ
diff --git a/www/media/ardor3d.png b/www/media/ardor3d.png
new file mode 100644
index 000000000..9be447465
--- /dev/null
+++ b/www/media/ardor3d.png
Binary files differ
diff --git a/www/media/dyn4j.png b/www/media/dyn4j.png
new file mode 100644
index 000000000..3fd7bf65c
--- /dev/null
+++ b/www/media/dyn4j.png
Binary files differ
diff --git a/www/media/jmonkeyengine.png b/www/media/jmonkeyengine.png
new file mode 100644
index 000000000..a3e2a2a1f
--- /dev/null
+++ b/www/media/jmonkeyengine.png
Binary files differ
diff --git a/www/media/nifty-logo-new.png b/www/media/nifty-logo-new.png
new file mode 100644
index 000000000..c8390ceac
--- /dev/null
+++ b/www/media/nifty-logo-new.png
Binary files differ
diff --git a/www/media/ticket2ride_picture4.jpg b/www/media/ticket2ride_picture4.jpg
new file mode 100644
index 000000000..e7d573797
--- /dev/null
+++ b/www/media/ticket2ride_picture4.jpg
Binary files differ