diff options
author | Sven Gothel <[email protected]> | 2013-04-18 08:31:11 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-04-18 08:31:11 +0200 |
commit | d173feb60d085399194549102d4b3d77512c3f73 (patch) | |
tree | 77aaef10eca29c3b91fdca5621bcfdfa57558672 | |
parent | f8adb848c0d6b61a8a34dfcdaf13ca773000fbb4 (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.xml | 24 | ||||
-rwxr-xr-x | make/scripts/tests.sh | 4 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/ScreenImpl.java | 10 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java | 225 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/x11/ScreenRandR.java | 12 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/x11/ScreenRandR11.java | 214 | ||||
-rw-r--r-- | src/newt/native/X11Common.h | 3 | ||||
-rw-r--r-- | src/newt/native/X11Screen.c | 397 | ||||
-rw-r--r-- | src/newt/native/X11Screen.h | 39 | ||||
-rw-r--r-- | src/newt/native/X11ScreenRandR11.c | 232 |
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); |