aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-04-18 08:31:11 +0200
committerSven Gothel <[email protected]>2013-04-18 08:31:11 +0200
commitd173feb60d085399194549102d4b3d77512c3f73 (patch)
tree77aaef10eca29c3b91fdca5621bcfdfa57558672
parentf8adb848c0d6b61a8a34dfcdaf13ca773000fbb4 (diff)
Bug 721: NEWT/X11 RandR 1.3 Support - Part 1 - Delegate RandR functionality to pluggable impl. for RandR 1.1 and 1.3 (todo)
-rw-r--r--make/build-newt.xml24
-rwxr-xr-xmake/scripts/tests.sh4
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java10
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java225
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/ScreenRandR.java12
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/ScreenRandR11.java214
-rw-r--r--src/newt/native/X11Common.h3
-rw-r--r--src/newt/native/X11Screen.c397
-rw-r--r--src/newt/native/X11Screen.h39
-rw-r--r--src/newt/native/X11ScreenRandR11.c232
10 files changed, 501 insertions, 659 deletions
diff --git a/make/build-newt.xml b/make/build-newt.xml
index c601bc120..d728b42c7 100644
--- a/make/build-newt.xml
+++ b/make/build-newt.xml
@@ -584,19 +584,20 @@
<patternset id="c.src.files.newt">
<include name="${rootrel.src.c}/NewtCommon.c" />
<!-- include name="${rootrel.src.c}/timespec.c" /--> <!-- currently used for X11 and OSX with special PERF DEBUG MODE-->
- <include name="${rootrel.src.c}/WindowsWindow.c" if="isWindows"/>
- <include name="${rootrel.src.c}/MacWindow.m" if="isOSX"/>
- <include name="${rootrel.src.c}/NewtMacWindow.m" if="isOSX"/>
- <include name="${rootrel.src.c}/AndroidWindow.c" if="isAndroid"/>
- <include name="${rootrel.src.c}/X11Display.c" if="isX11"/>
+ <include name="${rootrel.src.c}/WindowsWindow.c" if="isWindows"/>
+ <include name="${rootrel.src.c}/MacWindow.m" if="isOSX"/>
+ <include name="${rootrel.src.c}/NewtMacWindow.m" if="isOSX"/>
+ <include name="${rootrel.src.c}/AndroidWindow.c" if="isAndroid"/>
+ <include name="${rootrel.src.c}/X11Display.c" if="isX11"/>
<!-- include name="${rootrel.src.c}/X11Event.c" if="isX11"/-->
<!-- include name="${rootrel.src.c}/XCBEvent.c" if="isX11"/-->
- <include name="${rootrel.src.c}/X11Screen.c" if="isX11"/>
- <include name="${rootrel.src.c}/X11Window.c" if="isX11"/>
- <include name="${rootrel.src.c}/KDWindow.c" if="setup.addNativeKD"/>
- <include name="${rootrel.src.c}/IntelGDL.c" if="setup.addNativeIntelGDL"/>
- <include name="${rootrel.src.c}/bcm_egl.c" if="setup.addNativeBroadcom"/>
- <include name="${rootrel.src.c}/bcm_vc_iv.c" if="setup.addNativeBroadcom"/>
+ <include name="${rootrel.src.c}/X11Screen.c" if="isX11"/>
+ <include name="${rootrel.src.c}/X11ScreenRandR11.c" if="isX11"/>
+ <include name="${rootrel.src.c}/X11Window.c" if="isX11"/>
+ <include name="${rootrel.src.c}/KDWindow.c" if="setup.addNativeKD"/>
+ <include name="${rootrel.src.c}/IntelGDL.c" if="setup.addNativeIntelGDL"/>
+ <include name="${rootrel.src.c}/bcm_egl.c" if="setup.addNativeBroadcom"/>
+ <include name="${rootrel.src.c}/bcm_vc_iv.c" if="setup.addNativeBroadcom"/>
</patternset>
<echo message="Compiling @{output.lib.name}" />
@@ -700,6 +701,7 @@
<javah destdir="${src.generated.c}/MacOSX" classpath="${javah.classpath}" class="jogamp.newt.driver.macosx.DisplayDriver" />
<javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.newt.driver.x11.WindowDriver" />
<javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.newt.driver.x11.ScreenDriver" />
+ <javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.newt.driver.x11.ScreenRandR11" />
<javah destdir="${src.generated.c}/X11" classpath="${javah.classpath}" class="jogamp.newt.driver.x11.DisplayDriver" />
</target>
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 23dbf3fd0..d9d5cd622 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -289,7 +289,7 @@ function testawtswt() {
#testswt com.jogamp.opengl.test.junit.jogl.demos.es2.swt.TestGearsES2SWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWTAnalyzeBug455 $*
-testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWTBug450 $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $*
@@ -378,7 +378,7 @@ testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.TestGLWindowInvisiblePointer01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle02NEWT
-#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT $*
+testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00bNEWT
#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT
#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01bNEWT
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index 56d6f67ff..1282e5dc5 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -61,11 +61,11 @@ import com.jogamp.newt.util.ScreenModeUtil;
public abstract class ScreenImpl extends Screen implements ScreenModeListener {
protected static final boolean DEBUG_TEST_SCREENMODE_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableScreenMode", true);
- protected static final int default_sm_bpp = 32;
- protected static final int default_sm_widthmm = 519;
- protected static final int default_sm_heightmm = 324;
- protected static final int default_sm_rate = 60;
- protected static final int default_sm_rotation = 0;
+ public static final int default_sm_bpp = 32;
+ public static final int default_sm_widthmm = 519;
+ public static final int default_sm_heightmm = 324;
+ public static final int default_sm_rate = 60;
+ public static final int default_sm_rotation = 0;
protected DisplayImpl display;
protected int screen_idx;
diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
index 7a3c718c0..d94f27371 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
@@ -43,10 +43,10 @@ import jogamp.newt.DisplayImpl;
import jogamp.newt.DisplayImpl.DisplayRunnable;
import jogamp.newt.ScreenImpl;
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.util.ScreenModeUtil;
public class ScreenDriver extends ScreenImpl {
@@ -65,172 +65,63 @@ public class ScreenDriver extends ScreenImpl {
} } );
if (handle.longValue() == 0) {
throw new RuntimeException("Error creating screen: " + screen_idx);
- }
- aScreen = new X11GraphicsScreen((X11GraphicsDevice) getDisplay().getGraphicsDevice(), screen_idx);
+ }
+ final X11GraphicsDevice x11dev = (X11GraphicsDevice) getDisplay().getGraphicsDevice();
+ final long dpy = x11dev.getHandle();
+ aScreen = new X11GraphicsScreen(x11dev, screen_idx);
+ {
+ int v[] = getRandRVersion0(dpy);
+ randrVersion = new VersionNumber(v[0], v[1], 0);
+ }
+ System.err.println("RandR "+randrVersion);
+ if( !randrVersion.isZero() ) {
+ screenRandR = new ScreenRandR11();
+ } else {
+ screenRandR = null;
+ }
}
protected void closeNativeImpl() {
}
- private int[] nrotations;
- private int nrotation_index;
- private int nres_number;
- private int nres_index;
- private int[] nrates;
- private int nrate_index;
- private int nmode_number;
-
+ private VersionNumber randrVersion;
+ private ScreenRandR screenRandR;
+
+ @Override
protected int[] getScreenModeFirstImpl() {
+ if( null == screenRandR ) { return null; }
+
return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() {
public int[] run(long dpy) {
- // initialize iterators and static data
- nrotations = getAvailableScreenModeRotations0(dpy, screen_idx);
- if(null==nrotations || 0==nrotations.length) {
- return null;
- }
- nrotation_index = 0;
-
- nres_number = getNumScreenModeResolutions0(dpy, screen_idx);
- if(0==nres_number) {
- return null;
- }
- nres_index = 0;
-
- nrates = getScreenModeRates0(dpy, screen_idx, nres_index);
- if(null==nrates || 0==nrates.length) {
- return null;
- }
- nrate_index = 0;
-
- nmode_number = 0;
-
- return getScreenModeNextImpl();
+ return screenRandR.getScreenModeFirstImpl(dpy, screen_idx);
} } );
}
+ @Override
protected int[] getScreenModeNextImpl() {
+ if( null == screenRandR ) { return null; }
+
// assemble: w x h x bpp x f x r
return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() {
public int[] run(long dpy) {
- /**
- System.err.println("******** mode: "+nmode_number);
- System.err.println("rot "+nrotation_index);
- System.err.println("rate "+nrate_index);
- System.err.println("res "+nres_index); */
-
- int[] res = getScreenModeResolution0(dpy, screen_idx, nres_index);
- if(null==res || 0==res.length) {
- return null;
- }
- if(0>=res[0] || 0>=res[1]) {
- throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number);
- }
- int rate = nrates[nrate_index];
- if(0>=rate) {
- rate = default_sm_rate;
- if(DEBUG) {
- System.err.println("Invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length+", using default: "+default_sm_rate);
- }
- }
- int rotation = nrotations[nrotation_index];
-
- int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ];
- int i = 0;
- props[i++] = nres_index; // use resolution index, not unique for native -> ScreenMode
- props[i++] = 0; // set later for verification of iterator
- props[i++] = res[0]; // width
- props[i++] = res[1]; // height
- props[i++] = default_sm_bpp; // FIXME
- props[i++] = res[2]; // widthmm
- props[i++] = res[3]; // heightmm
- props[i++] = rate; // rate
- props[i++] = rotation;
- props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i - 1; // count without extra element
-
- nmode_number++;
-
- // iteration: r -> f -> bpp -> [w x h]
- nrotation_index++;
- if(nrotation_index == nrotations.length) {
- nrotation_index=0;
- nrate_index++;
- if(null == nrates || nrate_index == nrates.length){
- nres_index++;
- if(nres_index == nres_number) {
- // done
- nrates=null;
- nrotations=null;
- return null;
- }
-
- nrates = getScreenModeRates0(dpy, screen_idx, nres_index);
- if(null==nrates || 0==nrates.length) {
- return null;
- }
- nrate_index = 0;
- }
- }
-
- return props;
+ return screenRandR.getScreenModeNextImpl(dpy, screen_idx);
} } );
}
+ @Override
protected ScreenMode getCurrentScreenModeImpl() {
+ if( null == screenRandR ) { return null; }
+
return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<ScreenMode>() {
public ScreenMode run(long dpy) {
- long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
- if(0 == screenConfigHandle) {
- return null;
- }
- int[] res;
- int rate, rot;
- try {
- int resNumber = getNumScreenModeResolutions0(dpy, screen_idx);
- if(0==resNumber) {
- return null;
- }
-
- int resIdx = getCurrentScreenResolutionIndex0(screenConfigHandle);
- if(0>resIdx) {
- return null;
- }
- if(resIdx>=resNumber) {
- throw new RuntimeException("Invalid resolution index: ! "+resIdx+" < "+resNumber);
- }
- res = getScreenModeResolution0(dpy, screen_idx, resIdx);
- if(null==res || 0==res.length) {
- return null;
- }
- if(0>=res[0] || 0>=res[1]) {
- throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber);
- }
- rate = getCurrentScreenRate0(screenConfigHandle);
- if(0>rate) {
- return null;
- }
- rot = getCurrentScreenRotation0(screenConfigHandle);
- if(0>rot) {
- return null;
- }
- } finally {
- freeScreenConfiguration0(screenConfigHandle);
- }
- int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
- int i = 0;
- props[i++] = 0; // set later for verification of iterator
- props[i++] = res[0]; // width
- props[i++] = res[1]; // height
- props[i++] = default_sm_bpp; // FIXME
- props[i++] = res[2]; // widthmm
- props[i++] = res[3]; // heightmm
- props[i++] = rate; // rate
- props[i++] = rot;
- props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count
- return ScreenModeUtil.streamIn(props, 0);
+ return screenRandR.getCurrentScreenModeImpl(dpy, screen_idx);
} } );
}
+ @Override
protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) {
+ if( null == screenRandR ) { return false; }
+
final List<ScreenMode> screenModes = this.getScreenModesOrig();
final int screenModeIdx = screenModes.indexOf(screenMode);
if(0>screenModeIdx) {
@@ -239,33 +130,8 @@ public class ScreenDriver extends ScreenImpl {
final long t0 = System.currentTimeMillis();
boolean done = runWithTempDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
- boolean done = false;
- long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
- if(0 == screenConfigHandle) {
- return Boolean.valueOf(done);
- }
- try {
- int resNumber = getNumScreenModeResolutions0(dpy, screen_idx);
- int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx);
- if(0>resIdx || resIdx>=resNumber) {
- throw new RuntimeException("Invalid resolution index: ! 0 < "+resIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode);
- }
-
- final int f = screenMode.getMonitorMode().getRefreshRate();
- final int r = screenMode.getRotation();
-
- if( setCurrentScreenModeStart0(dpy, screen_idx, screenConfigHandle, resIdx, f, r) ) {
- while(!done && System.currentTimeMillis()-t0 < SCREEN_MODE_CHANGE_TIMEOUT) {
- done = setCurrentScreenModePollEnd0(dpy, screen_idx, resIdx, f, r);
- if(!done) {
- try { Thread.sleep(10); } catch (InterruptedException e) { }
- }
- }
- }
- } finally {
- freeScreenConfiguration0(screenConfigHandle);
- }
- return Boolean.valueOf(done);
+ final int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx);
+ return Boolean.valueOf( screenRandR.setCurrentScreenModeImpl(dpy, screen_idx, screenMode, screenModeIdx, resIdx) );
}
}).booleanValue();
@@ -328,25 +194,6 @@ public class ScreenDriver extends ScreenImpl {
private static native int getWidth0(long display, int scrn_idx);
private static native int getHeight0(long display, int scrn_idx);
-
- /** @return int[] { rot1, .. } */
- private static native int[] getAvailableScreenModeRotations0(long display, int screen_index);
-
- private static native int getNumScreenModeResolutions0(long display, int screen_index);
-
- /** @return int[] { width, height, widthmm, heightmm } */
- private static native int[] getScreenModeResolution0(long display, int screen_index, int mode_index);
-
- private static native int[] getScreenModeRates0(long display, int screen_index, int mode_index);
-
- private static native long getScreenConfiguration0(long display, int screen_index);
- private static native void freeScreenConfiguration0(long screenConfiguration);
- private static native int getCurrentScreenResolutionIndex0(long screenConfiguration);
- private static native int getCurrentScreenRate0(long screenConfiguration);
- private static native int getCurrentScreenRotation0(long screenConfiguration);
-
- /** needs own Display connection for XRANDR event handling */
- private static native boolean setCurrentScreenModeStart0(long display, int screen_index, long screenConfiguration, int mode_index, int freq, int rot);
- private static native boolean setCurrentScreenModePollEnd0(long display, int screen_index, int mode_index, int freq, int rot);
+ private static native int[] getRandRVersion0(long display);
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR.java
new file mode 100644
index 000000000..abf20ba59
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR.java
@@ -0,0 +1,12 @@
+package jogamp.newt.driver.x11;
+
+import com.jogamp.newt.ScreenMode;
+
+public interface ScreenRandR {
+
+ int[] getScreenModeFirstImpl(final long dpy, final int screen_idx);
+ int[] getScreenModeNextImpl(final long dpy, final int screen_idx);
+ ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx);
+ boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx);
+
+}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR11.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR11.java
new file mode 100644
index 000000000..e8a616b99
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenRandR11.java
@@ -0,0 +1,214 @@
+package jogamp.newt.driver.x11;
+
+import jogamp.newt.ScreenImpl;
+
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.util.ScreenModeUtil;
+
+public class ScreenRandR11 implements ScreenRandR {
+ private static final boolean DEBUG = ScreenDriver.DEBUG;
+
+ private int[] nrotations;
+ private int nrotation_index;
+ private int nres_number;
+ private int nres_index;
+ private int[] nrates;
+ private int nrate_index;
+ private int nmode_number;
+
+ @Override
+ public int[] getScreenModeFirstImpl(final long dpy, final int screen_idx) {
+ // initialize iterators and static data
+ nrotations = getAvailableScreenModeRotations0(dpy, screen_idx);
+ if(null==nrotations || 0==nrotations.length) {
+ return null;
+ }
+ nrotation_index = 0;
+
+ nres_number = getNumScreenModeResolutions0(dpy, screen_idx);
+ if(0==nres_number) {
+ return null;
+ }
+ nres_index = 0;
+
+ nrates = getScreenModeRates0(dpy, screen_idx, nres_index);
+ if(null==nrates || 0==nrates.length) {
+ return null;
+ }
+ nrate_index = 0;
+
+ nmode_number = 0;
+
+ return getScreenModeNextImpl(dpy, screen_idx);
+ }
+
+ @Override
+ public int[] getScreenModeNextImpl(final long dpy, final int screen_idx) {
+ /**
+ System.err.println("******** mode: "+nmode_number);
+ System.err.println("rot "+nrotation_index);
+ System.err.println("rate "+nrate_index);
+ System.err.println("res "+nres_index); */
+
+ int[] res = getScreenModeResolution0(dpy, screen_idx, nres_index);
+ if(null==res || 0==res.length) {
+ return null;
+ }
+ if(0>=res[0] || 0>=res[1]) {
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number);
+ }
+ int rate = nrates[nrate_index];
+ if(0>=rate) {
+ rate = ScreenImpl.default_sm_rate;
+ if(DEBUG) {
+ System.err.println("Invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length+", using default: "+ScreenImpl.default_sm_rate);
+ }
+ }
+ int rotation = nrotations[nrotation_index];
+
+ int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ];
+ int i = 0;
+ props[i++] = nres_index; // use resolution index, not unique for native -> ScreenMode
+ props[i++] = 0; // set later for verification of iterator
+ props[i++] = res[0]; // width
+ props[i++] = res[1]; // height
+ props[i++] = ScreenImpl.default_sm_bpp; // FIXME
+ props[i++] = res[2]; // widthmm
+ props[i++] = res[3]; // heightmm
+ props[i++] = rate; // rate
+ props[i++] = rotation;
+ props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i - 1; // count without extra element
+
+ nmode_number++;
+
+ // iteration: r -> f -> bpp -> [w x h]
+ nrotation_index++;
+ if(nrotation_index == nrotations.length) {
+ nrotation_index=0;
+ nrate_index++;
+ if(null == nrates || nrate_index == nrates.length){
+ nres_index++;
+ if(nres_index == nres_number) {
+ // done
+ nrates=null;
+ nrotations=null;
+ return null;
+ }
+
+ nrates = getScreenModeRates0(dpy, screen_idx, nres_index);
+ if(null==nrates || 0==nrates.length) {
+ return null;
+ }
+ nrate_index = 0;
+ }
+ }
+
+ return props;
+ }
+
+ @Override
+ public ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx) {
+ long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
+ if(0 == screenConfigHandle) {
+ return null;
+ }
+ int[] res;
+ int rate, rot;
+ try {
+ int resNumber = getNumScreenModeResolutions0(dpy, screen_idx);
+ if(0==resNumber) {
+ return null;
+ }
+
+ int resIdx = getCurrentScreenResolutionIndex0(screenConfigHandle);
+ if(0>resIdx) {
+ return null;
+ }
+ if(resIdx>=resNumber) {
+ throw new RuntimeException("Invalid resolution index: ! "+resIdx+" < "+resNumber);
+ }
+ res = getScreenModeResolution0(dpy, screen_idx, resIdx);
+ if(null==res || 0==res.length) {
+ return null;
+ }
+ if(0>=res[0] || 0>=res[1]) {
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber);
+ }
+ rate = getCurrentScreenRate0(screenConfigHandle);
+ if(0>rate) {
+ return null;
+ }
+ rot = getCurrentScreenRotation0(screenConfigHandle);
+ if(0>rot) {
+ return null;
+ }
+ } finally {
+ freeScreenConfiguration0(screenConfigHandle);
+ }
+ int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
+ int i = 0;
+ props[i++] = 0; // set later for verification of iterator
+ props[i++] = res[0]; // width
+ props[i++] = res[1]; // height
+ props[i++] = ScreenImpl.default_sm_bpp; // FIXME
+ props[i++] = res[2]; // widthmm
+ props[i++] = res[3]; // heightmm
+ props[i++] = rate; // rate
+ props[i++] = rot;
+ props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count
+ return ScreenModeUtil.streamIn(props, 0);
+ }
+
+ @Override
+ public boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx) {
+ final long t0 = System.currentTimeMillis();
+ boolean done = false;
+ long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
+ if(0 == screenConfigHandle) {
+ return Boolean.valueOf(done);
+ }
+ try {
+ int resNumber = getNumScreenModeResolutions0(dpy, screen_idx);
+ if(0>resolutionIdx || resolutionIdx>=resNumber) {
+ throw new RuntimeException("Invalid resolution index: ! 0 < "+resolutionIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode);
+ }
+
+ final int f = screenMode.getMonitorMode().getRefreshRate();
+ final int r = screenMode.getRotation();
+
+ if( setCurrentScreenModeStart0(dpy, screen_idx, screenConfigHandle, resolutionIdx, f, r) ) {
+ while(!done && System.currentTimeMillis()-t0 < ScreenImpl.SCREEN_MODE_CHANGE_TIMEOUT) {
+ done = setCurrentScreenModePollEnd0(dpy, screen_idx, resolutionIdx, f, r);
+ if(!done) {
+ try { Thread.sleep(10); } catch (InterruptedException e) { }
+ }
+ }
+ }
+ } finally {
+ freeScreenConfiguration0(screenConfigHandle);
+ }
+ return done;
+ }
+
+ /** @return int[] { rot1, .. } */
+ private static native int[] getAvailableScreenModeRotations0(long display, int screen_index);
+
+ private static native int getNumScreenModeResolutions0(long display, int screen_index);
+
+ /** @return int[] { width, height, widthmm, heightmm } */
+ private static native int[] getScreenModeResolution0(long display, int screen_index, int mode_index);
+
+ private static native int[] getScreenModeRates0(long display, int screen_index, int mode_index);
+
+ private static native long getScreenConfiguration0(long display, int screen_index);
+ private static native void freeScreenConfiguration0(long screenConfiguration);
+
+ private static native int getCurrentScreenResolutionIndex0(long screenConfiguration);
+ private static native int getCurrentScreenRate0(long screenConfiguration);
+ private static native int getCurrentScreenRotation0(long screenConfiguration);
+
+ /** needs own Display connection for XRANDR event handling */
+ private static native boolean setCurrentScreenModeStart0(long display, int screen_index, long screenConfiguration, int mode_index, int freq, int rot);
+ private static native boolean setCurrentScreenModePollEnd0(long display, int screen_index, int mode_index, int freq, int rot);
+
+}
diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h
index 4d1a7b59e..7f35216e3 100644
--- a/src/newt/native/X11Common.h
+++ b/src/newt/native/X11Common.h
@@ -45,8 +45,9 @@
#include <X11/extensions/Xrandr.h>
-#include "jogamp_newt_driver_x11_ScreenDriver.h"
#include "jogamp_newt_driver_x11_DisplayDriver.h"
+#include "jogamp_newt_driver_x11_ScreenDriver.h"
+#include "jogamp_newt_driver_x11_ScreenRandR11.h"
#include "jogamp_newt_driver_x11_WindowDriver.h"
#include "Window.h"
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11Screen.c
index e8a3ca656..69a06aad0 100644
--- a/src/newt/native/X11Screen.c
+++ b/src/newt/native/X11Screen.c
@@ -29,7 +29,7 @@
// #define VERBOSE_ON 1
// #define DBG_PERF 1
-#include "X11Common.h"
+#include "X11Screen.h"
#ifdef DBG_PERF
#include "timespec.h"
@@ -76,7 +76,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getHeight0
static int showedRandRVersion = 0;
-static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
+Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
if( 0 == XRRQueryVersion(dpy, major, minor) ) {
return False;
}
@@ -87,12 +87,12 @@ static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
return True;
}
-static Bool NewtScreen_hasRANDR(Display *dpy) {
+Bool NewtScreen_hasRANDR(Display *dpy) {
int major, minor;
return NewtScreen_getRANDRVersion(dpy, &major, &minor);
}
-static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
+int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
int rot;
if(xrotation == RR_Rotate_0) {
rot = 0;
@@ -113,386 +113,27 @@ static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
/*
* Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getAvailableScreenModeRotations0
- * Signature: (JI)I
+ * Method: GetRandRVersion0
+ * Signature: (J)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
- int num_rotations = 0;
- Rotation cur_rotation, rotations_supported;
- int rotations[4];
- int major, minor;
-
- if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) {
- fprintf(stderr, "RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation);
-
- if(0 != (rotations_supported & RR_Rotate_0)) {
- rotations[num_rotations++] = 0;
- }
- if(0 != (rotations_supported & RR_Rotate_90)) {
- rotations[num_rotations++] = 90;
- }
- if(0 != (rotations_supported & RR_Rotate_180)) {
- rotations[num_rotations++] = 180;
- }
- if(0 != (rotations_supported & RR_Rotate_270)) {
- rotations[num_rotations++] = 270;
- }
-
- jintArray properties = NULL;
-
- if(num_rotations>0) {
- properties = (*env)->NewIntArray(env, num_rotations);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rotations);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, num_rotations, rotations);
- }
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getNumScreenModeResolution0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getRandRVersion0
+ (JNIEnv *env, jclass clazz, jlong display)
{
- Display *dpy = (Display *) (intptr_t) display;
-#ifdef DBG_PERF
- struct timespec t0, t1, td;
- long td_ms;
- timespec_now(&t0);
-#endif
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0: RANDR not available\n");
- return 0;
- }
-
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getNumScreenModeResolution0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getNumScreenModeResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL);
-#endif
-
- DBG_PRINT("getNumScreenModeResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes);
-
- return num_sizes;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getScreenModeResolutions0
- * Signature: (JII)[I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- // Fill the properties in temp jint array
- int propIndex = 0;
- jint prop[4];
-
- prop[propIndex++] = xrrs[(int)resMode_idx].width;
- prop[propIndex++] = xrrs[(int)resMode_idx].height;
- prop[propIndex++] = xrrs[(int)resMode_idx].mwidth;
- prop[propIndex++] = xrrs[(int)resMode_idx].mheight;
-
- jintArray properties = (*env)->NewIntArray(env, 4);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, 4, prop);
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getScreenModeRates0
- * Signature: (JII)[I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- int num_rates;
- short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates);
-
- jint prop[num_rates];
- int i;
- for(i=0; i<num_rates; i++) {
- prop[i] = (int) rates[i];
- /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */
+ Display * dpy = (Display *)(intptr_t)display;
+ jint version[2];
+ Bool res = NewtScreen_getRANDRVersion(dpy, &version[0], &version[1]);
+ if( False == res ) {
+ version[0] = 0;
+ version[1] = 0;
}
-
- jintArray properties = (*env)->NewIntArray(env, num_rates);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates);
+ jintArray jversion = (*env)->NewIntArray(env, 2);
+ if (jversion == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size 2");
}
// move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop);
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getScreenConfiguration0
- * Signature: (JI)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenConfiguration0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)screen_idx);
-#ifdef DBG_PERF
- struct timespec t0, t1, td;
- long td_ms;
- timespec_now(&t0);
-#endif
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenConfiguration0: RANDR not available\n");
- return 0;
- }
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getScreenConfiguration0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
- // get current resolutions and frequencies
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getScreenConfiguration0.2 (XRRGetScreenInfo): %ld ms\n", td_ms); fflush(NULL);
-#endif
-
- return (jlong) (intptr_t) conf;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: freeScreenConfiguration0
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_freeScreenConfiguration0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
-{
- XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration );
-}
-
-/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getCurrentScreenRate0
- * Signature: (J)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
-{
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+ (*env)->SetIntArrayRegion(env, jversion, 0, 2, version);
- short original_rate = XRRConfigCurrentRate(conf);
- DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
-
- return (jint) original_rate;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getCurrentScreenRotation0
- * Signature: (J)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
-{
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
- Rotation rotation;
-
- XRRConfigCurrentConfiguration(conf, &rotation);
-
- return NewtScreen_XRotation2Degree(env, rotation);
-}
-
-
-/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getCurrentScreenResolutionIndex0
- * Signature: (J)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0
- (JNIEnv *env, jclass clazz, jlong screenConfiguration)
-{
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
-
- short original_rate = XRRConfigCurrentRate(conf);
-
- Rotation original_rotation;
- SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
-
- DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
- return (jint)original_size_id;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: setCurrentScreenModeStart0
- * Signature: (JIJIII)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation)
-{
- Display *dpy = (Display *) (intptr_t) display;
- XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
- Window root = RootWindow(dpy, (int)screen_idx);
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
- int rot;
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- switch(rotation) {
- case 0:
- rot = RR_Rotate_0;
- break;
- case 90:
- rot = RR_Rotate_90;
- break;
- case 180:
- rot = RR_Rotate_180;
- break;
- case 270:
- rot = RR_Rotate_270;
- break;
- default:
- NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
- }
-
- DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
- resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
-
- XRRSelectInput (dpy, root, RRScreenChangeNotifyMask);
-
- XSync(dpy, False);
- XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
- XSync(dpy, False);
-
- return JNI_TRUE;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: setCurrentScreenModePollEnd0
- * Signature: (J)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
-{
- Display *dpy = (Display *) (intptr_t) display;
- int randr_event_base, randr_error_base;
- XEvent evt;
- XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0: RANDR not available\n");
- return JNI_FALSE;
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
- XRRScreenConfiguration *conf;
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- XRRQueryExtension(dpy, &randr_event_base, &randr_error_base);
-
- int done = 0;
- int rot;
- do {
- if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) {
- return;
- }
- XNextEvent(dpy, &evt);
-
- switch (evt.type - randr_event_base) {
- case RRScreenChangeNotify:
- if(0 < scn_event->rotation ) {
- rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
- DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call(1) %p (root %p) resIdx %d rot %d %dx%d\n",
- (void*)scn_event->window, (void*)scn_event->root,
- (int)scn_event->size_index, rot,
- scn_event->width, scn_event->height);
- // done = scn_event->size_index == resMode_idx; // not reliable ..
- done = rot == rotation &&
- scn_event->width == xrrs[resMode_idx].width &&
- scn_event->height == xrrs[resMode_idx].height;
- } else {
- DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call(0) %p (root %p) resIdx %d %dx%d\n",
- (void*)scn_event->window, (void*)scn_event->root,
- (int)scn_event->size_index,
- scn_event->width, scn_event->height);
- }
- break;
- default:
- DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window);
- }
- XRRUpdateConfiguration(&evt);
- } while(!done);
-
- XSync(dpy, False);
-
+ return jversion;
}
diff --git a/src/newt/native/X11Screen.h b/src/newt/native/X11Screen.h
new file mode 100644
index 000000000..a5b8e3e70
--- /dev/null
+++ b/src/newt/native/X11Screen.h
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2013 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.
+ */
+
+#ifndef _X11SCREEN_H
+#define _X11SCREEN_H
+
+
+#include "X11Common.h"
+
+Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor);
+Bool NewtScreen_hasRANDR(Display *dpy);
+int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation);
+
+#endif /* _X11SCREEN_H */
diff --git a/src/newt/native/X11ScreenRandR11.c b/src/newt/native/X11ScreenRandR11.c
index bc7d91d20..a457fd47b 100644
--- a/src/newt/native/X11ScreenRandR11.c
+++ b/src/newt/native/X11ScreenRandR11.c
@@ -26,9 +26,14 @@
* or implied, of JogAmp Community.
*/
-#include "X11Common.h"
+#include "X11Screen.h"
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0_RandR11
+/*
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: getAvailableScreenModeRotations0
+ * Signature: (JI)I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getAvailableScreenModeRotations0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -73,30 +78,59 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailabl
return properties;
}
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0_RandR11
+/*
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: getNumScreenModeResolution0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getNumScreenModeResolutions0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
+#ifdef DBG_PERF
+ struct timespec t0, t1, td;
+ long td_ms;
+ timespec_now(&t0);
+#endif
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenRandR11_getNumScreenModeResolutions0: RANDR not available\n");
+ return 0;
+ }
+
+#ifdef DBG_PERF
+ timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
+ fprintf(stderr, "X11Screen_getNumScreenModeResolution0.1: %ld ms\n", td_ms); fflush(NULL);
+#endif
+
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
- DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
+#ifdef DBG_PERF
+ timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
+ fprintf(stderr, "X11Screen_getNumScreenModeResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL);
+#endif
+
+ DBG_PRINT("getNumScreenModeResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes);
return num_sizes;
}
/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getScreenModeResolutions0_RandR11
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: getScreenModeResolutions0
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0_RandR11
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenModeResolution0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenModeResolution0: RANDR not available\n");
+ return (*env)->NewIntArray(env, 0);
+ }
+
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
@@ -125,15 +159,20 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenMo
}
/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getScreenModeRates0_RandR11
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: getScreenModeRates0
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0_RandR11
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenModeRates0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenModeRates0: RANDR not available\n");
+ return (*env)->NewIntArray(env, 0);
+ }
+
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
@@ -163,100 +202,139 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenMo
}
/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getCurrentScreenRate0_RandR11
- * Signature: (JI)I
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: getScreenConfiguration0
+ * Signature: (JI)J
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0_RandR11
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenConfiguration0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
+ Window root = RootWindow(dpy, (int)screen_idx);
+#ifdef DBG_PERF
+ struct timespec t0, t1, td;
+ long td_ms;
+ timespec_now(&t0);
+#endif
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenRandR11_getScreenConfiguration0: RANDR not available\n");
+ return 0;
+ }
+#ifdef DBG_PERF
+ timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
+ fprintf(stderr, "X11Screen_getScreenConfiguration0.1: %ld ms\n", td_ms); fflush(NULL);
+#endif
+
// get current resolutions and frequencies
XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
- short original_rate = XRRConfigCurrentRate(conf);
+#ifdef DBG_PERF
+ timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
+ fprintf(stderr, "X11Screen_getScreenConfiguration0.2 (XRRGetScreenInfo): %ld ms\n", td_ms); fflush(NULL);
+#endif
- //free
- XRRFreeScreenConfigInfo(conf);
+ return (jlong) (intptr_t) conf;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: freeScreenConfiguration0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_freeScreenConfiguration0
+ (JNIEnv *env, jclass clazz, jlong screenConfiguration)
+{
+ XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration );
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: getCurrentScreenRate0
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getCurrentScreenRate0
+ (JNIEnv *env, jclass clazz, jlong screenConfiguration)
+{
+ XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
+ short original_rate = XRRConfigCurrentRate(conf);
DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
return (jint) original_rate;
}
/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getCurrentScreenRotation0_RandR11
- * Signature: (JI)I
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: getCurrentScreenRotation0
+ * Signature: (J)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0_RandR11
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getCurrentScreenRotation0
+ (JNIEnv *env, jclass clazz, jlong screenConfiguration)
{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- //get current resolutions and frequencies
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
-
+ XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
Rotation rotation;
+
XRRConfigCurrentConfiguration(conf, &rotation);
- //free
- XRRFreeScreenConfigInfo(conf);
-
return NewtScreen_XRotation2Degree(env, rotation);
}
/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: getCurrentScreenResolutionIndex0_RandR11
- * Signature: (JI)I
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: getCurrentScreenResolutionIndex0
+ * Signature: (J)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0_RandR11
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_getCurrentScreenResolutionIndex0
+ (JNIEnv *env, jclass clazz, jlong screenConfiguration)
{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
+ XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
- // 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);
-
DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
- return (jint)original_size_id;
+ return (jint)original_size_id;
}
/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: setCurrentScreenModeStart0_RandR11
- * Signature: (JIIII)Z
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: setCurrentScreenModeStart0
+ * Signature: (JIJIII)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0_RandR11
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_setCurrentScreenModeStart0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation)
{
Display *dpy = (Display *) (intptr_t) display;
+ XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration;
Window root = RootWindow(dpy, (int)screen_idx);
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
- XRRScreenConfiguration *conf;
int rot;
if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
}
- conf = XRRGetScreenInfo(dpy, root);
-
- rot = int NewtScreen_Degree2XRotation(env, rotation);
+ switch(rotation) {
+ case 0:
+ rot = RR_Rotate_0;
+ break;
+ case 90:
+ rot = RR_Rotate_90;
+ break;
+ case 180:
+ rot = RR_Rotate_180;
+ break;
+ case 270:
+ rot = RR_Rotate_270;
+ break;
+ default:
+ NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
+ }
DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
@@ -267,19 +345,15 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentSc
XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
XSync(dpy, False);
- //free
- XRRFreeScreenConfigInfo(conf);
- XSync(dpy, False);
-
return JNI_TRUE;
}
/*
- * Class: jogamp_newt_driver_x11_ScreenDriver
- * Method: setCurrentScreenModePollEnd0_RandR11
+ * Class: jogamp_newt_driver_x11_ScreenRandR11
+ * Method: setCurrentScreenModePollEnd0
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0_RandR11
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenRandR11_setCurrentScreenModePollEnd0
(JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -287,6 +361,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentSc
XEvent evt;
XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenRandR11_setCurrentScreenModePollEnd0: RANDR not available\n");
+ return JNI_FALSE;
+ }
+
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
XRRScreenConfiguration *conf;
@@ -307,15 +386,22 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentSc
switch (evt.type - randr_event_base) {
case RRScreenChangeNotify:
- rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
- DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n",
- (void*)scn_event->window, (void*)scn_event->root,
- (int)scn_event->size_index, rot,
- scn_event->width, scn_event->height);
- // done = scn_event->size_index == resMode_idx; // not reliable ..
- done = rot == rotation &&
- scn_event->width == xrrs[resMode_idx].width &&
- scn_event->height == xrrs[resMode_idx].height;
+ if(0 < scn_event->rotation ) {
+ rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
+ DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call(1) %p (root %p) resIdx %d rot %d %dx%d\n",
+ (void*)scn_event->window, (void*)scn_event->root,
+ (int)scn_event->size_index, rot,
+ scn_event->width, scn_event->height);
+ // done = scn_event->size_index == resMode_idx; // not reliable ..
+ done = rot == rotation &&
+ scn_event->width == xrrs[resMode_idx].width &&
+ scn_event->height == xrrs[resMode_idx].height;
+ } else {
+ DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call(0) %p (root %p) resIdx %d %dx%d\n",
+ (void*)scn_event->window, (void*)scn_event->root,
+ (int)scn_event->size_index,
+ scn_event->width, scn_event->height);
+ }
break;
default:
DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window);