diff options
Diffstat (limited to 'src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java')
-rw-r--r-- | src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java | 362 |
1 files changed, 247 insertions, 115 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java index 0ca5cd297..8d46d805a 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 2010 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: - * + * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * + * * - Redistribution 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. - * + * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A @@ -29,17 +29,18 @@ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * + * * You acknowledge that this software is not designed or intended for use * in the design, construction, operation or maintenance of any nuclear * facility. - * + * * Sun gratefully acknowledges that this software was originally authored * and developed by Kenneth Bradley Russell and Christopher John Kline. */ package jogamp.nativewindow.jawt.macosx; +import java.awt.Component; import java.nio.Buffer; import java.security.AccessController; import java.security.PrivilegedAction; @@ -48,12 +49,13 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.Capabilities; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.SurfaceChangeable; +import javax.media.nativewindow.MutableSurface; import javax.media.nativewindow.util.Point; -import com.jogamp.nativewindow.MutableGraphicsConfiguration; import com.jogamp.nativewindow.awt.JAWTWindow; +import jogamp.nativewindow.Debug; +import jogamp.nativewindow.awt.AWTMisc; import jogamp.nativewindow.jawt.JAWT; import jogamp.nativewindow.jawt.JAWTFactory; import jogamp.nativewindow.jawt.JAWTUtil; @@ -62,7 +64,15 @@ import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo; import jogamp.nativewindow.jawt.macosx.JAWT_MacOSXDrawingSurfaceInfo; import jogamp.nativewindow.macosx.OSXUtil; -public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { +public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { + /** May lead to deadlock, due to AWT pos comparison .. don't enable for Applets! */ + private static final boolean DEBUG_CALAYER_POS_CRITICAL; + + static { + Debug.initSingleton(); + DEBUG_CALAYER_POS_CRITICAL = Debug.isPropertyDefined("nativewindow.debug.JAWT.OSXCALayerPos", true /* jnlpAlias */); + } + public MacOSXJAWTWindow(Object comp, AbstractGraphicsConfiguration config) { super(comp, config); if(DEBUG) { @@ -70,70 +80,152 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { } } + @Override protected void invalidateNative() { - surfaceHandle=0; - if(isOffscreenLayerSurfaceEnabled()) { - if(0 != rootSurfaceLayerHandle) { - OSXUtil.DestroyCALayer(rootSurfaceLayerHandle); - rootSurfaceLayerHandle = 0; - } - if(0 != drawable) { - OSXUtil.DestroyNSWindow(drawable); - drawable = 0; + if(DEBUG) { + System.err.println("MacOSXJAWTWindow.invalidateNative(): osh-enabled "+isOffscreenLayerSurfaceEnabled()+ + ", osd-set "+offscreenSurfaceDrawableSet+ + ", osd "+toHexString(offscreenSurfaceDrawable)+ + ", osl "+toHexString(getAttachedSurfaceLayer())+ + ", rsl "+toHexString(rootSurfaceLayer)+ + ", wh "+toHexString(windowHandle)+" - "+Thread.currentThread().getName()); + } + offscreenSurfaceDrawable=0; + offscreenSurfaceDrawableSet=false; + if( isOffscreenLayerSurfaceEnabled() ) { + if(0 != windowHandle) { + OSXUtil.DestroyNSWindow(windowHandle); } + OSXUtil.RunOnMainThread(false, new Runnable() { + @Override + public void run() { + if( 0 != rootSurfaceLayer ) { + if( 0 != jawtSurfaceLayersHandle) { + UnsetJAWTRootSurfaceLayer0(jawtSurfaceLayersHandle, rootSurfaceLayer); + } + OSXUtil.DestroyCALayer(rootSurfaceLayer); + rootSurfaceLayer = 0; + } + jawtSurfaceLayersHandle = 0; + } + }); } + windowHandle=0; } + @Override protected void attachSurfaceLayerImpl(final long layerHandle) { - OSXUtil.AddCASublayer(rootSurfaceLayerHandle, layerHandle); - } - - protected void detachSurfaceLayerImpl(final long layerHandle) { - OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle); - } - - public long getSurfaceHandle() { - return isOffscreenLayerSurfaceEnabled() ? surfaceHandle : super.getSurfaceHandle() ; + OSXUtil.RunOnMainThread(false, new Runnable() { + @Override + public void run() { + // AWT position is top-left w/ insets, where CALayer position is bottom/left from root CALayer w/o insets. + // Determine p0: components location on screen w/o insets. + // CALayer position will be determined in native code. + // See detailed description in {@link JAWTUtil#JAWT_OSX_CALAYER_QUIRK_LAYOUT} + final Point p0 = new Point(); + final Component outterComp = getLocationOnScreenNonBlocking(p0, component); + final java.awt.Insets outterInsets = AWTMisc.getInsets(outterComp, true); + final Point p1 = (Point)p0.cloneMutable(); + p1.translate(-outterComp.getX(), -outterComp.getY()); + if( null != outterInsets ) { + p1.translate(-outterInsets.left, -outterInsets.top); + } + + if( DEBUG_CALAYER_POS_CRITICAL ) { + final java.awt.Point pA0 = component.getLocationOnScreen(); + final Point pA1 = new Point(pA0.x, pA0.y); + pA1.translate(-outterComp.getX(), -outterComp.getY()); + if( null != outterInsets ) { + pA1.translate(-outterInsets.left, -outterInsets.top); + } + System.err.println("JAWTWindow.attachSurfaceLayerImpl: "+toHexString(layerHandle) + ", [ins "+outterInsets+"], pA "+pA0+" -> "+pA1+ + ", p0 "+p0+" -> "+p1+", bounds "+bounds); + } else if( DEBUG ) { + System.err.println("JAWTWindow.attachSurfaceLayerImpl: "+toHexString(layerHandle) + ", [ins "+outterInsets+"], p0 "+p0+" -> "+p1+", bounds "+bounds); + } + OSXUtil.AddCASublayer(rootSurfaceLayer, layerHandle, p1.getX(), p1.getY(), getWidth(), getHeight(), JAWTUtil.getOSXCALayerQuirks()); + } } ); } - - public void setSurfaceHandle(long surfaceHandle) { - if( !isOffscreenLayerSurfaceEnabled() ) { - throw new java.lang.UnsupportedOperationException("Not using CALAYER"); + + @Override + protected void layoutSurfaceLayerImpl(long layerHandle, boolean visible) { + final int caLayerQuirks = JAWTUtil.getOSXCALayerQuirks(); + // AWT position is top-left w/ insets, where CALayer position is bottom/left from root CALayer w/o insets. + // Determine p0: components location on screen w/o insets. + // CALayer position will be determined in native code. + // See detailed description in {@link JAWTUtil#JAWT_OSX_CALAYER_QUIRK_LAYOUT} + final Point p0 = new Point(); + final Component outterComp = getLocationOnScreenNonBlocking(p0, component); + final java.awt.Insets outterInsets = AWTMisc.getInsets(outterComp, true); + final Point p1 = (Point)p0.cloneMutable(); + p1.translate(-outterComp.getX(), -outterComp.getY()); + if( null != outterInsets ) { + p1.translate(-outterInsets.left, -outterInsets.top); } - if(DEBUG) { - System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle)); + + if( DEBUG_CALAYER_POS_CRITICAL ) { + final java.awt.Point pA0 = component.getLocationOnScreen(); + final Point pA1 = new Point(pA0.x, pA0.y); + pA1.translate(-outterComp.getX(), -outterComp.getY()); + if( null != outterInsets ) { + pA1.translate(-outterInsets.left, -outterInsets.top); + } + System.err.println("JAWTWindow.layoutSurfaceLayerImpl: "+toHexString(layerHandle) + ", quirks "+caLayerQuirks+", visible "+visible+ + ", [ins "+outterInsets+"], pA "+pA0+" -> "+pA1+ + ", p0 "+p0+" -> "+p1+", bounds "+bounds); + } else if( DEBUG ) { + System.err.println("JAWTWindow.layoutSurfaceLayerImpl: "+toHexString(layerHandle) + ", quirks "+caLayerQuirks+", visible "+visible+ + ", [ins "+outterInsets+"], p0 "+p0+" -> "+p1+", bounds "+bounds); } - sscSet &= 0 != surfaceHandle; // reset ssc flag if NULL surfaceHandle, ie. back to JAWT - this.surfaceHandle = surfaceHandle; + OSXUtil.FixCALayerLayout(rootSurfaceLayer, layerHandle, visible, p1.getX(), p1.getY(), getWidth(), getHeight(), caLayerQuirks); } - public void surfaceSizeChanged(int width, int height) { - sscSet = true; - sscWidth = width; - sscHeight = height; + @Override + protected void detachSurfaceLayerImpl(final long layerHandle, final Runnable detachNotify) { + OSXUtil.RunOnMainThread(false, new Runnable() { + @Override + public void run() { + detachNotify.run(); + OSXUtil.RemoveCASublayer(rootSurfaceLayer, layerHandle); + } } ); } - public int getWidth() { - return sscSet ? sscWidth : super.getWidth(); + @Override + public final long getWindowHandle() { + return windowHandle; } - public int getHeight() { - return sscSet ? sscHeight: super.getHeight(); + @Override + public final long getSurfaceHandle() { + return offscreenSurfaceDrawableSet ? offscreenSurfaceDrawable : drawable /* super.getSurfaceHandle() */ ; + } + + @Override + public void setSurfaceHandle(long surfaceHandle) { + if( !isOffscreenLayerSurfaceEnabled() ) { + throw new java.lang.UnsupportedOperationException("Not using CALAYER"); + } + if(DEBUG) { + System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): "+toHexString(surfaceHandle)); + } + this.offscreenSurfaceDrawable = surfaceHandle; + this.offscreenSurfaceDrawableSet = true; } + @Override protected JAWT fetchJAWTImpl() throws NativeWindowException { // use offscreen if supported and [ applet or requested ] return JAWTUtil.getJAWT(getShallUseOffscreenLayer() || isApplet()); } + + @Override protected int lockSurfaceImpl() throws NativeWindowException { int ret = NativeWindow.LOCK_SURFACE_NOT_READY; - if(null == ds) { - ds = getJAWT().GetDrawingSurface(component); - if (ds == null) { - // Widget not yet realized - unlockSurfaceImpl(); - return NativeWindow.LOCK_SURFACE_NOT_READY; - } + ds = getJAWT().GetDrawingSurface(component); + if (ds == null) { + // Widget not yet realized + unlockSurfaceImpl(); + return NativeWindow.LOCK_SURFACE_NOT_READY; } int res = ds.Lock(); dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ; @@ -149,21 +241,20 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) { ret = NativeWindow.LOCK_SURFACE_CHANGED; } - if(null == dsi) { - if (firstLock) { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - dsi = ds.GetDrawingSurfaceInfo(); - return null; - } - }); - } else { - dsi = ds.GetDrawingSurfaceInfo(); - } - if (dsi == null) { - unlockSurfaceImpl(); - return NativeWindow.LOCK_SURFACE_NOT_READY; - } + if (firstLock) { + AccessController.doPrivileged(new PrivilegedAction<Object>() { + @Override + public Object run() { + dsi = ds.GetDrawingSurfaceInfo(); + return null; + } + }); + } else { + dsi = ds.GetDrawingSurfaceInfo(); + } + if (dsi == null) { + unlockSurfaceImpl(); + return NativeWindow.LOCK_SURFACE_NOT_READY; } updateBounds(dsi.getBounds()); if (DEBUG && firstLock ) { @@ -177,58 +268,83 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { return NativeWindow.LOCK_SURFACE_NOT_READY; } drawable = macosxdsi.getCocoaViewRef(); - + if (drawable == 0) { unlockSurfaceImpl(); return NativeWindow.LOCK_SURFACE_NOT_READY; } else { + windowHandle = OSXUtil.GetNSWindow(drawable); ret = NativeWindow.LOCK_SUCCESS; } } else { /** * Only create a fake invisible NSWindow for the drawable handle * to please frameworks requiring such (eg. NEWT). - * - * The actual surface/ca-layer shall be created/attached - * by the upper framework (JOGL) since they require more information. + * + * The actual surface/ca-layer shall be created/attached + * by the upper framework (JOGL) since they require more information. */ + String errMsg = null; if(0 == drawable) { - drawable = OSXUtil.CreateNSWindow(0, 0, getBounds().getWidth(), getBounds().getHeight()); - if(0 == drawable) { - unlockSurfaceImpl(); - throw new NativeWindowException("Unable to created dummy NSWindow (layered case)"); + windowHandle = OSXUtil.CreateNSWindow(0, 0, 64, 64); + if(0 == windowHandle) { + errMsg = "Unable to create dummy NSWindow (layered case)"; + } else { + drawable = OSXUtil.GetNSView(windowHandle); + if(0 == drawable) { + errMsg = "Null NSView of NSWindow "+toHexString(windowHandle); + } } - // fix caps reflecting offscreen! - Capabilities caps = (Capabilities) getPrivateGraphicsConfiguration().getChosenCapabilities().cloneMutable(); - caps.setOnscreen(false); - getPrivateGraphicsConfiguration().setChosenCapabilities(caps); - caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable(); - caps.setOnscreen(false); - ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps); - } - if(0 == rootSurfaceLayerHandle) { - rootSurfaceLayerHandle = OSXUtil.CreateCALayer(); - if(0 == rootSurfaceLayerHandle) { - OSXUtil.DestroyNSWindow(drawable); - drawable = 0; - unlockSurfaceImpl(); - throw new NativeWindowException("Could not create root CALayer: "+this); + if(null == errMsg) { + // Fix caps reflecting offscreen! (no GL available here ..) + final Capabilities caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable(); + caps.setOnscreen(false); + setChosenCapabilities(caps); } - if(!AttachJAWTSurfaceLayer0(dsi.getBuffer(), rootSurfaceLayerHandle)) { - OSXUtil.DestroyCALayer(rootSurfaceLayerHandle); - rootSurfaceLayerHandle = 0; - OSXUtil.DestroyNSWindow(drawable); - drawable = 0; - unlockSurfaceImpl(); - throw new NativeWindowException("Could not attach JAWT surfaceLayerHandle: "+this); + } + if(null == errMsg) { + jawtSurfaceLayersHandle = GetJAWTSurfaceLayersHandle0(dsi.getBuffer()); + OSXUtil.RunOnMainThread(false, new Runnable() { + @Override + public void run() { + String errMsg = null; + if(0 == rootSurfaceLayer && 0 != jawtSurfaceLayersHandle) { + rootSurfaceLayer = OSXUtil.CreateCALayer(bounds.getWidth(), bounds.getHeight()); + if(0 == rootSurfaceLayer) { + errMsg = "Could not create root CALayer"; + } else { + try { + SetJAWTRootSurfaceLayer0(jawtSurfaceLayersHandle, rootSurfaceLayer); + } catch(Exception e) { + errMsg = "Could not set JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayer)+", cause: "+e.getMessage(); + } + } + if(null != errMsg) { + if(0 != rootSurfaceLayer) { + OSXUtil.DestroyCALayer(rootSurfaceLayer); + rootSurfaceLayer = 0; + } + throw new NativeWindowException(errMsg+": "+MacOSXJAWTWindow.this); + } + } + } } ); + } + if(null != errMsg) { + if(0 != windowHandle) { + OSXUtil.DestroyNSWindow(windowHandle); + windowHandle = 0; } + drawable = 0; + unlockSurfaceImpl(); + throw new NativeWindowException(errMsg+": "+this); } ret = NativeWindow.LOCK_SUCCESS; } - + return ret; } - + + @Override protected void unlockSurfaceImpl() throws NativeWindowException { if(null!=ds) { if (null!=dsi) { @@ -247,7 +363,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { System.err.println("MaxOSXJAWTWindow: 0x"+Integer.toHexString(this.hashCode())+" - thread: "+Thread.currentThread().getName()); dumpJAWTInfo(); } - + /** * {@inheritDoc} * <p> @@ -257,32 +373,48 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable { * .. * ds = getJAWT().GetDrawingSurface(component); * due to a SIGSEGV. - * + * * Hence we have some threading / sync issues with the native JAWT implementation. - * </p> + * </p> */ @Override - public Point getLocationOnScreen(Point storage) { - return getLocationOnScreenNonBlocking(storage, component); - } + public Point getLocationOnScreen(Point storage) { + if( null == storage ) { + storage = new Point(); + } + getLocationOnScreenNonBlocking(storage, component); + return storage; + } + @Override protected Point getLocationOnScreenNativeImpl(final int x0, final int y0) { return null; } - private static native boolean AttachJAWTSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer); - // private static native boolean DetachJAWTSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer); - + + private static native long GetJAWTSurfaceLayersHandle0(Buffer jawtDrawingSurfaceInfoBuffer); + + /** + * Set the given root CALayer in the JAWT surface + */ + private static native void SetJAWTRootSurfaceLayer0(long jawtSurfaceLayersHandle, long caLayer); + + /** + * Unset the given root CALayer in the JAWT surface, passing the NIO DrawingSurfaceInfo buffer + */ + private static native void UnsetJAWTRootSurfaceLayer0(long jawtSurfaceLayersHandle, long caLayer); + // Variables for lockSurface/unlockSurface private JAWT_DrawingSurface ds; private boolean dsLocked; private JAWT_DrawingSurfaceInfo dsi; - + private long jawtSurfaceLayersHandle; + private JAWT_MacOSXDrawingSurfaceInfo macosxdsi; - - private long rootSurfaceLayerHandle = 0; // attached to the JAWT_SurfaceLayer - - private long surfaceHandle = 0; - private int sscWidth, sscHeight; - private boolean sscSet = false; - + + private volatile long rootSurfaceLayer = 0; // attached to the JAWT_SurfaceLayer + + private long windowHandle = 0; + private long offscreenSurfaceDrawable = 0; + private boolean offscreenSurfaceDrawableSet = false; + // Workaround for instance of 4796548 private boolean firstLock = true; |