aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
authorRami Santina <[email protected]>2010-10-17 03:36:59 +0300
committerRami Santina <[email protected]>2010-10-17 03:36:59 +0300
commit735ebb60ead9996106dfcb958ddfbb6b00b407fd (patch)
treebf393633d7fffc754ef6928aba6cc63abd299e53 /src/newt
parent774138544e1eec3330309ad682fa05154a07ab8d (diff)
Screen Mode manipulation API (with X11 impl) ; X11 Fullscreen impl
Added screen mode change capability with impl for X11 (using Xrandr) com.jogamp.newt.Screen: added 4 methods which cover screen mode lifecycle ScreenMode[] getScreenModes(): Get list of available screen modes returns null if not natively implemented. On first call will fetch the list thru a set of native calls and stores them in the ScreenModeState. Consequent calls will retreive the data from the ScreenModeStatus object. Native calls are done on creation stage, so subsequent API calls will return cached data. int getDesktopScreenModeIndex(): Get the Current Desktop Screen mode index returns -1 if functionality not natively implemented. The index returned refers to the screen mode location in the ScreenMode array. Used to get initial mode for reverting back. Initial call will retreive the mode thru a native call (done on initialization), subsequent API calls will retreive it from the ScreenModeStatus object. Note: If Window is closed without reverting back and screen is set to unreachable. The api will revert the screen. A call to destoy(unreachable) is needed for revert to take place on close windowDestroyNotify(WindowEvent e) { ... window.destroy(true); } short getCurrentScreenRate(): Get the current screen rate returns -1 if not natively implemented. Used along with getDesktopScreenModeIndex You can identify the current screen mode (w x h) and the rate. Initial call will retreive the mode thru a native call (done on initialization), subsequent API calls will retreive it from the ScreenModeStatus object. void setScreenMode(int modeIndex, short rate): change the screen mode to the mode index which refers to one of the screen modes retreived by getScreenModes() and a rate which can be one of screenModes.getRates(). If the rate provided doesnt belong to the list of available rates the first rate is chosen. build-newt.xml: Added header files generation for Screen and Display Added Xrandr syslink to x11 based builds. +++++++++++++ Fullscreen for X11Window: Added Fullscreen WM Hint for X11Window. Event of Fullscreen is sent to the display root. When changing to fullscreen the request is send after configuring the window otherwize before decoration. Not Stable yet, needs tweeking on other Linux dist. Window looses focus after switching to fullscreen mode. +++++++++++++++ Added TestScreenMode01NEWT which includes 4 tests 1- Fullscreen change mode 2- Screen mode change 3- Screen change with fullscreen (revert screenmode then revert fullscreen) 4- Screen change with fullscreen (revert fullscreen then revert screenmode) should fail if not screenmode not implemented on platform. +++++++++++++++ Cleaned up some unused imports
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java34
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java370
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/ScreenMode.java36
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java68
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/ScreensModeState.java21
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java97
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java9
-rw-r--r--src/newt/native/X11Window.c215
8 files changed, 695 insertions, 155 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);
}
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 8a07067b7..26bce0c63 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"
@@ -463,6 +467,44 @@ static void NewtWindows_setDecorations (Display *dpy, Window w, Bool decorated)
XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes);
}
+#define _NET_WM_STATE_REMOVE 0
+#define _NET_WM_STATE_ADD 1
+
+static void NewtWindows_setFullscreen (Display *dpy, 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 );
+ Atom _NET_WM_STATE_FULLSCREEN = XInternAtom( dpy, "_NET_WM_STATE_FULLSCREEN", False );
+
+ Atom types[2]={0};
+ int ntypes=0;
+
+ types[ntypes++] = _NET_WM_STATE_FULLSCREEN;
+ types[ntypes++] = _NET_WM_STATE_ABOVE;
+
+ XEvent xev;
+ memset ( &xev, 0, sizeof(xev) );
+
+ xev.type = ClientMessage;
+ xev.xclient.window = w;
+ xev.xclient.message_type = _NET_WM_STATE;
+ xev.xclient.format = 32;
+
+ if(True==fullscreen) {
+ xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
+ xev.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
+ xev.xclient.data.l[2] = _NET_WM_STATE_ABOVE;
+ xev.xclient.data.l[3] = 1; //source indication for normal applications
+ } else {
+ xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
+ xev.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
+ 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);
+ XSendEvent (dpy, DefaultRootWindow(dpy), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev );
+}
+
/*
* Class: com_jogamp_newt_impl_x11_X11Display
* Method: DispatchMessages
@@ -690,6 +732,158 @@ 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 num_rates; //number of available rates for selected mode index
+ short *rates = XRRRates(dpy, screen_indx, screenModeIndex, &num_rates);
+
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+
+ // 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, RR_Rotate_0, 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)
+{
+ 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);
+}
+
+#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;
+}
/**
* Window
@@ -1037,7 +1231,7 @@ static void NewtWindows_reparentWindow
*/
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow0
(JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window,
- jint x, jint y, jint width, jint height, jboolean undecorated, jboolean isVisible)
+ jint x, jint y, jint width, jint height, jboolean undecorated, jboolean isVisible, jboolean isFullscreen)
{
Display * dpy = (Display *) (intptr_t) display;
Window w = (Window)window;
@@ -1045,17 +1239,23 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow
XWindowChanges xwc;
XWindowAttributes xwa;
-
- DBG_PRINT( "X11: reconfigureWindow0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d, visible %d\n",
- (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated, isVisible);
+
+ DBG_PRINT( "X11: reconfigureWindow0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d, visible %d, fullscreen %d\n",
+ (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated, isVisible,isFullscreen);
if(dpy==NULL) {
_FatalError(env, "invalid display connection..");
}
+
XSync(dpy, False);
XGetWindowAttributes(dpy, w, &xwa);
-
+
+ if(JNI_FALSE == isFullscreen ) {
+ NewtWindows_setFullscreen(dpy, w, False );
+ XSync(dpy, False);
+ }
+
NewtWindows_reparentWindow(env, obj, dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible);
XSync(dpy, False);
@@ -1066,6 +1266,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow
xwc.height=height;
XConfigureWindow(dpy, w, CWX|CWY|CWWidth|CWHeight, &xwc);
XSync(dpy, False);
+
+ if(JNI_TRUE == isFullscreen ) {
+ NewtWindows_setFullscreen(dpy, w, True );
+ XSync(dpy, False);
+ }
}
/*