aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-03-19 00:33:00 +0100
committerSven Gothel <[email protected]>2013-03-19 00:33:00 +0100
commit81cbcdc8469143587b2044661dd613c798ae02ba (patch)
tree813982c77435a9ca75225019b8ea0ebe3d22b08c
parentf354fb204d8973453c538dda78a2c82c87be61dc (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-xmake/scripts/tests.sh6
-rw-r--r--src/newt/classes/jogamp/newt/DefaultEDTUtil.java1
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java17
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java165
-rw-r--r--src/newt/native/MacWindow.m257
-rw-r--r--src/newt/native/NewtMacWindow.h18
-rw-r--r--src/newt/native/NewtMacWindow.m145
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;