diff options
author | Sven Gothel <[email protected]> | 2011-09-06 02:56:07 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-09-06 02:56:07 +0200 |
commit | 4faa65ee907a78649e118717574c96031dc9e79b (patch) | |
tree | ed5e034e796c4174a60de38b64382433a24bf473 | |
parent | 7ea8aa31e055ba95a062c87ec4d606f73c2504fa (diff) |
NEWT/Window/Insets: Implement proper Inset usage ; Cleanup WindowImpl::reconfigureWindowImpl
Implement proper Inset usage (window decoration size)
- Insets are either polled (updateInsets()) or event driven (insetsChanged())
- Insets are used for size/pos calculations from Java side
- Natural size/pos in NEWT is client-area, ie w/o Insets
- Adding setTopLevelPosition()/setTopLevelSize() for top-level values,
ie including insets
WindowImpl::reconfigureWindowImpl
- Use flags to pass down the requested action to the native implementation
- Impl. all native actions: visible, decoration, reparent, resize, fullscreen
- Always use size/pos in client-area space, impl. shall use Insets to tranform them
- Remove double-setting of (reparent/fullscreen), which where introduced due to buggy impl. code
- Fix return from fullscreen position: Was overwritten with FS position (0/0)
- Fix decoration change: Remove visible toggle - not required, and actually disturbing
X11Windows/WindowsWindow: Added/Fixed Insets impl.
Tests (manual):
- TestSharedContextVBOES2NEWT utilizies proper window layout using Insets
- TestParenting03bAWT uses window layout for reparenting
20 files changed, 610 insertions, 472 deletions
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java index 2f893fb2c..7cdcfac9a 100644 --- a/src/newt/classes/jogamp/newt/OffscreenWindow.java +++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java @@ -85,11 +85,6 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable { return surfaceHandle; } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { - sizeChanged(width, height, false); - visibleChanged(visible); - } - protected void requestFocusImpl(boolean reparented) { } @@ -108,8 +103,14 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable { // nop return false; } - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) { - shouldNotCallThis(); + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + sizeChanged(width, height, false); + visibleChanged(0 != ( FLAG_IS_VISIBLE & flags)); + } else { + shouldNotCallThis(); + } return false; } diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index faf4c1a50..611af3d21 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -393,31 +393,76 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer */ protected abstract void requestFocusImpl(boolean force); - /** - * The native implementation must invoke {@link #visibleChanged(boolean)} - * to change the visibility state. This may happen asynchronous within - * {@link #TIMEOUT_NATIVEWINDOW}. - */ - protected abstract void setVisibleImpl(boolean visible, int x, int y, int width, int height); + public static final int FLAG_CHANGE_PARENTING = 1 << 0; + public static final int FLAG_CHANGE_DECORATION = 1 << 1; + public static final int FLAG_CHANGE_FULLSCREEN = 1 << 2; + public static final int FLAG_CHANGE_VISIBILITY = 1 << 3; + public static final int FLAG_HAS_PARENT = 1 << 4; + public static final int FLAG_IS_UNDECORATED = 1 << 5; + public static final int FLAG_IS_FULLSCREEN = 1 << 6; + public static final int FLAG_IS_VISIBLE = 1 << 7; /** * The native implementation should invoke the referenced java state callbacks * to notify this Java object of state changes. * - * @param x -1 if no position change requested, otherwise greater than zero - * @param y -1 if no position change requested, otherwise greater than zero - * @param width 0 if no size change requested, otherwise greater than zero - * @param height 0 if no size change requested, otherwise greater than zero - * @param parentChange true if reparenting requested, otherwise false - * @param fullScreenChange 0 if unchanged, -1 fullscreen off, 1 fullscreen on - * @param decorationChange 0 if unchanged, -1 undecorated, 1 decorated + * <p> + * Implementations shall set x/y to 0, in case it's negative. This could happen due + * to insets and positioning a decorated window to 0/0, which would place the frame + * outside of the screen.</p> + * + * @param x client-area position + * @param y client-area position + * @param width client-area size + * @param height client-area size + * @param flags bitfield of change and status flags * * @see #sizeChanged(int,int) * @see #positionChanged(int,int) */ - protected abstract boolean reconfigureWindowImpl(int x, int y, int width, int height, - boolean parentChange, int fullScreenChange, int decorationChange); + protected abstract boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags); + + protected int getReconfigureFlags(int changeFlags, boolean visible) { + return changeFlags |= ( ( 0 != getParentWindowHandle() ) ? FLAG_HAS_PARENT : 0 ) | + ( isUndecorated() ? FLAG_IS_UNDECORATED : 0 ) | + ( isFullscreen() ? FLAG_IS_FULLSCREEN : 0 ) | + ( visible ? FLAG_IS_VISIBLE : 0 ) ; + } + protected static String getReconfigureFlagsAsString(StringBuffer sb, int flags) { + if(null == sb) { sb = new StringBuffer(); } + sb.append("["); + + if( 0 != ( FLAG_CHANGE_PARENTING & flags) ) { + sb.append("*"); + } + sb.append("PARENT_"); + sb.append(0 != ( FLAG_HAS_PARENT & flags)); + sb.append(", "); + + if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { + sb.append("*"); + } + sb.append("FS_"); + sb.append(0 != ( FLAG_IS_FULLSCREEN & flags)); + sb.append(", "); + if( 0 != ( FLAG_CHANGE_DECORATION & flags) ) { + sb.append("*"); + } + sb.append("UNDECOR_"); + sb.append(0 != ( FLAG_IS_UNDECORATED & flags)); + sb.append(", "); + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + sb.append("*"); + } + sb.append("VISIBLE_"); + sb.append(0 != ( FLAG_IS_VISIBLE & flags)); + + sb.append("]"); + return sb.toString(); + } + protected void setTitleImpl(String title) {} /** @@ -679,7 +724,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer runOnEDTIfAvail(true, new VisibleAction(visible)); } } - + + protected final void setVisibleImpl(boolean visible, int x, int y, int width, int height) { + reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_VISIBILITY, visible)); + } + private class SetSizeActionImpl implements Runnable { int width, height; @@ -706,7 +755,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer WindowImpl.this.height = height; } else if ( 0 != windowHandle ) { // this width/height will be set by windowChanged, called by the native implementation - reconfigureWindowImpl(x, y, width, height, false, 0, 0); + reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(0, isVisible())); } else { WindowImpl.this.width = width; WindowImpl.this.height = height; @@ -969,7 +1018,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } // Case: Top Window - if( 0 == getParentWindowHandle() ) { + if( 0 == parentWindowHandle ) { // Already Top Window reparentAction = ACTION_UNCHANGED; } else if( !isNativeValid() || DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ) { @@ -1024,12 +1073,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } // Lock parentWindow only during reparenting (attempt) - NativeWindow parentWindowLocked = null; + final NativeWindow parentWindowLocked; if( null != parentWindow ) { parentWindowLocked = parentWindow; if( NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindowLocked.lockSurface() ) { throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow); } + } else { + parentWindowLocked = null; } boolean ok = false; try { @@ -1038,36 +1089,20 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer WindowImpl.this.y = y; WindowImpl.this.width = width; WindowImpl.this.height = height; - ok = reconfigureWindowImpl(x, y, width, height, true, 0, isUndecorated()?-1:1); + ok = reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_PARENTING | FLAG_CHANGE_DECORATION, isVisible())); } finally { if(null!=parentWindowLocked) { parentWindowLocked.unlockSurface(); } } - // set visible again, and revalidate 'ok', - // since it has been experienced that in some cases the reparented window gets hidden + // set visible again if(ok) { display.dispatchMessagesNative(); // status up2date if(wasVisible) { setVisibleImpl(true, x, y, width, height); ok = WindowImpl.this.waitForVisible(true, false); display.dispatchMessagesNative(); // status up2date - if( ok && - ( WindowImpl.this.x != x || - WindowImpl.this.y != y || - WindowImpl.this.width != width || - WindowImpl.this.height != height ) ) - { - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparent (reconfig)"); - } - // reset pos/size .. due to some native impl flakyness - reconfigureWindowImpl(x, y, width, height, false, 0, 0); - display.dispatchMessagesNative(); // status up2date - WindowImpl.this.waitForVisible(true, false); - display.dispatchMessagesNative(); // status up2date - } } } @@ -1086,7 +1121,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - // write back mirrored values, ensuring persitence + // write back mirrored values, ensuring persistence // and not relying on native messaging WindowImpl.this.x = x; WindowImpl.this.y = y; @@ -1184,10 +1219,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer windowLock.lock(); try { if(WindowImpl.this.undecorated != undecorated) { + final boolean nativeUndecorationChange = !fullscreen && isNativeValid() && + isUndecorated() != undecorated ; + // set current state WindowImpl.this.undecorated = undecorated; - if( !fullscreen && isNativeValid() ) { + if( nativeUndecorationChange) { // Change decoration on active window // Mirror pos/size so native change notification can get overwritten @@ -1199,28 +1237,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if( 0 != windowHandle ) { DisplayImpl display = (DisplayImpl) screen.getDisplay(); display.dispatchMessagesNative(); // status up2date - boolean wasVisible = isVisible(); - setVisibleImpl(false, x, y, width, height); - WindowImpl.this.waitForVisible(false, true); - display.dispatchMessagesNative(); // status up2date - reconfigureWindowImpl(x, y, width, height, false, 0, undecorated?-1:1); - display.dispatchMessagesNative(); // status up2date - if(wasVisible) { - setVisibleImpl(true, x, y, width, height); - WindowImpl.this.waitForVisible(true, true); - display.dispatchMessagesNative(); // status up2date - if( WindowImpl.this.x != x || - WindowImpl.this.y != y || - WindowImpl.this.width != width || - WindowImpl.this.height != height ) - { - // reset pos/size .. due to some native impl flakyness - reconfigureWindowImpl(x, y, width, height, false, 0, 0); - display.dispatchMessagesNative(); // status up2date - } - requestFocusImpl(true); - display.dispatchMessagesNative(); // status up2date - } + reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_DECORATION, isVisible())); + display.dispatchMessagesNative(); // status up2date } } } @@ -1324,7 +1342,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // protected final long getParentWindowHandle() { - return parentWindowHandle; + return isFullscreen() ? 0 : parentWindowHandle; } @Override @@ -1431,7 +1449,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(!fullscreen) { if(0!=windowHandle) { // this.x/this.y will be set by sizeChanged, triggered by windowing event system - reconfigureWindowImpl(x, y, 0, 0, false, 0, 0); + reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(0, isVisible())); } else { WindowImpl.this.x = x; WindowImpl.this.y = y; @@ -1468,13 +1486,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer int x,y,w,h; WindowImpl.this.fullscreen = fullscreen; if(fullscreen) { + nfs_x = WindowImpl.this.x; + nfs_y = WindowImpl.this.y; + nfs_width = WindowImpl.this.width; + nfs_height = WindowImpl.this.height; x = 0; y = 0; w = screen.getWidth(); h = screen.getHeight(); - nfs_width = width; - nfs_height = height; - nfs_x = x; - nfs_y = y; } else { x = nfs_x; y = nfs_y; @@ -1497,26 +1515,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer WindowImpl.this.y = y; WindowImpl.this.width = w; WindowImpl.this.height = h; - reconfigureWindowImpl(x, y, w, h, getParentWindowHandle()!=0, fullscreen?1:-1, isUndecorated()?-1:1); + reconfigureWindowImpl(x, y, width, height, + getReconfigureFlags( ( ( 0 != parentWindowHandle ) ? FLAG_CHANGE_PARENTING : 0 ) | + FLAG_CHANGE_FULLSCREEN | FLAG_CHANGE_DECORATION, isVisible()) ); display.dispatchMessagesNative(); // status up2date if(wasVisible) { setVisibleImpl(true, x, y, w, h); - boolean ok = WindowImpl.this.waitForVisible(true, true, Screen.SCREEN_MODE_CHANGE_TIMEOUT); + WindowImpl.this.waitForVisible(true, true, Screen.SCREEN_MODE_CHANGE_TIMEOUT); display.dispatchMessagesNative(); // status up2date - if( ok && - ( WindowImpl.this.x != x || - WindowImpl.this.y != y || - WindowImpl.this.width != w || - WindowImpl.this.height != h ) ) - { - if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { - System.err.println("Window fs (reconfig): "+x+"/"+y+" "+w+"x"+h+", "+screen); - } - // reset pos/size .. due to some native impl flakyness - reconfigureWindowImpl(x, y, w, h, false, 0, 0); - display.dispatchMessagesNative(); // status up2date - } requestFocusImpl(true); display.dispatchMessagesNative(); // status up2date if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { @@ -2093,7 +2100,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } } - + /** Triggered by implementation's WM events to update the position. */ protected void positionChanged(int newX, int newY) { if( 0==parentWindowHandle && ( x != newX || y != newY ) ) { @@ -2113,16 +2120,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer * @see #updateInsetsImpl(Insets) */ protected void insetsChanged(int left, int right, int top, int bottom) { - if ( left >= 0 && right >= 0 && top >= 0 && bottom >= 0 && - (left != insets.getLeftWidth() || right != insets.getRightWidth() || - top != insets.getTopHeight() || bottom != insets.getBottomHeight() ) - ) { - insets.setLeftWidth(left); - insets.setRightWidth(right); - insets.setTopHeight(top); - insets.setBottomHeight(bottom); - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.insetsChanged: "+insets); + if ( left >= 0 && right >= 0 && top >= 0 && bottom >= 0 ) { + if(isUndecorated()) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window.insetsChanged: skip insets change for undecoration mode"); + } + } else if ( (left != insets.getLeftWidth() || right != insets.getRightWidth() || + top != insets.getTopHeight() || bottom != insets.getBottomHeight() ) + ) { + insets.setLeftWidth(left); + insets.setRightWidth(right); + insets.setTopHeight(top); + insets.setBottomHeight(bottom); + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window.insetsChanged: "+insets); + } } } } diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java index cbe343f2c..83f306b46 100644 --- a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java +++ b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java @@ -30,14 +30,12 @@ package jogamp.newt.driver.android; import java.nio.IntBuffer; -import jogamp.newt.WindowImpl; import jogamp.newt.driver.android.event.AndroidNewtEventFactory; import javax.media.nativewindow.GraphicsConfigurationFactory; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.egl.EGLGraphicsDevice; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; -import javax.media.opengl.GLException; import com.jogamp.common.nio.Buffers; import com.jogamp.newt.event.MouseEvent; @@ -46,17 +44,13 @@ import jogamp.opengl.egl.EGL; import jogamp.opengl.egl.EGLGraphicsConfiguration; import android.content.Context; -import android.graphics.Canvas; import android.graphics.PixelFormat; import android.util.Log; -import android.view.MotionEvent; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback2; import android.view.SurfaceView; import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnTouchListener; public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 { static { @@ -156,18 +150,12 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 { return eglSurface; } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { - reconfigureWindowImpl(x, y, width, height, false, 0, 0); - visibleChanged(visible); - } - protected void requestFocusImpl(boolean reparented) { } - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, - boolean parentChange, int fullScreenChange, int decorationChange) { + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { if(0!=getWindowHandle()) { - if(0!=fullScreenChange) { - if( fullScreenChange > 0 ) { + if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { + if( 0 != ( FLAG_IS_FULLSCREEN & flags) ) { System.err.println("reconfigureWindowImpl.setFullscreen n/a"); return false; } @@ -183,6 +171,9 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 { System.err.println("reconfigureWindowImpl.setPos n/a"); return false; } + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + visibleChanged(0 != ( FLAG_IS_VISIBLE & flags)); + } return true; } diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java b/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java index 3ed0c758d..4ab12bbc8 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java +++ b/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java @@ -155,20 +155,6 @@ public class AWTWindow extends WindowImpl { return res; } - protected void setVisibleImpl(final boolean visible, int x, int y, int width, int height) { - container.setVisible(visible); - - reconfigureWindowImpl(x, y, width, height, false, 0, 0); - config = canvas.getAWTGraphicsConfiguration(); - - if (config == null) { - throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); - } - - updateDeviceData(); - visibleChanged(visible); - } - private void updateDeviceData() { // propagate new info .. ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)config.getScreen()); @@ -189,8 +175,12 @@ public class AWTWindow extends WindowImpl { insets.setBottomHeight(contInsets.bottom); } - protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final boolean parentChange, final int fullScreenChange, final int decorationChange) { - if(decorationChange!=0 && null!=frame) { + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + container.setVisible(0 != ( FLAG_IS_VISIBLE & flags)); + } + + if(0 != ( FLAG_CHANGE_DECORATION & flags) && null!=frame) { if(!container.isDisplayable()) { frame.setUndecorated(isUndecorated()); } else { @@ -199,15 +189,27 @@ public class AWTWindow extends WindowImpl { } } } - int _x=(x>=0)?x:AWTWindow.this.x; - int _y=(x>=0)?y:AWTWindow.this.y; - int _w=(width>0)?width:AWTWindow.this.width; - int _h=(height>0)?height:AWTWindow.this.height; + x=(x>=0)?x:AWTWindow.this.x; + y=(x>=0)?y:AWTWindow.this.y; + width=(width>0)?width:AWTWindow.this.width; + height=(height>0)?height:AWTWindow.this.height; - container.setLocation(_x, _y); + container.setLocation(x, y); Insets insets = container.getInsets(); - container.setSize(_w + insets.left + insets.right, - _h + insets.top + insets.bottom); + container.setSize(width + insets.left + insets.right, + height + insets.top + insets.bottom); + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + config = canvas.getAWTGraphicsConfiguration(); + + if (config == null) { + throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); + } + + updateDeviceData(); + visibleChanged(0 != ( FLAG_IS_VISIBLE & flags)); + } + return true; } diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java index 0a7f63a82..431ac934b 100644 --- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java +++ b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java @@ -72,11 +72,6 @@ public class Window extends jogamp.newt.WindowImpl { } } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { - reconfigureWindowImpl(x, y, width, height, false, 0, 0); - visibleChanged(visible); - } - protected void requestFocusImpl(boolean reparented) { } protected void setSizeImpl(int width, int height) { @@ -89,11 +84,10 @@ public class Window extends jogamp.newt.WindowImpl { } } - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, - boolean parentChange, int fullScreenChange, int decorationChange) { - if(0!=getWindowHandle()) { - if(0!=fullScreenChange) { - if( fullScreenChange > 0 ) { + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if(0!=getWindowHandle()) { + if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) { + if( 0 != ( FLAG_IS_FULLSCREEN & flags) ) { // n/a in BroadcomEGL System.err.println("setFullscreen n/a in BroadcomEGL"); return false; @@ -112,6 +106,10 @@ public class Window extends jogamp.newt.WindowImpl { if(x>=0 || y>=0) { System.err.println("BCEGL Window.setPositionImpl n/a in BroadcomEGL"); } + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + visibleChanged(0 != ( FLAG_IS_VISIBLE & flags)); + } return true; } diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java index 5e312f24d..05833e93b 100644 --- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java +++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java @@ -80,39 +80,38 @@ public class Window extends jogamp.newt.WindowImpl { } } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { - reconfigureWindowImpl(x, y, width, height, false, 0, 0); - if(visible) { - ((Display)getScreen().getDisplay()).setFocus(this); - } - this.visibleChanged(visible); - } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) { + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { Screen screen = (Screen) getScreen(); - int _x=(x>=0)?x:this.x; - int _y=(x>=0)?y:this.y; - int _w=(width>0)?width:this.width; - int _h=(height>0)?height:this.height; + x=(x>=0)?x:this.x; + y=(x>=0)?y:this.y; + width=(width>0)?width:this.width; + height=(height>0)?height:this.height; - if(_w>screen.getWidth()) { - _w=screen.getWidth(); + if(width>screen.getWidth()) { + width=screen.getWidth(); } - if(_h>screen.getHeight()) { - _h=screen.getHeight(); + if(height>screen.getHeight()) { + height=screen.getHeight(); } - if((_x+_w)>screen.getWidth()) { - _x=screen.getWidth()-_w; + if((x+width)>screen.getWidth()) { + x=screen.getWidth()-width; } - if((_y+_h)>screen.getHeight()) { - _y=screen.getHeight()-_h; + if((y+height)>screen.getHeight()) { + y=screen.getHeight()-height; } if(0!=surfaceHandle) { - SetBounds0(surfaceHandle, getScreen().getWidth(), getScreen().getHeight(), _x, _y, _w, _h); + SetBounds0(surfaceHandle, getScreen().getWidth(), getScreen().getHeight(), x, y, width, height); } + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + if(0 != ( FLAG_IS_VISIBLE & flags)) { + ((Display)getScreen().getDisplay()).setFocus(this); + } + visibleChanged(0 != ( FLAG_IS_VISIBLE & flags)); + } + return true; } diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java b/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java index f63233b37..d94538545 100644 --- a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java +++ b/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java @@ -34,6 +34,7 @@ package jogamp.newt.driver.kd; import jogamp.newt.*; +import jogamp.newt.driver.intel.gdl.Display; import jogamp.opengl.egl.*; import javax.media.nativewindow.*; import javax.media.nativewindow.util.Insets; @@ -82,19 +83,17 @@ public class KDWindow extends WindowImpl { } } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { - setVisible0(eglWindowHandle, visible); - reconfigureWindowImpl(x, y, width, height, false, 0, 0); - visibleChanged(visible); - } - protected void requestFocusImpl(boolean reparented) { } - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, - boolean parentChange, int fullScreenChange, int decorationChange) { + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + setVisible0(eglWindowHandle, 0 != ( FLAG_IS_VISIBLE & flags)); + visibleChanged(0 != ( FLAG_IS_VISIBLE & flags)); + } + if(0!=eglWindowHandle) { - if(0!=fullScreenChange) { - boolean fs = fullScreenChange > 0; + if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) { + final boolean fs = 0 != ( FLAG_IS_FULLSCREEN & flags) ; setFullScreen0(eglWindowHandle, fs); if(fs) { return true; @@ -102,15 +101,20 @@ public class KDWindow extends WindowImpl { } // int _x=(x>=0)?x:this.x; // int _y=(x>=0)?y:this.y; - int _w=(width>0)?width:this.width; - int _h=(height>0)?height:this.height; + width=(width>0)?width:this.width; + height=(height>0)?height:this.height; if(width>0 || height>0) { - setSize0(eglWindowHandle, _w, _h); + setSize0(eglWindowHandle, width, height); } if(x>=0 || y>=0) { System.err.println("setPosition n/a in KD"); } } + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + visibleChanged(0 != ( FLAG_IS_VISIBLE & flags)); + } + return true; } diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java index c38c83972..433fc5e2c 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java @@ -183,25 +183,6 @@ public class MacWindow extends WindowImpl { nsViewLock.unlock(); } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { - nsViewLock.lock(); - try { - if (visible) { - createWindow(false, x, y, width, height, isFullscreen()); - if (getWindowHandle() != 0) { - makeKeyAndOrderFront0(getWindowHandle()); - } - } else { - if (getWindowHandle() != 0) { - orderOut0(getWindowHandle()); - } - } - visibleChanged(visible); - } finally { - nsViewLock.unlock(); - } - } - @Override protected void setTitleImpl(final String title) { // FIXME: move nsViewLock up to window lock @@ -223,28 +204,41 @@ public class MacWindow extends WindowImpl { } } - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) { + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { nsViewLock.lock(); try { - if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { - System.err.println("MacWindow reconfig: parentChange "+parentChange+", fullScreenChange "+fullScreenChange+", decorationChange "+decorationChange+" "+x+"/"+y+" "+width+"x"+height); + if(DEBUG_IMPLEMENTATION) { + System.err.println("MacWindow reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ + getReconfigureFlagsAsString(null, flags)); } - int _x=(x>=0)?x:this.x; - int _y=(x>=0)?y:this.y; - int _w=(width>0)?width:this.width; - int _h=(height>0)?height:this.height; - - if(decorationChange!=0 || parentChange || fullScreenChange!=0) { - createWindow(true, _x, _y, _w, _h, fullScreenChange>0); - if (getWindowHandle() != 0) { - makeKeyAndOrderFront0(getWindowHandle()); - } - } else { - if(x>=0 || y>=0) { - setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), _x, _y); + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + if (0 != ( FLAG_IS_VISIBLE & flags)) { + createWindow(false, x, y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); + if (getWindowHandle() != 0) { + makeKeyAndOrderFront0(getWindowHandle()); + } + } else { + if (getWindowHandle() != 0) { + orderOut0(getWindowHandle()); + } } - if(width>0 || height>0) { - setContentSize0(getWindowHandle(), _w, _h); + visibleChanged(0 != ( FLAG_IS_VISIBLE & flags)); + } else { + if( 0 != ( FLAG_CHANGE_DECORATION & flags) || + 0 != ( FLAG_CHANGE_PARENTING & flags) || + 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { + createWindow(true, x, y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); + if (getWindowHandle() != 0) { + makeKeyAndOrderFront0(getWindowHandle()); + } + } else { + if(x>=0 || y>=0) { + setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), x, y); + } + if(width>0 || height>0) { + setContentSize0(getWindowHandle(), width, height); + } } } } finally { @@ -353,12 +347,19 @@ public class MacWindow extends WindowImpl { super.enqueueKeyEvent(wait, eventType, modifiers, key, keyChar); } - private void createWindow(final boolean recreate, final int x, final int y, final int width, final int height, final boolean fullscreen) { + private void createWindow(final boolean recreate, + int x, int y, int width, int height, + final boolean fullscreen) { if(0!=getWindowHandle() && !recreate) { return; } + x=(x>=0)?x:this.x; + y=(x>=0)?y:this.y; + width=(width>0)?width:this.width; + height=(height>0)?height:this.height; + try { //runOnEDTIfAvail(true, new Runnable() { // public void run() { diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java index d6ca64d24..1b33900a4 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java +++ b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java @@ -39,6 +39,7 @@ import jogamp.newt.WindowImpl; import javax.media.nativewindow.GraphicsConfigurationFactory; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.InsetsImmutable; import javax.media.nativewindow.util.Point; public class WindowsWindow extends WindowImpl { @@ -109,7 +110,7 @@ public class WindowsWindow extends WindowImpl { throw new NativeWindowException("Error creating window"); } windowHandleClose = getWindowHandle(); - if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { + if(DEBUG_IMPLEMENTATION) { Exception e = new Exception("Info: Window new window handle "+Thread.currentThread().getName()+ " (Parent HWND "+toHexString(getParentWindowHandle())+ ") : HWND "+toHexString(getWindowHandle())+", "+Thread.currentThread()); @@ -145,15 +146,30 @@ public class WindowsWindow extends WindowImpl { } } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { - setVisible0(getWindowHandle(), visible, (getParentWindowHandle()==0)?true:false, x, y, width, height); - visibleChanged(visible); - } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, - boolean parentChange, int fullScreenChange, int decorationChange) { - reconfigureWindow0( (fullScreenChange>0)?0:getParentWindowHandle(), - getWindowHandle(), x, y, width, height, isVisible(), parentChange, fullScreenChange, decorationChange); + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("WindowsWindow reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ + getReconfigureFlagsAsString(null, flags)); + } + + if(0 == ( FLAG_IS_UNDECORATED & flags)) { + final InsetsImmutable i = getInsets(); + + // client position -> top-level window position + x -= i.getLeftWidth() ; + y -= i.getTopHeight() ; + if( 0 > x ) { x = 0; } + if( 0 > y ) { y = 0; } + + // client size -> top-level window size + width += i.getTotalWidth(); + height += i.getTotalHeight(); + } + reconfigureWindow0( getParentWindowHandle(), getWindowHandle(), x, y, width, height, flags); + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + visibleChanged(0 != ( FLAG_IS_VISIBLE & flags)); + } return true; } @@ -184,10 +200,8 @@ public class WindowsWindow extends WindowImpl { long parentWindowHandle, long visualID, boolean isUndecorated, int x, int y, int width, int height); private native long MonitorFromWindow0(long windowHandle); - private native void setVisible0(long windowHandle, boolean visible, boolean top, int x, int y, int width, int height); - private native void reconfigureWindow0(long parentWindowHandle, long windowHandle, - int x, int y, int width, int height, boolean isVisible, - boolean parentChange, int fullScreenChange, int decorationChange); + private native void reconfigureWindow0(long parentWindowHandle, long windowHandle, + int x, int y, int width, int height, int flags); private static native void setTitle0(long windowHandle, String title); private native void requestFocus0(long windowHandle, boolean force); diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java b/src/newt/classes/jogamp/newt/driver/x11/X11Window.java index 265bec898..8e2e823e4 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java +++ b/src/newt/classes/jogamp/newt/driver/x11/X11Window.java @@ -38,6 +38,7 @@ import jogamp.newt.WindowImpl; import javax.media.nativewindow.*; import javax.media.nativewindow.x11.*; import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.InsetsImmutable; import javax.media.nativewindow.util.Point; public class X11Window extends WindowImpl { @@ -92,18 +93,26 @@ public class X11Window extends WindowImpl { } } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { - setVisible0(getDisplayEDTHandle(), getWindowHandle(), visible, x, y, width, height); - } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, - boolean parentChange, int fullScreenChange, int decorationChange) { + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ + getReconfigureFlagsAsString(null, flags)); + } reparentHandle=0; reparentCount=0; - long reqNewParentHandle = ( fullScreenChange > 0 ) ? 0 : getParentWindowHandle() ; - reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(), reqNewParentHandle, getWindowHandle(), - x, y, width, height, isVisible(), parentChange, fullScreenChange, decorationChange); + if(0 == ( FLAG_IS_UNDECORATED & flags)) { + final InsetsImmutable i = getInsets(); + + // client position -> top-level window position + x -= i.getLeftWidth() ; + y -= i.getTopHeight() ; + if( 0 > x ) { x = 0; } + if( 0 > y ) { y = 0; } + } + reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(), getParentWindowHandle(), getWindowHandle(), + x, y, width, height, flags); + return true; } @@ -121,7 +130,7 @@ public class X11Window extends WindowImpl { } protected void updateInsetsImpl(Insets insets) { - // TODO !! + // nop - using event driven insetsChange(..) } //---------------------------------------------------------------------- @@ -137,13 +146,10 @@ public class X11Window extends WindowImpl { long visualID, long javaObjectAtom, long windowDeleteAtom, int x, int y, int width, int height, boolean undecorated); private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom); - private native void setVisible0(long display, long windowHandle, boolean visible, int x, int y, int width, int height); - private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle, - int x, int y, int width, int height, boolean isVisible, - boolean parentChange, int fullScreenChange, int decorationChange); + private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle, + int x, int y, int width, int height, int flags); private native void setTitle0(long display, long windowHandle, String title); private native void requestFocus0(long display, long windowHandle, boolean force); - private native Object getRelativeLocation0(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y); private void windowReparented(long gotParentHandle) { reparentHandle = gotParentHandle; diff --git a/src/newt/native/Window.h b/src/newt/native/Window.h new file mode 100644 index 000000000..f46d9fbe9 --- /dev/null +++ b/src/newt/native/Window.h @@ -0,0 +1,24 @@ + +#ifndef _WINDOW_H_ +#define _WINDOW_H_ + +#define FLAG_CHANGE_PARENTING ( 1 << 0 ) +#define FLAG_CHANGE_DECORATION ( 1 << 1 ) +#define FLAG_CHANGE_FULLSCREEN ( 1 << 2 ) +#define FLAG_CHANGE_VISIBILITY ( 1 << 3 ) +#define FLAG_HAS_PARENT ( 1 << 4 ) +#define FLAG_IS_UNDECORATED ( 1 << 5 ) +#define FLAG_IS_FULLSCREEN ( 1 << 6 ) +#define FLAG_IS_VISIBLE ( 1 << 7 ) + +#define TST_FLAG_CHANGE_PARENTING(f) ( 0 != ( (f) & FLAG_CHANGE_PARENTING ) ) +#define TST_FLAG_CHANGE_DECORATION(f) ( 0 != ( (f) & FLAG_CHANGE_DECORATION ) ) +#define TST_FLAG_CHANGE_FULLSCREEN(f) ( 0 != ( (f) & FLAG_CHANGE_FULLSCREEN ) ) +#define TST_FLAG_CHANGE_VISIBILITY(f) ( 0 != ( (f) & FLAG_CHANGE_VISIBILITY ) ) + +#define TST_FLAG_HAS_PARENT(f) ( 0 != ( (f) & FLAG_HAS_PARENT ) ) +#define TST_FLAG_IS_UNDECORATED(f) ( 0 != ( (f) & FLAG_IS_UNDECORATED ) ) +#define TST_FLAG_IS_FULLSCREEN(f) ( 0 != ( (f) & FLAG_IS_FULLSCREEN ) ) +#define TST_FLAG_IS_VISIBLE(f) ( 0 != ( (f) & FLAG_IS_VISIBLE ) ) + +#endif diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 0dd1b6260..2ae50f550 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -85,6 +85,7 @@ #include "jogamp_newt_driver_windows_WindowsScreen.h" #include "jogamp_newt_driver_windows_WindowsWindow.h" +#include "Window.h" #include "MouseEvent.h" #include "InputEvent.h" #include "KeyEvent.h" @@ -666,8 +667,8 @@ static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd) (int)(m_insets.right-m_insets.left), (int)(m_insets.top-m_insets.bottom)); (*env)->CallVoidMethod(env, window, insetsChangedID, - m_insets.left, m_insets.top, - m_insets.right, m_insets.bottom); + m_insets.left, m_insets.right, + m_insets.top, m_insets.bottom); return &m_insets; } @@ -703,7 +704,6 @@ static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd) m_insets.right < 0 || m_insets.bottom < 0) { LONG style = GetWindowLong(hwnd, GWL_STYLE); - // TODO: TDV: better undecorated checking needed BOOL bIsUndecorated = (style & (WS_CHILD|WS_POPUP|WS_SYSMENU)) != 0; if (!bIsUndecorated) { @@ -728,12 +728,12 @@ static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd) } } - DBG_PRINT("*** WindowsWindow: UpdateInsets window %p, %d/%d %dx%d\n", - (void*)hwnd, (int)m_insets.left, (int)m_insets.top, (int)(m_insets.right-m_insets.left), (int)(m_insets.top-m_insets.bottom)); + DBG_PRINT("*** WindowsWindow: UpdateInsets window %p, [l %d, r %d - t %d, b %d - %dx%d]\n", + (void*)hwnd, (int)m_insets.left, (int)m_insets.right, (int)m_insets.top, (int)m_insets.bottom, + (int) ( m_insets.left + m_insets.right ), (int) (m_insets.top + m_insets.bottom)); - (*env)->CallVoidMethod(env, window, insetsChangedID, - m_insets.left, m_insets.top, - m_insets.right, m_insets.bottom); + (*env)->CallVoidMethod(env, window, insetsChangedID, + (int)m_insets.left, (int)m_insets.right, (int)m_insets.top, (int)m_insets.bottom); return &m_insets; } @@ -745,19 +745,19 @@ static void WmSize(JNIEnv *env, jobject window, HWND wnd, UINT type) int w, h; BOOL isVisible = IsWindowVisible(wnd); - // make sure insets are up to date - (void)UpdateInsets(env, window, wnd); - if (type == SIZE_MINIMIZED) { // TODO: deal with minimized window sizing return; } + // make sure insets are up to date + (void)UpdateInsets(env, window, wnd); + GetClientRect(wnd, &rc); // we report back the dimensions of the client area - w = rc.right - rc.left; - h = rc.bottom - rc.top; + w = (int) ( rc.right - rc.left ); + h = (int) ( rc.bottom - rc.top ); DBG_PRINT("*** WindowsWindow: WmSize window %p, %dx%d, visible %d\n", (void*)wnd, w, h, isVisible); @@ -1351,8 +1351,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind #else SetWindowLongPtr(window, GWLP_USERDATA, (intptr_t) wud); #endif - - UpdateInsets(env, obj, window); + (void)UpdateInsets(env, wud->jinstance, window); } #ifdef UNICODE @@ -1381,80 +1380,26 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_MonitorFro #endif } -/*** - * returns bits: 1: size change, 2: pos change - */ -int NewtWindow_setVisiblePosSize(JNIEnv *env, jobject obj, HWND hwnd, jboolean top, jboolean visible, - int x, int y, int width, int height) +void NewtWindow_setVisiblePosSize(JNIEnv *env, jobject obj, HWND hwnd, + BOOL top, BOOL undecorated, BOOL visible, + int x, int y, int width, int height) { UINT flags; - HWND hWndInsertAfter; BOOL bRes; - int iRes=0; - int wwidth = width; // final window width - int wheight = height; // final window height - DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize %d/%d %dx%d, top %d, visible %d\n", - x, y, width, height, (int)top, (int)visible); + DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize %d/%d %dx%d, top %d, undecorated %d, visible %d\n", + x, y, width, height, top, undecorated, visible); - if(JNI_TRUE == visible) { + if(visible) { flags = SWP_SHOWWINDOW; } else { flags = SWP_NOACTIVATE | SWP_NOZORDER; } - if(0>x || 0>y ) { - flags |= SWP_NOMOVE; - } else { - iRes |= 2; - } - if(0>=width || 0>=height ) { - flags |= SWP_NOSIZE; - } else { - iRes |= 1; - } - - if(JNI_TRUE == top) { - hWndInsertAfter = HWND_TOPMOST; - if ( 0 == ( flags & SWP_NOSIZE ) ) { - - // since width, height are the size of the client area, we need to add insets - RECT *pInsets = UpdateInsets(env, obj, hwnd); - - wwidth += pInsets->left + pInsets->right; - wheight += pInsets->top + pInsets->bottom; - } - DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize top size w/ insets: %d/%d %dx%d\n", x, y, wwidth, wheight); - } else { - hWndInsertAfter = HWND_TOP; - DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize client size: %d/%d %dx%d\n", x, y, wwidth, wheight); - } - - SetWindowPos(hwnd, hWndInsertAfter, x, y, wwidth, wheight, flags); + SetWindowPos(hwnd, top ? HWND_TOPMOST : HWND_TOP, x, y, width, height, flags); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); - - return iRes; -} - -/* - * Class: jogamp_newt_driver_windows_WindowsWindow - * Method: setVisible0 - * Signature: (JZ)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setVisible0 - (JNIEnv *env, jobject obj, jlong window, jboolean visible, jboolean top, jint x, jint y, jint width, jint height) -{ - HWND hwnd = (HWND) (intptr_t) window; - DBG_PRINT("*** WindowsWindow: setVisible window %p, visible: %d, top %d, %d/%d %dx%d\n", - hwnd, (int)visible, (int)top, x, y, width, height); - if (visible) { - NewtWindow_setVisiblePosSize(env, obj, hwnd, top, visible, x, y, width, height); - ShowWindow(hwnd, SW_SHOW); - } else { - ShowWindow(hwnd, SW_HIDE); - } } static jboolean NewtWindows_setFullScreen(jboolean fullscreen) @@ -1478,21 +1423,23 @@ static jboolean NewtWindows_setFullScreen(jboolean fullscreen) /* * Class: jogamp_newt_driver_windows_WindowsWindow * Method: reconfigureWindow0 - * Signature: (JIIIIZZII)V + * Signature: (JJIIIII)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigureWindow0 - (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, - jboolean visible, jboolean parentChange, jint fullScreenChange, jint decorationChange) + (JNIEnv *env, jobject obj, jlong parent, jlong window, + jint x, jint y, jint width, jint height, jint flags) { HWND hwndP = (HWND) (intptr_t) parent; HWND hwnd = (HWND) (intptr_t) window; DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN ; - BOOL styleChange = ( 0 != decorationChange || 0 != fullScreenChange || JNI_TRUE == parentChange ) ? TRUE : FALSE ; - UINT flags = SWP_SHOWWINDOW; - HWND hWndInsertAfter; + BOOL styleChange = TST_FLAG_CHANGE_DECORATION(flags) || TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags) ; - DBG_PRINT("*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, fullScreenChange %d, visible %d, decorationChange %d -> styleChange %d\n", - parent, window, x, y, width, height, parentChange, fullScreenChange, visible, decorationChange, styleChange); + DBG_PRINT( "*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, visibleChange %d, visible %d -> styleChange %d\n", + parent, window, x, y, width, height, + TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_HAS_PARENT(flags), + TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags), + TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags), + TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), styleChange); if (!IsWindow(hwnd)) { DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed window %p is invalid\n", (void*)hwnd); @@ -1504,12 +1451,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigure return; } - if(JNI_TRUE == visible) { + if(TST_FLAG_IS_VISIBLE(flags)) { windowStyle |= WS_VISIBLE ; } - if(fullScreenChange < 0) - { + if( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off NewtWindows_setFullScreen(JNI_FALSE); } @@ -1517,19 +1463,18 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigure // TOP: SetParent(.., NULL); Clear WS_CHILD [, Set WS_POPUP] // CHILD: Set WS_CHILD [, Clear WS_POPUP]; SetParent(.., PARENT) // - if ( JNI_TRUE == parentChange && NULL == hwndP ) { + if( TST_FLAG_CHANGE_PARENTING(flags) && NULL == hwndP ) { SetParent(hwnd, NULL); } - if(fullScreenChange > 0) - { + if( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) { // FS on NewtWindows_setFullScreen(JNI_TRUE); } if ( styleChange ) { if(NULL!=hwndP) { windowStyle |= WS_CHILD ; - } else if ( decorationChange < 0 || 0 < fullScreenChange ) { + } else if ( TST_FLAG_IS_UNDECORATED(flags) ) { windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; } else { windowStyle |= WS_OVERLAPPEDWINDOW; @@ -1538,12 +1483,20 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigure SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER ); } - if ( JNI_TRUE == parentChange && NULL != hwndP ) { + if ( TST_FLAG_CHANGE_PARENTING(flags) && NULL != hwndP ) { SetParent(hwnd, hwndP ); } - NewtWindow_setVisiblePosSize(env, obj, hwnd, (NULL == hwndP) ? JNI_TRUE : JNI_FALSE /* top */, visible, - x, y, width, height); + NewtWindow_setVisiblePosSize(env, obj, hwnd, (NULL == hwndP) ? JNI_TRUE : JNI_FALSE /* top */, + TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_VISIBLE(flags), x, y, width, height); + + if( TST_FLAG_CHANGE_VISIBILITY(flags) ) { + if( TST_FLAG_IS_VISIBLE(flags) ) { + ShowWindow(hwnd, SW_SHOW); + } else { + ShowWindow(hwnd, SW_HIDE); + } + } DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X\n"); } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index a18efbdb8..43ff6b3bc 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -52,6 +52,7 @@ #include "jogamp_newt_driver_x11_X11Display.h" #include "jogamp_newt_driver_x11_X11Window.h" +#include "Window.h" #include "MouseEvent.h" #include "InputEvent.h" #include "KeyEvent.h" @@ -164,6 +165,7 @@ static const char * const ClazzNameNewtWindow = "com/jogamp/newt/Window"; static jclass newtWindowClz=NULL; +static jmethodID insetsChangedID = NULL; static jmethodID sizeChangedID = NULL; static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; @@ -380,34 +382,34 @@ static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlon } static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) { - Atom actual_type_return; - int actual_format_return; + Atom actual_type; + int actual_format; int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ; unsigned char * jogl_java_object_data_pp = NULL; jobject jwindow; { - unsigned long nitems_return = 0; - unsigned long bytes_after_return = 0; + unsigned long nitems= 0; + unsigned long bytes_after= 0; jobject jwindow = NULL; int res; res = XGetWindowProperty(dpy, window, (Atom)javaObjectAtom, 0, nitems_32, False, - (Atom)javaObjectAtom, &actual_type_return, &actual_format_return, - &nitems_return, &bytes_after_return, &jogl_java_object_data_pp); + (Atom)javaObjectAtom, &actual_type, &actual_format, + &nitems, &bytes_after, &jogl_java_object_data_pp); if ( Success != res ) { if(True==showWarning) { - fprintf(stderr, "Warning: NEWT X11Window: Could not fetch Atom NEWT_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, result 0!\n", res, nitems_return, bytes_after_return); + fprintf(stderr, "Warning: NEWT X11Window: Could not fetch Atom NEWT_JAVA_OBJECT window property (res %d) nitems %ld, bytes_after %ld, result 0!\n", res, nitems, bytes_after); } return NULL; } - if(actual_type_return!=(Atom)javaObjectAtom || nitems_return<nitems_32 || NULL==jogl_java_object_data_pp) { + if(actual_type!=(Atom)javaObjectAtom || nitems<nitems_32 || NULL==jogl_java_object_data_pp) { XFree(jogl_java_object_data_pp); if(True==showWarning) { - fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom NEWT_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, actual_type_return %ld, NEWT_JAVA_OBJECT %ld, result 0!\n", - res, nitems_return, bytes_after_return, (long)actual_type_return, javaObjectAtom); + fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom NEWT_JAVA_OBJECT window property (res %d) nitems %ld, bytes_after %ld, actual_type %ld, NEWT_JAVA_OBJECT %ld, result 0!\n", + res, nitems, bytes_after, (long)actual_type, javaObjectAtom); } return NULL; } @@ -433,7 +435,7 @@ static Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * roo if(NULL!=children_return) { XFree(children_return); } - return res; + return res; // 0 == res -> Error } static Window NewtWindows_getRoot (Display *dpy, Window w) { Window root_return; @@ -441,7 +443,7 @@ static Window NewtWindows_getRoot (Display *dpy, Window w) { if( 0 != NewtWindows_getRootAndParent(dpy, w, &root_return, &parent_return) ) { return root_return; } - return 0; + return 0; // Error } static Window NewtWindows_getParent (Display *dpy, Window w) { Window root_return; @@ -449,26 +451,100 @@ static Window NewtWindows_getParent (Display *dpy, Window w) { if( 0 != NewtWindows_getRootAndParent(dpy, w, &root_return, &parent_return) ) { return parent_return; } - return 0; + return 0; // Error } +static Status NewtWindows_getParentPosition (Display *dpy, Window w, int *x_return, int *y_return) { + Window root_return; + unsigned int width_return, height_return; + unsigned int border_width_return; + unsigned int depth_return; + Window parent = NewtWindows_getParent(dpy, w); + if(0 != parent) { + XGetGeometry(dpy, parent, &root_return, x_return, y_return, &width_return, + &height_return, &border_width_return, &depth_return); + return 1; // OK + } + return 0; // Error +} +static Status NewtWindows_getFrameExtends(Display *dpy, Window window, int *left, int *right, int *top, int *bottom) { + Atom actual_type; + int actual_format; + int nitems_32 = 4; // l, r, t, b + unsigned char * frame_extends_data_pp = NULL; + + { + Atom _NET_FRAME_EXTENTS = XInternAtom( dpy, "_NET_FRAME_EXTENTS", False ); + unsigned long nitems = 0; + unsigned long bytes_after = 0; + int res; + + res = XGetWindowProperty(dpy, window, _NET_FRAME_EXTENTS, 0, nitems_32, False, + AnyPropertyType, &actual_type, &actual_format, + &nitems, &bytes_after, &frame_extends_data_pp); + + if ( Success != res ) { + fprintf(stderr, "Warning: NEWT X11Window: Could not fetch Atom _NET_FRAME_EXTENTS window property (res %d) nitems %ld, bytes_after %ld, result 0!\n", res, nitems, bytes_after); + return 0; // Error + } + + if(nitems<nitems_32 || NULL==frame_extends_data_pp) { + XFree(frame_extends_data_pp); + fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom _NET_FRAME_EXTENTS window property (res %d) nitems %ld, bytes_after %ld, actual_type %ld, actual_format %d, _NET_FRAME_EXTENTS %ld, result 0!\n", + res, nitems, bytes_after, (long)actual_type, actual_format, _NET_FRAME_EXTENTS); + return 0; // Error + } + } + long * extends = (long*) frame_extends_data_pp; + *left = (int) *(extends + 0); + *right = (int) *(extends + 1); + *top = (int) *(extends + 2); + *bottom = (int) *(extends + 3); + + DBG_PRINT( "X11: _NET_FRAME_EXTENTS: window %p insets [ l %d, r %d, t %d, b %d ]\n", + (void*)window, *left, *right, *top, *bottom); + + XFree(frame_extends_data_pp); + + return 1; // Ok +} +static Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom) { + if(0 != NewtWindows_getFrameExtends(dpy, window, left, right, top, bottom)) { + DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n", + *left, *right, *top, *bottom); + (*env)->CallVoidMethod(env, jwindow, insetsChangedID, *left, *right, *top, *bottom); + return 1; // OK + } else if(0 != NewtWindows_getParentPosition (dpy, window, left, top)) { + *right = *left; *bottom = *left; + DBG_PRINT( "NewtWindows_updateInsets: insets by parent position [ l %d, r %d, t %d, b %d ]\n", + *left, *right, *top, *bottom); + (*env)->CallVoidMethod(env, jwindow, insetsChangedID, *left, *right, *top, *bottom); + return 1; // OK + } + return 0; // Error +} static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w, jboolean force) { XWindowAttributes xwa; Window focus_return; int revert_to_return; + DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d\n", dpy, (void*)w, force); + XGetInputFocus(dpy, &focus_return, &revert_to_return); if( JNI_TRUE==force || focus_return!=w) { if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) { + DBG_PRINT( "X11: XRaiseWindow dpy %p,win %pd\n", dpy, (void*)w); XRaiseWindow(dpy, w); // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable XGetWindowAttributes(dpy, w, &xwa); if(xwa.map_state == IsViewable) { + DBG_PRINT( "X11: XSetInputFocus dpy %p,win %pd\n", dpy, (void*)w); XSetInputFocus(dpy, w, RevertToParent, CurrentTime); } } } + DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d - FIN\n", dpy, (void*)w, force); XSync(dpy, False); } @@ -583,7 +659,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0 return ; } - DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type); + // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type); displayDispatchErrorHandlerEnable(1, env); @@ -707,6 +783,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0 evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event); if ( evt.xconfigure.window == evt.xconfigure.event ) { // ignore child window change notification + { + // update insets + int left, right, top, bottom; + NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom); + } (*env)->CallVoidMethod(env, jwindow, sizeChangedID, (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE); (*env)->CallVoidMethod(env, jwindow, positionChangedID, @@ -749,6 +830,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0 evt.xmap.event!=evt.xmap.window); if( evt.xmap.event == evt.xmap.window ) { // ignore child window notification + { + // update insets + int left, right, top, bottom; + NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom); + } (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE); } break; @@ -786,7 +872,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0 parentResult = (jlong) (intptr_t) evt.xreparent.parent; } #ifdef VERBOSE_ON - DBG_PRINT( "X11: event . ReparentNotify: call OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n", + DBG_PRINT( "X11: event . ReparentNotify: call %d/%d OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n", + evt.xreparent.x, evt.xreparent.y, (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent, (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent, (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent); @@ -1256,6 +1343,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0 (JNIEnv *env, jclass clazz) { + insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V"); sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(IIZ)V"); positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); @@ -1270,7 +1358,8 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0 enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V"); focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z"); - if (sizeChangedID == NULL || + if (insetsChangedID == NULL || + sizeChangedID == NULL || positionChangedID == NULL || focusChangedID == NULL || visibleChangedID == NULL || @@ -1305,6 +1394,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0 int scrn_idx = (int)screen_index; Window windowParent = (Window) parent; Window window = 0; + jobject jwindow = 0; XVisualInfo visualTemplate; XVisualInfo *pVisualQuery = NULL; @@ -1401,11 +1491,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0 } XSetWMProtocols(dpy, window, &wm_delete_atom, 1); // windowDeleteAtom - setJavaWindowProperty(env, dpy, window, javaObjectAtom, (*env)->NewGlobalRef(env, obj)); + jwindow = (*env)->NewGlobalRef(env, obj); + setJavaWindowProperty(env, dpy, window, javaObjectAtom, jwindow); NewtWindows_setDecorations(dpy, window, ( JNI_TRUE == undecorated ) ? False : True ); XSync(dpy, False); + // since native creation happens at setVisible(true) .. + // we can pre-map the window here to be able to gather the insets. + XMapWindow(dpy, window); + XSync(dpy, False); + { + // update insets + int left, right, top, bottom; + NewtWindows_updateInsets(env, jwindow, dpy, window, &left, &right, &top, &bottom); + } + DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", (void*)window, dpy); return (jlong) window; } @@ -1454,57 +1555,31 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0 DBG_PRINT( "X11: CloseWindow END\n"); } -static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint width, jint height) +static void NewtWindows_setPosSize(Display *dpy, int screen_index, Window w, jint x, jint y, jint width, jint height, Bool undecorated) { if(width>0 && height>0 || x>=0 && y>=0) { // resize/position if requested XWindowChanges xwc; - unsigned int mod_flags = ( (x>=0)?CWX:0 ) | ( (y>=0)?CWY:0 ) | - ( (width>0)?CWWidth:0 ) | ( (height>0)?CWHeight:0 ) ; - DBG_PRINT( "X11: reconfigureWindow0 %d/%d %dx%d, mod: 0x%X\n", x, y, width, height, mod_flags); + + DBG_PRINT( "X11: reconfigureWindow0 %d/%d %dx%d\n", x, y, width, height); + memset(&xwc, 0, sizeof(XWindowChanges)); xwc.x=x; xwc.y=y; xwc.width=width; xwc.height=height; - XConfigureWindow(dpy, w, mod_flags, &xwc); + XConfigureWindow(dpy, w, (CWX | CWY | CWWidth | CWHeight), &xwc); XSync(dpy, False); } } /* * Class: jogamp_newt_driver_x11_X11Window - * Method: setVisible0 - * Signature: (JJZIIII)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_setVisible0 - (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean visible, jint x, jint y, jint width, jint height) -{ - Display * dpy = (Display *) (intptr_t) display; - Window w = (Window)window; - DBG_PRINT( "X11: setVisible0 vis %d - %d/%d %dx%d\n", visible, x, y, width, height); - - if(dpy==NULL) { - NewtCommon_FatalError(env, "invalid display connection.."); - } - - if(visible==JNI_TRUE) { - XMapRaised(dpy, w); - } else { - XUnmapWindow(dpy, w); - } - XSync(dpy, False); - - NewtWindows_setPosSize(dpy, w, x, y, width, height); -} - -/* - * Class: jogamp_newt_driver_x11_X11Window * Method: reconfigureWindow0 - * Signature: (JIJJIIIIZZII)V + * Signature: (JIJJIIIII)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 (JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index, jlong jparent, jlong jwindow, - jint x, jint y, jint width, jint height, jboolean isVisible, jboolean parentChange, jint fullscreenChange, jint decorationChange) + jint x, jint y, jint width, jint height, jint flags) { Display * dpy = (Display *) (intptr_t) jdisplay; Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index); @@ -1513,54 +1588,56 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 Window parent = (0!=jparent)?(Window)jparent:root; Window topParentParent; Window topParentWindow; - Bool moveIntoParent = False; displayDispatchErrorHandlerEnable(1, env); topParentParent = NewtWindows_getParent (dpy, parent); topParentWindow = NewtWindows_getParent (dpy, w); - DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d/%p, parent %p/%p (top %p), win %p (top %p), %d/%d %dx%d visible %d, parentChange %d, fullscreenChange %d, decorationChange %d\n", + DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d/%p, parent %p/%p (top %p), win %p (top %p), %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, visibleChange %d, visible %d\n", (void*)dpy, screen_index, (void*)scrn, (void*) jparent, (void*)parent, (void*) topParentParent, (void*)w, (void*)topParentWindow, - x, y, width, height, isVisible, parentChange, fullscreenChange, decorationChange); + x, y, width, height, + TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_HAS_PARENT(flags), + TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags), + TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags), + TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags)); - if(JNI_TRUE == isVisible) { // unmap window if visible, reduce X11 internal signaling (WM unmap) - XUnmapWindow(dpy, w); + if( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off + NewtWindows_setFullscreen(dpy, root, w, False ); XSync(dpy, False); } - if(0 > fullscreenChange ) { // FS off - NewtWindows_setFullscreen(dpy, root, w, False ); + if( TST_FLAG_CHANGE_DECORATION(flags) && TST_FLAG_IS_UNDECORATED(flags) ) { + NewtWindows_setDecorations (dpy, w, False); XSync(dpy, False); } - if(parentChange) { - if(0 != jparent) { // move into parent .. - moveIntoParent = True; - NewtWindows_setDecorations (dpy, w, False); - XSync(dpy, False); - } + if( TST_FLAG_CHANGE_PARENTING(flags) ) { XReparentWindow( dpy, w, parent, x, y ); // actual reparent call XSync(dpy, False); } - if(!moveIntoParent && 0!=decorationChange) { - NewtWindows_setDecorations (dpy, w, (0 < decorationChange) ? True : False); + if( TST_FLAG_CHANGE_DECORATION(flags) && !TST_FLAG_IS_UNDECORATED(flags) ) { + NewtWindows_setDecorations (dpy, w, True); + XSync(dpy, False); + } + + if( TST_FLAG_CHANGE_VISIBILITY(flags) ) { + if( TST_FLAG_IS_VISIBLE(flags) ) { + XMapRaised(dpy, w); + } else { + XUnmapWindow(dpy, w); + } XSync(dpy, False); } - NewtWindows_setPosSize(dpy, w, x, y, width, height); + NewtWindows_setPosSize(dpy, screen_index, w, x, y, width, height, TST_FLAG_IS_UNDECORATED(flags) ? True : False); - if(0 < fullscreenChange ) { // FS on + if( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) { // FS on NewtWindows_setFullscreen(dpy, root, w, True ); XSync(dpy, False); } - if(JNI_TRUE == isVisible) { // map window - XMapRaised(dpy, w); - XSync(dpy, False); - } - displayDispatchErrorHandlerEnable(0, env); DBG_PRINT( "X11: reconfigureWindow0 X\n"); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java index 8ee182939..99e81af04 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java @@ -60,8 +60,8 @@ public class TestSharedContextListAWT extends UITestCase { Assert.assertNotNull(glp); caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - width = 512; - height = 512; + width = 256; + height = 256; } private void initShared() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java index 231a45ca0..73a227740 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java @@ -30,6 +30,7 @@ package com.jogamp.opengl.test.junit.jogl.acore; import com.jogamp.newt.opengl.GLWindow; +import javax.media.nativewindow.util.InsetsImmutable; import javax.media.opengl.FPSCounter; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLDrawableFactory; @@ -58,8 +59,8 @@ public class TestSharedContextListNEWT extends UITestCase { Assert.assertNotNull(glp); caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - width = 512; - height = 512; + width = 256; + height = 256; } private void initShared() { @@ -86,7 +87,6 @@ public class TestSharedContextListNEWT extends UITestCase { } glWindow.setSize(width, height); - glWindow.setPosition(x, y); Gears gears = new Gears(vsync ? 1 : 0); if(useShared) { @@ -98,6 +98,9 @@ public class TestSharedContextListNEWT extends UITestCase { glWindow.setVisible(true); + /** insets (if supported) are available only if window is set visible and hence is created */ + glWindow.setTopLevelPosition(x, y); + return glWindow; } @@ -106,8 +109,9 @@ public class TestSharedContextListNEWT extends UITestCase { initShared(); Animator animator = new Animator(); GLWindow f1 = runTestGL(animator, 0, 0, true, false); - GLWindow f2 = runTestGL(animator, width, 0, true, false); - GLWindow f3 = runTestGL(animator, 0, height, false, true); + InsetsImmutable insets = f1.getInsets(); + GLWindow f2 = runTestGL(animator, width+insets.getTotalWidth(), 0, true, false); + GLWindow f3 = runTestGL(animator, 0, height+insets.getTotalHeight(), false, true); animator.setUpdateFPSFrames(1, null); animator.start(); while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java index c230ffd6d..e78efb396 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java @@ -30,6 +30,7 @@ package com.jogamp.opengl.test.junit.jogl.acore; import com.jogamp.newt.opengl.GLWindow; +import javax.media.nativewindow.util.InsetsImmutable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLPbuffer; @@ -57,8 +58,8 @@ public class TestSharedContextVBOES1NEWT extends UITestCase { Assert.assertNotNull(glp); caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - width = 512; - height = 512; + width = 256; + height = 256; } private void initShared() { @@ -85,7 +86,6 @@ public class TestSharedContextVBOES1NEWT extends UITestCase { } glWindow.setSize(width, height); - glWindow.setPosition(x, y); GearsES1 gears = new GearsES1(vsync ? 1 : 0); if(useShared) { @@ -97,6 +97,9 @@ public class TestSharedContextVBOES1NEWT extends UITestCase { glWindow.setVisible(true); + /** insets (if supported) are available only if window is set visible and hence is created */ + glWindow.setTopLevelPosition(x, y); + return glWindow; } @@ -105,8 +108,9 @@ public class TestSharedContextVBOES1NEWT extends UITestCase { initShared(); Animator animator = new Animator(); GLWindow f1 = runTestGL(animator, 0, 0, true, false); - GLWindow f2 = runTestGL(animator, width, 0, true, false); - GLWindow f3 = runTestGL(animator, 0, height, false, true); + InsetsImmutable insets = f1.getInsets(); + GLWindow f2 = runTestGL(animator, width+insets.getTotalWidth(), 0, true, false); + GLWindow f3 = runTestGL(animator, 0, height+insets.getTotalHeight(), false, true); animator.setUpdateFPSFrames(1, null); animator.start(); while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java index 602f5c3b5..a37c43c58 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java @@ -30,6 +30,7 @@ package com.jogamp.opengl.test.junit.jogl.acore; import com.jogamp.newt.opengl.GLWindow; +import javax.media.nativewindow.util.InsetsImmutable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLPbuffer; @@ -57,8 +58,8 @@ public class TestSharedContextVBOES2NEWT extends UITestCase { Assert.assertNotNull(glp); caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - width = 512; - height = 512; + width = 256; + height = 256; } private void initShared() { @@ -85,7 +86,6 @@ public class TestSharedContextVBOES2NEWT extends UITestCase { } glWindow.setSize(width, height); - glWindow.setPosition(x, y); GearsES2 gears = new GearsES2(vsync ? 1 : 0); if(useShared) { @@ -96,6 +96,9 @@ public class TestSharedContextVBOES2NEWT extends UITestCase { animator.add(glWindow); glWindow.setVisible(true); + + /** insets (if supported) are available only if window is set visible and hence is created */ + glWindow.setTopLevelPosition(x, y); return glWindow; } @@ -105,8 +108,9 @@ public class TestSharedContextVBOES2NEWT extends UITestCase { initShared(); Animator animator = new Animator(); GLWindow f1 = runTestGL(animator, 0, 0, true, false); - GLWindow f2 = runTestGL(animator, width, 0, true, false); - GLWindow f3 = runTestGL(animator, 0, height, false, true); + InsetsImmutable insets = f1.getInsets(); + GLWindow f2 = runTestGL(animator, width+insets.getTotalWidth(), 0, true, false); + GLWindow f3 = runTestGL(animator, 0, height+insets.getTotalHeight(), false, true); animator.setUpdateFPSFrames(1, null); animator.start(); while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java index c8c92ea48..3c7a8a006 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java @@ -90,12 +90,23 @@ public class TestGearsES2NEWT extends UITestCase { if(e.getKeyChar()=='f') { new Thread() { public void run() { + System.err.println("[set fullscreen pre]: "+f_glWindow.getX()+"/"+f_glWindow.getY()+" "+f_glWindow.getWidth()+"x"+f_glWindow.getHeight()+", f "+f_glWindow.isFullscreen()+", "+f_glWindow.getInsets()); f_glWindow.setFullscreen(!f_glWindow.isFullscreen()); + System.err.println("[set fullscreen post]: "+f_glWindow.getX()+"/"+f_glWindow.getY()+" "+f_glWindow.getWidth()+"x"+f_glWindow.getHeight()+", f "+f_glWindow.isFullscreen()+", "+f_glWindow.getInsets()); } }.start(); } else if(e.getKeyChar()=='d') { new Thread() { public void run() { + System.err.println("[set undecorated pre]: "+f_glWindow.getX()+"/"+f_glWindow.getY()+" "+f_glWindow.getWidth()+"x"+f_glWindow.getHeight()+", d "+f_glWindow.isUndecorated()+", "+f_glWindow.getInsets()); f_glWindow.setUndecorated(!f_glWindow.isUndecorated()); + System.err.println("[set undecorated post]: "+f_glWindow.getX()+"/"+f_glWindow.getY()+" "+f_glWindow.getWidth()+"x"+f_glWindow.getHeight()+", d "+f_glWindow.isUndecorated()+", "+f_glWindow.getInsets()); + } }.start(); + } else if(e.getKeyChar()=='s') { + new Thread() { + public void run() { + System.err.println("[set position pre]: "+f_glWindow.getX()+"/"+f_glWindow.getY()+" "+f_glWindow.getWidth()+"x"+f_glWindow.getHeight()+", "+f_glWindow.getInsets()); + f_glWindow.setPosition(100, 100); + System.err.println("[set position post]: "+f_glWindow.getX()+"/"+f_glWindow.getY()+" "+f_glWindow.getWidth()+"x"+f_glWindow.getHeight()+", "+f_glWindow.getInsets()); } }.start(); } } @@ -103,6 +114,9 @@ public class TestGearsES2NEWT extends UITestCase { glWindow.setSize(width, height); glWindow.setVisible(true); + + System.err.println("size/pos: "+f_glWindow.getX()+"/"+f_glWindow.getY()+" "+f_glWindow.getWidth()+"x"+f_glWindow.getHeight()+", "+f_glWindow.getInsets()); + animator.setUpdateFPSFrames(1, null); animator.start(); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java new file mode 100644 index 000000000..e3cf132f6 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java @@ -0,0 +1,66 @@ +/** + * Copyright 2011 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. + */ +package com.jogamp.opengl.test.junit.newt.parenting; + +import java.awt.Frame; + +import com.jogamp.newt.awt.NewtCanvasAWT; +import com.jogamp.newt.event.KeyAdapter; +import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.opengl.GLWindow; + +class NewtAWTReparentingKeyAdapter extends KeyAdapter { + Frame frame; + NewtCanvasAWT newtCanvasAWT; + GLWindow glWindow; + + public NewtAWTReparentingKeyAdapter(Frame frame, NewtCanvasAWT newtCanvasAWT, GLWindow glWindow) { + this.frame = frame; + this.newtCanvasAWT = newtCanvasAWT; + this.glWindow = glWindow; + } + + public void keyTyped(KeyEvent e) { + if(e.getKeyChar()=='d') { + glWindow.setUndecorated(!glWindow.isUndecorated()); + } else if(e.getKeyChar()=='f') { + glWindow.setFullscreen(!glWindow.isFullscreen()); + } else if(e.getKeyChar()=='r') { + if(glWindow.getParent()==null) { + System.err.println("XXX glWin to home"); + glWindow.reparentWindow(newtCanvasAWT.getNativeWindow()); + } else { + System.err.println("XXX glWin to TOP"); + glWindow.setUndecorated(false); + glWindow.reparentWindow(null); + glWindow.setTopLevelPosition(frame.getX()+frame.getWidth(), frame.getY()); + } + glWindow.requestFocus(); + } + } +}
\ No newline at end of file diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03bAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03bAWT.java index 1f2259d1d..ec481d3a1 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03bAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03bAWT.java @@ -71,6 +71,7 @@ public class TestParenting03bAWT extends UITestCase { } public void testWindowParenting1AWTTwoNewtChilds() throws InterruptedException, InvocationTargetException { + Frame frame1 = new Frame("AWT Parent Frame"); GLWindow glWindow1 = GLWindow.create(glCaps); glWindow1.setUpdateFPSFrames(1, null); glWindow1.setUndecorated(true); @@ -80,25 +81,7 @@ public class TestParenting03bAWT extends UITestCase { GLEventListener demo1 = new GearsES2(1); setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); - final NewtCanvasAWT f_newtCanvasAWT1 = newtCanvasAWT1; - final GLWindow f_glWindow1 = glWindow1; - glWindow1.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { - if(e.getKeyChar()=='d') { - f_glWindow1.setUndecorated(!f_glWindow1.isUndecorated()); - } else if(e.getKeyChar()=='f') { - f_glWindow1.setFullscreen(!f_glWindow1.isFullscreen()); - } else if(e.getKeyChar()=='r') { - if(f_glWindow1.getParent()==null) { - System.err.println("XXX glWin1 to home"); - f_glWindow1.reparentWindow(f_newtCanvasAWT1.getNativeWindow()); - } else { - System.err.println("XXX glWin1 to TOP"); - f_glWindow1.reparentWindow(null); - } - } - } - }); + glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1)); GLAnimatorControl animator1 = new Animator(glWindow1); animator1.start(); @@ -111,25 +94,7 @@ public class TestParenting03bAWT extends UITestCase { GLEventListener demo2 = new GearsES2(1); setDemoFields(demo2, glWindow2, false); glWindow2.addGLEventListener(demo2); - final NewtCanvasAWT f_newtCanvasAWT2 = newtCanvasAWT2; - final GLWindow f_glWindow2 = glWindow2; - glWindow2.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { - if(e.getKeyChar()=='d') { - f_glWindow2.setUndecorated(!f_glWindow2.isUndecorated()); - } else if(e.getKeyChar()=='f') { - f_glWindow2.setFullscreen(!f_glWindow2.isFullscreen()); - } else if(e.getKeyChar()=='r') { - if(f_glWindow2.getParent()==null) { - System.err.println("XXX glWin2 to home"); - f_glWindow2.reparentWindow(f_newtCanvasAWT2.getNativeWindow()); - } else { - System.err.println("XXX glWin2 to TOP"); - f_glWindow2.reparentWindow(null); - } - } - } - }); + glWindow2.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT2, glWindow2)); GLAnimatorControl animator2 = new Animator(glWindow2); animator2.start(); @@ -144,7 +109,6 @@ public class TestParenting03bAWT extends UITestCase { cont2.setVisible(true); final Container f_cont2 = cont2; - Frame frame1 = new Frame("AWT Parent Frame"); frame1.setLayout(new BorderLayout()); frame1.add(cont1, BorderLayout.EAST); frame1.add(new Label("center"), BorderLayout.CENTER); |