From 9a12ff413a216b7d591950e9d5fc9a261786bc00 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 26 Jun 2019 08:39:37 +0200 Subject: NEWT: Align native MacOS / IOS file- and classnames --- make/build-newt.xml | 4 +- src/newt/native/IOSUIWindow.m | 1161 ------------------------------- src/newt/native/IOSWindow.m | 1161 +++++++++++++++++++++++++++++++ src/newt/native/MacNewtNSWindow.h | 207 ++++++ src/newt/native/MacNewtNSWindow.m | 1356 +++++++++++++++++++++++++++++++++++++ src/newt/native/MacWindow.m | 144 ++-- src/newt/native/NewtMacWindow.h | 207 ------ src/newt/native/NewtMacWindow.m | 1356 ------------------------------------- 8 files changed, 2798 insertions(+), 2798 deletions(-) delete mode 100644 src/newt/native/IOSUIWindow.m create mode 100644 src/newt/native/IOSWindow.m create mode 100644 src/newt/native/MacNewtNSWindow.h create mode 100644 src/newt/native/MacNewtNSWindow.m delete mode 100644 src/newt/native/NewtMacWindow.h delete mode 100644 src/newt/native/NewtMacWindow.m diff --git a/make/build-newt.xml b/make/build-newt.xml index 6c2defaca..1f10e6746 100644 --- a/make/build-newt.xml +++ b/make/build-newt.xml @@ -679,8 +679,8 @@ - - + + diff --git a/src/newt/native/IOSUIWindow.m b/src/newt/native/IOSUIWindow.m deleted file mode 100644 index 780c2344f..000000000 --- a/src/newt/native/IOSUIWindow.m +++ /dev/null @@ -1,1161 +0,0 @@ -/** - * Copyright 2019 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -#import - -#import "jogamp_newt_driver_ios_WindowDriver.h" -#import "IOSNewtUIWindow.h" - -#import "MouseEvent.h" -#import "KeyEvent.h" -#import "ScreenMode.h" - -#import - -#ifdef DBG_PERF - #include "timespec.h" -#endif - -static const char * const ClazzNamePoint = "com/jogamp/nativewindow/util/Point"; -static const char * const ClazzAnyCstrName = ""; -static const char * const ClazzNamePointCstrSignature = "(II)V"; -static jclass pointClz = NULL; -static jmethodID pointCstr = NULL; - -static NSString* jstringToNSString(JNIEnv* env, jstring jstr) -{ - const jchar* jstrChars = (*env)->GetStringChars(env, jstr, NULL); - NSString* str = [[NSString alloc] initWithCharacters: jstrChars length: (*env)->GetStringLength(env, jstr)]; - (*env)->ReleaseStringChars(env, jstr, jstrChars); - return str; -} - -static void setWindowClientTopLeftPoint(NewtUIWindow* mWin, jint x, jint y, BOOL doDisplay) { - DBG_PRINT( "setWindowClientTopLeftPoint.0 - window: %p %d/%d, display %d\n", mWin, (int)x, (int)y, (int)doDisplay); - CGPoint pS = CGPointMake(x, y); - CGRect rect = [mWin frame]; - rect.origin = pS; - - [mWin setFrame: rect]; - DBG_PRINT( "setWindowClientTopLeftPoint.X: %d/%d\n", (int)pS.x, (int)pS.y); - - if( doDisplay ) { - // TODO UIView* mView = [mWin contentView]; - // TODO [mWin invalidateCursorRectsForView: mView]; - } -} - -static void setWindowClientTopLeftPointAndSize(NewtUIWindow* mWin, jint x, jint y, jint width, jint height, BOOL doDisplay) { - DBG_PRINT( "setWindowClientTopLeftPointAndSize.0 - window: %p %d/%d %dx%d, display %d\n", mWin, (int)x, (int)y, (int)width, (int)height, (int)doDisplay); - CGRect rect = CGRectMake(x, y, width, height); - DBG_PRINT( "setWindowClientTopLeftPointAndSize.1: %d/%d %dx%d\n", (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height); - - // TODO [mWin setFrame: rect display:doDisplay]; - [mWin setFrame: rect]; - 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); - - // -> display:YES - // if( doDisplay ) { - // UIView* mView = [mWin contentView]; - // [mWin invalidateCursorRectsForView: mView]; - // } -} - -#ifdef VERBOSE_ON -static int getRetainCount(NSObject * obj) { - return ( NULL == obj ) ? -1 : (int)([obj retainCount]) ; -} -#endif - -static void setJavaWindowObject(JNIEnv *env, jobject newJavaWindowObject, NewtUIView *view, BOOL enable) { - DBG_PRINT( "setJavaWindowObject.0: View %p\n", view); - if( !enable) { - jobject globJavaWindowObject = [view getJavaWindowObject]; - if( NULL != globJavaWindowObject ) { - DBG_PRINT( "setJavaWindowObject.1: View %p - Clear old javaWindowObject %p\n", view, globJavaWindowObject); - (*env)->DeleteGlobalRef(env, globJavaWindowObject); - [view setJavaWindowObject: NULL]; - } - } else if( NULL != newJavaWindowObject ) { - DBG_PRINT( "setJavaWindowObject.2: View %p - Set new javaWindowObject %p\n", view, newJavaWindowObject); - jobject globJavaWindowObject = (*env)->NewGlobalRef(env, newJavaWindowObject); - [view setJavaWindowObject: globJavaWindowObject]; - } - DBG_PRINT( "setJavaWindowObject.X: View %p\n", view); -} - -static void changeContentView(JNIEnv *env, jobject javaWindowObject, UIView *pview, NewtUIWindow *win, NewtUIView *newView, BOOL setJavaWindow) { - UIView* oldUIView = NULL; // TODO [win contentView]; - NewtUIView* oldNewtUIView = NULL; -#ifdef VERBOSE_ON - int dbgIdx = 1; -#endif - - if( [oldUIView isKindOfClass:[NewtUIView class]] ) { - oldNewtUIView = (NewtUIView *) oldUIView; - } - - DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d), parent view %p\n", - dbgIdx++, win, oldUIView, getRetainCount(oldUIView), NULL!=oldNewtUIView, newView, getRetainCount(newView), pview); - - if( NULL!=oldUIView ) { -NS_DURING - // Available >= 10.5 - Makes the menubar disapear - BOOL iifs = NO; // TODO [oldUIView isInFullScreenMode]; - if( iifs ) { - // TODO [oldUIView exitFullScreenModeWithOptions: NULL]; - } -NS_HANDLER -NS_ENDHANDLER - DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d)\n", - dbgIdx++, win, oldUIView, getRetainCount(oldUIView), NULL!=oldNewtUIView, newView, getRetainCount(newView)); - - if( NULL != oldNewtUIView ) { - [oldNewtUIView setDestroyNotifySent: false]; - setJavaWindowObject(env, NULL, oldNewtUIView, NO); - } - // TODO [oldUIView removeFromSuperviewWithoutNeedingDisplay]; - } - DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", - dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]); - - if( NULL!=newView ) { - [newView setDestroyNotifySent: false]; - if( setJavaWindow ) { - setJavaWindowObject(env, javaWindowObject, newView, YES); - } - - DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d)\n", - dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView)); - - if(NULL!=pview) { - // TODO [pview addSubview: newView positioned: UIWindowAbove relativeTo: nil]; - } - } - DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", - dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]); - - // TODO [win setContentView: newView]; - - DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", - dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]); - - // make sure the insets are updated in the java object - [win updateInsets: env jwin:javaWindowObject]; - - DBG_PRINT( "changeContentView.X win %p, view (%p,%d -> %p,%d)\n", - win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView)); -} - -/* - * Class: jogamp_newt_driver_ios_DisplayDriver - * Method: initIDs - * Signature: ()Z - */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_DisplayDriver_initUIApplication0 - (JNIEnv *env, jclass clazz) -{ - static int initialized = 0; - - if(initialized) return JNI_TRUE; - initialized = 1; - - NewtCommon_init(env); - - // Initialize the shared NSApplication instance - [UIApplication sharedApplication]; - - // Need this when debugging, as it is necessary to attach gdb to - // the running java process -- "gdb java" doesn't work - // printf("Going to sleep for 10 seconds\n"); - // sleep(10); - - return (jboolean) JNI_TRUE; -} - -static void NewtScreen_dump() { -#ifdef VERBOSE_ON - NSArray *screens = [UIScreen screens]; - int i; - for(i=0; i<[screens count]; i++) { - UIScreen * screen = (UIScreen *) [screens objectAtIndex: i]; - CGRect screenFrame = [screen frame]; - CGRect screenVisibleFrame = [screen visibleFrame]; - CGFloat pixelScale = 1.0; // default - pixelScale = [screen scale]; // HiDPI scaling - UIWindowDepth depth = [screen depth]; // an (int) value! - DBG_PRINT( "UIScreen #%d (%p): Frame %lf/%lf %lfx%lf (vis %lf/%lf %lfx%lf), scale %lf, depth %d\n", - i, screen, - screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height, - screenVisibleFrame.origin.x, screenVisibleFrame.origin.y, screenVisibleFrame.size.width, screenVisibleFrame.size.height, - pixelScale, depth); - } -#endif -} - -// Duplicate each Mode by all possible rotations (4): -// For each real-mode: [mode, 0], [mode, 90], [mode, 180], [mode, 270] -#define ROTMODES_PER_REALMODE 1 - -/* - * Class: jogamp_newt_driver_ios_ScreenDriver - * Method: getMonitorDeviceIds0 - * Signature: ()I - */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_getMonitorDeviceIds0 - (JNIEnv *env, jobject obj) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSArray *screens = [UIScreen screens]; - int count = [screens count]; - int32_t displayIDs[count]; - int i; - for(i=0; iNewIntArray(env, count); - if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", count); - } - (*env)->SetIntArrayRegion(env, properties, 0, count, displayIDs); - [pool release]; - return properties; -} - -/* - * Class: jogamp_newt_driver_ios_ScreenDriver - * Method: getMonitorProps0 - * Signature: (I)[I - */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_getMonitorProps0 - (JNIEnv *env, jobject obj, jint crt_id) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - -#ifdef DBG_PERF - struct timespec t0, t1, td; - long td_ms; - timespec_now(&t0); -#endif - -#ifdef DBG_PERF - timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "MacScreen_getMonitorProps0.1: %ld ms\n", td_ms); fflush(NULL); -#endif - NSArray *screens = [UIScreen screens]; - int count = [screens count]; - UIScreen * screen = (UIScreen *) [screens objectAtIndex: crt_id]; - if( NULL == screen ) { - [pool release]; - return NULL; - } - BOOL isPrimary = 0 == crt_id; -#ifdef DBG_PERF - timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "MacScreen_getMonitorProps0.2: %ld ms\n", td_ms); fflush(NULL); -#endif - - UIScreenMode * screenMode = [screen currentMode]; - CGSize sizeMM = CGSizeMake(161.0, 228.0); // TODO ??? -#ifdef DBG_PERF - timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "MacScreen_getMonitorProps0.3: %ld ms\n", td_ms); fflush(NULL); -#endif - - CGRect dBounds = [screen bounds]; -#ifdef VERBOSE_ON - DBG_PRINT( "getMonitorProps0: crt_id 0x%X (prim %d), top-left displayBounds[%d/%d %dx%d]\n", - (int)crt_id, isPrimary, - (int)dBounds.origin.x, (int)dBounds.origin.y, (int)dBounds.size.width, (int)dBounds.size.height); -#endif - - jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES; - jint prop[ propCount ]; - int offset = 0; - prop[offset++] = propCount; - prop[offset++] = crt_id; - prop[offset++] = 0; // isClone - prop[offset++] = isPrimary ? 1 : 0; // isPrimary - prop[offset++] = (jint) sizeMM.width; - prop[offset++] = (jint) sizeMM.height; - prop[offset++] = (jint) dBounds.origin.x; // rotated viewport x (pixel units, will be fixed in java code) - prop[offset++] = (jint) dBounds.origin.y; // rotated viewport y (pixel units, will be fixed in java code) - prop[offset++] = (jint) dBounds.size.width; // rotated viewport width (pixel units, will be fixed in java code) - prop[offset++] = (jint) dBounds.size.height; // rotated viewport height (pixel units, will be fixed in java code) - prop[offset++] = (jint) dBounds.origin.x; // rotated viewport x (window units, will be fixed in java code) - prop[offset++] = (jint) dBounds.origin.y; // rotated viewport y (window units, will be fixed in java code) - prop[offset++] = (jint) dBounds.size.width; // rotated viewport width (window units, will be fixed in java code) - prop[offset++] = (jint) dBounds.size.height; // rotated viewport height (window units, will be fixed in java code) - - jintArray properties = (*env)->NewIntArray(env, propCount); - if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount); - } - (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop); - - [pool release]; - - return properties; -} - -/* - * Class: jogamp_newt_driver_ios_ScreenDriver - * Method: getMonitorMode0 - * Signature: (II)[I - */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_getMonitorMode0 - (JNIEnv *env, jobject obj, jint crt_id, jint mode_idx) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - NSArray *screens = [UIScreen screens]; - int count = [screens count]; - UIScreen * screen = (UIScreen *) [screens objectAtIndex: crt_id]; - if( NULL == screen ) { - [pool release]; - return NULL; - } - CGFloat pixelScale = 1.0; // default -NS_DURING - // Available >= 10.7 - pixelScale = [screen scale]; // HiDPI scaling -NS_HANDLER -NS_ENDHANDLER - - NSArray *availableModes = [screen availableModes]; - int numberOfAvailableModes = [availableModes count]; - CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes; - int currentCCWRot = 0; - jint ccwRot = 0; - int nativeId = 0; - UIScreenMode * mode = NULL; - -#ifdef VERBOSE_ON - if(0 >= mode_idx) { - // only for current mode (-1) and first mode (scanning) - DBG_PRINT( "getScreenMode0: crtID 0x%X (s %p, pscale %lf), mode %d, avail: %d/%d, current rot %d ccw\n", - (uint32_t)displayID, screen, pixelScale, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot); - } -#endif - - if(numberOfAvailableModesRots<=mode_idx) { - // n/a - end of modes - DBG_PRINT( "getScreenMode0: end of modes: mode %d, avail: %d/%d\n", - (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots); - [pool release]; - return NULL; - } else if(-1 < mode_idx) { - // only at initialization time, where index >= 0 - nativeId = mode_idx / ROTMODES_PER_REALMODE; - ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90; - mode = (UIScreenMode*) [availableModes objectAtIndex: nativeId]; - } else { - // current mode - mode = [screen currentMode]; - ccwRot = 0; - nativeId = 0; - } - // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef - - CGSize mSize = [mode size]; - int mWidth = (int)mSize.width; - int mHeight = (int)mSize.height; - if( -1 == mode_idx ) { - mWidth *= (int)pixelScale; // accomodate HiDPI - mHeight *= (int)pixelScale; // accomodate HiDPI - } - - // swap width and height, since OSX reflects rotated dimension, we don't - if ( 90 == currentCCWRot || 270 == currentCCWRot ) { - int tempWidth = mWidth; - mWidth = mHeight; - mHeight = tempWidth; - } - - jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ]; - int propIndex = 0; - - int refreshRate = 60; // TODO - int fRefreshRate = ( 0 < refreshRate ) ? refreshRate : 60; // default .. (experienced on OSX 10.6.8) - prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL; - prop[propIndex++] = mWidth; - prop[propIndex++] = mHeight; - prop[propIndex++] = 32; // TODO CGDDGetModeBitsPerPixel(mode); - prop[propIndex++] = fRefreshRate * 100; // Hz*100 - prop[propIndex++] = 0; // flags - prop[propIndex++] = nativeId; - prop[propIndex++] = ccwRot; - - DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %d / %d Hz, nativeId %d, rot %d ccw\n", - (int)mode_idx, (int)numberOfAvailableModesRots, (int)numberOfAvailableModes, - (int)prop[1], (int)prop[2], (int)prop[3], - (int)prop[4], refreshRate, (int)prop[6], (int)prop[7]); - - jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL); - if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL); - } - (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop); - - // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef - [pool release]; - - return properties; -} - -/* - * Class: jogamp_newt_driver_ios_ScreenDriver - * Method: setMonitorMode0 - * Signature: (III)Z - */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_setMonitorMode0 - (JNIEnv *env, jobject object, jint crt_id, jint nativeId, jint ccwRot) -{ - return false; -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: initIDs - * Signature: ()Z - */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_WindowDriver_initIDs0 - (JNIEnv *env, jclass clazz) -{ - static int initialized = 0; - - if(initialized) return JNI_TRUE; - initialized = 1; - - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - NewtScreen_dump(); - - jclass c; - c = (*env)->FindClass(env, ClazzNamePoint); - if(NULL==c) { - NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_ios_WindowDriver_initIDs0: can't find %s", ClazzNamePoint); - } - pointClz = (jclass)(*env)->NewGlobalRef(env, c); - (*env)->DeleteLocalRef(env, c); - if(NULL==pointClz) { - NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_ios_WindowDriver_initIDs0: can't use %s", ClazzNamePoint); - } - pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); - if(NULL==pointCstr) { - NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_ios_WindowDriver_initIDs0: can't fetch %s.%s %s", - ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); - } - - // Need this when debugging, as it is necessary to attach gdb to - // the running java process -- "gdb java" doesn't work - // printf("Going to sleep for 10 seconds\n"); - // sleep(10); - - BOOL res = [NewtUIWindow initNatives: env forClass: clazz]; - [pool release]; - - return (jboolean) res; -} - -/** - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: createView0 - * Signature: (IIII)J - */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_ios_WindowDriver_createView0 - (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d (START)\n", - (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h); - - CGRect rectView = CGRectMake(0, 0, w, h); - NewtUIView *myView = [[NewtUIView alloc] initWithFrame: rectView] ; - DBG_PRINT( "createView0.X - 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_ios_WindowDriver - * Method: createWindow0 - * Signature: (IIIIZIIJ)J - */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_ios_WindowDriver_createWindow0 - (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, - jboolean fullscreen, jint styleMask, jint bufferingType, jlong jview) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtUIView* myView = (NewtUIView*) (intptr_t) jview ; - - DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, view %p (START)\n", - (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen, - (int)styleMask, (int)bufferingType, myView); - (void)myView; - - if (fullscreen) { - // TODO styleMask = NSBorderlessWindowMask; - } - CGRect rectWin = CGRectMake(x, y, w, h); - - // Allocate the window - NewtUIWindow* myWindow = [[NewtUIWindow alloc] initWithContentRect: rectWin - styleMask: (NSUInteger) styleMask - backing: 0 // TODO (NSBackingStoreType) bufferingType - defer: YES - 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); -} - -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_ios_WindowDriver_getDisplayID0(JNIEnv *env, jobject jthis, jlong window) { - NewtUIWindow* myWindow = (NewtUIWindow*) ((intptr_t) window); - if( NULL == myWindow ) { - DBG_PRINT( "getDisplayID0 - NULL NEWT win - abort\n"); - return 0; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - UIScreen *screen = [myWindow screen]; - int32_t displayID = 0; // TODO (int32_t)NewtScreen_getCGDirectDisplayIDByUIScreen(screen); - [pool release]; - return (jint) displayID; -} - -/** - * Method is called on Main-Thread, hence no special invocation required inside method. - * - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: initWindow0 - * Signature: (JJIIIIFZZZJ)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_initWindow0 - (JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h, jfloat reqPixelScale, - jboolean opaque, jboolean atop, jboolean abottom, jboolean visible, jlong jview) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtUIWindow* myWindow = (NewtUIWindow*) ((intptr_t) window); - NewtUIView* myView = (NewtUIView*) (intptr_t) jview ; - BOOL fullscreen = myWindow->isFullscreenWindow; - - DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, reqPixScale %f, opaque %d, atop %d, abottom %d, fs %d, visible %d, view %p (START)\n", - (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, (float)reqPixelScale, - (int) opaque, (int)atop, (int)abottom, (int)fullscreen, (int)visible, myView); - - // TODO [myWindow setReleasedWhenClosed: NO]; // We control UIWindow destruction! - // TODO [myWindow setPreservesContentDuringLiveResize: NO]; - - NSObject* nsParentObj = (NSObject*) ((intptr_t) parent); - UIWindow* parentWindow = NULL; - UIView* parentView = NULL; - if( nsParentObj != NULL && [nsParentObj isKindOfClass:[UIWindow class]] ) { - parentWindow = (UIWindow*) nsParentObj; - parentView = (UIView*)nsParentObj; - DBG_PRINT( "initWindow0 - Parent is UIWindow : %p (win) -> %p (view) \n", parentWindow, parentView); - } else if( nsParentObj != NULL && [nsParentObj isKindOfClass:[UIView class]] ) { - parentView = (UIView*) nsParentObj; - parentWindow = [parentView window]; - DBG_PRINT( "initWindow0 - Parent is UIView : %p -(view) > %p (win) \n", parentView, parentWindow); - } else { - DBG_PRINT( "initWindow0 - Parent is neither UIWindow nor UIView : %p\n", nsParentObj); - } - DBG_PRINT( "initWindow0 - is visible.1: %d\n", [myWindow isVisible]); - - // Remove animations for child windows - if(NULL != parentWindow) { - [UIView setAnimationsEnabled: NO]; - } - -#ifdef VERBOSE_ON - int dbgIdx = 1; -#endif - if(opaque) { - [myWindow setOpaque: YES]; - DBG_PRINT( "initWindow0.%d\n", dbgIdx++); - if (!fullscreen) { - // TODO [myWindow setShowsResizeIndicator: YES]; - } - DBG_PRINT( "initWindow0.%d\n", dbgIdx++); - } else { - [myWindow setOpaque: NO]; - [myWindow setBackgroundColor: [UIColor clearColor]]; - } - [myWindow setAlwaysOn: atop bottom:abottom]; - - // specify we want mouse-moved events - // TODO [myWindow setAcceptsMouseMovedEvents:YES]; - - DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", - dbgIdx++, myWindow, myView, [myWindow isVisible]); - - // Set the content view - changeContentView(env, jthis, parentView, myWindow, myView, NO); - // TODO [myWindow setInitialFirstResponder: myView]; - - DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", - dbgIdx++, myWindow, myView, [myWindow isVisible]); - - if(NULL!=parentWindow) { - [myWindow attachToParent: parentWindow]; - } - - DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d, visible %d\n", - dbgIdx++, myWindow, myView, [myWindow isVisible], visible); - - // Immediately re-position this window based on an upper-left coordinate system - setWindowClientTopLeftPointAndSize(myWindow, x, y, w, h, NO); - - DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", - dbgIdx++, myWindow, myView, [myWindow isVisible]); - - // TODO [myWindow setAllowsConcurrentViewDrawing: YES]; - - DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", - dbgIdx++, myWindow, myView, [myWindow isVisible]); - - // TODO [myView setCanDrawConcurrently: YES]; - - DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", - dbgIdx++, myWindow, myView, [myWindow isVisible]); - - // visible on front - if( visible ) { - // TODO [myWindow orderFront: myWindow]; - } - - DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", - dbgIdx++, myWindow, myView, [myWindow isVisible]); - - // force surface creation - // [myView lockFocus]; - // [myView unlockFocus]; - - // Set the next responder to be the window so that we can forward - // right mouse button down events - // TODO [myView setNextResponder: myWindow]; - - DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n", - dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView); - - [myView setDestroyNotifySent: false]; - setJavaWindowObject(env, jthis, myView, YES); - - DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n", - dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView); - -NS_DURING - if( fullscreen ) { - /** - * See Bug 914: We don't use exclusive fullscreen anymore (capturing display) - * allowing ALT-TAB to allow process/app switching! - * Shall have no penalty on modern GPU and is also recommended, see bottom box @ - * - * - UIScreen *myScreen = NewtScreen_getUIScreenByCoord(x, y); - if( NULL != myScreen ) { - if ( [myView respondsToSelector:@selector(enterFullScreenMode:withOptions:)] ) { - // Available >= 10.5 - Makes the menubar disapear - [myView enterFullScreenMode: myScreen withOptions:NULL]; - } - } - */ - if( myWindow->hasPresentationSwitch ) { - DBG_PRINT( "initWindow0.%d - %p view %p, setPresentationOptions 0x%X\n", - dbgIdx++, myWindow, myView, (int)myWindow->fullscreenPresentationOptions); - // TODO [NSApp setPresentationOptions: myWindow->fullscreenPresentationOptions]; - } - } -NS_HANDLER -NS_ENDHANDLER - - DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n", - dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView); - - [pool release]; - DBG_PRINT( "initWindow0.X - %p (this), %p (parent): new window: %p, view %p\n", - (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView); -} - -/** - * Method is called on Main-Thread, hence no special invocation required inside method. - * - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: setPixelScale0 - * Signature: (JJF)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_setPixelScale0 - (JNIEnv *env, jobject jthis, jlong window, jlong view, jfloat reqPixelScale) -{ - NewtUIWindow* myWindow = (NewtUIWindow*) ((intptr_t) window); - if( NULL == myWindow ) { - DBG_PRINT( "setPixelScale0 - NULL NEWT win - abort\n"); - return; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtUIView* myView = (NewtUIView*) (intptr_t) view ; -#ifdef VERBOSE_ON - int dbgIdx = 1; -#endif - DBG_PRINT( "setPixelScale0 - %p (this), %p (window), view %p, reqPixScale %f (START)\n", - (void*)(intptr_t)jthis, myWindow, myView, (float)reqPixelScale); - (void)myWindow; - - DBG_PRINT( "setPixelScale0.%d - %p (this), window: %p, view %p\n", - dbgIdx++, (void*)(intptr_t)jthis, myWindow, myView); - - [pool release]; - DBG_PRINT( "setPixelScale0.X - %p (this), window: %p, view %p\n", - (void*)(intptr_t)jthis, myWindow, myView); -} - -/** - * Method is called on Main-Thread, hence no special invocation required inside method. - * - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: close0 - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_close0 - (JNIEnv *env, jobject unused, jlong window) -{ - NewtUIWindow* mWin = (NewtUIWindow*) ((intptr_t) window); - if( NULL == mWin ) { - DBG_PRINT( "windowClose.0 - NULL NEWT win - abort\n"); - return; - } - BOOL isNSWin = [mWin isKindOfClass:[UIWindow class]]; - BOOL isNewtWin = [mWin isKindOfClass:[NewtUIWindow class]]; - UIWindow *pWin = NULL; // TODO [mWin parentWindow]; - DBG_PRINT( "windowClose.0 - %p [isUIWindow %d, isNewtWin %d], parent %p\n", mWin, isNSWin, isNewtWin, pWin); - (void)isNSWin; // silence - if( !isNewtWin ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtUIWindow %p", mWin); - return; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtUIView* mView = (NewtUIView *)mWin; // TODO [mWin contentView]; - BOOL fullscreen = mWin->isFullscreenWindow; - BOOL destroyNotifySent, isUIView, isNewtUIView; - if( NULL != mView ) { - isUIView = [mView isKindOfClass:[UIView class]]; - isNewtUIView = [mView isKindOfClass:[NewtUIView class]]; - destroyNotifySent = isNewtUIView ? [mView getDestroyNotifySent] : false; - } else { - isUIView = false; - isNewtUIView = false; - destroyNotifySent = false; - } - - DBG_PRINT( "windowClose.0 - %p, destroyNotifySent %d, view %p [isUIView %d, isNewtUIView %d], fullscreen %d, parent %p\n", - mWin, destroyNotifySent, mView, isUIView, isNewtUIView, (int)fullscreen, pWin); - - [mWin setRealized: NO]; - - if( isNewtUIView ) { - // cleanup view - [mView setDestroyNotifySent: true]; - setJavaWindowObject(env, NULL, mView, NO); - } - -NS_DURING - /** - * See Bug 914: We don't use exclusive fullscreen anymore (capturing display) - * See initWindow0(..) above .. - if(NULL!=mView) { - BOOL iifs; - if ( [mView respondsToSelector:@selector(isInFullScreenMode)] ) { - iifs = [mView isInFullScreenMode]; - } else { - iifs = NO; - } - if(iifs && [mView respondsToSelector:@selector(exitFullScreenModeWithOptions:)] ) { - [mView exitFullScreenModeWithOptions: NULL]; - } - } */ - // Note: mWin's release will also release it's mView! - DBG_PRINT( "windowClose.1a - %p view %p, fullscreen %d, hasPresSwitch %d, defaultPresentationOptions 0x%X\n", - mWin, mView, (int)fullscreen, (int)mWin->hasPresentationSwitch, (int)mWin->defaultPresentationOptions); - - if( fullscreen && mWin->hasPresentationSwitch ) { - DBG_PRINT( "windowClose.1b - %p view %p, setPresentationOptions 0x%X\n", - mWin, mView, (int)mWin->defaultPresentationOptions); - // TODO [NSApp setPresentationOptions: mWin->defaultPresentationOptions]; - } -NS_HANDLER -NS_ENDHANDLER - - if(NULL!=pWin) { - [mWin detachFromParent: pWin]; - } - // TODO [mWin orderOut: mWin]; - [mWin setHidden: YES]; // no release, close n/a, .. well: ref count counts :-( - - DBG_PRINT( "windowClose.2 - %p view %p, parent %p\n", mWin, mView, pWin); - - [mWin release]; - - DBG_PRINT( "windowClose.Xp\n"); - - [pool release]; -} - -/* - * Class: Java_jogamp_newt_driver_ios_WindowDriver - * Method: lockSurface0 - * Signature: (JJ)Z - */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_WindowDriver_lockSurface0 - (JNIEnv *env, jclass clazz, jlong window, jlong view) -{ - NewtUIWindow *mWin = (NewtUIWindow*) ((intptr_t) window); - if(NO == [mWin isRealized]) { - return JNI_FALSE; - } - NewtUIView * mView = (NewtUIView *) ((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; */ -} - -/* - * Class: Java_jogamp_newt_driver_ios_WindowDriver - * Method: unlockSurface0 - * Signature: (JJ)Z - */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_WindowDriver_unlockSurface0 - (JNIEnv *env, jclass clazz, jlong window, jlong view) -{ - // NewtUIWindow *mWin = (NewtUIWindow*) ((intptr_t) window); - (void) window; - NewtUIView * mView = (NewtUIView *) ((intptr_t) view); - return [mView softUnlock] == YES ? JNI_TRUE : JNI_FALSE; - /** deadlocks, since we render independent of focus - [mView unlockFocus]; */ -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: requestFocus0 - * Signature: (JZ)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_requestFocus0 - (JNIEnv *env, jobject window, jlong w, jboolean force) -{ - UIWindow* mWin = (UIWindow*) ((intptr_t) w); - if( NULL == mWin ) { - DBG_PRINT( "requestFocus - NULL NEWT win - abort\n"); - return; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; -#ifdef VERBOSE_ON - BOOL hasFocus = [mWin isKeyWindow]; -#endif - DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus); - - // TODO [mWin setAcceptsMouseMovedEvents: YES]; - // TODO [mWin makeFirstResponder: nil]; - // TODO [mWin orderFrontRegardless]; - [mWin makeKeyWindow]; - - DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", mWin, force); - - [pool release]; -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: resignFocus0 - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_resignFocus0 - (JNIEnv *env, jobject window, jlong w) -{ - UIWindow* mWin = (UIWindow*) ((intptr_t) w); - if( NULL == mWin ) { - DBG_PRINT( "resignFocus0 - NULL NEWT win - abort\n"); - return; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - UIWindow* pWin = NULL; // TODO [mWin parentWindow]; - BOOL hasFocus = [mWin isKeyWindow]; - - DBG_PRINT( "resignFocus0 - window: %p, parent %p, hasFocus %d (START)\n", mWin, pWin, hasFocus ); - if( hasFocus ) { - if(NULL != pWin) { - // [mWin makeFirstResponder: pWin]; - [pWin makeKeyWindow]; - } else { - [pWin resignKeyWindow]; - } - } - DBG_PRINT( "resignFocus0 - window: %p (END)\n", mWin); - - [pool release]; -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: orderFront0 - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_orderFront0 - (JNIEnv *env, jobject unused, jlong window) -{ - UIWindow* mWin = (UIWindow*) ((intptr_t) window); - if( NULL == mWin ) { - DBG_PRINT( "orderFront0 - NULL NEWT win - abort\n"); - return; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - UIWindow* pWin = NULL; // TODO [mWin parentWindow]; - - DBG_PRINT( "orderFront0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]); - - if( NULL == pWin ) { - // TODO [mWin orderFrontRegardless]; - } else { - // TODO [mWin orderWindow: UIWindowAbove relativeTo: [pWin windowNumber]]; - } - - DBG_PRINT( "orderFront0 - window: (parent %p) %p (END)\n", pWin, mWin); - - [pool release]; -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: orderOut - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_orderOut0 - (JNIEnv *env, jobject unused, jlong window) -{ - UIWindow* mWin = (UIWindow*) ((intptr_t) window); - if( NULL == mWin ) { - DBG_PRINT( "orderOut0 - NULL NEWT win - abort\n"); - return; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - UIWindow* pWin = NULL; // TODO [mWin parentWindow]; - - DBG_PRINT( "orderOut0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]); - - if( NULL == pWin ) { - // TODO [mWin orderOut: mWin]; - } else { - // TODO [mWin orderWindow: UIWindowOut relativeTo: [pWin windowNumber]]; - } - - DBG_PRINT( "orderOut0 - window: (parent %p) %p (END)\n", pWin, mWin); - - [pool release]; -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: setTitle0 - * Signature: (JLjava/lang/String;)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_setTitle0 - (JNIEnv *env, jobject unused, jlong window, jstring title) -{ - UIWindow* win = (UIWindow*) ((intptr_t) window); - if( NULL == win ) { - DBG_PRINT( "setTitle0 - NULL NEWT win - abort\n"); - return; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - DBG_PRINT( "setTitle0 - window: %p (START)\n", win); - - NSString* str = jstringToNSString(env, title); - [str autorelease]; - // TODO [win setTitle: str]; - - DBG_PRINT( "setTitle0 - window: %p (END)\n", win); - - [pool release]; -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: contentView0 - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_ios_WindowDriver_contentView0 - (JNIEnv *env, jobject unused, jlong window) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - UIWindow* win = (UIWindow*) ((intptr_t) window); - UIView* nsView = (UIView*)win; // TODO [win contentView]; - NewtUIView* newtView = NULL; - - if( [nsView isKindOfClass:[NewtUIView class]] ) { - newtView = (NewtUIView *) nsView; - } - - DBG_PRINT( "contentView0 - window: %p, view: %p, newtView %p\n", win, nsView, newtView); - - jlong res = (jlong) ((intptr_t) nsView); - - [pool release]; - return res; -} - -/** - * Method is called on Main-Thread, hence no special invocation required inside method. - * - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: changeContentView - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_changeContentView0 - (JNIEnv *env, jobject jthis, jlong parentWindowOrView, jlong window, jlong jview) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - NewtUIView* newView = (NewtUIView *) ((intptr_t) jview); - NewtUIWindow* win = (NewtUIWindow*) ((intptr_t) window); - - DBG_PRINT( "changeContentView0.0 - win %p, view (%p,%d)\n", - win, newView, getRetainCount(newView)); - - NSObject *nsParentObj = (NSObject*) ((intptr_t) parentWindowOrView); - UIView* pView = NULL; - if( NULL != nsParentObj ) { - if( [nsParentObj isKindOfClass:[UIWindow class]] ) { - UIWindow * pWin = (UIWindow*) nsParentObj; - pView = (UIView*)pWin; // TODO [pWin contentView]; - } else if( [nsParentObj isKindOfClass:[UIView class]] ) { - pView = (UIView*) nsParentObj; - } - } - - changeContentView(env, jthis, pView, win, newView, YES); - - DBG_PRINT( "changeContentView0.X\n"); - - [pool release]; -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: updateSizePosInsets0 - * Signature: (JZ)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_updateSizePosInsets0 - (JNIEnv *env, jobject jthis, jlong window, jboolean defer) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtUIWindow* mWin = (NewtUIWindow*) ((intptr_t) window); - - DBG_PRINT( "updateSizePosInsets - window: %p, defer %d (START)\n", mWin, (int)defer); - - [mWin updateSizePosInsets: env jwin:jthis defer:defer]; - - DBG_PRINT( "updateSizePosInsets - window: %p, defer %d (END)\n", mWin, (int)defer); - - [pool release]; -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: setWindowClientTopLeftPointAndSize0 - * Signature: (JIIIIZ)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_setWindowClientTopLeftPointAndSize0 - (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jint w, jint h, jboolean display) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtUIWindow* mWin = (NewtUIWindow*) ((intptr_t) window); - - DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (START)\n", mWin); - - setWindowClientTopLeftPointAndSize(mWin, x, y, w, h, display); - - DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (END)\n", mWin); - - [pool release]; -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: setWindowClientTopLeftPoint0 - * Signature: (JIIZ)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_setWindowClientTopLeftPoint0 - (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jboolean display) -{ - NewtUIWindow* mWin = (NewtUIWindow*) ((intptr_t) window); - if( NULL == mWin ) { - DBG_PRINT( "setWindowClientTopLeftPoint - NULL NEWT win - abort\n"); - return; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (START)\n", mWin); - - setWindowClientTopLeftPoint(mWin, x, y, display); - - DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (END)\n", mWin); - - [pool release]; -} - -/* - * Class: jogamp_newt_driver_ios_WindowDriver - * Method: getLocationOnScreen0 - * Signature: (JII)Lcom/jogamp/nativewindow/util/Point; - */ -JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_ios_WindowDriver_getLocationOnScreen0 - (JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y) -{ - NewtUIWindow *mWin = (NewtUIWindow*) (intptr_t) win; - if( NULL == mWin ) { - DBG_PRINT( "getLocationOnScreen0 - NULL NEWT win - abort\n"); - return NULL; - } - if( ![mWin isKindOfClass:[NewtUIWindow class]] ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtUIWindow %p", mWin); - return NULL; - } - CGPoint p0 = [mWin getLocationOnScreen: CGPointMake(src_x, src_y)]; - return (*env)->NewObject(env, pointClz, pointCstr, (jint)p0.x, (jint)p0.y); -} - diff --git a/src/newt/native/IOSWindow.m b/src/newt/native/IOSWindow.m new file mode 100644 index 000000000..780c2344f --- /dev/null +++ b/src/newt/native/IOSWindow.m @@ -0,0 +1,1161 @@ +/** + * Copyright 2019 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +#import + +#import "jogamp_newt_driver_ios_WindowDriver.h" +#import "IOSNewtUIWindow.h" + +#import "MouseEvent.h" +#import "KeyEvent.h" +#import "ScreenMode.h" + +#import + +#ifdef DBG_PERF + #include "timespec.h" +#endif + +static const char * const ClazzNamePoint = "com/jogamp/nativewindow/util/Point"; +static const char * const ClazzAnyCstrName = ""; +static const char * const ClazzNamePointCstrSignature = "(II)V"; +static jclass pointClz = NULL; +static jmethodID pointCstr = NULL; + +static NSString* jstringToNSString(JNIEnv* env, jstring jstr) +{ + const jchar* jstrChars = (*env)->GetStringChars(env, jstr, NULL); + NSString* str = [[NSString alloc] initWithCharacters: jstrChars length: (*env)->GetStringLength(env, jstr)]; + (*env)->ReleaseStringChars(env, jstr, jstrChars); + return str; +} + +static void setWindowClientTopLeftPoint(NewtUIWindow* mWin, jint x, jint y, BOOL doDisplay) { + DBG_PRINT( "setWindowClientTopLeftPoint.0 - window: %p %d/%d, display %d\n", mWin, (int)x, (int)y, (int)doDisplay); + CGPoint pS = CGPointMake(x, y); + CGRect rect = [mWin frame]; + rect.origin = pS; + + [mWin setFrame: rect]; + DBG_PRINT( "setWindowClientTopLeftPoint.X: %d/%d\n", (int)pS.x, (int)pS.y); + + if( doDisplay ) { + // TODO UIView* mView = [mWin contentView]; + // TODO [mWin invalidateCursorRectsForView: mView]; + } +} + +static void setWindowClientTopLeftPointAndSize(NewtUIWindow* mWin, jint x, jint y, jint width, jint height, BOOL doDisplay) { + DBG_PRINT( "setWindowClientTopLeftPointAndSize.0 - window: %p %d/%d %dx%d, display %d\n", mWin, (int)x, (int)y, (int)width, (int)height, (int)doDisplay); + CGRect rect = CGRectMake(x, y, width, height); + DBG_PRINT( "setWindowClientTopLeftPointAndSize.1: %d/%d %dx%d\n", (int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height); + + // TODO [mWin setFrame: rect display:doDisplay]; + [mWin setFrame: rect]; + 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); + + // -> display:YES + // if( doDisplay ) { + // UIView* mView = [mWin contentView]; + // [mWin invalidateCursorRectsForView: mView]; + // } +} + +#ifdef VERBOSE_ON +static int getRetainCount(NSObject * obj) { + return ( NULL == obj ) ? -1 : (int)([obj retainCount]) ; +} +#endif + +static void setJavaWindowObject(JNIEnv *env, jobject newJavaWindowObject, NewtUIView *view, BOOL enable) { + DBG_PRINT( "setJavaWindowObject.0: View %p\n", view); + if( !enable) { + jobject globJavaWindowObject = [view getJavaWindowObject]; + if( NULL != globJavaWindowObject ) { + DBG_PRINT( "setJavaWindowObject.1: View %p - Clear old javaWindowObject %p\n", view, globJavaWindowObject); + (*env)->DeleteGlobalRef(env, globJavaWindowObject); + [view setJavaWindowObject: NULL]; + } + } else if( NULL != newJavaWindowObject ) { + DBG_PRINT( "setJavaWindowObject.2: View %p - Set new javaWindowObject %p\n", view, newJavaWindowObject); + jobject globJavaWindowObject = (*env)->NewGlobalRef(env, newJavaWindowObject); + [view setJavaWindowObject: globJavaWindowObject]; + } + DBG_PRINT( "setJavaWindowObject.X: View %p\n", view); +} + +static void changeContentView(JNIEnv *env, jobject javaWindowObject, UIView *pview, NewtUIWindow *win, NewtUIView *newView, BOOL setJavaWindow) { + UIView* oldUIView = NULL; // TODO [win contentView]; + NewtUIView* oldNewtUIView = NULL; +#ifdef VERBOSE_ON + int dbgIdx = 1; +#endif + + if( [oldUIView isKindOfClass:[NewtUIView class]] ) { + oldNewtUIView = (NewtUIView *) oldUIView; + } + + DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d), parent view %p\n", + dbgIdx++, win, oldUIView, getRetainCount(oldUIView), NULL!=oldNewtUIView, newView, getRetainCount(newView), pview); + + if( NULL!=oldUIView ) { +NS_DURING + // Available >= 10.5 - Makes the menubar disapear + BOOL iifs = NO; // TODO [oldUIView isInFullScreenMode]; + if( iifs ) { + // TODO [oldUIView exitFullScreenModeWithOptions: NULL]; + } +NS_HANDLER +NS_ENDHANDLER + DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d)\n", + dbgIdx++, win, oldUIView, getRetainCount(oldUIView), NULL!=oldNewtUIView, newView, getRetainCount(newView)); + + if( NULL != oldNewtUIView ) { + [oldNewtUIView setDestroyNotifySent: false]; + setJavaWindowObject(env, NULL, oldNewtUIView, NO); + } + // TODO [oldUIView removeFromSuperviewWithoutNeedingDisplay]; + } + DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", + dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]); + + if( NULL!=newView ) { + [newView setDestroyNotifySent: false]; + if( setJavaWindow ) { + setJavaWindowObject(env, javaWindowObject, newView, YES); + } + + DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d)\n", + dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView)); + + if(NULL!=pview) { + // TODO [pview addSubview: newView positioned: UIWindowAbove relativeTo: nil]; + } + } + DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", + dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]); + + // TODO [win setContentView: newView]; + + DBG_PRINT( "changeContentView.%d win %p, view (%p,%d -> %p,%d), isHidden %d, isHiddenOrHasHiddenAncestor: %d\n", + dbgIdx++, win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView), [newView isHidden], [newView isHiddenOrHasHiddenAncestor]); + + // make sure the insets are updated in the java object + [win updateInsets: env jwin:javaWindowObject]; + + DBG_PRINT( "changeContentView.X win %p, view (%p,%d -> %p,%d)\n", + win, oldUIView, getRetainCount(oldUIView), newView, getRetainCount(newView)); +} + +/* + * Class: jogamp_newt_driver_ios_DisplayDriver + * Method: initIDs + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_DisplayDriver_initUIApplication0 + (JNIEnv *env, jclass clazz) +{ + static int initialized = 0; + + if(initialized) return JNI_TRUE; + initialized = 1; + + NewtCommon_init(env); + + // Initialize the shared NSApplication instance + [UIApplication sharedApplication]; + + // Need this when debugging, as it is necessary to attach gdb to + // the running java process -- "gdb java" doesn't work + // printf("Going to sleep for 10 seconds\n"); + // sleep(10); + + return (jboolean) JNI_TRUE; +} + +static void NewtScreen_dump() { +#ifdef VERBOSE_ON + NSArray *screens = [UIScreen screens]; + int i; + for(i=0; i<[screens count]; i++) { + UIScreen * screen = (UIScreen *) [screens objectAtIndex: i]; + CGRect screenFrame = [screen frame]; + CGRect screenVisibleFrame = [screen visibleFrame]; + CGFloat pixelScale = 1.0; // default + pixelScale = [screen scale]; // HiDPI scaling + UIWindowDepth depth = [screen depth]; // an (int) value! + DBG_PRINT( "UIScreen #%d (%p): Frame %lf/%lf %lfx%lf (vis %lf/%lf %lfx%lf), scale %lf, depth %d\n", + i, screen, + screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height, + screenVisibleFrame.origin.x, screenVisibleFrame.origin.y, screenVisibleFrame.size.width, screenVisibleFrame.size.height, + pixelScale, depth); + } +#endif +} + +// Duplicate each Mode by all possible rotations (4): +// For each real-mode: [mode, 0], [mode, 90], [mode, 180], [mode, 270] +#define ROTMODES_PER_REALMODE 1 + +/* + * Class: jogamp_newt_driver_ios_ScreenDriver + * Method: getMonitorDeviceIds0 + * Signature: ()I + */ +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_getMonitorDeviceIds0 + (JNIEnv *env, jobject obj) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSArray *screens = [UIScreen screens]; + int count = [screens count]; + int32_t displayIDs[count]; + int i; + for(i=0; iNewIntArray(env, count); + if (properties == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", count); + } + (*env)->SetIntArrayRegion(env, properties, 0, count, displayIDs); + [pool release]; + return properties; +} + +/* + * Class: jogamp_newt_driver_ios_ScreenDriver + * Method: getMonitorProps0 + * Signature: (I)[I + */ +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_getMonitorProps0 + (JNIEnv *env, jobject obj, jint crt_id) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + +#ifdef DBG_PERF + struct timespec t0, t1, td; + long td_ms; + timespec_now(&t0); +#endif + +#ifdef DBG_PERF + timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); + fprintf(stderr, "MacScreen_getMonitorProps0.1: %ld ms\n", td_ms); fflush(NULL); +#endif + NSArray *screens = [UIScreen screens]; + int count = [screens count]; + UIScreen * screen = (UIScreen *) [screens objectAtIndex: crt_id]; + if( NULL == screen ) { + [pool release]; + return NULL; + } + BOOL isPrimary = 0 == crt_id; +#ifdef DBG_PERF + timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); + fprintf(stderr, "MacScreen_getMonitorProps0.2: %ld ms\n", td_ms); fflush(NULL); +#endif + + UIScreenMode * screenMode = [screen currentMode]; + CGSize sizeMM = CGSizeMake(161.0, 228.0); // TODO ??? +#ifdef DBG_PERF + timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); + fprintf(stderr, "MacScreen_getMonitorProps0.3: %ld ms\n", td_ms); fflush(NULL); +#endif + + CGRect dBounds = [screen bounds]; +#ifdef VERBOSE_ON + DBG_PRINT( "getMonitorProps0: crt_id 0x%X (prim %d), top-left displayBounds[%d/%d %dx%d]\n", + (int)crt_id, isPrimary, + (int)dBounds.origin.x, (int)dBounds.origin.y, (int)dBounds.size.width, (int)dBounds.size.height); +#endif + + jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES; + jint prop[ propCount ]; + int offset = 0; + prop[offset++] = propCount; + prop[offset++] = crt_id; + prop[offset++] = 0; // isClone + prop[offset++] = isPrimary ? 1 : 0; // isPrimary + prop[offset++] = (jint) sizeMM.width; + prop[offset++] = (jint) sizeMM.height; + prop[offset++] = (jint) dBounds.origin.x; // rotated viewport x (pixel units, will be fixed in java code) + prop[offset++] = (jint) dBounds.origin.y; // rotated viewport y (pixel units, will be fixed in java code) + prop[offset++] = (jint) dBounds.size.width; // rotated viewport width (pixel units, will be fixed in java code) + prop[offset++] = (jint) dBounds.size.height; // rotated viewport height (pixel units, will be fixed in java code) + prop[offset++] = (jint) dBounds.origin.x; // rotated viewport x (window units, will be fixed in java code) + prop[offset++] = (jint) dBounds.origin.y; // rotated viewport y (window units, will be fixed in java code) + prop[offset++] = (jint) dBounds.size.width; // rotated viewport width (window units, will be fixed in java code) + prop[offset++] = (jint) dBounds.size.height; // rotated viewport height (window units, will be fixed in java code) + + jintArray properties = (*env)->NewIntArray(env, propCount); + if (properties == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount); + } + (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop); + + [pool release]; + + return properties; +} + +/* + * Class: jogamp_newt_driver_ios_ScreenDriver + * Method: getMonitorMode0 + * Signature: (II)[I + */ +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_getMonitorMode0 + (JNIEnv *env, jobject obj, jint crt_id, jint mode_idx) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + NSArray *screens = [UIScreen screens]; + int count = [screens count]; + UIScreen * screen = (UIScreen *) [screens objectAtIndex: crt_id]; + if( NULL == screen ) { + [pool release]; + return NULL; + } + CGFloat pixelScale = 1.0; // default +NS_DURING + // Available >= 10.7 + pixelScale = [screen scale]; // HiDPI scaling +NS_HANDLER +NS_ENDHANDLER + + NSArray *availableModes = [screen availableModes]; + int numberOfAvailableModes = [availableModes count]; + CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes; + int currentCCWRot = 0; + jint ccwRot = 0; + int nativeId = 0; + UIScreenMode * mode = NULL; + +#ifdef VERBOSE_ON + if(0 >= mode_idx) { + // only for current mode (-1) and first mode (scanning) + DBG_PRINT( "getScreenMode0: crtID 0x%X (s %p, pscale %lf), mode %d, avail: %d/%d, current rot %d ccw\n", + (uint32_t)displayID, screen, pixelScale, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot); + } +#endif + + if(numberOfAvailableModesRots<=mode_idx) { + // n/a - end of modes + DBG_PRINT( "getScreenMode0: end of modes: mode %d, avail: %d/%d\n", + (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots); + [pool release]; + return NULL; + } else if(-1 < mode_idx) { + // only at initialization time, where index >= 0 + nativeId = mode_idx / ROTMODES_PER_REALMODE; + ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90; + mode = (UIScreenMode*) [availableModes objectAtIndex: nativeId]; + } else { + // current mode + mode = [screen currentMode]; + ccwRot = 0; + nativeId = 0; + } + // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef + + CGSize mSize = [mode size]; + int mWidth = (int)mSize.width; + int mHeight = (int)mSize.height; + if( -1 == mode_idx ) { + mWidth *= (int)pixelScale; // accomodate HiDPI + mHeight *= (int)pixelScale; // accomodate HiDPI + } + + // swap width and height, since OSX reflects rotated dimension, we don't + if ( 90 == currentCCWRot || 270 == currentCCWRot ) { + int tempWidth = mWidth; + mWidth = mHeight; + mHeight = tempWidth; + } + + jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ]; + int propIndex = 0; + + int refreshRate = 60; // TODO + int fRefreshRate = ( 0 < refreshRate ) ? refreshRate : 60; // default .. (experienced on OSX 10.6.8) + prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL; + prop[propIndex++] = mWidth; + prop[propIndex++] = mHeight; + prop[propIndex++] = 32; // TODO CGDDGetModeBitsPerPixel(mode); + prop[propIndex++] = fRefreshRate * 100; // Hz*100 + prop[propIndex++] = 0; // flags + prop[propIndex++] = nativeId; + prop[propIndex++] = ccwRot; + + DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %d / %d Hz, nativeId %d, rot %d ccw\n", + (int)mode_idx, (int)numberOfAvailableModesRots, (int)numberOfAvailableModes, + (int)prop[1], (int)prop[2], (int)prop[3], + (int)prop[4], refreshRate, (int)prop[6], (int)prop[7]); + + jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL); + if (properties == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL); + } + (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop); + + // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef + [pool release]; + + return properties; +} + +/* + * Class: jogamp_newt_driver_ios_ScreenDriver + * Method: setMonitorMode0 + * Signature: (III)Z + */ +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_ScreenDriver_setMonitorMode0 + (JNIEnv *env, jobject object, jint crt_id, jint nativeId, jint ccwRot) +{ + return false; +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: initIDs + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_WindowDriver_initIDs0 + (JNIEnv *env, jclass clazz) +{ + static int initialized = 0; + + if(initialized) return JNI_TRUE; + initialized = 1; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + NewtScreen_dump(); + + jclass c; + c = (*env)->FindClass(env, ClazzNamePoint); + if(NULL==c) { + NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_ios_WindowDriver_initIDs0: can't find %s", ClazzNamePoint); + } + pointClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==pointClz) { + NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_ios_WindowDriver_initIDs0: can't use %s", ClazzNamePoint); + } + pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); + if(NULL==pointCstr) { + NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_ios_WindowDriver_initIDs0: can't fetch %s.%s %s", + ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); + } + + // Need this when debugging, as it is necessary to attach gdb to + // the running java process -- "gdb java" doesn't work + // printf("Going to sleep for 10 seconds\n"); + // sleep(10); + + BOOL res = [NewtUIWindow initNatives: env forClass: clazz]; + [pool release]; + + return (jboolean) res; +} + +/** + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: createView0 + * Signature: (IIII)J + */ +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_ios_WindowDriver_createView0 + (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d (START)\n", + (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h); + + CGRect rectView = CGRectMake(0, 0, w, h); + NewtUIView *myView = [[NewtUIView alloc] initWithFrame: rectView] ; + DBG_PRINT( "createView0.X - 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_ios_WindowDriver + * Method: createWindow0 + * Signature: (IIIIZIIJ)J + */ +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_ios_WindowDriver_createWindow0 + (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, + jboolean fullscreen, jint styleMask, jint bufferingType, jlong jview) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NewtUIView* myView = (NewtUIView*) (intptr_t) jview ; + + DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, view %p (START)\n", + (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen, + (int)styleMask, (int)bufferingType, myView); + (void)myView; + + if (fullscreen) { + // TODO styleMask = NSBorderlessWindowMask; + } + CGRect rectWin = CGRectMake(x, y, w, h); + + // Allocate the window + NewtUIWindow* myWindow = [[NewtUIWindow alloc] initWithContentRect: rectWin + styleMask: (NSUInteger) styleMask + backing: 0 // TODO (NSBackingStoreType) bufferingType + defer: YES + 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); +} + +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_ios_WindowDriver_getDisplayID0(JNIEnv *env, jobject jthis, jlong window) { + NewtUIWindow* myWindow = (NewtUIWindow*) ((intptr_t) window); + if( NULL == myWindow ) { + DBG_PRINT( "getDisplayID0 - NULL NEWT win - abort\n"); + return 0; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + UIScreen *screen = [myWindow screen]; + int32_t displayID = 0; // TODO (int32_t)NewtScreen_getCGDirectDisplayIDByUIScreen(screen); + [pool release]; + return (jint) displayID; +} + +/** + * Method is called on Main-Thread, hence no special invocation required inside method. + * + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: initWindow0 + * Signature: (JJIIIIFZZZJ)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_initWindow0 + (JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h, jfloat reqPixelScale, + jboolean opaque, jboolean atop, jboolean abottom, jboolean visible, jlong jview) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NewtUIWindow* myWindow = (NewtUIWindow*) ((intptr_t) window); + NewtUIView* myView = (NewtUIView*) (intptr_t) jview ; + BOOL fullscreen = myWindow->isFullscreenWindow; + + DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, reqPixScale %f, opaque %d, atop %d, abottom %d, fs %d, visible %d, view %p (START)\n", + (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, (float)reqPixelScale, + (int) opaque, (int)atop, (int)abottom, (int)fullscreen, (int)visible, myView); + + // TODO [myWindow setReleasedWhenClosed: NO]; // We control UIWindow destruction! + // TODO [myWindow setPreservesContentDuringLiveResize: NO]; + + NSObject* nsParentObj = (NSObject*) ((intptr_t) parent); + UIWindow* parentWindow = NULL; + UIView* parentView = NULL; + if( nsParentObj != NULL && [nsParentObj isKindOfClass:[UIWindow class]] ) { + parentWindow = (UIWindow*) nsParentObj; + parentView = (UIView*)nsParentObj; + DBG_PRINT( "initWindow0 - Parent is UIWindow : %p (win) -> %p (view) \n", parentWindow, parentView); + } else if( nsParentObj != NULL && [nsParentObj isKindOfClass:[UIView class]] ) { + parentView = (UIView*) nsParentObj; + parentWindow = [parentView window]; + DBG_PRINT( "initWindow0 - Parent is UIView : %p -(view) > %p (win) \n", parentView, parentWindow); + } else { + DBG_PRINT( "initWindow0 - Parent is neither UIWindow nor UIView : %p\n", nsParentObj); + } + DBG_PRINT( "initWindow0 - is visible.1: %d\n", [myWindow isVisible]); + + // Remove animations for child windows + if(NULL != parentWindow) { + [UIView setAnimationsEnabled: NO]; + } + +#ifdef VERBOSE_ON + int dbgIdx = 1; +#endif + if(opaque) { + [myWindow setOpaque: YES]; + DBG_PRINT( "initWindow0.%d\n", dbgIdx++); + if (!fullscreen) { + // TODO [myWindow setShowsResizeIndicator: YES]; + } + DBG_PRINT( "initWindow0.%d\n", dbgIdx++); + } else { + [myWindow setOpaque: NO]; + [myWindow setBackgroundColor: [UIColor clearColor]]; + } + [myWindow setAlwaysOn: atop bottom:abottom]; + + // specify we want mouse-moved events + // TODO [myWindow setAcceptsMouseMovedEvents:YES]; + + DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", + dbgIdx++, myWindow, myView, [myWindow isVisible]); + + // Set the content view + changeContentView(env, jthis, parentView, myWindow, myView, NO); + // TODO [myWindow setInitialFirstResponder: myView]; + + DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", + dbgIdx++, myWindow, myView, [myWindow isVisible]); + + if(NULL!=parentWindow) { + [myWindow attachToParent: parentWindow]; + } + + DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d, visible %d\n", + dbgIdx++, myWindow, myView, [myWindow isVisible], visible); + + // Immediately re-position this window based on an upper-left coordinate system + setWindowClientTopLeftPointAndSize(myWindow, x, y, w, h, NO); + + DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", + dbgIdx++, myWindow, myView, [myWindow isVisible]); + + // TODO [myWindow setAllowsConcurrentViewDrawing: YES]; + + DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", + dbgIdx++, myWindow, myView, [myWindow isVisible]); + + // TODO [myView setCanDrawConcurrently: YES]; + + DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", + dbgIdx++, myWindow, myView, [myWindow isVisible]); + + // visible on front + if( visible ) { + // TODO [myWindow orderFront: myWindow]; + } + + DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n", + dbgIdx++, myWindow, myView, [myWindow isVisible]); + + // force surface creation + // [myView lockFocus]; + // [myView unlockFocus]; + + // Set the next responder to be the window so that we can forward + // right mouse button down events + // TODO [myView setNextResponder: myWindow]; + + DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n", + dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView); + + [myView setDestroyNotifySent: false]; + setJavaWindowObject(env, jthis, myView, YES); + + DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n", + dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView); + +NS_DURING + if( fullscreen ) { + /** + * See Bug 914: We don't use exclusive fullscreen anymore (capturing display) + * allowing ALT-TAB to allow process/app switching! + * Shall have no penalty on modern GPU and is also recommended, see bottom box @ + * + * + UIScreen *myScreen = NewtScreen_getUIScreenByCoord(x, y); + if( NULL != myScreen ) { + if ( [myView respondsToSelector:@selector(enterFullScreenMode:withOptions:)] ) { + // Available >= 10.5 - Makes the menubar disapear + [myView enterFullScreenMode: myScreen withOptions:NULL]; + } + } + */ + if( myWindow->hasPresentationSwitch ) { + DBG_PRINT( "initWindow0.%d - %p view %p, setPresentationOptions 0x%X\n", + dbgIdx++, myWindow, myView, (int)myWindow->fullscreenPresentationOptions); + // TODO [NSApp setPresentationOptions: myWindow->fullscreenPresentationOptions]; + } + } +NS_HANDLER +NS_ENDHANDLER + + DBG_PRINT( "initWindow0.%d - %p (this), %p (parent): new window: %p, view %p\n", + dbgIdx++, (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView); + + [pool release]; + DBG_PRINT( "initWindow0.X - %p (this), %p (parent): new window: %p, view %p\n", + (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView); +} + +/** + * Method is called on Main-Thread, hence no special invocation required inside method. + * + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: setPixelScale0 + * Signature: (JJF)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_setPixelScale0 + (JNIEnv *env, jobject jthis, jlong window, jlong view, jfloat reqPixelScale) +{ + NewtUIWindow* myWindow = (NewtUIWindow*) ((intptr_t) window); + if( NULL == myWindow ) { + DBG_PRINT( "setPixelScale0 - NULL NEWT win - abort\n"); + return; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NewtUIView* myView = (NewtUIView*) (intptr_t) view ; +#ifdef VERBOSE_ON + int dbgIdx = 1; +#endif + DBG_PRINT( "setPixelScale0 - %p (this), %p (window), view %p, reqPixScale %f (START)\n", + (void*)(intptr_t)jthis, myWindow, myView, (float)reqPixelScale); + (void)myWindow; + + DBG_PRINT( "setPixelScale0.%d - %p (this), window: %p, view %p\n", + dbgIdx++, (void*)(intptr_t)jthis, myWindow, myView); + + [pool release]; + DBG_PRINT( "setPixelScale0.X - %p (this), window: %p, view %p\n", + (void*)(intptr_t)jthis, myWindow, myView); +} + +/** + * Method is called on Main-Thread, hence no special invocation required inside method. + * + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: close0 + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_close0 + (JNIEnv *env, jobject unused, jlong window) +{ + NewtUIWindow* mWin = (NewtUIWindow*) ((intptr_t) window); + if( NULL == mWin ) { + DBG_PRINT( "windowClose.0 - NULL NEWT win - abort\n"); + return; + } + BOOL isNSWin = [mWin isKindOfClass:[UIWindow class]]; + BOOL isNewtWin = [mWin isKindOfClass:[NewtUIWindow class]]; + UIWindow *pWin = NULL; // TODO [mWin parentWindow]; + DBG_PRINT( "windowClose.0 - %p [isUIWindow %d, isNewtWin %d], parent %p\n", mWin, isNSWin, isNewtWin, pWin); + (void)isNSWin; // silence + if( !isNewtWin ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtUIWindow %p", mWin); + return; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NewtUIView* mView = (NewtUIView *)mWin; // TODO [mWin contentView]; + BOOL fullscreen = mWin->isFullscreenWindow; + BOOL destroyNotifySent, isUIView, isNewtUIView; + if( NULL != mView ) { + isUIView = [mView isKindOfClass:[UIView class]]; + isNewtUIView = [mView isKindOfClass:[NewtUIView class]]; + destroyNotifySent = isNewtUIView ? [mView getDestroyNotifySent] : false; + } else { + isUIView = false; + isNewtUIView = false; + destroyNotifySent = false; + } + + DBG_PRINT( "windowClose.0 - %p, destroyNotifySent %d, view %p [isUIView %d, isNewtUIView %d], fullscreen %d, parent %p\n", + mWin, destroyNotifySent, mView, isUIView, isNewtUIView, (int)fullscreen, pWin); + + [mWin setRealized: NO]; + + if( isNewtUIView ) { + // cleanup view + [mView setDestroyNotifySent: true]; + setJavaWindowObject(env, NULL, mView, NO); + } + +NS_DURING + /** + * See Bug 914: We don't use exclusive fullscreen anymore (capturing display) + * See initWindow0(..) above .. + if(NULL!=mView) { + BOOL iifs; + if ( [mView respondsToSelector:@selector(isInFullScreenMode)] ) { + iifs = [mView isInFullScreenMode]; + } else { + iifs = NO; + } + if(iifs && [mView respondsToSelector:@selector(exitFullScreenModeWithOptions:)] ) { + [mView exitFullScreenModeWithOptions: NULL]; + } + } */ + // Note: mWin's release will also release it's mView! + DBG_PRINT( "windowClose.1a - %p view %p, fullscreen %d, hasPresSwitch %d, defaultPresentationOptions 0x%X\n", + mWin, mView, (int)fullscreen, (int)mWin->hasPresentationSwitch, (int)mWin->defaultPresentationOptions); + + if( fullscreen && mWin->hasPresentationSwitch ) { + DBG_PRINT( "windowClose.1b - %p view %p, setPresentationOptions 0x%X\n", + mWin, mView, (int)mWin->defaultPresentationOptions); + // TODO [NSApp setPresentationOptions: mWin->defaultPresentationOptions]; + } +NS_HANDLER +NS_ENDHANDLER + + if(NULL!=pWin) { + [mWin detachFromParent: pWin]; + } + // TODO [mWin orderOut: mWin]; + [mWin setHidden: YES]; // no release, close n/a, .. well: ref count counts :-( + + DBG_PRINT( "windowClose.2 - %p view %p, parent %p\n", mWin, mView, pWin); + + [mWin release]; + + DBG_PRINT( "windowClose.Xp\n"); + + [pool release]; +} + +/* + * Class: Java_jogamp_newt_driver_ios_WindowDriver + * Method: lockSurface0 + * Signature: (JJ)Z + */ +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_WindowDriver_lockSurface0 + (JNIEnv *env, jclass clazz, jlong window, jlong view) +{ + NewtUIWindow *mWin = (NewtUIWindow*) ((intptr_t) window); + if(NO == [mWin isRealized]) { + return JNI_FALSE; + } + NewtUIView * mView = (NewtUIView *) ((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; */ +} + +/* + * Class: Java_jogamp_newt_driver_ios_WindowDriver + * Method: unlockSurface0 + * Signature: (JJ)Z + */ +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_ios_WindowDriver_unlockSurface0 + (JNIEnv *env, jclass clazz, jlong window, jlong view) +{ + // NewtUIWindow *mWin = (NewtUIWindow*) ((intptr_t) window); + (void) window; + NewtUIView * mView = (NewtUIView *) ((intptr_t) view); + return [mView softUnlock] == YES ? JNI_TRUE : JNI_FALSE; + /** deadlocks, since we render independent of focus + [mView unlockFocus]; */ +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: requestFocus0 + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_requestFocus0 + (JNIEnv *env, jobject window, jlong w, jboolean force) +{ + UIWindow* mWin = (UIWindow*) ((intptr_t) w); + if( NULL == mWin ) { + DBG_PRINT( "requestFocus - NULL NEWT win - abort\n"); + return; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; +#ifdef VERBOSE_ON + BOOL hasFocus = [mWin isKeyWindow]; +#endif + DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus); + + // TODO [mWin setAcceptsMouseMovedEvents: YES]; + // TODO [mWin makeFirstResponder: nil]; + // TODO [mWin orderFrontRegardless]; + [mWin makeKeyWindow]; + + DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", mWin, force); + + [pool release]; +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: resignFocus0 + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_resignFocus0 + (JNIEnv *env, jobject window, jlong w) +{ + UIWindow* mWin = (UIWindow*) ((intptr_t) w); + if( NULL == mWin ) { + DBG_PRINT( "resignFocus0 - NULL NEWT win - abort\n"); + return; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + UIWindow* pWin = NULL; // TODO [mWin parentWindow]; + BOOL hasFocus = [mWin isKeyWindow]; + + DBG_PRINT( "resignFocus0 - window: %p, parent %p, hasFocus %d (START)\n", mWin, pWin, hasFocus ); + if( hasFocus ) { + if(NULL != pWin) { + // [mWin makeFirstResponder: pWin]; + [pWin makeKeyWindow]; + } else { + [pWin resignKeyWindow]; + } + } + DBG_PRINT( "resignFocus0 - window: %p (END)\n", mWin); + + [pool release]; +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: orderFront0 + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_orderFront0 + (JNIEnv *env, jobject unused, jlong window) +{ + UIWindow* mWin = (UIWindow*) ((intptr_t) window); + if( NULL == mWin ) { + DBG_PRINT( "orderFront0 - NULL NEWT win - abort\n"); + return; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + UIWindow* pWin = NULL; // TODO [mWin parentWindow]; + + DBG_PRINT( "orderFront0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]); + + if( NULL == pWin ) { + // TODO [mWin orderFrontRegardless]; + } else { + // TODO [mWin orderWindow: UIWindowAbove relativeTo: [pWin windowNumber]]; + } + + DBG_PRINT( "orderFront0 - window: (parent %p) %p (END)\n", pWin, mWin); + + [pool release]; +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: orderOut + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_orderOut0 + (JNIEnv *env, jobject unused, jlong window) +{ + UIWindow* mWin = (UIWindow*) ((intptr_t) window); + if( NULL == mWin ) { + DBG_PRINT( "orderOut0 - NULL NEWT win - abort\n"); + return; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + UIWindow* pWin = NULL; // TODO [mWin parentWindow]; + + DBG_PRINT( "orderOut0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]); + + if( NULL == pWin ) { + // TODO [mWin orderOut: mWin]; + } else { + // TODO [mWin orderWindow: UIWindowOut relativeTo: [pWin windowNumber]]; + } + + DBG_PRINT( "orderOut0 - window: (parent %p) %p (END)\n", pWin, mWin); + + [pool release]; +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: setTitle0 + * Signature: (JLjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_setTitle0 + (JNIEnv *env, jobject unused, jlong window, jstring title) +{ + UIWindow* win = (UIWindow*) ((intptr_t) window); + if( NULL == win ) { + DBG_PRINT( "setTitle0 - NULL NEWT win - abort\n"); + return; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + DBG_PRINT( "setTitle0 - window: %p (START)\n", win); + + NSString* str = jstringToNSString(env, title); + [str autorelease]; + // TODO [win setTitle: str]; + + DBG_PRINT( "setTitle0 - window: %p (END)\n", win); + + [pool release]; +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: contentView0 + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_ios_WindowDriver_contentView0 + (JNIEnv *env, jobject unused, jlong window) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + UIWindow* win = (UIWindow*) ((intptr_t) window); + UIView* nsView = (UIView*)win; // TODO [win contentView]; + NewtUIView* newtView = NULL; + + if( [nsView isKindOfClass:[NewtUIView class]] ) { + newtView = (NewtUIView *) nsView; + } + + DBG_PRINT( "contentView0 - window: %p, view: %p, newtView %p\n", win, nsView, newtView); + + jlong res = (jlong) ((intptr_t) nsView); + + [pool release]; + return res; +} + +/** + * Method is called on Main-Thread, hence no special invocation required inside method. + * + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: changeContentView + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_changeContentView0 + (JNIEnv *env, jobject jthis, jlong parentWindowOrView, jlong window, jlong jview) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + NewtUIView* newView = (NewtUIView *) ((intptr_t) jview); + NewtUIWindow* win = (NewtUIWindow*) ((intptr_t) window); + + DBG_PRINT( "changeContentView0.0 - win %p, view (%p,%d)\n", + win, newView, getRetainCount(newView)); + + NSObject *nsParentObj = (NSObject*) ((intptr_t) parentWindowOrView); + UIView* pView = NULL; + if( NULL != nsParentObj ) { + if( [nsParentObj isKindOfClass:[UIWindow class]] ) { + UIWindow * pWin = (UIWindow*) nsParentObj; + pView = (UIView*)pWin; // TODO [pWin contentView]; + } else if( [nsParentObj isKindOfClass:[UIView class]] ) { + pView = (UIView*) nsParentObj; + } + } + + changeContentView(env, jthis, pView, win, newView, YES); + + DBG_PRINT( "changeContentView0.X\n"); + + [pool release]; +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: updateSizePosInsets0 + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_updateSizePosInsets0 + (JNIEnv *env, jobject jthis, jlong window, jboolean defer) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NewtUIWindow* mWin = (NewtUIWindow*) ((intptr_t) window); + + DBG_PRINT( "updateSizePosInsets - window: %p, defer %d (START)\n", mWin, (int)defer); + + [mWin updateSizePosInsets: env jwin:jthis defer:defer]; + + DBG_PRINT( "updateSizePosInsets - window: %p, defer %d (END)\n", mWin, (int)defer); + + [pool release]; +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: setWindowClientTopLeftPointAndSize0 + * Signature: (JIIIIZ)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_setWindowClientTopLeftPointAndSize0 + (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jint w, jint h, jboolean display) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NewtUIWindow* mWin = (NewtUIWindow*) ((intptr_t) window); + + DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (START)\n", mWin); + + setWindowClientTopLeftPointAndSize(mWin, x, y, w, h, display); + + DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (END)\n", mWin); + + [pool release]; +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: setWindowClientTopLeftPoint0 + * Signature: (JIIZ)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_ios_WindowDriver_setWindowClientTopLeftPoint0 + (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jboolean display) +{ + NewtUIWindow* mWin = (NewtUIWindow*) ((intptr_t) window); + if( NULL == mWin ) { + DBG_PRINT( "setWindowClientTopLeftPoint - NULL NEWT win - abort\n"); + return; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (START)\n", mWin); + + setWindowClientTopLeftPoint(mWin, x, y, display); + + DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (END)\n", mWin); + + [pool release]; +} + +/* + * Class: jogamp_newt_driver_ios_WindowDriver + * Method: getLocationOnScreen0 + * Signature: (JII)Lcom/jogamp/nativewindow/util/Point; + */ +JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_ios_WindowDriver_getLocationOnScreen0 + (JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y) +{ + NewtUIWindow *mWin = (NewtUIWindow*) (intptr_t) win; + if( NULL == mWin ) { + DBG_PRINT( "getLocationOnScreen0 - NULL NEWT win - abort\n"); + return NULL; + } + if( ![mWin isKindOfClass:[NewtUIWindow class]] ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtUIWindow %p", mWin); + return NULL; + } + CGPoint p0 = [mWin getLocationOnScreen: CGPointMake(src_x, src_y)]; + return (*env)->NewObject(env, pointClz, pointCstr, (jint)p0.x, (jint)p0.y); +} + diff --git a/src/newt/native/MacNewtNSWindow.h b/src/newt/native/MacNewtNSWindow.h new file mode 100644 index 000000000..d55c8b060 --- /dev/null +++ b/src/newt/native/MacNewtNSWindow.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +#import +#import +#import "jni.h" + +#include "NewtCommon.h" + +// #define VERBOSE_ON 1 + +#ifdef VERBOSE_ON + #define DBG_PRINT(...) NSLog(@ __VA_ARGS__) ; fflush(stderr) + // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) +#else + #define DBG_PRINT(...) +#endif + +// #define DBG_LIFECYCLE 1 + +CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen); + +@interface NewtNSView : NSView +{ + jobject javaWindowObject; + + volatile BOOL destroyNotifySent; + volatile int softLockCount; + pthread_mutex_t softLockSync; + + volatile NSTrackingRectTag ptrTrackingTag; + NSRect ptrRect; + NSCursor * myCursor; + BOOL modsDown[4]; // shift, ctrl, alt/option, win/command + + BOOL mouseConfined; + BOOL mouseInside; + BOOL mouseVisible; + BOOL cursorIsHidden; + NSPoint lastInsideMousePosition; +} + +- (id)initWithFrame:(NSRect)frameRect; + +#ifdef DBG_LIFECYCLE +- (void) release; +#endif +- (void) dealloc; + +/* Register or deregister (NULL) the java Window object, + ie, if NULL, no events are send */ +- (void) setJavaWindowObject: (jobject) javaWindowObj; +- (jobject) getJavaWindowObject; + +- (void) setDestroyNotifySent: (BOOL) v; +- (BOOL) getDestroyNotifySent; + +- (BOOL) softLock; +- (BOOL) softUnlock; + +- (BOOL) needsDisplay; +- (void) displayIfNeeded; +- (void) display; +- (void) drawRect:(NSRect)dirtyRect; +- (void) viewDidHide; +- (void) viewDidUnhide; +- (BOOL) acceptsFirstResponder; +- (BOOL) becomeFirstResponder; +- (BOOL) resignFirstResponder; + +- (void) removeCursorRects; +- (void) addCursorRects; +- (void) removeMyCursor; +- (void) resetCursorRects; +- (void) setPointerIcon: (NSCursor*)c; +- (void) mouseEntered: (NSEvent*) theEvent; +- (void) mouseExited: (NSEvent*) theEvent; +- (BOOL) updateMouseInside; +- (void) cursorHide:(BOOL)v enter:(int)enterState; +- (void) setPointerIcon:(NSCursor*)c; +- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus; +- (BOOL) isMouseVisible; +- (void) setMouseConfined:(BOOL)v; +- (void) setMousePosition:(NSPoint)p; +- (void) mouseMoved: (NSEvent*) theEvent; +- (void) scrollWheel: (NSEvent*) theEvent; +- (void) mouseDown: (NSEvent*) theEvent; +- (void) mouseDragged: (NSEvent*) theEvent; +- (void) mouseUp: (NSEvent*) theEvent; +- (void) rightMouseDown: (NSEvent*) theEvent; +- (void) rightMouseDragged: (NSEvent*) theEvent; +- (void) rightMouseUp: (NSEvent*) theEvent; +- (void) otherMouseDown: (NSEvent*) theEvent; +- (void) otherMouseDragged: (NSEvent*) theEvent; +- (void) otherMouseUp: (NSEvent*) theEvent; +- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType; +- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p; + +- (void) handleFlagsChanged:(NSUInteger) mods; +- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods; +- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType; +- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType; +- (void) viewDidChangeBackingProperties; + +@end + +#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +@interface NewtNSWindow : NSWindow +#else +@interface NewtNSWindow : NSWindow +#endif +{ + BOOL realized; + jboolean withinLiveResize; +@public + BOOL hasPresentationSwitch; + NSUInteger defaultPresentationOptions; + NSUInteger fullscreenPresentationOptions; + BOOL isFullscreenWindow; + int cachedInsets[4]; // l, r, t, b +} + ++ (BOOL) initNatives: (JNIEnv*) env forClass: (jobject) clazz; + +- (id) initWithContentRect: (NSRect) contentRect + styleMask: (NSUInteger) windowStyle + backing: (NSBackingStoreType) bufferingType + defer: (BOOL) deferCreation + isFullscreenWindow:(BOOL)isfs; +#ifdef DBG_LIFECYCLE +- (void) release; +#endif +- (void) dealloc; +- (void) setRealized: (BOOL)v; +- (BOOL) isRealized; + +- (void) setAlwaysOn: (BOOL)top bottom:(BOOL)bottom; + +- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin; +- (void) updateSizePosInsets: (JNIEnv*) env jwin: (jobject) javaWin defer: (jboolean)defer; +- (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; + +- (void) focusChanged: (BOOL) gained; + +- (void) keyDown: (NSEvent*) theEvent; +- (void) keyUp: (NSEvent*) theEvent; +- (void) flagsChanged: (NSEvent *) theEvent; +- (BOOL) acceptsMouseMovedEvents; +- (BOOL) acceptsFirstResponder; +- (BOOL) becomeFirstResponder; +- (BOOL) resignFirstResponder; +- (BOOL) canBecomeKeyWindow; +- (void) becomeKeyWindow; +- (void) resignKeyWindow; +- (void) windowDidBecomeKey: (NSNotification *) notification; +- (void) windowDidResignKey: (NSNotification *) notification; + +- (void) windowWillStartLiveResize: (NSNotification *) notification; +- (void) windowDidEndLiveResize: (NSNotification *) notification; +- (NSSize) windowWillResize: (NSWindow *)sender toSize:(NSSize)frameSize; +- (void) windowDidResize: (NSNotification*) notification; +- (void) sendResizeEvent; + +- (void) windowDidMove: (NSNotification*) notification; +- (BOOL) windowClosingImpl: (BOOL) force; +- (BOOL) windowShouldClose: (id) sender; +- (void) windowWillClose: (NSNotification*) notification; + +@end diff --git a/src/newt/native/MacNewtNSWindow.m b/src/newt/native/MacNewtNSWindow.m new file mode 100644 index 000000000..9c116f995 --- /dev/null +++ b/src/newt/native/MacNewtNSWindow.m @@ -0,0 +1,1356 @@ +/* + * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +#import "MacNewtNSWindow.h" +#import "InputEvent.h" +#import "KeyEvent.h" +#import "MouseEvent.h" + +#include +#include /* For kVK_ constants, and TIS functions. */ + +#include + +#define PRINTF(...) NSLog(@ __VA_ARGS__) + +static jfloat GetDelta(NSEvent *event, jint javaMods[]) { + CGEventRef cgEvent = [event CGEvent]; + CGFloat deltaY = 0.0; + CGFloat deltaX = 0.0; + CGFloat delta = 0.0; + + if (CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventIsContinuous)) { + // mouse pad case + deltaX = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2); + deltaY = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1); + // fprintf(stderr, "WHEEL/PAD: %lf/%lf - 0x%X\n", (double)deltaX, (double)deltaY, javaMods[0]); + if( fabs(deltaX) > fabs(deltaY) ) { + javaMods[0] |= EVENT_SHIFT_MASK; + delta = deltaX; + } else { + delta = deltaY; + } + } else { + // traditional mouse wheel case + deltaX = [event deltaX]; + deltaY = [event deltaY]; + // fprintf(stderr, "WHEEL/TRACK: %lf/%lf - 0x%X\n", (double)deltaX, (double)deltaY, javaMods[0]); + if (deltaY == 0.0 && (javaMods[0] & EVENT_SHIFT_MASK) != 0) { + // shift+vertical wheel scroll produces horizontal scroll + // we convert it to vertical + delta = deltaX; + } else { + delta = deltaY; + } + if (-1.0 < delta && delta < 1.0) { + delta *= 10.0; + } else { + if (delta < 0.0) { + delta = delta - 0.5f; + } else { + delta = delta + 0.5f; + } + } + } + // fprintf(stderr, "WHEEL/RES: %lf - 0x%X\n", (double)delta, javaMods[0]); + return (jfloat) delta; +} + +#define kVK_Shift 0x38 +#define kVK_Option 0x3A +#define kVK_Control 0x3B +#define kVK_Command 0x37 + +static jint mods2JavaMods(NSUInteger mods) +{ + int javaMods = 0; + if (mods & NSShiftKeyMask) { + javaMods |= EVENT_SHIFT_MASK; + } + if (mods & NSControlKeyMask) { + javaMods |= EVENT_CTRL_MASK; + } + if (mods & NSCommandKeyMask) { + javaMods |= EVENT_META_MASK; + } + if (mods & NSAlternateKeyMask) { + javaMods |= EVENT_ALT_MASK; + } + return javaMods; +} + +static CFStringRef CKCH_CreateStringForKey(CGKeyCode keyCode, const UCKeyboardLayout *keyboardLayout) { + UInt32 keysDown = 0; + UniChar chars[4]; + UniCharCount realLength; + + UCKeyTranslate(keyboardLayout, keyCode, + kUCKeyActionDisplay, 0, + LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, + &keysDown, sizeof(chars) / sizeof(chars[0]), &realLength, chars); + + return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1); +} + +static CFMutableDictionaryRef CKCH_CreateCodeToCharDict(TISInputSourceRef keyboard) { + CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData); + if( NULL == layoutData ) { + return NULL; + } + const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); + + CFMutableDictionaryRef codeToCharDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 128, NULL, NULL); + if ( NULL != codeToCharDict ) { + intptr_t i; + for (i = 0; i < 128; ++i) { + CFStringRef string = CKCH_CreateStringForKey((CGKeyCode)i, keyboardLayout); + if( NULL != string ) { + CFIndex stringLen = CFStringGetLength (string); + if ( 0 < stringLen ) { + UniChar character = CFStringGetCharacterAtIndex(string, 0); + DBG_PRINT("CKCH: MAP 0x%X -> %c\n", (int)i, character); + CFDictionaryAddValue(codeToCharDict, (const void *)i, (const void *)(intptr_t)character); + } + CFRelease(string); + } + } + } + return codeToCharDict; +} + +static CFMutableDictionaryRef CKCH_USCodeToNNChar = NULL; + +static void CKCH_CreateDictionaries() { + TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); + if( NULL != currentKeyboard ) { + CKCH_USCodeToNNChar = CKCH_CreateCodeToCharDict(currentKeyboard); + CFRelease(currentKeyboard); + } +} + +static UniChar CKCH_CharForKeyCode(jshort keyCode) { + UniChar rChar = 0; + + if ( NULL != CKCH_USCodeToNNChar ) { + intptr_t code = (intptr_t) keyCode; + intptr_t character = 0; + + if ( CFDictionaryGetValueIfPresent(CKCH_USCodeToNNChar, (void *)code, (const void **)&character) ) { + rChar = (UniChar) character; + DBG_PRINT("CKCH: OK 0x%X -> 0x%X\n", (int)keyCode, (int)rChar); + } + } + return rChar; +} + +static jmethodID enqueueMouseEventID = NULL; +static jmethodID enqueueKeyEventID = NULL; +static jmethodID requestFocusID = NULL; + +static jmethodID insetsChangedID = NULL; +static jmethodID sizeChangedID = NULL; +static jmethodID sizeScreenPosInsetsChangedID = NULL; +static jmethodID updatePixelScaleID = NULL; +static jmethodID visibleChangedID = NULL; +static jmethodID screenPositionChangedID = NULL; +static jmethodID focusChangedID = NULL; +static jmethodID windowDestroyNotifyID = NULL; +static jmethodID windowRepaintID = NULL; + +// Need to enqueue all events to EDT, +// since we may operate on AWT-AppKit (Main Thread) +// and direct issuing 'requestFocus()' would deadlock: +// AWT-AppKit +// AWT-EventQueue-0 + +@implementation NewtNSView + +- (id)initWithFrame:(NSRect)frameRect +{ + id res = [super initWithFrame:frameRect]; + javaWindowObject = NULL; + + destroyNotifySent = NO; + softLockCount = 0; + + pthread_mutexattr_t softLockSyncAttr; + pthread_mutexattr_init(&softLockSyncAttr); + pthread_mutexattr_settype(&softLockSyncAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&softLockSync, &softLockSyncAttr); // recursive + + ptrTrackingTag = 0; + myCursor = NULL; + + modsDown[0] = NO; // shift + modsDown[1] = NO; // ctrl + modsDown[2] = NO; // alt + modsDown[3] = NO; // win + mouseConfined = NO; + mouseVisible = YES; + mouseInside = NO; + cursorIsHidden = NO; + + DBG_PRINT("NewtNSView::create: %p (refcnt %d)\n", res, (int)[res retainCount]); + return res; +} + +#ifdef DBG_LIFECYCLE +- (void) release +{ + DBG_PRINT("NewtNSView::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]); + [super release]; +} +#endif + +- (void) dealloc +{ + DBG_PRINT("NewtNSView::dealloc.0: %p (refcnt %d), ptrTrackingTag %d\n", self, (int)[self retainCount], (int)ptrTrackingTag); +#ifdef DBG_LIFECYCLE + NSLog(@"%@",[NSThread callStackSymbols]); +#endif + if( 0 < softLockCount ) { + NSLog(@"NewtNSView::dealloc: softLock still hold @ dealloc!\n"); + } + [self removeCursorRects]; + [self removeMyCursor]; + + pthread_mutex_destroy(&softLockSync); + DBG_PRINT("NewtNSView::dealloc.X: %p\n", self); + [super dealloc]; +} + +- (void) setJavaWindowObject: (jobject) javaWindowObj +{ + javaWindowObject = javaWindowObj; +} + +- (jobject) getJavaWindowObject +{ + return javaWindowObject; +} + +- (void) setDestroyNotifySent: (BOOL) v +{ + destroyNotifySent = v; +} + +- (BOOL) getDestroyNotifySent +{ + return destroyNotifySent; +} + +- (BOOL) softLock +{ + // DBG_PRINT("*************** softLock.0: %p\n", (void*)pthread_self()); + int err; + if( 0 != ( err = pthread_mutex_lock(&softLockSync) ) ) { + NSLog(@"NewtNSView::softLock failed: errCode %d - %@", err, [NSThread callStackSymbols]); + return NO; + } + softLockCount++; + // DBG_PRINT("*************** softLock.X: %p\n", (void*)pthread_self()); + return 0 < softLockCount; +} + +- (BOOL) softUnlock +{ + // DBG_PRINT("*************** softUnlock: %p\n", (void*)pthread_self()); + softLockCount--; + int err; + if( 0 != ( err = pthread_mutex_unlock(&softLockSync) ) ) { + softLockCount++; + NSLog(@"NewtNSView::softUnlock failed: Not locked by current thread - errCode %d - %@", err, [NSThread callStackSymbols]); + return NO; + } + return YES; +} + +- (BOOL) needsDisplay +{ + return NO == destroyNotifySent && [super needsDisplay]; +} + +- (void) displayIfNeeded +{ + if( YES == [self needsDisplay] ) { + [self softLock]; + [super displayIfNeeded]; + [self softUnlock]; + } +} + +- (void) display +{ + if( NO == destroyNotifySent ) { + [self softLock]; + [super display]; + [self softUnlock]; + } +} + +- (void) drawRect:(NSRect)dirtyRect +{ + DBG_PRINT("*************** dirtyRect: %p %lf/%lf %lfx%lf\n", + javaWindowObject, dirtyRect.origin.x, dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height); + + if(NULL==javaWindowObject) { + DBG_PRINT("drawRect: null javaWindowObject\n"); + return; + } + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + if(NULL==env) { + DBG_PRINT("drawRect: null JNIEnv\n"); + return; + } + + NSRect viewFrame = [self frame]; + + (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_TRUE, // defer .. + (int)dirtyRect.origin.x, (int)viewFrame.size.height - (int)dirtyRect.origin.y, + (int)dirtyRect.size.width, (int)dirtyRect.size.height); + + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); +} + +- (void) viewDidHide +{ + if(NULL==javaWindowObject) { + DBG_PRINT("viewDidHide: null javaWindowObject\n"); + return; + } + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + if(NULL==env) { + DBG_PRINT("viewDidHide: null JNIEnv\n"); + return; + } + + (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_FALSE); + + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); + + [super viewDidHide]; +} + +- (void) viewDidUnhide +{ + if(NULL==javaWindowObject) { + DBG_PRINT("viewDidUnhide: null javaWindowObject\n"); + return; + } + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + if(NULL==env) { + DBG_PRINT("viewDidUnhide: null JNIEnv\n"); + return; + } + + (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_TRUE); + + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); + + [super viewDidUnhide]; +} + +- (BOOL) acceptsFirstResponder +{ + return YES; +} + +- (BOOL) becomeFirstResponder +{ + DBG_PRINT( "*************** View.becomeFirstResponder\n"); + return [super becomeFirstResponder]; +} + +- (BOOL) resignFirstResponder +{ + DBG_PRINT( "*************** View.resignFirstResponder\n"); + return [super resignFirstResponder]; +} + +- (void) removeCursorRects +{ + if(0 != ptrTrackingTag) { + if(NULL != myCursor) { + [self removeCursorRect: ptrRect cursor: myCursor]; + } + [self removeTrackingRect: ptrTrackingTag]; + ptrTrackingTag = 0; + } +} + +- (void) addCursorRects +{ + ptrRect = [self bounds]; + if(NULL != myCursor) { + [self addCursorRect: ptrRect cursor: myCursor]; + } + ptrTrackingTag = [self addTrackingRect: ptrRect owner: self userData: nil assumeInside: NO]; +} + +- (void) removeMyCursor +{ + if(NULL != myCursor) { + [myCursor release]; + myCursor = NULL; + } +} + +- (void) resetCursorRects +{ + [super resetCursorRects]; + + [self removeCursorRects]; + [self addCursorRects]; +} + +- (void) setPointerIcon: (NSCursor*)c +{ + DBG_PRINT( "setPointerIcon: %p -> %p, top %p, mouseInside %d\n", myCursor, c, [NSCursor currentCursor], (int)mouseInside); + if( c != myCursor ) { + [self removeCursorRects]; + [self removeMyCursor]; + myCursor = c; + if( NULL != myCursor ) { + [myCursor retain]; + } + } + NSWindow* nsWin = [self window]; + if( NULL != nsWin ) { + [nsWin invalidateCursorRectsForView: self]; + } +} + +- (void) mouseEntered: (NSEvent*) theEvent +{ + DBG_PRINT( "mouseEntered: confined %d, visible %d, PointerIcon %p, top %p\n", mouseConfined, mouseVisible, myCursor, [NSCursor currentCursor]); + mouseInside = YES; + [self cursorHide: !mouseVisible enter: 1]; + if(NO == mouseConfined) { + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED]; + } + NSWindow* nsWin = [self window]; + if( NULL != nsWin ) { + [nsWin makeFirstResponder: self]; + } +} + +- (void) mouseExited: (NSEvent*) theEvent +{ + DBG_PRINT( "mouseExited: confined %d, visible %d, PointerIcon %p, top %p\n", mouseConfined, mouseVisible, myCursor, [NSCursor currentCursor]); + if(NO == mouseConfined) { + mouseInside = NO; + [self cursorHide: NO enter: -1]; + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED]; + [self resignFirstResponder]; + } else { + [self setMousePosition: lastInsideMousePosition]; + } +} + +/** + * p abs screen position w/ bottom-left origin + */ +- (void) setMousePosition:(NSPoint)p +{ + NSWindow* nsWin = [self window]; + if( NULL != nsWin ) { + NSScreen* screen = [nsWin screen]; + + CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); + CGRect frameTL = CGDisplayBounds (display); // origin top-left + NSRect frameBL = [screen frame]; // origin bottom-left + CGPoint pt = { p.x, frameTL.origin.y + frameTL.size.height - ( p.y - frameBL.origin.y ) }; // y-flip from BL-screen -> TL-screen + + DBG_PRINT( "setMousePosition: point-in[%d/%d], screen tl[%d/%d %dx%d] bl[%d/%d %dx%d] -> %d/%d\n", + (int)p.x, (int)p.y, + (int)frameTL.origin.x, (int)frameTL.origin.y, (int)frameTL.size.width, (int)frameTL.size.height, + (int)frameBL.origin.x, (int)frameBL.origin.y, (int)frameBL.size.width, (int)frameBL.size.height, + (int)pt.x, (int)pt.y); + + CGEventRef ev = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, pt, kCGMouseButtonLeft); + CGEventPost (kCGHIDEventTap, ev); + } +} + +- (BOOL) updateMouseInside +{ + NSRect viewFrame = [self frame]; + NSPoint l1 = [NSEvent mouseLocation]; + NSPoint l0 = [self screenPos2NewtClientWinPos: l1]; + mouseInside = viewFrame.origin.x <= l0.x && l0.x < (viewFrame.origin.x+viewFrame.size.width) && + viewFrame.origin.y <= l0.y && l0.y < (viewFrame.origin.y+viewFrame.size.height) ; + return mouseInside; +} + +- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus +{ + mouseVisible = v; + [self updateMouseInside]; + DBG_PRINT( "setMouseVisible: confined %d, visible %d (current: %d), mouseInside %d, hasFocus %d\n", + mouseConfined, mouseVisible, !cursorIsHidden, mouseInside, focus); + if(YES == focus && YES == mouseInside) { + [self cursorHide: !mouseVisible enter: 0]; + } +} +- (BOOL) isMouseVisible +{ + return mouseVisible; +} + +- (void) cursorHide:(BOOL)v enter:(int)enterState +{ + DBG_PRINT( "cursorHide: %d -> %d, enter %d; PointerIcon: %p, top %p\n", + cursorIsHidden, v, enterState, myCursor, [NSCursor currentCursor]); + if(v) { + if(!cursorIsHidden) { + [NSCursor hide]; + cursorIsHidden = YES; + } + } else { + if(cursorIsHidden) { + [NSCursor unhide]; + cursorIsHidden = NO; + } + } +} + +- (void) setMouseConfined:(BOOL)v +{ + mouseConfined = v; + DBG_PRINT( "setMouseConfined: confined %d, visible %d\n", mouseConfined, mouseVisible); +} + +- (void) mouseMoved: (NSEvent*) theEvent +{ + if( mouseInside ) { + NSCursor * currentCursor = [NSCursor currentCursor]; + BOOL setCursor = NULL != myCursor && NO == cursorIsHidden && currentCursor != myCursor; + DBG_PRINT( "mouseMoved.set: %d; mouseInside %d, CursorHidden %d, PointerIcon: %p, top %p\n", + setCursor, mouseInside, cursorIsHidden, myCursor, currentCursor); + if( setCursor ) { + // FIXME: Workaround missing NSCursor update for 'fast moving' pointer + [myCursor set]; + } + lastInsideMousePosition = [NSEvent mouseLocation]; + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; + } +} + +- (void) scrollWheel: (NSEvent*) theEvent +{ + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_WHEEL_MOVED]; +} + +- (void) mouseDown: (NSEvent*) theEvent +{ + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; +} + +- (void) mouseDragged: (NSEvent*) theEvent +{ + lastInsideMousePosition = [NSEvent mouseLocation]; + // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; +} + +- (void) mouseUp: (NSEvent*) theEvent +{ + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; +} + +- (void) rightMouseDown: (NSEvent*) theEvent +{ + NSResponder* next = [self nextResponder]; + if (next != nil) { + [next rightMouseDown: theEvent]; + } + // FIXME: ^^ OR [super rightMouseDown: theEvent] ? + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; +} + +- (void) rightMouseDragged: (NSEvent*) theEvent +{ + lastInsideMousePosition = [NSEvent mouseLocation]; + // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; +} + +- (void) rightMouseUp: (NSEvent*) theEvent +{ + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; +} + +- (void) otherMouseDown: (NSEvent*) theEvent +{ + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; +} + +- (void) otherMouseDragged: (NSEvent*) theEvent +{ + lastInsideMousePosition = [NSEvent mouseLocation]; + // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; +} + +- (void) otherMouseUp: (NSEvent*) theEvent +{ + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; +} + +- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType +{ + if (javaWindowObject == NULL) { + DBG_PRINT("sendMouseEvent: null javaWindowObject\n"); + return; + } + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + if(NULL==env) { + DBG_PRINT("sendMouseEvent: null JNIEnv\n"); + return; + } + jint javaMods[] = { 0 } ; + javaMods[0] = mods2JavaMods([event modifierFlags]); + + // convert to 1-based button number (or use zero if no button is involved) + // TODO: detect mouse button when mouse wheel scrolled + jshort javaButtonNum; + jfloat scrollDeltaY = 0.0f; + switch ([event type]) { + case NSScrollWheel: + scrollDeltaY = GetDelta(event, javaMods); + javaButtonNum = 1; + break; + case NSLeftMouseDown: + case NSLeftMouseUp: + case NSLeftMouseDragged: + javaButtonNum = 1; + break; + case NSRightMouseDown: + case NSRightMouseUp: + case NSRightMouseDragged: + javaButtonNum = 3; + break; + case NSOtherMouseDown: + case NSOtherMouseUp: + case NSOtherMouseDragged: + javaButtonNum = 2; + break; + default: + javaButtonNum = 0; + break; + } + if (evType == EVENT_MOUSE_WHEEL_MOVED && scrollDeltaY == 0) { + // ignore 0 increment wheel scroll events + return; + } + if (evType == EVENT_MOUSE_PRESSED) { + (*env)->CallVoidMethod(env, javaWindowObject, requestFocusID, JNI_FALSE); + } + + NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]]; + + (*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, JNI_FALSE, + evType, javaMods[0], + (jint) location.x, (jint) location.y, + javaButtonNum, scrollDeltaY); + + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); +} + +- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p +{ + NSRect viewFrame = [self frame]; + + NSRect r; + r.origin.x = p.x; + r.origin.y = p.y; + r.size.width = 0; + r.size.height = 0; + // NSRect rS = [[self window] convertRectFromScreen: r]; // 10.7 + NSPoint oS = [[self window] convertScreenToBase: r.origin]; + oS.y = viewFrame.size.height - oS.y; // y-flip + return oS; +} + +- (void) handleFlagsChanged:(NSUInteger) mods +{ + [self handleFlagsChanged: NSShiftKeyMask keyIndex: 0 keyCode: kVK_Shift modifiers: mods]; + [self handleFlagsChanged: NSControlKeyMask keyIndex: 1 keyCode: kVK_Control modifiers: mods]; + [self handleFlagsChanged: NSAlternateKeyMask keyIndex: 2 keyCode: kVK_Option modifiers: mods]; + [self handleFlagsChanged: NSCommandKeyMask keyIndex: 3 keyCode: kVK_Command modifiers: mods]; +} + +- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods +{ + if ( NO == modsDown[keyIdx] && 0 != ( mods & keyMask ) ) { + modsDown[keyIdx] = YES; + [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_PRESSED]; + } else if ( YES == modsDown[keyIdx] && 0 == ( mods & keyMask ) ) { + modsDown[keyIdx] = NO; + [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_RELEASED]; + } +} + +- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType +{ + jshort keyCode = (jshort) [event keyCode]; + NSString* chars = [event charactersIgnoringModifiers]; + NSUInteger mods = [event modifierFlags]; + [self sendKeyEvent: keyCode characters: chars modifiers: mods eventType: evType]; +} + +- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType +{ + if (javaWindowObject == NULL) { + DBG_PRINT("sendKeyEvent: null javaWindowObject\n"); + return; + } + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + if(NULL==env) { + DBG_PRINT("sendKeyEvent: null JNIEnv\n"); + return; + } + + int i; + int len = NULL != chars ? [chars length] : 0; + jint javaMods = mods2JavaMods(mods); + + if(len > 0) { + // printable chars + for (i = 0; i < len; i++) { + // Note: the key code in the NSEvent does not map to anything we can use + UniChar keyChar = (UniChar) [chars characterAtIndex: i]; + UniChar keySymChar = CKCH_CharForKeyCode(keyCode); + + DBG_PRINT("sendKeyEvent: %d/%d code 0x%X, char 0x%X, mods 0x%X/0x%X -> keySymChar 0x%X\n", i, len, (int)keyCode, (int)keyChar, + (int)mods, (int)javaMods, (int)keySymChar); + + (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE, + evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar); + } + } else { + // non-printable chars + jchar keyChar = (jchar) 0; + + DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode); + + (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE, + evType, javaMods, keyCode, keyChar, keyChar); + } + + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); +} + +- (void)viewDidChangeBackingProperties +{ + [super viewDidChangeBackingProperties]; + + // HiDPI scaling + BOOL useHiDPI = false; + CGFloat maxPixelScale = 1.0; + CGFloat winPixelScale = 1.0; + NSWindow* window = [self window]; + NSScreen* screen = [window screen]; +NS_DURING + maxPixelScale = [screen backingScaleFactor]; + useHiDPI = [self wantsBestResolutionOpenGLSurface]; + if( useHiDPI ) { + winPixelScale = [window backingScaleFactor]; + } +NS_HANDLER +NS_ENDHANDLER + DBG_PRINT("viewDidChangeBackingProperties: PixelScale: HiDPI %d, max %f, window %f\n", useHiDPI, (float)maxPixelScale, (float)winPixelScale); + [[self layer] setContentsScale: winPixelScale]; + + if (javaWindowObject == NULL) { + DBG_PRINT("viewDidChangeBackingProperties: null javaWindowObject\n"); + return; + } + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + if(NULL==env) { + DBG_PRINT("viewDidChangeBackingProperties: null JNIEnv\n"); + return; + } + + (*env)->CallVoidMethod(env, javaWindowObject, updatePixelScaleID, JNI_TRUE, (jfloat)winPixelScale, (jfloat)maxPixelScale); // defer + + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); +} + + +@end + +@implementation NewtNSWindow + ++ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz +{ + enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)V"); + enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)V"); + sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V"); + updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZFF)V"); + visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V"); + insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V"); + sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZZ)V"); + screenPositionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V"); + focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V"); + windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z"); + windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V"); + requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V"); + if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && updatePixelScaleID && visibleChangedID && + insetsChangedID && sizeScreenPosInsetsChangedID && + screenPositionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID) + { + CKCH_CreateDictionaries(); + return YES; + } + return NO; +} + +- (id) initWithContentRect: (NSRect) contentRect + styleMask: (NSUInteger) windowStyle + backing: (NSBackingStoreType) bufferingType + defer: (BOOL) deferCreation + isFullscreenWindow:(BOOL)isfs +{ + id res = [super initWithContentRect: contentRect + styleMask: windowStyle + backing: bufferingType + defer: deferCreation]; + // OSX 10.6 + if ( [NSApp respondsToSelector:@selector(currentSystemPresentationOptions)] && + [NSApp respondsToSelector:@selector(setPresentationOptions:)] ) { + hasPresentationSwitch = YES; + defaultPresentationOptions = [NSApp currentSystemPresentationOptions]; + fullscreenPresentationOptions = + // NSApplicationPresentationDefault| + // NSApplicationPresentationAutoHideDock| + NSApplicationPresentationHideDock| + // NSApplicationPresentationAutoHideMenuBar| + NSApplicationPresentationHideMenuBar| + NSApplicationPresentationDisableAppleMenu| + // NSApplicationPresentationDisableProcessSwitching| + // NSApplicationPresentationDisableSessionTermination| + NSApplicationPresentationDisableHideApplication| + // NSApplicationPresentationDisableMenuBarTransparency| + // NSApplicationPresentationFullScreen| // OSX 10.7 + 0 ; + } else { + hasPresentationSwitch = NO; + defaultPresentationOptions = 0; + fullscreenPresentationOptions = 0; + } + + isFullscreenWindow = isfs; + // Why is this necessary? Without it we don't get any of the + // delegate methods like resizing and window movement. + [self setDelegate: self]; + + cachedInsets[0] = 0; // l + cachedInsets[1] = 0; // r + cachedInsets[2] = 0; // t + cachedInsets[3] = 0; // b + + realized = YES; + withinLiveResize = JNI_FALSE; + DBG_PRINT("NewtWindow::create: %p, realized %d, hasPresentationSwitch %d[defaultOptions 0x%X, fullscreenOptions 0x%X], (refcnt %d)\n", + res, realized, (int)hasPresentationSwitch, (int)defaultPresentationOptions, (int)fullscreenPresentationOptions, (int)[res retainCount]); + return res; +} + +#ifdef DBG_LIFECYCLE +- (void) release +{ + DBG_PRINT("NewtWindow::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]); + // NSLog(@"%@",[NSThread callStackSymbols]); + [super release]; +} +#endif + +- (void) dealloc +{ + DBG_PRINT("NewtWindow::dealloc.0: %p (refcnt %d)\n", self, (int)[self retainCount]); +#ifdef DBG_LIFECYCLE + NSLog(@"%@",[NSThread callStackSymbols]); +#endif + + NewtNSView* mView = (NewtNSView *)[self contentView]; + if( NULL != mView ) { + [mView release]; + } + [super dealloc]; + DBG_PRINT("NewtWindow::dealloc.X: %p\n", self); +} + +- (void) setRealized: (BOOL)v +{ + realized = v; +} + +- (BOOL) isRealized +{ + return realized; +} + +- (void) setAlwaysOn: (BOOL)top bottom:(BOOL)bottom +{ + if( top ) { + DBG_PRINT( "*************** setAlwaysOn -> top\n"); + [self setLevel: kCGMaximumWindowLevel]; + } else if ( bottom ) { + DBG_PRINT( "*************** setAlwaysOn -> bottom\n"); + [self setLevel: kCGDesktopIconWindowLevel]; // w/ input + } else { + DBG_PRINT( "*************** setAlwaysOn -> normal\n"); + [self setLevel:NSNormalWindowLevel]; + } +} + +- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin +{ + NSRect frameRect = [self frame]; + NSRect contentRect = [self contentRectForFrameRect: frameRect]; + + // note: this is a simplistic implementation which doesn't take + // into account DPI and scaling factor + CGFloat l = contentRect.origin.x - frameRect.origin.x; + cachedInsets[0] = (int)l; // l + cachedInsets[1] = (int)(frameRect.size.width - (contentRect.size.width + l)); // r + cachedInsets[2] = (jint)(frameRect.size.height - contentRect.size.height); // t + cachedInsets[3] = (jint)(contentRect.origin.y - frameRect.origin.y); // b + + DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", 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) updateSizePosInsets: (JNIEnv*) env jwin: (jobject) javaWin defer: (jboolean)defer +{ + // update insets on every window resize for lack of better hook place + [self updateInsets: NULL jwin:NULL]; + + NSRect frameRect = [self frame]; + NSRect contentRect = [self contentRectForFrameRect: frameRect]; + + DBG_PRINT( "updateSize: [ w %d, h %d ], liveResize %d\n", (jint) contentRect.size.width, (jint) contentRect.size.height, (jint)withinLiveResize); + + NSPoint p0 = { 0, 0 }; + p0 = [self getLocationOnScreen: p0]; + + DBG_PRINT( "updatePos: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y); + + if( NULL != env && NULL != javaWin ) { + (*env)->CallVoidMethod(env, javaWin, sizeScreenPosInsetsChangedID, defer, + (jint) p0.x, (jint) p0.y, + (jint) contentRect.size.width, (jint) contentRect.size.height, + cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3], + JNI_FALSE, // force + withinLiveResize + ); + } +} + + +- (void) attachToParent: (NSWindow*) parent +{ + DBG_PRINT( "attachToParent.1\n"); + [parent addChildWindow: self ordered: NSWindowAbove]; + DBG_PRINT( "attachToParent.2\n"); + [self setParentWindow: parent]; + DBG_PRINT( "attachToParent.X\n"); +} + +- (void) detachFromParent: (NSWindow*) parent +{ + DBG_PRINT( "detachFromParent.1\n"); + [self setParentWindow: nil]; + if(NULL != parent) { + DBG_PRINT( "detachFromParent.2\n"); + [parent removeChildWindow: self]; + } + DBG_PRINT( "detachFromParent.X\n"); +} + +/** + * p abs screen position of client-area pos w/ top-left origin, using contentView's client NSSize + * returns: abs screen position w/ bottom-left origin + */ +- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p +{ + NSView* mView = [self contentView]; + NSRect mViewFrame = [mView frame]; + return [self newtAbsClientTLWinPos2AbsBLScreenPos: p size: mViewFrame.size]; +} + +/** + * p abs screen position of client-area pos w/ top-left origin, using given client NSSize + * returns: abs screen position w/ bottom-left origin + */ +- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p size: (NSSize) nsz +{ + int totalHeight = nsz.height + cachedInsets[3]; // height + insets.bottom + + DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: point-in[%d/%d], size-in[%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]; + + CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); + CGRect frameTL = CGDisplayBounds (display); // origin top-left + NSRect frameBL = [screen frame]; // origin bottom-left + NSPoint r = NSMakePoint(p.x, frameBL.origin.y + frameBL.size.height - ( p.y - frameTL.origin.y ) - totalHeight); // y-flip from TL-screen -> BL-screen + + DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: screen tl[%d/%d %dx%d] bl[%d/%d %dx%d -> %d/%d\n", + (int)frameTL.origin.x, (int)frameTL.origin.y, (int)frameTL.size.width, (int)frameTL.size.height, + (int)frameBL.origin.x, (int)frameBL.origin.y, (int)frameBL.size.width, (int)frameBL.size.height, + (int)r.x, (int)r.y); + + return r; +} + +/** + * p rel client window position w/ top-left origin + * returns: abs screen position w/ bottom-left origin + */ +- (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p +{ + NSRect winFrame = [self frame]; + + NSView* mView = [self contentView]; + NSRect mViewFrame = [mView frame]; + NSPoint r = NSMakePoint(winFrame.origin.x + p.x, + winFrame.origin.y + ( mViewFrame.size.height - p.y ) ); // y-flip in view + + DBG_PRINT( "newtRelClientTLWinPos2AbsBLScreenPos: point-in[%d/%d], winFrame[%d/%d %dx%d], viewFrame[%d/%d %dx%d] -> %d/%d\n", + (int)p.x, (int)p.y, + (int)winFrame.origin.x, (int)winFrame.origin.y, (int)winFrame.size.width, (int)winFrame.size.height, + (int)mViewFrame.origin.x, (int)mViewFrame.origin.y, (int)mViewFrame.size.width, (int)mViewFrame.size.height, + (int)r.x, (int)r.y); + + return r; +} + +- (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 + * returns: location in 0/0 top-left space. + */ +- (NSPoint) getLocationOnScreen: (NSPoint) p +{ + NSView* view = [self contentView]; + NSRect viewFrame = [view frame]; + NSRect r; + r.origin.x = p.x; + r.origin.y = viewFrame.size.height - p.y; // y-flip + r.size.width = 0; + r.size.height = 0; + // NSRect rS = [self convertRectToScreen: r]; // 10.7 + NSPoint oS = [self convertBaseToScreen: r.origin]; // BL-screen + + NSScreen* screen = [self screen]; + CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); + CGRect frameTL = CGDisplayBounds (display); // origin top-left + NSRect frameBL = [screen frame]; // origin bottom-left + oS.y = frameTL.origin.y + frameTL.size.height - ( oS.y - frameBL.origin.y ); // y-flip from BL-screen -> TL-screen + +#ifdef VERBOSE_ON + NSRect winFrame = [self frame]; + DBG_PRINT( "getLocationOnScreen: point-in[%d/%d], winFrame[%d/%d %dx%d], viewFrame[%d/%d %dx%d], screen tl[%d/%d %dx%d] bl[%d/%d %dx%d] -> %d/%d\n", + (int)p.x, (int)p.y, + (int)winFrame.origin.x, (int)winFrame.origin.y, (int)winFrame.size.width, (int)winFrame.size.height, + (int)viewFrame.origin.x, (int)viewFrame.origin.y, (int)viewFrame.size.width, (int)viewFrame.size.height, + (int)frameTL.origin.x, (int)frameTL.origin.y, (int)frameTL.size.width, (int)frameTL.size.height, + (int)frameBL.origin.x, (int)frameBL.origin.y, (int)frameBL.size.width, (int)frameBL.size.height, + (int)oS.x, (int)oS.y); +#endif + + return oS; +} + +- (void) focusChanged: (BOOL) gained +{ + DBG_PRINT( "focusChanged: gained %d\n", gained); + NewtNSView* newtView = (NewtNSView *) [self contentView]; + if( ! [newtView isKindOfClass:[NewtNSView class]] ) { + return; + } + jobject javaWindowObject = [newtView getJavaWindowObject]; + if (javaWindowObject == NULL) { + DBG_PRINT("focusChanged: null javaWindowObject\n"); + return; + } + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + if(NULL==env) { + DBG_PRINT("focusChanged: null JNIEnv\n"); + return; + } + + (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE); + + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); +} + +- (void) keyDown: (NSEvent*) theEvent +{ + NewtNSView* newtView = (NewtNSView *) [self contentView]; + if( [newtView isKindOfClass:[NewtNSView class]] ) { + [newtView sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_PRESSED]; + } +} + +- (void) keyUp: (NSEvent*) theEvent +{ + NewtNSView* newtView = (NewtNSView *) [self contentView]; + if( [newtView isKindOfClass:[NewtNSView class]] ) { + [newtView sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_RELEASED]; + } +} + +- (void) flagsChanged:(NSEvent *) theEvent +{ + NSUInteger mods = [theEvent modifierFlags]; + NewtNSView* newtView = (NewtNSView *) [self contentView]; + if( [newtView isKindOfClass:[NewtNSView class]] ) { + [newtView handleFlagsChanged: mods]; + } +} + +- (BOOL) acceptsMouseMovedEvents +{ + return YES; +} + +- (BOOL) acceptsFirstResponder +{ + return YES; +} + +- (BOOL) becomeFirstResponder +{ + DBG_PRINT( "*************** Win.becomeFirstResponder\n"); + return [super becomeFirstResponder]; +} + +- (BOOL) resignFirstResponder +{ + DBG_PRINT( "*************** Win.resignFirstResponder\n"); + return [super resignFirstResponder]; +} + +- (BOOL) canBecomeKeyWindow +{ + // Even if the window is borderless, we still want it to be able + // to become the key window to receive keyboard events + return YES; +} + +- (void) becomeKeyWindow +{ + DBG_PRINT( "*************** becomeKeyWindow\n"); + [super becomeKeyWindow]; +} + +- (void) resignKeyWindow +{ + DBG_PRINT( "*************** resignKeyWindow: isFullscreen %d\n", (int)isFullscreenWindow); + if(!isFullscreenWindow) { + [super resignKeyWindow]; + } +} + +- (void) windowDidBecomeKey: (NSNotification *) notification +{ + DBG_PRINT( "*************** windowDidBecomeKey\n"); + NewtNSView* newtView = (NewtNSView *) [self contentView]; + if( [newtView isKindOfClass:[NewtNSView class]] ) { + BOOL mouseInside = [newtView updateMouseInside]; + if(YES == mouseInside) { + [newtView cursorHide: ![newtView isMouseVisible] enter: 1]; + } + } + [self focusChanged: YES]; +} + +- (void) windowDidResignKey: (NSNotification *) notification +{ + DBG_PRINT( "*************** windowDidResignKey\n"); + // Implicit mouse exit by OS X + [self focusChanged: NO]; +} + +- (void) windowWillStartLiveResize: (NSNotification *) notification +{ + DBG_PRINT( "*************** windowWillStartLiveResize\n"); + withinLiveResize = JNI_TRUE; +} +- (void) windowDidEndLiveResize: (NSNotification *) notification +{ + DBG_PRINT( "*************** windowDidEndLiveResize\n"); + withinLiveResize = JNI_FALSE; + [self sendResizeEvent]; +} +- (NSSize) windowWillResize: (NSWindow *)sender toSize:(NSSize)frameSize +{ + DBG_PRINT( "*************** windowWillResize %lfx%lf\n", frameSize.width, frameSize.height); + return frameSize; +} +- (void)windowDidResize: (NSNotification*) notification +{ + DBG_PRINT( "*************** windowDidResize\n"); + [self sendResizeEvent]; +} + +- (void) sendResizeEvent +{ + jobject javaWindowObject = NULL; + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + + if( NULL == env ) { + DBG_PRINT("windowDidResize: null JNIEnv\n"); + return; + } + NewtNSView* newtView = (NewtNSView *) [self contentView]; + if( [newtView isKindOfClass:[NewtNSView class]] ) { + javaWindowObject = [newtView getJavaWindowObject]; + } + if( NULL != javaWindowObject ) { + [self updateSizePosInsets: env jwin: javaWindowObject defer:JNI_TRUE]; + } + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); +} + +- (void)windowDidMove: (NSNotification*) notification +{ + NewtNSView* newtView = (NewtNSView *) [self contentView]; + if( ! [newtView isKindOfClass:[NewtNSView class]] ) { + return; + } + jobject javaWindowObject = [newtView getJavaWindowObject]; + if (javaWindowObject == NULL) { + DBG_PRINT("windowDidMove: null javaWindowObject\n"); + return; + } + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + if(NULL==env) { + DBG_PRINT("windowDidMove: null JNIEnv\n"); + return; + } + + NSPoint p0 = { 0, 0 }; + p0 = [self getLocationOnScreen: p0]; + DBG_PRINT( "windowDidMove: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y); + (*env)->CallVoidMethod(env, javaWindowObject, screenPositionChangedID, JNI_TRUE, (jint) p0.x, (jint) p0.y); + + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); +} + +- (BOOL)windowShouldClose: (id) sender +{ + return [self windowClosingImpl: NO]; +} + +- (void)windowWillClose: (NSNotification*) notification +{ + [self windowClosingImpl: YES]; +} + +- (BOOL) windowClosingImpl: (BOOL) force +{ + jboolean closed = JNI_FALSE; + + NewtNSView* newtView = (NewtNSView *) [self contentView]; + if( ! [newtView isKindOfClass:[NewtNSView class]] ) { + return NO; + } + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [newtView cursorHide: NO enter: -1]; + + if( false == [newtView getDestroyNotifySent] ) { + jobject javaWindowObject = [newtView getJavaWindowObject]; + DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject); + if (javaWindowObject == NULL) { + DBG_PRINT("windowWillClose: null javaWindowObject\n"); + [pool release]; + return NO; + } + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + if(NULL==env) { + DBG_PRINT("windowWillClose: null JNIEnv\n"); + [pool release]; + return NO; + } + [newtView setDestroyNotifySent: true]; // earmark assumption of being closed + closed = (*env)->CallBooleanMethod(env, javaWindowObject, windowDestroyNotifyID, force ? JNI_TRUE : JNI_FALSE); + if(!force && !closed) { + // not closed on java side, not force -> clear flag + [newtView setDestroyNotifySent: false]; + } + + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); + DBG_PRINT( "*************** windowWillClose.X: %p, closed %d\n", (void *)(intptr_t)javaWindowObject, (int)closed); + } else { + DBG_PRINT( "*************** windowWillClose (skip)\n"); + } + [pool release]; + return JNI_TRUE == closed ? YES : NO ; +} + +@end + diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index ee012add3..49adf8767 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -34,7 +34,7 @@ #import #import "jogamp_newt_driver_macosx_WindowDriver.h" -#import "NewtMacWindow.h" +#import "MacNewtNSWindow.h" #import "MouseEvent.h" #import "KeyEvent.h" @@ -62,7 +62,7 @@ static NSString* jstringToNSString(JNIEnv* env, jstring jstr) return str; } -static void setWindowClientTopLeftPoint(NewtMacWindow* mWin, jint x, jint y, BOOL doDisplay) { +static void setWindowClientTopLeftPoint(NewtNSWindow* mWin, jint x, jint y, BOOL doDisplay) { DBG_PRINT( "setWindowClientTopLeftPoint.0 - window: %p %d/%d, display %d\n", mWin, (int)x, (int)y, (int)doDisplay); NSPoint pS = [mWin newtAbsClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]; DBG_PRINT( "setWindowClientTopLeftPoint.1: %d/%d\n", (int)pS.x, (int)pS.y); @@ -76,7 +76,7 @@ static void setWindowClientTopLeftPoint(NewtMacWindow* mWin, jint x, jint y, BOO } } -static void setWindowClientTopLeftPointAndSize(NewtMacWindow* mWin, jint x, jint y, jint width, jint height, BOOL doDisplay) { +static void setWindowClientTopLeftPointAndSize(NewtNSWindow* mWin, jint x, jint y, jint width, jint height, BOOL doDisplay) { DBG_PRINT( "setWindowClientTopLeftPointAndSize.0 - window: %p %d/%d %dx%d, display %d\n", mWin, (int)x, (int)y, (int)width, (int)height, (int)doDisplay); NSSize clientSZ = NSMakeSize(width, height); NSPoint pS = [mWin newtAbsClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y) size: clientSZ]; @@ -100,7 +100,7 @@ static int getRetainCount(NSObject * obj) { } #endif -static void setJavaWindowObject(JNIEnv *env, jobject newJavaWindowObject, NewtView *view, BOOL enable) { +static void setJavaWindowObject(JNIEnv *env, jobject newJavaWindowObject, NewtNSView *view, BOOL enable) { DBG_PRINT( "setJavaWindowObject.0: View %p\n", view); if( !enable) { jobject globJavaWindowObject = [view getJavaWindowObject]; @@ -117,19 +117,19 @@ static void setJavaWindowObject(JNIEnv *env, jobject newJavaWindowObject, NewtVi DBG_PRINT( "setJavaWindowObject.X: View %p\n", view); } -static void changeContentView(JNIEnv *env, jobject javaWindowObject, NSView *pview, NewtMacWindow *win, NewtView *newView, BOOL setJavaWindow) { +static void changeContentView(JNIEnv *env, jobject javaWindowObject, NSView *pview, NewtNSWindow *win, NewtNSView *newView, BOOL setJavaWindow) { NSView* oldNSView = [win contentView]; - NewtView* oldNewtView = NULL; + NewtNSView* oldNewtNSView = NULL; #ifdef VERBOSE_ON int dbgIdx = 1; #endif - if( [oldNSView isKindOfClass:[NewtView class]] ) { - oldNewtView = (NewtView *) oldNSView; + if( [oldNSView isKindOfClass:[NewtNSView class]] ) { + oldNewtNSView = (NewtNSView *) oldNSView; } DBG_PRINT( "changeContentView.%d win %p, view (%p,%d (%d) -> %p,%d), parent view %p\n", - dbgIdx++, win, oldNSView, getRetainCount(oldNSView), NULL!=oldNewtView, newView, getRetainCount(newView), pview); + dbgIdx++, win, oldNSView, getRetainCount(oldNSView), NULL!=oldNewtNSView, newView, getRetainCount(newView), pview); if( NULL!=oldNSView ) { NS_DURING @@ -146,11 +146,11 @@ 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!=oldNewtView, newView, getRetainCount(newView)); + dbgIdx++, win, oldNSView, getRetainCount(oldNSView), NULL!=oldNewtNSView, newView, getRetainCount(newView)); - if( NULL != oldNewtView ) { - [oldNewtView setDestroyNotifySent: false]; - setJavaWindowObject(env, NULL, oldNewtView, NO); + if( NULL != oldNewtNSView ) { + [oldNewtNSView setDestroyNotifySent: false]; + setJavaWindowObject(env, NULL, oldNewtNSView, NO); } [oldNSView removeFromSuperviewWithoutNeedingDisplay]; } @@ -764,7 +764,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0 // printf("Going to sleep for 10 seconds\n"); // sleep(10); - BOOL res = [NewtMacWindow initNatives: env forClass: clazz]; + BOOL res = [NewtNSWindow initNatives: env forClass: clazz]; [pool release]; return (jboolean) res; @@ -784,7 +784,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0 (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h); NSRect rectView = NSMakeRect(0, 0, w, h); - NewtView *myView = [[NewtView alloc] initWithFrame: rectView] ; + NewtNSView *myView = [[NewtNSView alloc] initWithFrame: rectView] ; DBG_PRINT( "createView0.X - new view: %p\n", myView); [pool release]; @@ -804,7 +804,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow jboolean fullscreen, jint styleMask, jint bufferingType, jlong jview) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtView* myView = (NewtView*) (intptr_t) jview ; + NewtNSView* myView = (NewtNSView*) (intptr_t) jview ; DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, view %p (START)\n", (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen, @@ -817,7 +817,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow NSRect rectWin = NSMakeRect(x, y, w, h); // Allocate the window - NewtMacWindow* myWindow = [[NewtMacWindow alloc] initWithContentRect: rectWin + NewtNSWindow* myWindow = [[NewtNSWindow alloc] initWithContentRect: rectWin styleMask: (NSUInteger) styleMask backing: (NSBackingStoreType) bufferingType defer: YES @@ -832,7 +832,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow } JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getDisplayID0(JNIEnv *env, jobject jthis, jlong window) { - NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window); + NewtNSWindow* myWindow = (NewtNSWindow*) ((intptr_t) window); if( NULL == myWindow ) { DBG_PRINT( "getDisplayID0 - NULL NEWT win - abort\n"); return 0; @@ -856,8 +856,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0 jboolean opaque, jboolean atop, jboolean abottom, jboolean visible, jlong jview) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window); - NewtView* myView = (NewtView*) (intptr_t) jview ; + NewtNSWindow* myWindow = (NewtNSWindow*) ((intptr_t) window); + NewtNSView* myView = (NewtNSView*) (intptr_t) jview ; BOOL fullscreen = myWindow->isFullscreenWindow; DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, reqPixScale %f, opaque %d, atop %d, abottom %d, fs %d, visible %d, view %p (START)\n", @@ -1040,13 +1040,13 @@ NS_ENDHANDLER JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPixelScale0 (JNIEnv *env, jobject jthis, jlong window, jlong view, jfloat reqPixelScale) { - NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window); + NewtNSWindow* myWindow = (NewtNSWindow*) ((intptr_t) window); if( NULL == myWindow ) { DBG_PRINT( "setPixelScale0 - NULL NEWT win - abort\n"); return; } NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtView* myView = (NewtView*) (intptr_t) view ; + NewtNSView* myView = (NewtNSView*) (intptr_t) view ; #ifdef VERBOSE_ON int dbgIdx = 1; #endif @@ -1082,40 +1082,40 @@ NS_ENDHANDLER JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0 (JNIEnv *env, jobject unused, jlong window) { - NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window); + NewtNSWindow* mWin = (NewtNSWindow*) ((intptr_t) window); if( NULL == mWin ) { DBG_PRINT( "windowClose.0 - NULL NEWT win - abort\n"); return; } BOOL isNSWin = [mWin isKindOfClass:[NSWindow class]]; - BOOL isNewtWin = [mWin isKindOfClass:[NewtMacWindow class]]; + BOOL isNewtWin = [mWin isKindOfClass:[NewtNSWindow class]]; NSWindow *pWin = [mWin parentWindow]; DBG_PRINT( "windowClose.0 - %p [isNSWindow %d, isNewtWin %d], parent %p\n", mWin, isNSWin, isNewtWin, pWin); (void)isNSWin; // silence if( !isNewtWin ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin); + NewtCommon_throwNewRuntimeException(env, "Not a NewtNSWindow %p", mWin); return; } NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtView* mView = (NewtView *)[mWin contentView]; + NewtNSView* mView = (NewtNSView *)[mWin contentView]; BOOL fullscreen = mWin->isFullscreenWindow; - BOOL destroyNotifySent, isNSView, isNewtView; + BOOL destroyNotifySent, isNSView, isNewtNSView; if( NULL != mView ) { isNSView = [mView isKindOfClass:[NSView class]]; - isNewtView = [mView isKindOfClass:[NewtView class]]; - destroyNotifySent = isNewtView ? [mView getDestroyNotifySent] : false; + isNewtNSView = [mView isKindOfClass:[NewtNSView class]]; + destroyNotifySent = isNewtNSView ? [mView getDestroyNotifySent] : false; } else { isNSView = false; - isNewtView = false; + isNewtNSView = false; destroyNotifySent = false; } - DBG_PRINT( "windowClose.0 - %p, destroyNotifySent %d, view %p [isNSView %d, isNewtView %d], fullscreen %d, parent %p\n", - mWin, destroyNotifySent, mView, isNSView, isNewtView, (int)fullscreen, pWin); + DBG_PRINT( "windowClose.0 - %p, destroyNotifySent %d, view %p [isNSView %d, isNewtNSView %d], fullscreen %d, parent %p\n", + mWin, destroyNotifySent, mView, isNSView, isNewtNSView, (int)fullscreen, pWin); [mWin setRealized: NO]; - if( isNewtView ) { + if( isNewtNSView ) { // cleanup view [mView setDestroyNotifySent: true]; setJavaWindowObject(env, NULL, mView, NO); @@ -1170,11 +1170,11 @@ NS_ENDHANDLER JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_lockSurface0 (JNIEnv *env, jclass clazz, jlong window, jlong view) { - NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); + NewtNSWindow *mWin = (NewtNSWindow*) ((intptr_t) window); if(NO == [mWin isRealized]) { return JNI_FALSE; } - NewtView * mView = (NewtView *) ((intptr_t) view); + NewtNSView * mView = (NewtNSView *) ((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; */ @@ -1188,9 +1188,9 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_lockSurfa JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_unlockSurface0 (JNIEnv *env, jclass clazz, jlong window, jlong view) { - // NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); + // NewtNSWindow *mWin = (NewtNSWindow*) ((intptr_t) window); (void) window; - NewtView * mView = (NewtView *) ((intptr_t) view); + NewtNSView * mView = (NewtNSView *) ((intptr_t) view); return [mView softUnlock] == YES ? JNI_TRUE : JNI_FALSE; /** deadlocks, since we render independent of focus [mView unlockFocus]; */ @@ -1351,10 +1351,10 @@ 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; + NewtNSView* newtView = NULL; - if( [nsView isKindOfClass:[NewtView class]] ) { - newtView = (NewtView *) nsView; + if( [nsView isKindOfClass:[NewtNSView class]] ) { + newtView = (NewtNSView *) nsView; } DBG_PRINT( "contentView0 - window: %p, view: %p, newtView %p\n", win, nsView, newtView); @@ -1377,8 +1377,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeContent { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtView* newView = (NewtView *) ((intptr_t) jview); - NewtMacWindow* win = (NewtMacWindow*) ((intptr_t) window); + NewtNSView* newView = (NewtNSView *) ((intptr_t) jview); + NewtNSWindow* win = (NewtNSWindow*) ((intptr_t) window); DBG_PRINT( "changeContentView0.0 - win %p, view (%p,%d)\n", win, newView, getRetainCount(newView)); @@ -1410,7 +1410,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_updateSizePos (JNIEnv *env, jobject jthis, jlong window, jboolean defer) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window); + NewtNSWindow* mWin = (NewtNSWindow*) ((intptr_t) window); DBG_PRINT( "updateSizePosInsets - window: %p, defer %d (START)\n", mWin, (int)defer); @@ -1430,7 +1430,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClie (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jint w, jint h, jboolean display) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window); + NewtNSWindow* mWin = (NewtNSWindow*) ((intptr_t) window); DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (START)\n", mWin); @@ -1449,7 +1449,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClie JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPoint0 (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jboolean display) { - NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window); + NewtNSWindow* mWin = (NewtNSWindow*) ((intptr_t) window); if( NULL == mWin ) { DBG_PRINT( "setWindowClientTopLeftPoint - NULL NEWT win - abort\n"); return; @@ -1473,13 +1473,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClie JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocationOnScreen0 (JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y) { - NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) win; + NewtNSWindow *mWin = (NewtNSWindow*) (intptr_t) win; if( NULL == mWin ) { DBG_PRINT( "getLocationOnScreen0 - NULL NEWT win - abort\n"); return NULL; } - if( ![mWin isKindOfClass:[NewtMacWindow class]] ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin); + if( ![mWin isKindOfClass:[NewtNSWindow class]] ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtNSWindow %p", mWin); return NULL; } NSPoint p0 = [mWin getLocationOnScreen: NSMakePoint(src_x, src_y)]; @@ -1489,7 +1489,7 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocatio JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIcon0 (JNIEnv *env, jobject unused, jlong window, jlong handle) { - NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window; + NewtNSWindow *mWin = (NewtNSWindow*) (intptr_t) window; if( NULL == mWin ) { DBG_PRINT( "setPointerIcon0 - NULL NEWT win - abort\n"); return; @@ -1499,13 +1499,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIco NewtCommon_throwNewRuntimeException(env, "Not a NSCursor %p", c); return; } - if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin); + if( ! [mWin isKindOfClass:[NewtNSWindow class]] ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtNSWindow %p", mWin); return; } - NewtView* nView = (NewtView *) [mWin contentView]; - if( ! [nView isKindOfClass:[NewtView class]] ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView); + NewtNSView* nView = (NewtNSView *) [mWin contentView]; + if( ! [nView isKindOfClass:[NewtNSView class]] ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtNSView %p", nView); return; } NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -1521,18 +1521,18 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIco JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVisible0 (JNIEnv *env, jclass clazz, jlong window, jboolean hasFocus, jboolean mouseVisible) { - NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); + NewtNSWindow *mWin = (NewtNSWindow*) ((intptr_t) window); if( NULL == mWin ) { DBG_PRINT( "setPointerVisible0 - NULL NEWT win - abort\n"); return; } - if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin); + if( ! [mWin isKindOfClass:[NewtNSWindow class]] ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtNSWindow %p", mWin); return; } - NewtView* nView = (NewtView *) [mWin contentView]; - if( ! [nView isKindOfClass:[NewtView class]] ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView); + NewtNSView* nView = (NewtNSView *) [mWin contentView]; + if( ! [nView isKindOfClass:[NewtNSView class]] ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtNSView %p", nView); return; } NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -1549,18 +1549,18 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVis JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointer0 (JNIEnv *env, jclass clazz, jlong window, jboolean confine) { - NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); + NewtNSWindow *mWin = (NewtNSWindow*) ((intptr_t) window); if( NULL == mWin ) { DBG_PRINT( "confinePointer0 - NULL NEWT win - abort\n"); return; } - if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin); + if( ! [mWin isKindOfClass:[NewtNSWindow class]] ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtNSWindow %p", mWin); return; } - NewtView* nView = (NewtView *) [mWin contentView]; - if( ! [nView isKindOfClass:[NewtView class]] ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView); + NewtNSView* nView = (NewtNSView *) [mWin contentView]; + if( ! [nView isKindOfClass:[NewtNSView class]] ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtNSView %p", nView); return; } NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -1576,18 +1576,18 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointe JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0 (JNIEnv *env, jclass clazz, jlong window, jint x, jint y) { - NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); + NewtNSWindow *mWin = (NewtNSWindow*) ((intptr_t) window); if( NULL == mWin ) { DBG_PRINT( "warpPointer0 - NULL NEWT win - abort\n"); return; } - if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin); + if( ! [mWin isKindOfClass:[NewtNSWindow class]] ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtNSWindow %p", mWin); return; } - NewtView* nView = (NewtView *) [mWin contentView]; - if( ! [nView isKindOfClass:[NewtView class]] ) { - NewtCommon_throwNewRuntimeException(env, "Not a NewtView %p", nView); + NewtNSView* nView = (NewtNSView *) [mWin contentView]; + if( ! [nView isKindOfClass:[NewtNSView class]] ) { + NewtCommon_throwNewRuntimeException(env, "Not a NewtNSView %p", nView); return; } NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h deleted file mode 100644 index 14474bc10..000000000 --- a/src/newt/native/NewtMacWindow.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2011 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -#import -#import -#import "jni.h" - -#include "NewtCommon.h" - -// #define VERBOSE_ON 1 - -#ifdef VERBOSE_ON - #define DBG_PRINT(...) NSLog(@ __VA_ARGS__) ; fflush(stderr) - // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) -#else - #define DBG_PRINT(...) -#endif - -// #define DBG_LIFECYCLE 1 - -CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen); - -@interface NewtView : NSView -{ - jobject javaWindowObject; - - volatile BOOL destroyNotifySent; - volatile int softLockCount; - pthread_mutex_t softLockSync; - - volatile NSTrackingRectTag ptrTrackingTag; - NSRect ptrRect; - NSCursor * myCursor; - BOOL modsDown[4]; // shift, ctrl, alt/option, win/command - - BOOL mouseConfined; - BOOL mouseInside; - BOOL mouseVisible; - BOOL cursorIsHidden; - NSPoint lastInsideMousePosition; -} - -- (id)initWithFrame:(NSRect)frameRect; - -#ifdef DBG_LIFECYCLE -- (void) release; -#endif -- (void) dealloc; - -/* Register or deregister (NULL) the java Window object, - ie, if NULL, no events are send */ -- (void) setJavaWindowObject: (jobject) javaWindowObj; -- (jobject) getJavaWindowObject; - -- (void) setDestroyNotifySent: (BOOL) v; -- (BOOL) getDestroyNotifySent; - -- (BOOL) softLock; -- (BOOL) softUnlock; - -- (BOOL) needsDisplay; -- (void) displayIfNeeded; -- (void) display; -- (void) drawRect:(NSRect)dirtyRect; -- (void) viewDidHide; -- (void) viewDidUnhide; -- (BOOL) acceptsFirstResponder; -- (BOOL) becomeFirstResponder; -- (BOOL) resignFirstResponder; - -- (void) removeCursorRects; -- (void) addCursorRects; -- (void) removeMyCursor; -- (void) resetCursorRects; -- (void) setPointerIcon: (NSCursor*)c; -- (void) mouseEntered: (NSEvent*) theEvent; -- (void) mouseExited: (NSEvent*) theEvent; -- (BOOL) updateMouseInside; -- (void) cursorHide:(BOOL)v enter:(int)enterState; -- (void) setPointerIcon:(NSCursor*)c; -- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus; -- (BOOL) isMouseVisible; -- (void) setMouseConfined:(BOOL)v; -- (void) setMousePosition:(NSPoint)p; -- (void) mouseMoved: (NSEvent*) theEvent; -- (void) scrollWheel: (NSEvent*) theEvent; -- (void) mouseDown: (NSEvent*) theEvent; -- (void) mouseDragged: (NSEvent*) theEvent; -- (void) mouseUp: (NSEvent*) theEvent; -- (void) rightMouseDown: (NSEvent*) theEvent; -- (void) rightMouseDragged: (NSEvent*) theEvent; -- (void) rightMouseUp: (NSEvent*) theEvent; -- (void) otherMouseDown: (NSEvent*) theEvent; -- (void) otherMouseDragged: (NSEvent*) theEvent; -- (void) otherMouseUp: (NSEvent*) theEvent; -- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType; -- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p; - -- (void) handleFlagsChanged:(NSUInteger) mods; -- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods; -- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType; -- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType; -- (void) viewDidChangeBackingProperties; - -@end - -#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 -@interface NewtMacWindow : NSWindow -#else -@interface NewtMacWindow : NSWindow -#endif -{ - BOOL realized; - jboolean withinLiveResize; -@public - BOOL hasPresentationSwitch; - NSUInteger defaultPresentationOptions; - NSUInteger fullscreenPresentationOptions; - BOOL isFullscreenWindow; - int cachedInsets[4]; // l, r, t, b -} - -+ (BOOL) initNatives: (JNIEnv*) env forClass: (jobject) clazz; - -- (id) initWithContentRect: (NSRect) contentRect - styleMask: (NSUInteger) windowStyle - backing: (NSBackingStoreType) bufferingType - defer: (BOOL) deferCreation - isFullscreenWindow:(BOOL)isfs; -#ifdef DBG_LIFECYCLE -- (void) release; -#endif -- (void) dealloc; -- (void) setRealized: (BOOL)v; -- (BOOL) isRealized; - -- (void) setAlwaysOn: (BOOL)top bottom:(BOOL)bottom; - -- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin; -- (void) updateSizePosInsets: (JNIEnv*) env jwin: (jobject) javaWin defer: (jboolean)defer; -- (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; - -- (void) focusChanged: (BOOL) gained; - -- (void) keyDown: (NSEvent*) theEvent; -- (void) keyUp: (NSEvent*) theEvent; -- (void) flagsChanged: (NSEvent *) theEvent; -- (BOOL) acceptsMouseMovedEvents; -- (BOOL) acceptsFirstResponder; -- (BOOL) becomeFirstResponder; -- (BOOL) resignFirstResponder; -- (BOOL) canBecomeKeyWindow; -- (void) becomeKeyWindow; -- (void) resignKeyWindow; -- (void) windowDidBecomeKey: (NSNotification *) notification; -- (void) windowDidResignKey: (NSNotification *) notification; - -- (void) windowWillStartLiveResize: (NSNotification *) notification; -- (void) windowDidEndLiveResize: (NSNotification *) notification; -- (NSSize) windowWillResize: (NSWindow *)sender toSize:(NSSize)frameSize; -- (void) windowDidResize: (NSNotification*) notification; -- (void) sendResizeEvent; - -- (void) windowDidMove: (NSNotification*) notification; -- (BOOL) windowClosingImpl: (BOOL) force; -- (BOOL) windowShouldClose: (id) sender; -- (void) windowWillClose: (NSNotification*) notification; - -@end diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m deleted file mode 100644 index 6024a90d4..000000000 --- a/src/newt/native/NewtMacWindow.m +++ /dev/null @@ -1,1356 +0,0 @@ -/* - * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -#import "NewtMacWindow.h" -#import "InputEvent.h" -#import "KeyEvent.h" -#import "MouseEvent.h" - -#include -#include /* For kVK_ constants, and TIS functions. */ - -#include - -#define PRINTF(...) NSLog(@ __VA_ARGS__) - -static jfloat GetDelta(NSEvent *event, jint javaMods[]) { - CGEventRef cgEvent = [event CGEvent]; - CGFloat deltaY = 0.0; - CGFloat deltaX = 0.0; - CGFloat delta = 0.0; - - if (CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventIsContinuous)) { - // mouse pad case - deltaX = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2); - deltaY = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1); - // fprintf(stderr, "WHEEL/PAD: %lf/%lf - 0x%X\n", (double)deltaX, (double)deltaY, javaMods[0]); - if( fabs(deltaX) > fabs(deltaY) ) { - javaMods[0] |= EVENT_SHIFT_MASK; - delta = deltaX; - } else { - delta = deltaY; - } - } else { - // traditional mouse wheel case - deltaX = [event deltaX]; - deltaY = [event deltaY]; - // fprintf(stderr, "WHEEL/TRACK: %lf/%lf - 0x%X\n", (double)deltaX, (double)deltaY, javaMods[0]); - if (deltaY == 0.0 && (javaMods[0] & EVENT_SHIFT_MASK) != 0) { - // shift+vertical wheel scroll produces horizontal scroll - // we convert it to vertical - delta = deltaX; - } else { - delta = deltaY; - } - if (-1.0 < delta && delta < 1.0) { - delta *= 10.0; - } else { - if (delta < 0.0) { - delta = delta - 0.5f; - } else { - delta = delta + 0.5f; - } - } - } - // fprintf(stderr, "WHEEL/RES: %lf - 0x%X\n", (double)delta, javaMods[0]); - return (jfloat) delta; -} - -#define kVK_Shift 0x38 -#define kVK_Option 0x3A -#define kVK_Control 0x3B -#define kVK_Command 0x37 - -static jint mods2JavaMods(NSUInteger mods) -{ - int javaMods = 0; - if (mods & NSShiftKeyMask) { - javaMods |= EVENT_SHIFT_MASK; - } - if (mods & NSControlKeyMask) { - javaMods |= EVENT_CTRL_MASK; - } - if (mods & NSCommandKeyMask) { - javaMods |= EVENT_META_MASK; - } - if (mods & NSAlternateKeyMask) { - javaMods |= EVENT_ALT_MASK; - } - return javaMods; -} - -static CFStringRef CKCH_CreateStringForKey(CGKeyCode keyCode, const UCKeyboardLayout *keyboardLayout) { - UInt32 keysDown = 0; - UniChar chars[4]; - UniCharCount realLength; - - UCKeyTranslate(keyboardLayout, keyCode, - kUCKeyActionDisplay, 0, - LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, - &keysDown, sizeof(chars) / sizeof(chars[0]), &realLength, chars); - - return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1); -} - -static CFMutableDictionaryRef CKCH_CreateCodeToCharDict(TISInputSourceRef keyboard) { - CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData); - if( NULL == layoutData ) { - return NULL; - } - const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); - - CFMutableDictionaryRef codeToCharDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 128, NULL, NULL); - if ( NULL != codeToCharDict ) { - intptr_t i; - for (i = 0; i < 128; ++i) { - CFStringRef string = CKCH_CreateStringForKey((CGKeyCode)i, keyboardLayout); - if( NULL != string ) { - CFIndex stringLen = CFStringGetLength (string); - if ( 0 < stringLen ) { - UniChar character = CFStringGetCharacterAtIndex(string, 0); - DBG_PRINT("CKCH: MAP 0x%X -> %c\n", (int)i, character); - CFDictionaryAddValue(codeToCharDict, (const void *)i, (const void *)(intptr_t)character); - } - CFRelease(string); - } - } - } - return codeToCharDict; -} - -static CFMutableDictionaryRef CKCH_USCodeToNNChar = NULL; - -static void CKCH_CreateDictionaries() { - TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); - if( NULL != currentKeyboard ) { - CKCH_USCodeToNNChar = CKCH_CreateCodeToCharDict(currentKeyboard); - CFRelease(currentKeyboard); - } -} - -static UniChar CKCH_CharForKeyCode(jshort keyCode) { - UniChar rChar = 0; - - if ( NULL != CKCH_USCodeToNNChar ) { - intptr_t code = (intptr_t) keyCode; - intptr_t character = 0; - - if ( CFDictionaryGetValueIfPresent(CKCH_USCodeToNNChar, (void *)code, (const void **)&character) ) { - rChar = (UniChar) character; - DBG_PRINT("CKCH: OK 0x%X -> 0x%X\n", (int)keyCode, (int)rChar); - } - } - return rChar; -} - -static jmethodID enqueueMouseEventID = NULL; -static jmethodID enqueueKeyEventID = NULL; -static jmethodID requestFocusID = NULL; - -static jmethodID insetsChangedID = NULL; -static jmethodID sizeChangedID = NULL; -static jmethodID sizeScreenPosInsetsChangedID = NULL; -static jmethodID updatePixelScaleID = NULL; -static jmethodID visibleChangedID = NULL; -static jmethodID screenPositionChangedID = NULL; -static jmethodID focusChangedID = NULL; -static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowRepaintID = NULL; - -// Need to enqueue all events to EDT, -// since we may operate on AWT-AppKit (Main Thread) -// and direct issuing 'requestFocus()' would deadlock: -// AWT-AppKit -// AWT-EventQueue-0 - -@implementation NewtView - -- (id)initWithFrame:(NSRect)frameRect -{ - id res = [super initWithFrame:frameRect]; - javaWindowObject = NULL; - - destroyNotifySent = NO; - softLockCount = 0; - - pthread_mutexattr_t softLockSyncAttr; - pthread_mutexattr_init(&softLockSyncAttr); - pthread_mutexattr_settype(&softLockSyncAttr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&softLockSync, &softLockSyncAttr); // recursive - - ptrTrackingTag = 0; - myCursor = NULL; - - modsDown[0] = NO; // shift - modsDown[1] = NO; // ctrl - modsDown[2] = NO; // alt - modsDown[3] = NO; // win - mouseConfined = NO; - mouseVisible = YES; - mouseInside = NO; - cursorIsHidden = NO; - - DBG_PRINT("NewtView::create: %p (refcnt %d)\n", res, (int)[res retainCount]); - return res; -} - -#ifdef DBG_LIFECYCLE -- (void) release -{ - DBG_PRINT("NewtView::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]); - [super release]; -} -#endif - -- (void) dealloc -{ - DBG_PRINT("NewtView::dealloc.0: %p (refcnt %d), ptrTrackingTag %d\n", self, (int)[self retainCount], (int)ptrTrackingTag); -#ifdef DBG_LIFECYCLE - NSLog(@"%@",[NSThread callStackSymbols]); -#endif - if( 0 < softLockCount ) { - NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n"); - } - [self removeCursorRects]; - [self removeMyCursor]; - - pthread_mutex_destroy(&softLockSync); - DBG_PRINT("NewtView::dealloc.X: %p\n", self); - [super dealloc]; -} - -- (void) setJavaWindowObject: (jobject) javaWindowObj -{ - javaWindowObject = javaWindowObj; -} - -- (jobject) getJavaWindowObject -{ - return javaWindowObject; -} - -- (void) setDestroyNotifySent: (BOOL) v -{ - destroyNotifySent = v; -} - -- (BOOL) getDestroyNotifySent -{ - return destroyNotifySent; -} - -- (BOOL) softLock -{ - // DBG_PRINT("*************** softLock.0: %p\n", (void*)pthread_self()); - 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 0 < softLockCount; -} - -- (BOOL) softUnlock -{ - // DBG_PRINT("*************** softUnlock: %p\n", (void*)pthread_self()); - 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 -{ - return NO == destroyNotifySent && [super needsDisplay]; -} - -- (void) displayIfNeeded -{ - if( YES == [self needsDisplay] ) { - [self softLock]; - [super displayIfNeeded]; - [self softUnlock]; - } -} - -- (void) display -{ - if( NO == destroyNotifySent ) { - [self softLock]; - [super display]; - [self softUnlock]; - } -} - -- (void) drawRect:(NSRect)dirtyRect -{ - DBG_PRINT("*************** dirtyRect: %p %lf/%lf %lfx%lf\n", - javaWindowObject, dirtyRect.origin.x, dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height); - - if(NULL==javaWindowObject) { - DBG_PRINT("drawRect: null javaWindowObject\n"); - return; - } - int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); - if(NULL==env) { - DBG_PRINT("drawRect: null JNIEnv\n"); - return; - } - - NSRect viewFrame = [self frame]; - - (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_TRUE, // defer .. - (int)dirtyRect.origin.x, (int)viewFrame.size.height - (int)dirtyRect.origin.y, - (int)dirtyRect.size.width, (int)dirtyRect.size.height); - - // detaching thread not required - daemon - // NewtCommon_ReleaseJNIEnv(shallBeDetached); -} - -- (void) viewDidHide -{ - if(NULL==javaWindowObject) { - DBG_PRINT("viewDidHide: null javaWindowObject\n"); - return; - } - int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); - if(NULL==env) { - DBG_PRINT("viewDidHide: null JNIEnv\n"); - return; - } - - (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_FALSE); - - // detaching thread not required - daemon - // NewtCommon_ReleaseJNIEnv(shallBeDetached); - - [super viewDidHide]; -} - -- (void) viewDidUnhide -{ - if(NULL==javaWindowObject) { - DBG_PRINT("viewDidUnhide: null javaWindowObject\n"); - return; - } - int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); - if(NULL==env) { - DBG_PRINT("viewDidUnhide: null JNIEnv\n"); - return; - } - - (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_TRUE); - - // detaching thread not required - daemon - // NewtCommon_ReleaseJNIEnv(shallBeDetached); - - [super viewDidUnhide]; -} - -- (BOOL) acceptsFirstResponder -{ - return YES; -} - -- (BOOL) becomeFirstResponder -{ - DBG_PRINT( "*************** View.becomeFirstResponder\n"); - return [super becomeFirstResponder]; -} - -- (BOOL) resignFirstResponder -{ - DBG_PRINT( "*************** View.resignFirstResponder\n"); - return [super resignFirstResponder]; -} - -- (void) removeCursorRects -{ - if(0 != ptrTrackingTag) { - if(NULL != myCursor) { - [self removeCursorRect: ptrRect cursor: myCursor]; - } - [self removeTrackingRect: ptrTrackingTag]; - ptrTrackingTag = 0; - } -} - -- (void) addCursorRects -{ - ptrRect = [self bounds]; - if(NULL != myCursor) { - [self addCursorRect: ptrRect cursor: myCursor]; - } - ptrTrackingTag = [self addTrackingRect: ptrRect owner: self userData: nil assumeInside: NO]; -} - -- (void) removeMyCursor -{ - if(NULL != myCursor) { - [myCursor release]; - myCursor = NULL; - } -} - -- (void) resetCursorRects -{ - [super resetCursorRects]; - - [self removeCursorRects]; - [self addCursorRects]; -} - -- (void) setPointerIcon: (NSCursor*)c -{ - DBG_PRINT( "setPointerIcon: %p -> %p, top %p, mouseInside %d\n", myCursor, c, [NSCursor currentCursor], (int)mouseInside); - if( c != myCursor ) { - [self removeCursorRects]; - [self removeMyCursor]; - myCursor = c; - if( NULL != myCursor ) { - [myCursor retain]; - } - } - NSWindow* nsWin = [self window]; - if( NULL != nsWin ) { - [nsWin invalidateCursorRectsForView: self]; - } -} - -- (void) mouseEntered: (NSEvent*) theEvent -{ - DBG_PRINT( "mouseEntered: confined %d, visible %d, PointerIcon %p, top %p\n", mouseConfined, mouseVisible, myCursor, [NSCursor currentCursor]); - mouseInside = YES; - [self cursorHide: !mouseVisible enter: 1]; - if(NO == mouseConfined) { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED]; - } - NSWindow* nsWin = [self window]; - if( NULL != nsWin ) { - [nsWin makeFirstResponder: self]; - } -} - -- (void) mouseExited: (NSEvent*) theEvent -{ - DBG_PRINT( "mouseExited: confined %d, visible %d, PointerIcon %p, top %p\n", mouseConfined, mouseVisible, myCursor, [NSCursor currentCursor]); - if(NO == mouseConfined) { - mouseInside = NO; - [self cursorHide: NO enter: -1]; - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED]; - [self resignFirstResponder]; - } else { - [self setMousePosition: lastInsideMousePosition]; - } -} - -/** - * p abs screen position w/ bottom-left origin - */ -- (void) setMousePosition:(NSPoint)p -{ - NSWindow* nsWin = [self window]; - if( NULL != nsWin ) { - NSScreen* screen = [nsWin screen]; - - CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); - CGRect frameTL = CGDisplayBounds (display); // origin top-left - NSRect frameBL = [screen frame]; // origin bottom-left - CGPoint pt = { p.x, frameTL.origin.y + frameTL.size.height - ( p.y - frameBL.origin.y ) }; // y-flip from BL-screen -> TL-screen - - DBG_PRINT( "setMousePosition: point-in[%d/%d], screen tl[%d/%d %dx%d] bl[%d/%d %dx%d] -> %d/%d\n", - (int)p.x, (int)p.y, - (int)frameTL.origin.x, (int)frameTL.origin.y, (int)frameTL.size.width, (int)frameTL.size.height, - (int)frameBL.origin.x, (int)frameBL.origin.y, (int)frameBL.size.width, (int)frameBL.size.height, - (int)pt.x, (int)pt.y); - - CGEventRef ev = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, pt, kCGMouseButtonLeft); - CGEventPost (kCGHIDEventTap, ev); - } -} - -- (BOOL) updateMouseInside -{ - NSRect viewFrame = [self frame]; - NSPoint l1 = [NSEvent mouseLocation]; - NSPoint l0 = [self screenPos2NewtClientWinPos: l1]; - mouseInside = viewFrame.origin.x <= l0.x && l0.x < (viewFrame.origin.x+viewFrame.size.width) && - viewFrame.origin.y <= l0.y && l0.y < (viewFrame.origin.y+viewFrame.size.height) ; - return mouseInside; -} - -- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus -{ - mouseVisible = v; - [self updateMouseInside]; - DBG_PRINT( "setMouseVisible: confined %d, visible %d (current: %d), mouseInside %d, hasFocus %d\n", - mouseConfined, mouseVisible, !cursorIsHidden, mouseInside, focus); - if(YES == focus && YES == mouseInside) { - [self cursorHide: !mouseVisible enter: 0]; - } -} -- (BOOL) isMouseVisible -{ - return mouseVisible; -} - -- (void) cursorHide:(BOOL)v enter:(int)enterState -{ - DBG_PRINT( "cursorHide: %d -> %d, enter %d; PointerIcon: %p, top %p\n", - cursorIsHidden, v, enterState, myCursor, [NSCursor currentCursor]); - if(v) { - if(!cursorIsHidden) { - [NSCursor hide]; - cursorIsHidden = YES; - } - } else { - if(cursorIsHidden) { - [NSCursor unhide]; - cursorIsHidden = NO; - } - } -} - -- (void) setMouseConfined:(BOOL)v -{ - mouseConfined = v; - DBG_PRINT( "setMouseConfined: confined %d, visible %d\n", mouseConfined, mouseVisible); -} - -- (void) mouseMoved: (NSEvent*) theEvent -{ - if( mouseInside ) { - NSCursor * currentCursor = [NSCursor currentCursor]; - BOOL setCursor = NULL != myCursor && NO == cursorIsHidden && currentCursor != myCursor; - DBG_PRINT( "mouseMoved.set: %d; mouseInside %d, CursorHidden %d, PointerIcon: %p, top %p\n", - setCursor, mouseInside, cursorIsHidden, myCursor, currentCursor); - if( setCursor ) { - // FIXME: Workaround missing NSCursor update for 'fast moving' pointer - [myCursor set]; - } - lastInsideMousePosition = [NSEvent mouseLocation]; - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; - } -} - -- (void) scrollWheel: (NSEvent*) theEvent -{ - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_WHEEL_MOVED]; -} - -- (void) mouseDown: (NSEvent*) theEvent -{ - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; -} - -- (void) mouseDragged: (NSEvent*) theEvent -{ - lastInsideMousePosition = [NSEvent mouseLocation]; - // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; -} - -- (void) mouseUp: (NSEvent*) theEvent -{ - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; -} - -- (void) rightMouseDown: (NSEvent*) theEvent -{ - NSResponder* next = [self nextResponder]; - if (next != nil) { - [next rightMouseDown: theEvent]; - } - // FIXME: ^^ OR [super rightMouseDown: theEvent] ? - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; -} - -- (void) rightMouseDragged: (NSEvent*) theEvent -{ - lastInsideMousePosition = [NSEvent mouseLocation]; - // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; -} - -- (void) rightMouseUp: (NSEvent*) theEvent -{ - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; -} - -- (void) otherMouseDown: (NSEvent*) theEvent -{ - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; -} - -- (void) otherMouseDragged: (NSEvent*) theEvent -{ - lastInsideMousePosition = [NSEvent mouseLocation]; - // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; -} - -- (void) otherMouseUp: (NSEvent*) theEvent -{ - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; -} - -- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType -{ - if (javaWindowObject == NULL) { - DBG_PRINT("sendMouseEvent: null javaWindowObject\n"); - return; - } - int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); - if(NULL==env) { - DBG_PRINT("sendMouseEvent: null JNIEnv\n"); - return; - } - jint javaMods[] = { 0 } ; - javaMods[0] = mods2JavaMods([event modifierFlags]); - - // convert to 1-based button number (or use zero if no button is involved) - // TODO: detect mouse button when mouse wheel scrolled - jshort javaButtonNum; - jfloat scrollDeltaY = 0.0f; - switch ([event type]) { - case NSScrollWheel: - scrollDeltaY = GetDelta(event, javaMods); - javaButtonNum = 1; - break; - case NSLeftMouseDown: - case NSLeftMouseUp: - case NSLeftMouseDragged: - javaButtonNum = 1; - break; - case NSRightMouseDown: - case NSRightMouseUp: - case NSRightMouseDragged: - javaButtonNum = 3; - break; - case NSOtherMouseDown: - case NSOtherMouseUp: - case NSOtherMouseDragged: - javaButtonNum = 2; - break; - default: - javaButtonNum = 0; - break; - } - if (evType == EVENT_MOUSE_WHEEL_MOVED && scrollDeltaY == 0) { - // ignore 0 increment wheel scroll events - return; - } - if (evType == EVENT_MOUSE_PRESSED) { - (*env)->CallVoidMethod(env, javaWindowObject, requestFocusID, JNI_FALSE); - } - - NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]]; - - (*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, JNI_FALSE, - evType, javaMods[0], - (jint) location.x, (jint) location.y, - javaButtonNum, scrollDeltaY); - - // detaching thread not required - daemon - // NewtCommon_ReleaseJNIEnv(shallBeDetached); -} - -- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p -{ - NSRect viewFrame = [self frame]; - - NSRect r; - r.origin.x = p.x; - r.origin.y = p.y; - r.size.width = 0; - r.size.height = 0; - // NSRect rS = [[self window] convertRectFromScreen: r]; // 10.7 - NSPoint oS = [[self window] convertScreenToBase: r.origin]; - oS.y = viewFrame.size.height - oS.y; // y-flip - return oS; -} - -- (void) handleFlagsChanged:(NSUInteger) mods -{ - [self handleFlagsChanged: NSShiftKeyMask keyIndex: 0 keyCode: kVK_Shift modifiers: mods]; - [self handleFlagsChanged: NSControlKeyMask keyIndex: 1 keyCode: kVK_Control modifiers: mods]; - [self handleFlagsChanged: NSAlternateKeyMask keyIndex: 2 keyCode: kVK_Option modifiers: mods]; - [self handleFlagsChanged: NSCommandKeyMask keyIndex: 3 keyCode: kVK_Command modifiers: mods]; -} - -- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods -{ - if ( NO == modsDown[keyIdx] && 0 != ( mods & keyMask ) ) { - modsDown[keyIdx] = YES; - [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_PRESSED]; - } else if ( YES == modsDown[keyIdx] && 0 == ( mods & keyMask ) ) { - modsDown[keyIdx] = NO; - [self sendKeyEvent: (jshort)keyCode characters: NULL modifiers: mods|keyMask eventType: (jshort)EVENT_KEY_RELEASED]; - } -} - -- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType -{ - jshort keyCode = (jshort) [event keyCode]; - NSString* chars = [event charactersIgnoringModifiers]; - NSUInteger mods = [event modifierFlags]; - [self sendKeyEvent: keyCode characters: chars modifiers: mods eventType: evType]; -} - -- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType -{ - if (javaWindowObject == NULL) { - DBG_PRINT("sendKeyEvent: null javaWindowObject\n"); - return; - } - int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); - if(NULL==env) { - DBG_PRINT("sendKeyEvent: null JNIEnv\n"); - return; - } - - int i; - int len = NULL != chars ? [chars length] : 0; - jint javaMods = mods2JavaMods(mods); - - if(len > 0) { - // printable chars - for (i = 0; i < len; i++) { - // Note: the key code in the NSEvent does not map to anything we can use - UniChar keyChar = (UniChar) [chars characterAtIndex: i]; - UniChar keySymChar = CKCH_CharForKeyCode(keyCode); - - DBG_PRINT("sendKeyEvent: %d/%d code 0x%X, char 0x%X, mods 0x%X/0x%X -> keySymChar 0x%X\n", i, len, (int)keyCode, (int)keyChar, - (int)mods, (int)javaMods, (int)keySymChar); - - (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE, - evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar); - } - } else { - // non-printable chars - jchar keyChar = (jchar) 0; - - DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode); - - (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE, - evType, javaMods, keyCode, keyChar, keyChar); - } - - // detaching thread not required - daemon - // NewtCommon_ReleaseJNIEnv(shallBeDetached); -} - -- (void)viewDidChangeBackingProperties -{ - [super viewDidChangeBackingProperties]; - - // HiDPI scaling - BOOL useHiDPI = false; - CGFloat maxPixelScale = 1.0; - CGFloat winPixelScale = 1.0; - NSWindow* window = [self window]; - NSScreen* screen = [window screen]; -NS_DURING - maxPixelScale = [screen backingScaleFactor]; - useHiDPI = [self wantsBestResolutionOpenGLSurface]; - if( useHiDPI ) { - winPixelScale = [window backingScaleFactor]; - } -NS_HANDLER -NS_ENDHANDLER - DBG_PRINT("viewDidChangeBackingProperties: PixelScale: HiDPI %d, max %f, window %f\n", useHiDPI, (float)maxPixelScale, (float)winPixelScale); - [[self layer] setContentsScale: winPixelScale]; - - if (javaWindowObject == NULL) { - DBG_PRINT("viewDidChangeBackingProperties: null javaWindowObject\n"); - return; - } - int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); - if(NULL==env) { - DBG_PRINT("viewDidChangeBackingProperties: null JNIEnv\n"); - return; - } - - (*env)->CallVoidMethod(env, javaWindowObject, updatePixelScaleID, JNI_TRUE, (jfloat)winPixelScale, (jfloat)maxPixelScale); // defer - - // detaching thread not required - daemon - // NewtCommon_ReleaseJNIEnv(shallBeDetached); -} - - -@end - -@implementation NewtMacWindow - -+ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz -{ - enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)V"); - enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)V"); - sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V"); - updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZFF)V"); - visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V"); - insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V"); - sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZZ)V"); - screenPositionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V"); - focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V"); - windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z"); - windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V"); - requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V"); - if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && updatePixelScaleID && visibleChangedID && - insetsChangedID && sizeScreenPosInsetsChangedID && - screenPositionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID) - { - CKCH_CreateDictionaries(); - return YES; - } - return NO; -} - -- (id) initWithContentRect: (NSRect) contentRect - styleMask: (NSUInteger) windowStyle - backing: (NSBackingStoreType) bufferingType - defer: (BOOL) deferCreation - isFullscreenWindow:(BOOL)isfs -{ - id res = [super initWithContentRect: contentRect - styleMask: windowStyle - backing: bufferingType - defer: deferCreation]; - // OSX 10.6 - if ( [NSApp respondsToSelector:@selector(currentSystemPresentationOptions)] && - [NSApp respondsToSelector:@selector(setPresentationOptions:)] ) { - hasPresentationSwitch = YES; - defaultPresentationOptions = [NSApp currentSystemPresentationOptions]; - fullscreenPresentationOptions = - // NSApplicationPresentationDefault| - // NSApplicationPresentationAutoHideDock| - NSApplicationPresentationHideDock| - // NSApplicationPresentationAutoHideMenuBar| - NSApplicationPresentationHideMenuBar| - NSApplicationPresentationDisableAppleMenu| - // NSApplicationPresentationDisableProcessSwitching| - // NSApplicationPresentationDisableSessionTermination| - NSApplicationPresentationDisableHideApplication| - // NSApplicationPresentationDisableMenuBarTransparency| - // NSApplicationPresentationFullScreen| // OSX 10.7 - 0 ; - } else { - hasPresentationSwitch = NO; - defaultPresentationOptions = 0; - fullscreenPresentationOptions = 0; - } - - isFullscreenWindow = isfs; - // Why is this necessary? Without it we don't get any of the - // delegate methods like resizing and window movement. - [self setDelegate: self]; - - cachedInsets[0] = 0; // l - cachedInsets[1] = 0; // r - cachedInsets[2] = 0; // t - cachedInsets[3] = 0; // b - - realized = YES; - withinLiveResize = JNI_FALSE; - DBG_PRINT("NewtWindow::create: %p, realized %d, hasPresentationSwitch %d[defaultOptions 0x%X, fullscreenOptions 0x%X], (refcnt %d)\n", - res, realized, (int)hasPresentationSwitch, (int)defaultPresentationOptions, (int)fullscreenPresentationOptions, (int)[res retainCount]); - return res; -} - -#ifdef DBG_LIFECYCLE -- (void) release -{ - DBG_PRINT("NewtWindow::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]); - // NSLog(@"%@",[NSThread callStackSymbols]); - [super release]; -} -#endif - -- (void) dealloc -{ - DBG_PRINT("NewtWindow::dealloc.0: %p (refcnt %d)\n", self, (int)[self retainCount]); -#ifdef DBG_LIFECYCLE - NSLog(@"%@",[NSThread callStackSymbols]); -#endif - - NewtView* mView = (NewtView *)[self contentView]; - if( NULL != mView ) { - [mView release]; - } - [super dealloc]; - DBG_PRINT("NewtWindow::dealloc.X: %p\n", self); -} - -- (void) setRealized: (BOOL)v -{ - realized = v; -} - -- (BOOL) isRealized -{ - return realized; -} - -- (void) setAlwaysOn: (BOOL)top bottom:(BOOL)bottom -{ - if( top ) { - DBG_PRINT( "*************** setAlwaysOn -> top\n"); - [self setLevel: kCGMaximumWindowLevel]; - } else if ( bottom ) { - DBG_PRINT( "*************** setAlwaysOn -> bottom\n"); - [self setLevel: kCGDesktopIconWindowLevel]; // w/ input - } else { - DBG_PRINT( "*************** setAlwaysOn -> normal\n"); - [self setLevel:NSNormalWindowLevel]; - } -} - -- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin -{ - NSRect frameRect = [self frame]; - NSRect contentRect = [self contentRectForFrameRect: frameRect]; - - // note: this is a simplistic implementation which doesn't take - // into account DPI and scaling factor - CGFloat l = contentRect.origin.x - frameRect.origin.x; - cachedInsets[0] = (int)l; // l - cachedInsets[1] = (int)(frameRect.size.width - (contentRect.size.width + l)); // r - cachedInsets[2] = (jint)(frameRect.size.height - contentRect.size.height); // t - cachedInsets[3] = (jint)(contentRect.origin.y - frameRect.origin.y); // b - - DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", 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) updateSizePosInsets: (JNIEnv*) env jwin: (jobject) javaWin defer: (jboolean)defer -{ - // update insets on every window resize for lack of better hook place - [self updateInsets: NULL jwin:NULL]; - - NSRect frameRect = [self frame]; - NSRect contentRect = [self contentRectForFrameRect: frameRect]; - - DBG_PRINT( "updateSize: [ w %d, h %d ], liveResize %d\n", (jint) contentRect.size.width, (jint) contentRect.size.height, (jint)withinLiveResize); - - NSPoint p0 = { 0, 0 }; - p0 = [self getLocationOnScreen: p0]; - - DBG_PRINT( "updatePos: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y); - - if( NULL != env && NULL != javaWin ) { - (*env)->CallVoidMethod(env, javaWin, sizeScreenPosInsetsChangedID, defer, - (jint) p0.x, (jint) p0.y, - (jint) contentRect.size.width, (jint) contentRect.size.height, - cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3], - JNI_FALSE, // force - withinLiveResize - ); - } -} - - -- (void) attachToParent: (NSWindow*) parent -{ - DBG_PRINT( "attachToParent.1\n"); - [parent addChildWindow: self ordered: NSWindowAbove]; - DBG_PRINT( "attachToParent.2\n"); - [self setParentWindow: parent]; - DBG_PRINT( "attachToParent.X\n"); -} - -- (void) detachFromParent: (NSWindow*) parent -{ - DBG_PRINT( "detachFromParent.1\n"); - [self setParentWindow: nil]; - if(NULL != parent) { - DBG_PRINT( "detachFromParent.2\n"); - [parent removeChildWindow: self]; - } - DBG_PRINT( "detachFromParent.X\n"); -} - -/** - * p abs screen position of client-area pos w/ top-left origin, using contentView's client NSSize - * returns: abs screen position w/ bottom-left origin - */ -- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p -{ - NSView* mView = [self contentView]; - NSRect mViewFrame = [mView frame]; - return [self newtAbsClientTLWinPos2AbsBLScreenPos: p size: mViewFrame.size]; -} - -/** - * p abs screen position of client-area pos w/ top-left origin, using given client NSSize - * returns: abs screen position w/ bottom-left origin - */ -- (NSPoint) newtAbsClientTLWinPos2AbsBLScreenPos: (NSPoint) p size: (NSSize) nsz -{ - int totalHeight = nsz.height + cachedInsets[3]; // height + insets.bottom - - DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: point-in[%d/%d], size-in[%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]; - - CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); - CGRect frameTL = CGDisplayBounds (display); // origin top-left - NSRect frameBL = [screen frame]; // origin bottom-left - NSPoint r = NSMakePoint(p.x, frameBL.origin.y + frameBL.size.height - ( p.y - frameTL.origin.y ) - totalHeight); // y-flip from TL-screen -> BL-screen - - DBG_PRINT( "newtAbsClientTLWinPos2AbsBLScreenPos: screen tl[%d/%d %dx%d] bl[%d/%d %dx%d -> %d/%d\n", - (int)frameTL.origin.x, (int)frameTL.origin.y, (int)frameTL.size.width, (int)frameTL.size.height, - (int)frameBL.origin.x, (int)frameBL.origin.y, (int)frameBL.size.width, (int)frameBL.size.height, - (int)r.x, (int)r.y); - - return r; -} - -/** - * p rel client window position w/ top-left origin - * returns: abs screen position w/ bottom-left origin - */ -- (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p -{ - NSRect winFrame = [self frame]; - - NSView* mView = [self contentView]; - NSRect mViewFrame = [mView frame]; - NSPoint r = NSMakePoint(winFrame.origin.x + p.x, - winFrame.origin.y + ( mViewFrame.size.height - p.y ) ); // y-flip in view - - DBG_PRINT( "newtRelClientTLWinPos2AbsBLScreenPos: point-in[%d/%d], winFrame[%d/%d %dx%d], viewFrame[%d/%d %dx%d] -> %d/%d\n", - (int)p.x, (int)p.y, - (int)winFrame.origin.x, (int)winFrame.origin.y, (int)winFrame.size.width, (int)winFrame.size.height, - (int)mViewFrame.origin.x, (int)mViewFrame.origin.y, (int)mViewFrame.size.width, (int)mViewFrame.size.height, - (int)r.x, (int)r.y); - - return r; -} - -- (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 - * returns: location in 0/0 top-left space. - */ -- (NSPoint) getLocationOnScreen: (NSPoint) p -{ - NSView* view = [self contentView]; - NSRect viewFrame = [view frame]; - NSRect r; - r.origin.x = p.x; - r.origin.y = viewFrame.size.height - p.y; // y-flip - r.size.width = 0; - r.size.height = 0; - // NSRect rS = [self convertRectToScreen: r]; // 10.7 - NSPoint oS = [self convertBaseToScreen: r.origin]; // BL-screen - - NSScreen* screen = [self screen]; - CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); - CGRect frameTL = CGDisplayBounds (display); // origin top-left - NSRect frameBL = [screen frame]; // origin bottom-left - oS.y = frameTL.origin.y + frameTL.size.height - ( oS.y - frameBL.origin.y ); // y-flip from BL-screen -> TL-screen - -#ifdef VERBOSE_ON - NSRect winFrame = [self frame]; - DBG_PRINT( "getLocationOnScreen: point-in[%d/%d], winFrame[%d/%d %dx%d], viewFrame[%d/%d %dx%d], screen tl[%d/%d %dx%d] bl[%d/%d %dx%d] -> %d/%d\n", - (int)p.x, (int)p.y, - (int)winFrame.origin.x, (int)winFrame.origin.y, (int)winFrame.size.width, (int)winFrame.size.height, - (int)viewFrame.origin.x, (int)viewFrame.origin.y, (int)viewFrame.size.width, (int)viewFrame.size.height, - (int)frameTL.origin.x, (int)frameTL.origin.y, (int)frameTL.size.width, (int)frameTL.size.height, - (int)frameBL.origin.x, (int)frameBL.origin.y, (int)frameBL.size.width, (int)frameBL.size.height, - (int)oS.x, (int)oS.y); -#endif - - return oS; -} - -- (void) focusChanged: (BOOL) gained -{ - DBG_PRINT( "focusChanged: gained %d\n", gained); - NewtView* newtView = (NewtView *) [self contentView]; - if( ! [newtView isKindOfClass:[NewtView class]] ) { - return; - } - jobject javaWindowObject = [newtView getJavaWindowObject]; - if (javaWindowObject == NULL) { - DBG_PRINT("focusChanged: null javaWindowObject\n"); - return; - } - int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); - if(NULL==env) { - DBG_PRINT("focusChanged: null JNIEnv\n"); - return; - } - - (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE); - - // detaching thread not required - daemon - // NewtCommon_ReleaseJNIEnv(shallBeDetached); -} - -- (void) keyDown: (NSEvent*) theEvent -{ - NewtView* newtView = (NewtView *) [self contentView]; - if( [newtView isKindOfClass:[NewtView class]] ) { - [newtView sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_PRESSED]; - } -} - -- (void) keyUp: (NSEvent*) theEvent -{ - NewtView* newtView = (NewtView *) [self contentView]; - if( [newtView isKindOfClass:[NewtView class]] ) { - [newtView sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_RELEASED]; - } -} - -- (void) flagsChanged:(NSEvent *) theEvent -{ - NSUInteger mods = [theEvent modifierFlags]; - NewtView* newtView = (NewtView *) [self contentView]; - if( [newtView isKindOfClass:[NewtView class]] ) { - [newtView handleFlagsChanged: mods]; - } -} - -- (BOOL) acceptsMouseMovedEvents -{ - return YES; -} - -- (BOOL) acceptsFirstResponder -{ - return YES; -} - -- (BOOL) becomeFirstResponder -{ - DBG_PRINT( "*************** Win.becomeFirstResponder\n"); - return [super becomeFirstResponder]; -} - -- (BOOL) resignFirstResponder -{ - DBG_PRINT( "*************** Win.resignFirstResponder\n"); - return [super resignFirstResponder]; -} - -- (BOOL) canBecomeKeyWindow -{ - // Even if the window is borderless, we still want it to be able - // to become the key window to receive keyboard events - return YES; -} - -- (void) becomeKeyWindow -{ - DBG_PRINT( "*************** becomeKeyWindow\n"); - [super becomeKeyWindow]; -} - -- (void) resignKeyWindow -{ - DBG_PRINT( "*************** resignKeyWindow: isFullscreen %d\n", (int)isFullscreenWindow); - if(!isFullscreenWindow) { - [super resignKeyWindow]; - } -} - -- (void) windowDidBecomeKey: (NSNotification *) notification -{ - DBG_PRINT( "*************** windowDidBecomeKey\n"); - NewtView* newtView = (NewtView *) [self contentView]; - if( [newtView isKindOfClass:[NewtView class]] ) { - BOOL mouseInside = [newtView updateMouseInside]; - if(YES == mouseInside) { - [newtView cursorHide: ![newtView isMouseVisible] enter: 1]; - } - } - [self focusChanged: YES]; -} - -- (void) windowDidResignKey: (NSNotification *) notification -{ - DBG_PRINT( "*************** windowDidResignKey\n"); - // Implicit mouse exit by OS X - [self focusChanged: NO]; -} - -- (void) windowWillStartLiveResize: (NSNotification *) notification -{ - DBG_PRINT( "*************** windowWillStartLiveResize\n"); - withinLiveResize = JNI_TRUE; -} -- (void) windowDidEndLiveResize: (NSNotification *) notification -{ - DBG_PRINT( "*************** windowDidEndLiveResize\n"); - withinLiveResize = JNI_FALSE; - [self sendResizeEvent]; -} -- (NSSize) windowWillResize: (NSWindow *)sender toSize:(NSSize)frameSize -{ - DBG_PRINT( "*************** windowWillResize %lfx%lf\n", frameSize.width, frameSize.height); - return frameSize; -} -- (void)windowDidResize: (NSNotification*) notification -{ - DBG_PRINT( "*************** windowDidResize\n"); - [self sendResizeEvent]; -} - -- (void) sendResizeEvent -{ - jobject javaWindowObject = NULL; - int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); - - if( NULL == env ) { - DBG_PRINT("windowDidResize: null JNIEnv\n"); - return; - } - NewtView* newtView = (NewtView *) [self contentView]; - if( [newtView isKindOfClass:[NewtView class]] ) { - javaWindowObject = [newtView getJavaWindowObject]; - } - if( NULL != javaWindowObject ) { - [self updateSizePosInsets: env jwin: javaWindowObject defer:JNI_TRUE]; - } - // detaching thread not required - daemon - // NewtCommon_ReleaseJNIEnv(shallBeDetached); -} - -- (void)windowDidMove: (NSNotification*) notification -{ - NewtView* newtView = (NewtView *) [self contentView]; - if( ! [newtView isKindOfClass:[NewtView class]] ) { - return; - } - jobject javaWindowObject = [newtView getJavaWindowObject]; - if (javaWindowObject == NULL) { - DBG_PRINT("windowDidMove: null javaWindowObject\n"); - return; - } - int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); - if(NULL==env) { - DBG_PRINT("windowDidMove: null JNIEnv\n"); - return; - } - - NSPoint p0 = { 0, 0 }; - p0 = [self getLocationOnScreen: p0]; - DBG_PRINT( "windowDidMove: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y); - (*env)->CallVoidMethod(env, javaWindowObject, screenPositionChangedID, JNI_TRUE, (jint) p0.x, (jint) p0.y); - - // detaching thread not required - daemon - // NewtCommon_ReleaseJNIEnv(shallBeDetached); -} - -- (BOOL)windowShouldClose: (id) sender -{ - return [self windowClosingImpl: NO]; -} - -- (void)windowWillClose: (NSNotification*) notification -{ - [self windowClosingImpl: YES]; -} - -- (BOOL) windowClosingImpl: (BOOL) force -{ - jboolean closed = JNI_FALSE; - - NewtView* newtView = (NewtView *) [self contentView]; - if( ! [newtView isKindOfClass:[NewtView class]] ) { - return NO; - } - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - [newtView cursorHide: NO enter: -1]; - - if( false == [newtView getDestroyNotifySent] ) { - jobject javaWindowObject = [newtView getJavaWindowObject]; - DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject); - if (javaWindowObject == NULL) { - DBG_PRINT("windowWillClose: null javaWindowObject\n"); - [pool release]; - return NO; - } - int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); - if(NULL==env) { - DBG_PRINT("windowWillClose: null JNIEnv\n"); - [pool release]; - return NO; - } - [newtView setDestroyNotifySent: true]; // earmark assumption of being closed - closed = (*env)->CallBooleanMethod(env, javaWindowObject, windowDestroyNotifyID, force ? JNI_TRUE : JNI_FALSE); - if(!force && !closed) { - // not closed on java side, not force -> clear flag - [newtView setDestroyNotifySent: false]; - } - - // detaching thread not required - daemon - // NewtCommon_ReleaseJNIEnv(shallBeDetached); - DBG_PRINT( "*************** windowWillClose.X: %p, closed %d\n", (void *)(intptr_t)javaWindowObject, (int)closed); - } else { - DBG_PRINT( "*************** windowWillClose (skip)\n"); - } - [pool release]; - return JNI_TRUE == closed ? YES : NO ; -} - -@end - -- cgit v1.2.3