summaryrefslogtreecommitdiffstats
path: root/src/newt/classes/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/classes/com')
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java12
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java95
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java314
-rw-r--r--src/newt/classes/com/jogamp/newt/util/EDTUtil.java5
4 files changed, 62 insertions, 364 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index e97dec88d..993aa33eb 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -158,19 +158,15 @@ public abstract class Display {
* </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.
+ * it's being stopped, wait-until-idle and reset to allow a restart at a later time.
* </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.
+ * no change is being made.
* </p>
* <p>
- * Note that <code>newEDTUtil</code> will not be started if not done so already,
- * to do so you may issue {@link EDTUtil#invoke(boolean, Runnable) invoke}
- * on the new EDTUtil:
- * <pre>
- * newEDTUtil.invoke(true, new Runnable() { public void run() { } } );
- * </pre>
+ * Note that <code>newEDTUtil</code> will be started by this method,
+ * if it is not running yet.
* </p>
*/
public abstract EDTUtil setEDTUtil(EDTUtil newEDTUtil);
diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
index 525225804..dbe7c0d98 100644
--- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
+++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
@@ -26,7 +26,6 @@
* or implied, of JogAmp Community.
*/
-
package com.jogamp.newt.swt;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
@@ -44,18 +43,18 @@ import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
+import javax.media.opengl.GLCapabilities;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.newt.Debug;
+import jogamp.newt.swt.SWTEDTUtil;
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 org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.newt.Display;
@@ -65,6 +64,9 @@ import com.jogamp.newt.util.EDTUtil;
/**
* SWT {@link Canvas} containing a NEWT {@link Window} using native parenting.
+ * <p>
+ * Implementation allows use of custom {@link GLCapabilities}.
+ * </p>
*/
public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("Window");
@@ -77,6 +79,8 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
private volatile SWTNativeWindow nativeWindow;
private volatile Window newtChild = null;
+ private volatile boolean newtChildReady = false; // ready if SWTEDTUtil is set and newtChild parented
+ private volatile boolean postSetSize = false; // pending resize
/**
* Creates an instance using {@link #NewtCanvasSWT(Composite, int, Window)}
@@ -122,45 +126,51 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
clientArea = getClientArea();
final AbstractGraphicsDevice device = SWTAccessor.getDevice(this);
- screen = SWTAccessor.getScreen(device, 0);
+ screen = SWTAccessor.getScreen(device, -1 /* default */);
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() {
+
+ final Listener listener = new Listener () {
@Override
- public void paintControl(final PaintEvent arg0) {
- if( null != nativeWindow || validateNative() ) {
- if( null !=newtChild ) {
- newtChild.windowRepaint(0, 0, clientArea.width, clientArea.height);
+ public void handleEvent (Event event) {
+ switch (event.type) {
+ case SWT.Paint:
+ if( null != nativeWindow || validateNative() ) {
+ if( newtChildReady ) {
+ if( postSetSize ) {
+ newtChild.setSize(clientArea.width, clientArea.height);
+ postSetSize = false;
+ }
+ newtChild.windowRepaint(0, 0, clientArea.width, clientArea.height);
+ }
}
+ break;
+ case SWT.Resize:
+ updateSizeCheck();
+ break;
+ case SWT.Dispose:
+ NewtCanvasSWT.this.dispose();
+ break;
}
}
- });
-
- addControlListener(new ControlAdapter() {
- @Override
- public void controlResized(final ControlEvent arg0) {
- updateSizeCheck();
- }
- });
+ };
+ addListener (SWT.Resize, listener);
+ addListener (SWT.Paint, listener);
+ addListener (SWT.Dispose, listener);
}
/** assumes nativeWindow == null ! */
protected final boolean validateNative() {
- if( isDisposed() ) {
- return false;
- }
updateSizeCheck();
final Rectangle nClientArea = clientArea;
if(0 >= nClientArea.width || 0 >= nClientArea.height) {
return false;
}
-
+ screen.getDevice().open();
+
/* Native handle for the control, used to associate with GLContext */
final long nativeWindowHandle = SWTAccessor.getWindowHandle(this);
final int visualID = SWTAccessor.getNativeVisualID(screen.getDevice(), nativeWindowHandle);
@@ -196,12 +206,18 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
( nClientArea.width != oClientArea.width || nClientArea.height != oClientArea.height )
) {
clientArea = nClientArea; // write back new value
- if( null != newtChild ) {
+ if(DEBUG) {
+ final long nsh = newtChildReady ? newtChild.getSurfaceHandle() : 0;
+ System.err.println("NewtCanvasSWT.sizeChanged: ("+Thread.currentThread().getName()+"): newtChildReady "+newtChildReady+", "+nClientArea.x+"/"+nClientArea.y+" "+nClientArea.width+"x"+nClientArea.height+" - surfaceHandle 0x"+Long.toHexString(nsh));
+ }
+ if( newtChildReady ) {
newtChild.setSize(clientArea.width, clientArea.height);
+ } else {
+ postSetSize = true;
}
}
}
-
+
@Override
public void update() {
// don't paint background etc .. nop avoids flickering
@@ -230,6 +246,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
newtChild.destroy();
newtChild = null;
}
+ screen.getDevice().close();
nativeWindow = null;
super.dispose();
}
@@ -238,11 +255,11 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
public NativeWindow getNativeWindow() { return nativeWindow; }
public WindowClosingMode getDefaultCloseOperation() {
- return newtChildCloseOp; // FIXME
+ return newtChildCloseOp; // TODO: implement ?!
}
public WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) {
- return newtChildCloseOp = op; // FIXME
+ return newtChildCloseOp = op; // TODO: implement ?!
}
@@ -299,7 +316,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
}
/* package */ void configureNewtChild(boolean attach) {
-
+ newtChildReady = attach;
if( null != newtChild ) {
newtChild.setKeyboardFocusHandler(null);
if(attach) {
@@ -324,23 +341,21 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
updateSizeCheck();
final int w = clientArea.width;
final int h = clientArea.height;
-
+
// set SWT EDT and start it
{
final Display newtDisplay = newtChild.getScreen().getDisplay();
- final EDTUtil edt = new SWTEDTUtil(newtDisplay, getDisplay());
- newtDisplay.setEDTUtil(edt);
- edt.invoke(true, new Runnable() { public void run() { } } ); // start EDT
+ newtDisplay.setEDTUtil( new SWTEDTUtil(newtDisplay, getDisplay()) );
}
- newtChild.setSize(w, h);
+ newtChild.setSize(w, h);
newtChild.reparentWindow(nativeWindow);
newtChild.setVisible(true);
- configureNewtChild(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).
+ // since it is completely covered by the newtChild (z-order).
setEnabled(true);
} else {
configureNewtChild(false);
@@ -353,7 +368,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
}
private final void requestFocusNEWTChild() {
- if( null != newtChild ) {
+ if( newtChildReady ) {
newtChild.setFocusAction(null);
newtChild.requestFocus();
}
diff --git a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
deleted file mode 100644
index 42e1c9be5..000000000
--- a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/**
- * 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 java.awt.EventQueue;
-
-import javax.media.nativewindow.NativeWindowException;
-
-import jogamp.newt.Debug;
-
-import com.jogamp.common.util.RunnableTask;
-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 {
- public static final boolean DEBUG = Debug.debug("EDT");
-
- private final Object edtLock = new Object(); // locking the EDT start/stop state
- private final ThreadGroup threadGroup;
- private final String name;
- private final Runnable dispatchMessages;
- private final org.eclipse.swt.widgets.Display swtDisplay;
- private NewtEventDispatchThread nedt = null;
- private int start_iter=0;
- private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
-
- public SWTEDTUtil(final com.jogamp.newt.Display newtDisplay, org.eclipse.swt.widgets.Display swtDisplay) {
- this.threadGroup = Thread.currentThread().getThreadGroup();
- this.name=Thread.currentThread().getName()+"-SWTDisplay-"+newtDisplay.getFQName()+"-EDT-";
- this.dispatchMessages = new Runnable() {
- public void run() {
- ((jogamp.newt.DisplayImpl) newtDisplay).dispatchMessages();
- } };
- this.swtDisplay = swtDisplay;
- this.nedt = new NewtEventDispatchThread(threadGroup, name);
- this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
- }
-
- public final org.eclipse.swt.widgets.Display getDisplay() {
- return swtDisplay;
- }
-
- @Override
- public long getPollPeriod() {
- return pollPeriod;
- }
-
- @Override
- public void setPollPeriod(long ms) {
- pollPeriod = ms;
- }
-
- @Override
- public void reset() {
- synchronized(edtLock) {
- waitUntilStopped();
- if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt);
- }
- this.nedt = new NewtEventDispatchThread(threadGroup, name);
- this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
- }
- }
-
- private final void startImpl() {
- if(nedt.isAlive()) {
- throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
- }
- start_iter++;
- nedt.setName(name+start_iter);
- nedt.shouldStop = false;
- if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT START - edt: "+nedt);
- // Thread.dumpStack();
- }
- nedt.start();
- }
-
- @Override
- public boolean isCurrentThreadEDT() {
- return swtDisplay.getThread() == Thread.currentThread();
- }
-
- @Override
- public final boolean isCurrentThreadNEDT() {
- return nedt == Thread.currentThread();
- }
-
- @Override
- public final boolean isCurrentThreadEDTorNEDT() {
- final Thread ct = Thread.currentThread();
- return ct == swtDisplay.getThread() || ct == nedt ;
- }
-
- @Override
- public boolean isRunning() {
- return nedt.isRunning() ; // SWT is always running
- }
-
- @Override
- public final void invokeStop(Runnable task) {
- invokeImpl(true, task, true);
- }
-
- @Override
- public final void invoke(boolean wait, Runnable task) {
- invokeImpl(wait, task, false);
- }
-
- private void invokeImpl(boolean wait, Runnable task, boolean stop) {
- if(task == null) {
- throw new RuntimeException("Null Runnable");
- }
- Throwable throwable = null;
- RunnableTask rTask = null;
- Object rTaskLock = new Object();
- synchronized(rTaskLock) { // lock the optional task execution
- synchronized(edtLock) { // lock the EDT status
- if( nedt.shouldStop ) {
- // drop task ..
- if(DEBUG) {
- System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
- Thread.dumpStack();
- }
- return;
- }
- // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
- // Thread.dumpStack();
- if(stop) {
- nedt.shouldStop = true;
- if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
- // Thread.dumpStack();
- }
- }
- if( isCurrentThreadEDT() ) {
- task.run();
- wait = false; // running in same thread (EDT) -> no wait
- } else if( swtDisplay.isDisposed() ) {
- wait = false; // drop task, SWT disposed
- } else {
- // start if should not stop && not started yet
- if( !stop && !nedt.isRunning() ) {
- startImpl();
- }
- rTask = new RunnableTask(task,
- wait ? rTaskLock : null,
- true /* always catch and report Exceptions, don't disturb EDT */);
- swtDisplay.asyncExec(rTask);
- }
- }
- if( wait ) {
- try {
- rTaskLock.wait(); // free lock, allow execution of rTask
- } catch (InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
- }
- if(null!=throwable) {
- if(throwable instanceof NativeWindowException) {
- throw (NativeWindowException)throwable;
- }
- throw new RuntimeException(throwable);
- }
- }
- }
- }
-
- @Override
- final public void waitUntilIdle() {
- final NewtEventDispatchThread _nedt;
- synchronized(edtLock) {
- _nedt = nedt;
- }
- final Thread ct = Thread.currentThread();
- if(!_nedt.isRunning() || _nedt == ct || swtDisplay.getThread() == ct) {
- return;
- }
- try {
- swtDisplay.syncExec(new Runnable() {
- public void run() { }
- });
- } catch (Exception e) { }
- }
-
- @Override
- final public void waitUntilStopped() {
- synchronized(edtLock) {
- final Thread ct = Thread.currentThread();
- if(nedt.isRunning() && nedt != ct && swtDisplay.getThread() != ct) {
- while(nedt.isRunning()) {
- try {
- edtLock.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
-
- class NewtEventDispatchThread extends Thread {
- volatile boolean shouldStop = false;
- volatile boolean isRunning = false;
- Object sync = new Object();
-
- public NewtEventDispatchThread(ThreadGroup tg, String name) {
- super(tg, name);
- }
-
- final public boolean isRunning() {
- return isRunning;
- }
-
- @Override
- final public void start() throws IllegalThreadStateException {
- isRunning = true;
- super.start();
- }
-
- /**
- * Utilizing locking only on tasks and its execution,
- * not for event dispatching.
- */
- @Override
- final public void run() {
- if(DEBUG) {
- System.err.println(getName()+": EDT run() START "+ getName());
- }
- RuntimeException error = null;
- try {
- do {
- // event dispatch
- if(!shouldStop) {
- // EDT invoke thread is SWT-EDT,
- // hence dispatching is required to run on SWT-EDT as well.
- // Otherwise a deadlock may happen due to dispatched event's
- // triggering a locking action.
- if ( !swtDisplay.isDisposed() ) {
- swtDisplay.syncExec(dispatchMessages);
- } else {
- dispatchMessages.run();
- }
- }
- // wait
- synchronized(sync) {
- if(!shouldStop) {
- try {
- sync.wait(pollPeriod);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- } while(!shouldStop) ;
- } catch (Throwable t) {
- // handle errors ..
- shouldStop = true;
- if(t instanceof RuntimeException) {
- error = (RuntimeException) t;
- } else {
- error = new RuntimeException("Within EDT", t);
- }
- } finally {
- if(DEBUG) {
- System.err.println(getName()+": EDT run() END "+ getName()+", "+error);
- }
- synchronized(edtLock) {
- isRunning = !shouldStop;
- if(!isRunning) {
- edtLock.notifyAll();
- }
- }
- if(DEBUG) {
- System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error);
- }
- if(null!=error) {
- throw error;
- }
- } // finally
- } // run()
- } // EventDispatchThread
-
-}
diff --git a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
index 7e19d9de5..0183da592 100644
--- a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
@@ -113,7 +113,8 @@ public interface EDTUtil {
/**
* Append the final task to the EDT task queue,
- * signals EDT to stop and wait until stopped.<br>
+ * signals EDT to stop and wait until stopped.<br/>
+ * <code>task</code> maybe <code>null</code><br/>
* Due to the nature of this method:
* <ul>
* <li>All previous queued tasks will be finished.</li>
@@ -125,7 +126,7 @@ public interface EDTUtil {
public void invokeStop(Runnable finalTask);
/**
- * Shall start the thread if not running.<br>
+ * Shall start the thread if not running, <code>task</code> maybe null for this purpose.<br>
* Append task to the EDT task queue.<br>
* Wait until execution is finished if <code>wait == true</code>.<br>
* Can be issued from within EDT, ie from within an enqueued task.<br>