aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--make/build-common.xml1
-rw-r--r--make/build-newt.xml2
-rw-r--r--make/config/nativewindow/x11-CustomJavaCode.java5
-rwxr-xr-xmake/scripts/tests-x32.sh2
-rwxr-xr-xmake/scripts/tests-x64.bat4
-rwxr-xr-xmake/scripts/tests.sh6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java350
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java345
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java4
-rw-r--r--src/nativewindow/native/x11/Xmisc.c123
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java82
-rw-r--r--src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java (renamed from src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java)2
-rw-r--r--src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java249
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java26
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java16
17 files changed, 924 insertions, 306 deletions
diff --git a/make/build-common.xml b/make/build-common.xml
index a718ae09a..414b0eba2 100644
--- a/make/build-common.xml
+++ b/make/build-common.xml
@@ -428,6 +428,7 @@
<property name="jogl-all-android.jar" value="${jar}/jogl-all-android.jar" />
<property name="jogl-all-android.apk" value="${jar}/jogl-all-android-${android.abi}.apk" />
+ <!-- NativeWindow Compilation .. -->
<path id="swt_gluegen.classpath">
<pathelement location="${gluegen-rt.jar}" />
<pathelement location="${swt.jar}" />
diff --git a/make/build-newt.xml b/make/build-newt.xml
index 7b9a51863..c3b51141f 100644
--- a/make/build-newt.xml
+++ b/make/build-newt.xml
@@ -112,7 +112,7 @@
value="com/jogamp/newt/awt/** com/jogamp/newt/event/awt/** jogamp/newt/awt/** ${java.part.driver.awt}"/>
<property name="java.part.swt"
- value="com/jogamp/newt/swt/**"/>
+ value="com/jogamp/newt/swt/** jogamp/newt/swt/**"/>
<property name="java.part.driver.linux"
value="jogamp/newt/driver/linux/**"/>
diff --git a/make/config/nativewindow/x11-CustomJavaCode.java b/make/config/nativewindow/x11-CustomJavaCode.java
index 8e5da3b2d..4240c5e2f 100644
--- a/make/config/nativewindow/x11-CustomJavaCode.java
+++ b/make/config/nativewindow/x11-CustomJavaCode.java
@@ -28,8 +28,9 @@
public static native int DefaultVisualID(long display, int screen);
- public static native long CreateDummyWindow(long display, int screen_index, int visualID, int width, int height);
- public static native void DestroyDummyWindow(long display, long window);
+ public static native long CreateWindow(long parent, long display, int screen_index, int visualID, int width, int height, boolean input, boolean visible);
+ public static native void DestroyWindow(long display, long window);
+ public static native void SetWindowPosSize(long display, long window, int x, int y, int width, int height);
public static Point GetRelativeLocation(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y) {
return (Point) GetRelativeLocation0(display, screen_index, src_win, dest_win, src_x, src_y);
diff --git a/make/scripts/tests-x32.sh b/make/scripts/tests-x32.sh
index a3aed84c3..858ed5fd8 100755
--- a/make/scripts/tests-x32.sh
+++ b/make/scripts/tests-x32.sh
@@ -6,6 +6,8 @@ if [ -e $SDIR/../../../gluegen/make/scripts/setenv-build-jogl-x86.sh ] ; then
. $SDIR/../../../gluegen/make/scripts/setenv-build-jogl-x86.sh
fi
+export SWT_CLASSPATH=`pwd`/lib/swt/gtk-linux-x86/swt-debug.jar
+
. $SDIR/tests.sh `which java` -d32 ../build-x86 $*
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat
index 7a2946d31..db7e27264 100755
--- a/make/scripts/tests-x64.bat
+++ b/make/scripts/tests-x64.bat
@@ -54,10 +54,10 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestP
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn %*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
+scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTBug628ResizeDeadlock %*
-scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTBug643AsyncExec %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTBug643AsyncExec %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestWindows01NEWT
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 0669efb37..628ab706b 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -113,7 +113,7 @@ function jrun() {
#D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile"
#D_ARGS="-Djogl.debug.GLProfile"
#D_ARGS="-Dnativewindow.debug.NativeWindow"
- #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT"
+ D_ARGS="-Djogl.debug.GLCanvas -Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT -Djogl.debug.Animator"
#D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Window -Djogl.debug.GLContext"
#D_ARGS="-Dnativewindow.debug.X11Util.XErrorStackDump -Dnativewindow.debug.X11Util.TraceDisplayLifecycle -Dnativewindow.debug.X11Util"
#D_ARGS="-Dnativewindow.debug.X11Util -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnewt.debug=all"
@@ -370,10 +370,10 @@ function testawtswt() {
#
#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTEclipseGLCanvas01GLn $*
#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn $*
-#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
+testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn $*
#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTBug628ResizeDeadlock $*
-testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTBug643AsyncExec $*
+#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTBug643AsyncExec $*
#
# newt.awt (testawt)
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index a080a7045..0320c63ae 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -29,10 +29,16 @@ package com.jogamp.opengl.swt;
import java.util.List;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.UpstreamSurfaceHook;
+import javax.media.nativewindow.VisualIDHolder;
+import javax.media.nativewindow.VisualIDHolder.VIDType;
import javax.media.opengl.GL;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
@@ -48,23 +54,20 @@ import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
import javax.media.opengl.Threading;
+import jogamp.nativewindow.x11.X11Util;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableHelper;
import jogamp.opengl.GLDrawableImpl;
import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import com.jogamp.common.GlueGenVersion;
@@ -73,13 +76,14 @@ import com.jogamp.common.util.VersionUtil;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.nativewindow.swt.SWTAccessor;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.opengl.JoglVersion;
/**
* Native SWT Canvas implementing GLAutoDrawable
- *
- * <p>Note: To employ custom GLCapabilities, NewtCanvasSWT shall be used instead.</p>
- *
+ * <p>
+ * Implementation allows use of custom {@link GLCapabilities}.
+ * </p>
*/
public class GLCanvas extends Canvas implements GLAutoDrawable {
private static final boolean DEBUG = Debug.debug("GLCanvas");
@@ -103,11 +107,15 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final GLCapabilitiesImmutable capsRequested;
private final GLCapabilitiesChooser capsChooser;
+ private volatile Rectangle clientArea;
private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
- private GLContextImpl context;
+ private volatile GLContextImpl context;
/* Native window surface */
- private AbstractGraphicsDevice device;
+ private final boolean useX11GTK;
+ private volatile long gdkWindow; // either GDK child window ..
+ private volatile long x11Window; // .. or X11 child window (for GL rendering)
+ private final AbstractGraphicsScreen screen;
/* Construction parameters stored for GLAutoDrawable accessor methods */
private int additionalCtxCreationFlags = 0;
@@ -135,7 +143,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public void run() {
if (sendReshape) {
- helper.reshape(GLCanvas.this, 0, 0, getWidth(), getHeight());
+ helper.reshape(GLCanvas.this, 0, 0, clientArea.width, clientArea.height);
sendReshape = false;
}
helper.display(GLCanvas.this);
@@ -143,7 +151,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
};
/* Action to make specified context current prior to running displayAction */
- private final Runnable makeCurrentAndDisplayOnEDTAction = new Runnable() {
+ private final Runnable makeCurrentAndDisplayOnGLAction = new Runnable() {
@Override
public void run() {
final RecursiveLock _lock = lock;
@@ -159,13 +167,14 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
};
/* Swaps buffers, assuming the GLContext is current */
- private final Runnable swapBuffersOnEDTAction = new Runnable() {
+ private final Runnable swapBuffersOnGLAction = new Runnable() {
@Override
public void run() {
final RecursiveLock _lock = lock;
_lock.lock();
try {
- if(null != drawable && !GLCanvas.this.isDisposed() ) {
+ final boolean drawableOK = null != drawable && drawable.isRealized();
+ if( drawableOK && !GLCanvas.this.isDisposed() ) {
drawable.swapBuffers();
}
} finally {
@@ -212,10 +221,14 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
drawable.setRealized(false);
drawable = null;
}
- if (null != device) {
- device.close();
- device = null;
+ if( 0 != x11Window) {
+ SWTAccessor.destroyX11Window(screen.getDevice(), x11Window);
+ x11Window = 0;
+ } else if( 0 != gdkWindow) {
+ SWTAccessor.destroyGDKWindow(gdkWindow);
+ gdkWindow = 0;
}
+ screen.getDevice().close();
if (animatorPaused) {
animator.resume();
@@ -249,11 +262,6 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
}
};
- /**
- * Storage for the client area rectangle so that it may be accessed from outside of the SWT thread.
- */
- private volatile Rectangle clientArea;
-
/**
* Creates an instance using {@link #GLCanvas(Composite, int, GLCapabilitiesImmutable, GLCapabilitiesChooser, GLContext)}
* on the SWT thread.
@@ -293,72 +301,80 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
* @param style
* Optional SWT style bit-field. The {@link SWT#NO_BACKGROUND} bit is set before passing this up to the
* Canvas constructor, so OpenGL handles the background.
- * @param caps
+ * @param capsReqUser
* Optional GLCapabilities. If not provided, the default capabilities for the default GLProfile for the
* graphics device determined by the parent Composite are used. Note that the GLCapabilities that are
* actually used may differ based on the capabilities of the graphics device.
- * @param chooser
+ * @param capsChooser
* Optional GLCapabilitiesChooser to customize the selection of the used GLCapabilities based on the
* requested GLCapabilities, and the available capabilities of the graphics device.
* @param shareWith
* Optional GLContext to share state (textures, vbos, shaders, etc.) with.
*/
- public GLCanvas(final Composite parent, final int style, GLCapabilitiesImmutable caps,
- final GLCapabilitiesChooser chooser, final GLContext shareWith) {
+ public GLCanvas(final Composite parent, final int style, GLCapabilitiesImmutable capsReqUser,
+ final GLCapabilitiesChooser capsChooser, final GLContext shareWith) {
/* NO_BACKGROUND required to avoid clearing bg in native SWT widget (we do this in the GL display) */
super(parent, style | SWT.NO_BACKGROUND);
GLProfile.initSingleton(); // ensure JOGL is completly initialized
SWTAccessor.setRealized(this, true);
-
+
clientArea = GLCanvas.this.getClientArea();
/* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite).
* Note: SWT is owner of the native handle, hence closing operation will be a NOP. */
- device = SWTAccessor.getDevice(this);
+ final AbstractGraphicsDevice swtDevice = SWTAccessor.getDevice(this);
+
+ useX11GTK = SWTAccessor.useX11GTK();
+ if(useX11GTK) {
+ // Decoupled X11 Device/Screen allowing X11 display lock-free off-thread rendering
+ final long x11DeviceHandle = X11Util.openDisplay(swtDevice.getConnection());
+ if( 0 == x11DeviceHandle ) {
+ throw new RuntimeException("Error creating display(EDT): "+swtDevice.getConnection());
+ }
+ final AbstractGraphicsDevice x11Device = new X11GraphicsDevice(x11DeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
+ screen = SWTAccessor.getScreen(x11Device, -1 /* default */);
+ } else {
+ screen = SWTAccessor.getScreen(swtDevice, -1 /* default */);
+ }
/* Select default GLCapabilities if none was provided, otherwise clone provided caps to ensure safety */
- if(null == caps) {
- caps = new GLCapabilities(GLProfile.getDefault(device));
+ if(null == capsReqUser) {
+ capsReqUser = new GLCapabilities(GLProfile.getDefault(screen.getDevice()));
}
- this.capsRequested = caps;
- this.capsChooser = chooser;
+
+ this.capsRequested = capsReqUser;
+ this.capsChooser = capsChooser;
this.shareWith = shareWith;
// post create .. when ready
+ gdkWindow = 0;
+ x11Window = 0;
drawable = null;
context = null;
- /* Register SWT listeners (e.g. PaintListener) to render/resize GL surface. */
- /* TODO: verify that these do not need to be manually de-registered when destroying the SWT component */
- addPaintListener(new PaintListener() {
- @Override
- public void paintControl(final PaintEvent arg0) {
- if ( !helper.isAnimatorAnimatingOnOtherThread() ) {
- display(); // checks: null != drawable
- }
- }
- });
-
- addControlListener(new ControlListener() {
- @Override
- public void controlMoved(ControlEvent e) {
- }
-
- @Override
- public void controlResized(final ControlEvent arg0) {
- updateSizeCheck();
- }
- });
-
- addDisposeListener(new DisposeListener() {
- @Override
- public void widgetDisposed(DisposeEvent e) {
- GLCanvas.this.dispose();
- }
- });
+ final Listener listener = new Listener () {
+ @Override
+ public void handleEvent (Event event) {
+ switch (event.type) {
+ case SWT.Paint:
+ displayIfNoAnimatorNoCheck();
+ break;
+ case SWT.Resize:
+ updateSizeCheck();
+ break;
+ case SWT.Dispose:
+ GLCanvas.this.dispose();
+ break;
+ }
+ }
+ };
+ addListener (SWT.Resize, listener);
+ addListener (SWT.Paint, listener);
+ addListener (SWT.Dispose, listener);
}
+
private final UpstreamSurfaceHook swtCanvasUpStreamHook = new UpstreamSurfaceHook() {
@Override
public final void create(ProxySurface s) { /* nop */ }
@@ -390,11 +406,13 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
) {
clientArea = nClientArea; // write back new value
- GLDrawableImpl _drawable = drawable;
- if( null != _drawable ) {
- if(DEBUG) {
- System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.width+"x"+nClientArea.height+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
- }
+ final GLDrawableImpl _drawable = drawable;
+ final boolean drawableOK = null != _drawable && _drawable.isRealized();
+ if(DEBUG) {
+ final long dh = drawableOK ? _drawable.getHandle() : 0;
+ System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.x+"/"+nClientArea.y+" "+nClientArea.width+"x"+nClientArea.height+" - drawableHandle 0x"+Long.toHexString(dh));
+ }
+ if( drawableOK ) {
if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
final RecursiveLock _lock = lock;
_lock.lock();
@@ -407,66 +425,154 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
} finally {
_lock.unlock();
}
- }
- sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
- }
+ }
+ }
+ if(0 != x11Window) {
+ SWTAccessor.resizeX11Window(screen.getDevice(), clientArea, x11Window);
+ } else if(0 != gdkWindow) {
+ SWTAccessor.resizeGDKWindow(clientArea, gdkWindow);
+ }
+ sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
}
}
- @Override
- public void display() {
- if( null != drawable || validateDrawableAndContext() ) {
- runInGLThread(makeCurrentAndDisplayOnEDTAction);
- }
+ private boolean isValidAndVisibleOnEDTActionResult;
+ private final Runnable isValidAndVisibleOnEDTAction = new Runnable() {
+ @Override
+ public void run() {
+ isValidAndVisibleOnEDTActionResult = !GLCanvas.this.isDisposed() && GLCanvas.this.isVisible();
+ } };
+
+ private final boolean isValidAndVisibleOnEDT() {
+ synchronized(isValidAndVisibleOnEDTAction) {
+ runOnEDTIfAvail(true, isValidAndVisibleOnEDTAction);
+ return isValidAndVisibleOnEDTActionResult;
+ }
}
-
- /** assumes drawable == null ! */
- protected final boolean validateDrawableAndContext() {
- if( isDisposed() || !isVisible() ) {
+ /** assumes drawable == null || !drawable.isRealized() ! Checks of !isDispose() and isVisible() */
+ protected final boolean validateDrawableAndContextWithCheck() {
+ if( !isValidAndVisibleOnEDT() ) {
return false;
}
+ return validateDrawableAndContextPostCheck();
+ }
+
+ /** assumes drawable == null || !drawable.isRealized() ! No check of !isDispose() and isVisible() */
+ protected final boolean validateDrawableAndContextPostCheck() {
final Rectangle nClientArea = clientArea;
if(0 >= nClientArea.width || 0 >= nClientArea.height) {
return false;
}
+ final boolean res;
final RecursiveLock _lock = lock;
_lock.lock();
try {
- final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(capsRequested.getGLProfile());
-
- /* Native handle for the control, used to associate with GLContext */
- final long nativeWindowHandle = SWTAccessor.getWindowHandle(this);
-
- /* Create a NativeWindow proxy for the SWT canvas */
- ProxySurface proxySurface = null;
- try {
- proxySurface = glFactory.createProxySurface(device, 0 /* screenIdx */, nativeWindowHandle,
- capsRequested, capsChooser, swtCanvasUpStreamHook);
- } catch (GLException gle) {
- // not ready yet ..
- if(DEBUG) { System.err.println(gle.getMessage()); }
+ if(null == drawable) {
+ createDrawableAndContext();
}
-
- if(null != proxySurface) {
- /* Associate a GL surface with the proxy */
- drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
+ if(null != drawable) {
drawable.setRealized(true);
-
- context = (GLContextImpl) drawable.createContext(shareWith);
+ res = drawable.isRealized();
+ } else {
+ res = false;
}
} finally {
_lock.unlock();
+ }
+
+ if(res) {
+ sendReshape = true;
+ if(DEBUG) {
+ System.err.println("SWT GLCanvas realized! "+this+", "+drawable);
+ // Thread.dumpStack();
+ }
}
- final boolean res = null != drawable;
- if(DEBUG && res) {
- System.err.println("SWT GLCanvas realized! "+this+", "+drawable);
- Thread.dumpStack();
- }
- return res;
+ return res;
+ }
+
+ private final void createDrawableAndContext() {
+ final AbstractGraphicsDevice device = screen.getDevice();
+ device.open();
+
+ final long nativeWindowHandle;
+ if( useX11GTK ) {
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(device, capsRequested);
+ final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capsChooser, screen, VisualIDHolder.VID_UNDEFINED);
+ if(DEBUG) {
+ System.err.println("SWT.GLCanvas.X11 factory: "+factory+", chosen config: "+cfg);
+ }
+ if (null == cfg) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+ final int visualID = cfg.getVisualID(VIDType.NATIVE);
+ if( VisualIDHolder.VID_UNDEFINED != visualID ) {
+ // gdkWindow = SWTAccessor.createCompatibleGDKChildWindow(this, visualID, clientArea.width, clientArea.height);
+ // nativeWindowHandle = SWTAccessor.gdk_window_get_xwindow(gdkWindow);
+ x11Window = SWTAccessor.createCompatibleX11ChildWindow(screen, this, visualID, clientArea.width, clientArea.height);
+ nativeWindowHandle = x11Window;
+ } else {
+ throw new GLException("Could not choose valid visualID: 0x"+Integer.toHexString(visualID)+", "+this);
+ }
+ } else {
+ nativeWindowHandle = SWTAccessor.getWindowHandle(this);
+ }
+ final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(capsRequested.getGLProfile());
+
+ // Create a NativeWindow proxy for the SWT canvas
+ ProxySurface proxySurface = glFactory.createProxySurface(device, screen.getIndex(), nativeWindowHandle,
+ capsRequested, capsChooser, swtCanvasUpStreamHook);
+ // Associate a GL surface with the proxy
+ drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setContextCreationFlags(additionalCtxCreationFlags);
+ }
+
+ @Override
+ public void update() {
+ // don't paint background etc .. nop avoids flickering
+ // super.update();
+ }
+
+ /**
+ @Override
+ public boolean forceFocus() {
+ final boolean r = super.forceFocus();
+ if(r && 0 != gdkWindow) {
+ SWTGTKUtil.focusGDKWindow(gdkWindow);
+ }
+ return r;
+ } */
+
+ @Override
+ public void dispose() {
+ runInGLThread(disposeOnEDTGLAction);
+ super.dispose();
+ }
+
+ private final void displayIfNoAnimatorNoCheck() {
+ if ( !helper.isAnimatorAnimatingOnOtherThread() ) {
+ final boolean drawableOK = null != drawable && drawable.isRealized();
+ if( drawableOK || validateDrawableAndContextPostCheck() ) {
+ runInGLThread(makeCurrentAndDisplayOnGLAction);
+ }
+ }
}
+ //
+ // GL[Auto]Drawable
+ //
+
+ @Override
+ public void display() {
+ final boolean drawableOK = null != drawable && drawable.isRealized();
+ if( drawableOK || validateDrawableAndContextWithCheck() ) {
+ runInGLThread(makeCurrentAndDisplayOnGLAction);
+ }
+ }
+
@Override
public final Object getUpstreamWidget() {
return this;
@@ -692,18 +798,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public void swapBuffers() throws GLException {
- runInGLThread(swapBuffersOnEDTAction);
- }
-
- @Override
- public void update() {
- // don't paint background etc .. nop avoids flickering
- }
-
- @Override
- public void dispose() {
- runInGLThread(disposeOnEDTGLAction);
- super.dispose();
+ runInGLThread(swapBuffersOnGLAction);
}
/**
@@ -746,7 +841,32 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
} */
action.run();
}
+
+ private void runOnEDTIfAvail(boolean wait, final Runnable action) {
+ final Display d = isDisposed() ? null : getDisplay();
+ if( null == d || d.isDisposed() || d.getThread() == Thread.currentThread() ) {
+ action.run();
+ } else if(wait) {
+ d.syncExec(action);
+ } else {
+ d.asyncExec(action);
+ }
+ }
+
+ @Override
+ public String toString() {
+ final GLDrawable _drawable = drawable;
+ final int dw = (null!=_drawable) ? _drawable.getWidth() : -1;
+ final int dh = (null!=_drawable) ? _drawable.getHeight() : -1;
+ return "SWT-GLCanvas[Realized "+isRealized()+
+ ",\n\t"+((null!=_drawable)?_drawable.getClass().getName():"null-drawable")+
+ ",\n\tFactory "+getFactory()+
+ ",\n\thandle 0x"+Long.toHexString(getHandle())+
+ ",\n\tDrawable size "+dw+"x"+dh+
+ ",\n\tSWT size "+getWidth()+"x"+getHeight()+"]";
+ }
+
public static void main(final String[] args) {
System.err.println(VersionUtil.getPlatformInfo());
System.err.println(GlueGenVersion.getInstance());
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index e208cfb28..eba26c7d3 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -34,6 +34,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import org.eclipse.swt.graphics.GCData;
+import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import javax.media.nativewindow.AbstractGraphicsScreen;
@@ -59,12 +60,22 @@ public class SWTAccessor {
private static final Field swt_control_handle;
private static final boolean swt_uses_long_handles;
+ private static Object swt_osx_init = new Object();
+ private static Field swt_osx_control_view = null;
+ private static Field swt_osx_view_id = null;
+
+ private static final String nwt;
+ private static final boolean isOSX;
+ private static final boolean isWindows;
+ private static final boolean isX11;
+ private static final boolean isX11GTK;
+
// X11/GTK, Windows/GDI, ..
private static final String str_handle = "handle";
// OSX/Cocoa
- private static final String str_view = "view"; // OSX
- private static final String str_id = "id"; // OSX
+ private static final String str_osx_view = "view"; // OSX
+ private static final String str_osx_id = "id"; // OSX
// static final String str_NSView = "org.eclipse.swt.internal.cocoa.NSView";
private static final Method swt_control_internal_new_GC;
@@ -73,9 +84,10 @@ public class SWTAccessor {
private static final String str_internal_dispose_GC = "internal_dispose_GC";
private static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS";
- private static final Class<?> OS_gtk_class;
+ public static final Class<?> OS_gtk_class;
private static final String str_OS_gtk_version = "GTK_VERSION";
- private static final VersionNumber OS_gtk_version;
+ public static final VersionNumber OS_gtk_version;
+
private static final Method OS_gtk_widget_realize;
private static final Method OS_gtk_widget_unrealize; // optional (removed in SWT 4.3)
private static final Method OS_GTK_WIDGET_WINDOW;
@@ -85,6 +97,8 @@ public class SWTAccessor {
private static final Method OS_gdk_window_get_display;
private static final Method OS_gdk_x11_drawable_get_xid;
private static final Method OS_gdk_x11_window_get_xid;
+ private static final Method OS_gdk_window_set_back_pixmap;
+
private static final String str_gtk_widget_realize = "gtk_widget_realize";
private static final String str_gtk_widget_unrealize = "gtk_widget_unrealize";
private static final String str_GTK_WIDGET_WINDOW = "GTK_WIDGET_WINDOW";
@@ -94,6 +108,7 @@ public class SWTAccessor {
private static final String str_gdk_window_get_display = "gdk_window_get_display";
private static final String str_gdk_x11_drawable_get_xid = "gdk_x11_drawable_get_xid";
private static final String str_gdk_x11_window_get_xid = "gdk_x11_window_get_xid";
+ private static final String str_gdk_window_set_back_pixmap = "gdk_window_set_back_pixmap";
private static final VersionNumber GTK_VERSION_2_14_0 = new VersionNumber(2, 14, 0);
private static final VersionNumber GTK_VERSION_2_24_0 = new VersionNumber(2, 24, 0);
@@ -108,23 +123,25 @@ public class SWTAccessor {
}
static {
- Field f = null;
-
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
NativeWindowFactory.initSingleton(); // last resort ..
return null;
} } );
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
-
- if(NativeWindowFactory.TYPE_MACOSX != nwt ) {
+ nwt = NativeWindowFactory.getNativeWindowType(false);
+ isOSX = NativeWindowFactory.TYPE_MACOSX == nwt;
+ isWindows = NativeWindowFactory.TYPE_WINDOWS == nwt;
+ isX11 = NativeWindowFactory.TYPE_X11 == nwt;
+
+ Field f = null;
+ if( !isOSX ) {
try {
f = Control.class.getField(str_handle);
} catch (Exception ex) {
throw new NativeWindowException(ex);
}
- }
+ }
swt_control_handle = f; // maybe null !
boolean ulh;
@@ -158,31 +175,32 @@ public class SWTAccessor {
Class<?> c=null;
VersionNumber _gtk_version = new VersionNumber(0, 0, 0);
- Method m1=null, m2=null, m3=null, m4=null, m5=null, m6=null, m7=null, m8=null, m9=null;
- Class<?> handleType = swt_uses_long_handles ? long.class : int.class ;
- if( NativeWindowFactory.TYPE_X11 == nwt ) {
+ Method m1=null, m2=null, m3=null, m4=null, m5=null, m6=null, m7=null, m8=null, m9=null, ma=null;
+ final Class<?> handleType = swt_uses_long_handles ? long.class : int.class ;
+ if( isX11 ) {
// mandatory
try {
c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader());
Field field_OS_gtk_version = c.getField(str_OS_gtk_version);
_gtk_version = GTK_VERSION(field_OS_gtk_version.getInt(null));
m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType);
- if( _gtk_version.compareTo(GTK_VERSION_2_14_0) < 0 ) {
- m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType);
- } else {
+ if (_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) {
m4 = c.getDeclaredMethod(str_gtk_widget_get_window, handleType);
- }
- if( _gtk_version.compareTo(GTK_VERSION_2_24_0) < 0 ) {
- m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType);
} else {
+ m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType);
+ }
+ if (_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0) {
m6 = c.getDeclaredMethod(str_gdk_x11_display_get_xdisplay, handleType);
- m7 = c.getDeclaredMethod(str_gdk_window_get_display, handleType);
- }
- if( _gtk_version.compareTo(GTK_VERSION_3_0_0) < 0 ) {
- m8 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType);
+ m7 = c.getDeclaredMethod(str_gdk_window_get_display, handleType);
} else {
+ m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType);
+ }
+ if (_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0) {
m9 = c.getDeclaredMethod(str_gdk_x11_window_get_xid, handleType);
+ } else {
+ m8 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType);
}
+ ma = c.getDeclaredMethod(str_gdk_window_set_back_pixmap, handleType, handleType, boolean.class);
} catch (Exception ex) { throw new NativeWindowException(ex); }
// optional
try {
@@ -200,25 +218,31 @@ public class SWTAccessor {
OS_gdk_window_get_display = m7;
OS_gdk_x11_drawable_get_xid = m8;
OS_gdk_x11_window_get_xid = m9;
+ OS_gdk_window_set_back_pixmap = ma;
+
+ isX11GTK = isX11 && null != OS_gtk_class;
if(DEBUG) {
System.err.println("SWTAccessor.<init>: GTK Version: "+OS_gtk_version);
}
}
-
-
- static Object getIntOrLong(long arg) {
+
+ private static Number getIntOrLong(long arg) {
if(swt_uses_long_handles) {
return new Long(arg);
}
return new Integer((int) arg);
}
- static void callStaticMethodL2V(Method m, long arg) {
+ private static void callStaticMethodL2V(Method m, long arg) {
ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) });
}
- static long callStaticMethodL2L(Method m, long arg) {
+ private static void callStaticMethodLLZ2V(Method m, long arg0, long arg1, boolean arg3) {
+ ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg0), getIntOrLong(arg1), Boolean.valueOf(arg3) });
+ }
+
+ private static long callStaticMethodL2L(Method m, long arg) {
Object o = ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) });
if(o instanceof Number) {
return ((Number)o).longValue();
@@ -226,13 +250,73 @@ public class SWTAccessor {
throw new InternalError("SWT method "+m.getName()+" didn't return int or long but "+o.getClass());
}
}
-
+
+ //
+ // Public properties
+ //
+
public static boolean isUsingLongHandles() {
return swt_uses_long_handles;
}
+ public static boolean useX11GTK() { return isX11GTK; }
public static VersionNumber GTK_VERSION() { return OS_gtk_version; }
+ //
+ // Common GTK
+ //
+
+ public static long gdk_widget_get_window(long handle) {
+ final long window;
+ if (OS_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) {
+ window = callStaticMethodL2L(OS_gtk_widget_get_window, handle);
+ } else {
+ window = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
+ }
+ if(0 == window) {
+ throw new NativeWindowException("Null gtk-window-handle of SWT handle 0x"+Long.toHexString(handle));
+ }
+ return window;
+ }
+
+ public static long gdk_window_get_xdisplay(long window) {
+ final long xdisplay;
+ if (OS_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0) {
+ final long display = callStaticMethodL2L(OS_gdk_window_get_display, window);
+ if(0 == display) {
+ throw new NativeWindowException("Null display-handle of gtk-window-handle 0x"+Long.toHexString(window));
+ }
+ xdisplay = callStaticMethodL2L(OS_gdk_x11_display_get_xdisplay, display);
+ } else {
+ xdisplay = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, window);
+ }
+ if(0 == xdisplay) {
+ throw new NativeWindowException("Null x11-display-handle of gtk-window-handle 0x"+Long.toHexString(window));
+ }
+ return xdisplay;
+ }
+
+ public static long gdk_window_get_xwindow(long window) {
+ final long xWindow;
+ if (OS_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0) {
+ xWindow = callStaticMethodL2L(OS_gdk_x11_window_get_xid, window);
+ } else {
+ xWindow = callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, window);
+ }
+ if(0 == xWindow) {
+ throw new NativeWindowException("Null x11-window-handle of gtk-window-handle 0x"+Long.toHexString(window));
+ }
+ return xWindow;
+ }
+
+ public static void gdk_window_set_back_pixmap(long window, long pixmap, boolean parent_relative) {
+ callStaticMethodLLZ2V(OS_gdk_window_set_back_pixmap, window, pixmap, parent_relative);
+ }
+
+ //
+ // Common any toolkit
+ //
+
/**
* @param swtControl the SWT Control to retrieve the native widget-handle from
* @return the native widget-handle
@@ -240,15 +324,21 @@ public class SWTAccessor {
*/
public static long getHandle(Control swtControl) throws NativeWindowException {
long h = 0;
- if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
- try {
- Field fView = Control.class.getField(str_view);
- Object view = fView.get(swtControl);
- Field fId = view.getClass().getField(str_id);
- h = fId.getLong(view);
- } catch (Exception ex) {
- throw new NativeWindowException(ex);
- }
+ if( isOSX ) {
+ synchronized(swt_osx_init) {
+ try {
+ if(null == swt_osx_view_id) {
+ swt_osx_control_view = Control.class.getField(str_osx_view);
+ Object view = swt_osx_control_view.get(swtControl);
+ swt_osx_view_id = view.getClass().getField(str_osx_id);
+ h = swt_osx_view_id.getLong(view);
+ } else {
+ h = swt_osx_view_id.getLong( swt_osx_control_view.get(swtControl) );
+ }
+ } catch (Exception ex) {
+ throw new NativeWindowException(ex);
+ }
+ }
} else {
try {
h = swt_control_handle.getLong(swtControl);
@@ -283,49 +373,6 @@ public class SWTAccessor {
}
}
- private static long gdk_x11_display_get_xdisplay(long window) {
- final long xdisplay;
- if ( OS_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0 ) {
- final long display = callStaticMethodL2L(OS_gdk_window_get_display, window);
- if(0 == display) {
- throw new NativeWindowException("Null display-handle of gtk-window-handle 0x"+Long.toHexString(window));
- }
- xdisplay = callStaticMethodL2L(OS_gdk_x11_display_get_xdisplay, display);
- } else {
- xdisplay = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, window);
- }
- if(0 == xdisplay) {
- throw new NativeWindowException("Null x11-display-handle of gtk-window-handle 0x"+Long.toHexString(window));
- }
- return xdisplay;
- }
-
- private static long gdk_widget_get_window(long handle) {
- final long window;
- if ( OS_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0 ) {
- window = callStaticMethodL2L(OS_gtk_widget_get_window, handle);
- } else {
- window = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
- }
- if(0 == window) {
- throw new NativeWindowException("Null gtk-window-handle of SWT handle 0x"+Long.toHexString(handle));
- }
- return window;
- }
-
- private static long gdk_window_get_xwindow(long window) {
- final long xwindow;
- if ( OS_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0 ) {
- xwindow = callStaticMethodL2L(OS_gdk_x11_window_get_xid, window);
- } else {
- xwindow = callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, window);
- }
- if(0 == xwindow) {
- throw new NativeWindowException("Null x11-window-handle of gtk-window-handle 0x"+Long.toHexString(window));
- }
- return xwindow;
- }
-
/**
* @param swtControl the SWT Control to retrieve the native device handle from
* @return the AbstractGraphicsDevice w/ the native device handle
@@ -333,43 +380,49 @@ public class SWTAccessor {
* @throws UnsupportedOperationException if the windowing system is not supported
*/
public static AbstractGraphicsDevice getDevice(Control swtControl) throws NativeWindowException, UnsupportedOperationException {
- long handle = getHandle(swtControl);
- if( null != OS_gtk_class ) {
- final long xdisplay0 = gdk_x11_display_get_xdisplay( gdk_widget_get_window( handle ) );
- // final String displayName = X11Lib.XDisplayString(xdisplay0);
- // final long xdisplay1 = X11Util.openDisplay(displayName);
- // return new X11GraphicsDevice(xdisplay1, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */);
+ final long handle = getHandle(swtControl);
+ if( isX11GTK ) {
+ final long xdisplay0 = gdk_window_get_xdisplay( gdk_widget_get_window( handle ) );
return new X11GraphicsDevice(xdisplay0, AbstractGraphicsDevice.DEFAULT_UNIT, false /* owner */);
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
+ if( isWindows ) {
return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if( isOSX ) {
return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
+ /**
+ *
+ * @param device
+ * @param screen -1 is default screen of the given device, e.g. maybe 0 or determined by native API. >= 0 is specific screen
+ * @return
+ * @throws UnsupportedOperationException
+ */
public static AbstractGraphicsScreen getScreen(AbstractGraphicsDevice device, int screen) throws UnsupportedOperationException {
- if( null != OS_gtk_class ) {
- return new X11GraphicsScreen((X11GraphicsDevice)device, screen);
+ if( isX11 ) {
+ X11GraphicsDevice x11Device = (X11GraphicsDevice)device;
+ if(0 > screen) {
+ screen = x11Device.getDefaultScreen();
+ }
+ return new X11GraphicsScreen(x11Device, screen);
+ }
+ if(0 > screen) {
+ screen = 0; // FIXME: Needs native API utilization
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
- NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if( isWindows || isOSX ) {
return new DefaultGraphicsScreen(device, screen);
}
throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
public static int getNativeVisualID(AbstractGraphicsDevice device, long windowHandle) {
- if( null != OS_gtk_class ) {
+ if( isX11 ) {
return X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
- NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if( isWindows || isOSX ) {
return VisualIDHolder.VID_UNDEFINED;
}
throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
@@ -383,12 +436,13 @@ public class SWTAccessor {
*/
public static long getWindowHandle(Control swtControl) throws NativeWindowException, UnsupportedOperationException {
final long handle = getHandle(swtControl);
- if( null != OS_gtk_class ) {
+ if(0 == handle) {
+ throw new NativeWindowException("Null SWT handle of SWT control "+swtControl);
+ }
+ if( isX11GTK ) {
return gdk_window_get_xwindow( gdk_widget_get_window( handle ) );
}
- final String nwt = NativeWindowFactory.getNativeWindowType(false);
- if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
- NativeWindowFactory.TYPE_MACOSX == nwt ) {
+ if( isWindows || isOSX ) {
return handle;
}
throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
@@ -407,7 +461,7 @@ public class SWTAccessor {
throw new InternalError("SWT internal_new_GC did not return int or long but "+o[0].getClass());
}
}
-
+
public static void disposeGC(final Control swtControl, final long gc, final GCData gcData) {
invoke(true, new Runnable() {
public void run() {
@@ -437,7 +491,7 @@ public class SWTAccessor {
* @see Platform#getOSType()
*/
public static void invoke(boolean wait, Runnable runnable) {
- if( Platform.OS_TYPE == Platform.OSType.MACOS ) {
+ if( isOSX ) {
// Use SWT main thread! Only reliable config w/ -XStartOnMainThread !?
OSXUtil.RunOnMainThread(wait, runnable);
} else {
@@ -445,4 +499,85 @@ public class SWTAccessor {
}
}
+ //
+ // Specific X11 GTK ChildWindow - Using plain X11 native parenting (works well)
+ //
+
+ public static long createCompatibleX11ChildWindow(AbstractGraphicsScreen screen, Control swtControl, int visualID, int width, int height) {
+ final long handle = getHandle(swtControl);
+ final long parentWindow = gdk_widget_get_window( handle );
+ gdk_window_set_back_pixmap (parentWindow, 0, false);
+
+ final long x11ParentHandle = gdk_window_get_xwindow(parentWindow);
+ final long x11WindowHandle = X11Lib.CreateWindow(x11ParentHandle, screen.getDevice().getHandle(), screen.getIndex(), visualID, width, height, true, true);
+
+ return x11WindowHandle;
+ }
+
+ public static void resizeX11Window(AbstractGraphicsDevice device, Rectangle clientArea, long x11Window) {
+ X11Lib.SetWindowPosSize(device.getHandle(), x11Window, clientArea.x, clientArea.y, clientArea.width, clientArea.height);
+ }
+ public static void destroyX11Window(AbstractGraphicsDevice device, long x11Window) {
+ X11Lib.DestroyWindow(device.getHandle(), x11Window);
+ }
+
+ //
+ // Specific X11 SWT/GTK ChildWindow - Using SWT/GTK native parenting (buggy - sporadic resize flickering, sporadic drop of rendering)
+ //
+ // FIXME: Need to use reflection for 32bit access as well !
+ //
+
+ // public static final int GDK_WA_TYPE_HINT = 1 << 9;
+ // public static final int GDK_WA_VISUAL = 1 << 6;
+
+ public static long createCompatibleGDKChildWindow(Control swtControl, int visualID, int width, int height) {
+ return 0;
+ /**
+ final long handle = SWTAccessor.getHandle(swtControl);
+ final long parentWindow = gdk_widget_get_window( handle );
+
+ final long screen = OS.gdk_screen_get_default ();
+ final long gdkvisual = OS.gdk_x11_screen_lookup_visual (screen, visualID);
+
+ final GdkWindowAttr attrs = new GdkWindowAttr();
+ attrs.width = width > 0 ? width : 1;
+ attrs.height = height > 0 ? height : 1;
+ attrs.event_mask = OS.GDK_KEY_PRESS_MASK | OS.GDK_KEY_RELEASE_MASK |
+ OS.GDK_FOCUS_CHANGE_MASK | OS.GDK_POINTER_MOTION_MASK |
+ OS.GDK_BUTTON_PRESS_MASK | OS.GDK_BUTTON_RELEASE_MASK |
+ OS.GDK_ENTER_NOTIFY_MASK | OS.GDK_LEAVE_NOTIFY_MASK |
+ OS.GDK_EXPOSURE_MASK | OS.GDK_VISIBILITY_NOTIFY_MASK |
+ OS.GDK_POINTER_MOTION_HINT_MASK;
+ attrs.window_type = OS.GDK_WINDOW_CHILD;
+ attrs.visual = gdkvisual;
+
+ final long childWindow = OS.gdk_window_new (parentWindow, attrs, OS.GDK_WA_VISUAL|GDK_WA_TYPE_HINT);
+ OS.gdk_window_set_user_data (childWindow, handle);
+ OS.gdk_window_set_back_pixmap (parentWindow, 0, false);
+
+ OS.gdk_window_show (childWindow);
+ OS.gdk_flush();
+ return childWindow; */
+ }
+
+ public static void showGDKWindow(long gdkWindow) {
+ /* OS.gdk_window_show (gdkWindow);
+ OS.gdk_flush(); */
+ }
+ public static void focusGDKWindow(long gdkWindow) {
+ /*
+ OS.gdk_window_show (gdkWindow);
+ OS.gdk_window_focus(gdkWindow, 0);
+ OS.gdk_flush(); */
+ }
+ public static void resizeGDKWindow(Rectangle clientArea, long gdkWindow) {
+ /**
+ OS.gdk_window_move (gdkWindow, clientArea.x, clientArea.y);
+ OS.gdk_window_resize (gdkWindow, clientArea.width, clientArea.height);
+ OS.gdk_flush(); */
+ }
+
+ public static void destroyGDKWindow(long gdkWindow) {
+ // OS.gdk_window_destroy (gdkWindow);
+ }
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
index 67a33e55c..827862002 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
@@ -37,7 +37,7 @@ public class X11DummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize
s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
}
if( 0 == s.getSurfaceHandle() ) {
- final long windowHandle = X11Lib.CreateDummyWindow(device.getHandle(), screen.getIndex(), cfg.getXVisualID(), 64, 64);
+ final long windowHandle = X11Lib.CreateWindow(0, device.getHandle(), screen.getIndex(), cfg.getXVisualID(), 64, 64, false, false);
if(0 == windowHandle) {
throw new NativeWindowException("Creating dummy window failed w/ "+cfg);
}
@@ -59,7 +59,7 @@ public class X11DummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize
}
device.lock();
try {
- X11Lib.DestroyDummyWindow(device.getHandle(), s.getSurfaceHandle());
+ X11Lib.DestroyWindow(device.getHandle(), s.getSurfaceHandle());
s.setSurfaceHandle(0);
s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
} finally {
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index c73952693..a8d45f288 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -31,6 +31,8 @@
#include "jogamp_nativewindow_x11_X11Lib.h"
#include "jogamp_nativewindow_x11_X11Util.h"
+#include <X11/Xatom.h>
+
// #define VERBOSE_ON 1
#ifdef VERBOSE_ON
@@ -85,6 +87,8 @@ Bool XF86VidModeSetGammaRamp(
#define RTLD_DEFAULT NULL
#endif
+#define X11_MOUSE_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask)
+
static const char * const ClazzNameBuffers = "com/jogamp/common/nio/Buffers";
static const char * const ClazzNameBuffersStaticCstrName = "copyByteBuffer";
static const char * const ClazzNameBuffersStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;";
@@ -436,17 +440,62 @@ Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused
return _res;
}
+static void NativewindowX11_setNormalWindowEWMH (Display *dpy, Window w) {
+ Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False );
+ Atom types[1]={0};
+ types[0] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False );
+ XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, 1);
+ XSync(dpy, False);
+}
+
+#define DECOR_USE_MWM 1 // works for known WMs
+// #define DECOR_USE_EWMH 1 // haven't seen this to work (NORMAL->POPUP, never gets undecorated)
+
+/* see <http://tonyobryan.com/index.php?article=9> */
+#define MWM_HINTS_DECORATIONS (1L << 1)
+#define PROP_MWM_HINTS_ELEMENTS 5
+
+static void NativewindowX11_setDecorations (Display *dpy, Window w, Bool decorated) {
+
+#ifdef DECOR_USE_MWM
+ unsigned long mwmhints[PROP_MWM_HINTS_ELEMENTS] = { MWM_HINTS_DECORATIONS, 0, decorated, 0, 0 }; // flags, functions, decorations, input_mode, status
+ Atom _MOTIF_WM_HINTS = XInternAtom( dpy, "_MOTIF_WM_HINTS", False );
+#endif
+
+#ifdef DECOR_USE_EWMH
+ Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False );
+ Atom types[3]={0};
+ int ntypes=0;
+ if(True==decorated) {
+ types[ntypes++] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False );
+ } else {
+ types[ntypes++] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_POPUP_MENU", False );
+ }
+#endif
+
+#ifdef DECOR_USE_MWM
+ XChangeProperty( dpy, w, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char *)&mwmhints, PROP_MWM_HINTS_ELEMENTS);
+#endif
+
+#ifdef DECOR_USE_EWMH
+ XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes);
+#endif
+
+ XSync(dpy, False);
+}
+
/*
* Class: jogamp_nativewindow_x11_X11Lib
- * Method: CreateDummyWindow
- * Signature: (JIIII)J
+ * Method: CreateWindow
+ * Signature: (JJIIIIZZ)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
- (JNIEnv *env, jclass unused, jlong display, jint screen_index, jint visualID, jint width, jint height)
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateWindow
+ (JNIEnv *env, jclass unused, jlong parent, jlong display, jint screen_index, jint visualID, jint width, jint height, jboolean input, jboolean visible)
{
Display * dpy = (Display *)(intptr_t)display;
int scrn_idx = (int)screen_index;
- Window windowParent = 0;
+ Window root = RootWindow(dpy, scrn_idx);
+ Window windowParent = (Window) parent;
Window window = 0;
XVisualInfo visualTemplate;
@@ -473,6 +522,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, 0, 0);
scrn = ScreenOfDisplay(dpy, scrn_idx);
+ if(0==windowParent) {
+ windowParent = root;
+ }
// try given VisualID on screen
memset(&visualTemplate, 0, sizeof(XVisualInfo));
@@ -500,9 +552,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
pVisualQuery=NULL;
}
- if(0==windowParent) {
- windowParent = XRootWindowOfScreen(scrn);
- }
attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap |
CWBorderPixel | CWColormap | CWOverrideRedirect ) ;
@@ -514,15 +563,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */
xswa.backing_planes=0; /* planes to be preserved if possible */
xswa.backing_pixel=0; /* value to use in restoring planes */
+ if( input ) {
+ xswa.event_mask = X11_MOUSE_EVENT_MASK;
+ xswa.event_mask |= KeyPressMask | KeyReleaseMask ;
+ }
+ if( visible ) {
+ xswa.event_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask ;
+ }
xswa.colormap = XCreateColormap(dpy,
- XRootWindow(dpy, scrn_idx),
+ windowParent,
visual,
AllocNone);
window = XCreateWindow(dpy,
windowParent,
- 0, 0,
+ 0, 0, // only a hint, WM most likely will override
width, height,
0, // border width
depth,
@@ -530,9 +586,25 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
visual,
attrMask,
&xswa);
+ if(0==window) {
+ NativewindowCommon_throwNewRuntimeException(env, "could not create Window, bail out!");
+ return 0;
+ }
+
+ NativewindowX11_setNormalWindowEWMH(dpy, window);
+ NativewindowX11_setDecorations(dpy, window, False);
+
+ if( visible ) {
+ XEvent event;
+
+ XMapWindow(dpy, window);
+ }
+
XSync(dpy, False);
- XSelectInput(dpy, window, 0); // no events
+ if( !input ) {
+ XSelectInput(dpy, window, 0); // no events
+ }
// NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0, 1);
@@ -544,10 +616,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
/*
* Class: jogamp_nativewindow_x11_X11Lib
- * Method: DestroyDummyWindow
+ * Method: DestroyWindow
* Signature: (JJ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyWindow
(JNIEnv *env, jclass unused, jlong display, jlong window)
{
Display * dpy = (Display *)(intptr_t)display;
@@ -559,12 +631,37 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow
}
NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, 0, 0);
+ XSelectInput(dpy, w, 0);
XUnmapWindow(dpy, w);
XSync(dpy, False);
XDestroyWindow(dpy, w);
// NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0, 1);
}
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_SetWindowPosSize
+ (JNIEnv *env, jclass unused, jlong display, jlong window, jint x, jint y, jint width, jint height) {
+ Display * dpy = (Display *)(intptr_t)display;
+ Window w = (Window) window;
+ XWindowChanges xwc;
+ int flags = 0;
+
+ memset(&xwc, 0, sizeof(XWindowChanges));
+
+ if(0<=x && 0<=y) {
+ flags |= CWX | CWY;
+ xwc.x=x;
+ xwc.y=y;
+ }
+
+ if(0<width && 0<height) {
+ flags |= CWWidth | CWHeight;
+ xwc.width=width;
+ xwc.height=height;
+ }
+ XConfigureWindow(dpy, w, flags, &xwc);
+ XSync(dpy, False);
+}
+
/*
* Class: jogamp_nativewindow_x11_X11Lib
* Method: GetRelativeLocation
diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
index 5af7afeb3..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,20 +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.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-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;
@@ -67,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");
@@ -126,54 +126,44 @@ 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( newtChildReady ) {
- if( postSetSize ) {
- newtChild.setSize(clientArea.width, clientArea.height);
- postSetSize = false;
+ 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);
}
- newtChild.windowRepaint(0, 0, clientArea.width, clientArea.height);
}
+ break;
+ case SWT.Resize:
+ updateSizeCheck();
+ break;
+ case SWT.Dispose:
+ NewtCanvasSWT.this.dispose();
+ break;
}
}
- });
-
- addControlListener(new ControlListener() {
- @Override
- public void controlMoved(ControlEvent e) {
- }
- @Override
- public void controlResized(final ControlEvent arg0) {
- updateSizeCheck();
- }
- });
-
- addDisposeListener(new DisposeListener() {
- @Override
- public void widgetDisposed(DisposeEvent e) {
- NewtCanvasSWT.this.dispose();
- }
- });
-
+ };
+ addListener (SWT.Resize, listener);
+ addListener (SWT.Paint, listener);
+ addListener (SWT.Dispose, listener);
}
/** assumes nativeWindow == null ! */
protected final boolean validateNative() {
- if( isDisposed() || !isVisible() ) {
- return false;
- }
updateSizeCheck();
final Rectangle nClientArea = clientArea;
if(0 >= nClientArea.width || 0 >= nClientArea.height) {
@@ -216,6 +206,10 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
( nClientArea.width != oClientArea.width || nClientArea.height != oClientArea.height )
) {
clientArea = nClientArea; // write back new value
+ 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 {
@@ -223,7 +217,7 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
}
}
}
-
+
@Override
public void update() {
// don't paint background etc .. nop avoids flickering
@@ -261,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 ?!
}
diff --git a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
index 1c20fe524..7297e5858 100644
--- a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
@@ -25,7 +25,7 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-package com.jogamp.newt.swt;
+package jogamp.newt.swt;
import javax.media.nativewindow.NativeWindowException;
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/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
index e9fe9b401..a3023538f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
@@ -60,8 +60,8 @@ public class GearsES2 implements GLEventListener {
private int swapInterval = 0;
private boolean pmvUseBackingArray = true; // the default for PMVMatrix now, since it's faster
// private MouseListener gearsMouse = new TraceMouseAdapter(new GearsMouseAdapter());
- private MouseListener gearsMouse = new GearsMouseAdapter();
- private KeyListener gearsKeys = new GearsKeyAdapter();
+ public MouseListener gearsMouse = new GearsMouseAdapter();
+ public KeyListener gearsKeys = new GearsKeyAdapter();
private int prevMouseX, prevMouseY;
private boolean doRotate = true;
@@ -352,6 +352,10 @@ public class GearsES2 implements GLEventListener {
window = (Window) source;
width=window.getWidth();
height=window.getHeight();
+ } else if (source instanceof GLAutoDrawable) {
+ GLAutoDrawable glad = (GLAutoDrawable) source;
+ width = glad.getWidth();
+ height = glad.getHeight();
} else if (GLProfile.isAWTAvailable() && source instanceof java.awt.Component) {
java.awt.Component comp = (java.awt.Component) source;
width=comp.getWidth();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java
index a0874e609..1f3bf3156 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java
@@ -366,8 +366,9 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
try {
while( !shallStop && !dsc.display.isDisposed() ) {
- if( !dsc.display.readAndDispatch() ) {
- dsc.display.sleep();
+ if( !dsc.display.readAndDispatch() && !shallStop ) {
+ // blocks on linux .. dsc.display.sleep();
+ Thread.sleep(10);
}
}
} catch (Exception e0) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java
index 0a47b96eb..97b3ab243 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTBug643AsyncExec.java
@@ -45,12 +45,13 @@ import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities ;
import javax.media.opengl.GLProfile;
+import jogamp.newt.swt.SWTEDTUtil;
+import jogamp.newt.swt.event.SWTNewtEventFactory;
import junit.framework.Assert;
import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.newt.opengl.GLWindow ;
import com.jogamp.newt.swt.NewtCanvasSWT ;
-import com.jogamp.newt.swt.SWTEDTUtil;
import com.jogamp.opengl.swt.GLCanvas;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
@@ -121,15 +122,15 @@ public class TestSWTBug643AsyncExec extends UITestCase {
final Runnable swtAsyncAction = new Runnable() {
public void run()
{
- ++swtN ;
- System.err.println("[SWT A-i shallStop "+shallStop+"]: Counter[loc "+swtN+", glob: "+incrSWTCount()+"]");
+ ++swtN ; incrSWTCount();
+ System.err.println("[SWT A-i shallStop "+shallStop+"]: Counter[loc "+swtN+", glob: "+getSWTCount()+"]");
} };
final Runnable newtAsyncAction = new Runnable() {
public void run()
{
- ++newtN ;
- System.err.println("[NEWT A-i shallStop "+shallStop+"]: Counter[loc "+newtN+", glob: "+incrNEWTCount()+"]");
+ ++newtN ; incrNEWTCount();
+ System.err.println("[NEWT A-i shallStop "+shallStop+"]: Counter[loc "+newtN+", glob: "+getNEWTCount()+"]");
} };
public void run()
@@ -219,9 +220,13 @@ public class TestSWTBug643AsyncExec extends UITestCase {
final GLAutoDrawable glad;
if( useJOGLGLCanvas ) {
- glad = GLCanvas.create(dsc.composite, 0, caps, null, null);
- glad.addGLEventListener( new GearsES2() ) ;
- newtDisplay = null;
+ final GearsES2 demo = new GearsES2();
+ final GLCanvas glc = GLCanvas.create(dsc.composite, 0, caps, null, null);
+ final SWTNewtEventFactory swtNewtEventFactory = new SWTNewtEventFactory();
+ swtNewtEventFactory.attachDispatchListener(glc, glc, demo.gearsMouse, demo.gearsKeys);
+ glc.addGLEventListener( demo ) ;
+ glad = glc;
+ newtDisplay = null;
} else if( useNewtCanvasSWT ) {
final GLWindow glWindow = GLWindow.create( caps ) ;
glWindow.addGLEventListener( new GearsES2() ) ;
@@ -287,8 +292,9 @@ public class TestSWTBug643AsyncExec extends UITestCase {
try {
final Display d = dsc.display;
while( !shallStop && !d.isDisposed() ) {
- if( !d.readAndDispatch() ) {
- dsc.display.sleep();
+ if( !d.readAndDispatch() && !shallStop ) {
+ // blocks on linux .. dsc.display.sleep();
+ Thread.sleep(10);
}
}
} catch (Exception e0) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
index a5d2c8012..1822d2eaf 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java
@@ -50,6 +50,7 @@ import org.junit.Test;
import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.opengl.swt.GLCanvas;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLReadBufferUtil;
@@ -58,10 +59,9 @@ import com.jogamp.opengl.util.texture.TextureIO;
/**
* Tests that a basic SWT app can open without crashing under different GL profiles.
* <p>
- * Uses JOGL's new SWT GLCanvas.
- * </p>
- * <p>
- * Note: To employ custom GLCapabilities, NewtCanvasSWT shall be used.
+ * Uses JOGL's new SWT GLCanvas,
+ * which allows utilizing custom GLCapability settings,
+ * independent from the already instantiated SWT visual.
* </p>
* <p>
* Note that {@link SWTAccessor#invoke(boolean, Runnable)} is still used to comply w/
@@ -188,6 +188,14 @@ public class TestSWTJOGLGLCanvas01GLn extends UITestCase {
runTestAGL( new GLCapabilities(GLProfile.getGL2ES2()), new GearsES2() );
}
+ @Test
+ public void test_MultisampleAndAlpha() throws InterruptedException {
+ GLCapabilities caps = new GLCapabilities(GLProfile.getGL2ES2());
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(2);
+ runTestAGL( caps, new MultisampleDemoES2(true) );
+ }
+
static int atoi(String a) {
int i=0;
try {