From 2c88b6dfd4eb7e2cd9a50fa48e08ecafc980931a Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 20 Mar 2015 21:42:23 +0100 Subject: Bug 1147 - Fix XRandR13 Usage: Rotate / Change-Mode, use unique CRTC/Mode ids, .. RandR 1.3 XRRSetCrtcConfig related: - X11RandR13 now sets the new screen size via XRRSetScreenSize(..) - X11RandR13 now propagates RRScreenChangeNotify events via XRRUpdateConfiguration(event). Hence reporting virtual desktop size now. - X11RandR13 now disables the CRTC before XRRSetCrtcConfig(..) to avoid invalid configuration (see spec)! RandR 1.3 General: - Uses unique id named instead of unstable index for modes and CRTC. This allows proper identification even for 'swizzled' devices. --- make/scripts/tests-win.bat | 3 +- make/scripts/tests.sh | 7 +- .../classes/com/jogamp/newt/MonitorDevice.java | 1 + src/newt/classes/jogamp/newt/MonitorModeProps.java | 2 +- src/newt/classes/jogamp/newt/ScreenImpl.java | 2 +- .../jogamp/newt/driver/x11/DisplayDriver.java | 25 +- src/newt/classes/jogamp/newt/driver/x11/RandR.java | 23 +- .../classes/jogamp/newt/driver/x11/RandR11.java | 104 ++++--- .../classes/jogamp/newt/driver/x11/RandR13.java | 71 +++-- .../jogamp/newt/driver/x11/ScreenDriver.java | 37 ++- .../jogamp/newt/driver/x11/WindowDriver.java | 6 +- src/newt/native/X11Display.c | 22 +- src/newt/native/X11RandR11.c | 89 +++--- src/newt/native/X11RandR13.c | 275 +++++++++++++----- src/newt/native/X11Screen.c | 6 +- src/newt/native/X11Screen.h | 4 +- src/newt/native/X11Window.c | 6 +- src/newt/native/xrandr_utils.c | 322 +++++++++++++++++++++ 18 files changed, 773 insertions(+), 232 deletions(-) create mode 100644 src/newt/native/xrandr_utils.c diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat index 88545b857..97c580539 100755 --- a/make/scripts/tests-win.bat +++ b/make/scripts/tests-win.bat @@ -167,7 +167,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestGLWindows02NEWTAn REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestGLWindowInvisiblePointer01NEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.nativewindow.TestRecursiveToolkitLockCORE -scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT %* +REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00bNEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00cNEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01aNEWT %* @@ -217,3 +217,4 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.GPUUISceneNewt REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 +scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.stereo.StereoDemo01 %* diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 316262606..caa5bfea6 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -311,6 +311,9 @@ function jrun() { #D_ARGS="-Djogl.debug.GLMediaPlayer.Native" #D_ARGS="-Djogl.debug.StereoDevice -Djogl.debug.StereoDevice.DumpData" #D_ARGS="-Djogl.debug.StereoDevice" + #D_ARGS="-Dnewt.debug.Screen -Djogl.debug.StereoDevice" + #D_ARGS="-Dnewt.debug.Screen -Dnewt.test.Screen.disableRandR13" + D_ARGS="-Dnewt.debug.Screen" if [ $awton -eq 1 ] ; then export USE_CLASSPATH=$JOGAMP_ALL_AWT_CLASSPATH @@ -620,7 +623,7 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01bNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01cNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01dNEWT $* -#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aNEWT $* +testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02bNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.ManualScreenMode03aNEWT $* #testnoawt -Djava.awt.headless=true com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT $* @@ -689,7 +692,7 @@ function testawtswt() { #testawt com.jogamp.opengl.test.junit.jogl.awt.TestIsRealizedConcurrency01AWT $* #testawt com.jogamp.opengl.test.junit.jogl.awt.text.TestAWTTextRendererUseVertexArrayBug464 #testawt com.jogamp.opengl.test.junit.jogl.glu.TestBug463ScaleImageMemoryAWT $* -testawt com.jogamp.opengl.test.junit.jogl.glu.TestBug694ScaleImageUnpackBufferSizeAWT $* +#testawt com.jogamp.opengl.test.junit.jogl.glu.TestBug694ScaleImageUnpackBufferSizeAWT $* #testawt com.jogamp.opengl.test.junit.jogl.glu.TestBug365TextureGenerateMipMaps $* #testawt com.jogamp.opengl.test.junit.jogl.awt.TestGLCanvasAWTActionDeadlock00AWT $* #testawt com.jogamp.opengl.test.junit.jogl.awt.TestGLCanvasAWTActionDeadlock01AWT $* diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java index 4f06a946a..e96fc82f5 100644 --- a/src/newt/classes/com/jogamp/newt/MonitorDevice.java +++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java @@ -332,6 +332,7 @@ public abstract class MonitorDevice { /** * Set the current {@link com.jogamp.newt.MonitorMode}. + *

This method is lifecycle heavy.

* @param mode to be made current, must be element of the list {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}. * @return true if successful, otherwise false * @throws IllegalStateException if the {@link #getScreen() associated screen} is not {@link Screen#isNativeValid() valid natively}. diff --git a/src/newt/classes/jogamp/newt/MonitorModeProps.java b/src/newt/classes/jogamp/newt/MonitorModeProps.java index 073a9a355..4e2806118 100644 --- a/src/newt/classes/jogamp/newt/MonitorModeProps.java +++ b/src/newt/classes/jogamp/newt/MonitorModeProps.java @@ -272,7 +272,7 @@ public class MonitorModeProps { * @param cache hash arrays of unique {@link MonitorMode} components and {@link MonitorDevice}s, allowing to avoid duplicates * @param screen the associated {@link ScreenImpl} * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. - * @param monitorProperties the input data minus supported modes! + * @param monitorProperties the input data inclusive supported modes. * @param offset the offset to the input data * @param monitor_idx if not null, returns the index of resulting {@link MonitorDevice} within {@link Cache#monitorDevices}. * @return {@link MonitorDevice} of the identical (old or new) element in {@link Cache#monitorDevices}, diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index c96a2e06e..347ea650e 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -440,7 +440,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { monitor.getMutuableViewportPU(), monitor.getMutuableViewportWU()); if( DEBUG ) { - System.err.println("Screen.updateMonitorViewport["+i+"] @ "+Thread.currentThread().getName()+": updated: "+viewportUpdated+ + System.err.println("Screen.updateMonitorViewport["+Display.toHexString(monitor.getId())+"] @ "+Thread.currentThread().getName()+": updated: "+viewportUpdated+ ", PU "+monitor.getViewport()+", WU "+monitor.getViewportInWindowUnits()+ ", pixelScale ["+pixelScale[0]+", "+pixelScale[1]+"]"); } diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java index 3276f3ed1..81ccdbfcd 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java @@ -40,7 +40,6 @@ import java.nio.ByteBuffer; import com.jogamp.nativewindow.AbstractGraphicsDevice; import com.jogamp.nativewindow.NativeWindowException; import com.jogamp.nativewindow.util.PixelFormat; - import com.jogamp.common.nio.Buffers; import com.jogamp.nativewindow.x11.X11GraphicsDevice; @@ -110,7 +109,8 @@ public class DisplayDriver extends DisplayImpl { try { final long handle = _aDevice.getHandle(); if(0 != handle) { - DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now + DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom /*, kbdHandle */, // XKB disabled for now + randr_event_base, randr_error_base); } } finally { _aDevice.unlock(); @@ -120,6 +120,8 @@ public class DisplayDriver extends DisplayImpl { protected long getJavaObjectAtom() { return javaObjectAtom; } protected long getWindowDeleteAtom() { return windowDeleteAtom; } // protected long getKbdHandle() { return kbdHandle; } // XKB disabled for now + protected int getRandREventBase() { return randr_event_base; } + protected int getRandRErrorBase() { return randr_error_base; } /** Returns null if !{@link #isNativeValid()}, otherwise the Boolean value of {@link X11GraphicsDevice#isXineramaEnabled()}. */ protected Boolean isXineramaEnabled() { return isNativeValid() ? Boolean.valueOf(((X11GraphicsDevice)aDevice).isXineramaEnabled()) : null; } @@ -142,14 +144,26 @@ public class DisplayDriver extends DisplayImpl { private native void CompleteDisplay0(long handle); - private void displayCompleted(final long javaObjectAtom, final long windowDeleteAtom /*, long kbdHandle */) { + private void displayCompleted(final long javaObjectAtom, final long windowDeleteAtom /*, long kbdHandle */, + final int randr_event_base, final int randr_error_base) { this.javaObjectAtom=javaObjectAtom; this.windowDeleteAtom=windowDeleteAtom; // this.kbdHandle = kbdHandle; // XKB disabled for now + this.randr_event_base = randr_event_base; + this.randr_error_base = randr_error_base; + } + private void sendRRScreenChangeNotify(final long event) { + if( null != rAndR ) { + rAndR.sendRRScreenChangeNotify(getHandle(), event); + } + } + void registerRandR(final RandR rAndR) { + this.rAndR = rAndR; } private native void DisplayRelease0(long handle, long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle */); // XKB disabled for now - private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom /* , long kbdHandle */); // XKB disabled for now + private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom /* , long kbdHandle */, // XKB disabled for now + final int randr_event_base, final int randr_error_base); private static long createPointerIcon(final long display, final Buffer pixels, final int width, final int height, final int hotX, final int hotY) { final boolean pixels_is_direct = Buffers.isDirect(pixels); @@ -171,5 +185,8 @@ public class DisplayDriver extends DisplayImpl { /** X11 Keyboard handle used on EDT */ // private long kbdHandle; // XKB disabled for now + private int randr_event_base, randr_error_base; + + private RandR rAndR; } diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR.java b/src/newt/classes/jogamp/newt/driver/x11/RandR.java index 14c9c0856..f45762173 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/RandR.java +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR.java @@ -43,6 +43,8 @@ public interface RandR { public static final VersionNumber version140 = new VersionNumber(1, 4, 0); VersionNumber getVersion(); + @Override + String toString(); void dumpInfo(final long dpy, final int screen_idx); @@ -50,7 +52,7 @@ public interface RandR { * Encapsulate initial device query allowing caching of internal data structures. * Methods covered: *