summaryrefslogtreecommitdiffstats
path: root/src/newt/classes/com/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-07-25 04:23:35 +0200
committerSven Gothel <[email protected]>2012-07-25 04:23:35 +0200
commit7bb5885fc3a904f49e22f0c8cbf747d9b189a7ba (patch)
treee5617fa74ff4a401fa60a080c5b3e8cf4ee21233 /src/newt/classes/com/jogamp
parent00bef95008b02cc71e166da122884402e9381f44 (diff)
SWT Update: SWT GLCanvas creates lazy when resource is ready; Create new NewtCanvasSWT allowing to parent NEWT windows natively.
SWT GLCanvas creates lazy when resource is ready - Ensures drawable and context are created when size > zero and native visualID is valid. The latter is platform dependent. - Note that you cannot utilize custom GLCapabilities w/ this one, since the configurations is already realized - use NewtCanvasSWT. Create new NewtCanvasSWT allowing to parent NEWT windows natively: - Similar to NewtCanvasAWT - Allows attaching / detaching NEWT windows NewtCanvasAWT: Public setNEWTChild(..) fixed Added test cases for the above - tested on Linux, OSX and Windows w/ SWT Note: As usual for OSX, add -XstartOnFirstThread Details: - NEWT Display has new method: 'EDTUtil setEDTUtil(EDTUtil)' allowing to set a custom event dispatch utility. We use this to set our SWTEDTUtil for using NEWT w/ SWT complying w/ SWT threading constraints.
Diffstat (limited to 'src/newt/classes/com/jogamp')
-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
5 files changed, 678 insertions, 21 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 ..
+ }
+}