diff options
author | Sven Gothel <[email protected]> | 2013-03-19 00:33:00 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-03-19 00:33:00 +0100 |
commit | 81cbcdc8469143587b2044661dd613c798ae02ba (patch) | |
tree | 813982c77435a9ca75225019b8ea0ebe3d22b08c | |
parent | f354fb204d8973453c538dda78a2c82c87be61dc (diff) |
OSX/NEWT: Following CALayer streaming design, i.e. issue NSWindow/NSView Ops on main-thread w/o blocking; NEWT/WindowImpl: Volatile multithreaded mutable values
Similar to commits:
28c6472335b924080d638b33a28f8f4eedb459b1
f354fb204d8973453c538dda78a2c82c87be61dc
main-thread operations cannot block main-thread.
Luckily we are able to create the NSWindow and NSView instance uninitialized (deferred) on the current thread,
while issuing their initialization on the main-thread w/o blocking.
Further more a size glitch is fixed, which didn't take the title bar into account.
+++
NEWT/WindowImpl: Volatile multithreaded mutable values
Since position, size and other attributes might get changes off-thread, these fields needs to be volatile.
-rwxr-xr-x | make/scripts/tests.sh | 6 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/DefaultEDTUtil.java | 1 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/WindowImpl.java | 17 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java | 165 | ||||
-rw-r--r-- | src/newt/native/MacWindow.m | 257 | ||||
-rw-r--r-- | src/newt/native/NewtMacWindow.h | 18 | ||||
-rw-r--r-- | src/newt/native/NewtMacWindow.m | 145 |
7 files changed, 376 insertions, 233 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 8cc3fd84a..71e8ef98d 100755 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -90,6 +90,7 @@ function jrun() { #D_ARGS="-Djogl.debug.GLSLCode" #D_ARGS="-Djogl.debug.GLSLCode -Djogl.debug.DebugGL -Djogl.debug.TraceGL" #D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.JAWT -Dnewt.debug.Window" + #D_ARGS="-Dnativewindow.debug.JAWT -Djogamp.debug.TaskBase.TraceSource" #D_ARGS="-Djogl.debug.GLContext.TraceSwitch" #D_ARGS="-Djogl.debug.FixedFuncPipeline -Djogl.debug.GLSLCode" #D_ARGS="-Djogl.debug.FixedFuncPipeline -Djogl.debug.GLSLState" @@ -268,7 +269,7 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestOlympicES1NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestRedSquareES1NEWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $* -#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $* +testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testawtswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $* @@ -348,8 +349,7 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch10NEWT $* #testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch11NewtAWT $* #testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch12AWT $* -testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch21Newt2AWT $* - +#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch21Newt2AWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $* #testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $* diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java index 3c015d3ec..651522799 100644 --- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java +++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java @@ -332,6 +332,7 @@ public class DefaultEDTUtil implements EDTUtil { validateNoRecursiveLocksHold(); if(!task.hasWaiter() && null != task.getThrowable()) { // at least dump stack-trace in case nobody waits for result + System.err.println("DefaultEDT.run(): Catched exception occured on thread "+Thread.currentThread().getName()+": "+task.toString()); task.getThrowable().printStackTrace(); } } diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 448b192a2..c01f880fc 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -82,9 +82,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer /** Timeout of queued events (repaint and resize) */ static final long QUEUED_EVENT_TO = 1200; // ms - + + // + // Volatile: Multithread Mutable Access + // private volatile long windowHandle = 0; // lifecycle critical private volatile boolean visible = false; // lifecycle critical + private volatile boolean hasFocus = false; + private volatile int width = 128, height = 128; // client-area size w/o insets, default: may be overwritten by user + private volatile int x = 64, y = 64; // client-area pos w/o insets + private volatile Insets insets = new Insets(); // insets of decoration (if top-level && decorated) + private RecursiveLock windowLock = LockFactory.createRecursiveLock(); // Window instance wide lock private int surfaceLockCount = 0; // surface lock recursion count @@ -95,12 +103,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private AbstractGraphicsConfiguration config = null; // control access due to delegation protected CapabilitiesImmutable capsRequested = null; protected CapabilitiesChooser capabilitiesChooser = null; // default null -> default - private boolean fullscreen = false, hasFocus = false, brokenFocusChange = false; - private int width = 128, height = 128; // client-area size w/o insets, default: may be overwritten by user - private int x = 64, y = 64; // client-area pos w/o insets + private boolean fullscreen = false, brokenFocusChange = false; private boolean autoPosition = true; // default: true (allow WM to choose top-level position, if not set by user) - private Insets insets = new Insets(); // insets of decoration (if top-level && decorated) - + private int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen client-area size/pos w/o insets private NativeWindow nfs_parent = null; // non fullscreen parent, in case explicit reparenting is performed (offscreen) private String title = "Newt Window"; diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index 6e9335f08..d3a92e023 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -49,7 +49,6 @@ import jogamp.newt.WindowImpl; import jogamp.newt.driver.DriverClearFocus; import jogamp.newt.driver.DriverUpdatePosition; -import com.jogamp.common.util.Function; import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.KeyEvent; @@ -86,7 +85,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl sscSurfaceHandle = 0; isOffscreenInstance = false; if (0 != handle) { - OSXUtil.RunOnMainThread(true, new Runnable() { + OSXUtil.RunOnMainThread(false, new Runnable() { public void run() { close0( handle ); } } ); @@ -101,18 +100,31 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl @Override protected int lockSurfaceImpl() { - if(!isOffscreenInstance) { - return lockSurface0(getWindowHandle()) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY; + /** + * if( isOffscreenInstance ) { + * return LOCK_SUCCESS; + * } + */ + final long w = getWindowHandle(); + final long v = surfaceHandle; + if( 0 != v && 0 != w ) { + return lockSurface0(w, v) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY; } - return LOCK_SUCCESS; + return LOCK_SURFACE_NOT_READY; } @Override protected void unlockSurfaceImpl() { - if(!isOffscreenInstance) { - final long h = getWindowHandle(); - if(0 != h) { - unlockSurface0(h); + /** + * if( isOffscreenInstance ) { + * return; + * } + */ + final long w = getWindowHandle(); + final long v = surfaceHandle; + if(0 != w && 0 != v) { + if( !unlockSurface0(w, v) ) { + throw new NativeWindowException("Failed to unlock surface, probably not locked!"); } } } @@ -130,7 +142,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl sscSurfaceHandle = surfaceHandle; if (isNativeValid()) { if (0 != sscSurfaceHandle) { - orderOut0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); + orderOut0( 0 != getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); } /** this is done by recreation! else if (isVisible()){ orderFront0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); @@ -172,7 +184,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow: updatePosition() -> abs child-client-pos: "+pS); } - setWindowClientTopLeftPoint0(handle, pS.getX(), pS.getY()); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + setWindowClientTopLeftPoint0(handle, pS.getX(), pS.getY()); + } } ); // no native event (fullscreen, some reparenting) positionChanged(true, pS.getX(), pS.getY()); } @@ -189,14 +204,17 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow: sizeChanged() "+newWidth+"x"+newHeight+" -> abs child-client-pos "+p0S); } - setWindowClientTopLeftPoint0(getWindowHandle(), p0S.getX(), p0S.getY()); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + setWindowClientTopLeftPoint0(getWindowHandle(), p0S.getX(), p0S.getY()); + } } ); } } super.sizeChanged(defer, newWidth, newHeight, force); } @Override - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, int flags) { final boolean _isOffscreenInstance = isOffscreenInstance(this, this.getParent()); isOffscreenInstance = 0 != sscSurfaceHandle || _isOffscreenInstance; final PointImmutable pClientLevelOnSreen; @@ -224,7 +242,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl ", ioi: "+_isOffscreenInstance+ ") -> "+isOffscreenInstance+ "\n\t, "+getReconfigureFlagsAsString(null, flags)); - Thread.dumpStack(); + // Thread.dumpStack(); } if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) { @@ -244,11 +262,12 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl createWindow(false, 0 != getWindowHandle(), pClientLevelOnSreen, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); } if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; } - } - if( width>0 && height>0 && x>=0 && y>=0 ) { - if( !isOffscreenInstance ) { - // setContentSize0(getWindowHandle(), width, height); - setWindowClientTopLeftPointAndSize0(getWindowHandle(), pClientLevelOnSreen.getX(), pClientLevelOnSreen.getY(), width, height); + } else if( width>0 && height>0 ) { + if( !isOffscreenInstance ) { + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + setWindowClientTopLeftPointAndSize0(getWindowHandle(), pClientLevelOnSreen.getX(), pClientLevelOnSreen.getY(), width, height); + } } ); } // else offscreen size is realized via recreation // no native event (fullscreen, some reparenting) positionChanged(true, x, y); @@ -297,19 +316,25 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl /** Callback for native screen position change event of the client area. */ protected void screenPositionChanged(boolean defer, int newX, int newY) { // passed coordinates are in screen position of the client area - if(DEBUG_IMPLEMENTATION) { - System.err.println("MacWindow.positionChanged (Screen Pos): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> "+newX+"/"+newY); - } if(getWindowHandle()!=0) { final NativeWindow parent = getParent(); - if(null == parent) { + if( null == parent || isOffscreenInstance ) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("MacWindow.positionChanged.0 (Screen Pos - TOP): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> "+newX+"/"+newY); + } positionChanged(defer, newX, newY); } else { // screen position -> rel child window position Point absPos = new Point(newX, newY); - absPos.translate( parent.getLocationOnScreen(null).scale(-1, -1) ); + Point parentOnScreen = parent.getLocationOnScreen(null); + absPos.translate( parentOnScreen.scale(-1, -1) ); + if(DEBUG_IMPLEMENTATION) { + System.err.println("MacWindow.positionChanged.1 (Screen Pos - CHILD): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> absPos "+newX+"/"+newY+", parentOnScreen "+parentOnScreen+" -> "+absPos); + } positionChanged(defer, absPos.getX(), absPos.getY()); } + } else if(DEBUG_IMPLEMENTATION) { + System.err.println("MacWindow.positionChanged.2 (Screen Pos - IGN): ("+getThreadName()+"): (defer: "+defer+") "+getX()+"/"+getY()+" -> "+newX+"/"+newY); } } @@ -383,65 +408,69 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl final PointImmutable pS, final int width, final int height, final boolean fullscreen) { - if(0!=getWindowHandle() && !recreate) { + if( 0 != getWindowHandle() && !recreate ) { return; } try { - if(0!=getWindowHandle()) { - // save the view .. close the window - surfaceHandle = OSXUtil.RunOnMainThread(true, new Function<Long, Object>() { - public Long eval(Object... args) { - return Long.valueOf( - changeContentView0(getParentWindowHandle(), getWindowHandle(), 0) ); - } } ).longValue(); - if(recreate && 0==surfaceHandle) { - throw new NativeWindowException("Internal Error - recreate, window but no view"); - } - OSXUtil.RunOnMainThread(true, new Runnable() { - public void run() { - close0( getWindowHandle() ); - } } ); + final long parentWin = getParentWindowHandle(); + if( 0 != getWindowHandle() ) { + final long thisWin = getWindowHandle(); setWindowHandle(0); + + if( 0 == surfaceHandle ) { + throw new NativeWindowException("Internal Error - create w/ window, but no Newt NSView"); + } + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + changeContentView0(parentWin, thisWin, 0); + close0( thisWin ); + } } ); } else { - surfaceHandle = 0; + if( 0 != surfaceHandle ) { + throw new NativeWindowException("Internal Error - create w/o window, but has Newt NSView"); + } + surfaceHandle = createView0(pS.getX(), pS.getY(), width, height, fullscreen, getScreen().getIndex()); + if( 0 == surfaceHandle ) { + throw new NativeWindowException("Could not create native view "+Thread.currentThread().getName()+" "+this); + } } - setWindowHandle( OSXUtil.RunOnMainThread(true, new Function<Long, Object>() { - public Long eval(Object... args) { - return Long.valueOf( - createWindow0( getParentWindowHandle(), - pS.getX(), pS.getY(), width, height, - (getGraphicsConfiguration().getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance), - fullscreen, - ( (isUndecorated() || offscreenInstance) ? NSBorderlessWindowMask : - NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask ), - NSBackingStoreBuffered, - getScreen().getIndex(), surfaceHandle) ); - } } ).longValue() ); - - if (getWindowHandle() == 0) { - throw new NativeWindowException("Could create native window "+Thread.currentThread().getName()+" "+this); - } - surfaceHandle = contentView0(getWindowHandle()); - if( offscreenInstance ) { - orderOut0(0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle()); - } else { - setTitle0(getWindowHandle(), getTitle()); + final long newWin = createWindow0( pS.getX(), pS.getY(), width, height, fullscreen, + ( isUndecorated() || offscreenInstance ) ? NSBorderlessWindowMask : + NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask, + NSBackingStoreBuffered, getScreen().getIndex(), surfaceHandle); + if ( newWin == 0 ) { + throw new NativeWindowException("Could not create native window "+Thread.currentThread().getName()+" "+this); } + setWindowHandle( newWin ); + + final boolean isOpaque = getGraphicsConfiguration().getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance; + // Non blocking initialization on main-thread! + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + initWindow0( parentWin, newWin, + pS.getX(), pS.getY(), width, height, + isOpaque, fullscreen, offscreenInstance, getScreen().getIndex(), surfaceHandle); + if( offscreenInstance ) { + orderOut0(0!=parentWin ? parentWin : newWin); + } else { + setTitle0(newWin, getTitle()); + } + } } ); } catch (Exception ie) { ie.printStackTrace(); } } protected static native boolean initIDs0(); + private native long createView0(int x, int y, int w, int h, boolean fullscreen, int screen_idx); + private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, int screen_idx, long view); /** Must be called on Main-Thread */ - private native long createWindow0(long parentWindowHandle, int x, int y, int w, int h, - boolean opaque, boolean fullscreen, int windowStyle, - int backingStoreType, - int screen_idx, long view); - private native boolean lockSurface0(long window); - private native void unlockSurface0(long window); + private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h, + boolean opaque, boolean fullscreen, boolean offscreen, int screen_idx, long view); + private native boolean lockSurface0(long window, long view); + private native boolean unlockSurface0(long window, long view); private native void requestFocus0(long window, boolean force); private native void resignFocus0(long window); /** in case of a child window, it actually only issues orderBack(..) */ @@ -452,7 +481,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl private native void setTitle0(long window, String title); private native long contentView0(long window); /** Must be called on Main-Thread */ - private native long changeContentView0(long parentWindowOrViewHandle, long window, long view); + private native void changeContentView0(long parentWindowOrView, long window, long view); private native void setWindowClientTopLeftPointAndSize0(long window, int x, int y, int w, int h); private native void setWindowClientTopLeftPoint0(long window, int x, int y); private native void setAlwaysOnTop0(long window, boolean atop); diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index 1895b98a5..db4420b49 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -70,11 +70,18 @@ static void setWindowClientTopLeftPoint(NewtMacWindow* mWin, jint x, jint y) { [mWin invalidateCursorRectsForView: mView]; } -static void setWindowClientTopLeftPointAndSize(NewtMacWindow* mWin, jint x, jint y, jint width, jint height) { - NSSize sz = NSMakeSize(width, height); - NSPoint pS = [mWin newtAbsClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y) size: sz]; - NSRect rect = { pS, sz }; - [mWin setFrame: rect display:YES]; +static void setWindowClientTopLeftPointAndSize(NewtMacWindow* mWin, jint x, jint y, jint width, jint height, BOOL doDisplay) { + DBG_PRINT( "setWindowClientTopLeftPointAndSize.0 - window: %p %d/%d %dx%d\n", + mWin, (int)x, (int)y, (int)width, (int)height); + NSSize clientSZ = NSMakeSize(width, height); + NSPoint pS = [mWin newtAbsClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y) size: clientSZ]; + NSSize topSZ = [mWin newtClientSize2TLSize: clientSZ]; + NSRect rect = { pS, topSZ }; + + DBG_PRINT( "setWindowClientTopLeftPointAndSize.X: %d/%d %dx%d\n", + (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height); + + [mWin setFrame: rect display:doDisplay]; // -> display:YES // NSView* mView = [mWin contentView]; @@ -88,21 +95,20 @@ static int getRetainCount(NSObject * obj) { #endif static void changeContentView(JNIEnv *env, jobject javaWindowObject, NSView *pview, NewtMacWindow *win, NewtView *newView) { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSView* oldNSView = [win contentView]; - NewtView* oldView = NULL; + NewtView* oldNewtView = NULL; #ifdef VERBOSE_ON int dbgIdx = 1; #endif - if( [oldNSView isMemberOfClass:[NewtView class]] ) { - oldView = (NewtView *) oldNSView; + if( [oldNSView isKindOfClass:[NewtView class]] ) { + oldNewtView = (NewtView *) oldNSView; } DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d), parent view %p\n", - dbgIdx++, win, oldNSView, getRetainCount(oldNSView), NULL!=oldView, newView, getRetainCount(newView), pview); + dbgIdx++, win, oldNSView, getRetainCount(oldNSView), NULL!=oldNewtView, newView, getRetainCount(newView), pview); - if(NULL!=oldNSView) { + if( NULL!=oldNSView ) { NS_DURING // Available >= 10.5 - Makes the menubar disapear BOOL iifs; @@ -117,20 +123,20 @@ NS_DURING NS_HANDLER NS_ENDHANDLER DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d)\n", - dbgIdx++, win, oldNSView, getRetainCount(oldNSView), NULL!=oldView, newView, getRetainCount(newView)); + dbgIdx++, win, oldNSView, getRetainCount(oldNSView), NULL!=oldNewtView, newView, getRetainCount(newView)); - if( NULL != oldView ) { - jobject globJavaWindowObject = [oldView getJavaWindowObject]; + if( NULL != oldNewtView ) { + jobject globJavaWindowObject = [oldNewtView getJavaWindowObject]; (*env)->DeleteGlobalRef(env, globJavaWindowObject); - [oldView setJavaWindowObject: NULL]; - [oldView setDestroyNotifySent: false]; + [oldNewtView setJavaWindowObject: NULL]; + [oldNewtView setDestroyNotifySent: false]; } [oldNSView removeFromSuperviewWithoutNeedingDisplay]; } DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", dbgIdx++, win, oldNSView, getRetainCount(oldNSView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]); - if(NULL!=newView) { + if( NULL!=newView ) { jobject globJavaWindowObject = (*env)->NewGlobalRef(env, javaWindowObject); [newView setJavaWindowObject: globJavaWindowObject]; [newView setDestroyNotifySent: false]; @@ -163,12 +169,10 @@ NS_ENDHANDLER dbgIdx++, win, oldNSView, getRetainCount(oldNSView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]); // make sure the insets are updated in the java object - [win updateInsets: env]; + [win updateInsets: env jwin:javaWindowObject]; DBG_PRINT( "changeContentView.X win %p, view (%p,%d -> %p,%d)\n", win, oldNSView, getRetainCount(oldNSView), newView, getRetainCount(newView)); - - [pool release]; } /* @@ -565,29 +569,69 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0 } /** - * Method is called on Main-Thread, hence no special invocation required inside method. + * Class: jogamp_newt_driver_macosx_WindowDriver + * Method: createView0 + * Signature: (IIIIZI)J + */ +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0 + (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, + jboolean fullscreen, jint screen_idx) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d, fs %d, screenidx %d (START)\n", + (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen, (int)screen_idx); + + NSArray *screens = [NSScreen screens]; + if(screen_idx<0) screen_idx=0; + if(screen_idx>=[screens count]) screen_idx=0; + NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx]; + NSRect rectWin; + + if (fullscreen) { + rectWin = [myScreen frame]; + x = 0; + y = 0; + w = (jint) (rectWin.size.width); + h = (jint) (rectWin.size.height); + } else { + rectWin = NSMakeRect(x, y, w, h); + } + + NSRect rectView = NSMakeRect(0, 0, w, h); + NewtView *myView = [[NewtView alloc] initWithFrame: rectView] ; + DBG_PRINT( "createView0.X.%d - new view: %p\n", myView); + + [pool release]; + + return (jlong) ((intptr_t) myView); +} + +/** + * Method creates a deferred un-initialized Window, hence no special invocation required inside method. * * Class: jogamp_newt_driver_macosx_WindowDriver * Method: createWindow0 - * Signature: (JIIIIZIIIJ)J + * Signature: (IIIIZIIIJ)J */ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow0 - (JNIEnv *env, jobject jthis, jlong parent, jint x, jint y, jint w, jint h, jboolean opaque, jboolean fullscreen, jint styleMask, - jint bufferingType, jint screen_idx, jlong jview) + (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, + jboolean fullscreen, jint styleMask, jint bufferingType, jint screen_idx, jlong jview) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NewtView* myView = (NewtView*) (intptr_t) jview ; - DBG_PRINT( "createWindow0 - %p (this), %p (parent), %d/%d %dx%d, opaque %d, fs %d, style %X, buffType %X, screenidx %d, view %p (START)\n", - (void*)(intptr_t)jthis, (void*)(intptr_t)parent, (int)x, (int)y, (int)w, (int)h, (int) opaque, (int)fullscreen, + DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, screenidx %d, view %p (START)\n", + (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen, (int)styleMask, (int)bufferingType, (int)screen_idx, myView); + (void)myView; NSArray *screens = [NSScreen screens]; if(screen_idx<0) screen_idx=0; if(screen_idx>=[screens count]) screen_idx=0; NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx]; - NSRect rectWin; + NSRect rectWin; if (fullscreen) { styleMask = NSBorderlessWindowMask; rectWin = [myScreen frame]; @@ -603,9 +647,54 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow NewtMacWindow* myWindow = [[NewtMacWindow alloc] initWithContentRect: rectWin styleMask: (NSUInteger) styleMask backing: (NSBackingStoreType) bufferingType - defer: NO + defer: YES screen: myScreen isFullscreenWindow: fullscreen]; + + // DBG_PRINT( "createWindow0.1 - %p, isVisible %d\n", myWindow, [myWindow isVisible]); + + DBG_PRINT( "createWindow0.X - %p, isVisible %d\n", myWindow, [myWindow isVisible]); + + [pool release]; + + return (jlong) ((intptr_t) myWindow); +} + +/** + * Method is called on Main-Thread, hence no special invocation required inside method. + * + * Class: jogamp_newt_driver_macosx_WindowDriver + * Method: initWindow0 + * Signature: (JJIIIIZZZIIJ)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0 + (JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h, + jboolean opaque, jboolean fullscreen, jboolean offscreen, jint screen_idx, jlong jview) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window); + NewtView* myView = (NewtView*) (intptr_t) jview ; + + DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, opaque %d, fs %d, offscreen %d, screenidx %d, view %p (START)\n", + (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, (int) opaque, (int)fullscreen, + (int)offscreen, (int)screen_idx, myView); + + NSArray *screens = [NSScreen screens]; + if(screen_idx<0) screen_idx=0; + if(screen_idx>=[screens count]) screen_idx=0; + NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx]; + NSRect rectWin; + + if (fullscreen) { + rectWin = [myScreen frame]; + x = 0; + y = 0; + w = (jint) (rectWin.size.width); + h = (jint) (rectWin.size.height); + } else { + rectWin = NSMakeRect(x, y, w, h); + } + [myWindow setReleasedWhenClosed: YES]; // default [myWindow setPreservesContentDuringLiveResize: NO]; @@ -615,15 +704,15 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSWindow class]] ) { parentWindow = (NSWindow*) nsParentObj; parentView = [parentWindow contentView]; - DBG_PRINT( "createWindow0 - Parent is NSWindow : %p (win) -> %p (view) \n", parentWindow, parentView); + DBG_PRINT( "initWindow0 - Parent is NSWindow : %p (win) -> %p (view) \n", parentWindow, parentView); } else if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSView class]] ) { parentView = (NSView*) nsParentObj; parentWindow = [parentView window]; - DBG_PRINT( "createWindow0 - Parent is NSView : %p -(view) > %p (win) \n", parentView, parentWindow); + DBG_PRINT( "initWindow0 - Parent is NSView : %p -(view) > %p (win) \n", parentView, parentWindow); } else { - DBG_PRINT( "createWindow0 - Parent is neither NSWindow nor NSView : %p\n", nsParentObj); + DBG_PRINT( "initWindow0 - Parent is neither NSWindow nor NSView : %p\n", nsParentObj); } - DBG_PRINT( "createWindow0 - is visible.1: %d\n", [myWindow isVisible]); + DBG_PRINT( "initWindow0 - is visible.1: %d\n", [myWindow isVisible]); // Remove animations for child windows if(NULL != parentWindow) { @@ -641,11 +730,11 @@ NS_ENDHANDLER #endif if(opaque) { [myWindow setOpaque: YES]; - DBG_PRINT( "createWindow0.%d\n", dbgIdx++); + DBG_PRINT( "initWindow0.%d\n", dbgIdx++); if (!fullscreen) { [myWindow setShowsResizeIndicator: YES]; } - DBG_PRINT( "createWindow0.%d\n", dbgIdx++); + DBG_PRINT( "initWindow0.%d\n", dbgIdx++); } else { [myWindow setOpaque: NO]; [myWindow setBackgroundColor: [NSColor clearColor]]; @@ -653,36 +742,25 @@ NS_ENDHANDLER // specify we want mouse-moved events [myWindow setAcceptsMouseMovedEvents:YES]; - DBG_PRINT( "createWindow0.%d\n", dbgIdx++); - // Use given NewtView or allocate an NewtView if NULL - if(NULL == myView) { - NSRect rectView = NSMakeRect(0, 0, w, h); - myView = [[NewtView alloc] initWithFrame: rectView] ; - DBG_PRINT( "createWindow0.%d - use new view: %p,%d\n", dbgIdx++, myView, getRetainCount(myView)); - } else { - DBG_PRINT( "createWindow0.%d - use given view: %p,%d\n", dbgIdx++, myView, getRetainCount(myView)); - } - - DBG_PRINT( "createWindow0.%d - %p,%d view %p,%d, isVisible %d\n", + DBG_PRINT( "initWindow0.%d - %p,%d view %p,%d, isVisible %d\n", dbgIdx++, myWindow, getRetainCount(myWindow), myView, getRetainCount(myView), [myWindow isVisible]); // Set the content view changeContentView(env, jthis, parentView, myWindow, myView); - DBG_PRINT( "createWindow0.%d - %p,%d view %p,%d, isVisible %d\n", + DBG_PRINT( "initWindow0.%d - %p,%d view %p,%d, isVisible %d\n", dbgIdx++, myWindow, getRetainCount(myWindow), myView, getRetainCount(myView), [myWindow isVisible]); if(NULL!=parentWindow) { [myWindow attachToParent: parentWindow]; } - // Immediately re-position the window based on an upper-left coordinate system - setWindowClientTopLeftPoint(myWindow, x, y); + DBG_PRINT( "initWindow0.%d - %p,%d view %p,%d, isVisible %d\n", + dbgIdx++, myWindow, getRetainCount(myWindow), myView, getRetainCount(myView), [myWindow isVisible]); - // force surface creation - [myView lockFocus]; - [myView unlockFocus]; + // Immediately re-position the window based on an upper-left coordinate system + setWindowClientTopLeftPointAndSize(myWindow, x, y, w, h, NO); NS_DURING // concurrent view rendering @@ -696,12 +774,24 @@ NS_DURING NS_HANDLER NS_ENDHANDLER + DBG_PRINT( "initWindow0.%d - %p,%d view %p,%d, isVisible %d\n", + dbgIdx++, myWindow, getRetainCount(myWindow), myView, getRetainCount(myView), [myWindow isVisible]); + // visible on front - [myWindow orderFront: myWindow]; + if( JNI_FALSE == offscreen ) { + [myWindow orderFront: myWindow]; + } + + DBG_PRINT( "initWindow0.%d - %p,%d view %p,%d, isVisible %d\n", + dbgIdx++, myWindow, getRetainCount(myWindow), myView, getRetainCount(myView), [myWindow isVisible]); + + // force surface creation + // [myView lockFocus]; + // [myView unlockFocus]; NS_DURING // Available >= 10.5 - Makes the menubar disapear - if(fullscreen) { + if( fullscreen ) { if ( [myView respondsToSelector:@selector(enterFullScreenMode:withOptions:)] ) { [myView enterFullScreenMode: myScreen withOptions:NULL]; } @@ -713,12 +803,10 @@ NS_ENDHANDLER // right mouse button down events [myView setNextResponder: myWindow]; - DBG_PRINT( "createWindow0 - %p (this), %p (parent): new window: %p, view %p,%d (END)\n", + DBG_PRINT( "initWindow0.X - %p (this), %p (parent): new window: %p, view %p,%d\n", (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView, getRetainCount(myView)); [pool release]; - - return (jlong) ((intptr_t) myWindow); } /** @@ -740,7 +828,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0 DBG_PRINT( "windowClose.0 - %p,%d, destroyNotifySent %d, view %p,%d, parent %p\n", mWin, getRetainCount(mWin), destroyNotifySent, mView, getRetainCount(mView), pWin); - [mWin setUnrealized]; + [mWin setRealized: NO]; if(NULL!=mView) { // cleanup view @@ -786,8 +874,7 @@ NS_ENDHANDLER [mWin release]; } - DBG_PRINT( "windowClose.X - %p,%d, released %d, view %p,%d, parent %p\n", - mWin, getRetainCount(mWin), !destroyNotifySent, mView, getRetainCount(mView), pWin); + DBG_PRINT( "windowClose.Xp\n"); [pool release]; } @@ -795,16 +882,16 @@ NS_ENDHANDLER /* * Class: Java_jogamp_newt_driver_macosx_WindowDriver * Method: lockSurface0 - * Signature: (J)Z + * Signature: (JJ)Z */ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_lockSurface0 - (JNIEnv *env, jclass clazz, jlong window) + (JNIEnv *env, jclass clazz, jlong window, jlong view) { NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); if(NO == [mWin isRealized]) { return JNI_FALSE; } - NewtView * mView = (NewtView *) [mWin contentView]; + NewtView * mView = (NewtView *) ((intptr_t) view); return [mView softLock] == YES ? JNI_TRUE : JNI_FALSE; /** deadlocks, since we render independent of focus return [mView lockFocusIfCanDraw] == YES ? JNI_TRUE : JNI_FALSE; */ @@ -813,14 +900,15 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_lockSurfa /* * Class: Java_jogamp_newt_driver_macosx_WindowDriver * Method: unlockSurface0 - * Signature: (J)V + * Signature: (JJ)Z */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_unlockSurface0 - (JNIEnv *env, jclass clazz, jlong window) +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_unlockSurface0 + (JNIEnv *env, jclass clazz, jlong window, jlong view) { - NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); - NewtView * mView = (NewtView *) [mWin contentView]; - [mView softUnlock]; + // NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); + (void) window; + NewtView * mView = (NewtView *) ((intptr_t) view); + return [mView softUnlock] == YES ? JNI_TRUE : JNI_FALSE; /** deadlocks, since we render independent of focus [mView unlockFocus]; */ } @@ -946,7 +1034,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setTitle0 /* * Class: jogamp_newt_driver_macosx_WindowDriver - * Method: contentView + * Method: contentView0 * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_contentView0 @@ -954,12 +1042,16 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_contentView0 { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSWindow* win = (NSWindow*) ((intptr_t) window); + NSView* nsView = [win contentView]; + NewtView* newtView = NULL; - DBG_PRINT( "contentView0 - window: %p (START)\n", win); + if( [nsView isKindOfClass:[NewtView class]] ) { + newtView = (NewtView *) nsView; + } - jlong res = (jlong) ((intptr_t) [win contentView]); + DBG_PRINT( "contentView0 - window: %p, view: %p, newtView %p\n", win, nsView, newtView); - DBG_PRINT( "contentView0 - window: %p (END)\n", win); + jlong res = (jlong) ((intptr_t) nsView); [pool release]; return res; @@ -970,24 +1062,18 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_contentView0 * * Class: jogamp_newt_driver_macosx_WindowDriver * Method: changeContentView - * Signature: (J)J + * Signature: (J)V */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeContentView0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeContentView0 (JNIEnv *env, jobject jthis, jlong parentWindowOrView, jlong window, jlong jview) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NewtView* newView = (NewtView *) ((intptr_t) jview); NewtMacWindow* win = (NewtMacWindow*) ((intptr_t) window); - NSView* oldNSView = [win contentView]; - NewtView* oldView = NULL; - if( [oldNSView isMemberOfClass:[NewtView class]] ) { - oldView = (NewtView *) oldNSView; - } - - DBG_PRINT( "changeContentView0.0 - win %p, view (%p,%d (%d) -> %p,%d)\n", - win, oldNSView, getRetainCount(oldNSView), NULL!=oldView, newView, getRetainCount(newView)); + DBG_PRINT( "changeContentView0.0 - win %p, view (%p,%d)\n", + win, newView, getRetainCount(newView)); NSObject *nsParentObj = (NSObject*) ((intptr_t) parentWindowOrView); NSView* pView = NULL; @@ -1002,12 +1088,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeConten changeContentView(env, jthis, pView, win, newView); - DBG_PRINT( "changeContentView0.X - win %p, view (%p,%d (%d) -> %p,%d)\n", - win, oldNSView, getRetainCount(oldNSView), NULL!=oldView, newView, getRetainCount(newView)); + DBG_PRINT( "changeContentView0.X\n"); [pool release]; - - return (jlong) ((intptr_t) oldView); } /* @@ -1023,7 +1106,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClie DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (START)\n", mWin); - setWindowClientTopLeftPointAndSize(mWin, x, y, w, h); + setWindowClientTopLeftPointAndSize(mWin, x, y, w, h, YES); DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (END)\n", mWin); diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h index 6d1bcca00..09f4a1fd3 100644 --- a/src/newt/native/NewtMacWindow.h +++ b/src/newt/native/NewtMacWindow.h @@ -47,6 +47,8 @@ #define DBG_PRINT(...) #endif +// #define DBG_LIFECYCLE 1 + @interface NewtView : NSView { jobject javaWindowObject; @@ -56,16 +58,19 @@ int jvmVersion; volatile BOOL destroyNotifySent; - volatile BOOL softLocked; + volatile int softLockCount; pthread_mutex_t softLockSync; - NSTrackingRectTag ptrTrackingTag; + volatile NSTrackingRectTag ptrTrackingTag; NSRect ptrRect; NSCursor * myCursor; } - (id)initWithFrame:(NSRect)frameRect; + +#ifdef DBG_LIFECYCLE - (void) release; +#endif - (void) dealloc; /* Set during event dispatching cycle */ @@ -87,7 +92,7 @@ - (BOOL) getDestroyNotifySent; - (BOOL) softLock; -- (void) softUnlock; +- (BOOL) softUnlock; - (BOOL) needsDisplay; - (void) displayIfNeeded; @@ -125,18 +130,21 @@ defer: (BOOL) deferCreation screen:(NSScreen *)screen isFullscreenWindow:(BOOL)isfs; +#ifdef DBG_LIFECYCLE - (void) release; +#endif - (void) dealloc; -- (void) setUnrealized; +- (void) setRealized: (BOOL)v; - (BOOL) isRealized; -- (void) updateInsets: (JNIEnv*) env; +- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin; - (void) attachToParent: (NSWindow*) parent; - (void) detachFromParent: (NSWindow*) parent; - (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p; - (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p size: (NSSize) nsz; - (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p; +- (NSSize) newtClientSize2TLSize: (NSSize) nsz; - (NSPoint) getLocationOnScreen: (NSPoint) p; - (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p; diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index 282c13fd3..d7b357349 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -113,7 +113,7 @@ static jmethodID windowRepaintID = NULL; jvmHandle = NULL; jvmVersion = 0; destroyNotifySent = NO; - softLocked = NO; + softLockCount = 0; pthread_mutexattr_t softLockSyncAttr; pthread_mutexattr_init(&softLockSyncAttr); @@ -134,19 +134,21 @@ static jmethodID windowRepaintID = NULL; return res; } +#ifdef DBG_LIFECYCLE - (void) release { DBG_PRINT("NewtView::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]); -#ifdef VERBOSE_ON - // NSLog(@"%@",[NSThread callStackSymbols]); -#endif [super release]; } +#endif - (void) dealloc { DBG_PRINT("NewtView::dealloc.0: %p (refcnt %d), ptrTrackingTag %d\n", self, (int)[self retainCount], (int)ptrTrackingTag); - if(softLocked) { +#ifdef DBG_LIFECYCLE + NSLog(@"%@",[NSThread callStackSymbols]); +#endif + if( 0 < softLockCount ) { NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n"); } if(0 != ptrTrackingTag) { @@ -155,9 +157,6 @@ static jmethodID windowRepaintID = NULL; ptrTrackingTag = 0; } pthread_mutex_destroy(&softLockSync); -#ifdef VERBOSE_ON - //NSLog(@"%@",[NSThread callStackSymbols]); -#endif DBG_PRINT("NewtView::dealloc.X: %p\n", self); [super dealloc]; } @@ -206,6 +205,7 @@ static jmethodID windowRepaintID = NULL; if(0 != ptrTrackingTag) { // [self removeCursorRect: ptrRect cursor: myCursor]; [self removeTrackingRect: ptrTrackingTag]; + ptrTrackingTag = 0; } ptrRect = [self bounds]; // [self addCursorRect: ptrRect cursor: myCursor]; @@ -230,18 +230,27 @@ static jmethodID windowRepaintID = NULL; - (BOOL) softLock { // DBG_PRINT("*************** softLock.0: %p\n", (void*)pthread_self()); - // NSLog(@"NewtView::softLock: %@",[NSThread callStackSymbols]); - pthread_mutex_lock(&softLockSync); - softLocked = YES; + int err; + if( 0 != ( err = pthread_mutex_lock(&softLockSync) ) ) { + NSLog(@"NewtView::softLock failed: errCode %d - %@", err, [NSThread callStackSymbols]); + return NO; + } + softLockCount++; // DBG_PRINT("*************** softLock.X: %p\n", (void*)pthread_self()); - return softLocked; + return 0 < softLockCount; } -- (void) softUnlock +- (BOOL) softUnlock { // DBG_PRINT("*************** softUnlock: %p\n", (void*)pthread_self()); - softLocked = NO; - pthread_mutex_unlock(&softLockSync); + softLockCount--; + int err; + if( 0 != ( err = pthread_mutex_unlock(&softLockSync) ) ) { + softLockCount++; + NSLog(@"NewtView::softUnlock failed: Not locked by current thread - errCode %d - %@", err, [NSThread callStackSymbols]); + return NO; + } + return YES; } - (BOOL) needsDisplay @@ -398,25 +407,26 @@ static jmethodID windowRepaintID = NULL; mouseInside = NO; cursorIsHidden = NO; realized = YES; - DBG_PRINT("NewtWindow::create: %p (refcnt %d)\n", res, (int)[res retainCount]); + DBG_PRINT("NewtWindow::create: %p, realized %d (refcnt %d)\n", res, realized, (int)[res retainCount]); return res; } +#ifdef DBG_LIFECYCLE - (void) release { DBG_PRINT("NewtWindow::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]); -#ifdef VERBOSE_ON // NSLog(@"%@",[NSThread callStackSymbols]); -#endif [super release]; } +#endif - (void) dealloc { DBG_PRINT("NewtWindow::dealloc.0: %p (refcnt %d)\n", self, (int)[self retainCount]); -#ifdef VERBOSE_ON - // NSLog(@"%@",[NSThread callStackSymbols]); +#ifdef DBG_LIFECYCLE + NSLog(@"%@",[NSThread callStackSymbols]); #endif + NewtView* mView = (NewtView *)[self contentView]; if( NULL != mView ) { [mView release]; @@ -425,9 +435,9 @@ static jmethodID windowRepaintID = NULL; DBG_PRINT("NewtWindow::dealloc.X: %p\n", self); } -- (void) setUnrealized +- (void) setRealized: (BOOL)v { - realized = NO; + realized = v; } - (BOOL) isRealized @@ -435,18 +445,8 @@ static jmethodID windowRepaintID = NULL; return realized; } -- (void) updateInsets: (JNIEnv*) env +- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin { - NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { - return; - } - NewtView* view = (NewtView *) nsview; - jobject javaWindowObject = [view getJavaWindowObject]; - if (env==NULL || javaWindowObject == NULL) { - return; - } - NSRect frameRect = [self frame]; NSRect contentRect = [self contentRectForFrameRect: frameRect]; @@ -460,7 +460,9 @@ static jmethodID windowRepaintID = NULL; DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]); - (*env)->CallVoidMethod(env, javaWindowObject, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]); + if( NULL != env && NULL != javaWin ) { + (*env)->CallVoidMethod(env, javaWin, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]); + } } - (void) attachToParent: (NSWindow*) parent @@ -502,11 +504,21 @@ static jmethodID windowRepaintID = NULL; { int totalHeight = nsz.height + cachedInsets[3]; // height + insets.bottom + DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: given %d/%d %dx%d, insets bottom %d -> totalHeight %d\n", + (int)p.x, (int)p.y, (int)nsz.width, (int)nsz.height, cachedInsets[3], totalHeight); + NSScreen* screen = [self screen]; NSRect screenFrame = [screen frame]; - return NSMakePoint(screenFrame.origin.x + p.x, - screenFrame.origin.y + screenFrame.size.height - p.y - totalHeight); + DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: screen %d/%d %dx%d\n", + (int)screenFrame.origin.x, (int)screenFrame.origin.y, (int)screenFrame.size.width, (int)screenFrame.size.height); + + NSPoint r = NSMakePoint(screenFrame.origin.x + p.x, + screenFrame.origin.y + screenFrame.size.height - p.y - totalHeight); + + DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: result %d/%d\n", (int)r.x, (int)r.y); + + return r; } /** @@ -524,6 +536,12 @@ static jmethodID windowRepaintID = NULL; winFrame.origin.y + ( mViewFrame.size.height - p.y ) ); // y-flip in view } +- (NSSize) newtClientSize2TLSize: (NSSize) nsz +{ + NSSize topSZ = { nsz.width, nsz.height + cachedInsets[2] + cachedInsets[3] }; // height + insets.top + insets.bottom + return topSZ; +} + /** * y-flips input / output * p rel client window position w/ top-left origin @@ -646,7 +664,7 @@ static jint mods2JavaMods(NSUInteger mods) - (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType { NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { + if( ! [nsview isKindOfClass:[NewtView class]] ) { return; } NewtView* view = (NewtView *) nsview; @@ -706,7 +724,7 @@ static jint mods2JavaMods(NSUInteger mods) - (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType { NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { + if( ! [nsview isKindOfClass:[NewtView class]] ) { return; } NewtView* view = (NewtView *) nsview; @@ -783,7 +801,7 @@ static jint mods2JavaMods(NSUInteger mods) { DBG_PRINT( "focusChanged: gained %d\n", gained); NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { + if( ! [nsview isKindOfClass:[NewtView class]] ) { return; } NewtView* view = (NewtView *) nsview; @@ -981,43 +999,42 @@ static jint mods2JavaMods(NSUInteger mods) - (void)windowDidResize: (NSNotification*) notification { - NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { - return; - } - NewtView* view = (NewtView *) nsview; - jobject javaWindowObject = [view getJavaWindowObject]; - if (javaWindowObject == NULL) { - DBG_PRINT("windowDidResize: null javaWindowObject\n"); - return; - } + JNIEnv* env = NULL; + jobject javaWindowObject = NULL; int shallBeDetached = 0; - JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); - if(NULL==env) { - DBG_PRINT("windowDidResize: null JNIEnv\n"); - return; + JavaVM *jvmHandle = NULL; + + NSView* nsview = [self contentView]; + if( [nsview isKindOfClass:[NewtView class]] ) { + NewtView* view = (NewtView *) nsview; + javaWindowObject = [view getJavaWindowObject]; + if (javaWindowObject != NULL) { + jvmHandle = [view getJVMHandle]; + env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + } } // update insets on every window resize for lack of better hook place - [self updateInsets: env]; + [self updateInsets: env jwin:javaWindowObject]; - NSRect frameRect = [self frame]; - NSRect contentRect = [self contentRectForFrameRect: frameRect]; + if( NULL != env && NULL != javaWindowObject ) { + NSRect frameRect = [self frame]; + NSRect contentRect = [self contentRectForFrameRect: frameRect]; - (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, JNI_FALSE, - (jint) contentRect.size.width, - (jint) contentRect.size.height, JNI_FALSE); + (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, JNI_FALSE, + (jint) contentRect.size.width, + (jint) contentRect.size.height, JNI_FALSE); - if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); + if (shallBeDetached) { + (*jvmHandle)->DetachCurrentThread(jvmHandle); + } } } - (void)windowDidMove: (NSNotification*) notification { NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { + if( ! [nsview isKindOfClass:[NewtView class]] ) { return; } NewtView* view = (NewtView *) nsview; @@ -1061,7 +1078,7 @@ static jint mods2JavaMods(NSUInteger mods) [self cursorHide: NO]; NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { + if( ! [nsview isKindOfClass:[NewtView class]] ) { return NO; } NewtView* view = (NewtView *) nsview; |