aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2015-09-15 07:50:50 +0200
committerSven Gothel <[email protected]>2015-09-15 07:50:50 +0200
commit68c8e39fa8d6e700f0a99241c1a01a435b7f6284 (patch)
treed02cf789a06514da205f6da8a45f55538b019a0b /src/newt
parentcf9b31c30de3768447b20d6aa31ec1df00595871 (diff)
Bug 1211: Hardening Condition-Wait from Spurious-Wakeups and unintended InterruptedException(s)
Below is an updated list of Condition-Wait classifications as described in Bug 1211. This list includes recent changes on GlueGen regarding this Bug 1211. A followup commit will address the unit tests. - Noncancelable + Persistent-Wait - GLMediaPlayerImpl.StreamWorker thread (changed) - pauses thread in case of intr - Cancelable + Persistent-Wait: - LFRingbuffer.getImpl(..) - LFRingbuffer.waitForFreeSlots(int) - SyncedRingbuffer.getImpl(..) - SyncedRingbuffer.waitForFreeSlots(int) - FunctionTask.invokeOnNewThread(..) (changed) - RunnableTask.invokeOnNewThread(..) (changed) - SharedResourceRunner.run() - SharedResourceRunner.doAndWait() (changed) - SharedResourceRunner.start() (changed) - SharedResourceRunner.stop() (changed) - GLMediaPlayerImpl.StreamWorker ctor (changed) - GLMediaPlayerImpl caller thread actions do*() (changed) - AndroidGLMediaPlayerAPI14.getNextTextureImpl(..) (changed) - DisplayImpl.enqueueEvent(..) (changed) -> Persistent-Wait -> Cancels wait and NEWTEvent -> dispatchMessage(NEWTEventTask): always notifyCaller! - GLDrawableHelper.invoke(..) (changed) - DefaultEDTUtil.waitUntilIdle() (changed) - DefaultEDTUtil.waitUntilStopped() (changed) - DefaultEDTUtil.invokeImpl(..) (changed) - DefaultEDTUtil.NEDT.run(..) (changed) - AWTEDTUtil.waitUntilStopped(..) (changed) - AWTEDTUtil.invokeImpl(..) (changed) - AWTEDTUtil.NEDT.run(..) (changed) - SWTEDTUtil.invokeImpl(..) (changed) - SWTEDTUtil.waitUntilStopped(..) (changed) - SWTEDTUtil.NEDT.run(..) (changed) - GLWorkerThread.invokeAndWait(..) - GLWorkerThread.start() (changed) - GLWorkerThread.WorkerRunnable.run() (changed) - Animator.run() (changed) - AnimatorBase.finishLifecycleAction() (changed) - OSXUtil.RunOnMainThread(..) (changed) - SingletonInstanceServerSocket.Server.shutdown() (changed) - SingletonInstanceServerSocket.Server.start() (changed) - com.jogamp.audio.windows.waveout.Mixer.shutdown() (changed) - Extending/Using InterruptSource.Thread (changed) - DefaultEDTUtil.NEDT - AWTEDTUtil.NEDT - SWTEDTUtil.NEDT - GLWorkerThread.thread - Mixer.FillerThread - Mixer.MixerThread - Using InterruptSource.Thread (changed) - TempFileCache - LauncherTempFileCache - Animator.thread - SingletonInstanceServerSocket.Server.serverThread Deprecated: - FunctionTask.invoke(..) (changed) -> on current thread, no wait -> deprecated - RunnableTask.invoke(..) (changed) -> on current thread, no wait -> deprecated
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/util/NEWTDemoListener.java499
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MainThread.java20
-rw-r--r--src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java93
-rw-r--r--src/newt/classes/jogamp/newt/DefaultEDTUtil.java45
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java14
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java35
-rw-r--r--src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java5
-rw-r--r--src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java3
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java3
-rw-r--r--src/newt/classes/jogamp/newt/event/NEWTEventTask.java8
-rw-r--r--src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java33
11 files changed, 604 insertions, 154 deletions
diff --git a/src/newt/classes/com/jogamp/newt/opengl/util/NEWTDemoListener.java b/src/newt/classes/com/jogamp/newt/opengl/util/NEWTDemoListener.java
new file mode 100644
index 000000000..ca4b51192
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/opengl/util/NEWTDemoListener.java
@@ -0,0 +1,499 @@
+/**
+ * Copyright 2015 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.opengl.util;
+
+import java.net.URLConnection;
+
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.nativewindow.CapabilitiesImmutable;
+import com.jogamp.nativewindow.ScalableSurface;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Display.PointerIcon;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.FPSCounter;
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GLAnimatorControl;
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLRunnable;
+import com.jogamp.opengl.util.Gamma;
+import com.jogamp.opengl.util.PNGPixelRect;
+
+import jogamp.newt.driver.PNGIcon;
+
+public class NEWTDemoListener extends WindowAdapter implements KeyListener, MouseListener {
+ protected final GLWindow glWindow;
+ final PointerIcon[] pointerIcons;
+ int pointerIconIdx = 0;
+ float gamma = 1f;
+ float brightness = 0f;
+ float contrast = 1f;
+ boolean confinedFixedCenter = false;
+
+ public NEWTDemoListener(final GLWindow glWin, final PointerIcon[] pointerIcons) {
+ this.glWindow = glWin;
+ if( null != pointerIcons ) {
+ this.pointerIcons = pointerIcons;
+ } else {
+ this.pointerIcons = createPointerIcons(glWindow);
+ }
+ }
+ public NEWTDemoListener(final GLWindow glWin) {
+ this(glWin, null);
+ }
+
+ protected void printlnState(final String prelude) {
+ System.err.println(prelude+": "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()+", state "+glWindow.getStateMaskString());
+ }
+ protected void printlnState(final String prelude, final String post) {
+ System.err.println(prelude+": "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()+", state "+glWindow.getStateMaskString()+", "+post);
+ }
+
+ @Override
+ public void keyPressed(final KeyEvent e) {
+ if( e.isAutoRepeat() || e.isConsumed() ) {
+ return;
+ }
+ final int keySymbol = e.getKeySymbol();
+ switch(keySymbol) {
+ case KeyEvent.VK_SPACE:
+ e.setConsumed(true);
+ glWindow.invokeOnCurrentThread(new Runnable() {
+ public void run() {
+ if(glWindow.getAnimator().isPaused()) {
+ glWindow.getAnimator().resume();
+ } else {
+ glWindow.getAnimator().pause();
+ }
+ } } );
+ break;
+ case KeyEvent.VK_A:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ printlnState("[set alwaysontop pre]");
+ glWindow.setAlwaysOnTop(!glWindow.isAlwaysOnTop());
+ printlnState("[set alwaysontop post]");
+ } } );
+ break;
+ case KeyEvent.VK_B:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ printlnState("[set alwaysonbottom pre]");
+ glWindow.setAlwaysOnBottom(!glWindow.isAlwaysOnBottom());
+ printlnState("[set alwaysonbottom post]");
+ } } );
+ break;
+ case KeyEvent.VK_C:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ if( null != pointerIcons ) {
+ printlnState("[set pointer-icon pre]");
+ final PointerIcon currentPI = glWindow.getPointerIcon();
+ final PointerIcon newPI;
+ if( pointerIconIdx >= pointerIcons.length ) {
+ newPI=null;
+ pointerIconIdx=0;
+ } else {
+ newPI=pointerIcons[pointerIconIdx++];
+ }
+ glWindow.setPointerIcon( newPI );
+ printlnState("[set pointer-icon post]", currentPI+" -> "+glWindow.getPointerIcon());
+ }
+ } } );
+ break;
+ case KeyEvent.VK_D:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ printlnState("[set undecorated pre]");
+ glWindow.setUndecorated(!glWindow.isUndecorated());
+ printlnState("[set undecorated post]");
+ } } );
+ break;
+ case KeyEvent.VK_F:
+ e.setConsumed(true);
+ quitAdapterOff();
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ printlnState("[set fullscreen pre]");
+ if( glWindow.isFullscreen() ) {
+ glWindow.setFullscreen( false );
+ } else {
+ if( e.isAltDown() ) {
+ glWindow.setFullscreen( null );
+ } else {
+ glWindow.setFullscreen( true );
+ }
+ }
+ printlnState("[set fullscreen post]");
+ quitAdapterOn();
+ } } );
+ break;
+ case KeyEvent.VK_G:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ final float newGamma = gamma + ( e.isShiftDown() ? -0.1f : 0.1f );
+ System.err.println("[set gamma]: "+gamma+" -> "+newGamma);
+ if( Gamma.setDisplayGamma(glWindow, newGamma, brightness, contrast) ) {
+ gamma = newGamma;
+ }
+ } } );
+ break;
+ case KeyEvent.VK_I:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ printlnState("[set pointer-visible pre]");
+ glWindow.setPointerVisible(!glWindow.isPointerVisible());
+ printlnState("[set pointer-visible post]");
+ } } );
+ break;
+ case KeyEvent.VK_J:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ printlnState("[set pointer-confined pre]", "warp-center: "+e.isShiftDown());
+ final boolean confine = !glWindow.isPointerConfined();
+ glWindow.confinePointer(confine);
+ printlnState("[set pointer-confined post]", "warp-center: "+e.isShiftDown());
+ if( e.isShiftDown() ) {
+ setConfinedFixedCenter(confine);
+ } else if( !confine ) {
+ setConfinedFixedCenter(false);
+ }
+ } } );
+ break;
+ case KeyEvent.VK_M:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ // none: max-v
+ // alt: max-h
+ // shift: max-hv
+ // ctrl: max-off
+ final boolean horz, vert;
+ if( e.isControlDown() ) {
+ horz = false;
+ vert = false;
+ } else if( e.isShiftDown() ) {
+ final boolean bothMax = glWindow.isMaximizedHorz() && glWindow.isMaximizedVert();
+ horz = !bothMax;
+ vert = !bothMax;
+ } else if( !e.isAltDown() ) {
+ horz = glWindow.isMaximizedHorz();
+ vert = !glWindow.isMaximizedVert();
+ } else if( e.isAltDown() ) {
+ horz = !glWindow.isMaximizedHorz();
+ vert = glWindow.isMaximizedVert();
+ } else {
+ vert = glWindow.isMaximizedVert();
+ horz = glWindow.isMaximizedHorz();
+ }
+ printlnState("[set maximize pre]", "max[vert "+vert+", horz "+horz+"]");
+ glWindow.setMaximized(horz, vert);
+ printlnState("[set maximize post]", "max[vert "+vert+", horz "+horz+"]");
+ } } );
+ break;
+ case KeyEvent.VK_Q:
+ if( quitAdapterEnabled && 0 == e.getModifiers() ) {
+ System.err.println("QUIT Key "+Thread.currentThread());
+ quitAdapterShouldQuit = true;
+ }
+ break;
+ case KeyEvent.VK_P:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ printlnState("[set position pre]");
+ glWindow.setPosition(100, 100);
+ printlnState("[set position post]");
+ } } );
+ break;
+ case KeyEvent.VK_R:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ printlnState("[set resizable pre]");
+ glWindow.setResizable(!glWindow.isResizable());
+ printlnState("[set resizable post]");
+ } } );
+ break;
+ case KeyEvent.VK_S:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ printlnState("[set sticky pre]");
+ glWindow.setSticky(!glWindow.isSticky());
+ printlnState("[set sticky post]");
+ } } );
+ break;
+ case KeyEvent.VK_V:
+ e.setConsumed(true);
+ if( e.isControlDown() ) {
+ glWindow.invoke(false, new GLRunnable() {
+ @Override
+ public boolean run(final GLAutoDrawable drawable) {
+ final GL gl = drawable.getGL();
+ final int _i = gl.getSwapInterval();
+ final int i;
+ switch(_i) {
+ case 0: i = -1; break;
+ case -1: i = 1; break;
+ case 1: i = 0; break;
+ default: i = 1; break;
+ }
+ gl.setSwapInterval(i);
+
+ final GLAnimatorControl a = drawable.getAnimator();
+ if( null != a ) {
+ a.resetFPSCounter();
+ }
+ if(drawable instanceof FPSCounter) {
+ ((FPSCounter)drawable).resetFPSCounter();
+ }
+ System.err.println("Swap Interval: "+_i+" -> "+i+" -> "+gl.getSwapInterval());
+ return true;
+ }
+ });
+ } else {
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ final boolean wasVisible = glWindow.isVisible();
+ {
+ printlnState("[set visible pre]");
+ glWindow.setVisible(!wasVisible);
+ printlnState("[set visible post]");
+ }
+ if( wasVisible && !e.isControlDown() ) {
+ try {
+ java.lang.Thread.sleep(5000);
+ } catch (final InterruptedException e) {
+ e.printStackTrace();
+ }
+ printlnState("[reset visible pre]");
+ glWindow.setVisible(true);
+ printlnState("[reset visible post]");
+ }
+ } } );
+ }
+ break;
+ case KeyEvent.VK_W:
+ e.setConsumed(true);
+ glWindow.invokeOnNewThread(null, false, new Runnable() {
+ public void run() {
+ printlnState("[set pointer-pos pre]");
+ glWindow.warpPointer(glWindow.getSurfaceWidth()/2, glWindow.getSurfaceHeight()/2);
+ printlnState("[set pointer-pos post]");
+ } } );
+ break;
+ case KeyEvent.VK_X:
+ e.setConsumed(true);
+ final float[] hadSurfacePixelScale = glWindow.getCurrentSurfaceScale(new float[2]);
+ final float[] reqSurfacePixelScale;
+ if( hadSurfacePixelScale[0] == ScalableSurface.IDENTITY_PIXELSCALE ) {
+ reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
+ } else {
+ reqSurfacePixelScale = new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
+ }
+ System.err.println("[set PixelScale pre]: had "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" -> req "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]);
+ glWindow.setSurfaceScale(reqSurfacePixelScale);
+ final float[] valReqSurfacePixelScale = glWindow.getRequestedSurfaceScale(new float[2]);
+ final float[] hasSurfacePixelScale1 = glWindow.getCurrentSurfaceScale(new float[2]);
+ System.err.println("[set PixelScale post]: "+hadSurfacePixelScale[0]+"x"+hadSurfacePixelScale[1]+" (had) -> "+
+ reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
+ valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
+ hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
+ setTitle();
+ }
+ }
+ @Override
+ public void keyReleased(final KeyEvent e) { }
+
+ public void setConfinedFixedCenter(final boolean v) {
+ confinedFixedCenter = v;
+ }
+ @Override
+ public void mouseMoved(final MouseEvent e) {
+ if( e.isConfined() ) {
+ mouseCenterWarp(e);
+ }
+ }
+ @Override
+ public void mouseDragged(final MouseEvent e) {
+ if( e.isConfined() ) {
+ mouseCenterWarp(e);
+ }
+ }
+ @Override
+ public void mouseClicked(final MouseEvent e) {
+ if(e.getClickCount() == 2 && e.getPointerCount() == 1) {
+ glWindow.setFullscreen(!glWindow.isFullscreen());
+ System.err.println("setFullscreen: "+glWindow.isFullscreen());
+ }
+ }
+ private void mouseCenterWarp(final MouseEvent e) {
+ if(e.isConfined() && confinedFixedCenter ) {
+ final int x=glWindow.getSurfaceWidth()/2;
+ final int y=glWindow.getSurfaceHeight()/2;
+ glWindow.warpPointer(x, y);
+ }
+ }
+ @Override
+ public void mouseEntered(final MouseEvent e) {}
+ @Override
+ public void mouseExited(final MouseEvent e) {}
+ @Override
+ public void mousePressed(final MouseEvent e) {}
+ @Override
+ public void mouseReleased(final MouseEvent e) {}
+ @Override
+ public void mouseWheelMoved(final MouseEvent e) {}
+
+ /////////////////////////////////////////////////////////////
+
+ private boolean quitAdapterShouldQuit = false;
+ private boolean quitAdapterEnabled = false;
+ private boolean quitAdapterEnabled2 = true;
+
+ protected void quitAdapterOff() {
+ quitAdapterEnabled2 = false;
+ }
+ protected void quitAdapterOn() {
+ clearQuitAdapter();
+ quitAdapterEnabled2 = true;
+ }
+ public void quitAdapterEnable(final boolean v) { quitAdapterEnabled = v; }
+ public void clearQuitAdapter() { quitAdapterShouldQuit = false; }
+ public boolean shouldQuit() { return quitAdapterShouldQuit; }
+ public void doQuit() { quitAdapterShouldQuit=true; }
+
+ public void windowDestroyNotify(final WindowEvent e) {
+ if( quitAdapterEnabled && quitAdapterEnabled2 ) {
+ System.err.println("QUIT Window "+Thread.currentThread());
+ quitAdapterShouldQuit = true;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////
+
+ public void setTitle() {
+ setTitle(glWindow);
+ }
+ public static void setTitle(final GLWindow win) {
+ final CapabilitiesImmutable chosenCaps = win.getChosenCapabilities();
+ final CapabilitiesImmutable reqCaps = win.getRequestedCapabilities();
+ final CapabilitiesImmutable caps = null != chosenCaps ? chosenCaps : reqCaps;
+ final String capsA = caps.isBackgroundOpaque() ? "opaque" : "transl";
+ final float[] sDPI = win.getPixelsPerMM(new float[2]);
+ sDPI[0] *= 25.4f;
+ sDPI[1] *= 25.4f;
+ win.setTitle("GLWindow["+capsA+"], win: "+win.getBounds()+", pix: "+win.getSurfaceWidth()+"x"+win.getSurfaceHeight()+", sDPI "+sDPI[0]+" x "+sDPI[1]);
+ }
+
+ public static PointerIcon[] createPointerIcons(final GLWindow glWindow) {
+ final PointerIcon[] pointerIcons = { null, null, null, null, null };
+ {
+ final Display disp = glWindow.getScreen().getDisplay();
+ disp.createNative();
+ int idx = 0;
+ {
+ PointerIcon _pointerIcon = null;
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/cross-grey-alpha-16x16.png" } );
+ try {
+ _pointerIcon = disp.createPointerIcon(res, 8, 8);
+ System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ pointerIcons[idx] = _pointerIcon;
+ }
+ idx++;
+ {
+ PointerIcon _pointerIcon = null;
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/pointer-grey-alpha-16x24.png" } );
+ try {
+ _pointerIcon = disp.createPointerIcon(res, 0, 0);
+ System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ pointerIcons[idx] = _pointerIcon;
+ }
+ idx++;
+ {
+ PointerIcon _pointerIcon = null;
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "arrow-red-alpha-64x64.png" } );
+ try {
+ _pointerIcon = disp.createPointerIcon(res, 0, 0);
+ System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ pointerIcons[idx] = _pointerIcon;
+ }
+ idx++;
+ {
+ PointerIcon _pointerIcon = null;
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "arrow-blue-alpha-64x64.png" } );
+ try {
+ _pointerIcon = disp.createPointerIcon(res, 0, 0);
+ System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ pointerIcons[idx] = _pointerIcon;
+ }
+ idx++;
+ if( PNGIcon.isAvailable() ) {
+ PointerIcon _pointerIcon = null;
+ final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "jogamp-pointer-64x64.png" } );
+ try {
+ final URLConnection urlConn = res.resolve(0);
+ final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), null, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */);
+ System.err.printf("Create PointerIcon #%02d: %s%n", idx, image.toString());
+ _pointerIcon = disp.createPointerIcon(image, 32, 0);
+ System.err.printf("Create PointerIcon #%02d: %s%n", idx, _pointerIcon.toString());
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ pointerIcons[idx] = _pointerIcon;
+ }
+ idx++;
+ }
+ return pointerIcons;
+ }
+} \ No newline at end of file
diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java
index 8bf4bc20f..05df63794 100644
--- a/src/newt/classes/com/jogamp/newt/util/MainThread.java
+++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java
@@ -45,6 +45,7 @@ import java.util.List;
import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.ReflectionUtil;
@@ -171,15 +172,14 @@ public class MainThread {
return res;
}
- static class UserApp extends Thread {
+ static class UserApp extends InterruptSource.Thread {
private final String mainClassNameShort;
private final String mainClassName;
private final String[] mainClassArgs;
private final Method mainClassMain;
- private List<Thread> nonDaemonThreadsAtStart;
+ private List<java.lang.Thread> nonDaemonThreadsAtStart;
public UserApp(final String mainClassName, final String[] mainClassArgs) throws SecurityException, NoSuchMethodException, ClassNotFoundException {
- super();
this.mainClassName=mainClassName;
this.mainClassArgs=mainClassArgs;
@@ -200,10 +200,10 @@ public class MainThread {
@Override
public void run() {
nonDaemonThreadsAtStart = getNonDaemonThreads();
- if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" start, nonDaemonThreadsAtStart "+nonDaemonThreadsAtStart);
+ if(DEBUG) System.err.println("MainAction.run(): "+java.lang.Thread.currentThread().getName()+" start, nonDaemonThreadsAtStart "+nonDaemonThreadsAtStart);
// start user app ..
try {
- if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" invoke "+mainClassName);
+ if(DEBUG) System.err.println("MainAction.run(): "+java.lang.Thread.currentThread().getName()+" invoke "+mainClassName);
mainClassMain.invoke(null, new Object[] { mainClassArgs } );
} catch (final InvocationTargetException ite) {
ite.getTargetException().printStackTrace();
@@ -219,30 +219,30 @@ public class MainThread {
while( 0 < ( ndtr = getNonDaemonThreadCount(nonDaemonThreadsAtStart) ) ) {
if(DEBUG) System.err.println("MainAction.run(): post user app, non daemon threads alive: "+ndtr);
try {
- Thread.sleep(1000);
+ java.lang.Thread.sleep(1000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
- if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" user app fin: "+ndtr);
+ if(DEBUG) System.err.println("MainAction.run(): "+java.lang.Thread.currentThread().getName()+" user app fin: "+ndtr);
}
if ( useMainThread ) {
if(isMacOSX) {
try {
if(DEBUG) {
- System.err.println("MainAction.main(): "+Thread.currentThread()+" MainAction fin - stopNSApp.0");
+ System.err.println("MainAction.main(): "+java.lang.Thread.currentThread()+" MainAction fin - stopNSApp.0");
}
ReflectionUtil.callStaticMethod(MACOSXDisplayClassName, "stopNSApplication",
null, null, MainThread.class.getClassLoader());
if(DEBUG) {
- System.err.println("MainAction.main(): "+Thread.currentThread()+" MainAction fin - stopNSApp.X");
+ System.err.println("MainAction.main(): "+java.lang.Thread.currentThread()+" MainAction fin - stopNSApp.X");
}
} catch (final Exception e) {
e.printStackTrace();
}
} else {
- if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" MainAction fin - System.exit(0)");
+ if(DEBUG) System.err.println("MainAction.run(): "+java.lang.Thread.currentThread().getName()+" MainAction fin - System.exit(0)");
System.exit(0);
}
}
diff --git a/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java
index c2cf64da2..e02e02013 100644
--- a/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java
+++ b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java
@@ -33,7 +33,6 @@ import java.security.PrivilegedAction;
import com.jogamp.nativewindow.NativeWindow;
import com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode;
-import com.jogamp.nativewindow.util.InsetsImmutable;
import com.jogamp.opengl.FPSCounter;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLAutoDrawable;
@@ -43,16 +42,17 @@ import com.jogamp.opengl.GLPipelineFactory;
import jogamp.newt.Debug;
import com.jogamp.common.util.IOUtil;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.Display;
import com.jogamp.newt.Window;
import com.jogamp.newt.Display.PointerIcon;
-import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.MouseListener;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.newt.opengl.util.NEWTDemoListener;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.AnimatorBase;
@@ -60,7 +60,7 @@ import com.jogamp.opengl.util.AnimatorBase;
/** Shows how to deploy an applet using JOGL. This demo must be
referenced from a web page via an &lt;applet&gt; tag. */
-public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
+public class JOGLNewtAppletBase implements GLEventListener {
public static final boolean DEBUG = Debug.debug("Applet");
String glEventListenerClazzName;
@@ -194,7 +194,9 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
}
if(!noDefaultKeyListener) {
- glWindow.addKeyListener(this);
+ final NEWTDemoListener newtDemoListener = new NEWTDemoListener(glWindow);
+ glWindow.addKeyListener(newtDemoListener);
+ glWindow.addMouseListener(newtDemoListener);
}
glWindow.setUpdateFPSFrames(FPSCounter.DEFAULT_FRAMES_PER_INTERVAL, System.err);
@@ -220,7 +222,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
null == glWindow.getParent() && null != parentWin && 0 != parentWin.getWindowHandle() )
{
// we may be called directly by the native EDT
- new Thread(new Runnable() {
+ new InterruptSource.Thread(null, new Runnable() {
@Override
public void run() {
if( glWindow.isNativeValid() && null != parentWin && 0 != parentWin.getWindowHandle() ) {
@@ -303,86 +305,5 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
public void dispose(final GLAutoDrawable drawable) {
}
- // ***********************************************************************************
- // ***********************************************************************************
- // ***********************************************************************************
-
- @Override
- public void keyPressed(final KeyEvent e) {
- if( !e.isPrintableKey() || e.isAutoRepeat() ) {
- return;
- }
- if(e.getKeyChar()=='d') {
- new Thread() {
- public void run() {
- glWindow.setUndecorated(!glWindow.isUndecorated());
- } }.start();
- } if(e.getKeyChar()=='f') {
- new Thread() {
- public void run() {
- glWindow.setFullscreen(!glWindow.isFullscreen());
- } }.start();
- } else if(e.getKeyChar()=='a') {
- new Thread() {
- public void run() {
- glWindow.setAlwaysOnTop(!glWindow.isAlwaysOnTop());
- } }.start();
- } else if(e.getKeyChar()=='r' && null!=parentWin) {
- new Thread() {
- public void run() {
- if(null == glWindow.getParent()) {
- glWindow.reparentWindow(parentWin, -1, -1, 0 /* hints */);
- } else {
- final InsetsImmutable insets = glWindow.getInsets();
- final int x, y;
- if ( 0 >= insets.getTopHeight() ) {
- // fail safe ..
- x = 32;
- y = 32;
- } else {
- x = insets.getLeftWidth();
- y = insets.getTopHeight();
- }
- glWindow.reparentWindow(null, x, y, 0 /* hints */);
- glWindow.setDefaultCloseOperation( glClosable ? WindowClosingMode.DISPOSE_ON_CLOSE : WindowClosingMode.DO_NOTHING_ON_CLOSE );
- }
- } }.start();
- } else if(e.getKeyChar()=='c') {
- new Thread() {
- public void run() {
- System.err.println("[set pointer-icon pre]");
- final PointerIcon currentPI = glWindow.getPointerIcon();
- glWindow.setPointerIcon( currentPI == pointerIconTest ? null : pointerIconTest);
- System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon());
- } }.start();
- } else if(e.getKeyChar()=='i') {
- new Thread() {
- public void run() {
- System.err.println("[set mouse visible pre]: "+glWindow.isPointerVisible());
- glWindow.setPointerVisible(!glWindow.isPointerVisible());
- System.err.println("[set mouse visible post]: "+glWindow.isPointerVisible());
- } }.start();
- } else if(e.getKeyChar()=='j') {
- new Thread() {
- public void run() {
- final Thread t = glWindow.setExclusiveContextThread(null);
- System.err.println("[set mouse confined pre]: "+glWindow.isPointerConfined());
- glWindow.confinePointer(!glWindow.isPointerConfined());
- System.err.println("[set mouse confined post]: "+glWindow.isPointerConfined());
- glWindow.setExclusiveContextThread(t);
- } }.start();
- } else if(e.getKeyChar()=='w') {
- new Thread() {
- public void run() {
- System.err.println("[set mouse pos pre]");
- glWindow.warpPointer(glWindow.getSurfaceWidth()/2, glWindow.getSurfaceHeight()/2);
- System.err.println("[set mouse pos post]");
- } }.start();
- }
- }
-
- @Override
- public void keyReleased(final KeyEvent e) {
- }
}
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
index bf46ce609..ff713410b 100644
--- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
@@ -44,6 +44,8 @@ import com.jogamp.nativewindow.NativeWindowException;
import jogamp.common.util.locks.LockDebugUtil;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.common.util.locks.Lock;
import com.jogamp.newt.util.EDTUtil;
@@ -68,7 +70,7 @@ public class DefaultEDTUtil implements EDTUtil {
this.threadGroup = tg;
this.name=Thread.currentThread().getName()+"-"+name+"-EDT-";
this.dispatchMessages=dispatchMessages;
- this.edt = new NEDT(threadGroup, name);
+ this.edt = new NEDT(threadGroup, this.name);
this.edt.setDaemon(true); // don't stop JVM from shutdown ..
}
@@ -169,8 +171,7 @@ public class DefaultEDTUtil implements EDTUtil {
};
private final boolean invokeImpl(boolean wait, Runnable task, final boolean stop, final boolean provokeError) {
- Throwable throwable = null;
- RunnableTask rTask = null;
+ final RunnableTask rTask;
final Object rTaskLock = new Object();
synchronized(rTaskLock) { // lock the optional task execution
synchronized(edtLock) { // lock the EDT status
@@ -187,6 +188,7 @@ public class DefaultEDTUtil implements EDTUtil {
task.run();
}
wait = false; // running in same thread (EDT) -> no wait
+ rTask = null;
if( stop ) {
edt.shouldStop = true;
if( edt.tasks.size()>0 ) {
@@ -230,18 +232,19 @@ public class DefaultEDTUtil implements EDTUtil {
}
} else {
wait = false;
+ rTask = null;
}
}
}
if( wait ) {
try {
- rTaskLock.wait(); // free lock, allow execution of rTask
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
} catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
+ throw new InterruptedRuntimeException(ie);
}
+ final Throwable throwable = rTask.getThrowable();
if(null!=throwable) {
if(throwable instanceof NativeWindowException) {
throw (NativeWindowException)throwable;
@@ -268,13 +271,13 @@ public class DefaultEDTUtil implements EDTUtil {
return false;
}
synchronized(_edt.tasks) {
- while(_edt.isRunning && _edt.tasks.size()>0) {
- try {
+ try {
+ while(_edt.isRunning && _edt.tasks.size()>0) {
_edt.tasks.notifyAll();
_edt.tasks.wait();
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
return true;
}
@@ -284,12 +287,12 @@ public class DefaultEDTUtil implements EDTUtil {
final public boolean waitUntilStopped() {
synchronized(edtLock) {
if(edt.isRunning && edt != Thread.currentThread() ) {
- while( edt.isRunning ) {
- try {
+ try {
+ while( edt.isRunning ) {
edtLock.wait();
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
return true;
} else {
@@ -298,13 +301,13 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
- class NEDT extends Thread {
+ class NEDT extends InterruptSource.Thread {
volatile boolean shouldStop = false;
volatile boolean isRunning = false;
final ArrayList<RunnableTask> tasks = new ArrayList<RunnableTask>(); // one shot tasks
public NEDT(final ThreadGroup tg, final String name) {
- super(tg, name);
+ super(tg, null, name);
}
final public boolean isRunning() {
@@ -347,11 +350,11 @@ public class DefaultEDTUtil implements EDTUtil {
RunnableTask task = null;
synchronized(tasks) {
// wait for tasks
- if(!shouldStop && tasks.size()==0) {
+ if( !shouldStop && tasks.size()==0 ) {
try {
tasks.wait(pollPeriod);
} catch (final InterruptedException e) {
- e.printStackTrace();
+ throw new InterruptedRuntimeException(e);
}
}
// execute one task, if available
@@ -375,7 +378,7 @@ public class DefaultEDTUtil implements EDTUtil {
}
if(!task.hasWaiter() && null != task.getThrowable()) {
// at least dump stack-trace in case nobody waits for result
- System.err.println("DefaultEDT.run(): Caught exception occured on thread "+Thread.currentThread().getName()+": "+task.toString());
+ System.err.println("DefaultEDT.run(): Caught exception occured on thread "+java.lang.Thread.currentThread().getName()+": "+task.toString());
task.getThrowable().printStackTrace();
}
}
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index cc1f3d8e0..c1cd6db32 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -37,6 +37,7 @@ package jogamp.newt;
import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.IOUtil;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.newt.Display;
import com.jogamp.newt.NewtFactory;
@@ -697,8 +698,9 @@ public abstract class DisplayImpl extends Display {
} else {
throw re;
}
+ } finally {
+ eventTask.notifyCaller();
}
- eventTask.notifyCaller();
}
@Override
@@ -725,7 +727,10 @@ public abstract class DisplayImpl extends Display {
}
if( null != _events ) {
for (int i=0; i < _events.size(); i++) {
- dispatchMessage(_events.get(i));
+ final NEWTEventTask e = _events.get(i);
+ if( !e.isDispatched() ) {
+ dispatchMessage(e);
+ }
}
}
}
@@ -759,11 +764,12 @@ public abstract class DisplayImpl extends Display {
haveEvents = true;
eventsLock.notifyAll();
}
- if( wait ) {
+ while( wait && !eTask.isDispatched() ) {
try {
lock.wait();
} catch (final InterruptedException ie) {
- throw new RuntimeException(ie);
+ eTask.setDispatched(); // Cancels NEWTEvent ..
+ throw new InterruptedRuntimeException(ie);
}
if( null != eTask.getException() ) {
throw eTask.getException();
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
index 9d3121635..3d9073769 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
@@ -33,6 +33,8 @@ import java.awt.EventQueue;
import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.common.util.awt.AWTEDTExecutor;
import com.jogamp.newt.util.EDTUtil;
@@ -54,7 +56,7 @@ public class AWTEDTUtil implements EDTUtil {
this.threadGroup = tg;
this.name=Thread.currentThread().getName()+"-"+name+"-EDT-";
this.dispatchMessages=dispatchMessages;
- this.nedt = new NEDT(threadGroup, name);
+ this.nedt = new NEDT(threadGroup, this.name);
this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
}
@@ -132,8 +134,7 @@ public class AWTEDTUtil implements EDTUtil {
}
private final boolean invokeImpl(boolean wait, final Runnable task, final boolean stop) {
- Throwable throwable = null;
- RunnableTask rTask = null;
+ final RunnableTask rTask;
final Object rTaskLock = new Object();
synchronized(rTaskLock) { // lock the optional task execution
synchronized(edtLock) { // lock the EDT status
@@ -150,6 +151,7 @@ public class AWTEDTUtil implements EDTUtil {
task.run();
}
wait = false; // running in same thread (EDT) -> no wait
+ rTask = null;
if(stop) {
nedt.shouldStop = true;
}
@@ -182,18 +184,21 @@ public class AWTEDTUtil implements EDTUtil {
true /* always catch and report Exceptions, don't disturb EDT */,
wait ? null : System.err);
AWTEDTExecutor.singleton.invoke(false, rTask);
+ } else {
+ wait = false;
+ rTask = null;
}
}
}
if( wait ) {
try {
- rTaskLock.wait(); // free lock, allow execution of rTask
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
} catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
+ throw new InterruptedRuntimeException(ie);
}
+ final Throwable throwable = rTask.getThrowable();
if(null!=throwable) {
if(throwable instanceof NativeWindowException) {
throw (NativeWindowException)throwable;
@@ -227,12 +232,12 @@ public class AWTEDTUtil implements EDTUtil {
final public boolean waitUntilStopped() {
synchronized(edtLock) {
if( nedt.isRunning && nedt != Thread.currentThread() && !EventQueue.isDispatchThread() ) {
- while( nedt.isRunning ) {
- try {
+ try {
+ while( nedt.isRunning ) {
edtLock.wait();
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
return true;
} else {
@@ -241,13 +246,13 @@ public class AWTEDTUtil implements EDTUtil {
}
}
- class NEDT extends Thread {
+ class NEDT extends InterruptSource.Thread {
volatile boolean shouldStop = false;
volatile boolean isRunning = false;
Object sync = new Object();
public NEDT(final ThreadGroup tg, final String name) {
- super(tg, name);
+ super(tg, null, name);
}
final public boolean isRunning() {
@@ -286,7 +291,7 @@ public class AWTEDTUtil implements EDTUtil {
try {
sync.wait(pollPeriod);
} catch (final InterruptedException e) {
- e.printStackTrace();
+ throw new InterruptedRuntimeException(e);
}
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
index bc0bfaa16..c3b7bff36 100644
--- a/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxEventDeviceTracker.java
@@ -43,6 +43,7 @@ import jogamp.newt.WindowImpl;
import jogamp.newt.driver.KeyTracker;
import com.jogamp.common.nio.StructAccessor;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.WindowEvent;
@@ -63,7 +64,7 @@ public class LinuxEventDeviceTracker implements WindowListener, KeyTracker {
static {
ledt = new LinuxEventDeviceTracker();
- final Thread t = new Thread(ledt.eventDeviceManager, "NEWT-LinuxEventDeviceManager");
+ final Thread t = new InterruptSource.Thread(null, ledt.eventDeviceManager, "NEWT-LinuxEventDeviceManager");
t.setDaemon(true);
t.start();
}
@@ -153,7 +154,7 @@ public class LinuxEventDeviceTracker implements WindowListener, KeyTracker {
if(number<32&&number>=0) {
if(eventDevicePollers[number]==null){
eventDevicePollers[number] = new EventDevicePoller(number);
- final Thread t = new Thread(eventDevicePollers[number], "NEWT-LinuxEventDeviceTracker-event"+number);
+ final Thread t = new InterruptSource.Thread(null, eventDevicePollers[number], "NEWT-LinuxEventDeviceTracker-event"+number);
t.setDaemon(true);
t.start();
} else if(eventDevicePollers[number].stop) {
diff --git a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
index f40728da0..53bb9c3a5 100644
--- a/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
+++ b/src/newt/classes/jogamp/newt/driver/linux/LinuxMouseTracker.java
@@ -37,6 +37,7 @@ import java.io.InputStream;
import jogamp.newt.WindowImpl;
import jogamp.newt.driver.MouseTracker;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.MouseEvent;
@@ -55,7 +56,7 @@ public class LinuxMouseTracker implements WindowListener, MouseTracker {
static {
lmt = new LinuxMouseTracker();
- final Thread t = new Thread(lmt.mouseDevicePoller, "NEWT-LinuxMouseTracker");
+ final Thread t = new InterruptSource.Thread(null, lmt.mouseDevicePoller, "NEWT-LinuxMouseTracker");
t.setDaemon(true);
t.start();
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index a38ba4c13..2bbcdce38 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -34,6 +34,7 @@
package jogamp.newt.driver.macosx;
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
import com.jogamp.nativewindow.GraphicsConfigurationFactory;
import com.jogamp.nativewindow.NativeWindow;
@@ -378,7 +379,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
private void superSizeChangedOffThread(final boolean defer, final int newWidth, final int newHeight, final boolean force) {
if( defer ) {
- new Thread() {
+ new InterruptSource.Thread() {
public void run() {
WindowDriver.super.sizeChanged(false /* defer */, newWidth, newHeight, force);
} }.start();
diff --git a/src/newt/classes/jogamp/newt/event/NEWTEventTask.java b/src/newt/classes/jogamp/newt/event/NEWTEventTask.java
index 2bdab2796..260a1beb4 100644
--- a/src/newt/classes/jogamp/newt/event/NEWTEventTask.java
+++ b/src/newt/classes/jogamp/newt/event/NEWTEventTask.java
@@ -38,19 +38,27 @@ public class NEWTEventTask {
private final NEWTEvent event;
private final Object notifyObject;
private RuntimeException exception;
+ private volatile boolean dispatched;
public NEWTEventTask(final NEWTEvent event, final Object notifyObject) {
this.event = event ;
this.notifyObject = notifyObject ;
this.exception = null;
+ this.dispatched = false;
}
public final NEWTEvent get() { return event; }
public final void setException(final RuntimeException e) { exception = e; }
public final RuntimeException getException() { return exception; }
public final boolean isCallerWaiting() { return null != notifyObject; }
+ public final boolean isDispatched() { return dispatched; }
+ public final void setDispatched() { dispatched = true; }
+ /**
+ * Notifies caller after {@link #setDispatched()}.
+ */
public void notifyCaller() {
+ setDispatched();
if(null != notifyObject) {
synchronized (notifyObject) {
notifyObject.notifyAll();
diff --git a/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
index 9039b6083..9d2b41bbc 100644
--- a/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
@@ -32,6 +32,8 @@ import com.jogamp.nativewindow.NativeWindowException;
import jogamp.newt.Debug;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.common.util.InterruptedRuntimeException;
import com.jogamp.common.util.RunnableTask;
import com.jogamp.newt.util.EDTUtil;
@@ -162,8 +164,7 @@ public class SWTEDTUtil implements EDTUtil {
}
private final boolean invokeImpl(boolean wait, final Runnable task, boolean stop) {
- Throwable throwable = null;
- RunnableTask rTask = null;
+ final RunnableTask rTask;
final Object rTaskLock = new Object();
synchronized(rTaskLock) { // lock the optional task execution
synchronized(edtLock) { // lock the EDT status
@@ -184,6 +185,7 @@ public class SWTEDTUtil implements EDTUtil {
task.run();
}
wait = false; // running in same thread (EDT) -> no wait
+ rTask = null;
if( stop ) {
nedt.shouldStop = true;
}
@@ -225,18 +227,21 @@ public class SWTEDTUtil implements EDTUtil {
true /* always catch and report Exceptions, don't disturb EDT */,
wait ? null : System.err);
swtDisplay.asyncExec(rTask);
+ } else {
+ wait = false;
+ rTask = null;
}
}
}
if( wait ) {
try {
- rTaskLock.wait(); // free lock, allow execution of rTask
+ while( rTask.isInQueue() ) {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ }
} catch (final InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
+ throw new InterruptedRuntimeException(ie);
}
+ final Throwable throwable = rTask.getThrowable();
if(null!=throwable) {
if(throwable instanceof NativeWindowException) {
throw (NativeWindowException)throwable;
@@ -274,12 +279,12 @@ public class SWTEDTUtil implements EDTUtil {
final Thread swtT = !swtDisplay.isDisposed() ? swtDisplay.getThread() : null;
final boolean onSWTEDT = swtT == curT;
if( nedt.isRunning && nedt != curT && !onSWTEDT ) {
- while( nedt.isRunning ) {
- try {
+ try {
+ while( nedt.isRunning ) {
edtLock.wait();
- } catch (final InterruptedException e) {
- e.printStackTrace();
}
+ } catch (final InterruptedException e) {
+ throw new InterruptedRuntimeException(e);
}
return true;
} else {
@@ -288,13 +293,13 @@ public class SWTEDTUtil implements EDTUtil {
}
}
- class NEDT extends Thread {
+ class NEDT extends InterruptSource.Thread {
volatile boolean shouldStop = false;
volatile boolean isRunning = false;
Object sync = new Object();
public NEDT(final ThreadGroup tg, final String name) {
- super(tg, name);
+ super(tg, null, name);
}
final public boolean isRunning() {
@@ -337,7 +342,7 @@ public class SWTEDTUtil implements EDTUtil {
try {
sync.wait(pollPeriod);
} catch (final InterruptedException e) {
- e.printStackTrace();
+ throw new InterruptedRuntimeException(e);
}
}
}