diff options
Diffstat (limited to 'src/newt')
7 files changed, 135 insertions, 82 deletions
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index 422d5b06c..c02f4f288 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -284,12 +284,12 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { vOriginSize.setWidth(usrSize.getWidth()); vOriginSize.setHeight(usrSize.getHeight()); if(DEBUG) { - System.err.println("User virtual screen viewport "+vOriginSize); + System.err.println("Update user virtual screen viewport @ "+Thread.currentThread().getName()+": "+vOriginSize); } } else { calcVirtualScreenOriginAndSize(vOriginSize); if(DEBUG) { - System.err.println("Detected virtual screen viewport "+vOriginSize); + System.err.println("Updated virtual screen viewport @ "+Thread.currentThread().getName()+": "+vOriginSize); } } } @@ -396,7 +396,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { @Override public void monitorModeChangeNotify(MonitorEvent me) { if(DEBUG) { - System.err.println("monitorModeChangeNotify: "+me); + System.err.println("monitorModeChangeNotify @ "+Thread.currentThread().getName()+": "+me); } for(int i=0; i<refMonitorModeListener.size(); i++) { ((MonitorModeListener)refMonitorModeListener.get(i)).monitorModeChangeNotify(me); @@ -409,7 +409,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { final MonitorDeviceImpl monitor = (MonitorDeviceImpl) monitors.get(i); final Rectangle newViewport = getNativeMonitorDeviceViewportImpl(monitor); if( DEBUG ) { - System.err.println("Screen.updateMonitorViewport["+i+"]: "+monitor.getViewport()+" -> "+newViewport); + System.err.println("Screen.updateMonitorViewport["+i+"] @ "+Thread.currentThread().getName()+": "+monitor.getViewport()+" -> "+newViewport); } if( null != newViewport ) { monitor.setViewportValue(newViewport); @@ -424,7 +424,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { updateVirtualScreenOriginAndSize(); } if(DEBUG) { - System.err.println("monitorModeChanged: success "+success+", "+me); + System.err.println("monitorModeChangeNotify @ "+Thread.currentThread().getName()+": success "+success+", "+me); } for(int i=0; i<refMonitorModeListener.size(); i++) { ((MonitorModeListener)refMonitorModeListener.get(i)).monitorModeChanged(me, success); diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index f449d185f..7c4011f34 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -129,6 +129,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private boolean fullscreen = false, brokenFocusChange = false; private List<MonitorDevice> fullscreenMonitors = null; private boolean fullscreenUseMainMonitor = true; + private boolean fullscreenUseSpanningMode = true; // spanning mode: fake full screen, only on certain platforms private boolean autoPosition = true; // default: true (allow WM to choose top-level position, if not set by user) private int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen client-area size/pos w/o insets @@ -251,6 +252,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer fullscreen = false; fullscreenMonitors = null; fullscreenUseMainMonitor = true; + fullscreenUseSpanningMode = false; hasFocus = false; parentWindowHandle = 0; } @@ -560,6 +562,16 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer * @see #positionChanged(boolean,int, int) */ protected abstract boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags); + + /** + * Tests whether a single reconfigure flag is supported by implementation. + * <p> + * Default is all but {@link #FLAG_IS_FULLSCREEN_SPAN} + * </p> + */ + protected boolean isReconfigureFlagSupported(int changeFlags) { + return 0 == ( changeFlags & FLAG_IS_FULLSCREEN_SPAN ); + } protected int getReconfigureFlags(int changeFlags, boolean visible) { return changeFlags |= ( ( 0 != getParentWindowHandle() ) ? FLAG_HAS_PARENT : 0 ) | @@ -1018,6 +1030,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer fullscreen = false; fullscreenMonitors = null; fullscreenUseMainMonitor = true; + fullscreenUseSpanningMode = false; hasFocus = false; parentWindowHandle = 0; @@ -1874,7 +1887,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer int x,y,w,h; - final RectangleImmutable viewport; + final RectangleImmutable sviewport = screen.getViewport(); + final RectangleImmutable viewport; final int fs_span_flag; if(fullscreen) { if( null == fullscreenMonitors ) { @@ -1885,19 +1899,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer fullscreenMonitors = getScreen().getMonitorDevices(); } } - /** - * Bug 770: - * _NET_WM_STATE_FULLSCREEN may result in ConfigureNotify event w/ virtual screen size, instead of monitor-mode size (NV + Fglrx). - * ConfigureNotify reflects the actual size of the window and is being propagated - * to NEWT and the GLEventListener. - * With Mesa/Intel open-source driver, the correct desired monitor mode size is reported - * at least on one test machine here. - * - * Bug 771: Implementation requires not to use _NET_WM_STATE_FULLSCREEN! - */ - // fs_span_flag = monitors.size() > 1 ? FLAG_IS_FULLSCREEN_SPAN : 0 ; - fs_span_flag = FLAG_IS_FULLSCREEN_SPAN; viewport = MonitorDevice.unionOfViewports(new Rectangle(), fullscreenMonitors); + if( isReconfigureFlagSupported(FLAG_IS_FULLSCREEN_SPAN) && + ( fullscreenMonitors.size() > 1 || sviewport.compareTo(viewport) > 0 ) ) { + fullscreenUseSpanningMode = true; + fs_span_flag = FLAG_IS_FULLSCREEN_SPAN; + } else { + fullscreenUseSpanningMode = false; + fs_span_flag = 0; + } nfs_x = getX(); nfs_y = getY(); nfs_width = getWidth(); @@ -1908,6 +1918,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer h = viewport.getHeight(); } else { fullscreenUseMainMonitor = true; + fullscreenUseSpanningMode = false; fullscreenMonitors = null; fs_span_flag = 0; viewport = null; @@ -1932,7 +1943,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if(DEBUG_IMPLEMENTATION) { System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+ - ", virtl-size: "+screen.getWidth()+"x"+screen.getHeight()+", monitorsViewport "+viewport); + ", virtl-screenSize: "+sviewport+", monitorsViewport "+viewport+ + ", spanning "+fullscreenUseSpanningMode+" @ "+Thread.currentThread().getName()); } final DisplayImpl display = (DisplayImpl) screen.getDisplay(); @@ -1991,6 +2003,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer synchronized(fullScreenAction) { fullscreenMonitors = monitors; fullscreenUseMainMonitor = useMainMonitor; + fullscreenUseSpanningMode = false; if( fullScreenAction.init(fullscreen) ) { if(fullScreenAction.fsOn() && isOffscreenInstance(WindowImpl.this, parentWindow)) { // enable fullscreen on offscreen instance @@ -2021,21 +2034,33 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private class MonitorModeListenerImpl implements MonitorModeListener { boolean animatorPaused = false; boolean hadFocus = false; + boolean fullscreenPaused = false; + List<MonitorDevice> _fullscreenMonitors = null; + boolean _fullscreenUseMainMonitor = true; public void monitorModeChangeNotify(MonitorEvent me) { hadFocus = hasFocus(); if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.monitorModeChangeNotify: hadFocus "+hadFocus+", "+me); + System.err.println("Window.monitorModeChangeNotify: hadFocus "+hadFocus+", "+me+" @ "+Thread.currentThread().getName()); } if(null!=lifecycleHook) { animatorPaused = lifecycleHook.pauseRenderingAction(); } + if( fullscreen && isReconfigureFlagSupported(FLAG_IS_FULLSCREEN_SPAN) ) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window.monitorModeChangeNotify: FS Pause"); + } + fullscreenPaused = true; + _fullscreenMonitors = fullscreenMonitors; + _fullscreenUseMainMonitor = fullscreenUseMainMonitor; + setFullscreenImpl(false, true, null); + } } public void monitorModeChanged(MonitorEvent me, boolean success) { if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.monitorModeChanged: hadFocus "+hadFocus+", "+me+", success: "+success); + System.err.println("Window.monitorModeChanged: hadFocus "+hadFocus+", "+me+", success: "+success+" @ "+Thread.currentThread().getName()); } if(success) { @@ -2043,7 +2068,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // Didn't pass above notify method. probably detected screen change after it happened. animatorPaused = lifecycleHook.pauseRenderingAction(); } - if( !fullscreen ) { + if( !fullscreen && !fullscreenPaused ) { // Simply move/resize window to fit in virtual screen if required final RectangleImmutable viewport = screen.getViewport(); if( viewport.getWidth() > 0 && viewport.getHeight() > 0 ) { // failsafe @@ -2059,6 +2084,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer setSize(viewport.getWidth(), viewport.getHeight()); } } + } else if( fullscreenPaused ){ + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window.monitorModeChanged: FS Restore"); + } + setFullscreenImpl(true, _fullscreenUseMainMonitor, _fullscreenMonitors); + fullscreenPaused = false; + _fullscreenMonitors = null; + _fullscreenUseMainMonitor = true; } else { // If changed monitor is part of this fullscreen mode, reset size! (Bug 771) final MonitorDevice md = me.getMonitor(); diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR.java b/src/newt/classes/jogamp/newt/driver/x11/RandR.java index 769ebe225..e39a6c63a 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/RandR.java +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR.java @@ -29,6 +29,8 @@ package jogamp.newt.driver.x11; import java.util.List; +import javax.media.nativewindow.util.RectangleImmutable; + import jogamp.newt.MonitorModeProps; import com.jogamp.common.util.VersionNumber; @@ -78,5 +80,7 @@ public interface RandR { int[] getMonitorDeviceProps(final long dpy, final ScreenDriver screen, MonitorModeProps.Cache cache, final int crt_idx); int[] getMonitorDeviceViewport(final long dpy, final ScreenDriver screen, final int crt_idx); int[] getCurrentMonitorModeProps(final long dpy, final ScreenDriver screen, final int crt_idx); - boolean setCurrentMonitorMode(final long dpy, final ScreenDriver screen, MonitorDevice monitor, final MonitorMode mode); + boolean setCurrentMonitorMode(final long dpy, final ScreenDriver screen, MonitorDevice monitor, final MonitorMode mode); + + public void updateScreenViewport(final long dpy, final ScreenDriver screen, RectangleImmutable viewport); } diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java index 58468e112..877607f72 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java @@ -27,6 +27,8 @@ */ package jogamp.newt.driver.x11; +import javax.media.nativewindow.util.RectangleImmutable; + import jogamp.newt.MonitorModeProps; import jogamp.newt.ScreenImpl; @@ -333,6 +335,11 @@ class RandR11 implements RandR { } return done; } + + @Override + public final void updateScreenViewport(final long dpy, final ScreenDriver screen, RectangleImmutable viewport) { + // nop + } /** @return int[] { rot1, .. } */ private static native int[] getAvailableScreenRotations0(long display, int screen_index); diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR13.java b/src/newt/classes/jogamp/newt/driver/x11/RandR13.java index 375cffe42..ac83fc5f2 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/RandR13.java +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR13.java @@ -29,6 +29,8 @@ package jogamp.newt.driver.x11; import java.util.Iterator; +import javax.media.nativewindow.util.RectangleImmutable; + import jogamp.newt.MonitorModeProps; import com.jogamp.common.util.IntLongHashMap; @@ -235,54 +237,20 @@ class RandR13 implements RandR { } finally { releaseScreenResourceHandle(screenResources); } - /*** - * TODO: Would need a complete re-layout of crt positions, - * which is _not_ implicit by XRandR .. sadly. - * - if( res ) { - updateScreenViewport(dpy, screen, monitor); - } */ return res; } - /** See above .. - private final void updateScreenViewport(final long dpy, final ScreenDriver screen, MonitorDevice monitor) { + @Override + public final void updateScreenViewport(final long dpy, final ScreenDriver screen, final RectangleImmutable viewport) { final int screen_idx = screen.getIndex(); final long screenResources = getScreenResourceHandle(dpy, screen_idx); try { - RectangleImmutable newViewp = null; - final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, monitor.getId()); - try { - final int[] vprops = getMonitorViewport0(monitorInfo); - if( null != vprops ) { - newViewp = new Rectangle(vprops[0], vprops[1], vprops[2], vprops[3]); - } - System.err.println("XXX setScreenViewport: newVp "+newViewp); - } finally { - releaseMonitorInfoHandle(monitorInfo); - } - if( null != newViewp ) { - final List<MonitorDevice> monitors = screen.getMonitorDevices(); - final ArrayList<RectangleImmutable> viewports = new ArrayList<RectangleImmutable>(); - for(int i=0; i<monitors.size(); i++) { - final MonitorDevice crt = monitors.get(i); - if( crt.getId() != monitor.getId() ) { - System.err.println("XXX setScreenViewport: add.pre["+i+"]: "+crt.getViewport()); - viewports.add( crt.getViewport() ) ; - } else { - System.err.println("XXX setScreenViewport: add.new["+i+"]: "+newViewp); - viewports.add( newViewp ); - } - } - final RectangleImmutable newScrnViewp = new Rectangle().union(viewports); - System.err.println("XXX setScreenViewport: "+screen.getViewport()+" -> "+newScrnViewp); - setScreenViewport0(dpy, screen_idx, screenResources, newScrnViewp.getX(), newScrnViewp.getY(), newScrnViewp.getWidth(), newScrnViewp.getHeight()); - } + setScreenViewport0(dpy, screen_idx, screenResources, viewport.getX(), viewport.getY(), viewport.getWidth(), viewport.getHeight()); } finally { dumpInfo0(dpy, screen_idx, screenResources); releaseScreenResourceHandle(screenResources); - } - } */ + } + } private static native long getScreenResources0(long display, int screen_index); private static native void freeScreenResources0(long screenResources); diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java index 19a69a3f9..1335f5697 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java @@ -38,6 +38,7 @@ import java.util.List; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.util.Rectangle; +import javax.media.nativewindow.util.RectangleImmutable; import jogamp.nativewindow.x11.X11Util; import jogamp.newt.Debug; @@ -218,14 +219,31 @@ public class ScreenDriver extends ScreenImpl { @Override protected void calcVirtualScreenOriginAndSize(final Rectangle vOriginSize) { - runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() { - public Object run(long dpy) { - vOriginSize.setX(0); - vOriginSize.setY(0); - vOriginSize.setWidth(getWidth0(dpy, screen_idx)); - vOriginSize.setHeight(getHeight0(dpy, screen_idx)); - return null; - } } ); + final RectangleImmutable ov = (RectangleImmutable) getViewport().cloneMutable(); + /** + if( null != rAndR && rAndR.getVersion().compareTo(RandR.version130) >= 0 && getMonitorDevices().size()>0 ) { + super.calcVirtualScreenOriginAndSize(vOriginSize); + if( DEBUG ) { + System.err.println("X11Screen.calcVirtualScreenOriginAndSize: UpdatingViewport "+ov+" -> "+vOriginSize); + } + runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() { + public Object run(long dpy) { + rAndR.updateScreenViewport(dpy, ScreenDriver.this, vOriginSize); + return null; + } } ); + } else */ { + runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() { + public Object run(long dpy) { + vOriginSize.setX(0); + vOriginSize.setY(0); + vOriginSize.setWidth(getWidth0(dpy, screen_idx)); + vOriginSize.setHeight(getHeight0(dpy, screen_idx)); + return null; + } } ); + if( DEBUG ) { + System.err.println("X11Screen.calcVirtualScreenOriginAndSize: Querying X11: "+ov+" -> "+vOriginSize); + } + } } //---------------------------------------------------------------------- diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index aec7f310e..4786ea04f 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -65,6 +65,7 @@ public class WindowDriver extends WindowImpl { public WindowDriver() { } + @Override protected void createNativeImpl() { final ScreenDriver screen = (ScreenDriver) getScreen(); final DisplayDriver display = (DisplayDriver) screen.getDisplay(); @@ -109,6 +110,7 @@ public class WindowDriver extends WindowImpl { } } + @Override protected void closeNativeImpl() { if(0!=windowHandleClose && null!=getScreen() ) { DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); @@ -133,6 +135,18 @@ public class WindowDriver extends WindowImpl { } } + /** + * <p> + * X11 Window supports {@link #FLAG_IS_FULLSCREEN_SPAN} + * </p> + * {@inheritDoc} + */ + @Override + protected boolean isReconfigureFlagSupported(int changeFlags) { + return true; // all flags! + } + + @Override protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, int flags) { if(DEBUG_IMPLEMENTATION) { System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ getReconfigureFlagsAsString(null, flags)); @@ -148,14 +162,16 @@ public class WindowDriver extends WindowImpl { _x = x; _y = y; } - if( 0 != ( FLAG_IS_FULLSCREEN & flags) && 0 == ( FLAG_IS_ALWAYSONTOP & flags) ) { - tempAlwaysOnTop = true; - flags |= FLAG_IS_ALWAYSONTOP; - if(DEBUG_IMPLEMENTATION) { - System.err.println("X11Window reconfig.2: temporary "+getReconfigureFlagsAsString(null, flags)); + if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags ) ) { + if( 0 != ( FLAG_IS_FULLSCREEN & flags) && 0 != ( FLAG_IS_FULLSCREEN_SPAN & flags) && 0 == ( FLAG_IS_ALWAYSONTOP & flags) ) { + tempFSAlwaysOnTop = true; + flags |= FLAG_IS_ALWAYSONTOP; + if(DEBUG_IMPLEMENTATION) { + System.err.println("X11Window reconfig.2: temporary "+getReconfigureFlagsAsString(null, flags)); + } + } else { + tempFSAlwaysOnTop = false; } - } else { - tempAlwaysOnTop = false; } final int fflags = flags; final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); @@ -169,7 +185,7 @@ public class WindowDriver extends WindowImpl { }); return true; } - volatile boolean tempAlwaysOnTop = false; + volatile boolean tempFSAlwaysOnTop = false; /** * <p> @@ -177,9 +193,13 @@ public class WindowDriver extends WindowImpl { * </p> * {@inheritDoc} */ + @Override protected void focusChanged(boolean defer, boolean focusGained) { - if( tempAlwaysOnTop && hasFocus() != focusGained && isNativeValid() ) { + if( tempFSAlwaysOnTop && hasFocus() != focusGained && isNativeValid() ) { final int flags = getReconfigureFlags(FLAG_CHANGE_ALWAYSONTOP, isVisible()) | ( focusGained ? FLAG_IS_ALWAYSONTOP : 0 ); + if(DEBUG_IMPLEMENTATION) { + System.err.println("X11Window reconfig.3 (focus): temporary "+getReconfigureFlagsAsString(null, flags)); + } final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() { public Object run(long dpy) { @@ -192,8 +212,7 @@ public class WindowDriver extends WindowImpl { } super.focusChanged(defer, focusGained); } - - + protected void reparentNotify(long newParentWindowHandle) { if(DEBUG_IMPLEMENTATION) { final long p0 = getParentWindowHandle(); @@ -201,6 +220,7 @@ public class WindowDriver extends WindowImpl { } } + @Override protected void requestFocusImpl(final boolean force) { runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() { public Object run(long dpy) { @@ -248,6 +268,7 @@ public class WindowDriver extends WindowImpl { }); } + @Override protected Point getLocationOnScreenImpl(final int x, final int y) { return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Point>() { public Point run(long dpy) { @@ -256,6 +277,7 @@ public class WindowDriver extends WindowImpl { } ); } + @Override protected void updateInsetsImpl(Insets insets) { // nop - using event driven insetsChange(..) } @@ -304,7 +326,8 @@ public class WindowDriver extends WindowImpl { } super.doMouseEvent(enqueue, wait, eventType, modifiers, x, y, button, rotationXYZ, rotationScale); } - + + /** Called by native TK */ protected final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar0, String keyString) { // handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar); final boolean isModifierKey = KeyEvent.isModifierKey(keyCode); |