aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/classes')
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java17
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java74
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java1
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java508
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java99
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java40
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java11
-rw-r--r--src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java21
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java5
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java11
11 files changed, 749 insertions, 49 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index 7b6849a30..1e9a0e9eb 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -141,6 +141,23 @@ public abstract class Display {
*/
public abstract String getType();
+ /**
+ * Sets a new {@link EDTUtil} and returns the previous one.
+ * <p>
+ * If <code>newEDTUtil</code> is <code>null</code>,
+ * the device's default EDTUtil is created and used.
+ * </p>
+ * <p>
+ * If a previous one exists and it differs from the new one,
+ * it's being stopped, wait-until-idle and reset to allow restart.
+ * </p>
+ * <p>
+ * If <code>newEDTUtil</code> is not null and equals the previous one,
+ * <code>null</code> is returned and no change is being made.
+ * </p>
+ */
+ public abstract EDTUtil setEDTUtil(EDTUtil newEDTUtil);
+
public abstract EDTUtil getEDTUtil();
public abstract boolean isEDTRunning();
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index cd0e9aab6..6f0028a77 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -263,17 +263,35 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
private final FocusPropertyChangeListener focusPropertyChangeListener = new FocusPropertyChangeListener();
private volatile KeyboardFocusManager keyboardFocusManager = null;
- /** sets a new NEWT child, provoking reparenting. */
- private NewtCanvasAWT setNEWTChild(Window child) {
- if(newtChild!=child) {
- newtChild = child;
- if(isDisplayable()) {
- // reparent right away, addNotify has been called already
- final java.awt.Container cont = AWTMisc.getContainer(this);
- reparentWindow( (null!=child) ? true : false, cont );
- }
+ /**
+ * Sets a new NEWT child, provoking reparenting.
+ * <p>
+ * A previously detached <code>newChild</code> will be released to top-level status
+ * and made invisible.
+ * </p>
+ * <p>
+ * Note: When switching NEWT child's, detaching the previous first via <code>setNEWTChild(null)</code>
+ * produced much cleaner visual results.
+ * </p>
+ * @return the previous attached newt child.
+ */
+ public Window setNEWTChild(Window newChild) {
+ final Window prevChild = newtChild;
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.setNEWTChild.0: win "+newtWinHandleToHexString(prevChild)+" -> "+newtWinHandleToHexString(newChild));
+ }
+ final java.awt.Container cont = AWTMisc.getContainer(this);
+ // remove old one
+ if(null != newtChild) {
+ reparentWindow( false, cont );
+ newtChild = null;
}
- return this;
+ // add new one, reparent only if ready
+ newtChild = newChild;
+ if( isDisplayable() && null != newChild) {
+ reparentWindow( true, cont );
+ }
+ return prevChild;
}
/** @return the current NEWT child */
@@ -306,13 +324,13 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
awtKeyAdapter.removeFrom(this);
awtKeyAdapter = null;
}
- newtChild.setKeyboardFocusHandler(null);
if(null != keyboardFocusManager) {
keyboardFocusManager.removePropertyChangeListener("focusOwner", focusPropertyChangeListener);
keyboardFocusManager = null;
}
if( null != newtChild ) {
+ newtChild.setKeyboardFocusHandler(null);
if(attach) {
if(null == jawtWindow.getGraphicsConfiguration()) {
throw new InternalError("XXX");
@@ -360,7 +378,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
// if ( isShowing() == true ) -> Container is already visible.
System.err.println("NewtCanvasAWT.addNotify: "+newtChild+", "+this+", visible "+isVisible()+", showing "+isShowing()+
", displayable "+isDisplayable()+" -> "+cont);
- }
+ }
reparentWindow(true, cont);
}
@@ -375,6 +393,12 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
ols.detachSurfaceLayer();
}
reparentWindow(false, cont);
+
+ if(null != jawtWindow) {
+ NewtFactoryAWT.destroyNativeWindow(jawtWindow);
+ jawtWindow=null;
+ }
+
super.removeNotify();
}
@@ -382,14 +406,19 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
if(null==newtChild) {
return; // nop
}
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.reparentWindow.0: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil());
+ }
newtChild.setFocusAction(null); // no AWT focus traversal ..
if(add) {
- jawtWindow = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities());
- jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
if(DEBUG) {
System.err.println("NewtCanvasAWT.reparentWindow: newtChild: "+newtChild);
}
+ if(null == jawtWindow) {
+ jawtWindow = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities());
+ jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
+ }
final int w;
final int h;
if(isPreferredSizeSet()) {
@@ -413,7 +442,6 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
newtChild.setVisible(true);
configureNewtChild(true);
newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
- newtChild.windowRepaint(0, 0, w, h);
// force this AWT Canvas to be focus-able,
// since this it is completely covered by the newtChild (z-order).
@@ -422,10 +450,9 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
configureNewtChild(false);
newtChild.setVisible(false);
newtChild.reparentWindow(null);
- if(null != jawtWindow) {
- NewtFactoryAWT.destroyNativeWindow(jawtWindow);
- jawtWindow=null;
- }
+ }
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.reparentWindow.X: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil());
}
}
@@ -451,7 +478,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
NewtFactoryAWT.destroyNativeWindow(jawtWindow);
jawtWindow=null;
}
- newtChild.setVisible(false);
+ newtChild.setVisible(false);
newtChild.reparentWindow(null);
newtChild.destroy();
newtChild=null;
@@ -569,5 +596,12 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
}
}
+
+ static String newtWinHandleToHexString(Window w) {
+ return null != w ? toHexString(w.getWindowHandle()) : "nil";
+ }
+ static String toHexString(long l) {
+ return "0x"+Long.toHexString(l);
+ }
}
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 2205aec8e..d662a743a 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -480,7 +480,6 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
}
if(Window.DEBUG_IMPLEMENTATION) {
System.err.println("GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+WindowImpl.getThreadName()+", fin: dt "+ (System.nanoTime()-t0)/1e6 +"ms");
- Thread.dumpStack(); // JAU
}
}
diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
new file mode 100644
index 000000000..f45b864fa
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
@@ -0,0 +1,508 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+
+package com.jogamp.newt.swt;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.Capabilities;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.nativewindow.util.Point;
+
+import jogamp.nativewindow.macosx.OSXUtil;
+import jogamp.newt.Debug;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+
+import com.jogamp.nativewindow.swt.SWTAccessor;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.util.EDTUtil;
+
+public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
+ private static final boolean DEBUG = Debug.debug("Window");
+ private static final boolean isOSX = NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false);
+
+ /** SWT EDTUtil associated w/ parent's SWT Display */
+ private final EDTUtil swtEDTUtil;
+
+ private final AbstractGraphicsScreen screen;
+
+ private WindowClosingMode newtChildCloseOp = WindowClosingMode.DISPOSE_ON_CLOSE;
+ private volatile Rectangle clientArea;
+
+ private volatile SWTNativeWindow nativeWindow;
+ private volatile Window newtChild = null;
+
+ /**
+ * Creates an instance using {@link #NewtCanvasSWT(Composite, int, Window)}
+ * on the SWT thread.
+ *
+ * <p>
+ * Note: The NEWT child {@link Display}'s {@link EDTUtil} is being set to an SWT conform implementation
+ * via {@link Display#setEDTUtil(EDTUtil)}.
+ * </p>
+ *
+ * @param parent the SWT composite
+ * @param style additional styles to SWT#NO_BACKGROUND
+ * @param child optional preassigned {@link #Window}, maybe null
+ * @return a new instance
+ */
+ public static NewtCanvasSWT create(final Composite parent, final int style, final Window child) {
+ final NewtCanvasSWT[] res = new NewtCanvasSWT[] { null };
+ parent.getDisplay().syncExec( new Runnable() {
+ public void run() {
+ res[0] = new NewtCanvasSWT( parent, style, child);
+ }
+ });
+ return res[0];
+ }
+
+ /**
+ * Instantiates a NewtCanvas with a NEWT child.
+ *
+ * <p>
+ * Note: The NEWT child {@link Display}'s {@link EDTUtil} is being set to an SWT conform implementation
+ * via {@link Display#setEDTUtil(EDTUtil)}.
+ * </p>
+ *
+ * @param parent the SWT composite
+ * @param style additional styles to SWT#NO_BACKGROUND
+ * @param child optional preassigned {@link #Window}, maybe null
+ */
+ public NewtCanvasSWT(final Composite parent, final int style, Window child) {
+ super(parent, style | SWT.NO_BACKGROUND);
+
+ swtEDTUtil = new SWTEDTUtil(parent.getDisplay());
+
+ SWTAccessor.setRealized(this, true);
+
+ clientArea = getClientArea();
+
+ final AbstractGraphicsDevice device = SWTAccessor.getDevice(this);
+ screen = SWTAccessor.getScreen(device, 0);
+ nativeWindow = null;
+
+ if(null != child) {
+ setNEWTChild(child);
+ }
+
+ /* Register SWT listeners (e.g. PaintListener) to render/resize GL surface. */
+ /* TODO: verify that these do not need to be manually de-registered when destroying the SWT component */
+ addPaintListener(new PaintListener() {
+ @Override
+ public void paintControl(final PaintEvent arg0) {
+ if( null != nativeWindow || validateNative() ) {
+ if( null !=newtChild ) {
+ newtChild.windowRepaint(0, 0, clientArea.width, clientArea.height);
+ }
+ }
+ }
+ });
+
+ addControlListener(new ControlAdapter() {
+ @Override
+ public void controlResized(final ControlEvent arg0) {
+ updateSizeCheck();
+ }
+ });
+ }
+
+ /** assumes nativeWindow == null ! */
+ protected final boolean validateNative() {
+ if( isDisposed() ) {
+ return false;
+ }
+ updateSizeCheck();
+ final Rectangle nClientArea = clientArea;
+ if(0 == nClientArea.width * nClientArea.height) {
+ return false;
+ }
+
+ /* Native handle for the control, used to associate with GLContext */
+ final long nativeWindowHandle = SWTAccessor.getWindowHandle(this);
+ final int visualID = SWTAccessor.getNativeVisualID(screen.getDevice(), nativeWindowHandle);
+ final boolean visualIDValid = NativeWindowFactory.isNativeVisualIDValidForProcessing(visualID);
+ if(DEBUG) {
+ System.err.println("NewtCanvasSWT.validateNative() windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", visualID 0x"+Integer.toHexString(visualID)+", valid "+visualIDValid);
+ }
+ if( visualIDValid ) {
+ /* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite).
+ * Note: SWT is owner of the native handle, hence no closing operation will be a NOP. */
+ final CapabilitiesImmutable caps = new Capabilities();
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(screen.getDevice(), caps);
+ final AbstractGraphicsConfiguration config = factory.chooseGraphicsConfiguration( caps, caps, null, screen, visualID );
+ if(DEBUG) {
+ System.err.println("NewtCanvasSWT.validateNative() factory: "+factory+", windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", visualID 0x"+Integer.toHexString(visualID)+", chosen config: "+config);
+ // Thread.dumpStack();
+ }
+ if (null == config) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+
+ nativeWindow = new SWTNativeWindow(config, nativeWindowHandle);
+ reparentWindow( true );
+ }
+
+ return null != nativeWindow;
+ }
+
+ protected final void updateSizeCheck() {
+ final Rectangle oClientArea = clientArea;
+ final Rectangle nClientArea = getClientArea();
+ if ( nClientArea != null &&
+ ( nClientArea.width != oClientArea.width || nClientArea.height != oClientArea.height )
+ ) {
+ clientArea = nClientArea; // write back new value
+ if( null != newtChild ) {
+ newtChild.setSize(clientArea.width, clientArea.height);
+ }
+ }
+ }
+
+ @Override
+ public void update() {
+ // don't paint background etc .. nop avoids flickering
+ }
+
+ /**
+ * Destroys this resource:
+ * <ul>
+ * <li> Make the NEWT Child invisible </li>
+ * <li> Disconnects the NEWT Child from this Canvas NativeWindow, reparent to NULL </li>
+ * <li> Issues <code>destroy()</code> on the NEWT Child</li>
+ * <li> Remove reference to the NEWT Child</li>
+ * </ul>
+ * @see Window#destroy()
+ */
+ @Override
+ public void dispose() {
+ if( null != newtChild ) {
+ if(DEBUG) {
+ System.err.println("NewtCanvasSWT.dispose.0: EDTUtil cur "+newtChild.getScreen().getDisplay().getEDTUtil()+
+ ",\n\t"+newtChild);
+ }
+ configureNewtChild(false);
+ newtChild.setVisible(false);
+ newtChild.reparentWindow(null);
+ newtChild.destroy();
+ newtChild = null;
+ }
+ nativeWindow = null;
+ super.dispose();
+ }
+
+ /** @return this SWT Canvas NativeWindow representation, may be null in case it has not been realized. */
+ public NativeWindow getNativeWindow() { return nativeWindow; }
+
+ public WindowClosingMode getDefaultCloseOperation() {
+ return newtChildCloseOp; // FIXME
+ }
+
+ public WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) {
+ return newtChildCloseOp = op; // FIXME
+ }
+
+
+ boolean isParent() {
+ return null!=newtChild ;
+ }
+
+ boolean isFullscreen() {
+ return null != newtChild && newtChild.isFullscreen();
+ }
+
+ /**
+ * Sets a new NEWT child, provoking reparenting.
+ * <p>
+ * A previously detached <code>newChild</code> will be released to top-level status
+ * and made invisible.
+ * </p>
+ * <p>
+ * Note: When switching NEWT child's, detaching the previous first via <code>setNEWTChild(null)</code>
+ * produced much cleaner visual results.
+ * </p>
+ * <p>
+ * Note: The NEWT child {@link Display}'s {@link EDTUtil} is being set to an SWT conform implementation
+ * via {@link Display#setEDTUtil(EDTUtil)}.
+ * </p>
+ * @return the previous attached newt child.
+ */
+ public Window setNEWTChild(final Window newChild) {
+ final Window prevChild = newtChild;
+ if(DEBUG) {
+ System.err.println("NewtCanvasSWT.setNEWTChild.0: win "+newtWinHandleToHexString(prevChild)+" -> "+newtWinHandleToHexString(newChild));
+ }
+ // remove old one
+ if(null != newtChild) {
+ reparentWindow( false );
+ newtChild = null;
+ }
+ // add new one, reparent only if ready
+ newtChild = newChild;
+ if(null != nativeWindow && null != newChild) {
+ reparentWindow( true );
+ }
+ return prevChild;
+ }
+
+ /** @return the current NEWT child */
+ public Window getNEWTChild() {
+ return newtChild;
+ }
+
+ @Override
+ public boolean setParent(Composite parent) {
+ return super.setParent(parent);
+ }
+
+ /* package */ void configureNewtChild(boolean attach) {
+
+ if( null != newtChild ) {
+ newtChild.setKeyboardFocusHandler(null);
+ if(attach) {
+ newtChildCloseOp = newtChild.setDefaultCloseOperation(WindowClosingMode.DO_NOTHING_ON_CLOSE);
+ } else {
+ newtChild.setFocusAction(null);
+ newtChild.setDefaultCloseOperation(newtChildCloseOp);
+ }
+ }
+ }
+
+ void reparentWindow(boolean add) {
+ if( null == newtChild ) {
+ return; // nop
+ }
+ if(DEBUG) {
+ System.err.println("NewtCanvasSWT.reparentWindow.0: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil());
+ }
+
+ newtChild.setFocusAction(null); // no AWT focus traversal ..
+ if(add) {
+ updateSizeCheck();
+ final int w = clientArea.width;
+ final int h = clientArea.height;
+
+ newtChild.getScreen().getDisplay().setEDTUtil(swtEDTUtil);
+
+ newtChild.setSize(w, h);
+ newtChild.reparentWindow(nativeWindow);
+ newtChild.setVisible(true);
+ configureNewtChild(true);
+ newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
+
+ // force this SWT Canvas to be focus-able,
+ // since this it is completely covered by the newtChild (z-order).
+ setEnabled(true);
+ } else {
+ configureNewtChild(false);
+ newtChild.setVisible(false);
+ newtChild.reparentWindow(null);
+ }
+ if(DEBUG) {
+ System.err.println("NewtCanvasSWT.reparentWindow.X: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil());
+ }
+ }
+
+ private final void requestFocusNEWTChild() {
+ if( null != newtChild ) {
+ newtChild.setFocusAction(null);
+ newtChild.requestFocus();
+ }
+ }
+
+ @Override
+ public boolean forceFocus() {
+ final boolean res = NewtCanvasSWT.super.forceFocus();
+ requestFocusNEWTChild();
+ return res;
+ }
+
+ private class SWTNativeWindow implements NativeWindow {
+ private final AbstractGraphicsConfiguration config;
+ private final long nativeWindowHandle;
+ private final InsetsImmutable insets; // only required to allow proper client position calculation on OSX
+
+ public SWTNativeWindow(AbstractGraphicsConfiguration config, long nativeWindowHandle) {
+ this.config = config;
+ this.nativeWindowHandle = nativeWindowHandle;
+ if(isOSX) {
+ this.insets = OSXUtil.GetInsets(nativeWindowHandle);
+ } else {
+ this.insets = new Insets(0, 0, 0, 0);
+ }
+ }
+
+ @Override
+ public int lockSurface() throws NativeWindowException, RuntimeException {
+ return NativeSurface.LOCK_SUCCESS;
+ }
+
+ @Override
+ public void unlockSurface() { }
+
+ @Override
+ public boolean isSurfaceLockedByOtherThread() {
+ return false;
+ }
+
+ @Override
+ public Thread getSurfaceLockOwner() {
+ return null;
+ }
+
+ @Override
+ public boolean surfaceSwap() {
+ return false;
+ }
+
+ @Override
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) { }
+
+ @Override
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ }
+
+ @Override
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) { }
+
+ @Override
+ public long getSurfaceHandle() {
+ return 0;
+ }
+
+ @Override
+ public int getWidth() {
+ return clientArea.width;
+ }
+
+ @Override
+ public int getHeight() {
+ return clientArea.height;
+ }
+
+ @Override
+ public AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config;
+ }
+
+ @Override
+ public long getDisplayHandle() {
+ return config.getScreen().getDevice().getHandle();
+ }
+
+ @Override
+ public int getScreenIndex() {
+ return config.getScreen().getIndex();
+ }
+
+ @Override
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) { }
+
+ @Override
+ public void destroy() { }
+
+ @Override
+ public NativeWindow getParent() {
+ return null;
+ }
+
+ @Override
+ public long getWindowHandle() {
+ return nativeWindowHandle;
+ }
+
+ @Override
+ public InsetsImmutable getInsets() {
+ return insets;
+ }
+
+ @Override
+ public int getX() {
+ return 0;
+ }
+
+ @Override
+ public int getY() {
+ return 0;
+ }
+
+ @Override
+ public Point getLocationOnScreen(Point point) {
+ if( isOSX ) {
+ final Point los = OSXUtil.GetLocationOnScreen(nativeWindowHandle, false, 0, 0);
+ // top-level position -> client window position
+ los.setX(los.getX() + insets.getLeftWidth());
+ los.setY(los.getY() + insets.getTopHeight());
+ if(null!=point) {
+ return point.translate(los);
+ } else {
+ return los;
+ }
+ } else {
+ // client position on 'normal' windowing systems is 0/0
+ if(null == point) {
+ point = new Point(0, 0);
+ }
+ return point;
+ }
+ }
+
+ @Override
+ public boolean hasFocus() {
+ return isFocusControl();
+ }
+ };
+
+ static String newtWinHandleToHexString(Window w) {
+ return null != w ? toHexString(w.getWindowHandle()) : "nil";
+ }
+ static String toHexString(long l) {
+ return "0x"+Long.toHexString(l);
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
new file mode 100644
index 000000000..3538caad2
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright 2012 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.newt.swt;
+
+import org.eclipse.swt.widgets.Display;
+
+import com.jogamp.newt.util.EDTUtil;
+
+/**
+ * Simple {@link EDTUtil} implementation utilizing the SWT UI thread
+ * of the given {@link Display}.
+ */
+public class SWTEDTUtil implements EDTUtil {
+ private final Display swtDisplay;
+
+ public SWTEDTUtil(Display swtDisplay) {
+ this.swtDisplay = swtDisplay;
+ }
+
+ public final Display getDisplay() {
+ return swtDisplay;
+ }
+
+ @Override
+ public long getPollPeriod() {
+ return 0;
+ }
+
+ @Override
+ public void setPollPeriod(long ms) {
+ }
+
+ @Override
+ public void reset() {
+ }
+
+ @Override
+ public void start() {
+ }
+
+ @Override
+ public boolean isCurrentThreadEDT() {
+ return swtDisplay.getThread() == Thread.currentThread();
+ }
+
+ @Override
+ public boolean isRunning() {
+ return true;
+ }
+
+ @Override
+ public void invokeStop(Runnable finalTask) {
+ swtDisplay.syncExec(finalTask);
+ }
+
+ @Override
+ public void invoke(boolean wait, Runnable task) {
+ if(wait) {
+ swtDisplay.syncExec(task);
+ } else {
+ swtDisplay.asyncExec(task);
+ }
+ }
+
+ @Override
+ public void waitUntilIdle() {
+ // all sync ..
+ }
+
+ @Override
+ public void waitUntilStopped() {
+ // all sync ..
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index b10561c5b..b178bb5d3 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -101,7 +101,9 @@ public abstract class DisplayImpl extends Display {
display.hashCode = display.fqname.hashCode();
displayList.add(display);
}
- display.createEDTUtil();
+ if(null == display.edtUtil) {
+ display.setEDTUtil(null); // device's default if EDT is used, or null
+ }
if(DEBUG) {
System.err.println("Display.create() NEW: "+display+" "+getThreadName());
}
@@ -168,15 +170,45 @@ public abstract class DisplayImpl extends Display {
return true;
}
- protected void createEDTUtil() {
+ protected EDTUtil createEDTUtil() {
+ final EDTUtil def;
if(NewtFactory.useEDT()) {
- edtUtil = new DefaultEDTUtil(Thread.currentThread().getThreadGroup(), "Display-"+getFQName(), dispatchMessagesRunnable);
+ def = new DefaultEDTUtil(Thread.currentThread().getThreadGroup(), "Display-"+getFQName(), dispatchMessagesRunnable);
if(DEBUG) {
- System.err.println("Display.createNative("+getFQName()+") Create EDTUtil: "+edtUtil.getClass().getName());
+ System.err.println("Display.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName());
}
+ } else {
+ def = null;
}
+ return def;
}
+ @Override
+ public EDTUtil setEDTUtil(EDTUtil newEDTUtil) {
+ if(null == newEDTUtil) {
+ newEDTUtil = createEDTUtil();
+ }
+ if( newEDTUtil == edtUtil ) {
+ if(DEBUG) {
+ System.err.println("Display.setEDTUtil: "+newEDTUtil+" - keep!");
+ }
+ return null; // no change
+ }
+ final EDTUtil oldEDTUtil = edtUtil;
+ if(DEBUG) {
+ System.err.println("Display.setEDTUtil: "+oldEDTUtil+" -> "+newEDTUtil);
+ }
+ if(null != oldEDTUtil) {
+ stopEDT( new Runnable() { public void run() {} } );
+ // ready for restart ..
+ oldEDTUtil.waitUntilStopped();
+ oldEDTUtil.reset();
+ }
+ edtUtil = newEDTUtil;
+ return oldEDTUtil;
+ }
+
+ @Override
public final EDTUtil getEDTUtil() {
return edtUtil;
}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index b12e42680..606101ade 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -445,9 +445,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
protected abstract void closeNativeImpl();
/**
- * The native implementation must invoke {@link #focusChanged(boolean, boolean)}
- * to change the focus state, if <code>force == false</code>.
- * This may happen asynchronous within {@link #TIMEOUT_NATIVEWINDOW}.
+ * Async request which shall be performed within {@link #TIMEOUT_NATIVEWINDOW}.
+ * <p>
+ * If if <code>force == false</code> the native implementation
+ * may only request focus if not yet owner.</p>
+ * <p>
+ * {@link #focusChanged(boolean, boolean)} should be called
+ * to notify about the focus traversal.
+ * </p>
*
* @param force if true, bypass {@link #focusChanged(boolean, boolean)} and force focus request
*/
diff --git a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
index ce8ed7c49..747e2368e 100644
--- a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
+++ b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
@@ -34,6 +34,7 @@ import javax.media.nativewindow.NativeWindow;
import jogamp.newt.driver.DriverUpdatePosition;
+import com.jogamp.newt.Window;
import com.jogamp.newt.event.awt.AWTAdapter;
import com.jogamp.newt.event.awt.AWTWindowAdapter;
@@ -92,19 +93,20 @@ public class AWTParentWindowAdapter
if(DEBUG_IMPLEMENTATION) {
System.err.println("AWT: componentResized: "+comp);
}
- getNewtWindow().runOnEDTIfAvail(false, new Runnable() {
+ final Window newtWindow = getNewtWindow();
+ newtWindow.runOnEDTIfAvail(false, new Runnable() {
public void run() {
int cw = comp.getWidth();
int ch = comp.getHeight();
if( 0 < cw * ch ) {
- if( getNewtWindow().getWidth() != cw || getNewtWindow().getHeight() != ch ) {
- getNewtWindow().setSize(cw, ch);
- if(comp.isVisible() != getNewtWindow().isVisible()) {
- getNewtWindow().setVisible(comp.isVisible());
+ if( newtWindow.getWidth() != cw || newtWindow.getHeight() != ch ) {
+ newtWindow.setSize(cw, ch);
+ if(comp.isVisible() != newtWindow.isVisible()) {
+ newtWindow.setVisible(comp.isVisible());
}
}
- } else if(getNewtWindow().isVisible()) {
- getNewtWindow().setVisible(false);
+ } else if(newtWindow.isVisible()) {
+ newtWindow.setVisible(false);
}
}});
}
@@ -113,8 +115,9 @@ public class AWTParentWindowAdapter
if(DEBUG_IMPLEMENTATION) {
System.err.println("AWT: componentMoved: "+e);
}
- if(getNewtWindow().getDelegatedWindow() instanceof DriverUpdatePosition) {
- ((DriverUpdatePosition)getNewtWindow().getDelegatedWindow()).updatePosition();
+ final Window newtWindow = getNewtWindow();
+ if(newtWindow.getDelegatedWindow() instanceof DriverUpdatePosition) {
+ ((DriverUpdatePosition)newtWindow.getDelegatedWindow()).updatePosition();
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java b/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
index 166da5c1c..65f8b4715 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
@@ -36,6 +36,7 @@ package jogamp.newt.driver.awt;
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.util.EDTUtil;
import jogamp.newt.DisplayImpl;
@@ -54,13 +55,17 @@ public class AWTDisplay extends DisplayImpl {
protected void closeNativeImpl() { }
@Override
- protected void createEDTUtil() {
+ protected EDTUtil createEDTUtil() {
+ final EDTUtil def;
if(NewtFactory.useEDT()) {
- edtUtil = AWTEDTUtil.getSingleton();
+ def = AWTEDTUtil.getSingleton();
if(DEBUG) {
- System.err.println("AWTDisplay.createNative("+getFQName()+") Create EDTUtil: "+edtUtil.getClass().getName());
+ System.err.println("AWTDisplay.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName());
}
+ } else {
+ def = null;
}
+ return def;
}
protected void dispatchMessagesNative() { /* nop */ }
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
index 720d4ee4c..27d7a1679 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
@@ -150,7 +150,7 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
System.err.println("MacWindow: clearFocus() - requestFocusParent, isOffscreenInstance "+isOffscreenInstance);
}
if(!isOffscreenInstance) {
- requestFocusParent0(getWindowHandle());
+ resignFocus0(getWindowHandle());
} else {
focusChanged(false, false);
}
@@ -360,7 +360,6 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
if(recreate && 0==surfaceHandle) {
throw new NativeWindowException("Internal Error - recreate, window but no view");
}
- orderOut0(getWindowHandle());
close0(getWindowHandle());
setWindowHandle(0);
} else {
@@ -397,7 +396,7 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
private native boolean lockSurface0(long window);
private native void unlockSurface0(long window);
private native void requestFocus0(long window, boolean force);
- private native void requestFocusParent0(long window);
+ private native void resignFocus0(long window);
/** in case of a child window, it actually only issues orderBack(..) */
private native void orderOut0(long window);
private native void orderFront0(long window);
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
index 34d76a148..6a8c81f3d 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
@@ -151,8 +151,8 @@ public class WindowsWindow extends WindowImpl {
}
protected void closeNativeImpl() {
- if (hdc != 0) {
- if(windowHandleClose != 0) {
+ if(windowHandleClose != 0) {
+ if (hdc != 0) {
try {
GDI.ReleaseDC(windowHandleClose, hdc);
} catch (Throwable t) {
@@ -162,11 +162,8 @@ public class WindowsWindow extends WindowImpl {
}
}
}
- hdc = 0;
- hdc_old = 0;
- }
- if(windowHandleClose != 0) {
try {
+ GDI.SetParent(windowHandleClose, 0); // detach first, experience hang w/ SWT parent
GDI.DestroyWindow(windowHandleClose);
} catch (Throwable t) {
if(DEBUG_IMPLEMENTATION) {
@@ -177,6 +174,8 @@ public class WindowsWindow extends WindowImpl {
windowHandleClose = 0;
}
}
+ hdc = 0;
+ hdc_old = 0;
}
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {