1 /** 2 * Copyright 2011 JogAmp Community. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without modification, are 5 * permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, this list of 8 * conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED 15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * The views and conclusions contained in the software and documentation are those of the 25 * authors and should not be interpreted as representing official policies, either expressed 26 * or implied, of JogAmp Community. 27 */ 28 29 package com.jogamp.opengl.test.junit.jogl.swt; 30 31 import java.io.IOException; 32 import java.lang.reflect.InvocationTargetException; 33 34 import com.jogamp.nativewindow.swt.SWTAccessor; 35 import com.jogamp.newt.NewtFactory; 36 import com.jogamp.newt.event.KeyAdapter; 37 import com.jogamp.newt.event.KeyEvent; 38 import com.jogamp.newt.event.WindowEvent; 39 import com.jogamp.newt.event.WindowAdapter; 40 import com.jogamp.newt.opengl.GLWindow; 41 import com.jogamp.newt.swt.NewtCanvasSWT; 42 import com.jogamp.opengl.test.junit.util.AWTRobotUtil; 43 import com.jogamp.opengl.test.junit.util.MiscUtils; 44 import com.jogamp.opengl.test.junit.util.UITestCase; 45 import com.jogamp.opengl.test.junit.util.QuitAdapter; 46 import com.jogamp.opengl.util.Animator; 47 import com.jogamp.opengl.util.AnimatorBase; 48 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; 49 50 import com.jogamp.nativewindow.util.Dimension; 51 import com.jogamp.nativewindow.util.Point; 52 import com.jogamp.nativewindow.util.PointImmutable; 53 import com.jogamp.nativewindow.util.DimensionImmutable; 54 import com.jogamp.opengl.GLCapabilities; 55 import com.jogamp.opengl.GLCapabilitiesImmutable; 56 import com.jogamp.opengl.GLProfile; 57 58 import org.eclipse.swt.SWT; 59 import org.eclipse.swt.custom.SashForm; 60 import org.eclipse.swt.layout.FillLayout; 61 import org.eclipse.swt.widgets.Composite; 62 import org.eclipse.swt.widgets.Display; 63 import org.eclipse.swt.widgets.Shell; 64 import org.junit.After; 65 import org.junit.Assert; 66 import org.junit.Assume; 67 import org.junit.Before; 68 import org.junit.BeforeClass; 69 import org.junit.AfterClass; 70 import org.junit.Test; 71 import org.junit.FixMethodOrder; 72 import org.junit.runners.MethodSorters; 73 74 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 75 public class TestBug672NewtCanvasSWTSashFormComposite extends UITestCase { 76 static int screenIdx = 0; 77 static PointImmutable wpos; 78 static DimensionImmutable wsize, rwsize = null; 79 80 static long duration = 500; // ms 81 82 @BeforeClass initClass()83 public static void initClass() { 84 if(null == wsize) { 85 wsize = new Dimension(640, 480); 86 } 87 } 88 89 @AfterClass releaseClass()90 public static void releaseClass() { 91 } 92 93 Display display = null; 94 Shell shell = null; 95 Composite composite = null; 96 SashForm sash = null; 97 Composite innerComposite = null; 98 com.jogamp.newt.Display swtNewtDisplay = null; 99 100 @Before init()101 public void init() { 102 SWTAccessor.invoke(true, new Runnable() { 103 public void run() { 104 display = new Display(); 105 Assert.assertNotNull( display ); 106 }}); 107 display.syncExec(new Runnable() { 108 public void run() { 109 shell = new Shell( display ); 110 Assert.assertNotNull( shell ); 111 shell.setLayout( new FillLayout() ); 112 composite = new Composite( shell, SWT.NONE ); 113 composite.setLayout( new FillLayout() ); 114 Assert.assertNotNull( composite ); 115 sash = new SashForm(composite, SWT.NONE); 116 Assert.assertNotNull( sash ); 117 final org.eclipse.swt.widgets.Label c = new org.eclipse.swt.widgets.Label(sash, SWT.NONE); 118 c.setText("Left cell"); 119 innerComposite = new Composite(sash, SWT.NONE); 120 Assert.assertNotNull( innerComposite ); 121 innerComposite.setLayout( new FillLayout() ); 122 }}); 123 swtNewtDisplay = NewtFactory.createDisplay(null, false); // no-reuse 124 } 125 126 @After release()127 public void release() { 128 Assert.assertNotNull( display ); 129 Assert.assertNotNull( shell ); 130 Assert.assertNotNull( composite ); 131 Assert.assertNotNull( sash ); 132 Assert.assertNotNull( innerComposite ); 133 try { 134 display.syncExec(new Runnable() { 135 public void run() { 136 innerComposite.dispose(); 137 sash.dispose(); 138 composite.dispose(); 139 shell.dispose(); 140 }}); 141 SWTAccessor.invoke(true, new Runnable() { 142 public void run() { 143 display.dispose(); 144 }}); 145 } 146 catch( final Throwable throwable ) { 147 throwable.printStackTrace(); 148 Assume.assumeNoException( throwable ); 149 } 150 swtNewtDisplay = null; 151 display = null; 152 shell = null; 153 composite = null; 154 sash = null; 155 innerComposite = null; 156 } 157 158 class WaitAction implements Runnable { 159 private final long sleepMS; 160 WaitAction(final long sleepMS)161 WaitAction(final long sleepMS) { 162 this.sleepMS = sleepMS; 163 } run()164 public void run() { 165 if( !display.readAndDispatch() ) { 166 // blocks on linux .. display.sleep(); 167 try { 168 Thread.sleep(sleepMS); 169 } catch (final InterruptedException e) { } 170 } 171 } 172 } 173 final WaitAction awtRobotWaitAction = new WaitAction(AWTRobotUtil.TIME_SLICE); 174 final WaitAction generalWaitAction = new WaitAction(10); 175 runTestGL(final GLCapabilitiesImmutable caps)176 protected void runTestGL(final GLCapabilitiesImmutable caps) throws InterruptedException, InvocationTargetException { 177 final com.jogamp.newt.Screen screen = NewtFactory.createScreen(swtNewtDisplay, screenIdx); 178 final GLWindow glWindow = GLWindow.create(screen, caps); 179 Assert.assertNotNull(glWindow); 180 181 final GearsES2 demo = new GearsES2(1); 182 glWindow.addGLEventListener(demo); 183 184 final Animator animator = new Animator(); 185 animator.setModeBits(false, AnimatorBase.MODE_EXPECT_AWT_RENDERING_THREAD); 186 187 final QuitAdapter quitAdapter = new QuitAdapter(); 188 //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter)); 189 //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter)); 190 glWindow.addKeyListener(quitAdapter); 191 glWindow.addWindowListener(quitAdapter); 192 193 glWindow.addWindowListener(new WindowAdapter() { 194 public void windowResized(final WindowEvent e) { 195 System.err.println("window resized: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()); 196 } 197 public void windowMoved(final WindowEvent e) { 198 System.err.println("window moved: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()); 199 } 200 }); 201 202 glWindow.addKeyListener(new KeyAdapter() { 203 public void keyReleased(final KeyEvent e) { 204 if( !e.isPrintableKey() || e.isAutoRepeat() ) { 205 return; 206 } 207 if(e.getKeyChar()=='f') { 208 glWindow.invokeOnNewThread(null, false, new Runnable() { 209 public void run() { 210 final Thread t = glWindow.setExclusiveContextThread(null); 211 System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); 212 glWindow.setFullscreen(!glWindow.isFullscreen()); 213 System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); 214 glWindow.setExclusiveContextThread(t); 215 } } ); 216 } 217 } 218 }); 219 220 animator.add(glWindow); 221 animator.start(); 222 Assert.assertTrue(animator.isStarted()); 223 Assert.assertTrue(animator.isAnimating()); 224 animator.setUpdateFPSFrames(60, null); 225 final NewtCanvasSWT canvas1 = NewtCanvasSWT.create( innerComposite, 0, glWindow ); 226 Assert.assertNotNull( canvas1 ); 227 228 display.syncExec( new Runnable() { 229 public void run() { 230 shell.setText( getSimpleTestName(".") ); 231 shell.setSize( wsize.getWidth(), wsize.getHeight() ); 232 if( null != wpos ) { 233 shell.setLocation( wpos.getX(), wpos.getY() ); 234 } 235 shell.open(); 236 } 237 }); 238 Assert.assertTrue("GLWindow didn't become visible natively!", AWTRobotUtil.waitForRealized(glWindow, awtRobotWaitAction, true)); 239 Assert.assertNotNull( canvas1.getNativeWindow() ); 240 241 System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities()); 242 System.err.println("GL chosen: "+glWindow.getChosenCapabilities()); 243 System.err.println("window pos/siz.0: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets()); 244 System.err.println("GLWindow LOS.0: "+glWindow.getLocationOnScreen(null)); 245 System.err.println("NewtCanvasSWT LOS.0: "+canvas1.getNativeWindow().getLocationOnScreen(null)); 246 247 if( null != rwsize ) { 248 for(int i=0; i<50; i++) { // 500 ms dispatched delay 249 generalWaitAction.run(); 250 } 251 display.syncExec( new Runnable() { 252 public void run() { 253 shell.setSize( rwsize.getWidth(), rwsize.getHeight() ); 254 } 255 }); 256 System.err.println("window resize pos/siz.1: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", "+glWindow.getInsets()); 257 System.err.println("GLWindow LOS.1: "+glWindow.getLocationOnScreen(null)); 258 System.err.println("NewtCanvasSWT LOS.1: "+canvas1.getNativeWindow().getLocationOnScreen(null)); 259 } 260 261 final PointImmutable pSashRightClient = new Point(wsize.getWidth(), 0); 262 final PointImmutable pNatWinLOS = canvas1.getNativeWindow().getLocationOnScreen(null); 263 final PointImmutable pGLWinLOS = glWindow.getLocationOnScreen(null); 264 265 System.err.println("GLWindow LOS: "+pGLWinLOS); 266 System.err.println("NewtCanvasSWT LOS: "+pNatWinLOS); 267 268 Assert.assertTrue( "NewtCanvasAWT LOS "+pNatWinLOS+" not >= sash-right "+pSashRightClient, pNatWinLOS.compareTo(pSashRightClient) >= 0 ); 269 Assert.assertTrue( "GLWindow LOS "+pGLWinLOS+" not >= sash-right "+pSashRightClient, pGLWinLOS.compareTo(pSashRightClient) >= 0 ); 270 271 while( !quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration ) { 272 generalWaitAction.run(); 273 } 274 275 animator.stop(); 276 Assert.assertFalse(animator.isAnimating()); 277 Assert.assertFalse(animator.isStarted()); 278 Assert.assertEquals(null, glWindow.getExclusiveContextThread()); 279 280 canvas1.dispose(); 281 glWindow.destroy(); 282 Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow, false)); 283 } 284 285 @Test test01()286 public void test01() throws InterruptedException, InvocationTargetException { 287 final GLProfile glp = GLProfile.getGL2ES2(); 288 final GLCapabilities caps = new GLCapabilities( glp ); 289 runTestGL(caps); 290 } 291 main(final String args[])292 public static void main(final String args[]) throws IOException { 293 int x=0, y=0, w=640, h=480, rw=-1, rh=-1; 294 boolean usePos = false; 295 296 for(int i=0; i<args.length; i++) { 297 if(args[i].equals("-time")) { 298 i++; 299 duration = MiscUtils.atol(args[i], duration); 300 } else if(args[i].equals("-width")) { 301 i++; 302 w = MiscUtils.atoi(args[i], w); 303 } else if(args[i].equals("-height")) { 304 i++; 305 h = MiscUtils.atoi(args[i], h); 306 } else if(args[i].equals("-x")) { 307 i++; 308 x = MiscUtils.atoi(args[i], x); 309 usePos = true; 310 } else if(args[i].equals("-y")) { 311 i++; 312 y = MiscUtils.atoi(args[i], y); 313 usePos = true; 314 } else if(args[i].equals("-rwidth")) { 315 i++; 316 rw = MiscUtils.atoi(args[i], rw); 317 } else if(args[i].equals("-rheight")) { 318 i++; 319 rh = MiscUtils.atoi(args[i], rh); 320 } else if(args[i].equals("-screen")) { 321 i++; 322 screenIdx = MiscUtils.atoi(args[i], 0); 323 } 324 } 325 wsize = new Dimension(w, h); 326 if( 0 < rw && 0 < rh ) { 327 rwsize = new Dimension(rw, rh); 328 } 329 330 if(usePos) { 331 wpos = new Point(x, y); 332 } 333 System.err.println("position "+wpos); 334 System.err.println("size "+wsize); 335 System.err.println("resize "+rwsize); 336 System.err.println("screen "+screenIdx); 337 338 org.junit.runner.JUnitCore.main(TestBug672NewtCanvasSWTSashFormComposite.class.getName()); 339 } 340 } 341