aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-10-21 04:24:06 +0200
committerSven Gothel <[email protected]>2010-10-21 04:24:06 +0200
commit18bf27fa86da1f26fd085565f501736816d2f2e9 (patch)
treeca44458e4bb00b7969b77473ad93cd826c5ca6a7 /src/newt
parent6da90f18da639f942bce9dec7fdd9a6c43e22145 (diff)
NEWT: Fix / Stabilize Fullscreen/Decoration/Reparenting Mode Changes
- setSizeImpl/setPositionImpl/reparent -> reconfigureWindowImpl - setVisible(boolean) is state checked (500ms) for better reliability on resource creation. Guarantees valid surface. - reparentWindow: start pos of child -> top is current position on screen - reparentWindow: Recheck success (setVisible), if failed fall back to recreate, which gets rid of a lost child windows (1/20) .. - reparentWindow: if size failed, reconfigure for size again - add toggle decoration - unify nfs_ size/pos state - WindowsWindow.c/X11Window.c: Unify size/pos settings - X11Window.c: - NewtWindows_setFullscreen: use 'root of screen' instead of 'default root of display' - Adding SubstructureNotifyMask incl event semantics - Parse ReparentNotify (debugging of reparenting) Misc: - Add native getLocationOnScreen() impl to avoid possible AWT deadlock - setSize/setPosition/setFullScreen -> EDT - More documentation on expected native implementation semantics
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java22
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/WindowImpl.java574
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java52
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java50
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java55
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java39
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java47
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java70
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java74
-rw-r--r--src/newt/native/KDWindow.c11
-rw-r--r--src/newt/native/NewtMacWindow.m23
-rw-r--r--src/newt/native/WindowsWindow.c379
-rw-r--r--src/newt/native/X11Window.c507
14 files changed, 1146 insertions, 760 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 4bdcd67a4..7e1a55b21 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -48,6 +48,9 @@ public interface Window extends NativeWindow {
public static final boolean DEBUG_WINDOW_EVENT = Debug.debug("Window.WindowEvent");
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
+ /** A 500ms timeout while waiting for a native action response, ie {@link #setVisible(boolean)}. */
+ public static final long TIMEOUT_NATIVEWINDOW = 500;
+
//
// Lifecycle
//
diff --git a/src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java b/src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java
index 95c326ce4..f3c7b8415 100644
--- a/src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java
+++ b/src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java
@@ -86,7 +86,9 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
return surfaceHandle;
}
- protected void setVisibleImpl(boolean visible) {
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ sizeChanged(width, height, false);
+ visibleChanged(visible);
}
protected void requestFocusImpl(boolean reparented) {
@@ -94,27 +96,19 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
public void setSize(int width, int height) {
if(!visible) {
- this.width = width;
- this.height = height;
+ sizeChanged(width, height, false);
}
}
- protected void setSizeImpl(int width, int height) {
- shouldNotCallThis();
- }
-
public void setPosition(int x, int y) {
// nop
}
- protected void setPositionImpl(int x, int y) {
- shouldNotCallThis();
- }
-
public boolean setFullscreen(boolean fullscreen) {
// nop
return false;
}
- protected void reconfigureWindowImpl(int x, int y, int width, int height) {
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) {
shouldNotCallThis();
+ return false;
}
public Point getLocationOnScreen(Point storage) {
@@ -125,5 +119,9 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
}
return new Point(0,0);
}
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
+ }
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
index a0879a634..631c1b1c0 100644
--- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
+++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
@@ -171,12 +171,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
protected Capabilities caps;
protected boolean fullscreen, visible, hasFocus;
protected int width, height, x, y;
-
- // non fullscreen dimensions ..
- protected int nfs_width, nfs_height, nfs_x, nfs_y;
+ protected int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen dimensions ..
protected String title = "Newt Window";
protected boolean undecorated = false;
+ private boolean handleDestroyNotify = true;
private final void destroyScreen() {
screenReferenced = false;
@@ -194,9 +193,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
private boolean createNative() {
- if( null==screen || 0!=windowHandle || !visible ) {
- return 0 != windowHandle ;
- }
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.createNative() START ("+getThreadName()+", "+this+")");
}
@@ -211,7 +207,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
screen.addReference();
}
createNativeImpl();
- setVisibleImpl(true);
+ setVisibleImpl(true, x, y, width, height);
}
} finally {
if(null!=parentWindow) {
@@ -271,22 +267,68 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// Window: Native implementation
//
+ /**
+ * The native implementation must set the native windowHandle.<br>
+ *
+ * The implementation should invoke the referenced java state callbacks
+ * to notify this Java object of state changes.
+ *
+ * @see #windowDestroyNotify()
+ * @see #focusChanged(boolean)
+ * @see #visibleChanged(boolean)
+ * @see #sizeChanged(int,int)
+ * @see #positionChanged(int,int)
+ * @see #windowDestroyNotify()
+ */
protected abstract void createNativeImpl();
protected abstract void closeNativeImpl();
- protected abstract void requestFocusImpl(boolean reparented);
-
- protected abstract void setVisibleImpl(boolean visible);
-
- protected abstract void setSizeImpl(int width, int height);
+ /**
+ * The native implementation must invoke {@link #focusChanged(boolean)}
+ * to change the focus state, if <code>force == false</code>.
+ * This may happen asynchronous within {@link #TIMEOUT_NATIVEWINDOW}.
+ *
+ * @param force if true, bypass {@link #focusChanged(boolean)} and force focus request
+ */
+ protected abstract void requestFocusImpl(boolean force);
- protected abstract void setPositionImpl(int x, int y);
+ /**
+ * 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);
- protected abstract void reconfigureWindowImpl(int x, int y, int width, int height);
+ /**
+ * 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 -1 if no size change requested, otherwise greater than zero
+ * @param height -1 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
+ *
+ * @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 void setTitleImpl(String title) {}
+ /**
+ * Return screen coordinates of the given coordinates
+ * or null, in which case a NativeWindow traversal shall being used
+ * as demonstrated in {@link #getLocationOnScreen(javax.media.nativewindow.util.Point)}.
+ *
+ * @return if not null, the screen location of the given coordinates
+ */
+ protected abstract Point getLocationOnScreenImpl(int x, int y);
+
//----------------------------------------------------------------------
// NativeSurface
//
@@ -371,12 +413,31 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public Point getLocationOnScreen(Point storage) {
+ if(isNativeValid()) {
+ Point d;
+ windowLock.lock();
+ try {
+ d = getLocationOnScreenImpl(0, 0);
+ } finally {
+ windowLock.unlock();
+ }
+ if(null!=d) {
+ if(null!=storage) {
+ storage.translate(d.getX(),d.getY());
+ return storage;
+ }
+ return d;
+ }
+ // fall through intended ..
+ }
+
if(null!=storage) {
storage.translate(getX(),getY());
} else {
storage = new Point(getX(),getY());
}
if(null!=parentWindow) {
+ // traverse through parent list ..
parentWindow.getLocationOnScreen(storage);
}
return storage;
@@ -398,27 +459,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return screen;
}
- public void setVisible(boolean visible) {
- if(isValid()) {
- if( 0==windowHandle && visible && 0>=width*height ) {
- // fast-path: not realized yet, make visible, but zero size
- return;
- }
- VisibleAction va = new VisibleAction(visible);
- runOnEDTIfAvail(true, va);
- if( va.getChanged() ) {
- sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
- }
-
- }
- }
-
class VisibleAction implements Runnable {
boolean visible;
boolean nativeWindowCreated;
boolean madeVisible;
- public VisibleAction(boolean visible) {
+ public VisibleAction (boolean visible) {
this.visible = visible;
this.nativeWindowCreated = false;
this.madeVisible = false;
@@ -446,14 +492,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
if(0==windowHandle && visible) {
- WindowImpl.this.visible = visible;
if( 0<width*height ) {
nativeWindowCreated = createNative();
+ WindowImpl.this.waitForVisible(visible, true);
+ madeVisible = visible;
}
} else if(WindowImpl.this.visible != visible) {
- WindowImpl.this.visible = visible;
if(0 != windowHandle) {
- setVisibleImpl(visible);
+ setVisibleImpl(visible, x, y, width, height);
+ WindowImpl.this.waitForVisible(visible, true);
madeVisible = visible;
}
}
@@ -481,58 +528,78 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- public void setSize(int width, int height) {
- int visibleAction = 0; // 1 invisible, 2 visible
- windowLock.lock();
- try{
- if ( !fullscreen && ( width != this.width || this.height != height ) ) {
- if(DEBUG_IMPLEMENTATION) {
- String msg = new String("Window setSize: START "+this.width+"x"+this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
- System.err.println(msg);
- }
- nfs_width=width;
- nfs_height=height;
- if ( 0 != windowHandle && 0>=width*height && visible ) {
- visibleAction=1; // invisible
- this.width = 0;
- this.height = 0;
- } else if ( 0 == windowHandle && 0<width*height && visible ) {
- visibleAction = 2; // visible
- this.width = width;
- this.height = height;
- } else if ( 0 != windowHandle ) {
- // this width/height will be set by windowChanged, called by the native implementation
- setSizeImpl(width, height);
- } else {
- this.width = width;
- this.height = height;
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setSize: END "+this.width+"x"+this.height+", visibleAction "+visibleAction);
- }
+ public void setVisible(boolean visible) {
+ if(isValid()) {
+ if( 0==windowHandle && visible && 0>=width*height ) {
+ // fast-path: not realized yet, make visible, but zero size
+ return;
}
- } finally {
- windowLock.unlock();
+ VisibleAction visibleAction = new VisibleAction(visible);
+ runOnEDTIfAvail(true, visibleAction);
+ if( visibleAction.getChanged() ) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ }
+ }
+
+ class SetSizeActionImpl implements Runnable {
+ int visibleAction = 0; // 1 invisible, 2 visible (create)
+ int width, height;
+
+ public int getVisibleAction() {
+ return visibleAction;
}
- if(visibleAction>0) {
- setVisible( ( 1 == visibleAction ) ? false : true );
+ public SetSizeActionImpl(int w, int h) {
+ width = w;
+ height = h;
+ }
+ public void run() {
+ windowLock.lock();
+ try {
+ if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) {
+ if(DEBUG_IMPLEMENTATION) {
+ String msg = new String("Window setSize: START "+WindowImpl.this.width+"x"+WindowImpl.this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
+ System.err.println(msg);
+ }
+ if ( 0 != windowHandle && 0>=width*height && visible ) {
+ visibleAction=1; // invisible
+ WindowImpl.this.width = 0;
+ WindowImpl.this.height = 0;
+ } else if ( 0 == windowHandle && 0<width*height && visible ) {
+ visibleAction = 2; // visible (create)
+ WindowImpl.this.width = width;
+ 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);
+ } else {
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setSize: END "+WindowImpl.this.width+"x"+WindowImpl.this.height+", visibleAction "+visibleAction);
+ }
+ }
+ } finally {
+ windowLock.unlock();
+ }
}
}
- public void destroy(boolean unrecoverable) {
- if( isValid() ) {
- if(DEBUG_IMPLEMENTATION) {
- String msg = new String("Window.destroy(unrecoverable: "+unrecoverable+") START "+getThreadName()/*+", "+this*/);
- System.err.println(msg);
- //Exception ee = new Exception(msg);
- //ee.printStackTrace();
+ public void setSize(int width, int height) {
+ if(isValid()) {
+ SetSizeActionImpl setSizeAction = new SetSizeActionImpl(width, height);
+ runOnEDTIfAvail(true, setSizeAction);
+ switch(setSizeAction.getVisibleAction()) {
+ case 1: setVisible(false); break;
+ case 2: setVisible(true); break;
}
- runOnEDTIfAvail(true, new DestroyAction(unrecoverable));
}
}
class DestroyAction implements Runnable {
boolean unrecoverable;
+
public DestroyAction(boolean unrecoverable) {
this.unrecoverable = unrecoverable;
}
@@ -592,6 +659,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ public void destroy(boolean unrecoverable) {
+ if( isValid() ) {
+ if(DEBUG_IMPLEMENTATION) {
+ String msg = new String("Window.destroy(unrecoverable: "+unrecoverable+") START "+getThreadName()/*+", "+this*/);
+ System.err.println(msg);
+ //Exception ee = new Exception(msg);
+ //ee.printStackTrace();
+ }
+ DestroyAction destroyAction = new DestroyAction(unrecoverable);
+ runOnEDTIfAvail(true, destroyAction);
+ }
+ }
+
/**
* <p>
* render all native window information invalid,
@@ -618,7 +698,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
*/
protected void invalidate(boolean unrecoverable) {
windowLock.lock();
- try{
+ try {
if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
String msg = new String("!!! Window Invalidate(unrecoverable: "+unrecoverable+") "+getThreadName());
System.err.println(msg);
@@ -667,6 +747,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
boolean wasVisible;
boolean displayChanged = false;
+ // mirror pos/size so native change notification can get overwritten
+ int x = WindowImpl.this.x;
+ int y = WindowImpl.this.y;
+ int width = WindowImpl.this.width;
+ int height = WindowImpl.this.height;
+
windowLock.lock();
try {
wasVisible = isVisible();
@@ -679,10 +765,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
long newParentWindowHandle = 0 ;
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCode(parentWindow)+", new parentWindow: "+Display.hashCode(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", DEBUG_TEST_REPARENT_INCOMPATIBLE "+DEBUG_TEST_REPARENT_INCOMPATIBLE);
+ System.err.println("Window.reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCode(parentWindow)+", new parentWindow: "+Display.hashCode(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", DEBUG_TEST_REPARENT_INCOMPATIBLE "+DEBUG_TEST_REPARENT_INCOMPATIBLE+" "+x+"/"+y+" "+width+"x"+height);
}
if(null!=newParentWindow) {
+ // reset position to 0/0 within parent space
+ x = 0;
+ y = 0;
+
+ // refit if size is bigger than parent
+ if( width > newParentWindow.getWidth() ) {
+ width = newParentWindow.getWidth();
+ }
+ if( height > newParentWindow.getHeight() ) {
+ height = newParentWindow.getHeight();
+ }
+
// Case: Child Window
newParentWindowHandle = getNativeWindowHandle(newParentWindow);
if(0 == newParentWindowHandle) {
@@ -740,6 +838,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
reparentAction = ACTION_UNCHANGED;
}
} else {
+ if( null != parentWindow ) {
+ // child -> top
+ // put client to current parent+child position
+ Point p = getLocationOnScreen(null);
+ x = p.getX();
+ y = p.getY();
+ }
+
// Case: Top Window
if( 0 == getParentWindowHandle() ) {
// Already Top Window
@@ -789,45 +895,59 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
if( ACTION_NATIVE_REPARENTING == reparentAction ) {
- if(0!=parentWindowHandle) {
- // reset position to 0/0 within parent space
- // FIXME .. cache position ?
- x = 0;
- y = 0;
- }
DisplayImpl display = (DisplayImpl) screen.getDisplay();
- display.dispatchMessages(); // status up2date
+ display.dispatchMessagesNative(); // status up2date
if(wasVisible) {
- visible = false;
- setVisibleImpl(false);
- display.dispatchMessages(); // status up2date
+ setVisibleImpl(false, x, y, width, height);
+ WindowImpl.this.waitForVisible(false, true);
}
// Lock parentWindow only during reparenting (attempt)
NativeWindow parentWindowLocked = null;
if( null != parentWindow ) {
parentWindowLocked = parentWindow;
- if(NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindowLocked.lockSurface() ) {
+ if( NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindowLocked.lockSurface() ) {
throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
}
}
boolean ok = false;
try {
- ok = reparentWindowImpl();
+ // write back mirrored values, to be able to detect satisfaction
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ ok = reconfigureWindowImpl(x, y, width, height, true, 0, isUndecorated()?-1:1);
} finally {
if(null!=parentWindowLocked) {
parentWindowLocked.unlockSurface();
}
}
+ // set visible again, and revalidate 'ok',
+ // since it has been experience that in some cases the reparented window gets hidden
+ 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( 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
+ }
+ }
+ }
+
if(ok) {
- display.dispatchMessages(); // status up2date
if(wasVisible) {
- visible = true;
- setVisibleImpl(true);
- display.dispatchMessages(); // status up2date
requestFocusImpl(true);
- display.dispatchMessages(); // status up2date
+ display.dispatchMessagesNative(); // status up2date
}
} else {
// native reparent failed -> try creation
@@ -839,15 +959,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ // write back mirrored values, ensuring persitence
+ // and not relying on native messaging
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCode(parentWindow));
+ System.err.println("Window.reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCode(parentWindow)+" "+x+"/"+y+" "+width+"x"+height);
}
} finally {
windowLock.unlock();
}
if( ACTION_NATIVE_CREATION == reparentAction && wasVisible ) {
- // This may run on the the Display/Screen connection,
+ // This may run on the Display/Screen connection,
// hence a new EDT task
runOnEDTIfAvail(true, reparentActionRecreate);
}
@@ -884,24 +1011,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
runOnEDTIfAvail(true, reparentAction);
reparentActionStrategy = reparentAction.getStrategy();
- boolean sizeSignaled=false;
- if(null!=newParent) {
- // refit if size is bigger than parent
- int w = getWidth();
- int h = getHeight();
- if(w>newParent.getWidth()) {
- w=newParent.getWidth();
- sizeSignaled=true;
- }
- if(h>newParent.getHeight()) {
- h=newParent.getHeight();
- sizeSignaled=true;
- }
- if(sizeSignaled) {
- setSize(w, h);
- }
- }
- if( !sizeSignaled && isVisible() ) {
+ if( isVisible() ) {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
} finally {
@@ -935,22 +1045,70 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- public void setUndecorated(boolean value) {
- if(!fullscreen && this.undecorated != value) {
- undecorated = value;
- if( 0 != windowHandle ) {
- reconfigureWindowImpl(x, y, width, height);
- requestFocus();
+ class DecorationActionImpl implements Runnable {
+ boolean undecorated;
+
+ public DecorationActionImpl(boolean undecorated) {
+ this.undecorated = undecorated;
+ }
+
+ public void run() {
+ windowLock.lock();
+ try {
+ if(!fullscreen && isNativeValid() && WindowImpl.this.undecorated != undecorated) {
+ WindowImpl.this.undecorated = undecorated;
+ // mirror pos/size so native change notification can get overwritten
+ int x = WindowImpl.this.x;
+ int y = WindowImpl.this.y;
+ int width = WindowImpl.this.width;
+ int height = WindowImpl.this.height;
+
+ 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
+ }
+ }
+ }
+ } finally {
+ windowLock.unlock();
}
}
}
+ public void setUndecorated(boolean value) {
+ if(isValid()) {
+ DecorationActionImpl decorationAction = new DecorationActionImpl(value);
+ runOnEDTIfAvail(true, decorationAction);
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ }
+
public boolean isUndecorated() {
return 0 != parentWindowHandle || undecorated || fullscreen ;
}
public void requestFocus() {
- // enqueueRequestFocus(false); // FIXME: or shall we wait ?
enqueueRequestFocus(true);
}
@@ -1083,12 +1241,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
class RequestFocusAction implements Runnable {
public void run() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.RequestFocusAction: ("+getThreadName()+"): "+hasFocus+" -> true - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
WindowImpl.this.requestFocusImpl(false);
}
}
RequestFocusAction requestFocusAction = new RequestFocusAction();
- public void enqueueRequestFocus(boolean wait) {
+ protected void enqueueRequestFocus(boolean wait) {
runOnEDTIfAvail(wait, requestFocusAction);
}
@@ -1117,67 +1278,100 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
protected FocusRunnable focusAction = null;
- private boolean handleDestroyNotify = true;
+ class SetPositionActionImpl implements Runnable {
+ int x, y;
- public void setPosition(int x, int y) {
- windowLock.lock();
- try{
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setPosition: "+this.x+"/"+this.y+" -> "+x+"/"+y+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle));
- }
- if ( this.x != x || this.y != y ) {
- if(!fullscreen) {
- nfs_x=x;
- nfs_y=y;
- if(0!=windowHandle) {
- // this x/y will be set by windowChanged, called by X11
- setPositionImpl(x, y);
- } else {
- this.x = x;
- this.y = y;
+ public SetPositionActionImpl(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+ public void run() {
+ windowLock.lock();
+ try {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setPosition: "+WindowImpl.this.x+"/"+WindowImpl.this.y+" -> "+x+"/"+y+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle));
+ }
+ if ( WindowImpl.this.x != x || WindowImpl.this.y != y ) {
+ if(!fullscreen) {
+ if(0!=windowHandle) {
+ // this.x/this.y will be set by windowChanged, called by the native implementation
+ reconfigureWindowImpl(x, y, -1, -1, false, 0, 0);
+ } else {
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ }
}
}
+ } finally {
+ windowLock.unlock();
}
- } finally {
- windowLock.unlock();
}
}
- public boolean setFullscreen(boolean fullscreen) {
- boolean action = false;
- windowLock.lock();
- try{
- if(0!=windowHandle && this.fullscreen!=fullscreen) {
- int x,y,w,h;
- if(fullscreen) {
- x = 0; y = 0;
- w = screen.getWidth();
- h = screen.getHeight();
- } else {
- if(0!=parentWindowHandle) {
- x=0;
- y=0;
+ public void setPosition(int x, int y) {
+ if(isValid()) {
+ SetPositionActionImpl setPositionAction = new SetPositionActionImpl(x, y);
+ runOnEDTIfAvail(true, setPositionAction);
+ }
+ }
+
+ class FullScreenActionImpl implements Runnable {
+ boolean fullscreen;
+
+ public FullScreenActionImpl (boolean fullscreen) {
+ this.fullscreen = fullscreen;
+ }
+
+ public void run() {
+ windowLock.lock();
+ try {
+ if(isNativeValid() && WindowImpl.this.fullscreen != fullscreen) {
+ int x,y,w,h;
+ WindowImpl.this.fullscreen = fullscreen;
+ if(fullscreen) {
+ 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;
+ w = nfs_width;
+ h = nfs_height;
+ }
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen);
+ }
+
+ 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, w, h, getParentWindowHandle()!=0, fullscreen?1:-1, isUndecorated()?-1:1);
+ display.dispatchMessagesNative(); // status up2date
+ if(wasVisible) {
+ setVisibleImpl(true, x, y, width, height);
+ WindowImpl.this.waitForVisible(true, true);
+ display.dispatchMessagesNative(); // status up2date
+ requestFocusImpl(true);
+ display.dispatchMessagesNative(); // status up2date
}
- w = nfs_width;
- h = nfs_height;
- }
- if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
- System.err.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen);
}
- this.fullscreen = fullscreen;
- reconfigureWindowImpl(x, y, w, h);
- action = true;
+ } finally {
+ windowLock.unlock();
}
- } finally {
- windowLock.unlock();
}
- if(action) {
- requestFocus();
- }
- if( isVisible() ) {
+ }
+
+ public boolean setFullscreen(boolean fullscreen) {
+ if(isValid()) {
+ FullScreenActionImpl fullScreenAction = new FullScreenActionImpl(fullscreen);
+ runOnEDTIfAvail(true, fullScreenAction);
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
return this.fullscreen;
@@ -1654,7 +1848,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
*/
protected void focusChanged(boolean focusGained) {
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.focusChanged: ("+getThreadName()+"): "+focusGained+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ System.err.println("Window.focusChanged: ("+getThreadName()+"): "+this.hasFocus+" -> "+focusGained+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
}
hasFocus = focusGained;
if (focusGained) {
@@ -1667,23 +1861,36 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
protected void visibleChanged(boolean visible) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.visibleChanged ("+getThreadName()+"): "+this.visible+" -> "+visible+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
- // Exception e = new Exception("Window.visibleChanged ("+getThreadName()+"): "+this.visible+" -> "+visible+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
- // e.printStackTrace();
}
this.visible = visible ;
}
- protected void sizeChanged(int newWidth, int newHeight) {
- if(width != newWidth || height != newHeight) {
+ private boolean waitForVisible(boolean visible, boolean failFast) {
+ DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ for(long sleep = TIMEOUT_NATIVEWINDOW; 0<sleep && this.visible != visible; sleep-=10 ) {
+ display.dispatchMessagesNative(); // status up2date
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ie) {}
+ sleep -=10;
+ }
+ if(this.visible != visible) {
+ if(failFast) {
+ throw new NativeWindowException("Visibility not reached as requested within "+TIMEOUT_NATIVEWINDOW+"ms : requested "+visible+", is "+this.visible);
+ } else if (DEBUG_IMPLEMENTATION) {
+ System.err.println("******* Visibility not reached as requested within "+TIMEOUT_NATIVEWINDOW+"ms : requested "+visible+", is "+this.visible);
+ }
+ }
+ return this.visible == visible;
+ }
+
+ protected void sizeChanged(int newWidth, int newHeight, boolean force) {
+ if(force || width != newWidth || height != newHeight) {
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.sizeChanged: ("+getThreadName()+"): "+width+"x"+height+" -> "+newWidth+"x"+newHeight+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ System.err.println("Window.sizeChanged: ("+getThreadName()+"): force "+force+", "+width+"x"+height+" -> "+newWidth+"x"+newHeight+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
}
width = newWidth;
height = newHeight;
- if(!fullscreen) {
- nfs_width=width;
- nfs_height=height;
- }
if(isNativeValid()) {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
}
@@ -1697,10 +1904,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
x = newX;
y = newY;
- if(!fullscreen) {
- nfs_x=x;
- nfs_y=y;
- }
sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED);
}
}
@@ -1731,6 +1934,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public void windowRepaint(int x, int y, int width, int height) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.windowRepaint "+getThreadName()+" - "+x+"/"+y+" "+width+"x"+height);
+ // Exception ee = new Exception("Window.windowRepaint: "+" - "+x+"/"+y+" "+width+"x"+height);
+ // ee.printStackTrace();
}
if(0>width) {
width=this.width;
@@ -1746,11 +1951,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- protected boolean reparentWindowImpl() {
- // default implementation, no native reparenting support
- return false;
- }
-
protected int getWindowLockRecursionCount() {
return windowLock.getRecursionCount();
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java
index 5abff047f..edd851451 100644
--- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java
+++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java
@@ -46,6 +46,7 @@ import com.jogamp.newt.impl.WindowImpl;
import java.awt.Insets;
import javax.media.nativewindow.*;
import javax.media.nativewindow.awt.*;
+import javax.media.nativewindow.util.Point;
/** An implementation of the Newt Window class built using the
AWT. This is provided for convenience of porting to platforms
@@ -74,8 +75,6 @@ public class AWTWindow extends WindowImpl {
private Container container = null;
private Frame frame = null; // same instance as container, just for impl. convenience
private AWTCanvas canvas;
- // non fullscreen dimensions ..
- private int nfs_width, nfs_height, nfs_x, nfs_y;
protected void requestFocusImpl(boolean reparented) {
runOnEDT(true, new Runnable() {
@@ -176,13 +175,14 @@ public class AWTWindow extends WindowImpl {
return res;
}
- protected void setVisibleImpl(final boolean visible) {
+ protected void setVisibleImpl(final boolean visible, int x, int y, int width, int height) {
runOnEDT(true, new Runnable() {
public void run() {
container.setVisible(visible);
}
});
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
config = canvas.getAWTGraphicsConfiguration();
if (config == null) {
@@ -190,6 +190,7 @@ public class AWTWindow extends WindowImpl {
}
updateDeviceData();
+ visibleChanged(visible);
}
private void updateDeviceData() {
@@ -203,19 +204,6 @@ public class AWTWindow extends WindowImpl {
((AWTScreen)getScreen()).setScreenSize(w, h);
}
- protected void setSizeImpl(final int width, final int height) {
- if(null!=container) {
- /** An AWT event on setSize() would bring us in a deadlock situation, hence invokeLater() */
- runOnEDT(false, new Runnable() {
- public void run() {
- Insets insets = container.getInsets();
- container.setSize(width + insets.left + insets.right,
- height + insets.top + insets.bottom);
- }
- });
- }
- }
-
public javax.media.nativewindow.util.Insets getInsets() {
final int insets[] = new int[] { 0, 0, 0, 0 };
runOnEDT(true, new Runnable() {
@@ -230,21 +218,11 @@ public class AWTWindow extends WindowImpl {
return new javax.media.nativewindow.util.Insets(insets[0],insets[1],insets[2],insets[3]);
}
- protected void setPositionImpl(final int x, final int y) {
- if(null!=container) {
- runOnEDT(true, new Runnable() {
- public void run() {
- container.setLocation(x, y);
- }
- });
- }
- }
-
- protected void reconfigureWindowImpl(final int x, final int y, final int width, final int height) {
+ protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final boolean parentChange, final int fullScreenChange, final int decorationChange) {
/** An AWT event on setSize() would bring us in a deadlock situation, hence invokeLater() */
runOnEDT(false, new Runnable() {
public void run() {
- if(null!=frame) {
+ if(decorationChange!=0 && null!=frame) {
if(!container.isDisplayable()) {
frame.setUndecorated(isUndecorated());
} else {
@@ -253,12 +231,26 @@ public class AWTWindow extends WindowImpl {
}
}
}
- container.setLocation(x, y);
- container.setSize(width, height);
+ 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;
+
+ container.setLocation(_x, _y);
+ Insets insets = container.getInsets();
+ container.setSize(_w + insets.left + insets.right,
+ _h + insets.top + insets.bottom);
}
});
+ return true;
}
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ java.awt.Point ap = canvas.getLocationOnScreen();
+ ap.translate(x, y);
+ return new Point((int)(ap.getX()+0.5),(int)(ap.getY()+0.5));
+ }
+
public Object getWrappedWindow() {
return canvas;
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java
index 040fa15a9..749be8506 100644
--- a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java
+++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java
@@ -34,6 +34,7 @@
package com.jogamp.newt.impl.intel.gdl;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Point;
public class Window extends com.jogamp.newt.impl.WindowImpl {
static {
@@ -77,42 +78,40 @@ public class Window extends com.jogamp.newt.impl.WindowImpl {
}
}
- protected void setVisibleImpl(boolean visible) {
+ 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 void setSizeImpl(int width, int height) {
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) {
Screen screen = (Screen) getScreen();
- if((x+width)>screen.getWidth()) {
- width=screen.getWidth()-x;
- }
- if((y+height)>screen.getHeight()) {
- height=screen.getHeight()-y;
- }
- if(0!=surfaceHandle) {
- SetBounds0(surfaceHandle, screen.getWidth(), screen.getHeight(), x, y, width, height);
- }
- }
- protected void setPositionImpl(int x, int y) {
- Screen screen = (Screen) getScreen();
- if((x+width)>screen.getWidth()) {
- x=screen.getWidth()-width;
+ 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(_w>screen.getWidth()) {
+ _w=screen.getWidth();
}
- if((y+height)>screen.getHeight()) {
- y=screen.getHeight()-height;
+ if(_h>screen.getHeight()) {
+ _h=screen.getHeight();
}
- if(0!=surfaceHandle) {
- SetBounds0(surfaceHandle, screen.getWidth(), screen.getHeight(), x, y, width, height);
+ if((_x+_w)>screen.getWidth()) {
+ _x=screen.getWidth()-_w;
+ }
+ if((_y+_h)>screen.getHeight()) {
+ _y=screen.getHeight()-_h;
}
- }
- protected void reconfigureWindowImpl(int x, int y, int width, int height) {
if(0!=surfaceHandle) {
- SetBounds0(surfaceHandle, getScreen().getWidth(), getScreen().getHeight(), x, y, width, height);
+ SetBounds0(surfaceHandle, getScreen().getWidth(), getScreen().getHeight(), _x, _y, _w, _h);
}
+
+ return true;
}
protected void requestFocusImpl(boolean reparented) {
@@ -123,6 +122,10 @@ public class Window extends com.jogamp.newt.impl.WindowImpl {
return surfaceHandle;
}
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
+ }
+
//----------------------------------------------------------------------
// Internals only
//
@@ -140,5 +143,4 @@ public class Window extends com.jogamp.newt.impl.WindowImpl {
}
private long surfaceHandle;
- private int nfs_width, nfs_height, nfs_x, nfs_y;
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java
index 15cadb05f..59b41c2aa 100644
--- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java
+++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java
@@ -40,6 +40,7 @@ import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.newt.event.*;
import com.jogamp.newt.impl.*;
import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.Point;
public class MacWindow extends WindowImpl {
@@ -194,11 +195,11 @@ public class MacWindow extends WindowImpl {
nsViewLock.unlock();
}
- protected void setVisibleImpl(final boolean visible) {
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
nsViewLock.lock();
try {
if (visible) {
- createWindow(false, getX(), getY(), getWidth(), getHeight(), isFullscreen());
+ createWindow(false, x, y, width, height, isFullscreen());
if (getWindowHandle() != 0) {
makeKeyAndOrderFront0(getWindowHandle());
}
@@ -207,6 +208,7 @@ public class MacWindow extends WindowImpl {
orderOut0(getWindowHandle());
}
}
+ visibleChanged(visible);
} finally {
nsViewLock.unlock();
}
@@ -232,39 +234,38 @@ public class MacWindow extends WindowImpl {
}
}
- protected void setSizeImpl(int width, int height) {
- // this width/height will be set by sizeChanged, called by OSX
- nsViewLock.lock();
- try {
- setContentSize0(getWindowHandle(), width, height);
- } finally {
- nsViewLock.unlock();
- }
- }
-
- protected void setPositionImpl(int x, int y) {
- // this x/y will be set by positionChanged, called by OSX
- nsViewLock.lock();
- try {
- setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), x, y);
- } finally {
- nsViewLock.unlock();
- }
- }
-
- protected void reconfigureWindowImpl(int x, int y, int width, int height) {
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) {
nsViewLock.lock();
try {
if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
- System.err.println("MacWindow reconfig: "+fullscreen+" "+x+"/"+y+" "+width+"x"+height);
+ System.err.println("MacWindow reconfig: parentChange "+parentChange+", fullScreenChange "+fullScreenChange+", decorationChange "+decorationChange+" "+x+"/"+y+" "+width+"x"+height);
}
- createWindow(true, x, y, width, height, fullscreen);
- if (getWindowHandle() != 0) {
- makeKeyAndOrderFront0(getWindowHandle());
+ 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(width>0 || height>0) {
+ setContentSize0(getWindowHandle(), _w, _h);
+ }
}
} finally {
nsViewLock.unlock();
}
+ return true;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return null;
}
private void insetsChanged(int left, int top, int right, int bottom) {
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java
index 9f5e7b7c1..ad903731b 100644
--- a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java
@@ -37,6 +37,7 @@ import com.jogamp.opengl.impl.egl.*;
import javax.media.nativewindow.*;
import javax.media.opengl.GLCapabilities;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.Point;
public class Window extends com.jogamp.newt.impl.WindowImpl {
static {
@@ -70,7 +71,10 @@ public class Window extends com.jogamp.newt.impl.WindowImpl {
}
}
- protected void setVisibleImpl(boolean visible) { }
+ 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) { }
@@ -84,16 +88,37 @@ public class Window extends com.jogamp.newt.impl.WindowImpl {
}
}
- protected void setPositionImpl(int x, int y) {
- // n/a in BroadcomEGL
- System.err.println("BCEGL Window.setPositionImpl n/a in BroadcomEGL");
+ 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 ) {
+ // n/a in BroadcomEGL
+ System.err.println("setFullscreen n/a in BroadcomEGL");
+ return false;
+ }
+ }
+ }
+ if(width>0 || height>0) {
+ if(0!=getWindowHandle()) {
+ // n/a in BroadcomEGL
+ System.err.println("BCEGL Window.setSizeImpl n/a in BroadcomEGL with realized window");
+ } else {
+ this.width=(width>0)?width:this.width;
+ this.height=(height>0)?height:this.height;
+ }
+ }
+ if(x>=0 || y>=0) {
+ System.err.println("BCEGL Window.setPositionImpl n/a in BroadcomEGL");
+ }
+ return true;
}
- protected void reconfigureWindowImpl(int x, int y, int width, int height) {
- // n/a in BroadcomEGL
- System.err.println("setFullscreen n/a in BroadcomEGL");
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
}
+
public boolean surfaceSwap() {
SwapWindow(getDisplayHandle(), getWindowHandle());
return true;
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java
index 6930741b8..f0bc8587b 100644
--- a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java
@@ -41,11 +41,10 @@ import javax.media.nativewindow.*;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.Point;
public class KDWindow extends WindowImpl {
private static final String WINDOW_CLASS_NAME = "NewtWindow";
- // non fullscreen dimensions ..
- private int nfs_width, nfs_height, nfs_x, nfs_y;
static {
KDDisplay.initSingleton();
@@ -85,30 +84,40 @@ public class KDWindow extends WindowImpl {
}
}
- protected void setVisibleImpl(boolean visible) {
+ 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 void setSizeImpl(int width, int height) {
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange) {
if(0!=eglWindowHandle) {
- setSize0(eglWindowHandle, width, height);
+ if(0!=fullScreenChange) {
+ boolean fs = fullScreenChange > 0;
+ setFullScreen0(eglWindowHandle, fs);
+ if(fs) {
+ return true;
+ }
+ }
+ // 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(width>0 || height>0) {
+ setSize0(eglWindowHandle, _w, _h);
+ }
+ if(x>=0 || y>=0) {
+ System.err.println("setPosition n/a in KD");
+ }
}
+ return true;
}
- protected void setPositionImpl(int x, int y) {
- // n/a in KD
- System.err.println("setPosition n/a in KD");
- }
-
- protected void reconfigureWindowImpl(int x, int y, int width, int height) {
- if(0!=eglWindowHandle) {
- setFullScreen0(eglWindowHandle, fullscreen);
- if(!fullscreen) {
- setSize0(eglWindowHandle, width, height);
- }
- }
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
}
//----------------------------------------------------------------------
@@ -127,11 +136,11 @@ public class KDWindow extends WindowImpl {
windowUserData=userData;
}
- protected void sizeChanged(int newWidth, int newHeight) {
+ protected void sizeChanged(int newWidth, int newHeight, boolean force) {
if(fullscreen) {
((KDScreen)getScreen()).setScreenSize(width, height);
}
- super.sizeChanged(newWidth, newHeight);
+ super.sizeChanged(newWidth, newHeight, force);
}
private long eglWindowHandle;
diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java
index 3ade599da..daa09b034 100644
--- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java
+++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java
@@ -37,6 +37,7 @@ package com.jogamp.newt.impl.windows;
import javax.media.nativewindow.*;
import com.jogamp.newt.impl.WindowImpl;
import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.Point;
public class WindowsWindow extends WindowImpl {
@@ -142,31 +143,20 @@ public class WindowsWindow extends WindowImpl {
super.windowDestroyed();
}
- protected void setVisibleImpl(boolean visible) {
- setVisible0(getWindowHandle(), visible);
+ 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 void setSizeImpl(int width, int height) {
- // this width/height will be set by sizeChanged, called by Windows
- setSize0(getParentWindowHandle(), getWindowHandle(), x, y, width, height);
- }
-
- protected void setPositionImpl(int x, int y) {
- // this x/y will be set by positionChanged, called by Windows
- setPosition0(getParentWindowHandle(), getWindowHandle(), x , y /*, width, height*/);
- }
-
- protected void reconfigureWindowImpl(int x, int y, int width, int height) {
- reconfigureWindow0(fullscreen?0:getParentWindowHandle(), getWindowHandle(), x, y, width, height, isUndecorated());
- }
-
- protected boolean reparentWindowImpl() {
- reparentWindow0(fullscreen?0:getParentWindowHandle(), getWindowHandle(), x, y, width, height, isUndecorated());
+ 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);
return true;
}
- protected void requestFocusImpl(boolean reparented) {
- requestFocus0(getWindowHandle(), reparented);
+ protected void requestFocusImpl(boolean force) {
+ requestFocus0(getWindowHandle(), force);
}
protected void setTitleImpl(final String title) {
@@ -177,34 +167,42 @@ public class WindowsWindow extends WindowImpl {
return (Insets)insets.clone();
}
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return (Point) getRelativeLocation0( getWindowHandle(), 0 /*root win*/, x, y);
+ }
+
//----------------------------------------------------------------------
// Internals only
//
protected static native boolean initIDs0();
- private native long CreateWindow0(long parentWindowHandle,
+ private native long CreateWindow0(long parentWindowHandle,
int wndClassAtom, String wndName,
long hInstance, long visualID,
boolean isUndecorated,
int x, int y, int width, int height);
- private native void DestroyWindow0(long windowHandle);
- private native long GetDC0(long windowHandle);
- private native void ReleaseDC0(long windowHandle, long hdc);
- private native long MonitorFromWindow0(long windowHandle);
- private static native void setVisible0(long windowHandle, boolean visible);
- private native void setSize0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height);
- private static native void setPosition0(long parentWindowHandle, long windowHandle, 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 isUndecorated);
- private native void reparentWindow0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height, boolean isUndecorated);
+ private native void DestroyWindow0(long windowHandle);
+ private native long GetDC0(long windowHandle);
+ private native void ReleaseDC0(long windowHandle, long hdc);
+ 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 static native void setTitle0(long windowHandle, String title);
- private native void requestFocus0(long windowHandle, boolean reparented);
+ private native void requestFocus0(long windowHandle, boolean force);
+ private native Object getRelativeLocation0(long src_win, long dest_win, int src_x, int src_y);
private void insetsChanged(int left, int top, int right, int bottom) {
if (left != -1 && top != -1 && right != -1 && bottom != -1) {
- insets.left = left;
- insets.top = top;
- insets.right = right;
- insets.bottom = bottom;
+ if (left != insets.left || top != insets.top || right != insets.right || bottom != insets.bottom) {
+ insets.left = left;
+ insets.top = top;
+ insets.right = right;
+ insets.bottom = bottom;
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.insetsChanged: "+insets);
+ }
+ }
}
}
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
index 3b3cd07ae..53b222189 100644
--- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
+++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
@@ -38,6 +38,7 @@ import com.jogamp.newt.event.*;
import com.jogamp.newt.impl.WindowImpl;
import javax.media.nativewindow.*;
import javax.media.nativewindow.x11.*;
+import javax.media.nativewindow.util.Point;
public class X11Window extends WindowImpl {
private static final String WINDOW_CLASS_NAME = "NewtWindow";
@@ -62,10 +63,11 @@ public class X11Window extends WindowImpl {
display.getHandle(), screen.getIndex(), visualID,
display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
x, y, width, height, isUndecorated());
- if (w == 0 || w!=getWindowHandle()) {
+ if (w == 0) {
throw new NativeWindowException("Error creating window: "+w);
}
- windowHandleClose = getWindowHandle();
+ setWindowHandle(w);
+ windowHandleClose = w;
}
protected void closeNativeImpl() {
@@ -90,62 +92,60 @@ public class X11Window extends WindowImpl {
super.windowDestroyed();
}
- protected void setVisibleImpl(boolean visible) {
- setVisible0(getDisplayHandle(), getWindowHandle(), visible);
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ setVisible0(getDisplayHandle(), getWindowHandle(), visible, x, y, width, height);
}
- protected void setSizeImpl(int width, int height) {
- // this width/height will be set by windowChanged, called by X11
- setSize0(getDisplayHandle(), getWindowHandle(), width, height);
- }
-
- protected void setPositionImpl(int x, int y) {
- setPosition0(getParentWindowHandle(), getDisplayHandle(), getWindowHandle(), x, y);
- }
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange) {
+ reparentHandle=0;
+ reparentCount=0;
+ long reqNewParentHandle = ( fullScreenChange > 0 ) ? 0 : getParentWindowHandle() ;
- protected void reconfigureWindowImpl(int x, int y, int width, int height) {
- reconfigureWindow0(fullscreen?0:getParentWindowHandle(), getDisplayHandle(), getScreenIndex(), getWindowHandle(),
- x, y, width, height, isUndecorated(), isVisible(), isFullscreen());
- }
+ reconfigureWindow0( getDisplayHandle(), getScreenIndex(), reqNewParentHandle, getWindowHandle(),
+ x, y, width, height, isVisible(), parentChange, fullScreenChange, decorationChange);
- protected boolean reparentWindowImpl() {
- if(0!=getWindowHandle()) {
- reparentWindow0(fullscreen?0:getParentWindowHandle(), getDisplayHandle(), getScreenIndex(), getWindowHandle(),
- x, y, isUndecorated(), isVisible());
- }
return true;
}
- protected void requestFocusImpl(boolean reparented) {
- requestFocus0(getDisplayHandle(), getWindowHandle(), reparented);
+ protected void requestFocusImpl(boolean force) {
+ requestFocus0(getDisplayHandle(), getWindowHandle(), force);
}
protected void setTitleImpl(String title) {
setTitle0(getDisplayHandle(), getWindowHandle(), title);
}
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return (Point) getRelativeLocation0( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ }
+
//----------------------------------------------------------------------
// Internals only
//
protected static native boolean initIDs0();
- private native long CreateWindow0(long parentWindowHandle, long display, int screen_index,
+ private native long CreateWindow0(long parentWindowHandle, long display, int screen_index,
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);
- private native void setSize0(long display, long windowHandle, int width, int height);
- private native void reconfigureWindow0(long parentWindowHandle, long display, int screen_index, long windowHandle,
- int x, int y, int width, int height, boolean undecorated, boolean isVisible, boolean fullscreen);
- private native void setTitle0(long display, long windowHandle, String title);
- private native void requestFocus0(long display, long windowHandle, boolean reparented);
- private native void setPosition0(long parentWindowHandle, long display, long windowHandle, int x, int y);
- private native void reparentWindow0(long parentWindowHandle, long display, int screen_index, long windowHandle,
- int x, int y, boolean undecorated, boolean isVisible);
-
- private void windowCreated(long windowHandle) {
- setWindowHandle(windowHandle);
+ 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 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;
+ reparentCount++;
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("******** new parent ("+reparentCount+"): " + toHexString(reparentHandle) );
+ }
}
private long windowHandleClose;
+ private volatile long reparentHandle;
+ private volatile int reparentCount;
}
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c
index 75a2fe1a1..b574731c2 100644
--- a/src/newt/native/KDWindow.c
+++ b/src/newt/native/KDWindow.c
@@ -93,6 +93,7 @@ typedef struct {
static jmethodID windowCreatedID = NULL;
static jmethodID sizeChangedID = NULL;
+static jmethodID visibleChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowDestroyedID = NULL;
static jmethodID sendMouseEventID = NULL;
@@ -150,7 +151,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDDisplay_DispatchMes
KDint32 v[2];
if(!kdGetWindowPropertyiv(kdWindow, KD_WINDOWPROPERTY_SIZE, v)) {
DBG_PRINT( "event window size change : src: %p %dx%d\n", userData, v[0], v[1]);
- (*env)->CallVoidMethod(env, javaWindow, sizeChangedID, (jint) v[0], (jint) v[1]);
+ (*env)->CallVoidMethod(env, javaWindow, sizeChangedID, (jint) v[0], (jint) v[1], JNI_FALSE);
} else {
DBG_PRINT( "event window size change error: src: %p %dx%d\n", userData, v[0], v[1]);
}
@@ -164,6 +165,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDDisplay_DispatchMes
KDboolean visible;
kdGetWindowPropertybv(kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visible);
DBG_PRINT( "event window visibility: src: %p, v:%d\n", userData, visible);
+ (*env)->CallVoidMethod(env, javaWindow, visibleChangedID, visible?JNI_TRUE:JNI_FALSE);
}
break;
default:
@@ -209,13 +211,15 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_initIDs
#endif
#endif
windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V");
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
+ sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(IIZ)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
if (windowCreatedID == NULL ||
sizeChangedID == NULL ||
+ visibleChangedID == NULL ||
windowDestroyNotifyID == NULL ||
windowDestroyedID == NULL ||
sendMouseEventID == NULL ||
@@ -309,6 +313,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_setVisible0
KDboolean v = (visible==JNI_TRUE)?KD_TRUE:KD_FALSE;
kdSetWindowPropertybv(w, KD_WINDOWPROPERTY_VISIBILITY, &v);
DBG_PRINT( "[setVisible] v=%d\n", visible);
+ (*env)->CallVoidMethod(env, obj, visibleChangedID, visible); // FIXME: or send via event ?
}
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_setFullScreen0
@@ -332,6 +337,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_setSize0
DBG_PRINT( "[setSize] v=%dx%d, res=%d\n", width, height, res);
(void)res;
- (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height);
+ (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height, JNI_FALSE);
}
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index da31a686e..9f9442e9d 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -100,12 +100,23 @@ jint GetDeltaY(NSEvent *event, jint javaMods) {
}
}
-/** FIXME: Tried child window: message reception ..
- (void)viewWillDraw
{
fprintf(stderr, "*************** viewWillDraw: 0x%p", javaWindowObject); fflush(stderr);
[super viewWillDraw];
-} */
+}
+
+- (void)viewDidHide
+{
+ (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE);
+ [super viewDidHide];
+}
+
+- (void)viewDidUnhide
+{
+ (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_TRUE);
+ [super viewDidUnhide];
+}
@end
@@ -113,6 +124,7 @@ static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
+static jmethodID visibleChangedID = NULL;
static jmethodID positionChangedID = NULL;
static jmethodID focusChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
@@ -124,13 +136,14 @@ static jmethodID windowDestroyedID = NULL;
{
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
+ sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(IIZ)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
- if (sendMouseEventID && sendKeyEventID && sizeChangedID && insetsChangedID &&
+ if (sendMouseEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
positionChangedID && focusChangedID && windowDestroyedID && windowDestroyNotifyID)
{
return YES;
@@ -398,7 +411,7 @@ static jint mods2JavaMods(NSUInteger mods)
(*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID,
(jint) contentRect.size.width,
- (jint) contentRect.size.height);
+ (jint) contentRect.size.height, JNI_FALSE);
}
- (void)windowDidMove: (NSNotification*) notification
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index e1250811c..44f90bc0e 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -109,6 +109,26 @@
#define STD_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+static void _FatalError(JNIEnv *env, const char* msg, ...)
+{
+ char buffer[512];
+ va_list ap;
+
+ va_start(ap, msg);
+ vsnprintf(buffer, sizeof(buffer), msg, ap);
+ va_end(ap);
+
+ fprintf(stderr, "%s\n", buffer);
+ (*env)->FatalError(env, buffer);
+}
+
+static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point";
+static const char * const ClazzAnyCstrName = "<init>";
+static const char * const ClazzNamePointCstrSignature = "(II)V";
+
+static jclass pointClz = NULL;
+static jmethodID pointCstr = NULL;
+
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
static jmethodID positionChangedID = NULL;
@@ -124,7 +144,7 @@ static jmethodID sendKeyEventID = NULL;
static jmethodID focusActionID = NULL;
static jmethodID enqueueRequestFocusID = NULL;
-static RECT* UpdateInsets(JNIEnv *env, HWND hwnd, jobject window);
+static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd);
typedef struct {
JNIEnv* jenv;
@@ -600,18 +620,15 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
return 0;
}
-static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, BOOL reparented) {
+static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, jboolean force) {
HWND pHwnd, current;
pHwnd = GetParent(hwnd);
current = GetFocus();
- DBG_PRINT("*** WindowsWindow: requestFocus.S parent %p, window %p, isCurrent %d, reparented %d\n",
- (void*) pHwnd, (void*)hwnd, current==hwnd, (int) reparented);
- if(reparented || current!=hwnd) {
- if( reparented || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
+ DBG_PRINT("*** WindowsWindow: requestFocus.S parent %p, window %p, isCurrent %d\n",
+ (void*) pHwnd, (void*)hwnd, current==hwnd);
+ if( JNI_TRUE==force || current!=hwnd) {
+ if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
- if(reparented) {
- flags |= SWP_FRAMECHANGED;
- }
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
SetForegroundWindow(hwnd); // Slightly Higher Priority
SetFocus(hwnd);// Sets Keyboard Focus To Window
@@ -626,7 +643,64 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, BO
DBG_PRINT("*** WindowsWindow: requestFocus.XX\n");
}
-static RECT * UpdateInsets(JNIEnv *env, HWND hwnd, jobject window)
+#if 0
+
+static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd)
+{
+ // being naughty here
+ static RECT m_insets = { 0, 0, 0, 0 };
+ RECT outside;
+ RECT inside;
+ POINT *rp_inside = (POINT *) (void *) &inside;
+ int dx, dy, dw, dh;
+
+ if (IsIconic(hwnd)) {
+ m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = -1;
+ return FALSE;
+ }
+
+ m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = 0;
+
+ GetClientRect(hwnd, &inside);
+ GetWindowRect(hwnd, &outside);
+
+ DBG_PRINT("*** WindowsWindow: UpdateInsets (a1) window %p, Inside CC: %d/%d - %d/%d %dx%d\n",
+ (void*)hwnd,
+ (int)inside.left, (int)inside.top, (int)inside.right, (int)inside.bottom,
+ (int)(inside.right - inside.left), (int)(inside.bottom - inside.top));
+ DBG_PRINT("*** WindowsWindow: UpdateInsets (a1) window %p, Outside SC: %d/%d - %d/%d %dx%d\n",
+ (void*)hwnd,
+ (int)outside.left, (int)outside.top, (int)outside.right, (int)outside.bottom,
+ (int)(outside.right - outside.left), (int)(outside.bottom - outside.top));
+
+ // xform client -> screen coord
+ ClientToScreen(hwnd, rp_inside);
+ ClientToScreen(hwnd, rp_inside+1);
+
+ DBG_PRINT("*** WindowsWindow: UpdateInsets (a2) window %p, Inside SC: %d/%d - %d/%d %dx%d\n",
+ (void*)hwnd,
+ (int)inside.left, (int)inside.top, (int)inside.right, (int)inside.bottom,
+ (int)(inside.right - inside.left), (int)(inside.bottom - inside.top));
+
+ m_insets.top = inside.top - outside.top;
+ m_insets.bottom = outside.bottom - inside.bottom;
+ m_insets.left = inside.left - outside.left;
+ m_insets.right = outside.right - inside.right;
+
+ DBG_PRINT("*** WindowsWindow: UpdateInsets (1.0) window %p, %d/%d - %d/%d %dx%d\n",
+ (void*)hwnd,
+ (int)m_insets.left, (int)m_insets.top, (int)m_insets.right, (int)m_insets.bottom,
+ (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);
+ return &m_insets;
+}
+
+#else
+
+static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd)
{
// being naughty here
static RECT m_insets = { 0, 0, 0, 0 };
@@ -690,13 +764,16 @@ static RECT * UpdateInsets(JNIEnv *env, HWND hwnd, jobject window)
return &m_insets;
}
-static void WmSize(JNIEnv *env, HWND wnd, jobject window, UINT type)
+#endif
+
+static void WmSize(JNIEnv *env, jobject window, HWND wnd, UINT type)
{
RECT rc;
int w, h;
+ BOOL isVisible = IsWindowVisible(wnd);
// make sure insets are up to date
- (void)UpdateInsets(env, wnd, window);
+ (void)UpdateInsets(env, window, wnd);
if (type == SIZE_MINIMIZED) {
// TODO: deal with minimized window sizing
@@ -709,9 +786,11 @@ static void WmSize(JNIEnv *env, HWND wnd, jobject window, UINT type)
w = rc.right - rc.left;
h = rc.bottom - rc.top;
- DBG_PRINT("*** WindowsWindow: WmSize window %p, %dx%d\n", (void*)wnd, w, h);
+ DBG_PRINT("*** WindowsWindow: WmSize window %p, %dx%d, visible %d\n", (void*)wnd, w, h, isVisible);
- (*env)->CallVoidMethod(env, window, sizeChangedID, w, h);
+ if(isVisible) {
+ (*env)->CallVoidMethod(env, window, sizeChangedID, w, h, JNI_FALSE);
+ }
}
static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
@@ -795,14 +874,14 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
break;
case WM_SIZE:
- WmSize(env, wnd, window, (UINT)wParam);
+ WmSize(env, window, wnd, (UINT)wParam);
break;
case WM_SETTINGCHANGE:
if (wParam == SPI_SETNONCLIENTMETRICS) {
// make sure insets are updated, we don't need to resize the window
// because the size of the client area doesn't change
- (void)UpdateInsets(env, wnd, window);
+ (void)UpdateInsets(env, window, wnd);
} else {
useDefWindowProc = 1;
}
@@ -935,7 +1014,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
// ignore erase background
(*env)->CallVoidMethod(env, window, windowRepaintID, 0, 0, -1, -1);
useDefWindowProc = 0;
- res = 1;
+ res = 1; // OpenGL, etc .. erases the background, hence we claim to have just done this
break;
@@ -1073,8 +1152,25 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getHeight
JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initIDs0
(JNIEnv *env, jclass clazz)
{
+ if(NULL==pointClz) {
+ jclass c = (*env)->FindClass(env, ClazzNamePoint);
+ if(NULL==c) {
+ _FatalError(env, "NEWT WindowsWindows: can't find %s", ClazzNamePoint);
+ }
+ pointClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==pointClz) {
+ _FatalError(env, "NEWT WindowsWindows: can't use %s", ClazzNamePoint);
+ }
+ pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ if(NULL==pointCstr) {
+ _FatalError(env, "NEWT WindowsWindows: can't fetch %s.%s %s",
+ ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ }
+ }
+
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V");
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)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");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
@@ -1170,7 +1266,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi
SetWindowLongPtr(window, GWLP_USERDATA, (intptr_t) wud);
#endif
- UpdateInsets(env, window, obj);
+ UpdateInsets(env, obj, window);
}
#ifdef UNICODE
@@ -1232,109 +1328,115 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_MonitorF
#endif
}
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: setVisible0
- * Signature: (JZ)V
+/***
+ * returns bits: 1: size change, 2: pos change
*/
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setVisible0
- (JNIEnv *_env, jclass clazz, jlong window, jboolean visible)
+int NewtWindow_setVisiblePosSize(JNIEnv *env, jobject obj, HWND hwnd, jboolean top, jboolean visible,
+ int x, int y, int width, int height)
{
- HWND hwnd = (HWND) (intptr_t) window;
- DBG_PRINT("*** WindowsWindow: setVisible window %p, visible: %d\n", hwnd, (int)visible);
- if (visible) {
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
- ShowWindow(hwnd, SW_SHOW);
+ 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);
+
+ if(JNI_TRUE == visible) {
+ flags = SWP_SHOWWINDOW;
} else {
- ShowWindow(hwnd, SW_HIDE);
+ flags = SWP_NOACTIVATE | SWP_NOZORDER;
}
-}
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: setSize0
- * Signature: (JIIII)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setSize0
- (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height)
-{
- HWND hwndP = (HWND) (intptr_t) parent;
- HWND hwnd = (HWND) (intptr_t) window;
- int nWidth=width, nHeight=height;
- int nX=x, nY=y;
+ if(0>x || 0>y ) {
+ flags |= SWP_NOMOVE;
+ } else {
+ iRes |= 2;
+ }
+ if(0>=width || 0>=height ) {
+ flags |= SWP_NOSIZE;
+ } else {
+ iRes |= 1;
+ }
- if(NULL==hwndP) {
- // since width, height are the size of the client area, we need to add
- // insets
- RECT *pInsets = UpdateInsets(env, hwnd, obj);
+ if(JNI_TRUE == top) {
+ hWndInsertAfter = HWND_TOPMOST;
+ if ( 0 == ( flags & SWP_NOSIZE ) ) {
- RECT r;
- GetWindowRect(hwnd, &r);
+ // since width, height are the size of the client area, we need to add insets
+ RECT *pInsets = UpdateInsets(env, obj, hwnd);
- nWidth = width + pInsets->left + pInsets->right;
- nHeight = height + pInsets->top + pInsets->bottom;
- nX=r.left; nY=r.top; // FIXME: really ?
+ 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);
}
- DBG_PRINT("*** WindowsWindow: setSize parent %p, window %p, %d/%d %dx%d -> %d/%d %dx%d\n",
- hwndP, hwnd, x, y, width, height, nX, nY, nWidth, nHeight);
+ SetWindowPos(hwnd, hWndInsertAfter, x, y, wwidth, wheight, flags);
- MoveWindow(hwnd, nX, nY, nWidth, nHeight, TRUE);
+ InvalidateRect(hwnd, NULL, TRUE);
+ UpdateWindow(hwnd);
// we report back the size of client area
- (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height);
+ (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height, JNI_FALSE);
+
+ return iRes;
}
/*
* Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: setPosition0
- * Signature: (JJII)V
+ * Method: setVisible0
+ * Signature: (JZ)V
*/
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setPosition0
- (JNIEnv *env, jclass clazz, jlong parent, jlong window, jint x, jint y/*, jint width, jint height*/)
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setVisible0
+ (JNIEnv *env, jobject obj, jlong window, jboolean visible, jboolean top, jint x, jint y, jint width, jint height)
{
- HWND hwndP = (HWND) (intptr_t) parent;
HWND hwnd = (HWND) (intptr_t) window;
-
- if(NULL==hwndP) {
- DBG_PRINT("*** WindowsWindow: setPosition.1 parent %p, window %p, %d/%d\n", hwndP, hwnd, x, y);
-
- // Top Level Window .. SetWindowPos -> no need to do insets ..
- SetWindowPos(hwnd, hwndP, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
+ 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 {
- RECT rc;
- int w, h;
-
- GetClientRect(hwnd, &rc);
- w = rc.right - rc.left;
- h = rc.bottom - rc.top;
-
- DBG_PRINT("*** WindowsWindow: setPosition.2 parent %p, window %p, %d/%d, %dx%d\n",
- hwndP, hwnd, x, y, /* width, height,*/ w, h);
-
- // Child Window .. must use MoveWindow, no insets (no decoration)
- MoveWindow(hwnd, x, y, w, h, FALSE);
+ ShowWindow(hwnd, SW_HIDE);
}
}
-static void NewtWindows_reparentWindow(JNIEnv *env, jobject obj, HWND hwndP, HWND hwnd, BOOL visible,
- jint x, jint y, jint width, jint height, jboolean bIsUndecorated)
+/*
+ * Class: com_jogamp_newt_impl_windows_WindowsWindow
+ * Method: reconfigureWindow0
+ * Signature: (JIIIIZZII)V
+ */
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_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)
{
- UINT flags;
- HWND hWndInsertAfter;
+ 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;
+
+ 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: reparentWindow.1 parent %p, window %p, %d/%d %dx%d undeco %d\n", (void*)hwndP, (void*)hwnd, x, y, width, height, bIsUndecorated);
if (!IsWindow(hwnd)) {
- DBG_PRINT("*** WindowsWindow: reparentWindow failure: Passed window %p is invalid\n", (void*)hwnd);
+ DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed window %p is invalid\n", (void*)hwnd);
return;
}
+
if (NULL!=hwndP && !IsWindow(hwndP)) {
- DBG_PRINT("*** WindowsWindow: reparentWindow failure: Passed parent window %p is invalid\n", (void*)hwndP);
+ DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed parent window %p is invalid\n", (void*)hwndP);
return;
}
- if(visible) {
+ if(JNI_TRUE == visible) {
windowStyle |= WS_VISIBLE ;
}
@@ -1342,74 +1444,30 @@ static void NewtWindows_reparentWindow(JNIEnv *env, jobject obj, HWND hwndP, HWN
// TOP: SetParent(.., NULL); Clear WS_CHILD [, Set WS_POPUP]
// CHILD: Set WS_CHILD [, Clear WS_POPUP]; SetParent(.., PARENT)
//
- if ( NULL == hwndP ) {
+ if ( JNI_TRUE == parentChange && NULL == hwndP ) {
SetParent(hwnd, NULL);
- DBG_PRINT("*** WindowsWindow: reparentWindow.2\n");
}
- if(NULL!=hwndP) {
- windowStyle |= WS_CHILD ;
- } else if (bIsUndecorated) {
- windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
- } else {
- windowStyle |= WS_OVERLAPPEDWINDOW;
+ if ( styleChange ) {
+ if(NULL!=hwndP) {
+ windowStyle |= WS_CHILD ;
+ } else if ( decorationChange < 0 || 0 < fullScreenChange ) {
+ windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
+ } else {
+ windowStyle |= WS_OVERLAPPEDWINDOW;
+ }
+ SetWindowLong(hwnd, GWL_STYLE, windowStyle);
+ SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
}
- SetWindowLong(hwnd, GWL_STYLE, windowStyle);
- DBG_PRINT("*** WindowsWindow: reparentWindow.3\n");
- if ( NULL != hwndP ) {
+ if ( JNI_TRUE == parentChange && NULL != hwndP ) {
SetParent(hwnd, hwndP );
- DBG_PRINT("*** WindowsWindow: reparentWindow.4\n");
}
- DBG_PRINT("*** WindowsWindow: reparentWindow.X\n");
-}
-
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: reconfigureWindow0
- * Signature: (JIIIIZ)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reconfigureWindow0
- (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated)
-{
- UINT flags;
- HWND hwndP = (HWND) (intptr_t) parent;
- HWND hwnd = (HWND) (intptr_t) window;
- HWND hWndInsertAfter;
- BOOL isVisible = IsWindowVisible(hwnd);
-
- DBG_PRINT("*** WindowsWindow: reconfigureWindow0.1 parent %p, window %p, %d/%d %dx%d undeco %d visible\n",
- parent, window, x, y, width, height, bIsUndecorated, isVisible);
-
- NewtWindows_reparentWindow(env, obj, hwndP, hwnd, FALSE, x, y, width, height, bIsUndecorated);
-
- if ( NULL == hwndP ) {
- flags = SWP_SHOWWINDOW;
- hWndInsertAfter = HWND_TOPMOST;
- } else {
- flags = SWP_NOACTIVATE | SWP_NOZORDER;
- hWndInsertAfter = 0;
- }
- SetWindowPos(hwnd, hWndInsertAfter, x, y, width, height, flags);
+ NewtWindow_setVisiblePosSize(env, obj, hwnd, (NULL == hwndP) ? JNI_TRUE : JNI_FALSE /* top */, visible,
+ x, y, width, height);
DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X\n");
- (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); // resize necessary ..
-}
-
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: reparentWindow0
- * Signature: (JIIIIZ)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentWindow0
- (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated)
-{
- HWND hwndP = (HWND) (intptr_t) parent;
- HWND hwnd = (HWND) (intptr_t) window;
- BOOL isVisible = IsWindowVisible(hwnd);
-
- NewtWindows_reparentWindow(env, obj, hwndP, hwnd, FALSE, x, y, width, height, bIsUndecorated);
}
/*
@@ -1433,12 +1491,33 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setTitle0
/*
* Class: com_jogamp_newt_impl_windows_WindowsWindow
* Method: requestFocus
- * Signature: (J)V
+ * Signature: (JZ)V
*/
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_requestFocus0
- (JNIEnv *env, jobject obj, jlong window, jboolean bReparented)
+ (JNIEnv *env, jobject obj, jlong window, jboolean force)
{
- DBG_PRINT("*** WindowsWindow: RequestFocus0: reparented %d\n", (int)bReparented);
- NewtWindows_requestFocus ( env, obj, (HWND) (intptr_t) window, bReparented ) ;
+ DBG_PRINT("*** WindowsWindow: RequestFocus0\n");
+ NewtWindows_requestFocus ( env, obj, (HWND) (intptr_t) window, force) ;
+}
+
+/*
+ * Class: com_jogamp_newt_impl_windows_WindowsWindows
+ * Method: getRelativeLocation0
+ * Signature: (JJII)Ljavax/media/nativewindow/util/Point;
+ */
+JNIEXPORT jobject JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_getRelativeLocation0
+ (JNIEnv *env, jobject obj, jlong jsrc_win, jlong jdest_win, jint src_x, jint src_y)
+{
+ HWND src_win = (HWND) (intptr_t) jsrc_win;
+ HWND dest_win = (HWND) (intptr_t) jdest_win;
+ POINT dest = { src_x, src_y } ;
+ int res;
+
+ res = MapWindowPoints(src_win, dest_win, &dest, 1);
+
+ DBG_PRINT("*** WindowsWindow: getRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n",
+ (void*)src_win, src_x, src_y, (void*)dest_win, (int)dest.x, (int)dest.y, res);
+
+ return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest.x, (jint)dest.y);
}
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 1394b5410..0cdf6ae57 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -146,12 +146,20 @@ static void _FatalError(JNIEnv *env, const char* msg, ...)
}
static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException";
+
+static const char * const ClazzNameNewtWindow = "com/jogamp/newt/Window";
+
+static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point";
+static const char * const ClazzAnyCstrName = "<init>";
+static const char * const ClazzNamePointCstrSignature = "(II)V";
+
static jclass runtimeExceptionClz=NULL;
-static const char * const ClazzNameNewtWindow =
- "com/jogamp/newt/Window";
static jclass newtWindowClz=NULL;
+static jclass pointClz = NULL;
+static jmethodID pointCstr = NULL;
+
static jmethodID sizeChangedID = NULL;
static jmethodID positionChangedID = NULL;
static jmethodID focusChangedID = NULL;
@@ -159,7 +167,7 @@ static jmethodID visibleChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowDestroyedID = NULL;
static jmethodID windowRepaintID = NULL;
-static jmethodID windowCreatedID = NULL;
+static jmethodID windowReparentedID = NULL;
static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
@@ -169,6 +177,7 @@ static jmethodID enqueueRequestFocusID = NULL;
static jmethodID displayCompletedID = NULL;
+
static void _throwNewRuntimeException(Display * unlockDisplay, JNIEnv *env, const char* msg, ...)
{
char buffer[512];
@@ -256,6 +265,22 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Display_initIDs0
}
}
+ if(NULL==pointClz) {
+ c = (*env)->FindClass(env, ClazzNamePoint);
+ if(NULL==c) {
+ _FatalError(env, "NEWT X11Windows: can't find %s", ClazzNamePoint);
+ }
+ pointClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==pointClz) {
+ _FatalError(env, "NEWT X11Windows: can't use %s", ClazzNamePoint);
+ }
+ pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ if(NULL==pointCstr) {
+ _FatalError(env, "NEWT X11Windows: can't fetch %s.%s %s",
+ ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ }
+ }
return JNI_TRUE;
}
@@ -298,7 +323,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_CompleteDisplay0
* Window
*/
-#define WINDOW_EVENT_MASK ( FocusChangeMask | StructureNotifyMask | ExposureMask )
+#define WINDOW_EVENT_MASK ( FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask )
static int putPtrIn32Long(unsigned long * dst, uintptr_t src) {
int i=0;
@@ -377,32 +402,43 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j
return jwindow;
}
-/**
-static Window NewtWindows_getParent (Display *dpy, Window w) {
- Window root_return=0;
- Window parent_return=0;
+/** @return zero if fails, non zero if OK */
+static Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return) {
Window *children_return=NULL;
unsigned int nchildren_return=0;
- Status res = XQueryTree(dpy, w, &root_return, &parent_return, &children_return, &nchildren_return);
+ Status res = XQueryTree(dpy, w, root_return, parent_return, &children_return, &nchildren_return);
if(NULL!=children_return) {
XFree(children_return);
}
- if(0!=res) {
+ return res;
+}
+static Window NewtWindows_getRoot (Display *dpy, Window w) {
+ Window root_return;
+ Window parent_return;
+ if( 0 != NewtWindows_getRootAndParent(dpy, w, &root_return, &parent_return) ) {
+ return root_return;
+ }
+ return 0;
+}
+static Window NewtWindows_getParent (Display *dpy, Window w) {
+ Window root_return;
+ Window parent_return;
+ if( 0 != NewtWindows_getRootAndParent(dpy, w, &root_return, &parent_return) ) {
return parent_return;
}
return 0;
-} */
+}
+
-static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w,
- Bool reparented) {
+static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w, jboolean force) {
XWindowAttributes xwa;
Window focus_return;
int revert_to_return;
XGetInputFocus(dpy, &focus_return, &revert_to_return);
- if(reparented || focus_return!=w) {
- if( reparented || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
+ if( JNI_TRUE==force || focus_return!=w) {
+ if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
XRaiseWindow(dpy, w);
// Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
XGetWindowAttributes(dpy, w, &xwa);
@@ -414,32 +450,6 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
XSync(dpy, False);
}
-/**
- * Changing this attribute while a window is established,
- * returns the previous value.
- */
-static Bool NewtWindows_setOverrideRedirect0 (Display *dpy, Window w, XWindowAttributes *xwa, Bool newVal) {
- Bool oldVal = xwa->override_redirect;
- XSetWindowAttributes xswa;
-
- if(oldVal != newVal) {
- memset(&xswa, 0, sizeof(XSetWindowAttributes));
- xswa.override_redirect = newVal;
- XChangeWindowAttributes(dpy, w, CWOverrideRedirect, &xswa);
- }
- return oldVal;
-}
-
-static Bool NewtWindows_setOverrideRedirect1 (Display *dpy, Window w, Bool newVal) {
- XWindowAttributes xwa;
- Bool oldVal;
-
- XSync(dpy, False);
- XGetWindowAttributes(dpy, w, &xwa);
-
- return NewtWindows_setOverrideRedirect0 (dpy, w, &xwa, newVal);
-}
-
#define MWM_HINTS_DECORATIONS (1L << 1)
#define PROP_MWM_HINTS_ELEMENTS 5
@@ -466,7 +476,7 @@ static void NewtWindows_setDecorations (Display *dpy, Window w, Bool decorated)
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
-static void NewtWindows_setFullscreen (Display *dpy, Window w, Bool fullscreen) {
+static void NewtWindows_setFullscreen (Display *dpy, Window root, Window w, Bool fullscreen) {
Atom _NET_WM_STATE = XInternAtom( dpy, "_NET_WM_STATE", False );
Atom _NET_WM_STATE_ABOVE = XInternAtom( dpy, "_NET_WM_STATE_ABOVE", False );
Atom _NET_WM_STATE_FULLSCREEN = XInternAtom( dpy, "_NET_WM_STATE_FULLSCREEN", False );
@@ -496,11 +506,13 @@ static void NewtWindows_setFullscreen (Display *dpy, Window w, Bool fullscreen)
xev.xclient.data.l[2] = _NET_WM_STATE_ABOVE;
xev.xclient.data.l[3] = 1; //source indication for normal applications
}
-
XChangeProperty( dpy, w, _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes);
- XSendEvent (dpy, DefaultRootWindow(dpy), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev );
+ XSync(dpy, False);
+ XSendEvent (dpy, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xev );
}
+#define USE_SENDIO_DIRECT 1
+
/*
* Class: com_jogamp_newt_impl_x11_X11Display
* Method: DispatchMessages
@@ -545,7 +557,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages
return ;
}
- DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type);
+ // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type);
displayDispatchErrorHandlerEnable(1, env);
@@ -581,30 +593,64 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages
switch(evt.type) {
case ButtonPress:
(*env)->CallVoidMethod(env, jwindow, enqueueRequestFocusID, JNI_FALSE);
+ #ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
(jint) evt.xbutton.state,
(jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID,
+ JNI_FALSE,
+ (jint) EVENT_MOUSE_PRESSED,
+ (jint) evt.xbutton.state,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #endif
break;
case ButtonRelease:
+ #ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
(jint) evt.xbutton.state,
(jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID,
+ JNI_FALSE,
+ (jint) EVENT_MOUSE_RELEASED,
+ (jint) evt.xbutton.state,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #endif
break;
case MotionNotify:
+ #ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendMouseEventID,
(jint) EVENT_MOUSE_MOVED,
(jint) evt.xmotion.state,
(jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID,
+ JNI_FALSE,
+ (jint) EVENT_MOUSE_MOVED,
+ (jint) evt.xmotion.state,
+ (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
+ #endif
break;
case KeyPress:
+ #ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID,
(jint) EVENT_KEY_PRESSED,
(jint) evt.xkey.state,
X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID,
+ JNI_FALSE,
+ (jint) EVENT_KEY_PRESSED,
+ (jint) evt.xkey.state,
+ X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+ #endif
+
break;
case KeyRelease:
+ #ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID,
(jint) EVENT_KEY_RELEASED,
(jint) evt.xkey.state,
@@ -614,69 +660,132 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages
(jint) EVENT_KEY_TYPED,
(jint) evt.xkey.state,
(jint) -1, (jchar) keyChar);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID,
+ JNI_FALSE,
+ (jint) EVENT_KEY_RELEASED,
+ (jint) evt.xkey.state,
+ X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID,
+ JNI_FALSE,
+ (jint) EVENT_KEY_TYPED,
+ (jint) evt.xkey.state,
+ (jint) -1, (jchar) keyChar);
+ #endif
+
break;
case DestroyNotify:
- DBG_PRINT( "X11: event . DestroyNotify call 0x%X\n", (unsigned int)evt.xdestroywindow.window);
- (*env)->CallVoidMethod(env, jwindow, windowDestroyedID);
+ DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n",
+ (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event);
+ if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) {
+ // ignore child destroy notification
+ (*env)->CallVoidMethod(env, jwindow, windowDestroyedID);
+ }
break;
case CreateNotify:
- DBG_PRINT( "X11: event . CreateNotify call 0x%X\n", (unsigned int)evt.xcreatewindow.window);
- (*env)->CallVoidMethod(env, jwindow, windowCreatedID);
+ DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n",
+ (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent);
break;
case ConfigureNotify:
- DBG_PRINT( "X11: event . ConfigureNotify call 0x%X (parent 0x%X, above 0x%X) %d/%d %dx%d %d\n",
- (unsigned int)evt.xconfigure.window, (unsigned int)evt.xconfigure.event, (unsigned int)evt.xconfigure.above,
+ DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n",
+ (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above,
evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height,
- evt.xconfigure.override_redirect);
- (*env)->CallVoidMethod(env, jwindow, sizeChangedID,
- (jint) evt.xconfigure.width, (jint) evt.xconfigure.height);
- (*env)->CallVoidMethod(env, jwindow, positionChangedID,
- (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+ evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event);
+ if ( evt.xconfigure.window == evt.xconfigure.event ) {
+ // ignore child window change notification
+ (*env)->CallVoidMethod(env, jwindow, sizeChangedID,
+ (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
+ (*env)->CallVoidMethod(env, jwindow, positionChangedID,
+ (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+ }
break;
case ClientMessage:
if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) {
- DBG_PRINT( "X11: event . ClientMessage call 0x%X type 0x%X !!!\n", (unsigned int)evt.xclient.window, (unsigned int)evt.xclient.message_type);
+ DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n",
+ (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type);
(*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID);
// Called by Window.java: CloseWindow();
}
break;
case FocusIn:
- DBG_PRINT( "X11: event . FocusIn call 0x%X\n", (unsigned int)evt.xvisibility.window);
+ DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window);
(*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_TRUE);
break;
case FocusOut:
- DBG_PRINT( "X11: event . FocusOut call 0x%X\n", (unsigned int)evt.xvisibility.window);
+ DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
(*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE);
break;
case Expose:
- DBG_PRINT( "X11: event . Expose call 0x%X %d/%d %dx%d\n", (unsigned int)evt.xexpose.window,
- evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
+ DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window,
+ evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count);
- if (evt.xexpose.width > 0 && evt.xexpose.height > 0) {
+ if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) {
(*env)->CallVoidMethod(env, jwindow, windowRepaintID,
evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
}
break;
case MapNotify:
- DBG_PRINT( "X11: event . MapNotify call Event 0x%X, Window 0x%X, override_redirect %d\n",
- (unsigned int)evt.xmap.event, (unsigned int)evt.xmap.window, (int)evt.xmap.override_redirect);
- (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE);
+ DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n",
+ (void*)evt.xmap.event, (void*)evt.xmap.window, (int)evt.xmap.override_redirect,
+ evt.xmap.event!=evt.xmap.window);
+ if( evt.xmap.event == evt.xmap.window ) {
+ // ignore child window notification
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE);
+ }
break;
case UnmapNotify:
- DBG_PRINT( "X11: event . UnmapNotify call Event 0x%X, Window 0x%X, from_configure %d\n",
- (unsigned int)evt.xunmap.event, (unsigned int)evt.xunmap.window, (int)evt.xunmap.from_configure);
- (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE);
+ DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, from_configure %d, child-event: %d\n",
+ (void*)evt.xunmap.event, (void*)evt.xunmap.window, (int)evt.xunmap.from_configure,
+ evt.xunmap.event!=evt.xunmap.window);
+ if( evt.xunmap.event == evt.xunmap.window ) {
+ // ignore child window notification
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE);
+ }
+ break;
+
+ case ReparentNotify:
+ {
+ jlong parentResult; // 0 if root, otherwise proper value
+ Window winRoot, winTopParent;
+ #ifdef VERBOSE_ON
+ Window oldParentRoot, oldParentTopParent;
+ Window parentRoot, parentTopParent;
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) {
+ oldParentRoot=0; oldParentTopParent = 0;
+ }
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) {
+ parentRoot=0; parentTopParent = 0;
+ }
+ #endif
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) {
+ winRoot=0; winTopParent = 0;
+ }
+ if(evt.xreparent.parent == winRoot) {
+ parentResult = 0; // our java indicator for root window
+ } else {
+ 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",
+ (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent,
+ (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent,
+ (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent);
+ #endif
+
+ (*env)->CallVoidMethod(env, jwindow, windowReparentedID, parentResult);
+ }
break;
// unhandled events .. yet ..
default:
- DBG_PRINT("X11: event . unhandled %d 0x%X call 0x%X\n", evt.type, evt.type, (unsigned int)evt.xunmap.window);
+ DBG_PRINT("X11: event . unhandled %d 0x%X call %p\n", (int)evt.type, (unsigned int)evt.type, (void*)evt.xunmap.window);
}
}
}
@@ -741,14 +850,14 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getHeight0
JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0
(JNIEnv *env, jclass clazz)
{
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)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");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(IIII)V");
- windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V");
+ windowReparentedID = (*env)->GetMethodID(env, clazz, "windowReparented", "(J)V");
enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIII)V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
@@ -763,7 +872,7 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0
windowDestroyNotifyID == NULL ||
windowDestroyedID == NULL ||
windowRepaintID == NULL ||
- windowCreatedID == NULL ||
+ windowReparentedID == NULL ||
enqueueMouseEventID == NULL ||
sendMouseEventID == NULL ||
enqueueKeyEventID == NULL ||
@@ -819,6 +928,9 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
if(0==windowParent) {
windowParent = XRootWindowOfScreen(scrn);
}
+ if( XRootWindowOfScreen(scrn) != XRootWindow(dpy, scrn_idx) ) {
+ _FatalError(env, "XRoot Malfunction: %p != %p"+XRootWindowOfScreen(scrn), XRootWindow(dpy, scrn_idx));
+ }
DBG_PRINT( "X11: CreateWindow dpy %p, parent %p, %x/%d %dx%d, undeco %d\n",
(void*)dpy, (void*)windowParent, x, y, width, height, undecorated);
@@ -853,7 +965,8 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
CWBorderPixel | CWColormap | CWOverrideRedirect ) ;
memset(&xswa, 0, sizeof(xswa));
- xswa.override_redirect = ( 0 != parent ) ? True : False ;
+ // xswa.override_redirect = ( 0 != parent ) ? False : True;
+ xswa.override_redirect = False; // use the window manager, always
xswa.border_pixel = 0;
xswa.background_pixel = 0;
xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */
@@ -861,7 +974,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
xswa.backing_pixel=0; /* value to use in restoring planes */
xswa.colormap = XCreateColormap(dpy,
- windowParent, // XRootWindow(dpy, scrn_idx),
+ windowParent,
visual,
AllocNone);
@@ -900,9 +1013,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
NewtWindows_setDecorations(dpy, window, ( JNI_TRUE == undecorated ) ? False : True );
XSync(dpy, False);
- DBG_PRINT( "X11: [CreateWindow] created window 0x%X on display %p\n", (unsigned int)window, dpy);
- (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) window);
-
+ DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", (void*)window, dpy);
return (jlong) window;
}
@@ -951,13 +1062,30 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0
(*env)->CallVoidMethod(env, obj, windowDestroyedID);
}
+static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint width, jint height)
+{
+ 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 pos/size mod: 0x%X\n", mod_flags);
+ memset(&xwc, 0, sizeof(XWindowChanges));
+ xwc.x=x;
+ xwc.y=y;
+ xwc.width=width;
+ xwc.height=height;
+ XConfigureWindow(dpy, w, mod_flags, &xwc);
+ XSync(dpy, False);
+ }
+}
+
/*
* Class: com_jogamp_newt_impl_x11_X11Window
* Method: setVisible0
- * Signature: (JJZ)V
+ * Signature: (JJZIIII)V
*/
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0
- (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean visible)
+ (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;
@@ -973,178 +1101,77 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0
XUnmapWindow(dpy, w);
}
XSync(dpy, False);
-}
-
-/*
- * Class: com_jogamp_newt_impl_x11_X11Window
- * Method: setSize0
- * Signature: (JJII)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0
- (JNIEnv *env, jobject obj, jlong display, jlong window, jint width, jint height)
-{
- Display * dpy = (Display *) (intptr_t) display;
- Window w = (Window)window;
- XWindowChanges xwc;
-
- DBG_PRINT( "X11: setSize0 %dx%d\n", width, height);
- if(dpy==NULL) {
- _FatalError(env, "invalid display connection..");
- }
-
- memset(&xwc, 0, sizeof(XWindowChanges));
- xwc.width=width;
- xwc.height=height;
- XConfigureWindow(dpy, w, CWWidth|CWHeight, &xwc);
-
- XSync(dpy, False);
+ NewtWindows_setPosSize(dpy, w, x, y, width, height);
}
/*
* Class: com_jogamp_newt_impl_x11_X11Window
- * Method: setPosition0
- * Signature: (JJII)V
+ * Method: reconfigureWindow0
+ * Signature: (JIJJIIIIZZII)V
*/
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0
- (JNIEnv *env, jobject obj, jlong parent, jlong display, jlong window, jint x, jint y)
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_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)
{
- Display * dpy = (Display *) (intptr_t) display;
- Window w = (Window)window;
- XWindowChanges xwc;
-
- DBG_PRINT( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y);
- if(dpy==NULL) {
- _FatalError(env, "invalid display connection..");
- }
+ Display * dpy = (Display *) (intptr_t) jdisplay;
+ Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index);
+ Window w = (Window)jwindow;
+ Window root = XRootWindowOfScreen(scrn);
+ Window parent = (0!=jparent)?(Window)jparent:root;
+ Window topParentParent;
+ Window topParentWindow;
+ Bool moveIntoParent = False;
- memset(&xwc, 0, sizeof(XWindowChanges));
- xwc.x=x;
- xwc.y=y;
- XConfigureWindow(dpy, w, CWX|CWY, &xwc);
- XSync(dpy, False);
-}
+ displayDispatchErrorHandlerEnable(1, env);
-static void NewtWindows_reparentWindow
- (JNIEnv *env, jobject obj,
- Display * dpy, Screen * scrn, Window w, XWindowAttributes *xwa, jlong jparent,
- jint x, jint y, jboolean undecorated, jboolean isVisible)
-{
- Window parent = (0!=jparent)?(Window)jparent:XRootWindowOfScreen(scrn);
+ topParentParent = NewtWindows_getParent (dpy, parent);
+ topParentWindow = NewtWindows_getParent (dpy, w);
- DBG_PRINT( "X11: reparentWindow dpy %p, parent %p/%p, win %p, %d/%d undec %d\n",
- (void*)dpy, (void*) jparent, (void*)parent, (void*)w, x, y, undecorated);
+ 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",
+ (void*)dpy, screen_index, (void*)scrn, (void*) jparent, (void*)parent, (void*) topParentParent, (void*)w, (void*)topParentWindow,
+ x, y, width, height, isVisible, parentChange, fullscreenChange, decorationChange);
- if(JNI_TRUE == isVisible) {
+ if(parentChange && JNI_TRUE == isVisible) { // unmap window if visible, reduce X11 internal signaling (WM unmap)
XUnmapWindow(dpy, w);
XSync(dpy, False);
}
- if(0 != jparent) {
- // move into parent ..
- NewtWindows_setDecorations (dpy, w, False);
- XSync(dpy, False);
- NewtWindows_setOverrideRedirect0 (dpy, w, xwa, True);
+ if(0 > fullscreenChange ) { // FS off
+ NewtWindows_setFullscreen(dpy, root, w, False );
XSync(dpy, False);
}
- XReparentWindow( dpy, w, parent, x, y );
- XSync(dpy, False);
-
- if(0 == jparent)
- {
- // move out of parent ..
- NewtWindows_setOverrideRedirect0 (dpy, w, xwa, False);
- XSync(dpy, False);
- NewtWindows_setDecorations (dpy, w, (JNI_TRUE == undecorated) ? False : True);
+ if(parentChange) {
+ if(0 != jparent) { // move into parent ..
+ moveIntoParent = True;
+ NewtWindows_setDecorations (dpy, w, False);
+ XSync(dpy, False);
+ }
+ XReparentWindow( dpy, w, parent, x, y ); // actual reparent call
XSync(dpy, False);
}
- if(JNI_TRUE == isVisible) {
- XMapRaised(dpy, w);
+ if(!moveIntoParent && 0!=decorationChange) {
+ NewtWindows_setDecorations (dpy, w, (0 < decorationChange) ? True : False);
XSync(dpy, False);
}
- DBG_PRINT( "X11: reparentWindow X\n");
-}
-
-/*
- * Class: com_jogamp_newt_impl_x11_X11Window
- * Method: reconfigureWindow0
- * Signature: (JJIJIIIIZ)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow0
- (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window,
- jint x, jint y, jint width, jint height, jboolean undecorated, jboolean isVisible, jboolean isFullscreen)
-{
- Display * dpy = (Display *) (intptr_t) display;
- Window w = (Window)window;
- Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index);
-
- XWindowChanges xwc;
- XWindowAttributes xwa;
-
- DBG_PRINT( "X11: reconfigureWindow0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d, visible %d, fullscreen %d\n",
- (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated, isVisible,isFullscreen);
-
- if(dpy==NULL) {
- _FatalError(env, "invalid display connection..");
- }
+ NewtWindows_setPosSize(dpy, w, x, y, width, height);
-
- XSync(dpy, False);
- XGetWindowAttributes(dpy, w, &xwa);
-
- if(JNI_FALSE == isFullscreen ) {
- NewtWindows_setFullscreen(dpy, w, False );
- XSync(dpy, False);
+ if(0 < fullscreenChange ) { // FS on
+ NewtWindows_setFullscreen(dpy, root, w, True );
+ XSync(dpy, False);
}
- NewtWindows_reparentWindow(env, obj, dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible);
- XSync(dpy, False);
-
- memset(&xwc, 0, sizeof(XWindowChanges));
- xwc.x=x;
- xwc.y=y;
- xwc.width=width;
- xwc.height=height;
- XConfigureWindow(dpy, w, CWX|CWY|CWWidth|CWHeight, &xwc);
- XSync(dpy, False);
-
- if(JNI_TRUE == isFullscreen ) {
- NewtWindows_setFullscreen(dpy, w, True );
- XSync(dpy, False);
- }
-}
-
-/*
- * Class: com_jogamp_newt_impl_x11_X11Window
- * Method: reparentWindow0
- * Signature: (JJIJIIZ)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0
- (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, jint x, jint y,
- jboolean undecorated, jboolean isVisible)
-{
- Display * dpy = (Display *) (intptr_t) display;
- Window w = (Window)window;
- Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index);
- XWindowAttributes xwa;
-
- DBG_PRINT( "X11: reparentWindow0 dpy %p, parent %p, win %p, %d/%d undec %d, visible %d\n",
- (void*)dpy, (void*) jparent, (void*)w, x, y, undecorated, isVisible);
-
- if(dpy==NULL) {
- _FatalError(env, "invalid display connection..");
+ if(parentChange && JNI_TRUE == isVisible) { // map window
+ XMapRaised(dpy, w);
+ XSync(dpy, False);
}
- XSync(dpy, False);
- XGetWindowAttributes(dpy, w, &xwa);
-
- NewtWindows_reparentWindow(env, obj, dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible);
- XSync(dpy, False);
+ displayDispatchErrorHandlerEnable(0, env);
- DBG_PRINT( "X11: reparentWindow0 X\n");
+ DBG_PRINT( "X11: reconfigureWindow0 X\n");
}
/*
@@ -1153,9 +1180,9 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_requestFocus0
- (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean bReparented)
+ (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean force)
{
- NewtWindows_requestFocus ( env, obj, (Display *) (intptr_t) display, (Window)window, bReparented ) ;
+ NewtWindows_requestFocus ( env, obj, (Display *) (intptr_t) display, (Window)window, force ) ;
}
/*
@@ -1210,3 +1237,37 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setTitle0
}
+
+/*
+ * Class: com_jogamp_newt_impl_x11_X11Window
+ * Method: getRelativeLocation0
+ * Signature: (JIJJII)Ljavax/media/nativewindow/util/Point;
+ */
+JNIEXPORT jobject JNICALL Java_com_jogamp_newt_impl_x11_X11Window_getRelativeLocation0
+ (JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index, jlong jsrc_win, jlong jdest_win, jint src_x, jint src_y)
+{
+ Display * dpy = (Display *) (intptr_t) jdisplay;
+ Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index);
+ Window root = XRootWindowOfScreen(scrn);
+ Window src_win = (Window)jsrc_win;
+ Window dest_win = (Window)jdest_win;
+ int dest_x=-1;
+ int dest_y=-1;
+ Window child;
+ Bool res;
+
+ if( 0 == jdest_win ) { dest_win = root; }
+ if( 0 == jsrc_win ) { src_win = root; }
+
+ displayDispatchErrorHandlerEnable(1, env);
+
+ res = XTranslateCoordinates(dpy, src_win, dest_win, src_x, src_y, &dest_x, &dest_y, &child);
+
+ displayDispatchErrorHandlerEnable(0, env);
+
+ DBG_PRINT( "X11: getRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n",
+ (void*)src_win, src_x, src_y, (void*)dest_win, dest_x, dest_y, (int)res);
+
+ return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest_x, (jint)dest_y);
+}
+