diff options
author | Sven Gothel <[email protected]> | 2010-05-28 16:53:08 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-05-28 16:53:08 +0200 |
commit | 811bd23ed37e392abb349f850a0b1dac635d021e (patch) | |
tree | c4faf8f5728eabd0fd9ed8a28816ab361984a9b7 /src/junit | |
parent | c787f50d77e2491eb0d8201d534a6fa4885a929e (diff) |
NEWT: Fix AWT Parenting ; Multithreading Issues ; Semantics: destroy(), .. ; Misc.
Due to incapabilities of the previous AWT/NEWT reparenting
the implementation and spec had to be changed to support this feature.
See the first 2 comments below.
- Tested on GNU/Linux (OK), Windows (a few bugs left)
-
TODO:
- Clarify the size/layout issue, ie who is responsible etc
In the test, incl AWT/NEWT, we set the size on the GLWindow
and ie pack the AWT Frame.
- Fix remaining [Windows] bugs ..
- Fix/Implement MacOSX port ..
Fix AWT/NEWT reparenting:
===========================
- Now NewtFactory's createWindow() method for parenting handles NativeWindow only
and is no more responsible for creating a child window upon an AWT Component.
See class com.jogamp.newt.awt.NewtCanvasAWT for NEWT/AWT parenting.
- New com.jogamp.newt.awt.NewtCanvasAWT, responsible for handling
AWT's reparent events via addNotify/removeNotify.
Reparenting is implemented via the new NEWT Window's reparentWindow() method.
Also sets the background erase to false, if supported.
- Fix zero size semantics in Window (setSize/setVisible)
Since a zero size window is not supported by many compoenent (Windowing system, OpenGL, ..)
we use the visibility methodology to not show a 0x0 window. See Javadoc.
AWT components may start with zero size.
- New NEWT Window: reparentWindow(NativeWindow newParent, Screen newScreen)
Allowing to change the parent of a window. Similar with the fullscreen toggle,
but without size/position change.
Native reparenting allows to keep alive the native
window while changing the container, hence it is preferred to a destroy/create cycle.
To benefit from the native reparenting, a NEWT implementation has to implement
'protected boolean reparentWindowImpl(long newWindowHandle)'
and return true, otherwise reparenting will be 'emulated' via
the expensive destroy/create cycle.
- NEWT's Window references all of it's children, if any
- NEWT's Window propagates setVisible/destroy actions to it's children.
- Fix NEWT's destroy() semantics.
A call of destroy() or destroy(false) shall only result in the destruction of the
native window (handle) nothing more. A subsequent setVisible(true) shall allow
the complete recreation of the Window into a usable state.
A call of destroy(true) destroys all resources the Window holds,
may include Screen/Display and OpenGL resources in case of GLWindow.
This is necessary to allow proper reparenting, where a native window may become
destroyed, but should be recreated via setVisible(true) later on.
- Fix NEWT set[Size|Position|Fullscreen|Visible] synchronization.
Use a recursive lock instead of the Window instance, otherwise arbitrary Window access
via AWT's EDT, NEWT's EDT or other threads can block.
Also removed a use pattern like:
key.lock()
try {
EDT.invoke(action());
} finally {
key.unlock();
}
Where action() itself uses the same lock object (here key), the result is a deadlock.
NativeWindow Changes:
======================
- We can use XInitThreads() now (concurrent threading support)
in combination with AWT.
Might have been some async in our NEWT locking in regards to AWT (sync()),
and the X11 Display changes made in c787f50d77e2491eb0d8201d534a6fa4885a929e.
- NativeWindow's window handle is _not_ transient like surface handle,
fixed documentation.
JOGL Changes:
=============
- New 'isRealized()' method in GLDrawable.
-
Misc Fixes
============
- Fix NEWT set[Size|Position|Fullscreen|Visible] duplicate code
Due to pure abstract signatures, the set[Size|Position|Fullscreen|Visible]
implementations of X11, OSX, .. contained duplicate code and state handling (size, pos, ..).
These are now decoupled, ie generic set[Size|Position|Fullscreen|Visible] implementations
calling simple set[Size|Position|Fullscreen|Visible]Impl implementations.
- Fix NEWT: Renamed setAutoDrawableClient(boolean) to setHandleDestroyNotify(boolean)
The semantic of
setAutoDrawableClient(boolean) defaults to false
was too complicated and specific, hence changed to
setHandleDestroyNotify(boolean) defaults to true
since its more clear and the name refers the window itself..
- Fix NEWT: Removed GLWindow's unused global window list
- Fix NEWT: Remove Window's unused event mask
- Rename com.jogamp.newt.impl.awt.AWTNewtFactory -> com.jogamp.newt.awt.NewtFactoryAWT
Diffstat (limited to 'src/junit')
8 files changed, 1188 insertions, 190 deletions
diff --git a/src/junit/com/jogamp/test/junit/newt/KeyAction.java b/src/junit/com/jogamp/test/junit/newt/KeyAction.java index 29b3d2ee2..3ca12a840 100644 --- a/src/junit/com/jogamp/test/junit/newt/KeyAction.java +++ b/src/junit/com/jogamp/test/junit/newt/KeyAction.java @@ -33,7 +33,6 @@ package com.jogamp.test.junit.newt; -import com.jogamp.opengl.util.Animator; import com.jogamp.newt.event.*; class KeyAction extends KeyAdapter { diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java new file mode 100755 index 000000000..b96e74182 --- /dev/null +++ b/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java @@ -0,0 +1,220 @@ +/* + * 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.opengl.*; +import java.io.IOException; + +import com.jogamp.test.junit.util.MiscUtils; +import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; + +public class TestGLWindows01NEWT { + static GLProfile glp; + static int width, height; + static long duration = 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); + 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); + + GLEventListener demo = new Gears(); + setDemoFields(demo, glWindow); + glWindow.addGLEventListener(demo); + + return glWindow; + } + + static void destroyWindow(GLWindow glWindow, boolean deep) { + if(null!=glWindow) { + glWindow.destroy(deep); + } + } + + @Test + public void testWindowNativeRecreate01Simple() throws InterruptedException { + GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + GLWindow window = createWindow(null, caps, width, height, true /* onscreen */, false /* undecorated */); + + window.display(); + window.destroy(); + Assert.assertEquals(false,window.isNativeWindowValid()); + Assert.assertEquals(true,window.isVisible()); + + window.display(); + Assert.assertEquals(true,window.isNativeWindowValid()); + + Animator animator = new Animator(window); + animator.start(); + while(animator.isAnimating() && animator.getDuration()<duration) { + Thread.sleep(100); + } + animator.stop(); + destroyWindow(window, true); + } + + @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()<duration) { + 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()<duration) { + 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 display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + + GLWindow window1 = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); + GLWindow window2 = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); + Animator animator1 = new Animator(window1); + animator1.start(); + Animator animator2 = new Animator(window2); + animator2.start(); + while(animator1.isAnimating() && animator1.getDuration()<duration) { + Thread.sleep(100); + } + animator2.stop(); + animator1.stop(); + destroyWindow(window2, false); + 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); + } + } + + public static void main(String args[]) throws IOException { + String tstname = TestGLWindows01NEWT.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/TestParenting01AWT.java b/src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java index 2c0dc31c1..39bd84e75 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestParenting01AWT.java @@ -47,15 +47,17 @@ import org.junit.Test; import java.awt.Button; import java.awt.BorderLayout; import java.awt.Canvas; -import java.awt.Component; import java.awt.Frame; +import java.awt.Dimension; import javax.media.opengl.*; import javax.media.nativewindow.*; +import com.jogamp.opengl.util.Animator; import com.jogamp.newt.*; import com.jogamp.newt.event.*; import com.jogamp.newt.opengl.*; +import com.jogamp.newt.awt.NewtCanvasAWT; import java.io.IOException; @@ -66,124 +68,293 @@ import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01AWT { static int width, height; static long durationPerTest = 500; + static long waitReparent = 0; + static GLCapabilities glCaps; @BeforeClass public static void initClass() { width = 640; height = 480; + glCaps = new GLCapabilities(null); } @Test - public void testWindowParenting01NewtChildOnAWTParentLayouted() throws InterruptedException { - runNewtChildOnAWTParent(true, false); - } + public void testWindowParenting01CreateVisibleDestroy1() throws InterruptedException { + int x = 0; + int y = 0; - @Test - public void testWindowParenting02NewtChildOnAWTParentLayoutedDef() throws InterruptedException { - runNewtChildOnAWTParent(true, true); - } + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); - @Test - public void testWindowParenting03NewtChildOnAWTParentDirect() throws InterruptedException { - runNewtChildOnAWTParent(false, false); + GLWindow glWindow1 = GLWindow.create(glCaps); + Assert.assertNotNull(glWindow1); + Assert.assertEquals(false, glWindow1.isVisible()); + Assert.assertEquals(false, glWindow1.isNativeWindowValid()); + Assert.assertNull(glWindow1.getParentNativeWindow()); + glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy"); + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, glWindow1, false); + glWindow1.addGLEventListener(demo1); + glWindow1.setSize(600, 300); + + NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); + Assert.assertNotNull(newtCanvasAWT); + Assert.assertEquals(false, glWindow1.isVisible()); + 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.pack(); + + // visible test + frame.setVisible(true); + Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); + + Animator animator1 = new Animator(glWindow1); + animator1.start(); + while(animator1.isAnimating() && animator1.getDuration()<durationPerTest) { + Thread.sleep(100); + } + animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); + + frame.setVisible(false); + Assert.assertEquals(false, glWindow1.isDestroyed()); + + frame.setVisible(true); + Assert.assertEquals(false, glWindow1.isDestroyed()); + + frame.remove(newtCanvasAWT); + Assert.assertNull(glWindow1.getParentNativeWindow()); + Assert.assertEquals(false, glWindow1.isDestroyed()); + + frame.dispose(); + Assert.assertEquals(false, glWindow1.isDestroyed()); + + glWindow1.destroy(true); + Assert.assertEquals(true, glWindow1.isDestroyed()); } @Test - public void testWindowParenting04NewtChildOnAWTParentDirectDef() throws InterruptedException { - runNewtChildOnAWTParent(false, true); - } + public void testWindowParenting02CreateVisibleDestroy2Defered() throws InterruptedException { + int x = 0; + int y = 0; + + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); + + GLWindow glWindow1 = GLWindow.create(glCaps); + Assert.assertNotNull(glWindow1); + Assert.assertEquals(false, glWindow1.isVisible()); + Assert.assertEquals(false, glWindow1.isNativeWindowValid()); + Assert.assertNull(glWindow1.getParentNativeWindow()); + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, glWindow1, false); + glWindow1.addGLEventListener(demo1); + glWindow1.setSize(600, 300); + + NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); + Assert.assertNotNull(newtCanvasAWT); + Assert.assertEquals(false, glWindow1.isVisible()); + Assert.assertEquals(false, glWindow1.isNativeWindowValid()); + Assert.assertNull(glWindow1.getParentNativeWindow()); - public void runNewtChildOnAWTParent(boolean useLayout, boolean deferredPeer) throws InterruptedException { Frame frame = new Frame("AWT Parent Frame"); Assert.assertNotNull(frame); - Component overlayedAWTComponent = null; - - if(useLayout) { - overlayedAWTComponent = new Canvas(); - - frame.setLayout(new BorderLayout()); - frame.add(new Button("North"), BorderLayout.NORTH); - frame.add(new Button("South"), BorderLayout.SOUTH); - frame.add(new Button("East"), BorderLayout.EAST); - frame.add(new Button("West"), BorderLayout.WEST); - if(!deferredPeer) { - frame.add(overlayedAWTComponent, BorderLayout.CENTER); - } + frame.setSize(width, height); + + // visible test + frame.setVisible(true); + + frame.add(newtCanvasAWT); + Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); + frame.pack(); - } else { - overlayedAWTComponent = frame; + Animator animator1 = new Animator(glWindow1); + animator1.start(); + while(animator1.isAnimating() && animator1.getDuration()<durationPerTest) { + Thread.sleep(100); } + animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); + + frame.dispose(); + glWindow1.destroy(true); + } + + @Test + public void testWindowParenting03ReparentNewtWin2Top() throws InterruptedException { + int x = 0; + int y = 0; + + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); + + GLWindow glWindow1 = GLWindow.create(glCaps); + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, glWindow1, false); + glWindow1.addGLEventListener(demo1); + glWindow1.setSize(600, 300); + + NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); - Assert.assertNotNull(overlayedAWTComponent); + Frame frame = new Frame("AWT Parent Frame"); frame.setSize(width, height); - if(!deferredPeer) { - // ensure native peers are valid and component is displayable - frame.setVisible(true); + frame.setLocation(640, 480); + frame.setVisible(true); + + frame.add(newtCanvasAWT); + Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); + frame.pack(); + + Animator animator1 = new Animator(glWindow1); + animator1.start(); + + int state = 0; + while(animator1.isAnimating() && animator1.getDuration()<3*durationPerTest) { + Thread.sleep(durationPerTest); + switch(state) { + case 0: + glWindow1.reparentWindow(null, null); + Assert.assertEquals(true, glWindow1.isNativeWindowValid()); + Assert.assertNull(glWindow1.getParentNativeWindow()); + break; + case 1: + glWindow1.reparentWindow(newtCanvasAWT.getNativeWindow(), null); + Assert.assertEquals(true, glWindow1.isNativeWindowValid()); + Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); + break; + } + state++; } + frame.dispose(); + glWindow1.destroy(true); + } + + @Test + public void testWindowParenting04ReparentNewtWin2TopLayouted() throws InterruptedException { + int x = 0; + int y = 0; + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); - GLCapabilities caps = new GLCapabilities(null); - Assert.assertNotNull(caps); + GLWindow glWindow1 = GLWindow.create(glCaps); + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, glWindow1, false); + glWindow1.addGLEventListener(demo1); + glWindow1.setSize(600, 300); - GLWindow glWindow = GLWindow.create(overlayedAWTComponent, caps); - Assert.assertNotNull(glWindow); - Assert.assertEquals(overlayedAWTComponent.isVisible(),glWindow.isVisible()); - if(!deferredPeer) { - Assert.assertTrue(0!=glWindow.getWindowHandle()); - } else { - Assert.assertTrue(0==glWindow.getWindowHandle()); - } - glWindow.setTitle("NEWT - CHILD"); - glWindow.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); - glWindow.addWindowListener(new TraceWindowAdapter(new WindowAction(eventFifo))); + NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); + + Frame frame = new Frame("AWT Parent Frame"); + frame.setLayout(new BorderLayout()); + frame.add(new Button("North"), BorderLayout.NORTH); + frame.add(new Button("South"), BorderLayout.SOUTH); + frame.add(new Button("East"), BorderLayout.EAST); + frame.add(new Button("West"), BorderLayout.WEST); + frame.setSize(width, height); + frame.setLocation(640, 480); + frame.setVisible(true); - if(deferredPeer) { - if(useLayout) { - frame.add(overlayedAWTComponent, BorderLayout.CENTER); + frame.add(newtCanvasAWT, BorderLayout.CENTER); + Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); + frame.pack(); + + Animator animator1 = new Animator(glWindow1); + animator1.start(); + + int state = 0; + while(animator1.isAnimating() && animator1.getDuration()<3*durationPerTest) { + Thread.sleep(durationPerTest); + switch(state) { + case 0: + glWindow1.reparentWindow(null, null); + Assert.assertEquals(true, glWindow1.isNativeWindowValid()); + Assert.assertNull(glWindow1.getParentNativeWindow()); + break; + case 1: + glWindow1.reparentWindow(newtCanvasAWT.getNativeWindow(), null); + Assert.assertEquals(true, glWindow1.isNativeWindowValid()); + Assert.assertEquals(newtCanvasAWT.getNativeWindow(),glWindow1.getParentNativeWindow()); + break; } - frame.setVisible(true); // should have native peers after this - and all childs shall be visible! + state++; } - GLEventListener demo = new Gears(); - setDemoFields(demo, glWindow, false); - glWindow.addGLEventListener(demo); - - long duration = durationPerTest; - long step = 20; - NEWTEvent event; - - while (duration>0 && !glWindow.isDestroyed()) { - glWindow.display(); - Thread.sleep(step); - duration -= step; - - while( null != ( event = (NEWTEvent) eventFifo.get() ) ) { - Window source = (Window) event.getSource(); - if(event instanceof KeyEvent) { - KeyEvent keyEvent = (KeyEvent) event; - switch(keyEvent.getKeyChar()) { - case 'q': - glWindow.destroy(); - break; - case 'f': - source.setFullscreen(!source.isFullscreen()); - break; - } - } + frame.dispose(); + glWindow1.destroy(true); + } + + @Test + public void testWindowParenting05ReparentAWTWinHopFrame2Frame() throws InterruptedException { + int x = 0; + int y = 0; + + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); + + GLWindow glWindow1 = GLWindow.create(glCaps); + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, glWindow1, false); + glWindow1.addGLEventListener(demo1); + glWindow1.setSize(600, 300); + + 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()); + frame1.pack(); + + Animator animator1 = new Animator(glWindow1); + animator1.start(); + + int state = 0; + while(animator1.isAnimating() && animator1.getDuration()<3*durationPerTest) { + Thread.sleep(durationPerTest); + switch(state) { + case 0: + frame1.remove(newtCanvasAWT); + frame2.add(newtCanvasAWT, BorderLayout.CENTER); + frame2.pack(); + break; + case 1: + frame2.remove(newtCanvasAWT); + frame1.add(newtCanvasAWT, BorderLayout.CENTER); + frame1.pack(); + break; } + state++; } - glWindow.destroy(); - if(useLayout) { - frame.remove(overlayedAWTComponent); - } - frame.dispose(); + + frame1.dispose(); + frame2.dispose(); + glWindow1.destroy(true); } public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) { Assert.assertNotNull(demo); Assert.assertNotNull(glWindow); - Window window = glWindow.getWindow(); + Window window = glWindow.getInnerWindow(); if(debug) { MiscUtils.setFieldIfExists(demo, "glDebug", true); MiscUtils.setFieldIfExists(demo, "glTrace", true); @@ -193,8 +364,22 @@ public class TestParenting01AWT { } } + static int atoi(String a) { + int i=0; + try { + durationPerTest = Integer.parseInt(a); + } catch (Exception ex) { ex.printStackTrace(); } + return i; + } + public static void main(String args[]) throws IOException { - durationPerTest = 5000; + 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 = TestParenting01AWT.class.getName(); org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { tstname, diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java index ee135e83e..37de52139 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestParenting01NEWT.java @@ -48,6 +48,7 @@ import javax.media.opengl.*; import javax.media.nativewindow.*; import javax.media.nativewindow.*; +import com.jogamp.opengl.util.Animator; import com.jogamp.newt.*; import com.jogamp.newt.event.*; import com.jogamp.newt.opengl.*; @@ -61,136 +62,202 @@ import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01NEWT { static int width, height; static long durationPerTest = 500; + static long waitReparent = 0; + static GLCapabilities glCaps; @BeforeClass public static void initClass() { width = 640; height = 480; + glCaps = new GLCapabilities(null); } - static Window createWindow(Screen screen, Capabilities caps) { - Assert.assertNotNull(caps); - Window window = NewtFactory.createWindow(screen, caps, false) ; - Assert.assertNotNull(window); - return window; - } + @Test + public void testWindowParenting01CreateVisibleDestroy() throws InterruptedException { + int x = 0; + int y = 0; - static Window createWindow(NativeWindow parent, Capabilities caps) { - Assert.assertNotNull(caps); - Window window = NewtFactory.createWindow(parent, caps, true); - Assert.assertNotNull(window); - return window; - } + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); - static void destroyWindow(Display display, Screen screen, Window window, GLWindow glWindow) { - if(null!=glWindow) { - glWindow.destroy(); - } - if(null!=window) { - window.destroy(); - } - if(null!=screen) { - screen.destroy(); - } - if(null!=display) { - display.destroy(); + GLWindow glWindow1 = GLWindow.create(glCaps); + Assert.assertNotNull(glWindow1); + Assert.assertEquals(false, glWindow1.isVisible()); + Assert.assertEquals(false, glWindow1.isNativeWindowValid()); + Assert.assertNull(glWindow1.getParentNativeWindow()); + glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy"); + glWindow1.setSize(640, 480); + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, glWindow1, false); + glWindow1.addGLEventListener(demo1); + + GLWindow glWindow2 = GLWindow.create(glWindow1, glCaps); + Assert.assertNotNull(glWindow2); + Assert.assertEquals(false, glWindow2.isVisible()); + Assert.assertEquals(false, glWindow2.isNativeWindowValid()); + Assert.assertEquals(glWindow1,glWindow2.getParentNativeWindow()); + glWindow2.setSize(320, 240); + GLEventListener demo2 = new Gears(); + setDemoFields(demo2, glWindow2, false); + glWindow2.addGLEventListener(demo2); + + // visible test + glWindow1.setVisible(true); + Assert.assertEquals(true, glWindow1.isVisible()); + Assert.assertEquals(true, glWindow1.isNativeWindowValid()); + Assert.assertEquals(true, glWindow2.isVisible()); + Assert.assertEquals(true, glWindow2.isNativeWindowValid()); + glWindow1.setVisible(false); + Assert.assertEquals(false, glWindow1.isVisible()); + Assert.assertEquals(true, glWindow1.isNativeWindowValid()); + Assert.assertEquals(false, glWindow2.isVisible()); + Assert.assertEquals(true, glWindow2.isNativeWindowValid()); + glWindow1.setVisible(true); + Assert.assertEquals(true, glWindow1.isVisible()); + Assert.assertEquals(true, glWindow1.isNativeWindowValid()); + Assert.assertEquals(true, glWindow2.isVisible()); + Assert.assertEquals(true, glWindow2.isNativeWindowValid()); + + Animator animator1 = new Animator(glWindow1); + animator1.start(); + Animator animator2 = new Animator(glWindow2); + animator2.start(); + while(animator1.isAnimating() && animator1.getDuration()<durationPerTest) { + Thread.sleep(100); } + animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); + animator2.stop(); + Assert.assertEquals(false, animator2.isAnimating()); + + glWindow1.destroy(); // false + + Assert.assertEquals(false, glWindow1.isVisible()); + Assert.assertEquals(false, glWindow1.isNativeWindowValid()); + Assert.assertEquals(false, glWindow1.isDestroyed()); + + Assert.assertEquals(false, glWindow2.isVisible()); + Assert.assertEquals(false, glWindow2.isNativeWindowValid()); + Assert.assertEquals(false, glWindow2.isDestroyed()); + + glWindow1.destroy(true); + Assert.assertEquals(true, glWindow1.isDestroyed()); + Assert.assertEquals(true, glWindow2.isDestroyed()); + + // test double destroy .. + glWindow2.destroy(true); + Assert.assertEquals(true, glWindow2.isDestroyed()); } @Test - public void testWindowParenting01NewtOnNewtParentChildDraw() throws InterruptedException { - GLCapabilities caps = new GLCapabilities(null); - Assert.assertNotNull(caps); - Display display = NewtFactory.createDisplay(null); // local display - Assert.assertNotNull(display); - Screen screen = NewtFactory.createScreen(display, 0); // screen 0 - Assert.assertNotNull(screen); - - int x = 1; - int y = 1; + public void testWindowParenting02ReparentTop2Win() throws InterruptedException { + int x = 0; + int y = 0; NEWTEventFiFo eventFifo = new NEWTEventFiFo(); - Window window1 = createWindow(screen, caps); - Assert.assertNotNull(window1); - GLWindow glWindow1 = GLWindow.create(window1); - Assert.assertNotNull(glWindow1); - glWindow1.setSize(width, height); - Assert.assertEquals(width,glWindow1.getWidth()); - Assert.assertEquals(height,glWindow1.getHeight()); - glWindow1.setTitle("testWindowParenting01NewtOnNewtParentChildDraw - PARENT"); - glWindow1.setPosition(x,y); - glWindow1.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); - glWindow1.addWindowListener(new TraceWindowAdapter()); - glWindow1.setVisible(true); - Capabilities capsChosen = glWindow1.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); - Assert.assertNotNull(capsChosen); - Assert.assertTrue(capsChosen.isOnscreen()==true); + GLWindow glWindow1 = GLWindow.create(glCaps); + glWindow1.setTitle("testWindowParenting02ReparentTop2Win"); + glWindow1.setSize(640, 480); + GLEventListener demo1 = new RedSquare(); + setDemoFields(demo1, glWindow1, false); + glWindow1.addGLEventListener(demo1); - Window window2 = createWindow(window1, caps); - Assert.assertNotNull(window2); - GLWindow glWindow2 = GLWindow.create(window2); - Assert.assertNotNull(glWindow2); - glWindow2.setSize(width/2, height/2); - //Assert.assertEquals(width/2,glWindow2.getWidth()); - //Assert.assertEquals(height/2,glWindow2.getHeight()); - glWindow2.setTitle("testWindowParenting01NewtOnNewtParentChildDraw - CHILD"); - glWindow2.setPosition(glWindow1.getWidth()/2, glWindow1.getHeight()/2); - glWindow2.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); - glWindow2.addWindowListener(new TraceWindowAdapter(new WindowAction(eventFifo))); - // glWindow2.addMouseListener(new TraceMouseAdapter()); + GLWindow glWindow2 = GLWindow.create(glCaps); + glWindow2.setSize(320, 240); + GLEventListener demo2 = new Gears(); + setDemoFields(demo2, glWindow2, false); + glWindow2.addGLEventListener(demo2); + + glWindow1.setVisible(true); glWindow2.setVisible(true); - capsChosen = glWindow2.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); - Assert.assertNotNull(capsChosen); - Assert.assertTrue(capsChosen.isOnscreen()==true); + Animator animator1 = new Animator(glWindow1); + animator1.start(); + Animator animator2 = new Animator(glWindow2); + animator2.start(); + + int state = 0; + while(animator1.isAnimating() && animator1.getDuration()<3*durationPerTest) { + Thread.sleep(durationPerTest); + switch(state) { + case 0: + glWindow2.reparentWindow(glWindow1, null); + Assert.assertEquals(true, glWindow2.isVisible()); + Assert.assertEquals(true, glWindow2.isNativeWindowValid()); + Assert.assertEquals(glWindow1,glWindow2.getParentNativeWindow()); + break; + case 1: + glWindow2.reparentWindow(null, null); + Assert.assertEquals(true, glWindow2.isVisible()); + Assert.assertEquals(true, glWindow2.isNativeWindowValid()); + Assert.assertNull(glWindow2.getParentNativeWindow()); + break; + } + state++; + } + animator1.stop(); + animator2.stop(); + + glWindow1.destroy(true); + glWindow2.destroy(true); + } + + @Test + public void testWindowParenting03ReparentWin2Top() throws InterruptedException { + int x = 0; + int y = 0; + + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); + + GLWindow glWindow1 = GLWindow.create(glCaps); + glWindow1.setTitle("testWindowParenting03ReparentWin2Top"); + glWindow1.setSize(640, 480); GLEventListener demo1 = new RedSquare(); - setDemoFields(demo1, window1, glWindow1, false); + setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); + GLWindow glWindow2 = GLWindow.create(glWindow1, glCaps); + glWindow2.setSize(320, 240); GLEventListener demo2 = new Gears(); - setDemoFields(demo2, window2, glWindow2, false); + setDemoFields(demo2, glWindow2, false); glWindow2.addGLEventListener(demo2); - boolean shouldQuit = false; - long duration = durationPerTest; - long step = 20; - NEWTEvent event; - - while (duration>0 && !shouldQuit) { - glWindow1.display(); - glWindow2.display(); - Thread.sleep(step); - duration -= step; - x += 1; - y += 1; - glWindow1.setPosition(x,y); - glWindow2.setPosition(glWindow1.getWidth()/2,glWindow1.getHeight()/2-y); - - while( null != ( event = (NEWTEvent) eventFifo.get() ) ) { - Window source = (Window) event.getSource(); - if(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY == event.getEventType()) { - shouldQuit = true; - } else if(event instanceof KeyEvent) { - KeyEvent keyEvent = (KeyEvent) event; - switch(keyEvent.getKeyChar()) { - case 'q': - shouldQuit = true; - break; - case 'f': - source.setFullscreen(!source.isFullscreen()); - break; - } - } + glWindow1.setVisible(true); + + Animator animator1 = new Animator(glWindow1); + animator1.start(); + Animator animator2 = new Animator(glWindow2); + animator2.start(); + + int state = 0; + while(animator1.isAnimating() && animator1.getDuration()<3*durationPerTest) { + Thread.sleep(durationPerTest); + switch(state) { + case 0: + glWindow2.reparentWindow(null, null); + Assert.assertEquals(true, glWindow2.isVisible()); + Assert.assertEquals(true, glWindow2.isNativeWindowValid()); + Assert.assertNull(glWindow2.getParentNativeWindow()); + break; + case 1: + glWindow2.reparentWindow(glWindow1, null); + Assert.assertEquals(true, glWindow2.isVisible()); + Assert.assertEquals(true, glWindow2.isNativeWindowValid()); + Assert.assertEquals(glWindow1,glWindow2.getParentNativeWindow()); + break; } + state++; } - destroyWindow(null, null, window2, glWindow2); - destroyWindow(display, screen, window1, glWindow1); + animator1.stop(); + animator2.stop(); + + glWindow1.destroy(true); } - public static void setDemoFields(GLEventListener demo, Window window, GLWindow glWindow, boolean debug) { + public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) { Assert.assertNotNull(demo); - Assert.assertNotNull(window); + Assert.assertNotNull(glWindow); + Window window = glWindow.getInnerWindow(); if(debug) { MiscUtils.setFieldIfExists(demo, "glDebug", true); MiscUtils.setFieldIfExists(demo, "glTrace", true); @@ -200,8 +267,22 @@ public class TestParenting01NEWT { } } + static int atoi(String a) { + int i=0; + try { + durationPerTest = Integer.parseInt(a); + } catch (Exception ex) { ex.printStackTrace(); } + return i; + } + public static void main(String args[]) throws IOException { - durationPerTest = 5000; + 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 = TestParenting01NEWT.class.getName(); org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { tstname, diff --git a/src/junit/com/jogamp/test/junit/newt/TestParenting02AWT.java b/src/junit/com/jogamp/test/junit/newt/TestParenting02AWT.java new file mode 100755 index 000000000..dc330c4a9 --- /dev/null +++ b/src/junit/com/jogamp/test/junit/newt/TestParenting02AWT.java @@ -0,0 +1,260 @@ +/* + * 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 java.awt.Button; +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Frame; + +import javax.media.opengl.*; +import javax.media.nativewindow.*; + +import com.jogamp.opengl.util.Animator; +import com.jogamp.newt.*; +import com.jogamp.newt.event.*; +import com.jogamp.newt.opengl.*; +import com.jogamp.newt.awt.NewtCanvasAWT; + +import java.io.IOException; + +import com.jogamp.test.junit.util.*; +import com.jogamp.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; + +public class TestParenting02AWT { + static int width, height; + static long durationPerTest = 300; + static long waitReparent = 300; + + @BeforeClass + public static void initClass() { + width = 640; + height = 480; + } + + @Test + public void testWindowParenting01NewtChildOnAWTParentLayouted() throws InterruptedException { + runNewtChildOnAWTParent(true, false); + } + + @Test + public void testWindowParenting02NewtChildOnAWTParentLayoutedDef() throws InterruptedException { + runNewtChildOnAWTParent(true, true); + } + + @Test + public void testWindowParenting03NewtChildOnAWTParentDirect() throws InterruptedException { + runNewtChildOnAWTParent(false, false); + } + + @Test + public void testWindowParenting04NewtChildOnAWTParentDirectDef() throws InterruptedException { + runNewtChildOnAWTParent(false, true); + } + + public void runNewtChildOnAWTParent(boolean useLayout, boolean deferredPeer) throws InterruptedException { + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); + + // setup NEWT GLWindow .. + GLWindow glWindow = GLWindow.create(new GLCapabilities(null)); + Assert.assertNotNull(glWindow); + glWindow.setTitle("NEWT - CHILD"); + glWindow.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); + glWindow.addWindowListener(new TraceWindowAdapter(new WindowAction(eventFifo))); + GLEventListener demo = new Gears(); + setDemoFields(demo, glWindow, false); + glWindow.addGLEventListener(demo); + + // attach NEWT GLWindow to AWT Canvas + NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow); + Assert.assertNotNull(newtCanvasAWT); + Assert.assertEquals(false, glWindow.isVisible()); + Assert.assertEquals(false, glWindow.isNativeWindowValid()); + Assert.assertNull(glWindow.getParentNativeWindow()); + + Frame frame = new Frame("AWT Parent Frame"); + Assert.assertNotNull(frame); + if(useLayout) { + frame.setLayout(new BorderLayout()); + frame.add(new Button("North"), BorderLayout.NORTH); + frame.add(new Button("South"), BorderLayout.SOUTH); + frame.add(new Button("East"), BorderLayout.EAST); + frame.add(new Button("West"), BorderLayout.WEST); + if(!deferredPeer) { + frame.add(newtCanvasAWT, BorderLayout.CENTER); + } + } else { + if(!deferredPeer) { + frame.add(newtCanvasAWT); + } + } + + frame.setSize(width, height); + + frame.setVisible(true); + // X11: true, Windows: false - Assert.assertEquals(true, glWindow.isVisible()); + + if(deferredPeer) { + if(useLayout) { + frame.add(newtCanvasAWT, BorderLayout.CENTER); + } else { + frame.add(newtCanvasAWT); + } + } + + // Since it is not defined when AWT's addNotify call happen + // we just have to wait for it in this junit test + // because we have assertions on the state. + // Regular application shall not need to do that. + do { + Thread.yield(); + // 1st display .. creation + glWindow.display(); + } while(!glWindow.isNativeWindowValid()) ; + + Assert.assertEquals(true, glWindow.isNativeWindowValid()); + Assert.assertNotNull(glWindow.getParentNativeWindow()); + System.out.println("+++++++++++++++++++ 1st ADDED"); + Thread.sleep(waitReparent); + + if(useLayout) { + // test some fancy re-layout .. + frame.remove(newtCanvasAWT); + Assert.assertEquals(false, glWindow.isVisible()); + Assert.assertEquals(true, glWindow.isNativeWindowValid()); + Assert.assertNull(glWindow.getParentNativeWindow()); + System.out.println("+++++++++++++++++++ REMOVED!"); + Thread.sleep(waitReparent); + + // should recreate properly .. + frame.add(newtCanvasAWT, BorderLayout.CENTER); + glWindow.display(); + Assert.assertEquals(true, glWindow.isVisible()); + Assert.assertEquals(true, glWindow.isNativeWindowValid()); + Assert.assertNotNull(glWindow.getParentNativeWindow()); + System.out.println("+++++++++++++++++++ 2nd ADDED"); + Thread.sleep(waitReparent); + } + + long duration = durationPerTest; + long step = 20; + NEWTEvent event; + boolean shouldQuit = false; + + while (duration>0 && !shouldQuit) { + glWindow.display(); + Thread.sleep(step); + duration -= step; + + while( null != ( event = (NEWTEvent) eventFifo.get() ) ) { + Window source = (Window) event.getSource(); + if(event instanceof KeyEvent) { + KeyEvent keyEvent = (KeyEvent) event; + switch(keyEvent.getKeyChar()) { + case 'q': + shouldQuit = true; + break; + case 'f': + source.setFullscreen(!source.isFullscreen()); + break; + } + } + } + } + System.out.println("+++++++++++++++++++ END"); + Thread.sleep(waitReparent); + + glWindow.destroy(); + if(useLayout) { + frame.remove(newtCanvasAWT); + } + frame.dispose(); + } + + public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) { + Assert.assertNotNull(demo); + Assert.assertNotNull(glWindow); + Window window = glWindow.getInnerWindow(); + if(debug) { + MiscUtils.setFieldIfExists(demo, "glDebug", true); + MiscUtils.setFieldIfExists(demo, "glTrace", true); + } + if(!MiscUtils.setFieldIfExists(demo, "window", window)) { + MiscUtils.setFieldIfExists(demo, "glWindow", glWindow); + } + } + + static int atoi(String a) { + int i=0; + try { + durationPerTest = 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]); + } else if(args[i].equals("-wait")) { + waitReparent = atoi(args[++i]); + } + } + String tstname = TestParenting02AWT.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/TestParenting02NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestParenting02NEWT.java new file mode 100755 index 000000000..0fa0bef0f --- /dev/null +++ b/src/junit/com/jogamp/test/junit/newt/TestParenting02NEWT.java @@ -0,0 +1,231 @@ +/* + * 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.opengl.*; +import javax.media.nativewindow.*; +import javax.media.nativewindow.*; + +import com.jogamp.newt.*; +import com.jogamp.newt.event.*; +import com.jogamp.newt.opengl.*; + +import java.io.IOException; + +import com.jogamp.test.junit.util.*; +import com.jogamp.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; + +public class TestParenting02NEWT { + static int width, height; + static long durationPerTest = 500; + + @BeforeClass + public static void initClass() { + width = 640; + height = 480; + } + + static Window createWindow(Screen screen, Capabilities caps) { + Assert.assertNotNull(caps); + Window window = NewtFactory.createWindow(screen, caps, false) ; + Assert.assertNotNull(window); + return window; + } + + static Window createWindow(NativeWindow parent, Capabilities caps) { + Assert.assertNotNull(caps); + Window window = NewtFactory.createWindow(parent, caps, true); + Assert.assertNotNull(window); + return window; + } + + static void destroyWindow(Display display, Screen screen, Window window, GLWindow glWindow) { + if(null!=glWindow) { + glWindow.destroy(); + } + if(null!=window) { + window.destroy(); + } + if(null!=screen) { + screen.destroy(); + } + if(null!=display) { + display.destroy(); + } + } + + @Test + public void testWindowParenting01NewtOnNewtParentChildDraw() throws InterruptedException { + GLCapabilities caps = new GLCapabilities(null); + Assert.assertNotNull(caps); + Display display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + + int x = 1; + int y = 1; + + NEWTEventFiFo eventFifo = new NEWTEventFiFo(); + + Window window1 = createWindow(screen, caps); + Assert.assertNotNull(window1); + GLWindow glWindow1 = GLWindow.create(window1); + Assert.assertNotNull(glWindow1); + glWindow1.setSize(width, height); + Assert.assertEquals(width,glWindow1.getWidth()); + Assert.assertEquals(height,glWindow1.getHeight()); + glWindow1.setTitle("testWindowParenting01NewtOnNewtParentChildDraw - PARENT"); + glWindow1.setPosition(x,y); + glWindow1.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); + glWindow1.addWindowListener(new TraceWindowAdapter()); + glWindow1.setVisible(true); + Capabilities capsChosen = glWindow1.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); + Assert.assertNotNull(capsChosen); + Assert.assertTrue(capsChosen.isOnscreen()==true); + + Window window2 = createWindow(window1, caps); + Assert.assertNotNull(window2); + GLWindow glWindow2 = GLWindow.create(window2); + Assert.assertNotNull(glWindow2); + glWindow2.setSize(width/2, height/2); + //Assert.assertEquals(width/2,glWindow2.getWidth()); + //Assert.assertEquals(height/2,glWindow2.getHeight()); + glWindow2.setTitle("testWindowParenting01NewtOnNewtParentChildDraw - CHILD"); + glWindow2.setPosition(glWindow1.getWidth()/2, glWindow1.getHeight()/2); + glWindow2.addKeyListener(new TraceKeyAdapter(new KeyAction(eventFifo))); + glWindow2.addWindowListener(new TraceWindowAdapter(new WindowAction(eventFifo))); + // glWindow2.addMouseListener(new TraceMouseAdapter()); + 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; + long duration = durationPerTest; + long step = 20; + NEWTEvent event; + + while (duration>0 && !shouldQuit) { + glWindow1.display(); + glWindow2.display(); + Thread.sleep(step); + duration -= step; + x += 1; + y += 1; + glWindow1.setPosition(x,y); + glWindow2.setPosition(glWindow1.getWidth()/2,glWindow1.getHeight()/2-y); + + while( null != ( event = (NEWTEvent) eventFifo.get() ) ) { + Window source = (Window) event.getSource(); + if(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY == event.getEventType()) { + shouldQuit = true; + } else if(event instanceof KeyEvent) { + KeyEvent keyEvent = (KeyEvent) event; + switch(keyEvent.getKeyChar()) { + case 'q': + shouldQuit = true; + break; + case 'f': + source.setFullscreen(!source.isFullscreen()); + break; + } + } + } + } + destroyWindow(null, null, window2, glWindow2); + destroyWindow(display, screen, window1, glWindow1); + } + + public static void setDemoFields(GLEventListener demo, Window window, GLWindow glWindow, boolean debug) { + Assert.assertNotNull(demo); + Assert.assertNotNull(window); + if(debug) { + MiscUtils.setFieldIfExists(demo, "glDebug", true); + MiscUtils.setFieldIfExists(demo, "glTrace", true); + } + if(!MiscUtils.setFieldIfExists(demo, "window", window)) { + MiscUtils.setFieldIfExists(demo, "glWindow", glWindow); + } + } + + static int atoi(String a) { + int i=0; + try { + durationPerTest = 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 = TestParenting02NEWT.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/TestWindows01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java index e0affa4ab..58ea235df 100755 --- a/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java @@ -69,9 +69,11 @@ public class TestWindows01NEWT { Window window = NewtFactory.createWindow(screen, caps, onscreen && undecorated); Assert.assertNotNull(window); window.setSize(width, height); + Assert.assertEquals(false,window.isNativeWindowValid()); Assert.assertEquals(false,window.isVisible()); window.setVisible(true); Assert.assertEquals(true,window.isVisible()); + Assert.assertEquals(true,window.isNativeWindowValid()); // Assert.assertEquals(width,window.getWidth()); // Assert.assertEquals(height,window.getHeight()); // System.out.println("Created: "+window); @@ -103,6 +105,27 @@ public class TestWindows01NEWT { } @Test + public void testWindowNativeRecreate01Simple() throws InterruptedException { + Capabilities caps = new Capabilities(); + Assert.assertNotNull(caps); + Display display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + + Window window = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); + window.destroy(); + Assert.assertEquals(false,window.isNativeWindowValid()); + Assert.assertEquals(false,window.isVisible()); + + window.setVisible(true); + Assert.assertEquals(true,window.isNativeWindowValid()); + + Thread.sleep(100); // 100 ms + destroyWindow(display, screen, window); + } + + @Test public void testWindowDecor01Simple() throws InterruptedException { Capabilities caps = new Capabilities(); Assert.assertNotNull(caps); @@ -112,7 +135,7 @@ public class TestWindows01NEWT { Assert.assertNotNull(screen); Window window = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); - Thread.sleep(1000); // 1000 ms + Thread.sleep(100); // 100 ms destroyWindow(display, screen, window); } @@ -126,7 +149,7 @@ public class TestWindows01NEWT { Assert.assertNotNull(screen); Window window = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); - Thread.sleep(1000); // 1000 ms + Thread.sleep(100); // 100 ms destroyWindow(null, null, window); destroyWindow(display, screen, window); } @@ -142,7 +165,7 @@ public class TestWindows01NEWT { Window window1 = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); Window window2 = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); - Thread.sleep(1000); // 1000 ms + Thread.sleep(100); // 100 ms destroyWindow(null, null, window2); destroyWindow(display, screen, window1); } diff --git a/src/junit/com/jogamp/test/junit/newt/WindowAction.java b/src/junit/com/jogamp/test/junit/newt/WindowAction.java index fa50cb34a..c52b895e6 100644 --- a/src/junit/com/jogamp/test/junit/newt/WindowAction.java +++ b/src/junit/com/jogamp/test/junit/newt/WindowAction.java @@ -32,7 +32,6 @@ package com.jogamp.test.junit.newt; -import com.jogamp.opengl.util.Animator; import com.jogamp.newt.event.*; class WindowAction extends WindowAdapter { |