diff options
Diffstat (limited to 'src/newt/classes')
7 files changed, 485 insertions, 150 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java index f1b4254d8..14de2f0da 100644 --- a/src/newt/classes/com/jogamp/newt/Screen.java +++ b/src/newt/classes/com/jogamp/newt/Screen.java @@ -29,6 +29,9 @@ package com.jogamp.newt; import com.jogamp.newt.impl.Debug; +import com.jogamp.newt.impl.ScreenMode; +import com.jogamp.newt.impl.ScreensModeState; + import javax.media.nativewindow.AbstractGraphicsScreen; public interface Screen { @@ -67,4 +70,35 @@ 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); } diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java b/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java index 1a76152f6..793c278a1 100644 --- a/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java +++ b/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java @@ -37,153 +37,235 @@ 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()); + 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()); + } + } + + 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; + } + + /** 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..22ed07250 --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/impl/ScreenMode.java @@ -0,0 +1,36 @@ +package com.jogamp.newt.impl; + +public class ScreenMode { + private int index; + private int width; + private int height; + private short[] rates = null; + + public ScreenMode(int index, int width, int height) { + this.index = index; + this.width = width; + this.height = height; + } + + 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; + } +} 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..b5b95da6a --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java @@ -0,0 +1,68 @@ +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 originalScreenMode = -1; + private short originalScreenRate = -1; + + public ScreenModeStatus(String screenFQN, int originalScreenMode, + short originalScreenRate) { + this.screenFQN = screenFQN; + this.originalScreenMode = originalScreenMode; + this.originalScreenRate = originalScreenRate; + + this.currentScreenMode = originalScreenMode; + this.currentScreenRate = originalScreenRate; + } + + 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 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/x11/X11Screen.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java index 9d4c592c8..79ccf5a7d 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,91 @@ 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); + 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; + } + //---------------------------------------------------------------------- // Internals only // @@ -66,5 +152,14 @@ 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 void setScreenMode0(long display, int screen_index, int mode_index, short freq); + + 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 80e5068b4..48352ee97 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.*; @@ -105,7 +103,8 @@ public class X11Window extends WindowImpl { protected void reconfigureWindowImpl(int x, int y, int width, int height) { reconfigureWindow0(fullscreen?0:getParentWindowHandle(), getDisplayHandle(), getScreenIndex(), getWindowHandle(), - x, y, width, height, isUndecorated(), isVisible()); + x, y, width, height, isUndecorated(), isVisible(),isFullscreen()); + } protected boolean reparentWindowImpl() { @@ -136,13 +135,13 @@ public class X11Window extends WindowImpl { private native void setVisible0(long display, long windowHandle, boolean visible); private native void setSize0(long display, long windowHandle, int width, int height); private native void reconfigureWindow0(long parentWindowHandle, long display, int screen_index, long windowHandle, - int x, int y, int width, int height, boolean undecorated, boolean isVisible); + int x, int y, int width, int height, boolean undecorated, boolean isVisible, boolean fullscreen); private native void setTitle0(long display, long windowHandle, String title); private native void requestFocus0(long display, long windowHandle, boolean reparented); private native void setPosition0(long parentWindowHandle, long display, long windowHandle, int x, int y); private native void reparentWindow0(long parentWindowHandle, long display, int screen_index, long windowHandle, int x, int y, boolean undecorated, boolean isVisible); - + private void windowCreated(long windowHandle) { setWindowHandle(windowHandle); } |