diff options
55 files changed, 1538 insertions, 711 deletions
diff --git a/make/build-junit.xml b/make/build-junit.xml index 9b7f48987..75215b03d 100644 --- a/make/build-junit.xml +++ b/make/build-junit.xml @@ -24,7 +24,7 @@ <property name="java.dir.test" value="com/jogamp/test"/> <property name="java.part.test" value="${java.dir.test}/**"/> - <property name="batchtest.timeout" value="60000"/> + <property name="batchtest.timeout" value="120000"/> </target> diff --git a/make/scripts/java-run-all.sh b/make/scripts/java-run-all.sh index 0188ae5d2..f99a49617 100755 --- a/make/scripts/java-run-all.sh +++ b/make/scripts/java-run-all.sh @@ -44,7 +44,7 @@ uname -a | grep -i Darwin && MOSX=1 # D_ARGS="-Dnewt.debug=all -Dnativewindow.debug=all" # D_ARGS="-Djogl.debug=all -Dnewt.debug=all -Dnativewindow.debug=all" # D_ARGS="-Dnewt.debug=all" -# D_ARGS="-Dnewt.debug.Window" +D_ARGS="-Dnewt.debug.Window" # D_ARGS="-Dnewt.debug.Display" # D_ARGS="-Djogl.debug=all -Djogl.debug.DynamicLookup=true -Djogamp.debug.NativeLibrary=true" # D_ARGS="-Djogl.debug=all" diff --git a/make/scripts/java-win64-dbg.bat b/make/scripts/java-win64-dbg.bat index 5f200127d..a80ec9bdf 100644 --- a/make/scripts/java-win64-dbg.bat +++ b/make/scripts/java-win64-dbg.bat @@ -13,4 +13,10 @@ set CP_ALL=.;%BLD_DIR%\jogl\jogl.all.jar;%BLD_DIR%\nativewindow\nativewindow.all echo CP_ALL %CP_ALL%
-%J2RE_HOME%\bin\java -classpath %CP_ALL% "-Djava.library.path=%LIB_DIR%" "-Dnativewindow.debug=all" "-Djogl.debug=all" "-Dnewt.debug=all" "-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true" %1 %2 %3 %4 %5 %6 %7 %8 %9 > java-win64-dbg.log 2>&1
+REM set D_ARGS="-Djogamp.debug.JNILibLoader=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true" "-Djogl.debug.GLProfile=true"
+REM set D_ARGS="-Djogl.debug=all -Dnewt.debug=all -Dnativewindow.debug=all"
+set D_ARGS="-Dnewt.debug.Window"
+
+set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true"
+
+%J2RE_HOME%\bin\java -classpath %CP_ALL% "-Djava.library.path=%LIB_DIR%" %D_ARGS% %X_ARGS% %1 %2 %3 %4 %5 %6 %7 %8 %9 > java-win64-dbg.log 2>&1
diff --git a/make/scripts/java-win64.bat b/make/scripts/java-win64.bat index f0d068b0e..7ce87574d 100644 --- a/make/scripts/java-win64.bat +++ b/make/scripts/java-win64.bat @@ -10,7 +10,8 @@ set BLD_DIR=..\%BLD_SUB% set LIB_DIR=%BLD_DIR%\lib;..\..\gluegen\%BLD_SUB%\obj
set CP_ALL=.;%BLD_DIR%\jogl\jogl.all.jar;%BLD_DIR%\nativewindow\nativewindow.all.jar;%BLD_DIR%\newt\newt.all.jar;%BLD_DIR%\jogl\jogl.test.jar;..\..\gluegen\%BLD_SUB%\gluegen-rt.jar;..\..\gluegen\make\lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar
-
echo CP_ALL %CP_ALL%
-%J2RE_HOME%\bin\java -classpath %CP_ALL% "-Djava.library.path=%LIB_DIR%" "-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true" %1 %2 %3 %4 %5 %6 %7 %8 %9 > java-win64.log 2>&1
+set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true"
+
+%J2RE_HOME%\bin\java -classpath %CP_ALL% "-Djava.library.path=%LIB_DIR%" %X_ARGS% %1 %2 %3 %4 %5 %6 %7 %8 %9 > java-win64.log 2>&1
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java index 8fefe149e..1e954af1d 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java @@ -46,75 +46,123 @@ import javax.media.opengl.*; methods to be able to share it between GLCanvas and GLJPanel. */ public class GLDrawableHelper { - private volatile List listeners = new ArrayList(); private static final boolean DEBUG = Debug.debug("GLDrawableHelper"); private static final boolean VERBOSE = Debug.verbose(); - private static final boolean NVIDIA_CRASH_WORKAROUND = Debug.isPropertyDefined("jogl.nvidia.crash.workaround", true); + private Object listenersLock = new Object(); + private List listeners = new ArrayList(); + private Set listenersToBeInit = new HashSet(); private boolean autoSwapBufferMode = true; + private Object glRunnablesLock = new Object(); private ArrayList glRunnables = new ArrayList(); // one shot GL tasks + private Thread animatorThread = null; // default public GLDrawableHelper() { } - public synchronized String toString() { + public String toString() { StringBuffer sb = new StringBuffer(); - sb.append("GLEventListeners num "+listeners.size()+" ["); - for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { - sb.append(iter.next()+", "); + synchronized(listenersLock) { + sb.append("GLEventListeners num "+listeners.size()+" ["); + for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { + Object l = iter.next(); + sb.append(l); + sb.append("[init "); + sb.append( !listenersToBeInit.contains(l) ); + sb.append("], "); + } } sb.append("]"); return sb.toString(); } - public synchronized void addGLEventListener(GLEventListener listener) { + public void addGLEventListener(GLEventListener listener) { addGLEventListener(-1, listener); } - public synchronized void addGLEventListener(int index, GLEventListener listener) { - if(0>index) { - index = listeners.size(); + public void addGLEventListener(int index, GLEventListener listener) { + synchronized(listenersLock) { + if(0>index) { + index = listeners.size(); + } + listenersToBeInit.add(listener); + listeners.add(index, listener); } - List newListeners = (List) ((ArrayList) listeners).clone(); - newListeners.add(index, listener); - listeners = newListeners; } - public synchronized void removeGLEventListener(GLEventListener listener) { - List newListeners = (List) ((ArrayList) listeners).clone(); - newListeners.remove(listener); - listeners = newListeners; + public void removeGLEventListener(GLEventListener listener) { + synchronized(listenersLock) { + listeners.remove(listener); + listenersToBeInit.remove(listener); + } } - public synchronized void dispose(GLAutoDrawable drawable) { - for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { - ((GLEventListener) iter.next()).dispose(drawable); + public void dispose(GLAutoDrawable drawable) { + synchronized(listenersLock) { + for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { + GLEventListener listener = (GLEventListener) iter.next() ; + listener.dispose(drawable); + listenersToBeInit.add(listener); + } } } + private final boolean init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) { + if(listenersToBeInit.remove(l)) { + l.init(drawable); + if(sendReshape) { + reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */); + } + return true; + } + return false; + } + public void init(GLAutoDrawable drawable) { - for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { - ((GLEventListener) iter.next()).init(drawable); + synchronized(listenersLock) { + for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { + GLEventListener listener = (GLEventListener) iter.next() ; + if ( ! init( listener, drawable, false ) ) { + throw new GLException("GLEventListener "+listener+" already initialized: "+drawable); + } + } } } public void display(GLAutoDrawable drawable) { - for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { - ((GLEventListener) iter.next()).display(drawable); + synchronized(listenersLock) { + for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { + GLEventListener listener = (GLEventListener) iter.next() ; + // GLEventListener may need to be init, + // in case this one is added after the realization of the GLAutoDrawable + init( listener, drawable, true ) ; + listener.display(drawable); + } } execGLRunnables(drawable); } - public void reshape(GLAutoDrawable drawable, - int x, int y, int width, int height) { - for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { - ((GLEventListener) iter.next()).reshape(drawable, x, y, width, height); + private final void reshape(GLEventListener listener, GLAutoDrawable drawable, + int x, int y, int width, int height, boolean setViewport) { + if(setViewport) { + drawable.getGL().glViewport(x, y, width, height); + } + listener.reshape(drawable, x, y, width, height); + } + + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + synchronized(listenersLock) { + int i=0; + for (Iterator iter = listeners.iterator(); iter.hasNext(); i++) { + reshape((GLEventListener) iter.next(), drawable, x, y, width, height, 0==i); + } } } private void execGLRunnables(GLAutoDrawable drawable) { if(glRunnables.size()>0) { + // swap one-shot list asap ArrayList _glRunnables = null; - synchronized(glRunnables) { + synchronized(glRunnablesLock) { if(glRunnables.size()>0) { _glRunnables = glRunnables; glRunnables = new ArrayList(); @@ -128,23 +176,38 @@ public class GLDrawableHelper { } } - private void invokeLater(GLRunnable glRunnable) { - synchronized(glRunnables) { - glRunnables.add(glRunnable); - glRunnables.notifyAll(); + public void setAnimator(Thread animator) throws GLException { + synchronized(glRunnablesLock) { + if(animator!=animatorThread && null!=animator && null!=animatorThread) { + throw new GLException("Trying to register animator thread "+animator+", where "+animatorThread+" is already registered. Unregister first."); + } + animatorThread = animator; + } + } + + public Thread getAnimator() { + synchronized(glRunnablesLock) { + return animatorThread; } } - public void invoke(boolean wait, GLRunnable glRunnable) { - if(glRunnable == null) { + public void invoke(GLAutoDrawable drawable, boolean wait, GLRunnable glRunnable) { + if( null == drawable || null == glRunnable ) { return; } - Object lock = new Object(); - GLRunnableTask rTask = new GLRunnableTask(glRunnable, wait?lock:null/*, true*/); Throwable throwable = null; + Object lock = new Object(); + GLRunnableTask rTask = null; synchronized(lock) { - invokeLater(rTask); - if( wait ) { + boolean callDisplay; + synchronized(glRunnablesLock) { + callDisplay = null == animatorThread || animatorThread == Thread.currentThread() ; + rTask = new GLRunnableTask(glRunnable, ( !callDisplay && wait ) ? lock : null); + glRunnables.add(rTask); + } + if( callDisplay ) { + drawable.display(); + } else if( wait ) { try { lock.wait(); } catch (InterruptedException ie) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java index 071ac1378..c2efb3f4e 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java @@ -138,8 +138,16 @@ public class GLPbufferImpl implements GLPbuffer { drawableHelper.removeGLEventListener(listener); } + public void setAnimator(Thread animator) { + drawableHelper.setAnimator(animator); + } + + public Thread getAnimator() { + return drawableHelper.getAnimator(); + } + public void invoke(boolean wait, GLRunnable glRunnable) { - drawableHelper.invoke(wait, glRunnable); + drawableHelper.invoke(this, wait, glRunnable); } public void setContext(GLContext ctx) { diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java index 15b9d5eb9..66d3d5b88 100755 --- a/src/jogl/classes/com/jogamp/opengl/util/Animator.java +++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java @@ -218,6 +218,9 @@ public class Animator { } else { thread = new Thread(threadGroup, runnable); } + for(Iterator iter = drawables.iterator(); iter.hasNext(); ) { + ((GLAutoDrawable) iter.next()).setAnimator(thread); + } thread.start(); } @@ -241,15 +244,16 @@ public class Animator { // dependencies on the Animator's internal thread. Currently we // use a couple of heuristics to determine whether we should do // the blocking wait(). - if (impl.skipWaitForStop(thread)) { - return; - } - - while (shouldStop && thread != null) { - try { - wait(); - } catch (InterruptedException ie) { + if (!impl.skipWaitForStop(thread)) { + while (shouldStop && thread != null) { + try { + wait(); + } catch (InterruptedException ie) { + } } } + for(Iterator iter = drawables.iterator(); iter.hasNext(); ) { + ((GLAutoDrawable) iter.next()).setAnimator(null); + } } } diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java index 7236aa533..1b5c56c95 100644 --- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java +++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java @@ -161,14 +161,49 @@ public interface GLAutoDrawable extends GLDrawable { during this update cycle. */ public void removeGLEventListener(GLEventListener listener); + /** + * <p> + * Indicates whether a running animator thread is periodically issuing {@link #display()} calls or not.</p><br> + * <p> + * This method shall be called by an animator implementation only,<br> + * e.g. {@link com.jogamp.opengl.util.Animator#start()}, passing the animator thread,<br> + * and {@link com.jogamp.opengl.util.Animator#start()}, passing <code>null</code>.</p><br> + * <p> + * Impacts {@link #display()} and {@link #invoke(boolean, GLRunnable)} semantics.</p><br> + * + * @param animator <code>null</code> reference indicates no running animator thread + * issues {@link #display()} calls on this <code>GLAutoDrawable</code>,<br> + * a valid reference indicates a running animator thread + * periodically issuing {@link #display()} calls. + * + * @throws GLException if a running animator thread is already registered and you try to register a different one without unregistering the previous one. + * @see #display() + * @see #invoke(boolean, GLRunnable) + */ + public void setAnimator(Thread animator) throws GLException; + + /** + * @return the value of the registered animator thread + * + * @see #setAnimator(Thread) + */ + public Thread getAnimator(); + /** - * Enqueues the one-shot {@link javax.media.opengl.GLRunnable} into the queue, - * which will be executed at the next {@link #display()} call. * <p> - * Warning: We cannot verify if the caller runs in the same thread - * as the display caller, hence we cannot avoid a deadlock - * in such case. You have to know what you are doing, - * ie call this only in a I/O event listener, or such.<br></p> + * Enqueues a one-shot {@link javax.media.opengl.GLRunnable}, + * which will be executed with the next {@link #display()} call.</p><br> + * <p> + * If {@link #setAnimator(Thread)} has not registered no running animator thread, the default,<br> + * or if the current thread is the animator thread,<br> + * a {@link #display()} call has to be issued after enqueueing the <code>GLRunnable</code>.<br> + * No extra synchronization must be performed in case <code>wait</code> is true, since it is executed in the current thread.</p><br> + * <p> + * If {@link #setAnimator(Thread)} has registered a valid animator thread,<br> + * no call of {@link #display()} must be issued, since the animator thread performs it.<br> + * If <code>wait</code> is true, the implementation must wait until the <code>GLRunnable</code> is excecuted.</p><br> + * + * @see #setAnimator(Thread) * @see #display() * @see javax.media.opengl.GLRunnable */ @@ -190,28 +225,37 @@ public interface GLAutoDrawable extends GLDrawable { routine may be called manually. */ public void destroy(); - /** <p>Causes OpenGL rendering to be performed for this GLAutoDrawable - in the following order: - <ul> - <li> Calling {@link GLEventListener#display display(..)} for all - registered {@link GLEventListener}s. </li> - <li> Execute and dismiss all one-shot {@link javax.media.opengl.GLRunnable}, - enqueued via {@link #invoke(boolean, GLRunnable)}.</li> - </ul></p> - <p> - Called automatically by the - window system toolkit upon receiving a repaint() request.</p> - <p> - This routine may be called manually for better control over the - rendering process. It is legal to call another GLAutoDrawable's - display method from within the {@link GLEventListener#display - display(..)} callback.</p> - <p> - In case of a new generated OpenGL context, - the implementation shall call {@link GLEventListener#init init(..)} for all - registered {@link GLEventListener}s <i>before</i> making the - actual {@link GLEventListener#display display(..)} calls, - in case this has not been done yet.</p> */ + /** + * <p> + * Causes OpenGL rendering to be performed for this GLAutoDrawable + * in the following order: + * <ul> + * <li> Calling {@link GLEventListener#display display(..)} for all + * registered {@link GLEventListener}s. </li> + * <li> Executes all one-shot {@link javax.media.opengl.GLRunnable}, + * enqueued via {@link #invoke(boolean, GLRunnable)}.</li> + * </ul></p> + * <p> + * Called automatically by the + * window system toolkit upon receiving a repaint() request, + * except a running animator thread is registered with {@link #setAnimator(Thread)}.</p> <br> + * <p> + * Maybe called periodically by a running animator thread,<br> + * which must register itself with {@link #setAnimator(Thread)}.</p> <br> + * <p> + * This routine may be called manually for better control over the + * rendering process. It is legal to call another GLAutoDrawable's + * display method from within the {@link GLEventListener#display + * display(..)} callback.</p> + * <p> + * In case of a new generated OpenGL context, + * the implementation shall call {@link GLEventListener#init init(..)} for all + * registered {@link GLEventListener}s <i>before</i> making the + * actual {@link GLEventListener#display display(..)} calls, + * in case this has not been done yet.</p> + * + * @see #setAnimator(Thread) + */ public void display(); /** Enables or disables automatic buffer swapping for this drawable. diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 2dafd691a..f150b2507 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -378,7 +378,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { return; } - display(); + if( null == getAnimator() ) { + display(); + } } /** Overridden to track when this component is added to a container. @@ -492,8 +494,16 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { drawableHelper.removeGLEventListener(listener); } + public void setAnimator(Thread animator) { + drawableHelper.setAnimator(animator); + } + + public Thread getAnimator() { + return drawableHelper.getAnimator(); + } + public void invoke(boolean wait, GLRunnable glRunnable) { - drawableHelper.invoke(wait, glRunnable); + drawableHelper.invoke(this, wait, glRunnable); } public void setContext(GLContext ctx) { @@ -640,10 +650,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { if (sendReshape) { // Note: we ignore the given x and y within the parent component // since we are drawing directly into this heavyweight component. - int width = getWidth(); - int height = getHeight(); - getGL().glViewport(0, 0, width, height); - drawableHelper.reshape(GLCanvas.this, 0, 0, width, height); + drawableHelper.reshape(GLCanvas.this, 0, 0, getWidth(), getHeight()); sendReshape = false; } diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 73962e979..d0d97fe31 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -380,8 +380,16 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { drawableHelper.removeGLEventListener(listener); } + public void setAnimator(Thread animator) { + drawableHelper.setAnimator(animator); + } + + public Thread getAnimator() { + return drawableHelper.getAnimator(); + } + public void invoke(boolean wait, GLRunnable glRunnable) { - drawableHelper.invoke(wait, glRunnable); + drawableHelper.invoke(this, wait, glRunnable); } public GLContext createContext(GLContext shareWith) { @@ -585,9 +593,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { } if (sendReshape) { if (DEBUG||VERBOSE) { - System.err.println("display: glViewport(" + viewportX + "," + viewportY + " " + panelWidth + "x" + panelHeight + ")"); + System.err.println("display: reshape(" + viewportX + "," + viewportY + " " + panelWidth + "x" + panelHeight + ")"); } - getGL().getGL2().glViewport(viewportX, viewportY, panelWidth, panelHeight); drawableHelper.reshape(GLJPanel.this, viewportX, viewportY, panelWidth, panelHeight); sendReshape = false; } diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java b/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java index 1652acd82..f10218509 100755 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java +++ b/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java @@ -48,6 +48,10 @@ import org.junit.After; import org.junit.Test; public class TestAWT01GLn { + static { + GLProfile.initSingleton(); + } + Frame frame=null; GLCanvas glCanvas=null; diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java b/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java index ed8a5dd0f..6144a6308 100755 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java +++ b/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java @@ -56,6 +56,10 @@ import static javax.swing.SwingUtilities.*; * @author Michael Bien */ public class TestSwingAWT01GLn { + static { + GLProfile.initSingleton(); + } + private Window[] windows; diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/es1/RedSquare.java b/src/junit/com/jogamp/test/junit/jogl/demos/es1/RedSquare.java index 9b8982ed4..be416f01d 100755 --- a/src/junit/com/jogamp/test/junit/jogl/demos/es1/RedSquare.java +++ b/src/junit/com/jogamp/test/junit/jogl/demos/es1/RedSquare.java @@ -44,6 +44,7 @@ public class RedSquare implements GLEventListener { private FloatBuffer vertices; public void init(GLAutoDrawable drawable) { + System.out.println("RedSquare: Init"); GL _gl = drawable.getGL(); if(glDebugEmu) { @@ -119,6 +120,7 @@ public class RedSquare implements GLEventListener { } public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + System.out.println("RedSquare: Reshape"); GL2ES1 gl = drawable.getGL().getGL2ES1(); // Set location in front of camera gl.glMatrixMode(gl.GL_PROJECTION); @@ -147,6 +149,7 @@ public class RedSquare implements GLEventListener { } public void dispose(GLAutoDrawable drawable) { + System.out.println("RedSquare: Dispose"); GL2ES1 gl = drawable.getGL().getGL2ES1(); if(debug) { System.out.println(Thread.currentThread()+" RedSquare.dispose: "+gl.getContext()); @@ -163,8 +166,4 @@ public class RedSquare implements GLEventListener { System.out.println(Thread.currentThread()+" RedSquare.dispose: FIN"); } } - - public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { - } - } diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java index 1fa49be8c..ef5cf134a 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java +++ b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java @@ -25,6 +25,7 @@ public class Gears implements GLEventListener { private boolean mouseRButtonDown = false; public void init(GLAutoDrawable drawable) { + System.out.println("Gears: Init"); // Use debug pipeline // drawable.setGL(new DebugGL(drawable.getGL())); @@ -77,6 +78,7 @@ public class Gears implements GLEventListener { } public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + System.out.println("Gears: Reshape"); GL2 gl = drawable.getGL().getGL2(); float h = (float)height / (float)width; @@ -91,6 +93,7 @@ public class Gears implements GLEventListener { } public void dispose(GLAutoDrawable drawable) { + System.out.println("Gears: Dispose"); } public void display(GLAutoDrawable drawable) { @@ -144,8 +147,6 @@ public class Gears implements GLEventListener { gl.glPopMatrix(); } - public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - public static void gear(GL2 gl, float inner_radius, float outer_radius, diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java index 2df3f0de9..b191dbbaf 100755 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java @@ -51,6 +51,10 @@ import org.junit.After; import org.junit.Test; public class TestGearsAWT { + static { + GLProfile.initSingleton(); + } + static GLProfile glp; static int width, height; diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNEWT.java b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNEWT.java index e50ffbde9..bafa8a1fb 100755 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNEWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNEWT.java @@ -48,6 +48,10 @@ import org.junit.After; import org.junit.Test; public class TestGearsNEWT { + static { + GLProfile.initSingleton(); + } + static GLProfile glp; static int width, height; diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNewtAWTWrapper.java b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNewtAWTWrapper.java index 51977d6d3..316c9edb4 100755 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNewtAWTWrapper.java +++ b/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsNewtAWTWrapper.java @@ -49,6 +49,10 @@ import org.junit.After; import org.junit.Test; public class TestGearsNewtAWTWrapper { + static { + GLProfile.initSingleton(); + } + static GLProfile glp; static int width, height; diff --git a/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java b/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java index cd0c7c0e0..8a9c960c1 100755 --- a/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java @@ -45,6 +45,10 @@ import com.jogamp.newt.*; import java.io.IOException; public class TestDrawable01NEWT { + static { + GLProfile.initSingleton(); + } + static GLProfile glp; static GLDrawableFactory factory; static int width, height; diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java b/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java index bae727019..ad198fca8 100755 --- a/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java @@ -57,6 +57,10 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import java.io.IOException; public class TestOffscreen01NEWT { + static { + GLProfile.initSingleton(); + } + static GLProfile glpDefault; static GLDrawableFactory glDrawableFactory; static int width, height; diff --git a/src/junit/com/jogamp/test/junit/jogl/texture/TestTexture01AWT.java b/src/junit/com/jogamp/test/junit/jogl/texture/TestTexture01AWT.java index 7fdbd59c8..b34023bee 100755 --- a/src/junit/com/jogamp/test/junit/jogl/texture/TestTexture01AWT.java +++ b/src/junit/com/jogamp/test/junit/jogl/texture/TestTexture01AWT.java @@ -56,6 +56,10 @@ import org.junit.BeforeClass; import org.junit.Test; public class TestTexture01AWT { + static { + GLProfile.initSingleton(); + } + static GLProfile glp; static GLCapabilities caps; BufferedImage textureImage; diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java index 4fd7744db..3a36a1132 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java @@ -47,8 +47,8 @@ import org.junit.Test; import javax.media.nativewindow.*; import javax.media.opengl.*; -import com.jogamp.opengl.util.Animator; import com.jogamp.newt.*; +import com.jogamp.newt.event.*; import com.jogamp.newt.opengl.*; import java.io.IOException; @@ -56,9 +56,13 @@ import com.jogamp.test.junit.util.MiscUtils; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestGLWindows01NEWT { + static { + GLProfile.initSingleton(); + } + static GLProfile glp; static int width, height; - static long duration = 100; // ms + static long durationPerTest = 100; // ms @BeforeClass public static void initClass() { @@ -67,7 +71,11 @@ public class TestGLWindows01NEWT { glp = GLProfile.getDefault(); } - static GLWindow createWindow(Screen screen, GLCapabilities caps, int width, int height, boolean onscreen, boolean undecorated) { + static GLWindow createWindow(Screen screen, GLCapabilities caps, + int width, int height, boolean onscreen, boolean undecorated, + boolean addGLEventListenerAfterVisible) + throws InterruptedException + { Assert.assertNotNull(caps); caps.setOnscreen(onscreen); // System.out.println("Requested: "+caps); @@ -84,12 +92,23 @@ public class TestGLWindows01NEWT { glWindow = GLWindow.create(caps, onscreen && undecorated); } Assert.assertNotNull(glWindow); + Assert.assertEquals(false,glWindow.isVisible()); Assert.assertEquals(false,glWindow.isNativeWindowValid()); + + GLEventListener demo = new Gears(); + setDemoFields(demo, glWindow); + if(!addGLEventListenerAfterVisible) { + glWindow.addGLEventListener(demo); + } + glWindow.addWindowListener(new TraceWindowAdapter()); + glWindow.setSize(width, height); - Assert.assertEquals(false,glWindow.isVisible()); + glWindow.setVisible(true); Assert.assertEquals(true,glWindow.isVisible()); Assert.assertEquals(true,glWindow.isNativeWindowValid()); + while(glWindow.getTotalFrames()<1) { Thread.sleep(100); } + Assert.assertEquals(1,glWindow.getTotalFrames()); // native expose .. // Assert.assertEquals(width,glWindow.getWidth()); // Assert.assertEquals(height,glWindow.getHeight()); // System.out.println("Created: "+glWindow); @@ -105,9 +124,10 @@ public class TestGLWindows01NEWT { Assert.assertTrue(caps.getRedBits()>5); Assert.assertEquals(caps.isOnscreen(),onscreen); - GLEventListener demo = new Gears(); - setDemoFields(demo, glWindow); - glWindow.addGLEventListener(demo); + if(addGLEventListenerAfterVisible) { + glWindow.addGLEventListener(demo); + glWindow.display(); + } return glWindow; } @@ -115,17 +135,21 @@ public class TestGLWindows01NEWT { static void destroyWindow(GLWindow glWindow, boolean deep) { if(null!=glWindow) { glWindow.destroy(deep); + Assert.assertEquals(false,glWindow.isNativeWindowValid()); } } @Test - public void testWindowNativeRecreate01Simple() throws InterruptedException { + public void testWindowNativeRecreate01aSimple() throws InterruptedException { GLCapabilities caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - GLWindow window = createWindow(null, caps, width, height, true /* onscreen */, false /* undecorated */); + GLWindow window = createWindow(null, caps, width, height, + true /* onscreen */, false /* undecorated */, + false /*addGLEventListenerAfterVisible*/); - window.display(); - window.destroy(); + Assert.assertEquals(true,window.isNativeWindowValid()); + Assert.assertEquals(true,window.isVisible()); + window.destroy(false); Assert.assertEquals(false,window.isNativeWindowValid()); Assert.assertEquals(false,window.isVisible()); @@ -136,28 +160,70 @@ public class TestGLWindows01NEWT { window.setVisible(true); Assert.assertEquals(true,window.isNativeWindowValid()); Assert.assertEquals(true,window.isVisible()); + + window.setVisible(false); + Assert.assertEquals(true,window.isNativeWindowValid()); + Assert.assertEquals(false,window.isVisible()); + + destroyWindow(window, true); + } + + @Test + public void testWindowNativeRecreate01bSimple() throws InterruptedException { + GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + GLWindow window = createWindow(null, caps, width, height, + true /* onscreen */, false /* undecorated */, + true /*addGLEventListenerAfterVisible*/); + + Assert.assertEquals(true,window.isNativeWindowValid()); + Assert.assertEquals(true,window.isVisible()); + window.destroy(false); + Assert.assertEquals(false,window.isNativeWindowValid()); + Assert.assertEquals(false,window.isVisible()); + window.display(); + Assert.assertEquals(false,window.isNativeWindowValid()); + Assert.assertEquals(false,window.isVisible()); + + window.setVisible(true); + Assert.assertEquals(true,window.isNativeWindowValid()); + Assert.assertEquals(true,window.isVisible()); - Animator animator = new Animator(window); - animator.start(); - while(animator.isAnimating() && animator.getDuration()<duration) { + window.setVisible(false); + Assert.assertEquals(true,window.isNativeWindowValid()); + Assert.assertEquals(false,window.isVisible()); + + destroyWindow(window, true); + } + + @Test + public void testWindowDecor01aSimple() throws InterruptedException { + GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + GLWindow window = createWindow(null, caps, width, height, + true /* onscreen */, false /* undecorated */, + false /*addGLEventListenerAfterVisible*/); + System.out.println("Created: "+window); + while(window.getDuration()<durationPerTest) { Thread.sleep(100); } - animator.stop(); + System.out.println("duration: "+window.getDuration()); destroyWindow(window, true); } @Test - public void testWindowDecor01Simple() throws InterruptedException { + public void testWindowDecor01bSimple() throws InterruptedException { GLCapabilities caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - GLWindow window = createWindow(null, caps, width, height, true /* onscreen */, false /* undecorated */); - Animator animator = new Animator(window); - animator.start(); - while(animator.isAnimating() && animator.getDuration()<duration) { + GLWindow window = createWindow(null, caps, width, height, + true /* onscreen */, false /* undecorated */, + true /*addGLEventListenerAfterVisible*/); + System.out.println("Created: "+window); + while(window.getDuration()<durationPerTest) { Thread.sleep(100); } - animator.stop(); + System.out.println("duration: "+window.getDuration()); destroyWindow(window, true); } @@ -165,13 +231,13 @@ public class TestGLWindows01NEWT { public void testWindowDecor02DestroyWinTwiceA() throws InterruptedException { GLCapabilities caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - GLWindow window = createWindow(null, caps, width, height, true /* onscreen */, false /* undecorated */); - Animator animator = new Animator(window); - animator.start(); - while(animator.isAnimating() && animator.getDuration()<duration) { + GLWindow window = createWindow(null, caps, width, height, + true /* onscreen */, false /* undecorated */, + false /*addGLEventListenerAfterVisible*/); + while(window.getDuration()<durationPerTest) { Thread.sleep(100); } - animator.stop(); + System.out.println("duration: "+window.getDuration()); destroyWindow(window, false); destroyWindow(window, true); } @@ -189,28 +255,26 @@ public class TestGLWindows01NEWT { Screen screen1 = NewtFactory.createScreen(display1, 0); // screen 0 Assert.assertNotNull(screen1); - GLWindow window1 = createWindow(screen1, caps, width, height, true /* onscreen */, false /* undecorated */); + GLWindow window1 = createWindow(screen1, caps, width, height, + true /* onscreen */, false /* undecorated */, + false /*addGLEventListenerAfterVisible*/); Assert.assertNotNull(window1); Screen screen2 = NewtFactory.createScreen(display2, 0); // screen 0 Assert.assertNotNull(screen2); - GLWindow window2 = createWindow(screen2, caps, width, height, true /* onscreen */, false /* undecorated */); + GLWindow window2 = createWindow(screen2, caps, width, height, + true /* onscreen */, false /* undecorated */, + false /*addGLEventListenerAfterVisible*/); Assert.assertNotNull(window2); - Animator animator1 = new Animator(window1); - animator1.start(); - Animator animator2 = new Animator(window2); - animator2.start(); - while(animator1.isAnimating() && animator1.getDuration()<duration) { + while(window1.getDuration()<durationPerTest) { Thread.sleep(100); } + System.out.println("duration1: "+window1.getDuration()); + System.out.println("duration2: "+window2.getDuration()); - animator2.stop(); - Assert.assertEquals(false, animator2.isAnimating()); destroyWindow(window2, true); - animator1.stop(); - Assert.assertEquals(false, animator1.isAnimating()); destroyWindow(window1, true); } @@ -222,7 +286,21 @@ public class TestGLWindows01NEWT { } } + static int atoi(String a) { + int i=0; + try { + i = Integer.parseInt(a); + } catch (Exception ex) { ex.printStackTrace(); } + return i; + } + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + durationPerTest = atoi(args[++i]); + } + } + System.out.println("durationPerTest: "+durationPerTest); String tstname = TestGLWindows01NEWT.class.getName(); org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { tstname, diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java b/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java new file mode 100755 index 000000000..0677bc82c --- /dev/null +++ b/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2010 Sven Gothel. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Sven Gothel or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.jogamp.test.junit.newt; + +import java.lang.reflect.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Test; + +import javax.media.nativewindow.*; +import javax.media.opengl.*; + +import com.jogamp.opengl.util.Animator; +import com.jogamp.newt.*; +import com.jogamp.newt.event.*; +import com.jogamp.newt.opengl.*; +import java.io.IOException; + +import com.jogamp.test.junit.util.MiscUtils; +import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; + +public class TestGLWindows02NEWTAnimated { + static { + GLProfile.initSingleton(); + } + + static GLProfile glp; + static int width, height; + static long durationPerTest = 100; // ms + + @BeforeClass + public static void initClass() { + width = 640; + height = 480; + glp = GLProfile.getDefault(); + } + + static GLWindow createWindow(Screen screen, GLCapabilities caps, int width, int height, boolean onscreen, boolean undecorated) { + Assert.assertNotNull(caps); + caps.setOnscreen(onscreen); + // System.out.println("Requested: "+caps); + + // + // Create native windowing resources .. X11/Win/OSX + // + GLWindow glWindow; + if(null!=screen) { + Window window = NewtFactory.createWindow(screen, caps, onscreen && undecorated); + Assert.assertNotNull(window); + glWindow = GLWindow.create(window); + } else { + glWindow = GLWindow.create(caps, onscreen && undecorated); + } + Assert.assertNotNull(glWindow); + GLEventListener demo = new Gears(); + setDemoFields(demo, glWindow); + glWindow.addGLEventListener(demo); + glWindow.addWindowListener(new TraceWindowAdapter()); + Assert.assertEquals(false,glWindow.isNativeWindowValid()); + + glWindow.setSize(width, height); + Assert.assertEquals(false,glWindow.isVisible()); + glWindow.setVisible(true); + Assert.assertEquals(true,glWindow.isVisible()); + Assert.assertEquals(true,glWindow.isNativeWindowValid()); + // Assert.assertEquals(width,glWindow.getWidth()); + // Assert.assertEquals(height,glWindow.getHeight()); + // System.out.println("Created: "+glWindow); + + // + // Create native OpenGL resources .. XGL/WGL/CGL .. + // equivalent to GLAutoDrawable methods: setVisible(true) + // + caps = (GLCapabilities) glWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); + Assert.assertNotNull(caps); + Assert.assertTrue(caps.getGreenBits()>5); + Assert.assertTrue(caps.getBlueBits()>5); + Assert.assertTrue(caps.getRedBits()>5); + Assert.assertEquals(caps.isOnscreen(),onscreen); + + return glWindow; + } + + static void destroyWindow(GLWindow glWindow, boolean deep) { + if(null!=glWindow) { + glWindow.destroy(deep); + } + } + + @Test + public void testWindowDecor01Simple() throws InterruptedException { + GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + GLWindow window = createWindow(null, caps, width, height, true /* onscreen */, false /* undecorated */); + Animator animator = new Animator(window); + animator.start(); + while(animator.isAnimating() && animator.getDuration()<durationPerTest) { + Thread.sleep(100); + } + animator.stop(); + destroyWindow(window, true); + } + + @Test + public void testWindowDecor02DestroyWinTwiceA() throws InterruptedException { + GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + GLWindow window = createWindow(null, caps, width, height, true /* onscreen */, false /* undecorated */); + Animator animator = new Animator(window); + animator.start(); + while(animator.isAnimating() && animator.getDuration()<durationPerTest) { + Thread.sleep(100); + } + animator.stop(); + destroyWindow(window, false); + destroyWindow(window, true); + } + + @Test + public void testWindowDecor03TwoWin() throws InterruptedException { + GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + + Display display1 = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display1); + Display display2 = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display2); + Assert.assertEquals(display1, display2); // must be equal: same thread - same display + + Screen screen1 = NewtFactory.createScreen(display1, 0); // screen 0 + Assert.assertNotNull(screen1); + GLWindow window1 = createWindow(screen1, caps, width, height, true /* onscreen */, false /* undecorated */); + Assert.assertNotNull(window1); + + Screen screen2 = NewtFactory.createScreen(display2, 0); // screen 0 + Assert.assertNotNull(screen2); + GLWindow window2 = createWindow(screen2, caps, width-10, height-10, true /* onscreen */, false /* undecorated */); + Assert.assertNotNull(window2); + + Animator animator1 = new Animator(window1); + animator1.start(); + Animator animator2 = new Animator(window2); + animator2.start(); + while(animator1.isAnimating() && animator1.getDuration()<durationPerTest) { + Thread.sleep(100); + } + + animator2.stop(); + Assert.assertEquals(false, animator2.isAnimating()); + destroyWindow(window2, false); + + animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); + destroyWindow(window1, true); + } + + public static void setDemoFields(GLEventListener demo, GLWindow glWindow) { + Assert.assertNotNull(demo); + Assert.assertNotNull(glWindow); + if(!MiscUtils.setFieldIfExists(demo, "window", glWindow.getInnerWindow())) { + MiscUtils.setFieldIfExists(demo, "glWindow", glWindow); + } + } + + static int atoi(String a) { + int i=0; + try { + i = Integer.parseInt(a); + } catch (Exception ex) { ex.printStackTrace(); } + return i; + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + durationPerTest = atoi(args[++i]); + } + } + String tstname = TestGLWindows02NEWTAnimated.class.getName(); + org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { + tstname, + "filtertrace=true", + "haltOnError=false", + "haltOnFailure=false", + "showoutput=true", + "outputtoformatters=true", + "logfailedtests=true", + "logtestlistenerevents=true", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); + } + +} diff --git a/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java b/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java index 495b8bb3e..5a67bbc15 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java @@ -65,9 +65,12 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestListenerCom01AWT { + static { + GLProfile.initSingleton(); + } + static int width, height; static long durationPerTest = 500; - static long waitReparent = 300; static boolean verbose = false; @BeforeClass @@ -152,8 +155,6 @@ public class TestListenerCom01AWT { for(int i=0; i<args.length; i++) { if(args[i].equals("-time")) { durationPerTest = atoi(args[++i]); - } else if(args[i].equals("-wait")) { - waitReparent = atoi(args[++i]); } } String tstname = TestListenerCom01AWT.class.getName(); diff --git a/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java index 58ea235df..89d9c1ca2 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java @@ -120,6 +120,7 @@ public class TestWindows01NEWT { window.setVisible(true); Assert.assertEquals(true,window.isNativeWindowValid()); + Assert.assertEquals(true,window.isVisible()); Thread.sleep(100); // 100 ms destroyWindow(display, screen, window); diff --git a/src/junit/com/jogamp/test/junit/newt/GLRunnableDummy.java b/src/junit/com/jogamp/test/junit/newt/parenting/GLRunnableDummy.java index 990a0c37d..53dd960f8 100644 --- a/src/junit/com/jogamp/test/junit/newt/GLRunnableDummy.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/GLRunnableDummy.java @@ -30,7 +30,7 @@ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -package com.jogamp.test.junit.newt; +package com.jogamp.test.junit.newt.parenting; import org.junit.Assert; import org.junit.Before; @@ -47,7 +47,7 @@ public class GLRunnableDummy implements GLRunnable { float d=0.001f; public void run(GLAutoDrawable drawable) { - // nop .. + System.out.println("Red: "+r); GL2ES1 gl = drawable.getGL().getGL2ES1(); gl.glClearColor(r, g, b, 1f); r+=d; diff --git a/src/junit/com/jogamp/test/junit/newt/KeyAction.java b/src/junit/com/jogamp/test/junit/newt/parenting/KeyAction.java index 3ca12a840..c9e1db074 100644 --- a/src/junit/com/jogamp/test/junit/newt/KeyAction.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/KeyAction.java @@ -31,7 +31,7 @@ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -package com.jogamp.test.junit.newt; +package com.jogamp.test.junit.newt.parenting; import com.jogamp.newt.event.*; diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01NEWT.java index b1d57e793..421f74aa4 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01NEWT.java @@ -30,7 +30,7 @@ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -package com.jogamp.test.junit.newt; +package com.jogamp.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -60,6 +60,10 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01NEWT { + static { + GLProfile.initSingleton(); + } + static int width, height; static long durationPerTest = 500; static long waitReparent = 0; diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting01aAWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01aAWT.java index d88e7157a..28b95884d 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting01aAWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01aAWT.java @@ -30,7 +30,7 @@ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -package com.jogamp.test.junit.newt; +package com.jogamp.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -47,6 +47,7 @@ import org.junit.Test; import java.awt.Button; import java.awt.BorderLayout; import java.awt.Canvas; +import java.awt.Container; import java.awt.Frame; import java.awt.Dimension; @@ -66,6 +67,10 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01aAWT { + static { + GLProfile.initSingleton(); + } + static int width, height; static long durationPerTest = 800; static long waitReparent = 0; @@ -101,13 +106,26 @@ public class TestParenting01aAWT { Assert.assertEquals(false, glWindow1.isNativeWindowValid()); Assert.assertNull(glWindow1.getParentNativeWindow()); - Frame frame = new Frame("AWT Parent Frame"); - Assert.assertNotNull(frame); - frame.add(newtCanvasAWT); - frame.setSize(width, height); + Frame frame1 = new Frame("AWT Parent Frame"); + frame1.setLayout(new BorderLayout()); + frame1.add(new Button("North"), BorderLayout.NORTH); + frame1.add(new Button("South"), BorderLayout.SOUTH); + frame1.add(new Button("East"), BorderLayout.EAST); + frame1.add(new Button("West"), BorderLayout.WEST); + + Container container1 = new Container(); + container1.setLayout(new BorderLayout()); + container1.add(new Button("north"), BorderLayout.NORTH); + container1.add(new Button("south"), BorderLayout.SOUTH); + container1.add(new Button("east"), BorderLayout.EAST); + container1.add(new Button("west"), BorderLayout.WEST); + container1.add(newtCanvasAWT, BorderLayout.CENTER); + + frame1.add(container1, BorderLayout.CENTER); + frame1.setSize(width, height); // visible test - frame.setVisible(true); + frame1.setVisible(true); Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); Animator animator1 = new Animator(glWindow1); @@ -118,17 +136,17 @@ public class TestParenting01aAWT { animator1.stop(); Assert.assertEquals(false, animator1.isAnimating()); - frame.setVisible(false); + frame1.setVisible(false); Assert.assertEquals(false, glWindow1.isDestroyed()); - frame.setVisible(true); + frame1.setVisible(true); Assert.assertEquals(false, glWindow1.isDestroyed()); - frame.remove(newtCanvasAWT); + frame1.remove(newtCanvasAWT); // Assert.assertNull(glWindow1.getParentNativeWindow()); Assert.assertEquals(false, glWindow1.isDestroyed()); - frame.dispose(); + frame1.dispose(); Assert.assertEquals(false, glWindow1.isDestroyed()); glWindow1.destroy(true); diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting01bAWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01bAWT.java index 227744296..f95ad1c14 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting01bAWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01bAWT.java @@ -30,7 +30,7 @@ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -package com.jogamp.test.junit.newt; +package com.jogamp.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -66,6 +66,10 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01bAWT { + static { + GLProfile.initSingleton(); + } + static int width, height; static long durationPerTest = 800; static long waitReparent = 0; diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting01cAWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cAWT.java index 7559390fa..0233a6aad 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting01cAWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cAWT.java @@ -30,7 +30,7 @@ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -package com.jogamp.test.junit.newt; +package com.jogamp.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -67,6 +67,10 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01cAWT { + static { + GLProfile.initSingleton(); + } + static int width, height; static long durationPerTest = 800; static long waitReparent = 0; @@ -124,13 +128,9 @@ public class TestParenting01cAWT { frame1.setVisible(true); Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); - Animator animator1 = new Animator(glWindow1); - animator1.start(); - while(animator1.isAnimating() && animator1.getDuration()<durationPerTest) { + while(glWindow1.getDuration()<durationPerTest) { Thread.sleep(100); } - animator1.stop(); - Assert.assertEquals(false, animator1.isAnimating()); frame1.setVisible(false); Assert.assertEquals(false, glWindow1.isDestroyed()); @@ -149,6 +149,64 @@ public class TestParenting01cAWT { //Assert.assertEquals(true, glWindow1.isDestroyed()); } + @Test + public void testWindowParenting05ReparentAWTWinHopFrame2Frame() throws InterruptedException { + int x = 0; + int y = 0; + + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); + + GLWindow glWindow1 = GLWindow.create(glCaps, true); + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, glWindow1, false); + glWindow1.addGLEventListener(demo1); + + NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); + + Frame frame1 = new Frame("AWT Parent Frame"); + frame1.setLayout(new BorderLayout()); + frame1.add(new Button("North"), BorderLayout.NORTH); + frame1.add(new Button("South"), BorderLayout.SOUTH); + frame1.add(new Button("East"), BorderLayout.EAST); + frame1.add(new Button("West"), BorderLayout.WEST); + frame1.setSize(width, height); + frame1.setLocation(0, 0); + frame1.setVisible(true); + + Frame frame2 = new Frame("AWT Parent Frame"); + frame2.setLayout(new BorderLayout()); + frame2.add(new Button("North"), BorderLayout.NORTH); + frame2.add(new Button("South"), BorderLayout.SOUTH); + frame2.add(new Button("East"), BorderLayout.EAST); + frame2.add(new Button("West"), BorderLayout.WEST); + frame2.setSize(width, height); + frame2.setLocation(640, 480); + frame2.setVisible(true); + + frame1.add(newtCanvasAWT, BorderLayout.CENTER); + Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); + + int state = 0; + while(glWindow1.getDuration()<3*durationPerTest) { + Thread.sleep(durationPerTest); + switch(state) { + case 0: + frame1.remove(newtCanvasAWT); + frame2.add(newtCanvasAWT, BorderLayout.CENTER); + break; + case 1: + frame2.remove(newtCanvasAWT); + frame1.add(newtCanvasAWT, BorderLayout.CENTER); + break; + } + state++; + } + + frame1.dispose(); + frame2.dispose(); + glWindow1.destroy(true); + } + public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) { Assert.assertNotNull(demo); Assert.assertNotNull(glWindow); diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting01cSwingAWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cSwingAWT.java index a3a06aea3..07e60ed1c 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting01cSwingAWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cSwingAWT.java @@ -30,7 +30,7 @@ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -package com.jogamp.test.junit.newt; +package com.jogamp.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -70,6 +70,10 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01cSwingAWT { + static { + GLProfile.initSingleton(); + } + static int width, height; static long durationPerTest = 800; static long waitReparent = 0; @@ -147,6 +151,7 @@ public class TestParenting01cSwingAWT { jFrame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event! jFrame1.setContentPane(jPanel1); jFrame1.setSize(width, height); + System.out.println("Demos: 1 - Visible"); jFrame1.setVisible(true); // from here on, we need to run modifications on EDT final JFrame _jFrame1 = jFrame1; @@ -159,23 +164,27 @@ public class TestParenting01cSwingAWT { while(animator1.isAnimating() && animator1.getDuration()<durationPerTest) { Thread.sleep(100); } + System.out.println("Demos: 2 - StopAnimator"); animator1.stop(); Assert.assertEquals(false, animator1.isAnimating()); SwingUtilities.invokeAndWait(new Runnable() { public void run() { + System.out.println("Demos: 3 - !Visible"); _jFrame1.setVisible(false); } }); Assert.assertEquals(false, glWindow1.isDestroyed()); SwingUtilities.invokeAndWait(new Runnable() { public void run() { + System.out.println("Demos: 4 - Visible"); _jFrame1.setVisible(true); } }); Assert.assertEquals(false, glWindow1.isDestroyed()); SwingUtilities.invokeAndWait(new Runnable() { public void run() { + System.out.println("Demos: 5 - X Container"); _jPanel1.remove(_container1); } }); // Assert.assertNull(glWindow1.getParentNativeWindow()); diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting02AWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02AWT.java index 8d9a0f380..08a3dc425 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting02AWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02AWT.java @@ -30,7 +30,7 @@ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -package com.jogamp.test.junit.newt; +package com.jogamp.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -65,6 +65,10 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting02AWT { + static { + GLProfile.initSingleton(); + } + static int width, height; static long durationPerTest = 500; static long waitReparent = 300; diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting02NEWT.java b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02NEWT.java index 5be04fcc2..0f25d2275 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting02NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02NEWT.java @@ -30,7 +30,7 @@ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -package com.jogamp.test.junit.newt; +package com.jogamp.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -59,6 +59,10 @@ import com.jogamp.test.junit.jogl.demos.es1.RedSquare; import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting02NEWT { + static { + GLProfile.initSingleton(); + } + static int width, height; static long durationPerTest = 500; @@ -122,6 +126,11 @@ public class TestParenting02NEWT { glWindow1.setPosition(x,y); glWindow1.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); glWindow1.addWindowListener(new TraceWindowAdapter()); + + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, window1, glWindow1, false); + // glWindow1.addGLEventListener(demo1); + glWindow1.setVisible(true); Capabilities capsChosen = glWindow1.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); Assert.assertNotNull(capsChosen); @@ -139,17 +148,17 @@ public class TestParenting02NEWT { glWindow2.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); glWindow2.addWindowListener(new TraceWindowAdapter(new WindowAction(eventFifo))); // glWindow2.addMouseListener(new TraceMouseAdapter()); + + GLEventListener demo2 = new Gears(); + setDemoFields(demo2, window2, glWindow2, false); + // glWindow2.addGLEventListener(demo2); + glWindow2.setVisible(true); capsChosen = glWindow2.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); Assert.assertNotNull(capsChosen); Assert.assertTrue(capsChosen.isOnscreen()==true); - GLEventListener demo1 = new RedSquare(); - setDemoFields(demo1, window1, glWindow1, false); glWindow1.addGLEventListener(demo1); - - GLEventListener demo2 = new Gears(); - setDemoFields(demo2, window2, glWindow2, false); glWindow2.addGLEventListener(demo2); boolean shouldQuit = false; diff --git a/src/junit/com/jogamp/test/junit/newt/WindowAction.java b/src/junit/com/jogamp/test/junit/newt/parenting/WindowAction.java index c52b895e6..387a06006 100644 --- a/src/junit/com/jogamp/test/junit/newt/WindowAction.java +++ b/src/junit/com/jogamp/test/junit/newt/parenting/WindowAction.java @@ -30,7 +30,7 @@ * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -package com.jogamp.test.junit.newt; +package com.jogamp.test.junit.newt.parenting; import com.jogamp.newt.event.*; diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java index 236ef0754..a3782d1e6 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java @@ -9,7 +9,7 @@ public class RecursiveToolkitLock { private Thread owner = null; private int recursionCount = 0; private Exception lockedStack = null; - private static final long timeout = 3000; // maximum wait 3s + private static final long timeout = 30000; // maximum wait 3s private static final boolean TRACE_LOCK = false; public Exception getLockedStack() { diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index 02c4733e7..deb4c7abe 100755 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -182,10 +182,9 @@ public abstract class Display { return true; } public EDTUtil getEDTUtil() { - if( !edtQueried ) { + if( null == edtUtil ) { synchronized (this) { - if( !edtQueried ) { - edtQueried = true; + if( null == edtUtil ) { if(NewtFactory.useEDT()) { final Display f_dpy = this; Thread current = Thread.currentThread(); @@ -203,12 +202,11 @@ public abstract class Display { } return edtUtil; } - volatile boolean edtQueried = false; public void runOnEDTIfAvail(boolean wait, final Runnable task) { - EDTUtil edtUtil = getEDTUtil(); - if(runCreateAndDestroyOnEDT() && null!=edtUtil) { - edtUtil.invoke(wait, task); + EDTUtil _edtUtil = getEDTUtil(); + if(runCreateAndDestroyOnEDT() && null!=_edtUtil) { + _edtUtil.invoke(wait, task); } else { task.run(); } @@ -238,6 +236,7 @@ public abstract class Display { if(null!=edtUtil) { edtUtil.waitUntilStopped(); edtUtil=null; + edt=null; } aDevice = null; } else { @@ -318,11 +317,12 @@ public abstract class Display { private LinkedList/*<NEWTEvent>*/ events = new LinkedList(); protected void dispatchMessages() { - if(0==refCount) return; // we should not exist .. + if(0==refCount) return; // in destruction .. + + LinkedList/*<NEWTEvent>*/ _events = null; if(!events.isEmpty()) { // swap events list to free ASAP - LinkedList/*<NEWTEvent>*/ _events = null; synchronized(eventsLock) { if(!events.isEmpty()) { _events = events; @@ -335,10 +335,13 @@ public abstract class Display { NEWTEventTask eventTask = (NEWTEventTask) iter.next(); NEWTEvent event = eventTask.get(); Object source = event.getSource(); - if(source instanceof Window) { - ((Window)source).sendEvent(event); + if(source instanceof NEWTEventConsumer) { + NEWTEventConsumer consumer = (NEWTEventConsumer) source ; + if(!consumer.consumeEvent(event)) { + enqueueEvent(false, event); + } } else { - throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source); + throw new RuntimeException("Event source not a NEWT one: "+source.getClass().getName()+", "+source); } eventTask.notifyIssuer(); } diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 9bd4bb377..0cd5b31bc 100755 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -34,11 +34,12 @@ package com.jogamp.newt; import com.jogamp.newt.event.*; +import com.jogamp.newt.util.*; import com.jogamp.newt.impl.Debug; -import com.jogamp.newt.util.EDTUtil; import com.jogamp.common.util.*; import javax.media.nativewindow.*; +import com.jogamp.nativewindow.util.Rectangle; import com.jogamp.nativewindow.impl.RecursiveToolkitLock; import java.util.ArrayList; @@ -46,7 +47,7 @@ import java.util.List; import java.util.Iterator; import java.lang.reflect.Method; -public abstract class Window implements NativeWindow +public abstract class Window implements NativeWindow, NEWTEventConsumer { public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent"); public static final boolean DEBUG_KEY_EVENT = Debug.debug("Window.KeyEvent"); @@ -155,7 +156,7 @@ public abstract class Window implements NativeWindow return 0 != windowHandle ; } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.createNative() START ("+getThreadName()+", "+this+")"); + System.out.println("Window.createNative() START ("+getThreadName()+", "+this+")"); } if(validateParentWindowHandle()) { Display dpy = getScreen().getDisplay(); @@ -163,7 +164,7 @@ public abstract class Window implements NativeWindow setVisibleImpl(true); } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.createNative() END ("+getThreadName()+", "+this+")"); + System.out.println("Window.createNative() END ("+getThreadName()+", "+this+")"); } return 0 != windowHandle ; } @@ -190,7 +191,7 @@ public abstract class Window implements NativeWindow } } catch (NativeWindowException nwe) { if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.getNativeWindowHandle: not successful yet: "+nwe); + System.out.println("Window.getNativeWindowHandle: not successful yet: "+nwe); } } finally { if(locked) { @@ -198,7 +199,7 @@ public abstract class Window implements NativeWindow } } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.getNativeWindowHandle: locked "+locked+", "+nativeWindow); + System.out.println("Window.getNativeWindowHandle: locked "+locked+", "+nativeWindow); } } return handle; @@ -245,7 +246,8 @@ public abstract class Window implements NativeWindow "\n, Visible "+isVisible()+ "\n, Undecorated "+undecorated+ "\n, Fullscreen "+fullscreen+ - "\n, WrappedWindow "+getWrappedWindow()); + "\n, WrappedWindow "+getWrappedWindow()+ + "\n, ChildWindows "+childWindows.size()); sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedListeners.size()+" ["); for (Iterator iter = surfaceUpdatedListeners.iterator(); iter.hasNext(); ) { @@ -376,41 +378,38 @@ public abstract class Window implements NativeWindow public void run() { windowLock(); try { - if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.destroy(deep: "+deep+") START "+getThreadName()+", "+this); + if(DEBUG_IMPLEMENTATION) { + System.out.println("Window.destroy(deep: "+deep+") START "+getThreadName()+", "+Window.this); } // Childs first .. - ArrayList listeners = null; - synchronized(childWindows) { - listeners = childWindows; - } - for(Iterator i = listeners.iterator(); i.hasNext(); ) { + synchronized(childWindowsLock) { + for(Iterator i = childWindows.iterator(); i.hasNext(); ) { NativeWindow nw = (NativeWindow) i.next(); + System.out.println("Window.destroy(deep: "+deep+") CHILD BEGIN"); if(nw instanceof Window) { - ((Window)nw).destroy(deep); + ((Window)nw).sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); + if(deep) { + ((Window)nw).destroy(deep); + } } else { nw.destroy(); } + System.out.println("Window.destroy(deep: "+deep+") CHILD END"); + } } // Now us .. if(deep) { - synchronized(childWindows) { + synchronized(childWindowsLock) { childWindows = new ArrayList(); } - synchronized(surfaceUpdatedListeners) { + synchronized(surfaceUpdatedListenersLock) { surfaceUpdatedListeners = new ArrayList(); } - synchronized(windowListeners) { - windowListeners = new ArrayList(); - } - synchronized(mouseListeners) { - mouseListeners = new ArrayList(); - } - synchronized(keyListeners) { - keyListeners = new ArrayList(); - } + windowListeners = new ArrayList(); + mouseListeners = new ArrayList(); + keyListeners = new ArrayList(); } Display dpy = null; Screen scr = null; @@ -428,8 +427,8 @@ public abstract class Window implements NativeWindow dpy.destroy(); } } - if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.destroy(deep: "+deep+") END "+getThreadName()+", "+this); + if(DEBUG_IMPLEMENTATION) { + System.out.println("Window.destroy(deep: "+deep+") END "+getThreadName()+", "+Window.this); } } finally { windowUnlock(); @@ -466,16 +465,16 @@ public abstract class Window implements NativeWindow try{ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { String msg = new String("!!! Window Invalidate(deep: "+deep+") "+getThreadName()); - System.err.println(msg); - //Exception e = new Exception(msg); - //e.printStackTrace(); + //System.out.println(msg); + Exception e = new Exception(msg); + e.printStackTrace(); } windowHandle = 0; - visible=false; - fullscreen=false; + visible = false; + fullscreen = false; if(deep) { - screen = null; + screen = null; parentWindowHandle = 0; parentNativeWindow = null; caps = null; @@ -593,43 +592,6 @@ public abstract class Window implements NativeWindow return false; } - /** - * If set to true, the default value, this NEWT Window implementation will - * handle the destruction (ie {@link #destroy()} call) within {@link #windowDestroyNotify()} implementation.<br> - * If set to false, it's up to the caller/owner to handle destruction within {@link #windowDestroyNotify()}. - */ - public void setHandleDestroyNotify(boolean b) { - handleDestroyNotify = b; - } - - protected void windowDestroyNotify() { - if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.windowDestroyNotify START "+getThreadName()); - } - - enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); - - if(handleDestroyNotify && !isDestroyed()) { - destroy(); - } - - if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.windowDestroyeNotify END "+getThreadName()); - } - } - - protected void windowDestroyed() { - if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.windowDestroyed "+getThreadName()); - } - invalidate(); - } - - protected boolean reparentWindowImpl() { - // default implementation, no native reparenting support - return false; - } - class ReparentAction implements Runnable { NativeWindow newParent; Screen newScreen; @@ -652,7 +614,7 @@ public abstract class Window implements NativeWindow } if(DEBUG_IMPLEMENTATION) { - System.err.println("reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+", visible "+visible+", parentNativeWindow "+(null!=parentNativeWindow)); + System.out.println("reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+", visible "+visible+", parentNativeWindow "+(null!=parentNativeWindow)); } if(null!=parentNativeWindow && parentNativeWindow instanceof Window) { @@ -671,8 +633,16 @@ public abstract class Window implements NativeWindow x = 0; y = 0; } + getScreen().getDisplay().dispatchMessages(); // status up2date + boolean wasVisible = isVisible(); + if(wasVisible) { + Window.this.visible = false; + setVisibleImpl(false); + getScreen().getDisplay().dispatchMessages(); // status up2date + } boolean reparentRes = false; reparentRes = reparentWindowImpl(); + getScreen().getDisplay().dispatchMessages(); // status up2date if(!reparentRes) { parentWindowHandle = 0; @@ -680,11 +650,17 @@ public abstract class Window implements NativeWindow if( 0 != windowHandle ) { destroy(false); } + } else { + if(wasVisible) { + Window.this.visible = true; + setVisibleImpl(true); + getScreen().getDisplay().dispatchMessages(); // status up2date + } } } if(DEBUG_IMPLEMENTATION) { - System.err.println("reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); + System.out.println("reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); } } finally { windowUnlock(); @@ -707,10 +683,10 @@ public abstract class Window implements NativeWindow public void reparentWindow(NativeWindow newParent, Screen newScreen) { if(!isDestroyed()) { runOnEDTIfAvail(true, new ReparentAction(newParent, newScreen)); - // if( isVisible() ) { - enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener - // enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_REPAINT); // trigger a repaint to listener - // } + if( isVisible() ) { + sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener + windowRepaint(0, 0, getWidth(), getHeight()); + } } } @@ -723,17 +699,15 @@ public abstract class Window implements NativeWindow windowLock(); try{ if( !isDestroyed() ) { - ArrayList listeners = null; - synchronized(childWindows) { - listeners = childWindows; - } - if(!visible && listeners.size()>0) { - for(Iterator i = listeners.iterator(); i.hasNext(); ) { + if(!visible && childWindows.size()>0) { + synchronized(childWindowsLock) { + for(Iterator i = childWindows.iterator(); i.hasNext(); ) { NativeWindow nw = (NativeWindow) i.next(); if(nw instanceof Window) { ((Window)nw).setVisible(false); } } + } } if(0==windowHandle && visible) { Window.this.visible = visible; @@ -746,18 +720,20 @@ public abstract class Window implements NativeWindow setVisibleImpl(visible); } } - if(0!=windowHandle && visible && listeners.size()>0) { - for(Iterator i = listeners.iterator(); i.hasNext(); ) { + if(0!=windowHandle && visible && childWindows.size()>0) { + synchronized(childWindowsLock) { + for(Iterator i = childWindows.iterator(); i.hasNext(); ) { NativeWindow nw = (NativeWindow) i.next(); if(nw instanceof Window) { ((Window)nw).setVisible(true); } } + } } } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+Window.this.visible); + System.out.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+Window.this.visible); } } finally { windowUnlock(); @@ -793,7 +769,7 @@ public abstract class Window implements NativeWindow public void setVisible(boolean visible) { if(DEBUG_IMPLEMENTATION) { String msg = new String("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); - //System.err.println(msg); + //System.out.println(msg); Exception ee = new Exception(msg); ee.printStackTrace(); } @@ -830,7 +806,7 @@ public abstract class Window implements NativeWindow try{ if(DEBUG_IMPLEMENTATION) { String msg = new String("Window setSize: START "+this.width+"x"+this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible); - //System.err.println(msg); + //System.out.println(msg); Exception e = new Exception(msg); e.printStackTrace(); } @@ -847,7 +823,7 @@ public abstract class Window implements NativeWindow this.width = width; this.height = height; } else if ( 0 != windowHandle ) { - // this width/height will be set by windowChanged, called by X11 + // this width/height will be set by windowChanged, called by the native implementation setSizeImpl(width, height); } else { this.width = width; @@ -856,7 +832,7 @@ public abstract class Window implements NativeWindow } } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window setSize: END "+this.width+"x"+this.height+", visibleAction "+visibleAction); + System.out.println("Window setSize: END "+this.width+"x"+this.height+", visibleAction "+visibleAction); } } finally { windowUnlock(); @@ -881,7 +857,7 @@ public abstract class Window implements NativeWindow windowLock(); try{ if(DEBUG_IMPLEMENTATION) { - System.err.println("Window setPosition: "+this.x+"/"+this.y+" -> "+x+"/"+y+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)); + System.out.println("Window setPosition: "+this.x+"/"+this.y+" -> "+x+"/"+y+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)); } if ( this.x != x || this.y != y ) { if(!fullscreen) { @@ -918,7 +894,7 @@ public abstract class Window implements NativeWindow h = nfs_height; } if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { - System.err.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()); + System.out.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()); } this.fullscreen = setFullscreenImpl(fullscreen, x, y, w, h); } @@ -934,12 +910,11 @@ public abstract class Window implements NativeWindow // private ArrayList childWindows = new ArrayList(); + private Object childWindowsLock = new Object(); protected void removeChild(NativeWindow win) { - synchronized(childWindows) { - ArrayList newChildWindows = (ArrayList) childWindows.clone(); - newChildWindows.remove(win); - childWindows = newChildWindows; + synchronized(childWindowsLock) { + childWindows.remove(win); } } @@ -947,16 +922,26 @@ public abstract class Window implements NativeWindow if (win == null) { return; } - synchronized(childWindows) { - ArrayList newChildWindows = (ArrayList) childWindows.clone(); - newChildWindows.add(win); - childWindows = newChildWindows; + synchronized(childWindowsLock) { + childWindows.add(win); } } // // Generic Event Support // + private void doEvent(boolean enqueue, boolean wait, com.jogamp.newt.event.NEWTEvent event) { + boolean done = false; + + if(!enqueue) { + done = consumeEvent(event); + wait = done; // don't wait if event can't be consumed now + } + + if(!done) { + enqueueEvent(wait, event); + } + } public void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) { if(!getInnerWindow().isDestroyed()) { @@ -964,21 +949,45 @@ public abstract class Window implements NativeWindow } } - public void sendEvent(NEWTEvent e) { + public boolean consumeEvent(NEWTEvent e) { + switch(e.getEventType()) { + case WindowEvent.EVENT_WINDOW_REPAINT: + if( windowIsLocked() ) { + if(!repaintQueued) { + repaintQueued=true; + return false; + } else { + return true; + } + } else { + if(DEBUG_IMPLEMENTATION) { + System.out.println("Window.windowRepaint: "+e); + // Exception ee = new Exception("Window.windowRepaint: "+e); + // ee.printStackTrace(); + } + repaintQueued=false; + } + break; + default: + break; + } if(e instanceof WindowEvent) { - getInnerWindow().sendWindowEvent((WindowEvent)e); + getInnerWindow().consumeWindowEvent((WindowEvent)e); } else if(e instanceof KeyEvent) { - getInnerWindow().sendKeyEvent((KeyEvent)e); + getInnerWindow().consumeKeyEvent((KeyEvent)e); } else if(e instanceof MouseEvent) { - getInnerWindow().sendMouseEvent((MouseEvent)e); + getInnerWindow().consumeMouseEvent((MouseEvent)e); } + return true; } + protected boolean repaintQueued = false; // // SurfaceUpdatedListener Support // private ArrayList surfaceUpdatedListeners = new ArrayList(); + private Object surfaceUpdatedListenersLock = new Object(); /** * Appends the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} to the end of @@ -1004,13 +1013,11 @@ public abstract class Window implements NativeWindow if(l == null) { return; } - synchronized(surfaceUpdatedListeners) { + synchronized(surfaceUpdatedListenersLock) { if(0>index) { index = surfaceUpdatedListeners.size(); } - ArrayList newSurfaceUpdatedListeners = (ArrayList) surfaceUpdatedListeners.clone(); - newSurfaceUpdatedListeners.add(index, l); - surfaceUpdatedListeners = newSurfaceUpdatedListeners; + surfaceUpdatedListeners.add(index, l); } } @@ -1018,21 +1025,19 @@ public abstract class Window implements NativeWindow if (l == null) { return; } - synchronized(surfaceUpdatedListeners) { - ArrayList newSurfaceUpdatedListeners = (ArrayList) surfaceUpdatedListeners.clone(); - newSurfaceUpdatedListeners.remove(l); - surfaceUpdatedListeners = newSurfaceUpdatedListeners; + synchronized(surfaceUpdatedListenersLock) { + surfaceUpdatedListeners.remove(l); } } public void removeAllSurfaceUpdatedListener() { - synchronized(surfaceUpdatedListeners) { + synchronized(surfaceUpdatedListenersLock) { surfaceUpdatedListeners = new ArrayList(); } } public SurfaceUpdatedListener getSurfaceUpdatedListener(int index) { - synchronized(surfaceUpdatedListeners) { + synchronized(surfaceUpdatedListenersLock) { if(0>index) { index = surfaceUpdatedListeners.size()-1; } @@ -1041,19 +1046,17 @@ public abstract class Window implements NativeWindow } public SurfaceUpdatedListener[] getSurfaceUpdatedListeners() { - synchronized(surfaceUpdatedListeners) { + synchronized(surfaceUpdatedListenersLock) { return (SurfaceUpdatedListener[]) surfaceUpdatedListeners.toArray(); } } public void surfaceUpdated(Object updater, NativeWindow window, long when) { - ArrayList listeners = null; - synchronized(surfaceUpdatedListeners) { - listeners = surfaceUpdatedListeners; - } - for(Iterator i = listeners.iterator(); i.hasNext(); ) { + synchronized(surfaceUpdatedListenersLock) { + for(Iterator i = surfaceUpdatedListeners.iterator(); i.hasNext(); ) { SurfaceUpdatedListener l = (SurfaceUpdatedListener) i.next(); l.surfaceUpdated(updater, window, when); + } } } @@ -1066,13 +1069,21 @@ public abstract class Window implements NativeWindow private int lastMouseClickCount = 0; // last mouse button click count public static final int ClickTimeout = 300; + public void sendMouseEvent(int eventType, int modifiers, + int x, int y, int button, int rotation) { + doMouseEvent(false, false, eventType, modifiers, x, y, button, rotation); + } public void enqueueMouseEvent(boolean wait, int eventType, int modifiers, int x, int y, int button, int rotation) { + doMouseEvent(true, wait, eventType, modifiers, x, y, button, rotation); + } + private void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers, + int x, int y, int button, int rotation) { if(x<0||y<0||x>=width||y>=height) { return; // .. invalid .. } if(DEBUG_MOUSE_EVENT) { - System.err.println("enqueueMouseEvent: "+MouseEvent.getEventTypeString(eventType)+ + System.out.println("doMouseEvent: enqueue"+enqueue+", wait "+wait+", "+MouseEvent.getEventTypeString(eventType)+ ", mod "+modifiers+", pos "+x+"/"+y+", button "+button); } if(button<0||button>MouseEvent.BUTTON_NUMBER) { @@ -1116,12 +1127,12 @@ public abstract class Window implements NativeWindow } else { e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, 0); } - screen.getDisplay().enqueueEvent(wait, e); + doEvent(enqueue, wait, e); if(null!=eClicked) { if(DEBUG_MOUSE_EVENT) { - System.err.println("enqueueMouseEvent: synthesized MOUSE_CLICKED event"); + System.out.println("doMouseEvent: synthesized MOUSE_CLICKED event"); } - screen.getDisplay().enqueueEvent(wait, eClicked); + doEvent(enqueue, wait, eClicked); } } @@ -1148,52 +1159,41 @@ public abstract class Window implements NativeWindow if(l == null) { return; } - synchronized(mouseListeners) { - if(0>index) { - index = mouseListeners.size(); - } - ArrayList newMouseListeners = (ArrayList) mouseListeners.clone(); - newMouseListeners.add(index, l); - mouseListeners = newMouseListeners; + ArrayList clonedListeners = (ArrayList) mouseListeners.clone(); + if(0>index) { + index = clonedListeners.size(); } + clonedListeners.add(index, l); + mouseListeners = clonedListeners; } public void removeMouseListener(MouseListener l) { if (l == null) { return; } - synchronized(mouseListeners) { - ArrayList newMouseListeners = (ArrayList) mouseListeners.clone(); - newMouseListeners.remove(l); - mouseListeners = newMouseListeners; - } + ArrayList clonedListeners = (ArrayList) mouseListeners.clone(); + clonedListeners.remove(l); + mouseListeners = clonedListeners; } public MouseListener getMouseListener(int index) { - synchronized(mouseListeners) { - if(0>index) { - index = mouseListeners.size()-1; - } - return (MouseListener) mouseListeners.get(index); + ArrayList clonedListeners = (ArrayList) mouseListeners.clone(); + if(0>index) { + index = clonedListeners.size()-1; } + return (MouseListener) clonedListeners.get(index); } public MouseListener[] getMouseListeners() { - synchronized(mouseListeners) { - return (MouseListener[]) mouseListeners.toArray(); - } + return (MouseListener[]) mouseListeners.toArray(); } - protected void sendMouseEvent(MouseEvent e) { + protected void consumeMouseEvent(MouseEvent e) { if(DEBUG_MOUSE_EVENT) { - System.err.println("sendMouseEvent: event: "+e); + System.out.println("consumeMouseEvent: event: "+e); } - ArrayList listeners = null; - synchronized(mouseListeners) { - listeners = mouseListeners; - } - for(Iterator i = listeners.iterator(); i.hasNext(); ) { + for(Iterator i = mouseListeners.iterator(); i.hasNext(); ) { MouseListener l = (MouseListener) i.next(); switch(e.getEventType()) { case MouseEvent.EVENT_MOUSE_CLICKED: @@ -1230,10 +1230,12 @@ public abstract class Window implements NativeWindow // KeyListener/Event Support // + public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) ); + } + public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) { - screen.getDisplay().enqueueEvent(wait, - new KeyEvent(eventType, this, System.currentTimeMillis(), - modifiers, keyCode, keyChar) ); + enqueueEvent(wait, new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) ); } /** @@ -1258,53 +1260,42 @@ public abstract class Window implements NativeWindow if(l == null) { return; } - synchronized(keyListeners) { - if(0>index) { - index = keyListeners.size(); - } - ArrayList newKeyListeners = (ArrayList) keyListeners.clone(); - newKeyListeners.add(index, l); - keyListeners = newKeyListeners; + ArrayList clonedListeners = (ArrayList) keyListeners.clone(); + if(0>index) { + index = clonedListeners.size(); } + clonedListeners.add(index, l); + keyListeners = clonedListeners; } public void removeKeyListener(KeyListener l) { if (l == null) { return; } - synchronized(keyListeners) { - ArrayList newKeyListeners = (ArrayList) keyListeners.clone(); - newKeyListeners.remove(l); - keyListeners = newKeyListeners; - } + ArrayList clonedListeners = (ArrayList) keyListeners.clone(); + clonedListeners.remove(l); + keyListeners = clonedListeners; } public KeyListener getKeyListener(int index) { - synchronized(keyListeners) { - if(0>index) { - index = keyListeners.size()-1; - } - return (KeyListener) keyListeners.get(index); + ArrayList clonedListeners = (ArrayList) keyListeners.clone(); + if(0>index) { + index = clonedListeners.size()-1; } + return (KeyListener) clonedListeners.get(index); } public KeyListener[] getKeyListeners() { - synchronized(keyListeners) { - return (KeyListener[]) keyListeners.toArray(); - } + return (KeyListener[]) keyListeners.toArray(); } private ArrayList keyListeners = new ArrayList(); - protected void sendKeyEvent(KeyEvent e) { + protected void consumeKeyEvent(KeyEvent e) { if(DEBUG_KEY_EVENT) { - System.err.println("sendKeyEvent: "+e); - } - ArrayList listeners = null; - synchronized(keyListeners) { - listeners = keyListeners; + System.out.println("consumeKeyEvent: "+e); } - for(Iterator i = listeners.iterator(); i.hasNext(); ) { + for(Iterator i = keyListeners.iterator(); i.hasNext(); ) { KeyListener l = (KeyListener) i.next(); switch(e.getEventType()) { case KeyEvent.EVENT_KEY_PRESSED: @@ -1325,10 +1316,12 @@ public abstract class Window implements NativeWindow // // WindowListener/Event Support // + public void sendWindowEvent(int eventType) { + consumeWindowEvent( new WindowEvent(eventType, this, System.currentTimeMillis()) ); + } + public void enqueueWindowEvent(boolean wait, int eventType) { - WindowEvent event = new WindowEvent(eventType, this, System.currentTimeMillis()); - screen.getDisplay().enqueueEvent( wait, event ); - // sendWindowEvent ( event ); // FIXME: Think about performance/lag .. ? + enqueueEvent( wait, new WindowEvent(eventType, this, System.currentTimeMillis()) ); } private ArrayList windowListeners = new ArrayList(); @@ -1357,55 +1350,40 @@ public abstract class Window implements NativeWindow if(l == null) { return; } - synchronized(windowListeners) { - if(0>index) { - index = windowListeners.size(); - } - ArrayList newWindowListeners = (ArrayList) windowListeners.clone(); - newWindowListeners.add(index, l); - windowListeners = newWindowListeners; + ArrayList clonedListeners = (ArrayList) windowListeners.clone(); + if(0>index) { + index = clonedListeners.size(); } + clonedListeners.add(index, l); + windowListeners = clonedListeners; } public void removeWindowListener(WindowListener l) { if (l == null) { return; } - synchronized(windowListeners) { - ArrayList newWindowListeners = (ArrayList) windowListeners.clone(); - newWindowListeners.remove(l); - windowListeners = newWindowListeners; - } + ArrayList clonedListeners = (ArrayList) windowListeners.clone(); + clonedListeners.remove(l); + windowListeners = clonedListeners; } public WindowListener getWindowListener(int index) { - synchronized(windowListeners) { - if(0>index) { - index = windowListeners.size()-1; - } - return (WindowListener) windowListeners.get(index); + ArrayList clonedListeners = (ArrayList) windowListeners.clone(); + if(0>index) { + index = clonedListeners.size()-1; } + return (WindowListener) clonedListeners.get(index); } public WindowListener[] getWindowListeners() { - synchronized(windowListeners) { - return (WindowListener[]) windowListeners.toArray(); - } - } - - protected void sendWindowEvent(WindowEvent e) { - getInnerWindow().sendWindowEvent(e, 0, 0, 0, 0); + return (WindowListener[]) windowListeners.toArray(); } - protected void sendWindowEvent(WindowEvent e, int p1, int p2, int p3, int p4) { + protected void consumeWindowEvent(WindowEvent e) { if(DEBUG_WINDOW_EVENT) { - System.err.println("sendWindowEvent: "+e+", "+p1+", "+p2+", "+p3+", "+p4); + System.out.println("consumeWindowEvent: "+e); } - ArrayList listeners = null; - synchronized(windowListeners) { - listeners = windowListeners; - } - for(Iterator i = listeners.iterator(); i.hasNext(); ) { + for(Iterator i = windowListeners.iterator(); i.hasNext(); ) { WindowListener l = (WindowListener) i.next(); switch(e.getEventType()) { case WindowEvent.EVENT_WINDOW_RESIZED: @@ -1423,9 +1401,9 @@ public abstract class Window implements NativeWindow case WindowEvent.EVENT_WINDOW_LOST_FOCUS: l.windowLostFocus(e); break; - //case WindowEvent.EVENT_WINDOW_REPAINT: - // l.windowRepaint(e); - // break; + case WindowEvent.EVENT_WINDOW_REPAINT: + l.windowRepaint((WindowUpdateEvent)e); + break; default: throw new NativeWindowException("Unexpected window event type " @@ -1434,6 +1412,115 @@ public abstract class Window implements NativeWindow } } + /** + * @param focusGained + */ + protected void focusChanged(boolean focusGained) { + if(DEBUG_IMPLEMENTATION) { + System.out.println("Window.focusChanged: "+focusGained); + } + if (focusGained) { + sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + } else { + sendWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); + } + } + + protected void visibleChanged(boolean visible) { + if(DEBUG_IMPLEMENTATION) { + System.out.println("Window.visibleChanged: "+this.visible+" -> "+visible); + } + this.visible = visible ; + } + + protected void sizeChanged(int newWidth, int newHeight) { + if(DEBUG_IMPLEMENTATION) { + System.out.println("Window.sizeChanged: "+width+"x"+height+" -> "+newWidth+"x"+newHeight); + } + if(width != newWidth || height != newHeight) { + width = newWidth; + height = newHeight; + if(!fullscreen) { + nfs_width=width; + nfs_height=height; + } + sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + } + } + + protected void positionChanged(int newX, int newY) { + if(DEBUG_IMPLEMENTATION) { + System.out.println("Window.positionChanged: "+x+"/"+y+" -> "+newX+"/"+newY); + } + if( 0==parentWindowHandle && ( x != newX || y != newY ) ) { + x = newX; + y = newY; + if(!fullscreen) { + nfs_x=x; + nfs_y=y; + } + sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); + } + } + + /** + * If set to true, the default value, this NEWT Window implementation will + * handle the destruction (ie {@link #destroy()} call) within {@link #windowDestroyNotify()} implementation.<br> + * If set to false, it's up to the caller/owner to handle destruction within {@link #windowDestroyNotify()}. + */ + public void setHandleDestroyNotify(boolean b) { + handleDestroyNotify = b; + } + + protected void windowDestroyNotify() { + if(DEBUG_IMPLEMENTATION) { + System.out.println("Window.windowDestroyNotify START "+getThreadName()); + } + + enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); + + if(handleDestroyNotify && !isDestroyed()) { + destroy(); + } + + if(DEBUG_IMPLEMENTATION) { + System.out.println("Window.windowDestroyeNotify END "+getThreadName()); + } + } + + protected void windowDestroyed() { + if(DEBUG_IMPLEMENTATION) { + System.out.println("Window.windowDestroyed "+getThreadName()); + } + invalidate(); + } + + public void setPropagateRepaint(boolean v) { + propagateRepaint = v; + } + protected boolean propagateRepaint = true; + + public void windowRepaint(int x, int y, int width, int height) { + if(!propagateRepaint) { + return; + } + if(0>width) { + width=this.width; + } + if(0>height) { + height=this.height; + } + + NEWTEvent e = new WindowUpdateEvent(WindowEvent.EVENT_WINDOW_REPAINT, this, System.currentTimeMillis(), + new Rectangle(x, y, width, height)); + doEvent(false, false, e); + } + + protected boolean reparentWindowImpl() { + // default implementation, no native reparenting support + return false; + } + // // Reflection helper .. // diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index 8944c03bb..b2dd719bc 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -35,13 +35,20 @@ package com.jogamp.newt.awt; import java.lang.reflect.*; import java.security.*; +import java.awt.Button; +import java.awt.Frame; import java.awt.Canvas; +import java.awt.Graphics; +import java.awt.KeyboardFocusManager; import javax.media.nativewindow.*; -// import javax.media.nativewindow.awt.*; import com.jogamp.newt.event.awt.AWTAdapter; import com.jogamp.newt.event.awt.AWTParentWindowAdapter; +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.MouseEvent; +import com.jogamp.newt.event.MouseAdapter; import com.jogamp.newt.Screen; import com.jogamp.newt.Window; import com.jogamp.newt.impl.Debug; @@ -52,6 +59,7 @@ public class NewtCanvasAWT extends java.awt.Canvas { NativeWindow parent = null; Window newtChild = null; AWTAdapter awtAdapter = null; + boolean hasSwingContainer = false; /** * Instantiates a NewtCanvas without a NEWT child.<br> @@ -67,11 +75,84 @@ public class NewtCanvasAWT extends java.awt.Canvas { super(); setNEWTChild(child); } + + class UnfocusRunnable implements Runnable { + boolean focusTraversed = false; + public void run() { + KeyboardFocusManager focusManager = + KeyboardFocusManager.getCurrentKeyboardFocusManager(); + java.awt.Component comp1 = focusManager.getPermanentFocusOwner(); + java.awt.Component comp2 = focusManager.getFocusOwner(); + if(DEBUG_IMPLEMENTATION) { + System.out.println("AWT Unfocus: traversed "+focusTraversed+" (1)"); + System.out.println("PRE PermenetFocusOwner: "+comp1); + System.out.println("PRE FocusOwner: "+comp2); + } + if(null!=comp1) { + if(!focusTraversed && null==comp2) { + comp1.requestFocus(); + focusTraversed=true; + if(DEBUG_IMPLEMENTATION) { + System.out.println("AWT Unfocus: traversed "+focusTraversed+" (*)"); + } + } else { + focusTraversed=false; + } + + if(DEBUG_IMPLEMENTATION) { + comp1 = focusManager.getPermanentFocusOwner(); + comp2 = focusManager.getFocusOwner(); + System.out.println("MID PermenetFocusOwner: "+comp1); + System.out.println("MID FocusOwner: "+comp2); + } + + focusManager.clearGlobalFocusOwner(); + + if(DEBUG_IMPLEMENTATION) { + comp1 = focusManager.getPermanentFocusOwner(); + comp2 = focusManager.getFocusOwner(); + System.out.println("POST PermenetFocusOwner: "+comp1); + System.out.println("POST FocusOwner: "+comp2); + } + + if(focusTraversed && null!=newtChild) { + newtChild.requestFocus(); + } + } + } + } + UnfocusRunnable unfocusRunnable = new UnfocusRunnable(); + + class FocusListener extends WindowAdapter { + public synchronized void windowGainedFocus(WindowEvent e) { + if(DEBUG_IMPLEMENTATION) { + System.out.println("NewtCanvasAWT focus on: AWT focus "+ NewtCanvasAWT.this.hasFocus()+ + ", focusable "+NewtCanvasAWT.this.isFocusable()+", onEDT "+hasSwingContainer); + } + if(hasSwingContainer) { + java.awt.EventQueue.invokeLater(unfocusRunnable); + } else { + unfocusRunnable.run(); + } + } + public synchronized void windowLostFocus(WindowEvent e) { + if(DEBUG_IMPLEMENTATION) { + System.out.println("NewtCanvasAWT focus off: AWT focus "+ NewtCanvasAWT.this.hasFocus()); + } + } + } + FocusListener focusListener = new FocusListener(); /** sets a new NEWT child, provoking reparenting on the NEWT level. */ public NewtCanvasAWT setNEWTChild(Window child) { if(newtChild!=child) { + if(null!=newtChild) { + newtChild.removeWindowListener(focusListener); + } newtChild = child; + if(null!=newtChild) { + newtChild.addWindowListener(focusListener); + } if(null!=parent) { java.awt.Container cont = getContainer(this); // reparent right away, addNotify has been called already @@ -100,12 +181,22 @@ public class NewtCanvasAWT extends java.awt.Canvas { } } - static java.awt.Container getContainer(java.awt.Component comp) { - while( null != comp && !(comp instanceof java.awt.Container) ) { + static boolean hasSwingContainer(java.awt.Component comp) { + while( null != comp ) { + if( comp instanceof javax.swing.JComponent ) { + return true; + } comp = comp.getParent(); } - if(comp instanceof java.awt.Container) { - return (java.awt.Container) comp; + return false; + } + + static java.awt.Container getContainer(java.awt.Component comp) { + while( null != comp ) { + if( comp instanceof java.awt.Container ) { + return (java.awt.Container) comp; + } + comp = comp.getParent(); } return null; } @@ -113,11 +204,13 @@ public class NewtCanvasAWT extends java.awt.Canvas { public void addNotify() { super.addNotify(); disableBackgroundErase(); + hasSwingContainer = hasSwingContainer(this); java.awt.Container cont = getContainer(this); if(DEBUG_IMPLEMENTATION) { // if ( isShowing() == false ) -> Container was not visible yet. // if ( isShowing() == true ) -> Container is already visible. - System.err.println("NewtCanvasAWT.addNotify: "+newtChild+", "+this+", visible "+isVisible()+", showing "+isShowing()+", displayable "+isDisplayable()+" -> "+cont); + System.err.println("NewtCanvasAWT.addNotify: "+newtChild+", "+this+", visible "+isVisible()+", showing "+isShowing()+ + ", displayable "+isDisplayable()+", swingContainer "+hasSwingContainer+" -> "+cont); } reparentWindow(true, cont); } @@ -154,6 +247,8 @@ public class NewtCanvasAWT extends java.awt.Canvas { newtChild.reparentWindow(parent, screen); newtChild.setVisible(true); setWindowAdapter(true); + newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener + newtChild.windowRepaint(0, 0, newtChild.getWidth(), newtChild.getHeight()); } } else { setWindowAdapter(false); @@ -164,9 +259,14 @@ public class NewtCanvasAWT extends java.awt.Canvas { } public void paint(Graphics g) { - if(null!=newtChild) { - // enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_REPAINT); // trigger a repaint to listener - } + if(null!=newtChild) { + newtChild.windowRepaint(0, 0, getWidth(), getHeight()); + } + } + public void update(Graphics g) { + if(null!=newtChild) { + newtChild.windowRepaint(0, 0, getWidth(), getHeight()); + } } // Disables the AWT's erasing of this Canvas's background on Windows diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java index 476b3640e..9afcb840c 100644 --- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java @@ -123,7 +123,7 @@ public class NEWTEvent extends java.util.EventObject { /** * Attach the passed object to this event.<br> - * If an object was previously attached, it will replaced.<br> + * If an object was previously attached, it will be replaced.<br> * Attachments to NEWT events allow users to pass on information * from one custom listener to another, ie custom listener to listener * communication. diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEventConsumer.java b/src/newt/classes/com/jogamp/newt/event/NEWTEventConsumer.java new file mode 100644 index 000000000..e37c820a1 --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/event/NEWTEventConsumer.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010 Sven Gothel. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Sven Gothel or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ +package com.jogamp.newt.event; + +public interface NEWTEventConsumer { + + /** + * Consume the event + * + * @return true if the event can be consumed now, + * otherwise propagate it later. + */ + public boolean consumeEvent(NEWTEvent event); +} diff --git a/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java index a6cf0d6ed..fb9e1877a 100644 --- a/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java @@ -65,7 +65,7 @@ public class TraceWindowAdapter implements WindowListener { System.out.println(e); if(null!=downstream) { downstream.windowLostFocus(e); } } - public void windowRepaint(WindowEvent e) { + public void windowRepaint(WindowUpdateEvent e) { System.out.println(e); if(null!=downstream) { downstream.windowRepaint(e); } } diff --git a/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java index 925bc7113..587622a81 100644 --- a/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java @@ -45,6 +45,6 @@ public abstract class WindowAdapter implements WindowListener } public void windowLostFocus(WindowEvent e) { } - public void windowRepaint(WindowEvent e) { + public void windowRepaint(WindowUpdateEvent e) { } } diff --git a/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java new file mode 100755 index 000000000..5a11f0f77 --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010 Sven Gothel. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Sven Gothel or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ +package com.jogamp.newt.event; + +import com.jogamp.newt.*; +import com.jogamp.nativewindow.util.Rectangle; + +public class WindowUpdateEvent extends WindowEvent { + Rectangle bounds; + + public WindowUpdateEvent(int eventType, Object source, long when, Rectangle bounds) + { + super(eventType, source, when); + this.bounds = bounds; + } + + public Rectangle getBounds() { + return bounds; + } + + public String toString() { + return "WindowUpdateEvent["+super.toString()+", "+bounds+"]"; + } +} diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java index e4e97946a..076165c73 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java @@ -48,8 +48,10 @@ class AWTNewtEventFactory { // n/a map.put(java.awt.event.WindowEvent.WINDOW_DEICONIFIED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DEICONIFIED); map.put(java.awt.event.WindowEvent.WINDOW_ACTIVATED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS); map.put(java.awt.event.WindowEvent.WINDOW_GAINED_FOCUS, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + map.put(java.awt.event.FocusEvent.FOCUS_GAINED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS); map.put(java.awt.event.WindowEvent.WINDOW_DEACTIVATED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS); map.put(java.awt.event.WindowEvent.WINDOW_LOST_FOCUS, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS); + map.put(java.awt.event.FocusEvent.FOCUS_LOST, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS); // n/a map.put(java.awt.event.WindowEvent.WINDOW_STATE_CHANGED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_STATE_CHANGED); map.put(java.awt.event.ComponentEvent.COMPONENT_MOVED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_MOVED); @@ -108,6 +110,14 @@ class AWTNewtEventFactory { return null; // no mapping .. } + static final com.jogamp.newt.event.WindowEvent createWindowEvent(java.awt.event.FocusEvent event, com.jogamp.newt.Window newtSource) { + int type = eventTypeAWT2NEWT.get(event.getID()); + if(-1 < type) { + return new com.jogamp.newt.event.WindowEvent(type, (null==newtSource)?(Object)event.getComponent():(Object)newtSource, System.currentTimeMillis()); + } + return null; // no mapping .. + } + static final com.jogamp.newt.event.MouseEvent createMouseEvent(java.awt.event.MouseEvent event, com.jogamp.newt.Window newtSource) { int type = eventTypeAWT2NEWT.get(event.getID()); if(-1 < type) { diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java index 7905a728c..43087289a 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java @@ -53,6 +53,19 @@ public class AWTParentWindowAdapter return super.removeFrom(awtComponent); } + public void focusGained(java.awt.event.FocusEvent e) { + if(DEBUG_IMPLEMENTATION) { + System.out.println("AWT: focusGained: START "+ e.getComponent()); + } + newtWindow.requestFocus(); + } + + public void focusLost(java.awt.event.FocusEvent e) { + if(DEBUG_IMPLEMENTATION) { + System.out.println("AWT: focusLost: "+ e.getComponent()); + } + } + public void componentResized(java.awt.event.ComponentEvent e) { // Need to resize the NEWT child window // the resized event will be send via the native window feedback. diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java index 7bfffbafc..875401544 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java @@ -33,7 +33,7 @@ package com.jogamp.newt.event.awt; public class AWTWindowAdapter extends AWTAdapter - implements java.awt.event.ComponentListener, java.awt.event.WindowListener + implements java.awt.event.ComponentListener, java.awt.event.WindowListener, java.awt.event.FocusListener { WindowClosingListener windowClosingListener; @@ -52,6 +52,7 @@ public class AWTWindowAdapter public AWTAdapter addTo(java.awt.Component awtComponent) { java.awt.Window win = getWindow(awtComponent); awtComponent.addComponentListener(this); + awtComponent.addFocusListener(this); if( null == windowClosingListener ) { windowClosingListener = new WindowClosingListener(); } @@ -65,6 +66,7 @@ public class AWTWindowAdapter } public AWTAdapter removeFrom(java.awt.Component awtComponent) { + awtComponent.removeFocusListener(this); awtComponent.removeComponentListener(this); java.awt.Window win = getWindow(awtComponent); if( null != win && null != windowClosingListener ) { @@ -86,6 +88,24 @@ public class AWTWindowAdapter return null; } + public void focusGained(java.awt.event.FocusEvent e) { + com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow); + if(null!=newtListener) { + ((com.jogamp.newt.event.WindowListener)newtListener).windowGainedFocus(event); + } else { + enqueueEvent(false, event); + } + } + + public void focusLost(java.awt.event.FocusEvent e) { + com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow); + if(null!=newtListener) { + ((com.jogamp.newt.event.WindowListener)newtListener).windowLostFocus(event); + } else { + enqueueEvent(false, event); + } + } + public void componentResized(java.awt.event.ComponentEvent e) { com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow); if(null!=newtListener) { diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java index a06b7160c..6f936d2c6 100644 --- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java @@ -215,7 +215,7 @@ public class AWTWindow extends Window { } } - public com.jogamp.newt.Insets getInsets() { + public com.jogamp.newt.util.Insets getInsets() { final int insets[] = new int[] { 0, 0, 0, 0 }; runOnEDT(true, new Runnable() { public void run() { @@ -226,7 +226,7 @@ public class AWTWindow extends Window { insets[3] = contInsets.right; } }); - return new com.jogamp.newt. + return new com.jogamp.newt.util. Insets(insets[0],insets[1],insets[2],insets[3]); } @@ -264,19 +264,6 @@ public class AWTWindow extends Window { return canvas; } - protected void enqueueWindowEvent(int eventType) { - super.enqueueWindowEvent(eventType); - } - - protected void enqueueKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { - super.enqueueKeyEvent(eventType, modifiers, keyCode, keyChar); - } - - protected void enqueueMouseEvent(int eventType, int modifiers, - int x, int y, int button, int rotation) { - super.enqueueMouseEvent(eventType, modifiers, x, y, button, rotation); - } - private void runOnEDT(boolean wait, Runnable r) { EDTUtil edtUtil = screen.getDisplay().getEDTUtil(); if ( ( null != edtUtil && edtUtil.isCurrentThreadEDT() ) || EventQueue.isDispatchThread() ) { diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java index 8a656a5a8..9f47aa49f 100755 --- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java @@ -39,6 +39,7 @@ import com.jogamp.nativewindow.impl.RecursiveToolkitLock; import com.jogamp.newt.*; import com.jogamp.newt.event.*; import com.jogamp.newt.impl.*; +import com.jogamp.newt.util.*; public class MacWindow extends Window { @@ -295,24 +296,6 @@ public class MacWindow extends Window { return fullscreen; } - private void sizeChanged(int newWidth, int newHeight) { - if(width != newWidth || height != newHeight) { - if (DEBUG_IMPLEMENTATION) { - System.out.println(Thread.currentThread().getName()+" Size changed to " + newWidth + ", " + newHeight); - } - width = newWidth; - height = newHeight; - if(!fullscreen) { - nfs_width=width; - nfs_height=height; - } - if (DEBUG_IMPLEMENTATION) { - System.out.println(" Posted WINDOW_RESIZED event"); - } - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); - } - } - private void insetsChanged(int left, int top, int right, int bottom) { if (DEBUG_IMPLEMENTATION) { System.out.println(Thread.currentThread().getName()+ @@ -326,32 +309,6 @@ public class MacWindow extends Window { } } - private void positionChanged(int newX, int newY) { - if( 0==parentWindowHandle && ( x != newX || y != newY ) ) { - if (DEBUG_IMPLEMENTATION) { - System.out.println(Thread.currentThread().getName()+" Position changed to " + newX + ", " + newY); - } - x = newX; - y = newY; - if(!fullscreen) { - nfs_x=x; - nfs_y=y; - } - if (DEBUG_IMPLEMENTATION) { - System.out.println(" Posted WINDOW_MOVED event"); - } - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); - } - } - - private void focusChanged(boolean focusGained) { - if (focusGained) { - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); - } else { - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); - } - } - private char convertKeyChar(char keyChar) { if (keyChar == '\r') { // Turn these into \n @@ -435,12 +392,12 @@ public class MacWindow extends Window { return keyChar; } - protected void enqueueKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) { int key = convertKeyChar(keyChar); if(DEBUG_IMPLEMENTATION) System.out.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName()); // Note that we send the key char for the key code on this // platform -- we do not get any useful key codes out of the system - super.enqueueKeyEvent(eventType, modifiers, key, keyChar); + super.enqueueKeyEvent(wait, eventType, modifiers, key, keyChar); } private void createWindow(final boolean recreate, final int x, final int y, final int width, final int height, final boolean fullscreen) { @@ -482,9 +439,9 @@ public class MacWindow extends Window { ie.printStackTrace(); } - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_MOVED); + enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_GAINED_FOCUS); } protected static native boolean initIDs0(); diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java index 0d12a4a0a..0c7254376 100755 --- a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java @@ -126,16 +126,11 @@ public class KDWindow extends Window { windowUserData=userData; } - private void sizeChanged(int newWidth, int newHeight) { - width = newWidth; - height = newHeight; - if(!fullscreen) { - nfs_width=width; - nfs_height=height; - } else { + protected void sizeChanged(int newWidth, int newHeight) { + if(fullscreen) { ((KDScreen)screen).setScreenSize(width, height); } - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + super.sizeChanged(newWidth, newHeight); } private long eglWindowHandle; diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java index aedb4ed7d..47f79f46a 100755 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java @@ -36,6 +36,7 @@ package com.jogamp.newt.impl.windows; import javax.media.nativewindow.*; import com.jogamp.newt.*; import com.jogamp.newt.event.*; +import com.jogamp.newt.util.*; public class WindowsWindow extends Window { @@ -216,42 +217,4 @@ public class WindowsWindow extends Window { insets.bottom = bottom; } } - - private void sizeChanged(int newWidth, int newHeight) { - if(width != newWidth || height != newHeight) { - width = newWidth; - height = newHeight; - if(!fullscreen) { - nfs_width=width; - nfs_height=height; - } - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); - } - } - - private void positionChanged(int newX, int newY) { - if( 0==parentWindowHandle && ( x != newX || y != newY ) ) { - x = newX; - y = newY; - if(!fullscreen) { - nfs_x=x; - nfs_y=y; - } - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); - } - } - - /** - * - * @param focusOwner if focusGained is true, focusOwner is the previous - * focus owner, if focusGained is false, focusOwner is the new focus owner - * @param focusGained - */ - private void focusChanged(long focusOwner, boolean focusGained) { - if (focusGained) { - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); - } else { - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); - } - } } diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java index e7fc96019..6890b29fa 100755 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java @@ -71,7 +71,8 @@ public class X11Window extends Window { if(0!=windowHandleClose && null!=getScreen() ) { X11Display display = (X11Display) getScreen().getDisplay(); try { - CloseWindow0(display.getHandle(), windowHandleClose, display.getJavaObjectAtom()); + CloseWindow0(display.getHandle(), windowHandleClose, + display.getJavaObjectAtom(), display.getWindowDeleteAtom()); } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { Exception e = new Exception("closeNative failed - "+Thread.currentThread().getName(), t); @@ -134,7 +135,7 @@ public class X11Window extends Window { private native long CreateWindow0(long parentWindowHandle, long display, int screen_index, long visualID, long javaObjectAtom, long windowDeleteAtom, int x, int y, int width, int height, boolean undecorated); - private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom); + private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom); private native void setVisible0(long display, long windowHandle, boolean visible); private native void setSize0(long display, long windowHandle, int width, int height); private native void setPosSizeDecor0(long parentWindowHandle, long display, int screen_index, long windowHandle, @@ -145,51 +146,6 @@ public class X11Window extends Window { private native void reparentWindow0(long parentWindowHandle, long display, int screen_index, long windowHandle, int x, int y, boolean undecorated, boolean isVisible); - private void windowChanged(int newX, int newY, int newWidth, int newHeight) { - if(width != newWidth || height != newHeight) { - if(DEBUG_IMPLEMENTATION) { - System.err.println("X11Window windowChanged size: "+this.width+"x"+this.height+" -> "+newWidth+"x"+newHeight); - } - width = newWidth; - height = newHeight; - if(!fullscreen) { - nfs_width=width; - nfs_height=height; - } - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); - } - if( 0==parentWindowHandle && ( x != newX || y != newY ) ) { - if(DEBUG_IMPLEMENTATION) { - System.err.println("X11Window windowChanged position: "+this.x+"/"+this.y+" -> "+newX+"x"+newY); - } - x = newX; - y = newY; - if(!fullscreen) { - nfs_x=x; - nfs_y=y; - } - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); - } - } - - /** - * @param focusGained - */ - private void focusChanged(boolean focusGained) { - if (focusGained) { - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); - } else { - enqueueWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); - } - } - - /** - * @param focusGained - */ - private void visibleChanged(boolean visible) { - // FIXME .. this.visible = visible ; - } - private void windowCreated(long windowHandle) { this.windowHandle = windowHandle; } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index e36e516df..e66ed1e34 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -35,6 +35,7 @@ package com.jogamp.newt.opengl; import com.jogamp.newt.*; import com.jogamp.newt.event.*; +import com.jogamp.newt.util.*; import com.jogamp.nativewindow.impl.RecursiveToolkitLock; import javax.media.nativewindow.*; import javax.media.opengl.*; @@ -55,22 +56,34 @@ import java.util.*; */ public class GLWindow extends Window implements GLAutoDrawable { private Window window; - private boolean runPumpMessages; /** * Constructor. Do not call this directly -- use {@link #create()} instead. */ protected GLWindow(Window window) { + this.startTime = System.currentTimeMillis(); this.window = window; this.window.setHandleDestroyNotify(false); - this.runPumpMessages = ( null == getScreen().getDisplay().getEDTUtil() ) ; window.addWindowListener(new WindowAdapter() { + public void windowRepaint(WindowUpdateEvent e) { + if( !windowIsLocked() && null == getAnimator() ) { + display(); + } + } + public void windowResized(WindowEvent e) { sendReshape = true; + if( !windowIsLocked() && null == getAnimator() ) { + display(); + } } public void windowDestroyNotify(WindowEvent e) { - sendDestroy = true; + if( !windowIsLocked() && null == getAnimator() ) { + destroy(); + } else { + sendDestroy = true; + } } }); } @@ -128,31 +141,6 @@ public class GLWindow extends Window implements GLAutoDrawable { return window.getWrappedWindow(); } - /** - * EXPERIMENTAL<br> - * Enable or disables running the {@link Display#pumpMessages} in the {@link #display()} call.<br> - * The default behavior is to run {@link Display#pumpMessages}.<P> - * - * The idea was that in a single threaded environment with one {@link Display} and many {@link Window}'s, - * a performance benefit was expected while disabling the implicit {@link Display#pumpMessages} and - * do it once via {@link GLWindow#runCurrentThreadPumpMessage()} <br> - * This could not have been verified. No measurable difference could have been recognized.<P> - * - * Best performance has been achieved with one GLWindow per thread.<br> - * - * Enabling local pump messages while using the EDT, - * {@link com.jogamp.newt.NewtFactory#setUseEDT(boolean)}, - * will result in an exception. - * - * @deprecated EXPERIMENTAL, semantic is about to be removed after further verification. - */ - public void setRunPumpMessages(boolean onoff) { - if( onoff && null!=getScreen().getDisplay().getEDTUtil() ) { - throw new GLException("GLWindow.setRunPumpMessages(true) - Can't do with EDT on"); - } - runPumpMessages = onoff; - } - protected void createNativeImpl() { shouldNotCallThis(); } @@ -178,7 +166,7 @@ public class GLWindow extends Window implements GLAutoDrawable { // Lock: Have to cover whole workflow (dispose all, context, drawable and window) windowLock(); try { - if(null==window || window.isDestroyed()) { + if( isDestroyed() ) { return; // nop } if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { @@ -186,21 +174,20 @@ public class GLWindow extends Window implements GLAutoDrawable { e1.printStackTrace(); } - if ( null != context && context.isCreated() && null != drawable && drawable.isRealized() ) { - // Catch dispose GLExceptions by GLEventListener, just 'print' them - // so we can continue with the destruction. - try { - helper.invokeGL(drawable, context, disposeAction, null); - } catch (GLException gle) { - gle.printStackTrace(); + if( window.isNativeWindowValid() && null != drawable && drawable.isRealized() ) { + if( null != context && context.isCreated() ) { + // Catch dispose GLExceptions by GLEventListener, just 'print' them + // so we can continue with the destruction. + try { + helper.invokeGL(drawable, context, disposeAction, null); + } catch (GLException gle) { + gle.printStackTrace(); + } + + context.destroy(); + context = null; } - } - if (context != null && null != drawable && drawable.isRealized() ) { - context.destroy(); - context = null; - } - if (drawable != null) { drawable.setRealized(false); drawable = null; } @@ -228,7 +215,7 @@ public class GLWindow extends Window implements GLAutoDrawable { * @see #destroy() */ public void destroy(boolean deep) { - if(!isDestroyed()) { + if( !isDestroyed() ) { runOnEDTIfAvail(true, new DestroyAction(deep)); } } @@ -369,6 +356,13 @@ public class GLWindow extends Window implements GLAutoDrawable { return window.isFullscreen(); } + public void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) { + window.enqueueEvent(wait, event); + } + public boolean consumeEvent(NEWTEvent e) { + return window.consumeEvent(e); + } + public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) { window.addSurfaceUpdatedListener(index, l); } @@ -414,6 +408,12 @@ public class GLWindow extends Window implements GLAutoDrawable { return window.getKeyListeners(); } + public void sendWindowEvent(int eventType) { + window.sendWindowEvent(eventType); + } + public void enqueueWindowEvent(boolean wait, int eventType) { + window.enqueueWindowEvent(wait, eventType); + } public void addWindowListener(int index, WindowListener l) { window.addWindowListener(index, l); } @@ -426,6 +426,12 @@ public class GLWindow extends Window implements GLAutoDrawable { public WindowListener[] getWindowListeners() { return window.getWindowListeners(); } + public void setPropagateRepaint(boolean v) { + window.setPropagateRepaint(v); + } + public void windowRepaint(int x, int y, int width, int height) { + window.windowRepaint(x, y, width, height); + } public String toString() { return "NEWT-GLWindow[ \n\tHelper: "+helper+", \n\tDrawable: "+drawable + /** ", \n\tWindow: "+window+", \n\tFactory: "+factory+ */ "]"; @@ -483,8 +489,17 @@ public class GLWindow extends Window implements GLAutoDrawable { helper.removeGLEventListener(listener); } + public void setAnimator(Thread animator) { + helper.setAnimator(animator); + window.setPropagateRepaint(null==animator); + } + + public Thread getAnimator() { + return helper.getAnimator(); + } + public void invoke(boolean wait, GLRunnable glRunnable) { - helper.invoke(wait, glRunnable); + helper.invoke(this, wait, glRunnable); } public void display() { @@ -494,28 +509,26 @@ public class GLWindow extends Window implements GLAutoDrawable { public void display(boolean forceReshape) { if( null == window ) { return; } + if(sendDestroy || ( null!=window && window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED ) ) { + sendDestroy=false; + destroy(); + return; + } + if( null == context && window.isVisible() ) { // retry native window and drawable/context creation setVisible(true); } - if( window.isNativeWindowValid() && null != context ) { - if(runPumpMessages) { - window.getScreen().getDisplay().pumpMessages(); + if( window.isVisible() && window.isNativeWindowValid() && null != context ) { + if(forceReshape) { + sendReshape = true; } - if(sendDestroy || window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED) { - destroy(); - sendDestroy=false; - } else if ( window.isVisible() ) { - if(forceReshape) { - sendReshape = true; - } - windowLock(); - try{ - helper.invokeGL(drawable, context, displayAction, initAction); - } finally { - windowUnlock(); - } + windowLock(); + try{ + helper.invokeGL(drawable, context, displayAction, initAction); + } finally { + windowUnlock(); } } } @@ -546,7 +559,7 @@ public class GLWindow extends Window implements GLAutoDrawable { public void run() { // Lock: Locked Surface/Window by MakeCurrent/Release helper.init(GLWindow.this); - startTime = System.currentTimeMillis(); + startTime = System.currentTimeMillis(); // overwrite startTime to real init one curTime = startTime; if(perfLog) { lastCheck = startTime; @@ -560,10 +573,7 @@ public class GLWindow extends Window implements GLAutoDrawable { public void run() { // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release if (sendReshape) { - int width = getWidth(); - int height = getHeight(); - getGL().glViewport(0, 0, width, height); - helper.reshape(GLWindow.this, 0, 0, width, height); + helper.reshape(GLWindow.this, 0, 0, getWidth(), getHeight()); sendReshape = false; } @@ -589,8 +599,8 @@ public class GLWindow extends Window implements GLAutoDrawable { private DisplayAction displayAction = new DisplayAction(); public long getStartTime() { return startTime; } - public long getCurrentTime() { return curTime; } - public long getDuration() { return curTime-startTime; } + public long getCurrentTime() { curTime = System.currentTimeMillis(); return curTime; } + public long getDuration() { return getCurrentTime()-startTime; } public int getTotalFrames() { return totalFrames; } private long startTime = 0; diff --git a/src/newt/classes/com/jogamp/newt/Insets.java b/src/newt/classes/com/jogamp/newt/util/Insets.java index e440892f0..068cc1dfb 100644 --- a/src/newt/classes/com/jogamp/newt/Insets.java +++ b/src/newt/classes/com/jogamp/newt/util/Insets.java @@ -30,7 +30,7 @@ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * */ -package com.jogamp.newt; +package com.jogamp.newt.util; /** * Simple class representing insets. diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 5e3311d3b..a1dab2678 100755 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -109,15 +109,16 @@ #define STD_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) -static jmethodID sizeChangedID = NULL; static jmethodID insetsChangedID = NULL; +static jmethodID sizeChangedID = NULL; static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; +static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; -static jmethodID enqueueMouseEventID = NULL; -static jmethodID enqueueKeyEventID = NULL; -static jmethodID sendPaintEventID = NULL; +static jmethodID windowRepaintID = NULL; +static jmethodID sendMouseEventID = NULL; +static jmethodID sendKeyEventID = NULL; static RECT* UpdateInsets(JNIEnv *env, HWND hwnd, jobject window); @@ -506,7 +507,7 @@ static int WmChar(JNIEnv *env, jobject window, UINT character, UINT repCnt, if (character == VK_RETURN) { character = J_VK_ENTER; } - (*env)->CallVoidMethod(env, window, enqueueKeyEventID, + (*env)->CallVoidMethod(env, window, sendKeyEventID, (jint) EVENT_KEY_TYPED, GetModifiers(), (jint) -1, @@ -551,7 +552,7 @@ static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, character = WindowsKeyToJavaChar(wkey, modifiers, SAVE); */ - (*env)->CallVoidMethod(env, window, enqueueKeyEventID, + (*env)->CallVoidMethod(env, window, sendKeyEventID, (jint) EVENT_KEY_PRESSED, modifiers, (jint) jkey, @@ -562,7 +563,7 @@ static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, WM_KEYDOWN. */ if (jkey == J_VK_DELETE) { - (*env)->CallVoidMethod(env, window, enqueueKeyEventID, + (*env)->CallVoidMethod(env, window, sendKeyEventID, (jint) EVENT_KEY_TYPED, GetModifiers(), (jint) -1, @@ -586,7 +587,7 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, character = WindowsKeyToJavaChar(wkey, modifiers, SAVE); */ - (*env)->CallVoidMethod(env, window, enqueueKeyEventID, + (*env)->CallVoidMethod(env, window, sendKeyEventID, (jint) EVENT_KEY_RELEASED, modifiers, (jint) jkey, @@ -706,6 +707,7 @@ static void WmSize(JNIEnv *env, HWND wnd, jobject window, UINT type) static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) { + LRESULT res = 0; int useDefWindowProc = 0; JNIEnv *env = NULL; jobject window = NULL; @@ -799,7 +801,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, case WM_LBUTTONDOWN: NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. - (*env)->CallVoidMethod(env, window, enqueueMouseEventID, + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -808,7 +810,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_LBUTTONUP: - (*env)->CallVoidMethod(env, window, enqueueMouseEventID, + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -818,7 +820,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, case WM_MBUTTONDOWN: NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. - (*env)->CallVoidMethod(env, window, enqueueMouseEventID, + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -827,7 +829,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_MBUTTONUP: - (*env)->CallVoidMethod(env, window, enqueueMouseEventID, + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -837,7 +839,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, case WM_RBUTTONDOWN: NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. - (*env)->CallVoidMethod(env, window, enqueueMouseEventID, + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -846,7 +848,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_RBUTTONUP: - (*env)->CallVoidMethod(env, window, enqueueMouseEventID, + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -855,7 +857,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_MOUSEMOVE: - (*env)->CallVoidMethod(env, window, enqueueMouseEventID, + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -871,7 +873,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, eventPt.x = x; eventPt.y = y; ScreenToClient(wnd, &eventPt); - (*env)->CallVoidMethod(env, window, enqueueMouseEventID, + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_WHEEL_MOVED, GetModifiers(), (jint) eventPt.x, (jint) eventPt.y, @@ -881,17 +883,19 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, } case WM_SETFOCUS: - (*env)->CallVoidMethod(env, window, focusChangedID, - (jlong)wParam, JNI_TRUE); + (*env)->CallVoidMethod(env, window, focusChangedID, JNI_TRUE); useDefWindowProc = 1; break; case WM_KILLFOCUS: - (*env)->CallVoidMethod(env, window, focusChangedID, - (jlong)wParam, JNI_FALSE); + (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE); useDefWindowProc = 1; break; + case WM_SHOWWINDOW: + (*env)->CallVoidMethod(env, window, visibleChangedID, wParam==TRUE?JNI_TRUE:JNI_FALSE); + break; + case WM_MOVE: DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d\n", wnd, (int)LOWORD(lParam), (int)HIWORD(lParam)); (*env)->CallVoidMethod(env, window, positionChangedID, @@ -901,21 +905,24 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, case WM_PAINT: { RECT r; - if (GetUpdateRect(wnd, &r, FALSE)) { - if ((r.right-r.left) > 0 && (r.bottom-r.top) > 0) { - (*env)->CallVoidMethod(env, window, sendPaintEventID, - 0, r.left, r.top, r.right-r.left, r.bottom-r.top); + 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, r.left, r.top, width, height); } ValidateRect(wnd, &r); - useDefWindowProc = 0; - } else { - useDefWindowProc = 1; + */ } break; } case WM_ERASEBKGND: // ignore erase background + (*env)->CallVoidMethod(env, window, windowRepaintID, 0, 0, -1, -1); useDefWindowProc = 0; + res = 1; break; @@ -926,7 +933,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, if (useDefWindowProc) return DefWindowProc(wnd, message, wParam, lParam); - return 0; + return res; } /* @@ -1052,24 +1059,26 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getHeight JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initIDs0 (JNIEnv *env, jclass clazz) { - sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V"); + sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); - focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(JZ)V"); + focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); + visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); - enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(IIIIII)V"); - enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(IIIC)V"); - sendPaintEventID = (*env)->GetMethodID(env, clazz, "sendPaintEvent", "(IIIII)V"); - if (sizeChangedID == NULL || - insetsChangedID == NULL || + windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(IIII)V"); + sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); + sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + if (insetsChangedID == NULL || + sizeChangedID == NULL || positionChangedID == NULL || focusChangedID == NULL || + visibleChangedID == NULL || windowDestroyNotifyID == NULL || windowDestroyedID == NULL || - enqueueMouseEventID == NULL || - sendPaintEventID == NULL || - enqueueKeyEventID == NULL) + windowRepaintID == NULL || + sendMouseEventID == NULL || + sendKeyEventID == NULL) { return JNI_FALSE; } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index a521d2dbd..dbf833633 100755 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -151,14 +151,16 @@ static const char * const ClazzNameNewtWindow = "com/jogamp/newt/Window"; static jclass newtWindowClz=NULL; -static jmethodID windowChangedID = NULL; +static jmethodID sizeChangedID = NULL; +static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; +static jmethodID windowRepaintID = NULL; static jmethodID windowCreatedID = NULL; -static jmethodID enqueueMouseEventID = NULL; -static jmethodID enqueueKeyEventID = NULL; +static jmethodID sendMouseEventID = NULL; +static jmethodID sendKeyEventID = NULL; static jmethodID displayCompletedID = NULL; @@ -291,8 +293,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_CompleteDisplay0 * Window */ -// #define WINDOW_EVENT_MASK ( FocusChangeMask | StructureNotifyMask | ExposureMask | VisibilityNotify ) -#define WINDOW_EVENT_MASK ( FocusChangeMask | StructureNotifyMask | VisibilityNotify ) +#define WINDOW_EVENT_MASK ( FocusChangeMask | StructureNotifyMask | ExposureMask ) static int putPtrIn32Long(unsigned long * dst, uintptr_t src) { int i=0; @@ -505,31 +506,37 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages switch(evt.type) { case ButtonPress: NewtWindows_requestFocus1 ( dpy, evt.xany.window ); - (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, (jint) EVENT_MOUSE_PRESSED, + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, + (jint) EVENT_MOUSE_PRESSED, (jint) evt.xbutton.state, (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); break; case ButtonRelease: - (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, (jint) EVENT_MOUSE_RELEASED, + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, + (jint) EVENT_MOUSE_RELEASED, (jint) evt.xbutton.state, (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); break; case MotionNotify: - (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, (jint) EVENT_MOUSE_MOVED, + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, + (jint) EVENT_MOUSE_MOVED, (jint) evt.xmotion.state, (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/); break; case KeyPress: - (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, (jint) EVENT_KEY_PRESSED, + (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, + (jint) EVENT_KEY_PRESSED, (jint) evt.xkey.state, X11KeySym2NewtVKey(keySym), (jchar) keyChar); break; case KeyRelease: - (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, (jint) EVENT_KEY_RELEASED, + (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, + (jint) EVENT_KEY_RELEASED, (jint) evt.xkey.state, X11KeySym2NewtVKey(keySym), (jchar) keyChar); - (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, (jint) EVENT_KEY_TYPED, + (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, + (jint) EVENT_KEY_TYPED, (jint) evt.xkey.state, (jint) -1, (jchar) keyChar); break; @@ -546,9 +553,10 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages (unsigned int)evt.xconfigure.window, (unsigned int)evt.xconfigure.event, (unsigned int)evt.xconfigure.above, evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height, evt.xconfigure.override_redirect); - (*env)->CallVoidMethod(env, jwindow, windowChangedID, - (jint) evt.xconfigure.x, (jint) evt.xconfigure.y, + (*env)->CallVoidMethod(env, jwindow, sizeChangedID, (jint) evt.xconfigure.width, (jint) evt.xconfigure.height); + (*env)->CallVoidMethod(env, jwindow, positionChangedID, + (jint) evt.xconfigure.x, (jint) evt.xconfigure.y); break; case ClientMessage: if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) { @@ -568,25 +576,28 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE); break; + case Expose: + DBG_PRINT( "X11: event . Expose call 0x%X %d/%d %dx%d\n", (unsigned int)evt.xexpose.window, + evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height); + + if (evt.xexpose.width > 0 && evt.xexpose.height > 0) { + (*env)->CallVoidMethod(env, jwindow, windowRepaintID, + evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height); + } + break; + case MapNotify: DBG_PRINT( "X11: event . MapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); - // FIXME (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE); + (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE); break; case UnmapNotify: DBG_PRINT( "X11: event . UnmapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); - // FIXME (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE); + (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE); break; // unhandled events .. yet .. - case VisibilityNotify: - DBG_PRINT( "X11: event . VisibilityNotify call 0x%X\n", (unsigned int)evt.xvisibility.window); - break; - case Expose: - DBG_PRINT( "X11: event . Expose call 0x%X\n", (unsigned int)evt.xexpose.window); - /* FIXME: Might want to send a repaint event .. */ - break; default: DBG_PRINT("X11: event . unhandled %d 0x%X call 0x%X\n", evt.type, evt.type, (unsigned int)evt.xunmap.window); } @@ -653,23 +664,27 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getHeight0 JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 (JNIEnv *env, jclass clazz) { - windowChangedID = (*env)->GetMethodID(env, clazz, "windowChanged", "(IIII)V"); + sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); + positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); + windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(IIII)V"); windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V"); - enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(IIIIII)V"); - enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(IIIC)V"); + sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); + sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); - if (windowChangedID == NULL || + if (sizeChangedID == NULL || + positionChangedID == NULL || focusChangedID == NULL || visibleChangedID == NULL || windowDestroyNotifyID == NULL || windowDestroyedID == NULL || + windowRepaintID == NULL || windowCreatedID == NULL || - enqueueMouseEventID == NULL || - enqueueKeyEventID == NULL) { + sendMouseEventID == NULL || + sendKeyEventID == NULL) { return JNI_FALSE; } return JNI_TRUE; @@ -749,12 +764,17 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 pVisualQuery=NULL; } - attrMask = ( CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect ) ; + attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixel | + CWBorderPixel | CWColormap | CWOverrideRedirect ) ; memset(&xswa, 0, sizeof(xswa)); xswa.override_redirect = ( 0 != parent ) ? True : False ; xswa.border_pixel = 0; xswa.background_pixel = 0; + 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 */ + xswa.colormap = XCreateColormap(dpy, windowParent, // XRootWindow(dpy, scrn_idx), visual, @@ -781,6 +801,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 setJavaWindowProperty(env, dpy, window, javaObjectAtom, (*env)->NewGlobalRef(env, obj)); + // XClearWindow(dpy, window); XSync(dpy, False); { @@ -806,7 +827,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0 - (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom) + (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong wmDeleteAtom) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; @@ -827,14 +848,19 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0 _throwNewRuntimeException(dpy, env, "Internal Error .. Window global ref not the same!"); return; } - (*env)->DeleteGlobalRef(env, jwindow); XSync(dpy, False); XSelectInput(dpy, w, 0); XUnmapWindow(dpy, w); + + // Drain all events related to this window .. + JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages0(env, obj, display, javaObjectAtom, wmDeleteAtom); + XDestroyWindow(dpy, w); XSync(dpy, False); + (*env)->DeleteGlobalRef(env, jwindow); + DBG_PRINT( "X11: CloseWindow END\n"); (*env)->CallVoidMethod(env, obj, windowDestroyedID); @@ -922,6 +948,11 @@ static void NewtWindows_reparentWindow DBG_PRINT( "X11: reparentWindow dpy %p, parent %p/%p, win %p, %d/%d undec %d\n", (void*)dpy, (void*) jparent, (void*)parent, (void*)w, x, y, undecorated); + // don't propagate events during reparenting + // long orig_xevent_mask = xwa->your_event_mask ; + /* XSelectInput(dpy, w, orig_xevent_mask & ~ ( StructureNotifyMask ) ); + XSync(dpy, False); */ + if(0 != jparent) { // move into parent .. NewtWindows_setDecorations (dpy, w, False); @@ -955,6 +986,14 @@ static void NewtWindows_reparentWindow XSync(dpy, False); } + /* XSelectInput(dpy, w, orig_xevent_mask); + XSync(dpy, False); */ + + if(JNI_TRUE == isVisible) { + NewtWindows_requestFocus0 ( dpy, w, xwa ); + XSync(dpy, False); + } + DBG_PRINT( "X11: reparentWindow X\n"); } @@ -993,12 +1032,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 xwc.width=width; xwc.height=height; XConfigureWindow(dpy, w, CWX|CWY|CWWidth|CWHeight, &xwc); - - if(JNI_TRUE == isVisible) { - XGetWindowAttributes(dpy, w, &xwa); - NewtWindows_requestFocus0 ( dpy, w, &xwa ); - XSync(dpy, False); - } } /* @@ -1039,7 +1072,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0 JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_requestFocus0 (JNIEnv *env, jobject obj, jlong display, jlong window) { - NewtWindows_requestFocus ( (Display *) (intptr_t) display, (Window)window ) ; + NewtWindows_requestFocus1 ( (Display *) (intptr_t) display, (Window)window ) ; } /* |