diff options
author | rhatcher <[email protected]> | 2012-12-06 11:48:05 -0600 |
---|---|---|
committer | rhatcher <[email protected]> | 2012-12-06 11:48:05 -0600 |
commit | 603609c54139ccb1791b10bef5672f22f030d6a4 (patch) | |
tree | b0c68726a4e6ecf45e1623c7f275b382725c567c /src/newt | |
parent | 811e3791b98fea0dfa3b7d301cb532c54df8dc82 (diff) | |
parent | 7a6f6b7a5b028e918a843de9fe16c38da75edba9 (diff) |
Merge branch 'master' of https://github.com/sgothel/jogl
Diffstat (limited to 'src/newt')
-rw-r--r-- | src/newt/classes/com/jogamp/newt/Display.java | 12 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java | 95 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/util/EDTUtil.java | 5 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/DefaultEDTUtil.java | 119 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/DisplayImpl.java | 33 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/WindowImpl.java | 81 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java | 37 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java | 14 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java (renamed from src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java) | 41 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java | 249 | ||||
-rw-r--r-- | src/newt/native/WindowsWindow.c | 19 |
11 files changed, 481 insertions, 224 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/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> diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java index 98987ef96..d8d04e79f 100644 --- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java +++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java @@ -81,10 +81,10 @@ public class DefaultEDTUtil implements EDTUtil { waitUntilStopped(); if(DEBUG) { if(edt.tasks.size()>0) { - System.err.println(Thread.currentThread()+": EDT reset, remaining tasks: "+edt.tasks.size()+" - "+edt); + System.err.println(Thread.currentThread()+": Default-EDT reset, remaining tasks: "+edt.tasks.size()+" - "+edt); // Thread.dumpStack(); } - System.err.println(Thread.currentThread()+": EDT reset - edt: "+edt); + System.err.println(Thread.currentThread()+": Default-EDT reset - edt: "+edt); } this.edt = new EventDispatchThread(threadGroup, name); this.edt.setDaemon(true); // don't stop JVM from shutdown .. @@ -93,13 +93,13 @@ public class DefaultEDTUtil implements EDTUtil { private final void startImpl() { if(edt.isAlive()) { - throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size()); + throw new RuntimeException("Default-EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size()); } start_iter++; edt.setName(name+start_iter); edt.shouldStop = false; if(DEBUG) { - System.err.println(Thread.currentThread()+": EDT START - edt: "+edt); + System.err.println(Thread.currentThread()+": Default-EDT START - edt: "+edt); // Thread.dumpStack(); } edt.start(); @@ -135,10 +135,12 @@ public class DefaultEDTUtil implements EDTUtil { invokeImpl(wait, task, false); } + private static Runnable nullTask = new Runnable() { + @Override + public void run() { } + }; + 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(); @@ -147,45 +149,57 @@ public class DefaultEDTUtil implements EDTUtil { if( edt.shouldStop ) { // drop task .. if(DEBUG) { - System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+edt); + System.err.println(Thread.currentThread()+": Warning: Default-EDT about (1) to stop, won't enqueue new task: "+edt); Thread.dumpStack(); } return; } // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task); // Thread.dumpStack(); - if(stop) { - edt.shouldStop = true; - if(DEBUG) { - System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - tasks: "+edt.tasks.size()+" - "+edt); - // Thread.dumpStack(); - } - } if( isCurrentThreadEDT() ) { - task.run(); + if(null != task) { + task.run(); + } wait = false; // running in same thread (EDT) -> no wait - if(stop && edt.tasks.size()>0) { - System.err.println("Warning: EDT about (2) to stop, having remaining tasks: "+edt.tasks.size()+" - "+edt); - if(DEBUG) { - Thread.dumpStack(); + if(stop) { + edt.shouldStop = true; + if( edt.tasks.size()>0 ) { + System.err.println(Thread.currentThread()+": Warning: Default-EDT about (2) to stop, task executed. Remaining tasks: "+edt.tasks.size()+" - "+edt); + if(DEBUG) { + Thread.dumpStack(); + } } } } else { - // start if should not stop && not started yet - if( !stop && !edt.isRunning() ) { - startImpl(); + if( !edt.isRunning() ) { + if( !stop ) { + startImpl(); + } else { + // drop task and don't wait + task = null; + System.err.println(Thread.currentThread()+": Warning: Default-EDT is about (3) to stop and stopped already, dropping task. Remaining tasks: "+edt.tasks.size()+" - "+edt); + if(true || DEBUG) { + Thread.dumpStack(); + } + } + } else if(stop && null == task) { + task = nullTask; } - synchronized(edt.tasks) { - wait = wait && edt.isRunning(); - rTask = new RunnableTask(task, - wait ? rTaskLock : null, - true /* always catch and report Exceptions, don't disturb EDT */); - if(stop) { - rTask.setAttachment(new Boolean(true)); // mark final task + + if(null != task) { + synchronized(edt.tasks) { + rTask = new RunnableTask(task, + wait ? rTaskLock : null, + true /* always catch and report Exceptions, don't disturb EDT */); + if(stop) { + rTask.setAttachment(new Boolean(true)); // mark final task, will imply shouldStop:=true + } + // append task .. + edt.tasks.add(rTask); + edt.tasks.notifyAll(); } - // append task .. - edt.tasks.add(rTask); - edt.tasks.notifyAll(); + } else { + wait = false; } } } @@ -207,7 +221,7 @@ public class DefaultEDTUtil implements EDTUtil { } } if(DEBUG && stop) { - System.err.println(Thread.currentThread()+": EDT signal STOP X edt: "+edt); + System.err.println(Thread.currentThread()+": Default-EDT signal STOP X edt: "+edt); } } @@ -282,7 +296,7 @@ public class DefaultEDTUtil implements EDTUtil { @Override final public void run() { if(DEBUG) { - System.err.println(getName()+": EDT run() START "+ getName()); + System.err.println(getName()+": Default-EDT run() START "+ getName()); } validateNoRecursiveLocksHold(); RuntimeException error = null; @@ -307,6 +321,9 @@ public class DefaultEDTUtil implements EDTUtil { if(tasks.size()>0) { task = tasks.remove(0); tasks.notifyAll(); + if( null != task.getAttachment() ) { + shouldStop = true; + } } } if(null!=task) { @@ -324,41 +341,19 @@ public class DefaultEDTUtil implements EDTUtil { if(t instanceof RuntimeException) { error = (RuntimeException) t; } else { - error = new RuntimeException("Within EDT", t); + error = new RuntimeException("Within Default-EDT", t); } } finally { if(DEBUG) { RunnableTask rt = ( tasks.size() > 0 ) ? tasks.get(0) : null ; - System.err.println(getName()+": EDT run() END "+ getName()+", tasks: "+tasks.size()+", "+rt+", "+error); + System.err.println(getName()+": Default-EDT run() END "+ getName()+", tasks: "+tasks.size()+", "+rt+", "+error); } synchronized(edtLock) { - if(null==error) { - synchronized(tasks) { - // drain remaining tasks (stop not on EDT), - // while having tasks and no previous-task, or previous-task is non final - RunnableTask task = null; - while ( ( null == task || task.getAttachment() == null ) && tasks.size() > 0 ) { - task = tasks.remove(0); - task.run(); - tasks.notifyAll(); - } - if(DEBUG) { - if(null!=task && task.getAttachment()==null) { - System.err.println(getName()+" Warning: EDT exit: Last task Not Final: "+tasks.size()+", "+task+" - "+edt); - } else if(tasks.size()>0) { - System.err.println(getName()+" Warning: EDT exit: Remaining tasks Post Final: "+tasks.size()); - } - Thread.dumpStack(); - } - } - } - isRunning = !shouldStop; - if(!isRunning) { - edtLock.notifyAll(); - } + isRunning = false; + edtLock.notifyAll(); } if(DEBUG) { - System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error); + System.err.println(getName()+": Default-EDT run() EXIT "+ getName()+", exception: "+error); } if(null!=error) { throw error; diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index 317535805..20b915cae 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -84,9 +84,8 @@ public abstract class DisplayImpl extends Display { display.hashCode = display.fqname.hashCode(); displayList.add(display); } - if(null == display.edtUtil) { - display.setEDTUtil(null); // device's default if EDT is used, or null - } + display.setEDTUtil(display.edtUtil); // device's default if EDT is used, or null + if(DEBUG) { System.err.println("Display.create() NEW: "+display+" "+getThreadName()); } @@ -166,20 +165,24 @@ public abstract class DisplayImpl extends Display { @Override public EDTUtil setEDTUtil(EDTUtil newEDTUtil) { + final EDTUtil oldEDTUtil = edtUtil; if(null == newEDTUtil) { - newEDTUtil = createEDTUtil(); - } else if( newEDTUtil == edtUtil ) { if(DEBUG) { - System.err.println("Display.setEDTUtil: "+newEDTUtil+" - keep!"); + System.err.println("Display.setEDTUtil(default): "+oldEDTUtil+" -> "+newEDTUtil); + } + edtUtil = createEDTUtil(); + } else if( newEDTUtil != edtUtil ) { + if(DEBUG) { + System.err.println("Display.setEDTUtil(custom): "+oldEDTUtil+" -> "+newEDTUtil); } - return null; // no change + removeEDT( null ); + edtUtil = newEDTUtil; + } else if( DEBUG ) { + System.err.println("Display.setEDTUtil: "+newEDTUtil+" - keep!"); } - final EDTUtil oldEDTUtil = edtUtil; - if(DEBUG) { - System.err.println("Display.setEDTUtil: "+oldEDTUtil+" -> "+newEDTUtil); + if( !edtUtil.isRunning() ) { // start EDT if not running yet + edtUtil.invoke(true, null); } - removeEDT( new Runnable() { public void run() {} } ); - edtUtil = newEDTUtil; return oldEDTUtil; } @@ -209,11 +212,7 @@ public abstract class DisplayImpl extends Display { public boolean validateEDT() { if(0==refCount && null==aDevice && null != edtUtil && edtUtil.isRunning()) { - removeEDT( new Runnable() { - public void run() { - // nop - } - } ); + removeEDT( null ); return true; } return false; diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 4f8eb3d3a..a9294c1ff 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -173,7 +173,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer window.parentWindowHandle = parentWindowHandle; window.screen = (ScreenImpl) screen; window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable(); - window.setUndecorated(0!=parentWindowHandle); window.instantiationFinished(); return window; } catch (Throwable t) { @@ -573,6 +572,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } finally { if (LOCK_SURFACE_NOT_READY >= res) { + surfaceLockCount--; _wlock.unlock(); } } @@ -729,8 +729,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } else if(WindowImpl.this.visible != visible) { if(isNativeValid()) { setVisibleImpl(visible, getX(), getY(), getWidth(), getHeight()); - WindowImpl.this.waitForVisible(visible, true); + WindowImpl.this.waitForVisible(visible, false); madeVisible = visible; + } else { + WindowImpl.this.visible = true; } } @@ -804,11 +806,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } else if ( visible && !isNativeValid() && 0 < width && 0 < height ) { visibleAction = 2; // visible (create) defineSize(width, height); - } else if ( isNativeValid() ) { + } else if ( visible && isNativeValid() ) { visibleAction = 0; // this width/height will be set by windowChanged, called by the native implementation reconfigureWindowImpl(getX(), getY(), width, height, getReconfigureFlags(0, isVisible())); + WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW); } else { + // invisible or invalid w/ 0 size visibleAction = 0; defineSize(width, height); } @@ -1045,8 +1049,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(null!=newParentWindowNEWT) { setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() ); } else { - Screen newScreen = NewtFactory.createCompatibleScreen(newParentWindow, getScreen()); - if( getScreen() != newScreen ) { + final Screen newScreen = NewtFactory.createCompatibleScreen(newParentWindow, screen); + if( screen != newScreen ) { // auto destroy on-the-fly created Screen/Display setScreen( (ScreenImpl) newScreen ); } @@ -1056,14 +1060,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } else { operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING; } - } else if ( forceDestroyCreate || !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) { + } else if ( forceDestroyCreate || !NewtFactory.isScreenCompatible(newParentWindow, screen) ) { // Destroy this window, may create a new compatible Screen/Display, // and mark it for creation. destroy(); if(null!=newParentWindowNEWT) { setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() ); } else { - setScreen( (ScreenImpl) NewtFactory.createCompatibleScreen(newParentWindow, getScreen()) ); + setScreen( (ScreenImpl) NewtFactory.createCompatibleScreen(newParentWindow, screen) ); } operation = ReparentOperation.ACTION_NATIVE_CREATION; } else { @@ -1078,7 +1082,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if( null != parentWindow ) { // child -> top // put client to current parent+child position - Point p = getLocationOnScreen(null); + final Point p = getLocationOnScreen(null); x = p.getX(); y = p.getY(); } @@ -1134,13 +1138,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if( ReparentOperation.ACTION_NATIVE_REPARENTING == operation ) { - DisplayImpl display = (DisplayImpl) screen.getDisplay(); + final DisplayImpl display = (DisplayImpl) screen.getDisplay(); display.dispatchMessagesNative(); // status up2date if(wasVisible) { setVisibleImpl(false, x, y, width, height); - WindowImpl.this.waitForVisible(false, true); - // some composite WM behave slacky .. give 'em chance to change state -> invisible, + WindowImpl.this.waitForVisible(false, false); + // FIXME: Some composite WM behave slacky .. give 'em chance to change state -> invisible, // even though we do exactly that (KDE+Composite) try { Thread.sleep(100); } catch (InterruptedException e) { } display.dispatchMessagesNative(); // status up2date @@ -1166,6 +1170,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer parentWindowLocked.unlockSurface(); } } + definePosition(x, y); // position might not get updated by WM events (SWT parent apparently) // set visible again if(ok) { @@ -1173,7 +1178,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(wasVisible) { setVisibleImpl(true, x, y, width, height); ok = WindowImpl.this.waitForVisible(true, false); - display.dispatchMessagesNative(); // status up2date if(ok) { ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW); } @@ -1202,7 +1206,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparentWindow: END-1 ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+x+"/"+y+" "+width+"x"+height); + System.err.println("Window.reparentWindow: END-1 ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); } } finally { _lock.unlock(); @@ -1223,7 +1227,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparentWindow: END-X ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+x+"/"+y+" "+width+"x"+height); + System.err.println("Window.reparentWindow: END-X ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); } } } @@ -1557,7 +1561,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer for (int i = 0; i < keyListeners.size(); i++ ) { sb.append(keyListeners.get(i)+", "); } - sb.append("], windowLock "+windowLock+"]"); + sb.append("], windowLock "+windowLock+", surfaceLockCount "+surfaceLockCount+"]"); return sb.toString(); } @@ -1566,15 +1570,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } public void runOnEDTIfAvail(boolean wait, final Runnable task) { - if(windowLock.isOwner(Thread.currentThread())) { + if( windowLock.isOwner( Thread.currentThread() ) ) { task.run(); } else { - Screen scrn = getScreen(); - if(null==scrn) { - throw new RuntimeException("Null screen of inner class: "+this); - } - DisplayImpl d = (DisplayImpl) scrn.getDisplay(); - d.runOnEDTIfAvail(wait, task); + ( (DisplayImpl) screen.getDisplay() ).runOnEDTIfAvail(wait, task); } } @@ -1899,7 +1898,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) { if(isNativeValid()) { - ((DisplayImpl)getScreen().getDisplay()).enqueueEvent(wait, event); + ((DisplayImpl)screen.getDisplay()).enqueueEvent(wait, event); } } @@ -1914,7 +1913,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer repaintQueued=true; final boolean discardTO = QUEUED_EVENT_TO <= System.currentTimeMillis()-e.getWhen(); if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.consumeEvent: "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO); + System.err.println("Window.consumeEvent: REPAINT "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO); // Thread.dumpStack(); } return discardTO; // discardTO:=true -> consumed @@ -1930,7 +1929,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if( null != windowLock.getOwner() ) { final boolean discardTO = QUEUED_EVENT_TO <= System.currentTimeMillis()-e.getWhen(); if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.consumeEvent: "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO); + System.err.println("Window.consumeEvent: RESIZED "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO); // Thread.dumpStack(); } return discardTO; // discardTO:=true -> consumed @@ -2430,10 +2429,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } private boolean waitForVisible(boolean visible, boolean failFast, long timeOut) { - DisplayImpl display = (DisplayImpl) screen.getDisplay(); + final DisplayImpl display = (DisplayImpl) screen.getDisplay(); + display.dispatchMessagesNative(); // status up2date for(long sleep = timeOut; 0<sleep && this.visible != visible; sleep-=10 ) { - display.dispatchMessagesNative(); // status up2date try { Thread.sleep(10); } catch (InterruptedException ie) {} + display.dispatchMessagesNative(); // status up2date } if(this.visible != visible) { final String msg = "Visibility not reached as requested within "+timeOut+"ms : requested "+visible+", is "+this.visible; @@ -2441,9 +2441,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer throw new NativeWindowException(msg); } else if (DEBUG_IMPLEMENTATION) { System.err.println(msg); + Thread.dumpStack(); } + return false; + } else { + return true; } - return this.visible == visible; } /** Triggered by implementation's WM events to update the client-area size w/o insets/decorations. */ @@ -2467,18 +2470,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } private boolean waitForSize(int w, int h, boolean failFast, long timeOut) { - DisplayImpl display = (DisplayImpl) screen.getDisplay(); - boolean reached = false; - for(long sleep = timeOut; !reached && 0<sleep; sleep-=10 ) { - if( w==getWidth() && h==getHeight() ) { - // reached pos/size - reached = true; - } else { - display.dispatchMessagesNative(); // status up2date - try { Thread.sleep(10); } catch (InterruptedException ie) {} - } + final DisplayImpl display = (DisplayImpl) screen.getDisplay(); + display.dispatchMessagesNative(); // status up2date + long sleep; + for(sleep = timeOut; 0<sleep && w!=getWidth() && h!=getHeight(); sleep-=10 ) { + try { Thread.sleep(10); } catch (InterruptedException ie) {} + display.dispatchMessagesNative(); // status up2date } - if(!reached) { + if(0 >= sleep) { final String msg = "Size/Pos not reached as requested within "+timeOut+"ms : requested "+w+"x"+h+", is "+getWidth()+"x"+getHeight(); if(failFast) { throw new NativeWindowException(msg); @@ -2486,8 +2485,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer System.err.println(msg); Thread.dumpStack(); } + return false; + } else { + return true; } - return reached; } /** Triggered by implementation's WM events to update the position. */ diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java index 2175f2190..27d0f3506 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java +++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java @@ -72,7 +72,7 @@ public class AWTEDTUtil implements EDTUtil { synchronized(edtLock) { waitUntilStopped(); if(DEBUG) { - System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt); + System.err.println(Thread.currentThread()+": AWT-EDT reset - edt: "+nedt); } this.nedt = new NewtEventDispatchThread(threadGroup, name); this.nedt.setDaemon(true); // don't stop JVM from shutdown .. @@ -81,13 +81,13 @@ public class AWTEDTUtil implements EDTUtil { private final void startImpl() { if(nedt.isAlive()) { - throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt); + throw new RuntimeException("AWT-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); + System.err.println(Thread.currentThread()+": AWT-EDT START - edt: "+nedt); // Thread.dumpStack(); } nedt.start(); @@ -124,9 +124,6 @@ public class AWTEDTUtil implements EDTUtil { } 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(); @@ -135,7 +132,7 @@ public class AWTEDTUtil implements EDTUtil { if( nedt.shouldStop ) { // drop task .. if(DEBUG) { - System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt); + System.err.println(Thread.currentThread()+": Warning: AWT-EDT about (1) to stop, won't enqueue new task: "+nedt); Thread.dumpStack(); } return; @@ -143,20 +140,24 @@ public class AWTEDTUtil implements EDTUtil { // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task); // Thread.dumpStack(); if(stop) { - nedt.shouldStop = true; + synchronized(nedt.sync) { + nedt.shouldStop = true; + nedt.sync.notifyAll(); // stop immediate if waiting (poll freq) + } if(DEBUG) { - System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt); + System.err.println(Thread.currentThread()+": AWT-EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt); // Thread.dumpStack(); } + } else if( !nedt.isRunning() ) { + // start if should not stop && not started yet + startImpl(); } - if( isCurrentThreadEDT() ) { + if( null == task ) { + wait = false; + } else if( isCurrentThreadEDT() ) { task.run(); wait = false; // running in same thread (EDT) -> no wait } 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 */); @@ -239,7 +240,7 @@ public class AWTEDTUtil implements EDTUtil { @Override final public void run() { if(DEBUG) { - System.err.println(getName()+": EDT run() START "+ getName()); + System.err.println(getName()+": AWT-EDT run() START "+ getName()); } RuntimeException error = null; try { @@ -269,11 +270,11 @@ public class AWTEDTUtil implements EDTUtil { if(t instanceof RuntimeException) { error = (RuntimeException) t; } else { - error = new RuntimeException("Within EDT", t); + error = new RuntimeException("Within AWT-EDT", t); } } finally { if(DEBUG) { - System.err.println(getName()+": EDT run() END "+ getName()+", "+error); + System.err.println(getName()+": AWT-EDT run() END "+ getName()+", "+error); } synchronized(edtLock) { isRunning = !shouldStop; @@ -282,7 +283,7 @@ public class AWTEDTUtil implements EDTUtil { } } if(DEBUG) { - System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error); + System.err.println(getName()+": AWT-EDT run() EXIT "+ getName()+", exception: "+error); } if(null!=error) { throw error; diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java index 6aac8617c..2ec88852c 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java @@ -71,13 +71,15 @@ public class WindowDriver extends WindowImpl { if (0 != hdc) { throw new InternalError("surface not released"); } - hdc = GDI.GetDC(getWindowHandle()); - hmon = MonitorFromWindow0(getWindowHandle()); + final long hWnd = getWindowHandle(); + hdc = GDI.GetDC(hWnd); // return ( 0 == hdc ) ? LOCK_SURFACE_NOT_READY : ( hdc_old != hdc ) ? LOCK_SURFACE_CHANGED : LOCK_SUCCESS ; if( 0 == hdc ) { return LOCK_SURFACE_NOT_READY; - } + } + hmon = MonitorFromWindow0(hWnd); + if( hdc_old == hdc ) { return LOCK_SUCCESS; } @@ -217,14 +219,14 @@ public class WindowDriver extends WindowImpl { @Override protected boolean setPointerVisibleImpl(final boolean pointerVisible) { - final Boolean[] res = new Boolean[] { Boolean.FALSE }; + final boolean[] res = new boolean[] { false }; this.runOnEDTIfAvail(true, new Runnable() { public void run() { - res[0] = Boolean.valueOf(setPointerVisible0(getWindowHandle(), pointerVisible)); + res[0] = setPointerVisible0(getWindowHandle(), pointerVisible); } }); - return res[0].booleanValue(); + return res[0]; } @Override diff --git a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java index 42e1c9be5..7297e5858 100644 --- a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java +++ b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java @@ -25,9 +25,7 @@ * 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; +package jogamp.newt.swt; import javax.media.nativewindow.NativeWindowException; @@ -83,7 +81,7 @@ public class SWTEDTUtil implements EDTUtil { synchronized(edtLock) { waitUntilStopped(); if(DEBUG) { - System.err.println(Thread.currentThread()+": EDT reset - edt: "+nedt); + System.err.println(Thread.currentThread()+": SWT-EDT reset - edt: "+nedt); } this.nedt = new NewtEventDispatchThread(threadGroup, name); this.nedt.setDaemon(true); // don't stop JVM from shutdown .. @@ -92,13 +90,13 @@ public class SWTEDTUtil implements EDTUtil { private final void startImpl() { if(nedt.isAlive()) { - throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt); + throw new RuntimeException("SWT-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); + System.err.println(Thread.currentThread()+": SWT-EDT START - edt: "+nedt); // Thread.dumpStack(); } nedt.start(); @@ -136,9 +134,6 @@ public class SWTEDTUtil implements EDTUtil { } 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(); @@ -147,7 +142,7 @@ public class SWTEDTUtil implements EDTUtil { if( nedt.shouldStop ) { // drop task .. if(DEBUG) { - System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt); + System.err.println(Thread.currentThread()+": Warning: SWT-EDT about (1) to stop, won't enqueue new task: "+nedt); Thread.dumpStack(); } return; @@ -155,22 +150,26 @@ public class SWTEDTUtil implements EDTUtil { // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task); // Thread.dumpStack(); if(stop) { - nedt.shouldStop = true; + synchronized(nedt.sync) { + nedt.shouldStop = true; + nedt.sync.notifyAll(); // stop immediate if waiting (poll freq) + } if(DEBUG) { - System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt); + System.err.println(Thread.currentThread()+": SWT-EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt); // Thread.dumpStack(); } + } else if( !nedt.isRunning() ) { + // start if should not stop && not started yet + startImpl(); } - if( isCurrentThreadEDT() ) { + if( null == task ) { + wait = false; + } else 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 */); @@ -255,7 +254,7 @@ public class SWTEDTUtil implements EDTUtil { @Override final public void run() { if(DEBUG) { - System.err.println(getName()+": EDT run() START "+ getName()); + System.err.println(getName()+": SWT-EDT run() START "+ getName()); } RuntimeException error = null; try { @@ -289,11 +288,11 @@ public class SWTEDTUtil implements EDTUtil { if(t instanceof RuntimeException) { error = (RuntimeException) t; } else { - error = new RuntimeException("Within EDT", t); + error = new RuntimeException("Within SWT-EDT", t); } } finally { if(DEBUG) { - System.err.println(getName()+": EDT run() END "+ getName()+", "+error); + System.err.println(getName()+": SWT-EDT run() END "+ getName()+", "+error); } synchronized(edtLock) { isRunning = !shouldStop; @@ -302,7 +301,7 @@ public class SWTEDTUtil implements EDTUtil { } } if(DEBUG) { - System.err.println(getName()+": EDT run() EXIT "+ getName()+", exception: "+error); + System.err.println(getName()+": SWT-EDT run() EXIT "+ getName()+", exception: "+error); } if(null!=error) { throw error; diff --git a/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java b/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java new file mode 100644 index 000000000..e238f5d9e --- /dev/null +++ b/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java @@ -0,0 +1,249 @@ +/** + * 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 jogamp.newt.swt.event; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; + +import com.jogamp.common.util.IntIntHashMap; +import com.jogamp.newt.event.InputEvent; + +/** + * SWT event translator to NEWT, inclusive dispatch listener. + * <p> + * <b>Disclaimer:</b> This code is merely tested and subject to change. + * </p> + */ +public class SWTNewtEventFactory { + + protected static final IntIntHashMap eventTypeSWT2NEWT; + + static { + IntIntHashMap map = new IntIntHashMap(); + map.setKeyNotFoundValue(0xFFFFFFFF); + + // map.put(SWT.MouseXXX, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED); + map.put(SWT.MouseDown, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED); + map.put(SWT.MouseUp, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED); + map.put(SWT.MouseMove, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_MOVED); + map.put(SWT.MouseEnter, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_ENTERED); + map.put(SWT.MouseExit, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_EXITED); + // map.put(SWT.MouseXXX, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED); + map.put(SWT.MouseVerticalWheel, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_WHEEL_MOVED); + + map.put(SWT.KeyDown, com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED); + map.put(SWT.KeyUp, com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED); + // map.put(SWT.KeyXXX, com.jogamp.newt.event.KeyEvent.EVENT_KEY_TYPED); + + eventTypeSWT2NEWT = map; + } + + public static final int swtModifiers2Newt(int awtMods, boolean mouseHint) { + int newtMods = 0; + if ((awtMods & SWT.SHIFT) != 0) newtMods |= com.jogamp.newt.event.InputEvent.SHIFT_MASK; + if ((awtMods & SWT.CTRL) != 0) newtMods |= com.jogamp.newt.event.InputEvent.CTRL_MASK; + if ((awtMods & SWT.ALT) != 0) newtMods |= com.jogamp.newt.event.InputEvent.ALT_MASK; + return newtMods; + } + + public static final com.jogamp.newt.event.InputEvent createInputEvent(org.eclipse.swt.widgets.Event event, Object source) { + com.jogamp.newt.event.InputEvent res = createMouseEvent(event, source); + if(null == res) { + res = createKeyEvent(event, source); + } + return res; + } + + public static final com.jogamp.newt.event.MouseEvent createMouseEvent(org.eclipse.swt.widgets.Event event, Object source) { + switch(event.type) { + case SWT.MouseDown: + case SWT.MouseUp: + case SWT.MouseMove: + case SWT.MouseEnter: + case SWT.MouseExit: + case SWT.MouseVerticalWheel: + break; + default: + return null; + } + int type = eventTypeSWT2NEWT.get(event.type); + if(0xFFFFFFFF != type) { + int rotation = 0; + if (SWT.MouseVerticalWheel == event.type) { + // SWT/NEWT rotation is reversed - AWT +1 is down, NEWT +1 is up. + // rotation = -1 * (int) event.rotation; + rotation = (int) event.rotation; + } + + int mods = swtModifiers2Newt(event.stateMask, true); + + if( source instanceof com.jogamp.newt.Window) { + final com.jogamp.newt.Window newtSource = (com.jogamp.newt.Window)source; + if(newtSource.isPointerConfined()) { + mods |= InputEvent.CONFINED_MASK; + } + if(!newtSource.isPointerVisible()) { + mods |= InputEvent.INVISIBLE_MASK; + } + } + + return new com.jogamp.newt.event.MouseEvent( + type, (null==source)?(Object)event.data:source, (0xFFFFFFFFL & (long)event.time), + mods, event.x, event.y, event.count, event.button, rotation); + } + return null; // no mapping .. + } + + public static final com.jogamp.newt.event.KeyEvent createKeyEvent(org.eclipse.swt.widgets.Event event, Object source) { + switch(event.type) { + case SWT.KeyDown: + case SWT.KeyUp: + break; + default: + return null; + } + int type = eventTypeSWT2NEWT.get(event.type); + if(0xFFFFFFFF != type) { + return new com.jogamp.newt.event.KeyEvent( + type, (null==source)?(Object)event.data:source, (0xFFFFFFFFL & (long)event.time), + swtModifiers2Newt(event.stateMask, false), + event.keyCode, event.character); + } + return null; // no mapping .. + } + + // + // + // + + int dragButtonDown = 0; + + public SWTNewtEventFactory() { + resetButtonsDown(); + } + + final void resetButtonsDown() { + dragButtonDown = 0; + } + + public final boolean dispatchMouseEvent(org.eclipse.swt.widgets.Event event, Object source, com.jogamp.newt.event.MouseListener l) { + com.jogamp.newt.event.MouseEvent res = createMouseEvent(event, source); + if(null != res) { + if(null != l) { + switch(event.type) { + case SWT.MouseDown: + dragButtonDown = event.button; + l.mousePressed(res); break; + case SWT.MouseUp: + dragButtonDown = 0; + l.mouseReleased(res); + { + final com.jogamp.newt.event.MouseEvent res2 = new com.jogamp.newt.event.MouseEvent( + com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED, + res.getSource(), + res.getWhen(), res.getModifiers(), + res.getX(), res.getY(), res.getClickCount(), + res.getButton(), res.getWheelRotation() ); + l.mouseClicked(res2); + } + break; + case SWT.MouseMove: + if( 0 < dragButtonDown ) { + final com.jogamp.newt.event.MouseEvent res2 = new com.jogamp.newt.event.MouseEvent( + com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED, + res.getSource(), + res.getWhen(), res.getModifiers(), + res.getX(), res.getY(), res.getClickCount(), + dragButtonDown, res.getWheelRotation() ); + l.mouseDragged( res2 ); + } else { + l.mouseMoved(res); + } + break; + case SWT.MouseEnter: + l.mouseEntered(res); + break; + case SWT.MouseExit: + resetButtonsDown(); + l.mouseExited(res); + break; + case SWT.MouseVerticalWheel: + l.mouseWheelMoved(res); + break; + } + } + return true; + } + return false; + } + + public final boolean dispatchKeyEvent(org.eclipse.swt.widgets.Event event, Object source, com.jogamp.newt.event.KeyListener l) { + com.jogamp.newt.event.KeyEvent res = createKeyEvent(event, source); + if(null != res) { + if(null != l) { + switch(event.type) { + case SWT.KeyDown: + l.keyPressed(res); + break; + case SWT.KeyUp: + l.keyReleased(res); + l.keyTyped(res); + break; + } + } + return true; + } + return false; + } + + public final void attachDispatchListener(final org.eclipse.swt.widgets.Control ctrl, final Object source, + final com.jogamp.newt.event.MouseListener ml, + final com.jogamp.newt.event.KeyListener kl) { + final Listener listener = new Listener () { + @Override + public void handleEvent (Event event) { + if( dispatchMouseEvent( event, source, ml ) ) { + return; + } + if( dispatchKeyEvent( event, source, kl ) ) { + return; + } + } }; + ctrl.addListener(SWT.MouseDown, listener); + ctrl.addListener(SWT.MouseUp, listener); + ctrl.addListener(SWT.MouseMove, listener); + ctrl.addListener(SWT.MouseEnter, listener); + ctrl.addListener(SWT.MouseExit, listener); + ctrl.addListener(SWT.MouseVerticalWheel, listener); + ctrl.addListener(SWT.KeyDown, listener); + ctrl.addListener(SWT.KeyUp, listener); + } +} + diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index e3d5cffa0..e7b454580 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -1034,23 +1034,22 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP case WM_PAINT: { RECT r; useDefWindowProc = 0; - if (GetUpdateRect(wnd, &r, TRUE /* erase background */)) { - /* - jint width = r.right-r.left; - jint height = r.bottom-r.top; - if (width > 0 && height > 0) { - (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, r.left, r.top, width, height); - } - ValidateRect(wnd, &r); - */ + if (GetUpdateRect(wnd, &r, FALSE /* do not erase background */)) { + // clear the whole client area and issue repaint for it, w/o looping through erase background + ValidateRect(wnd, NULL); // clear all! + (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1); + } else { + // shall not happen ? + ValidateRect(wnd, NULL); // clear all! } + // return 0 == done break; } case WM_ERASEBKGND: // ignore erase background (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1); useDefWindowProc = 0; - res = 1; // OpenGL, etc .. erases the background, hence we claim to have just done this + res = 1; // return 1 == done, OpenGL, etc .. erases the background, hence we claim to have just done this break; |