diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/junit/com/jogamp/test/junit/newt/TestScreenMode01NEWT.java | 265 | ||||
-rw-r--r-- | src/junit/com/jogamp/test/junit/newt/TestScreenMode02NEWT.java | 274 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/Screen.java | 43 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java | 390 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/impl/ScreenMode.java | 76 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java | 89 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/impl/ScreensModeState.java | 21 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java | 157 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java | 129 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java | 3 | ||||
-rw-r--r-- | src/newt/native/WindowsWindow.c | 258 | ||||
-rw-r--r-- | src/newt/native/X11Window.c | 258 |
12 files changed, 1813 insertions, 150 deletions
diff --git a/src/junit/com/jogamp/test/junit/newt/TestScreenMode01NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestScreenMode01NEWT.java new file mode 100644 index 000000000..a3da32bd3 --- /dev/null +++ b/src/junit/com/jogamp/test/junit/newt/TestScreenMode01NEWT.java @@ -0,0 +1,265 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.test.junit.newt; + +import java.io.IOException; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.jogamp.newt.Display; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; +import com.jogamp.newt.Window; +import com.jogamp.newt.impl.ScreenMode; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.test.junit.util.UITestCase; + +public class TestScreenMode01NEWT extends UITestCase { + static GLProfile glp; + static int width, height; + + static int waitTimeShort = 4; //1 sec + static int waitTimeLong = 6; //6 sec + + + + @BeforeClass + public static void initClass() { + NativeWindowFactory.initSingleton(true); + 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); + + boolean destroyWhenUnused = screen.getDestroyWhenUnused(); + GLWindow window = GLWindow.create(screen, caps); + window.addGLEventListener(new Gears()); + Assert.assertNotNull(window); + Assert.assertEquals(destroyWhenUnused, window.getScreen().getDestroyWhenUnused()); + window.setVisible(true); + return window; + } + + static void destroyWindow(Display display, Screen screen, Window window) { + if(null!=window) { + window.destroy(); + } + if(null!=screen) { + screen.destroy(); + } + if(null!=display) { + display.destroy(); + } + } + + @Test + public void testFullscreenChange01() 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 window = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); + + window.setFullscreen(true); + Assert.assertEquals(true, window.isFullscreen()); + + for(int state=0; state<waitTimeShort; state++) { + Thread.sleep(100); + } + window.setFullscreen(false); + Assert.assertEquals(false, window.isFullscreen()); + + destroyWindow(display, screen, window); + } + + @Test + public void testScreenModeChange01() 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 window = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); + + ScreenMode[] screenModes = screen.getScreenModes(); + Assert.assertNotNull(screenModes); + + int originalScreenMode = screen.getDesktopScreenModeIndex(); + short originalScreenRate = screen.getCurrentScreenRate(); + + Assert.assertNotSame(-1, originalScreenMode); + Assert.assertNotSame(-1, originalScreenRate); + + int modeIndex = 1; + + ScreenMode screenMode = screenModes[modeIndex]; + Assert.assertNotNull(screenMode); + + short modeRate = screenMode.getRates()[0]; + screen.setScreenMode(modeIndex, modeRate); + + Assert.assertEquals(modeIndex, screen.getDesktopScreenModeIndex()); + Assert.assertEquals(modeRate, screen.getCurrentScreenRate()); + + for(int state=0; state<waitTimeLong; state++) { + Thread.sleep(100); + } + + screen.setScreenMode(-1, (short)-1); + Assert.assertEquals(originalScreenMode, screen.getDesktopScreenModeIndex()); + Assert.assertEquals(originalScreenRate, screen.getCurrentScreenRate()); + + destroyWindow(display, screen, window); + } + + @Test + public void testScreenModeChangeWithFS01() 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 window = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); + ScreenMode[] screenModes = screen.getScreenModes(); + Assert.assertNotNull(screenModes); + + int originalScreenMode = screen.getDesktopScreenModeIndex(); + short originalScreenRate = screen.getCurrentScreenRate(); + + Assert.assertNotSame(-1, originalScreenMode); + Assert.assertNotSame(-1, originalScreenRate); + + int modeIndex = 1; + + ScreenMode screenMode = screenModes[modeIndex]; + Assert.assertNotNull(screenMode); + + short modeRate = screenMode.getRates()[0]; + screen.setScreenMode(modeIndex, modeRate); + + Assert.assertEquals(modeIndex, screen.getDesktopScreenModeIndex()); + Assert.assertEquals(modeRate, screen.getCurrentScreenRate()); + + window.setFullscreen(true); + Assert.assertEquals(true, window.isFullscreen()); + + for(int state=0; state<waitTimeLong; state++) { + Thread.sleep(100); + } + + window.setFullscreen(false); + Assert.assertEquals(false, window.isFullscreen()); + + screen.setScreenMode(-1, (short)-1); + Assert.assertEquals(originalScreenMode, screen.getDesktopScreenModeIndex()); + Assert.assertEquals(originalScreenRate, screen.getCurrentScreenRate()); + + destroyWindow(display, screen, window); + } + + @Test + public void testScreenModeChangeWithFS02() 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 window = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); + + ScreenMode[] screenModes = screen.getScreenModes(); + Assert.assertNotNull(screenModes); + + int originalScreenMode = screen.getDesktopScreenModeIndex(); + short originalScreenRate = screen.getCurrentScreenRate(); + + Assert.assertNotSame(-1, originalScreenMode); + Assert.assertNotSame(-1, originalScreenRate); + + int modeIndex = 1; + + ScreenMode screenMode = screenModes[modeIndex]; + Assert.assertNotNull(screenMode); + + short modeRate = screenMode.getRates()[0]; + screen.setScreenMode(modeIndex, modeRate); + + Assert.assertEquals(modeIndex, screen.getDesktopScreenModeIndex()); + Assert.assertEquals(modeRate, screen.getCurrentScreenRate()); + + window.setFullscreen(true); + Assert.assertEquals(true, window.isFullscreen()); + + for(int state=0; state<waitTimeLong; state++) { + Thread.sleep(100); + } + + screen.setScreenMode(-1, (short)-1); + Assert.assertEquals(originalScreenMode, screen.getDesktopScreenModeIndex()); + Assert.assertEquals(originalScreenRate, screen.getCurrentScreenRate()); + + window.setFullscreen(false); + Assert.assertEquals(false, window.isFullscreen()); + + destroyWindow(display, screen, window); + } + + public static void main(String args[]) throws IOException { + String tstname = TestScreenMode01NEWT.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/TestScreenMode02NEWT.java b/src/junit/com/jogamp/test/junit/newt/TestScreenMode02NEWT.java new file mode 100644 index 000000000..4d6c40016 --- /dev/null +++ b/src/junit/com/jogamp/test/junit/newt/TestScreenMode02NEWT.java @@ -0,0 +1,274 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.test.junit.newt; + + +import java.io.IOException; + +import javax.media.nativewindow.Capabilities; +import javax.media.nativewindow.NativeWindowFactory; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.jogamp.newt.Display; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; +import com.jogamp.newt.Window; +import com.jogamp.newt.impl.ScreenMode; +import com.jogamp.test.junit.util.UITestCase; + +public class TestScreenMode02NEWT extends UITestCase { + static int width, height; + + static int waitTimeShort = 1000; //1 sec + static int waitTimeLong = 4000; //4 sec + + + @BeforeClass + public static void initClass() { + NativeWindowFactory.initSingleton(true); + width = 640; + height = 480; + } + + static Window createWindow(Screen screen, Capabilities caps, int width, int height, boolean onscreen, boolean undecorated) { + Assert.assertNotNull(caps); + caps.setOnscreen(onscreen); + // Create native windowing resources .. X11/Win/OSX + // + Window window = NewtFactory.createWindow(screen, caps); + Assert.assertNotNull(window); + window.setUndecorated(onscreen && undecorated); + window.setSize(width, height); + Assert.assertEquals(false,window.isNativeValid()); + Assert.assertEquals(false,window.isVisible()); + window.setVisible(true); + Assert.assertEquals(true,window.isVisible()); + Assert.assertEquals(true,window.isNativeValid()); + + // + // Create native OpenGL resources .. XGL/WGL/CGL .. + // equivalent to GLAutoDrawable methods: setVisible(true) + // + caps = window.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 window; + } + + static void destroyWindow(Display display, Screen screen, Window window) { + if(null!=window) { + window.destroy(); + } + if(null!=screen) { + screen.destroy(); + } + if(null!=display) { + display.destroy(); + } + } + + @Test + public void testScreenRotationChange01() 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 */); + + ScreenMode[] screenModes = screen.getScreenModes(); + Assert.assertNotNull(screenModes); + + int originalScreenMode = screen.getDesktopScreenModeIndex(); + short originalScreenRate = screen.getCurrentScreenRate(); + int originalScreenRotation = screen.getCurrentScreenRotation(); + + Assert.assertNotSame(-1, originalScreenMode); + Assert.assertNotSame(-1, originalScreenRate); + Assert.assertNotSame(-1, originalScreenRotation); + + screen.setScreenRotation(ScreenMode.ROTATE_90); + Assert.assertEquals(ScreenMode.ROTATE_90, screen.getCurrentScreenRotation()); + + Thread.sleep(waitTimeShort); + + screen.setScreenRotation(originalScreenRotation); + Assert.assertEquals(originalScreenRotation, screen.getCurrentScreenRotation()); + + destroyWindow(display, screen, window); + } + + @Test + public void testScreenRotationChange02() 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 */); + + ScreenMode[] screenModes = screen.getScreenModes(); + Assert.assertNotNull(screenModes); + + int originalScreenMode = screen.getDesktopScreenModeIndex(); + short originalScreenRate = screen.getCurrentScreenRate(); + int originalScreenRotation = screen.getCurrentScreenRotation(); + + Assert.assertNotSame(-1, originalScreenMode); + Assert.assertNotSame(-1, originalScreenRate); + Assert.assertNotSame(-1, originalScreenRotation); + + screen.setScreenRotation(ScreenMode.ROTATE_180); + Assert.assertEquals(ScreenMode.ROTATE_180, screen.getCurrentScreenRotation()); + + Thread.sleep(waitTimeShort); + + screen.setScreenRotation(originalScreenRotation); + Assert.assertEquals(originalScreenRotation, screen.getCurrentScreenRotation()); + + destroyWindow(display, screen, window); + } + + @Test + public void testScreenRotationChange03() 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 */); + + ScreenMode[] screenModes = screen.getScreenModes(); + Assert.assertNotNull(screenModes); + + int originalScreenMode = screen.getDesktopScreenModeIndex(); + short originalScreenRate = screen.getCurrentScreenRate(); + int originalScreenRotation = screen.getCurrentScreenRotation(); + + Assert.assertNotSame(-1, originalScreenMode); + Assert.assertNotSame(-1, originalScreenRate); + Assert.assertNotSame(-1, originalScreenRotation); + + screen.setScreenRotation(ScreenMode.ROTATE_270); + Assert.assertEquals(ScreenMode.ROTATE_270, screen.getCurrentScreenRotation()); + + Thread.sleep(waitTimeShort); + + screen.setScreenRotation(originalScreenRotation); + Assert.assertEquals(originalScreenRotation, screen.getCurrentScreenRotation()); + + destroyWindow(display, screen, window); + } + + @Test + public void testScreenModeChangeWithRotate01() 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 */); + + ScreenMode[] screenModes = screen.getScreenModes(); + Assert.assertNotNull(screenModes); + + int originalScreenMode = screen.getDesktopScreenModeIndex(); + short originalScreenRate = screen.getCurrentScreenRate(); + int originalScreenRotation = screen.getCurrentScreenRotation(); + + Assert.assertNotSame(-1, originalScreenMode); + Assert.assertNotSame(-1, originalScreenRate); + Assert.assertNotSame(-1, originalScreenRotation); + + + int modeIndex = 1; + if(screenModes.length > 4) + { + modeIndex = screenModes.length - 2; + } + ScreenMode screenMode = screenModes[modeIndex]; + Assert.assertNotNull(screenMode); + + short modeRate = screenMode.getRates()[0]; + screen.setScreenMode(modeIndex, modeRate); + + Assert.assertEquals(modeIndex, screen.getDesktopScreenModeIndex()); + Assert.assertEquals(modeRate, screen.getCurrentScreenRate()); + + Thread.sleep(waitTimeLong); + + screen.setScreenRotation(ScreenMode.ROTATE_180); + Assert.assertEquals(ScreenMode.ROTATE_180, screen.getCurrentScreenRotation()); + + Thread.sleep(waitTimeShort); + + screen.setScreenRotation(originalScreenRotation); + Assert.assertEquals(originalScreenRotation, screen.getCurrentScreenRotation()); + + Thread.sleep(waitTimeShort); + + screen.setScreenMode(-1, (short)-1); + Assert.assertEquals(originalScreenMode, screen.getDesktopScreenModeIndex()); + Assert.assertEquals(originalScreenRate, screen.getCurrentScreenRate()); + + destroyWindow(display, screen, window); + } + + + public static void main(String args[]) throws IOException { + String tstname = TestScreenMode02NEWT.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/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java index f1b4254d8..ab4b9f0b4 100644 --- a/src/newt/classes/com/jogamp/newt/Screen.java +++ b/src/newt/classes/com/jogamp/newt/Screen.java @@ -29,6 +29,7 @@ package com.jogamp.newt; import com.jogamp.newt.impl.Debug; +import com.jogamp.newt.impl.ScreenMode; import javax.media.nativewindow.AbstractGraphicsScreen; public interface Screen { @@ -67,4 +68,46 @@ public interface Screen { int getHeight(); Display getDisplay(); + + /** Get the screen fully qualified name + * which can be used to get the screen controller + * associated with this screen + */ + String getScreenFQN(); + + /** + * Get the Current Desktop Screen mode index + * returns -1 if functionality not implemented + * for screen platform + */ + int getDesktopScreenModeIndex(); + + /** Get the current screen rate + * returns -1 if not natively implemented + */ + short getCurrentScreenRate(); + + /** + * Get list of available screen modes + * null if not implemented for screen platform + */ + ScreenMode[] getScreenModes(); + + /** + * change the screen mode + * @param modeIndex mode index from the list of available screen modes + * @param rate the desired rate should be one of the available rates. + */ + void setScreenMode(int modeIndex, short rate); + + /** Change the Screen Rotation to + * one of the rotations defined in ScreenMode + * @param rot rotation id, example ScreenMode.ROTATE_0 + */ + public void setScreenRotation(int rot); + + /** Get the Current screen rotation + * returns -1 if not implemented natively + */ + public int getCurrentScreenRotation(); } diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java b/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java index 1a76152f6..4535213da 100644 --- a/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java +++ b/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java @@ -37,153 +37,255 @@ package com.jogamp.newt.impl; import com.jogamp.newt.*; import javax.media.nativewindow.*; + import java.security.*; public abstract class ScreenImpl implements Screen { + protected DisplayImpl display; + protected int idx; + protected AbstractGraphicsScreen aScreen; + protected int refCount; // number of Screen references by Window + protected int width=-1, height=-1; // detected values: set using setScreenSize + protected static int usrWidth=-1, usrHeight=-1; // property values: newt.ws.swidth and newt.ws.sheight + private static AccessControlContext localACC = AccessController.getContext(); + + + protected static ScreensModeState screensModeState = new ScreensModeState(); // hold all screen mode controllers + private String screenFQN = null; // string fully qualified name + + private static Class getScreenClass(String type) + throws ClassNotFoundException + { + Class screenClass = NewtFactory.getCustomClass(type, "Screen"); + if(null==screenClass) { + if (NativeWindowFactory.TYPE_EGL.equals(type)) { + screenClass = Class.forName("com.jogamp.newt.impl.opengl.kd.KDScreen"); + } else if (NativeWindowFactory.TYPE_WINDOWS.equals(type)) { + screenClass = Class.forName("com.jogamp.newt.impl.windows.WindowsScreen"); + } else if (NativeWindowFactory.TYPE_MACOSX.equals(type)) { + screenClass = Class.forName("com.jogamp.newt.impl.macosx.MacScreen"); + } else if (NativeWindowFactory.TYPE_X11.equals(type)) { + screenClass = Class.forName("com.jogamp.newt.impl.x11.X11Screen"); + } else if (NativeWindowFactory.TYPE_AWT.equals(type)) { + screenClass = Class.forName("com.jogamp.newt.impl.awt.AWTScreen"); + } else { + throw new RuntimeException("Unknown window type \"" + type + "\""); + } + } + return screenClass; + } + + public static ScreenImpl create(String type, Display display, final int idx) { + try { + if(usrWidth<0 || usrHeight<0) { + usrWidth = Debug.getIntProperty("newt.ws.swidth", true, localACC); + usrHeight = Debug.getIntProperty("newt.ws.sheight", true, localACC); + if(usrWidth>0 || usrHeight>0) { + System.err.println("User screen size "+usrWidth+"x"+usrHeight); + } + } + Class screenClass = getScreenClass(type); + ScreenImpl screen = (ScreenImpl) screenClass.newInstance(); + screen.display = (DisplayImpl) display; + screen.idx = idx; + + return screen; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + protected synchronized final void createNative() { + if(null == aScreen) { + if(DEBUG) { + System.err.println("Screen.createNative() START ("+DisplayImpl.getThreadName()+", "+this+")"); + } + display.addReference(); + createNativeImpl(); + if(null == aScreen) { + throw new RuntimeException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen"); + } + if(DEBUG) { + System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+")"); + } + } + + initScreenModes(); + } + + /** Retrieve screen modes + * and screen rate initializing the status + * of the screen mode + */ + private void initScreenModes(){ + ScreenMode[] screenModes = getScreenModes(); + String screenFQN = display.getFQName()+idx; + setScreenFQN(screenFQN); + ScreenModeStatus screenModeStatus = new ScreenModeStatus(screenFQN , + getDesktopScreenModeIndex(), getCurrentScreenRate(),getCurrentScreenRotation()); + screenModeStatus.setScreenModes(screenModes); + + screensModeState.setScreenModeController(screenModeStatus); + } + + private void resetScreenMode() { + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + + /**Revert the screen mode and rate + * to original state of creation + */ + if(!sms.isOriginalMode()) { + setScreenMode(sms.getOriginalScreenMode(), + sms.getOriginalScreenRate()); + } + /**Revert Screen Rotation + * to original value + */ + if(!sms.isOriginalRotation()) { + setScreenRotation(sms.getOriginalScreenRotation()); + } + } + + public synchronized final void destroy() { + resetScreenMode(); + + if ( null != aScreen ) { + closeNativeImpl(); + aScreen = null; + } + refCount = 0; + display.removeReference(); + } + + protected synchronized final int addReference() { + if(DEBUG) { + System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1)); + } + if ( 0 == refCount ) { + createNative(); + } + if(null == aScreen) { + throw new RuntimeException("Screen.addReference() (refCount "+refCount+") null AbstractGraphicsScreen"); + } + return ++refCount; + } + + protected synchronized final int removeReference() { + if(DEBUG) { + System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1)); + } + refCount--; // could become < 0, in case of forced destruction without actual creation/addReference + if(0>=refCount && getDestroyWhenUnused()) { + destroy(); + } + return refCount; + } + + public synchronized final int getReferenceCount() { + return refCount; + } + + public final boolean getDestroyWhenUnused() { + return display.getDestroyWhenUnused(); + } + public final void setDestroyWhenUnused(boolean v) { + display.setDestroyWhenUnused(v); + } + + protected abstract void createNativeImpl(); + protected abstract void closeNativeImpl(); + + public int getDesktopScreenModeIndex() { + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + if(sms != null){ + return sms.getCurrentScreenMode(); + } + return -1; + } + + /** + * Get list of available screen modes + * null if not implemented for screen platform + */ + public ScreenMode[] getScreenModes(){ + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + if(sms != null) { + return sms.getScreenModes(); + } + return null; + } + + public void setScreenMode(int modeIndex, short rate) { + } + + public short getCurrentScreenRate() { + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + if(sms != null){ + return sms.getCurrentScreenRate(); + } + return -1; + } + + + public void setScreenRotation(int rot) { + + } + + public int getCurrentScreenRotation() { + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + if(sms != null) { + return sms.getCurrentScreenRotation(); + } + return -1; + } + + /** get the screens mode state handler + * which contain the screen mode controller of each screen + * @return the ScreensModeState static object + */ + protected ScreensModeState getScreensModeState() { + return screensModeState; + } + + public String getScreenFQN() { + return screenFQN; + } + + private void setScreenFQN(String screenFQN) { + this.screenFQN = screenFQN; + } + + protected void setScreenSize(int w, int h) { + System.err.println("Detected screen size "+w+"x"+h); + width=w; height=h; + } + + public final Display getDisplay() { + return display; + } + + public final int getIndex() { + return idx; + } + + public final AbstractGraphicsScreen getGraphicsScreen() { + return aScreen; + } + + public final boolean isNativeValid() { + return null != aScreen; + } + + public final int getWidth() { + return (usrWidth>0) ? usrWidth : (width>0) ? width : 480; + } + + public final int getHeight() { + return (usrHeight>0) ? usrHeight : (height>0) ? height : 480; + } - private static Class getScreenClass(String type) - throws ClassNotFoundException - { - Class screenClass = NewtFactory.getCustomClass(type, "Screen"); - if(null==screenClass) { - if (NativeWindowFactory.TYPE_EGL.equals(type)) { - screenClass = Class.forName("com.jogamp.newt.impl.opengl.kd.KDScreen"); - } else if (NativeWindowFactory.TYPE_WINDOWS.equals(type)) { - screenClass = Class.forName("com.jogamp.newt.impl.windows.WindowsScreen"); - } else if (NativeWindowFactory.TYPE_MACOSX.equals(type)) { - screenClass = Class.forName("com.jogamp.newt.impl.macosx.MacScreen"); - } else if (NativeWindowFactory.TYPE_X11.equals(type)) { - screenClass = Class.forName("com.jogamp.newt.impl.x11.X11Screen"); - } else if (NativeWindowFactory.TYPE_AWT.equals(type)) { - screenClass = Class.forName("com.jogamp.newt.impl.awt.AWTScreen"); - } else { - throw new RuntimeException("Unknown window type \"" + type + "\""); - } - } - return screenClass; - } - - public static ScreenImpl create(String type, Display display, final int idx) { - try { - if(usrWidth<0 || usrHeight<0) { - usrWidth = Debug.getIntProperty("newt.ws.swidth", true, localACC); - usrHeight = Debug.getIntProperty("newt.ws.sheight", true, localACC); - if(usrWidth>0 || usrHeight>0) { - System.err.println("User screen size "+usrWidth+"x"+usrHeight); - } - } - Class screenClass = getScreenClass(type); - ScreenImpl screen = (ScreenImpl) screenClass.newInstance(); - screen.display = (DisplayImpl) display; - screen.idx = idx; - return screen; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - protected synchronized final void createNative() { - if(null == aScreen) { - if(DEBUG) { - System.err.println("Screen.createNative() START ("+DisplayImpl.getThreadName()+", "+this+")"); - } - display.addReference(); - createNativeImpl(); - if(null == aScreen) { - throw new RuntimeException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen"); - } - if(DEBUG) { - System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+")"); - } - } - } - - public synchronized final void destroy() { - if ( null != aScreen ) { - closeNativeImpl(); - aScreen = null; - } - refCount = 0; - display.removeReference(); - } - - protected synchronized final int addReference() { - if(DEBUG) { - System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1)); - } - if ( 0 == refCount ) { - createNative(); - } - if(null == aScreen) { - throw new RuntimeException("Screen.addReference() (refCount "+refCount+") null AbstractGraphicsScreen"); - } - return ++refCount; - } - - protected synchronized final int removeReference() { - if(DEBUG) { - System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1)); - } - refCount--; // could become < 0, in case of forced destruction without actual creation/addReference - if(0>=refCount && getDestroyWhenUnused()) { - destroy(); - } - return refCount; - } - - public synchronized final int getReferenceCount() { - return refCount; - } - - public final boolean getDestroyWhenUnused() { - return display.getDestroyWhenUnused(); - } - public final void setDestroyWhenUnused(boolean v) { - display.setDestroyWhenUnused(v); - } - - protected abstract void createNativeImpl(); - protected abstract void closeNativeImpl(); - - protected void setScreenSize(int w, int h) { - System.err.println("Detected screen size "+w+"x"+h); - width=w; height=h; - } - - public final Display getDisplay() { - return display; - } - - public final int getIndex() { - return idx; - } - - public final AbstractGraphicsScreen getGraphicsScreen() { - return aScreen; - } - - public final boolean isNativeValid() { - return null != aScreen; - } - - public final int getWidth() { - return (usrWidth>0) ? usrWidth : (width>0) ? width : 480; - } - - public final int getHeight() { - return (usrHeight>0) ? usrHeight : (height>0) ? height : 480; - } - - public String toString() { - return "NEWT-Screen[idx "+idx+", refCount "+refCount+", "+getWidth()+"x"+getHeight()+", "+aScreen+", "+display+"]"; - } - - protected DisplayImpl display; - protected int idx; - protected AbstractGraphicsScreen aScreen; - protected int refCount; // number of Screen references by Window - protected int width=-1, height=-1; // detected values: set using setScreenSize - protected static int usrWidth=-1, usrHeight=-1; // property values: newt.ws.swidth and newt.ws.sheight - private static AccessControlContext localACC = AccessController.getContext(); + public String toString() { + return "NEWT-Screen[idx "+idx+", refCount "+refCount+", "+getWidth()+"x"+getHeight()+", "+aScreen+", "+display+"]"; + } } diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreenMode.java b/src/newt/classes/com/jogamp/newt/impl/ScreenMode.java new file mode 100644 index 000000000..2b61d34c4 --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/impl/ScreenMode.java @@ -0,0 +1,76 @@ +package com.jogamp.newt.impl; + +public class ScreenMode { + public static final int ROTATE_0 = 0; + public static final int ROTATE_90 = 90; + public static final int ROTATE_180 = 180; + public static final int ROTATE_270 = 270; + + private int index; + private int width; + private int height; + private int bitsPerPixel = -1; + + private short[] rates = null; + + public ScreenMode(int index, int width, int height) { + this.index = index; + this.width = width; + this.height = height; + } + /** Not safe to use this on platforms + * other than windows. Since the mode ids + * on X11 match the native ids. unlike windows + * where the ids are generated . + * @param index + */ + public void setIndex(int index) { + this.index = index; + } + public int getIndex() { + return index; + } + public int getWidth() { + return width; + } + public void setWidth(int width) { + this.width = width; + } + public int getHeight() { + return height; + } + public void setHeight(int height) { + this.height = height; + } + public short[] getRates() { + return rates; + } + public void setRates(short[] rates) { + this.rates = rates; + } + + public int getBitsPerPixel() { + return bitsPerPixel; + } + + public void setBitsPerPixel(int bitsPerPixel) { + this.bitsPerPixel = bitsPerPixel; + } + + public short getHighestAvailableRate(){ + short highest = rates[0]; + if(rates.length > 1){ + for (int i = 1; i < rates.length; i++) { + if(rates[i] > highest){ + highest = rates[i]; + } + } + } + return highest; + } + + public String toString() { + return "ScreenMode: " + this.index + " - " + this.width + " x " + + this.height + " " + getHighestAvailableRate() + " Hz"; + } +} diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java b/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java new file mode 100644 index 000000000..2ea77c33e --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java @@ -0,0 +1,89 @@ +package com.jogamp.newt.impl; + +public class ScreenModeStatus { + private String screenFQN = null; + private ScreenMode[] screenModes = null; + + private int currentScreenMode = -1; + private short currentScreenRate = -1; + private int currentScreenRotation = -1; + + private int originalScreenMode = -1; + private short originalScreenRate = -1; + private int originalScreenRotation = -1; + + public ScreenModeStatus(String screenFQN, int originalScreenMode, + short originalScreenRate, int originalScreenRotation) { + this.screenFQN = screenFQN; + this.originalScreenMode = originalScreenMode; + this.originalScreenRate = originalScreenRate; + this.originalScreenRotation = originalScreenRotation; + + this.currentScreenMode = originalScreenMode; + this.currentScreenRate = originalScreenRate; + this.currentScreenRotation = originalScreenRotation; + } + + public void setCurrentScreenRotation(int currentScreenRotation) { + this.currentScreenRotation = currentScreenRotation; + } + + public int getCurrentScreenRotation() { + return currentScreenRotation; + } + + public int getOriginalScreenRotation() { + return originalScreenRotation; + } + + public int getCurrentScreenMode() { + return currentScreenMode; + } + + public void setCurrentScreenMode(int currentScreenMode) { + this.currentScreenMode = currentScreenMode; + } + + public short getCurrentScreenRate() { + return currentScreenRate; + } + + public void setCurrentScreenRate(short currentRate) { + this.currentScreenRate = currentRate; + } + + public String getScreenFQN() { + return screenFQN; + } + + public void setScreenFQN(String screenFQN) { + this.screenFQN = screenFQN; + } + + public ScreenMode[] getScreenModes() { + return screenModes; + } + + public void setScreenModes(ScreenMode[] screenModes) { + this.screenModes = screenModes; + } + public boolean isOriginalMode(){ + if(currentScreenMode == originalScreenMode + && currentScreenRate == originalScreenRate) + return true; + return false; + } + public boolean isOriginalRotation(){ + if(currentScreenRotation == originalScreenRotation) + return true; + return false; + } + + public int getOriginalScreenMode() { + return originalScreenMode; + } + + public short getOriginalScreenRate() { + return originalScreenRate; + } +} diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreensModeState.java b/src/newt/classes/com/jogamp/newt/impl/ScreensModeState.java new file mode 100644 index 000000000..e4291496d --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/impl/ScreensModeState.java @@ -0,0 +1,21 @@ +package com.jogamp.newt.impl; + +import java.util.HashMap; + +public class ScreensModeState { + private static HashMap screenModes = new HashMap(); + private static Object lock = new Object(); + + public ScreensModeState(){ + + } + public synchronized void setScreenModeController(ScreenModeStatus screenModeStatus){ + synchronized (lock) { + screenModes.put(screenModeStatus.getScreenFQN(), screenModeStatus); + } + } + + public synchronized ScreenModeStatus getScreenModeController(String screenFQN){ + return (ScreenModeStatus) screenModes.get(screenFQN); + } +} diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java index 5dd2689e5..3cac617ab 100644 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java @@ -33,8 +33,13 @@ package com.jogamp.newt.impl.windows; +import java.util.ArrayList; + import com.jogamp.newt.*; import com.jogamp.newt.impl.ScreenImpl; +import com.jogamp.newt.impl.ScreenMode; +import com.jogamp.newt.impl.ScreenModeStatus; + import javax.media.nativewindow.*; public class WindowsScreen extends ScreenImpl { @@ -52,7 +57,155 @@ public class WindowsScreen extends ScreenImpl { } protected void closeNativeImpl() { } + + public int getDesktopScreenModeIndex() { + int index = super.getDesktopScreenModeIndex(); + if(index == -1) { + /** Set the current screen mode to refering to index zero + * dependent on the impl of getScreenModes which saves the + * current screen mode at index 0 which is the original screen mode + */ + ScreenMode[] screenModes = getScreenModes(); + if(screenModes != null) { + if(screenModes[0] != null) { + index = screenModes[0].getIndex(); + } + } + } + return index; + } + + public void setScreenMode(int modeIndex, short rate) { + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + ScreenMode[] screenModes = sms.getScreenModes(); + + short selectedRate = rate; + int selectedMode = modeIndex; + + if(modeIndex < 0 || (modeIndex > screenModes.length)){ + selectedMode = sms.getOriginalScreenMode(); + } + ScreenMode sm = screenModes[selectedMode]; + + if(selectedRate == -1){ + selectedRate = sms.getOriginalScreenRate(); + } + + boolean rateAvailable = false; + short[] rates = sm.getRates(); + for(int i=0;i<rates.length;i++){ + if(rates[i] == selectedRate){ + rateAvailable = true; + break; + } + } + if(!rateAvailable){ + selectedRate = rates[0]; + } + + if(0 == setScreenMode0(idx, sm.getWidth(), sm.getHeight(), sm.getBitsPerPixel(), selectedRate)){ + sms.setCurrentScreenMode(selectedMode); + sms.setCurrentScreenRate(selectedRate); + } + } + + public short getCurrentScreenRate() { + short rate = super.getCurrentScreenRate(); + if(rate == -1){ + rate = (short)getCurrentScreenRate0(idx); + } + return rate; + } + + public ScreenMode[] getScreenModes() { + ScreenMode[] screenModes = super.getScreenModes(); + if(screenModes == null) { + ArrayList smTemp = new ArrayList(); + + int modeID = -1; + ScreenMode mySM = getScreenMode(modeID++); + int currentBitsPerPixel = mySM.getBitsPerPixel(); + while(mySM != null){ + //filter out modes with diff bits per pixel + if(mySM.getBitsPerPixel() == currentBitsPerPixel) { + smTemp.add(mySM); + } + mySM = getScreenMode(modeID++); + } + int numModes = smTemp.size(); + if(numModes > 0) { + screenModes = new ScreenMode[numModes]; + for(int i=0;i<numModes;i++) { + ScreenMode sm = (ScreenMode)smTemp.get(i); + sm.setIndex(i); + screenModes[i] = sm; + } + } + } + return screenModes; + } + private ScreenMode getScreenMode(int modeIndex) { + int[] modeProp = getScreenMode0(idx, modeIndex); + if(modeProp == null){ + return null; + } + int propIndex = 0; + int width = modeProp[propIndex++]; + int height = modeProp[propIndex++]; + int bits = modeProp[propIndex++]; + short rate = (short)modeProp[propIndex++]; + + ScreenMode screenMode = new ScreenMode(modeIndex+1, width, height); + screenMode.setRates(new short[]{rate}); + screenMode.setBitsPerPixel(bits); + return screenMode; + } + + public void setScreenRotation(int rot) { + if(!isRotationValid(rot)){ + return; + } + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + if(0 == setScreenRotation0(idx, rot)) { + sms.setCurrentScreenRotation(rot); + } + } + + /** Check if this rotation is valid for platform + * @param rot user requested rotation angle + * @return true if is valid + */ + private boolean isRotationValid(int rot){ + if((rot == ScreenMode.ROTATE_0) || (rot == ScreenMode.ROTATE_90) || + (rot == ScreenMode.ROTATE_180) || (rot == ScreenMode.ROTATE_270)) { + return true; + } + return false; + } + + public int getCurrentScreenRotation() { + int rot = super.getCurrentScreenRotation(); + if(rot == -1){ + return getCurrentScreenRotation0(idx); + } + return rot; + } + + // Native calls - private native int getWidthImpl0(int scrn_idx); - private native int getHeightImpl0(int scrn_idx); + private native int getWidthImpl0(int scrn_idx); + private native int getHeightImpl0(int scrn_idx); + + private native int getCurrentScreenRate0(int scrn_idx); + private native int[] getScreenMode0(int screen_index, int mode_index); + + /** Change screen mode and return zero if successful + */ + private native int setScreenMode0(int screen_index, int width, int height, int bits, short freq); + + private native int getCurrentScreenRotation0(int screen_index); + + /** Change screen mode and return zero if successful + */ + private native int setScreenRotation0(int screen_index, int rot); } diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java index 9d4c592c8..f01ffdea4 100644 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java @@ -33,8 +33,10 @@ package com.jogamp.newt.impl.x11; -import com.jogamp.newt.*; import com.jogamp.newt.impl.ScreenImpl; +import com.jogamp.newt.impl.ScreenMode; +import com.jogamp.newt.impl.ScreenModeStatus; + import javax.media.nativewindow.x11.*; public class X11Screen extends ScreenImpl { @@ -58,7 +60,120 @@ public class X11Screen extends ScreenImpl { } protected void closeNativeImpl() { } + + public int getDesktopScreenModeIndex() { + int index = super.getDesktopScreenModeIndex(); + if(index == -1){ + return getDesktopScreenModeIndex0(display.getHandle(), idx); + } + return index; + } + + public void setScreenMode(int modeIndex, short rate) { + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + ScreenMode[] screenModes = sms.getScreenModes(); + + short selectedRate = rate; + int selectedMode = modeIndex; + + if(modeIndex < 0 || (modeIndex > screenModes.length)){ + selectedMode = sms.getOriginalScreenMode(); + } + ScreenMode screenMode = screenModes[selectedMode]; + + if(selectedRate == -1){ + selectedRate = sms.getOriginalScreenRate(); + } + + boolean rateAvailable = false; + short[] rates = screenMode.getRates(); + for(int i=0;i<rates.length;i++){ + if(rates[i] == selectedRate){ + rateAvailable = true; + break; + } + } + if(!rateAvailable){ + selectedRate = rates[0]; + } + + + setScreenMode0(display.getHandle(), idx, selectedMode, selectedRate, getCurrentScreenRotation()); + sms.setCurrentScreenMode(selectedMode); + sms.setCurrentScreenRate(selectedRate); + } + + public short getCurrentScreenRate() { + short rate = super.getCurrentScreenRate(); + if(rate == -1){ + return getCurrentScreenRate0(display.getHandle(), idx); + } + return rate; + } + + public ScreenMode[] getScreenModes() { + ScreenMode[] screenModes = super.getScreenModes(); + if(screenModes == null){ + int numModes = getNumScreenModes0(display.getHandle(), idx); + screenModes = new ScreenMode[numModes]; + for(int i=0; i< numModes; i++){ + screenModes[i] = getScreenMode(i); + } + } + return screenModes; + } + + private ScreenMode getScreenMode(int modeIndex){ + int[] modeProp = getScreenMode0(display.getHandle(), idx, modeIndex); + + if(modeProp == null){ + return null; + } + int propIndex = 0; + int index = modeProp[propIndex++]; + int width = modeProp[propIndex++]; + int height = modeProp[propIndex++]; + + ScreenMode screenMode = new ScreenMode(index, width, height); + + short[] rates = new short[modeProp.length - propIndex]; + for(int i= propIndex; i < modeProp.length; i++) + { + rates[i-propIndex] = (short) modeProp[i]; + } + screenMode.setRates(rates); + return screenMode; + } + + public void setScreenRotation(int rot) { + if(!isRotationValid(rot)){ + return; + } + ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN()); + setScreenRotation0(display.getHandle(), idx, rot); + sms.setCurrentScreenRotation(rot); + } + /** Check if this rotation is valid for platform + * @param rot user requested rotation angle + * @return true if is valid + */ + private boolean isRotationValid(int rot){ + if((rot == ScreenMode.ROTATE_0) || (rot == ScreenMode.ROTATE_90) || + (rot == ScreenMode.ROTATE_180) || (rot == ScreenMode.ROTATE_270)) { + return true; + } + return false; + } + + public int getCurrentScreenRotation() { + int rotation = super.getCurrentScreenRotation(); + if(rotation == -1){ + rotation = getCurrentScreenRotation0(display.getHandle(), idx); + } + return rotation; + } + //---------------------------------------------------------------------- // Internals only // @@ -66,5 +181,17 @@ public class X11Screen extends ScreenImpl { private native long GetScreen0(long dpy, int scrn_idx); private native int getWidth0(long display, int scrn_idx); private native int getHeight0(long display, int scrn_idx); + + private native int getDesktopScreenModeIndex0(long display, int screen_index); + private native short getCurrentScreenRate0(long display, int screen_index); + + private native int getCurrentScreenRotation0(long display, int screen_index); + private native void setScreenRotation0(long display, int screen_index, int rot); + + private native void setScreenMode0(long display, int screen_index, int mode_index, short freq, int rot); + + private native int[] getScreenMode0(long display, int screen_index, int mode_index); + private native int getNumScreenModes0(long display, int screen_index); + } 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 53b222189..06c7dfa99 100644 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java @@ -33,8 +33,6 @@ package com.jogamp.newt.impl.x11; -import com.jogamp.newt.*; -import com.jogamp.newt.event.*; import com.jogamp.newt.impl.WindowImpl; import javax.media.nativewindow.*; import javax.media.nativewindow.x11.*; @@ -104,7 +102,6 @@ public class X11Window extends WindowImpl { reconfigureWindow0( getDisplayHandle(), getScreenIndex(), reqNewParentHandle, getWindowHandle(), x, y, width, height, isVisible(), parentChange, fullScreenChange, decorationChange); - return true; } diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 44f90bc0e..9aac8720c 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -90,6 +90,8 @@ #define MONITOR_DEFAULTTONEAREST 2 #endif +#include "com_jogamp_newt_impl_windows_WindowsDisplay.h" +#include "com_jogamp_newt_impl_windows_WindowsScreen.h" #include "com_jogamp_newt_impl_windows_WindowsWindow.h" #include "MouseEvent.h" @@ -1145,6 +1147,220 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getHeight } /* + * Class: com_jogamp_newt_impl_windows_WindowsScreen + * Method: getCurrentScreenRate0 + * Signature: (I)S + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getCurrentScreenRate0 + (JNIEnv *env, jobject object, jint scrn_idx) +{ + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + int rate = -1; + if (0 != EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm)) + { + rate = dm.dmDisplayFrequency; + } + + return rate; +} + +/* + * Class: com_jogamp_newt_impl_windows_WindowsScreen + * Method: getScreenMode0 + * Signature: (II)[I + */ +JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getScreenMode0 + (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx) +{ + int propIndex = 0; + int prop_size = 4; //wxhxbxf + + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + int devModeID = (int)mode_idx; + + if(devModeID == -1) + { + devModeID = ENUM_CURRENT_SETTINGS; + } + + jintArray properties = (*env)->NewIntArray(env, prop_size); + + //Fill the properties in temp jint array + jint prop[prop_size]; + if (0 == EnumDisplaySettings(NULL /*current display device*/, devModeID, &dm)) + { + return NULL; + } + prop[propIndex++] = dm.dmPelsWidth; + prop[propIndex++] = dm.dmPelsHeight; + prop[propIndex++] = dm.dmBitsPerPel; + prop[propIndex++] = dm.dmDisplayFrequency; + + (*env)->SetIntArrayRegion(env, properties, 0, prop_size, prop); + + return properties; +} + +#define SCREEN_MODE_NOERROR 0 +#define SCREEN_MODE_ERROR 1 +/* + * Class: com_jogamp_newt_impl_windows_WindowsScreen + * Method: setScreenMode0 + * Signature: (IIIIS)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_setScreenMode0 + (JNIEnv *env, jobject object, jint scrn_idx, jint width, jint height, jint bits, jshort rate) +{ + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm)) + { + return SCREEN_MODE_ERROR; + } + + dm.dmPelsWidth = (int)width; + dm.dmPelsHeight = (int)height; + dm.dmBitsPerPel = (int)bits; + dm.dmDisplayFrequency = (int)rate; + dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + + long result = ChangeDisplaySettings(&dm, 0); + if(result == DISP_CHANGE_SUCCESSFUL) + { + return SCREEN_MODE_NOERROR; + } + return SCREEN_MODE_ERROR; +} + +#define SCREEN_ROT_ERROR -1 +/* + * Class: com_jogamp_newt_impl_windows_WindowsScreen + * Method: getCurrentScreenRotation0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getCurrentScreenRotation0 + (JNIEnv *env, jobject object, jint scrn_idx) +{ + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm)) + { + return SCREEN_ROT_ERROR; + } + + int currentRotation = -1; + switch (dm.dmDisplayOrientation) + { + case DMDO_DEFAULT: + currentRotation = 0; + break; + case DMDO_270: + currentRotation = 270; + break; + case DMDO_180: + currentRotation = 180; + break; + case DMDO_90: + currentRotation = 90; + break; + default: + break; + } + return currentRotation; +} +/* + * Class: com_jogamp_newt_impl_windows_WindowsScreen + * Method: setScreenRotation0 + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_setScreenRotation0 + (JNIEnv *env, jobject object, jint scrn_idx, jint rot) +{ + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm)) + { + return SCREEN_MODE_ERROR; + } + int requestedRotation = dm.dmDisplayOrientation; + int currentRotation = dm.dmDisplayOrientation; + + int shouldFlipDims = 0; + + int rotation = (int)rot; + switch (rotation) + { + case 0: + requestedRotation = DMDO_DEFAULT; + if (currentRotation == DMDO_90 || currentRotation == DMDO_270) + { + shouldFlipDims = 1; + } + break; + case 270: + requestedRotation = DMDO_270; + if (currentRotation == DMDO_DEFAULT || currentRotation == DMDO_180) + { + shouldFlipDims = 1; + } + break; + case 180: + requestedRotation = DMDO_180; + if (currentRotation == DMDO_90 || currentRotation == DMDO_270) + { + shouldFlipDims = 1; + } + break; + case 90: + requestedRotation = DMDO_90; + if (currentRotation == DMDO_DEFAULT || currentRotation == DMDO_180) + { + shouldFlipDims = 1; + } + break; + default: + //requested rotation not available + return SCREEN_MODE_ERROR; + break; + } + /** swap width and height if changing from vertical to horizantal + * or horizantal to vertical + */ + if (shouldFlipDims) + { + int tempWidth = dm.dmPelsWidth; + dm.dmPelsWidth = dm.dmPelsHeight; + dm.dmPelsHeight = tempWidth; + } + dm.dmDisplayOrientation = requestedRotation; + dm.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + + long result = ChangeDisplaySettings(&dm, 0); + if(result == DISP_CHANGE_SUCCESSFUL) + { + return SCREEN_MODE_NOERROR; + } + return SCREEN_MODE_ERROR; +} + +/* * Class: com_jogamp_newt_impl_windows_WindowsWindow * Method: initIDs0 * Signature: ()Z @@ -1407,6 +1623,38 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setVisibl } } +#define FULLSCREEN_NOERROR 0 +#define FULLSCREEN_ERROR 1 + +static int NewtWindows_setFullScreen(jboolean fullscreen) +{ + int flags = 0; + DEVMODE dm; + // initialize the DEVMODE structure + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm)) + { + return FULLSCREEN_ERROR; + } + + if(fullscreen == JNI_TRUE) + { + flags = CDS_FULLSCREEN; //set fullscreen temporary + } + else + { + flags = CDS_RESET; // reset to registery values + } + long result = ChangeDisplaySettings(&dm, flags); + if(result == DISP_CHANGE_SUCCESSFUL) + { + return FULLSCREEN_NOERROR; + } + return FULLSCREEN_ERROR; +} + /* * Class: com_jogamp_newt_impl_windows_WindowsWindow * Method: reconfigureWindow0 @@ -1439,6 +1687,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reconfigu if(JNI_TRUE == visible) { windowStyle |= WS_VISIBLE ; } + + if(fullScreenChange < 0) + { + NewtWindows_setFullScreen(JNI_FALSE); + } // order of call sequence: (MS documentation) // TOP: SetParent(.., NULL); Clear WS_CHILD [, Set WS_POPUP] @@ -1447,6 +1700,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reconfigu if ( JNI_TRUE == parentChange && NULL == hwndP ) { SetParent(hwnd, NULL); } + + if(fullScreenChange > 0) + { + NewtWindows_setFullScreen(JNI_TRUE); + } if ( styleChange ) { if(NULL!=hwndP) { diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 0cdf6ae57..6c6aff478 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -48,6 +48,10 @@ #include <X11/keysym.h> #include <X11/Xatom.h> +#include<X11/extensions/Xrandr.h> + +#include "com_jogamp_newt_impl_x11_X11Screen.h" +#include "com_jogamp_newt_impl_x11_X11Display.h" #include "com_jogamp_newt_impl_x11_X11Window.h" #include "MouseEvent.h" @@ -476,6 +480,8 @@ static void NewtWindows_setDecorations (Display *dpy, Window w, Bool decorated) #define _NET_WM_STATE_REMOVE 0 #define _NET_WM_STATE_ADD 1 + + static void NewtWindows_setFullscreen (Display *dpy, Window root, Window w, Bool fullscreen) { Atom _NET_WM_STATE = XInternAtom( dpy, "_NET_WM_STATE", False ); Atom _NET_WM_STATE_ABOVE = XInternAtom( dpy, "_NET_WM_STATE_ABOVE", False ); @@ -506,6 +512,7 @@ static void NewtWindows_setFullscreen (Display *dpy, Window root, Window w, Bool xev.xclient.data.l[2] = _NET_WM_STATE_ABOVE; xev.xclient.data.l[3] = 1; //source indication for normal applications } + XChangeProperty( dpy, w, _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes); XSync(dpy, False); XSendEvent (dpy, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xev ); @@ -837,6 +844,256 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getHeight0 return (jint) XDisplayHeight( dpy, scrn_idx); } +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: getDesktopScreenModeIndex0 + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getDesktopScreenModeIndex0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + // get current resolutions and frequency configuration + XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); + short original_rate = XRRConfigCurrentRate(conf); + + Rotation original_rotation; + SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation); + + //free + XRRFreeScreenConfigInfo(conf); + + return (jint)original_size_id; +} + +static void X11Screen_changeScreenMode(Display* dpy, Window root, int screen_indx, XRRScreenSize *xrrs, int screenModeIndex, short freq, int rotation) +{ + int num_rates; //number of available rates for selected mode index + short *rates = XRRRates(dpy, screen_indx, screenModeIndex, &num_rates); + + XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); + + int rot = RR_Rotate_0; + + if(rotation == 90) + { + rot = RR_Rotate_90; + } + else if(rotation == 180) + { + rot = RR_Rotate_180; + } + else if(rotation == 270) + { + rot = RR_Rotate_270; + } + // Change the resolution + DBG_PRINT("\nCHANGED TO %i x %i PIXELS, %i Hz\n\n", xrrs[screenModeIndex].width, xrrs[screenModeIndex].height, selectedFreq); + XRRSetScreenConfigAndRate(dpy, conf, root, screenModeIndex, rot, freq, CurrentTime); + + //free + XRRFreeScreenConfigInfo(conf); +} + +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: setScreenMode0 + * Signature: (JIIS)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setScreenMode0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx, jint mode_indx, jshort freq, jint rotation) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + int num_sizes; + XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_indx, &num_sizes); //get possible screen resolutions + int screenModeIndex = (int)mode_indx; + + if((screenModeIndex > num_sizes) || (screenModeIndex < 0)) + { + DBG_PRINT("\nSelected mode index not available for selected screen, index: %i\n", screenModeIndex); + return; + } + + X11Screen_changeScreenMode(dpy, root, (int)scrn_indx, xrrs, screenModeIndex, (short)freq, (int)rotation); +} + +#define NUM_SCREEN_MODE_PROPERTIES 3 + +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: getScreenMode0 + * Signature: (JII)[I + */ +JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getScreenMode0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx, jint mode_indx) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + int num_sizes; + XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_indx, &num_sizes); //get possible screen resolutions + + int num_rates; + short *rates = XRRRates(dpy, (int)scrn_indx, (int)mode_indx, &num_rates); + + int prop_size = NUM_SCREEN_MODE_PROPERTIES +num_rates; + + jintArray properties = (*env)->NewIntArray(env, prop_size); + if (properties == NULL) + { + return NULL; /* out of memory error thrown */ + } + + //Fill the properties in temp jint array + int propIndex = 0; + jint prop[prop_size]; + + prop[propIndex++] = (int)mode_indx; + prop[propIndex++] = xrrs[(int)mode_indx].width; + prop[propIndex++] = xrrs[(int)mode_indx].height; + + //loop through all possible resolutions + //with the selectable display frequencies + int i= 0; + while(i < num_rates) + { + prop[propIndex++] = rates[i]; + i++; + } + + + // move from the temp structure to the java structure + (*env)->SetIntArrayRegion(env, properties, 0, prop_size, prop); + + return properties; +} + +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: getNumScreenModes0 + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getNumScreenModes0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + int num_sizes; + XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_indx, &num_sizes); //get possible screen resolutions + + return num_sizes; +} + + +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: getCurrentScreenRate0 + * Signature: (JI)S + */ +JNIEXPORT jshort JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenRate0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + // get current resolutions and frequencies + XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); + short original_rate = XRRConfigCurrentRate(conf); + + //free + XRRFreeScreenConfigInfo(conf); + + return original_rate; +} + +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: getCurrentScreenRotation0 + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenRotation0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + //get current resolutions and frequencies + XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); + + Rotation rotation; + XRRConfigCurrentConfiguration(conf, &rotation); + + //free + XRRFreeScreenConfigInfo(conf); + + int rot = -1; + + if(rotation == RR_Rotate_0) { + rot = 0; + } + else if(rotation == RR_Rotate_90) { + rot = 90; + } + else if(rotation == RR_Rotate_180) { + rot = 180; + } + else if(rotation == RR_Rotate_270) { + rot = 270; + } + + return rot; +} + +/* + * Class: com_jogamp_newt_impl_x11_X11Screen + * Method: setScreenRotation0 + * Signature: (JII)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setScreenRotation0 + (JNIEnv *env, jobject object, jlong display, jint scrn_indx, jint rotation) +{ + Display *dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)scrn_indx); + + int rot = -1; + + if(rotation == 0) + { + rot = RR_Rotate_0; + } + else if(rotation == 90) + { + rot = RR_Rotate_90; + } + else if(rotation == 180) + { + rot = RR_Rotate_180; + } + else if(rotation == 270) + { + rot = RR_Rotate_270; + } + else + { + return; + } + + XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); + + Rotation current_rotation; + SizeID current_mode_id = XRRConfigCurrentConfiguration(conf, ¤t_rotation); + short current_rate = XRRConfigCurrentRate(conf); + + XRRSetScreenConfigAndRate(dpy, conf, root, current_mode_id, rot, current_rate, CurrentTime); + + //free + XRRFreeScreenConfigInfo(conf); +} /** * Window @@ -1159,6 +1416,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow NewtWindows_setPosSize(dpy, w, x, y, width, height); + if(0 < fullscreenChange ) { // FS on NewtWindows_setFullscreen(dpy, root, w, True ); XSync(dpy, False); |