1 /**
2  * Copyright 2013 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.newt.mm;
30 
31 import java.io.IOException;
32 
33 import com.jogamp.opengl.GLCapabilities;
34 import com.jogamp.opengl.GLProfile;
35 
36 import org.junit.AfterClass;
37 import org.junit.Assert;
38 import org.junit.BeforeClass;
39 import org.junit.Test;
40 import org.junit.FixMethodOrder;
41 import org.junit.runners.MethodSorters;
42 
43 import com.jogamp.newt.Display;
44 import com.jogamp.newt.MonitorDevice;
45 import com.jogamp.newt.NewtFactory;
46 import com.jogamp.newt.Screen;
47 import com.jogamp.newt.Window;
48 import com.jogamp.newt.MonitorMode;
49 import com.jogamp.newt.opengl.GLWindow;
50 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
51 import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
52 import com.jogamp.opengl.test.junit.util.MiscUtils;
53 import com.jogamp.opengl.test.junit.util.UITestCase;
54 import com.jogamp.opengl.util.Animator;
55 
56 import java.util.ArrayList;
57 import java.util.List;
58 
59 import com.jogamp.nativewindow.util.Dimension;
60 import com.jogamp.nativewindow.util.DimensionImmutable;
61 import com.jogamp.nativewindow.util.Rectangle;
62 import com.jogamp.nativewindow.util.RectangleImmutable;
63 
64 /**
65  * Fullscreen on separate monitors, incl. spanning across multiple monitors.
66  */
67 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
68 public class TestScreenMode01cNEWT extends UITestCase {
69     static GLProfile glp;
70     static int width, height;
71 
72     static long waitTimeShort = 2000;
73     static long duration = 4000;
74 
75     @BeforeClass
initClass()76     public static void initClass() {
77         setResetXRandRIfX11AfterClass();
78         width  = 200;
79         height = 200;
80         glp = GLProfile.getDefault();
81     }
82 
83     @AfterClass
releaseClass()84     public static void releaseClass() throws InterruptedException {
85         Thread.sleep(waitTimeShort);
86     }
87 
createWindow(final Screen screen, final GLCapabilities caps, final String name, final int screenXPos, final int screenYPos, final int width, final int height)88     static GLWindow createWindow(final Screen screen, final GLCapabilities caps, final String name, final int screenXPos, final int screenYPos, final int width, final int height) throws InterruptedException {
89         Assert.assertNotNull(caps);
90 
91         final GLWindow window = GLWindow.create(screen, caps);
92         // Window window = NewtFactory.createWindow(screen, caps);
93         final int[] winPos = window.convertToWindowUnits(new int[] { screenXPos, screenYPos });
94         window.setTitle(name);
95         window.setPosition(winPos[0], winPos[1]);
96         window.setSize(width, height);
97         window.addGLEventListener(new GearsES2());
98         Assert.assertNotNull(window);
99         final long t0 = System.currentTimeMillis();
100         window.setVisible(true);
101         System.err.println("Time for visible/pos: "+(System.currentTimeMillis()-t0)+" ms");
102         return window;
103     }
104 
destroyWindow(final Window window)105     static void destroyWindow(final Window window) throws InterruptedException {
106         if(null!=window) {
107             window.destroy();
108             AWTRobotUtil.waitForRealized(window, false); // don't override a previous assertion failure
109         }
110     }
111 
112     @Test
test01ScreenFullscreenSingleQ1()113     public void test01ScreenFullscreenSingleQ1() throws InterruptedException {
114         final Display display = NewtFactory.createDisplay(null); // local display
115         Assert.assertNotNull(display);
116         final Screen screen  = NewtFactory.createScreen(display, 0); // screen 0
117         Assert.assertNotNull(screen);
118         screen.addReference(); // trigger creation
119         try {
120             final RectangleImmutable monitorVp = screen.getMonitorDevices().get(0).getViewport();
121             testScreenFullscreenImpl(screen, monitorVp.getX(), monitorVp.getY(), false, null);
122         } finally {
123             screen.removeReference();
124             AWTRobotUtil.waitForRealized(screen, false); // don't override a previous assertion failure
125         }
126     }
127 
128     @Test
test02ScreenFullscreenSingleQ2()129     public void test02ScreenFullscreenSingleQ2() throws InterruptedException {
130         final Display display = NewtFactory.createDisplay(null); // local display
131         Assert.assertNotNull(display);
132         final Screen screen  = NewtFactory.createScreen(display, 0); // screen 0
133         Assert.assertNotNull(screen);
134         screen.addReference(); // trigger creation
135         try {
136             if( 2 > screen.getMonitorDevices().size() ) {
137                 System.err.println("Test Disabled (1): Monitor count < 2: "+screen);
138                 return;
139             }
140             final RectangleImmutable monitorVp = screen.getMonitorDevices().get(1).getViewport();
141             testScreenFullscreenImpl(screen, monitorVp.getX(), monitorVp.getY(), false, null);
142         } finally {
143             screen.removeReference();
144             AWTRobotUtil.waitForRealized(screen, false); // don't override a previous assertion failure
145         }
146     }
147 
148     @Test
test03ScreenFullscreenSpanQ1Q2()149     public void test03ScreenFullscreenSpanQ1Q2() throws InterruptedException {
150         final Display display = NewtFactory.createDisplay(null); // local display
151         Assert.assertNotNull(display);
152         final Screen screen  = NewtFactory.createScreen(display, 0); // screen 0
153         Assert.assertNotNull(screen);
154         screen.addReference(); // trigger creation
155         try {
156             if( 2 > screen.getMonitorDevices().size() ) {
157                 System.err.println("Test Disabled (2): Spanning monitor count < 2: "+screen);
158                 return;
159             }
160             final ArrayList<MonitorDevice> monitors = new ArrayList<MonitorDevice>();
161             monitors.add(screen.getMonitorDevices().get(0)); // Q1
162             monitors.add(screen.getMonitorDevices().get(1)); // Q2
163             final RectangleImmutable monitorVp = screen.getMonitorDevices().get(0).getViewport();
164             testScreenFullscreenImpl(screen, monitorVp.getX()+50, monitorVp.getY()+50, true, monitors);
165         } finally {
166             screen.removeReference();
167             AWTRobotUtil.waitForRealized(screen, false); // don't override a previous assertion failure
168         }
169     }
170 
171     @Test
test04ScreenFullscreenSpanALL()172     public void test04ScreenFullscreenSpanALL() throws InterruptedException {
173         final Display display = NewtFactory.createDisplay(null); // local display
174         Assert.assertNotNull(display);
175         final Screen screen  = NewtFactory.createScreen(display, 0); // screen 0
176         Assert.assertNotNull(screen);
177         screen.addReference(); // trigger creation
178         try {
179             if( 2 > screen.getMonitorDevices().size() ) {
180                 System.err.println("Test Disabled (3): Monitor count < 2: "+screen);
181                 return;
182             }
183             final RectangleImmutable monitorVp = screen.getMonitorDevices().get(1).getViewport();
184             testScreenFullscreenImpl(screen, monitorVp.getX()-50, monitorVp.getY()+50, true, null);
185         } finally {
186             screen.removeReference();
187             AWTRobotUtil.waitForRealized(screen, false); // don't override a previous assertion failure
188         }
189     }
190 
testScreenFullscreenImpl(final Screen screen, final int screenXPos, final int screenYPos, final boolean spanAcrossMonitors, final List<MonitorDevice> monitors)191     void testScreenFullscreenImpl(final Screen screen, final int screenXPos, final int screenYPos,
192                                   final boolean spanAcrossMonitors, final List<MonitorDevice> monitors) throws InterruptedException {
193         Thread.sleep(waitTimeShort);
194 
195         final GLCapabilities caps = new GLCapabilities(glp);
196         Assert.assertNotNull(caps);
197         final Display display = screen.getDisplay();
198 
199         System.err.println("Test.0: Window screen: "+screen);
200 
201         System.err.println("Test.0: Window bounds (pre): screenPos "+screenXPos+"/"+screenYPos+" [pixels], windowSize "+width+"x"+height+" [wu] within "+screen.getViewport()+" [pixels]");
202 
203         final GLWindow window0 = createWindow(screen, caps, "win0", screenXPos, screenYPos, width, height);
204         Assert.assertNotNull(window0);
205         Rectangle window0WindowBounds = window0.getBounds();
206         DimensionImmutable window0SurfaceSize = new Dimension(window0.getSurfaceWidth(), window0.getSurfaceHeight());
207         System.err.println("Test.0: Window bounds    : "+window0WindowBounds+" [wu] within "+screen.getViewportInWindowUnits()+" [wu]");
208         System.err.println("Test.0: Window size      : "+window0SurfaceSize+" [pixels]");
209         System.err.println("Test.0: Screen viewport  : "+screen.getViewport()+" [pixels]");
210 
211         final Animator anim = new Animator(window0);
212         anim.start();
213 
214         final List<MonitorMode> allMonitorModes = screen.getMonitorModes();
215         Assert.assertTrue(allMonitorModes.size()>0);
216 
217         MonitorDevice monitor = window0.getMainMonitor();
218         System.err.println("Test.0: Window monitor: "+monitor);
219         if( !spanAcrossMonitors ) {
220             window0.setFullscreen(true);
221         } else {
222             window0.setFullscreen(monitors);
223         }
224 
225         monitor = window0.getMainMonitor();
226         window0WindowBounds = window0.getBounds();
227         window0SurfaceSize = new Dimension(window0.getSurfaceWidth(), window0.getSurfaceHeight());
228         System.err.println("Test.1: Window bounds    : "+window0WindowBounds+" [wu] within "+screen.getViewportInWindowUnits()+" [wu]");
229         System.err.println("Test.1: Window size      : "+window0SurfaceSize+" [pixels]");
230         System.err.println("Test.1: Screen viewport  : "+screen.getViewport()+" [pixels]");
231         System.err.println("Test.1: Monitor viewport : "+monitor.getViewport()+" [pixels], "+monitor.getViewportInWindowUnits()+" [wu]");
232         if( !spanAcrossMonitors ) {
233             Assert.assertEquals(monitor.getViewportInWindowUnits(), window0WindowBounds);
234         } else {
235             List<MonitorDevice> monitorsUsed = monitors;
236             if( null == monitorsUsed ) {
237                 monitorsUsed = window0.getScreen().getMonitorDevices();
238             }
239             final Rectangle monitorsUsedViewport = new Rectangle();
240             MonitorDevice.unionOfViewports(null, monitorsUsedViewport, monitorsUsed);
241             Assert.assertEquals(monitorsUsedViewport,  window0WindowBounds);
242         }
243 
244         Thread.sleep(duration);
245 
246         window0.setFullscreen(false);
247 
248         window0WindowBounds = window0.getBounds();
249         window0SurfaceSize = new Dimension(window0.getSurfaceWidth(), window0.getSurfaceHeight());;
250         monitor = window0.getMainMonitor();
251         System.err.println("Test.2: Window bounds    : "+window0WindowBounds+" [wu] within "+screen.getViewportInWindowUnits()+" [wu]");
252         System.err.println("Test.2: Window size      : "+window0SurfaceSize+" [pixels]");
253         System.err.println("Test.2: Screen viewport  : "+screen.getViewport()+" [pixels]");
254         System.err.println("Test.2: Monitor viewport : "+monitor.getViewport()+" [pixels], "+monitor.getViewportInWindowUnits()+" [wu]");
255 
256         Thread.sleep(duration);
257         anim.stop();
258         destroyWindow(window0);
259         Assert.assertEquals(false,window0.isVisible());
260         Assert.assertEquals(false,window0.isNativeValid());
261         Assert.assertEquals(true,display.isNativeValid());
262         Assert.assertEquals(true,screen.isNativeValid());
263     }
264 
main(final String args[])265     public static void main(final String args[]) throws IOException {
266         for(int i=0; i<args.length; i++) {
267             if(args[i].equals("-time")) {
268                 i++;
269                 duration = MiscUtils.atol(args[i], duration);
270             }
271         }
272         final String tstname = TestScreenMode01cNEWT.class.getName();
273         org.junit.runner.JUnitCore.main(tstname);
274     }
275 }
276