aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/native
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-01-04 17:15:04 +0100
committerSven Gothel <[email protected]>2014-01-04 17:15:04 +0100
commitfcc0e7397bb6f3ceb1fe143667f8c59b5bf63874 (patch)
treefbb8225c6408cfe6bf17cccdfeafbc293d126e39 /src/newt/native
parente3cf96249f4c722f8b2a7d0e052e19165cef171e (diff)
Bug 935: NEWT PointerIcon: Refine Spec and Implementation / Fix OSX Crash and Issues
- Refine Display.PointerIcon: Complete type allowing re-creation - Add associated Display reference - Add used IOUtil.ClassResources reference - Add isValid()/validate() methods for recreation - Refine API doc - Move Display.destroyPointerIcon(PointerIcon) -> PointerIcon.destroy() - Move DisplayImpl.PointerIconImpl -> PointerIconImpl (own source file) - Creation/Destruction and setting of PointerIcon happens on EDT - DisplayImpl.shutdownAll() and Display.destroy() calls destroyAllPointerIconFromList - WindowDriver.setPointerIconImpl: Validates PointerIconImpl (i.e. re-creates if required) - Fix 'initial' window.setPointerIcon(..) before createNative(..), tested w/ TestGearsES2NEWT - OSX Native Code: - Move mouse and pointer-state handling from NewtMacWindow -> NewtView class to retain states (pointer handle, pointer visibility, etc) when reparenting. Reparenting will move an exisiting NewtView into a new NewtMacWindow. - Enable all mouse move events: - NewtView::mouseEnter [nsWin makeFirstResponder: nsView]; - NewtView::mouseExited if( !mouseConfined ) { [nsView resignFirstResponder]; } - NewtView::mouseMoved issued [myCurser set] if required, fixing OSX issue not updating NSCursor properly. - MacWindow: - Test NewtMacWindow, NewtView and NSCursor handles before usage - Fix DBG_PRINT(..) warnings
Diffstat (limited to 'src/newt/native')
-rw-r--r--src/newt/native/MacWindow.m113
-rw-r--r--src/newt/native/NewtMacWindow.h86
-rw-r--r--src/newt/native/NewtMacWindow.m1017
3 files changed, 652 insertions, 564 deletions
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index 1be3a6ed5..eb5913706 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -347,30 +347,14 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_createPoint
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_destroyPointerIcon0
(JNIEnv *env, jobject unused, jlong handle)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSCursor * c = (NSCursor*) (intptr_t) handle ;
- if( NULL != c ) {
- if ( NO == [c isKindOfClass:[NSCursor class]] ) {
- DBG_PRINT( "destroyPointerIcon0 NSCursor %p - is of invalid type\n", c);
- } else {
- DBG_PRINT( "destroyPointerIcon0 %p\n", c);
- [c release];
- }
+ if( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
+ DBG_PRINT( "Not a NSCursor %p\n", c);
+ return;
}
- [pool release];
-}
-
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIcon0
- (JNIEnv *env, jobject unused, jlong window, jlong handle)
-{
+ DBG_PRINT( "destroyPointerIcon0 %p\n", c);
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window;
- NSCursor * c = (NSCursor*) (intptr_t) handle ;
- if ( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
- DBG_PRINT( "setPointerIcon0 NSCursor %p - is of invalid type (1)\n", c);
- } else {
- [mWin setPointerIcon: c];
- }
+ [c release];
[pool release];
}
@@ -717,7 +701,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0
NSRect rectView = NSMakeRect(0, 0, w, h);
NewtView *myView = [[NewtView alloc] initWithFrame: rectView] ;
- DBG_PRINT( "createView0.X.%d - new view: %p\n", myView);
+ DBG_PRINT( "createView0.X - new view: %p\n", myView);
[pool release];
@@ -738,7 +722,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtView* myView = (NewtView*) (intptr_t) jview ;
- DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, screenidx %d, view %p (START)\n",
+ 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;
@@ -865,6 +849,7 @@ NS_ENDHANDLER
// Set the content view
changeContentView(env, jthis, parentView, myWindow, myView, NO);
+ [myWindow setInitialFirstResponder: myView];
DBG_PRINT( "initWindow0.%d - %p view %p, isVisible %d\n",
dbgIdx++, myWindow, myView, [myWindow isVisible]);
@@ -965,7 +950,6 @@ NS_ENDHANDLER
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0
(JNIEnv *env, jobject unused, jlong window)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
if( NULL == mWin ) {
DBG_PRINT( "windowClose.0 - NULL NEWT win - abort\n");
@@ -979,6 +963,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0
DBG_PRINT( "windowClose.0 - Not a NEWT win - abort\n");
return;
}
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtView* mView = (NewtView *)[mWin contentView];
BOOL fullscreen = mWin->isFullscreenWindow;
BOOL destroyNotifySent, isNSView, isNewtView;
@@ -1093,6 +1078,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0
#endif
DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus);
+ [mWin setAcceptsMouseMovedEvents: YES];
[mWin makeFirstResponder: nil];
[mWin orderFrontRegardless];
[mWin makeKeyWindow];
@@ -1331,18 +1317,39 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocatio
(JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y)
{
NSObject *nsObj = (NSObject*) ((intptr_t) win);
- NewtMacWindow * mWin = NULL;
-
- if( [nsObj isKindOfClass:[NewtMacWindow class]] ) {
- mWin = (NewtMacWindow*) nsObj;
- } else {
- NewtCommon_throwNewRuntimeException(env, "not NewtMacWindow %p\n", nsObj);
+ NewtMacWindow * mWin = (NewtMacWindow*) nsObj;
+ if( ![mWin isKindOfClass:[NewtMacWindow class]] ) {
+ DBG_PRINT("Not a NewtMacWindow %p\n", nsObj);
+ return NULL;
}
-
NSPoint p0 = [mWin getLocationOnScreen: NSMakePoint(src_x, src_y)];
return (*env)->NewObject(env, pointClz, pointCstr, (jint)p0.x, (jint)p0.y);
}
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIcon0
+ (JNIEnv *env, jobject unused, jlong window, jlong handle)
+{
+ NSCursor *c = (NSCursor*) (intptr_t) handle ;
+ if ( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
+ DBG_PRINT("Not a NSCursor %p\n", c);
+ return JNI_FALSE;
+ }
+ NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window;
+ if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+ DBG_PRINT("Not a NewtMacWindow %p\n", mWin);
+ return JNI_FALSE;
+ }
+ NewtView* nView = (NewtView *) [mWin contentView];
+ if( ! [nView isKindOfClass:[NewtView class]] ) {
+ DBG_PRINT("Not a NewtView %p\n", nView);
+ return JNI_FALSE;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [nView setPointerIcon: c];
+ [pool release];
+ return JNI_TRUE;
+}
+
/*
* Class: Java_jogamp_newt_driver_macosx_WindowDriver
* Method: setPointerVisible0
@@ -1351,10 +1358,19 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocatio
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVisible0
(JNIEnv *env, jclass clazz, jlong window, jboolean hasFocus, jboolean mouseVisible)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
- [mWin setMouseVisible: ( JNI_TRUE == mouseVisible ) ? YES : NO
- hasFocus: ( JNI_TRUE == hasFocus ) ? YES : NO];
+ if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+ DBG_PRINT("Not a NewtMacWindow %p\n", mWin);
+ return JNI_FALSE;
+ }
+ NewtView* nView = (NewtView *) [mWin contentView];
+ if( ! [nView isKindOfClass:[NewtView class]] ) {
+ DBG_PRINT("Not a NewtView %p\n", nView);
+ return JNI_FALSE;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [nView setMouseVisible: ( JNI_TRUE == mouseVisible ) ? YES : NO
+ hasFocus: ( JNI_TRUE == hasFocus ) ? YES : NO];
[pool release];
return JNI_TRUE;
}
@@ -1367,9 +1383,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointe
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointer0
(JNIEnv *env, jclass clazz, jlong window, jboolean confine)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
- [mWin setMouseConfined: ( JNI_TRUE == confine ) ? YES : NO];
+ if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+ DBG_PRINT("Not a NewtMacWindow %p\n", mWin);
+ return JNI_FALSE;
+ }
+ NewtView* nView = (NewtView *) [mWin contentView];
+ if( ! [nView isKindOfClass:[NewtView class]] ) {
+ DBG_PRINT("Not a NewtView %p\n", nView);
+ return JNI_FALSE;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [nView setMouseConfined: ( JNI_TRUE == confine ) ? YES : NO];
[pool release];
return JNI_TRUE;
}
@@ -1379,12 +1404,22 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePo
* Method: warpPointer0
* Signature: (JJII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0
(JNIEnv *env, jclass clazz, jlong window, jint x, jint y)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
- [mWin setMousePosition: [mWin newtRelClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]];
+ if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
+ DBG_PRINT("Not a NewtMacWindow %p\n", mWin);
+ return JNI_FALSE;
+ }
+ NewtView* nView = (NewtView *) [mWin contentView];
+ if( ! [nView isKindOfClass:[NewtView class]] ) {
+ DBG_PRINT("Not a NewtView %p\n", nView);
+ return JNI_FALSE;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [nView setMousePosition: [mWin newtRelClientTLWinPos2AbsBLScreenPos: NSMakePoint(x, y)]];
[pool release];
+ return JNI_TRUE;
}
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index 2728c2201..daf75bec7 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -63,6 +63,14 @@
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;
@@ -83,9 +91,6 @@
- (void) setJavaWindowObject: (jobject) javaWindowObj;
- (jobject) getJavaWindowObject;
-- (void) rightMouseDown: (NSEvent*) theEvent;
-- (void) resetCursorRects;
-
- (void) setDestroyNotifySent: (BOOL) v;
- (BOOL) getDestroyNotifySent;
@@ -99,6 +104,41 @@
- (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;
@end
@@ -108,14 +148,7 @@
@interface NewtMacWindow : NSWindow
#endif
{
- BOOL mouseConfined;
- BOOL mouseVisible;
- BOOL mouseInside;
- BOOL cursorIsHidden;
- NSCursor * customCursor;
BOOL realized;
- BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
- NSPoint lastInsideMousePosition;
@public
BOOL hasPresentationSwitch;
NSUInteger defaultPresentationOptions;
@@ -147,20 +180,14 @@
- (NSPoint) newtRelClientTLWinPos2AbsBLScreenPos: (NSPoint) p;
- (NSSize) newtClientSize2TLSize: (NSSize) nsz;
- (NSPoint) getLocationOnScreen: (NSPoint) p;
-- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p;
-- (BOOL) isMouseInside;
-- (void) cursorHide:(BOOL)v enter:(int)enterState;
-- (void) setPointerIcon:(NSCursor*)c;
-- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus;
-- (void) setMouseConfined:(BOOL)v;
-- (void) setMousePosition:(NSPoint)p;
-
-- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType;
-- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType;
-- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType;
- (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;
@@ -168,22 +195,7 @@
- (void) resignKeyWindow;
- (void) windowDidBecomeKey: (NSNotification *) notification;
- (void) windowDidResignKey: (NSNotification *) notification;
-- (void) keyDown: (NSEvent*) theEvent;
-- (void) keyUp: (NSEvent*) theEvent;
-- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods;
-- (void) flagsChanged: (NSEvent *) theEvent;
-- (void) mouseEntered: (NSEvent*) theEvent;
-- (void) mouseExited: (NSEvent*) theEvent;
-- (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) otherMouseUp: (NSEvent*) theEvent;
+
- (void) windowDidResize: (NSNotification*) notification;
- (void) windowDidMove: (NSNotification*) notification;
- (BOOL) windowClosingImpl: (BOOL) force;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 96965b67a..5ccd9c658 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -86,6 +86,88 @@ static jfloat GetDelta(NSEvent *event, jint javaMods[]) {
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);
+ 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();
+ 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;
@@ -122,6 +204,16 @@ static jmethodID windowRepaintID = NULL;
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;
@@ -144,10 +236,9 @@ static jmethodID windowRepaintID = NULL;
if( 0 < softLockCount ) {
NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n");
}
- if(0 != ptrTrackingTag) {
- [self removeTrackingRect: ptrTrackingTag];
- ptrTrackingTag = 0;
- }
+ [self removeCursorRects];
+ [self removeMyCursor];
+
pthread_mutex_destroy(&softLockSync);
DBG_PRINT("NewtView::dealloc.X: %p\n", self);
[super dealloc];
@@ -182,26 +273,6 @@ static jmethodID windowRepaintID = NULL;
return javaWindowObject;
}
-- (void) rightMouseDown: (NSEvent*) theEvent
-{
- NSResponder* next = [self nextResponder];
- if (next != nil) {
- [next rightMouseDown: theEvent];
- }
-}
-
-- (void) resetCursorRects
-{
- [super resetCursorRects];
-
- if(0 != ptrTrackingTag) {
- [self removeTrackingRect: ptrTrackingTag];
- ptrTrackingTag = 0;
- }
- ptrRect = [self bounds];
- ptrTrackingTag = [self addTrackingRect: ptrRect owner: self userData: nil assumeInside: NO];
-}
-
- (void) setDestroyNotifySent: (BOOL) v
{
destroyNotifySent = v;
@@ -337,67 +408,397 @@ static jmethodID windowRepaintID = NULL;
return YES;
}
-@end
+- (BOOL) becomeFirstResponder
+{
+ DBG_PRINT( "*************** View.becomeFirstResponder\n");
+ return [super becomeFirstResponder];
+}
-static CFStringRef CKCH_CreateStringForKey(CGKeyCode keyCode, const UCKeyboardLayout *keyboardLayout) {
- UInt32 keysDown = 0;
- UniChar chars[4];
- UniCharCount realLength;
+- (BOOL) resignFirstResponder
+{
+ DBG_PRINT( "*************** View.resignFirstResponder\n");
+ return [super resignFirstResponder];
+}
- UCKeyTranslate(keyboardLayout, keyCode,
- kUCKeyActionDisplay, 0,
- LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
- &keysDown, sizeof(chars) / sizeof(chars[0]), &realLength, chars);
+- (void) removeCursorRects
+{
+ if(0 != ptrTrackingTag) {
+ if(NULL != myCursor) {
+ [self removeCursorRect: ptrRect cursor: myCursor];
+ }
+ [self removeTrackingRect: ptrTrackingTag];
+ ptrTrackingTag = 0;
+ }
+}
- return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
+- (void) addCursorRects
+{
+ ptrRect = [self bounds];
+ if(NULL != myCursor) {
+ [self addCursorRect: ptrRect cursor: myCursor];
+ }
+ ptrTrackingTag = [self addTrackingRect: ptrRect owner: self userData: nil assumeInside: NO];
}
-static CFMutableDictionaryRef CKCH_CreateCodeToCharDict(TISInputSourceRef keyboard) {
- CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData);
- const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+- (void) removeMyCursor
+{
+ if(NULL != myCursor) {
+ [myCursor release];
+ myCursor = NULL;
+ }
+}
- 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);
- }
+- (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];
}
}
- return codeToCharDict;
+ NSWindow* nsWin = [self window];
+ if( NULL != nsWin ) {
+ [nsWin invalidateCursorRectsForView: self];
+ }
}
-static CFMutableDictionaryRef CKCH_USCodeToNNChar = NULL;
+- (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];
+ }
+}
-static void CKCH_CreateDictionaries() {
- TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
- CKCH_USCodeToNNChar = CKCH_CreateCodeToCharDict(currentKeyboard);
- CFRelease(currentKeyboard);
+- (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];
+ }
}
-static UniChar CKCH_CharForKeyCode(jshort keyCode) {
- UniChar rChar = 0;
+- (void) setMousePosition:(NSPoint)p
+{
+ NSWindow* nsWin = [self window];
+ if( NULL != nsWin ) {
+ NSScreen* screen = [nsWin screen];
+ NSRect screenRect = [screen frame];
- if ( NULL != CKCH_USCodeToNNChar ) {
- intptr_t code = (intptr_t) keyCode;
- intptr_t character = 0;
+ CGPoint pt = { p.x, screenRect.size.height - p.y }; // y-flip (CG is top-left origin)
+ CGEventRef ev = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, pt, kCGMouseButtonLeft);
+ CGEventPost (kCGHIDEventTap, ev);
+ }
+}
- 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);
+- (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;
}
}
- return rChar;
}
+- (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;
+ if( NULL != jvmHandle ) {
+ env = NewtCommon_GetJNIEnv(jvmHandle, [self getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ } else {
+ env = NULL;
+ }
+ if(NULL==env) {
+ DBG_PRINT("sendMouseEvent: JVM %p JNIEnv %p\n", jvmHandle, env);
+ 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 = 0;
+ 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;
+ }
+
+ 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);
+
+ /* if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ } */
+}
+
+- (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;
+ if( NULL != jvmHandle ) {
+ env = NewtCommon_GetJNIEnv(jvmHandle, [self getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ } else {
+ env = NULL;
+ }
+ if(NULL==env) {
+ DBG_PRINT("sendKeyEvent: JVM %p JNIEnv %p\n", jvmHandle, env);
+ 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);
+ }
+
+ /* if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ } */
+}
+
+@end
+
@implementation NewtMacWindow
+ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz
@@ -463,15 +864,6 @@ static UniChar CKCH_CharForKeyCode(jshort keyCode) {
cachedInsets[1] = 0; // r
cachedInsets[2] = 0; // t
cachedInsets[3] = 0; // b
- modsDown[0] = NO; // shift
- modsDown[1] = NO; // ctrl
- modsDown[2] = NO; // alt
- modsDown[3] = NO; // win
- mouseConfined = NO;
- mouseVisible = YES;
- mouseInside = NO;
- cursorIsHidden = NO;
- customCursor = NULL;
realized = YES;
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]);
@@ -633,311 +1025,82 @@ static UniChar CKCH_CharForKeyCode(jshort keyCode) {
return oS;
}
-- (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p
-{
- NSView* view = [self contentView];
- NSRect viewFrame = [view frame];
-
- NSRect r;
- r.origin.x = p.x;
- r.origin.y = p.y;
- r.size.width = 0;
- r.size.height = 0;
- // NSRect rS = [win convertRectFromScreen: r]; // 10.7
- NSPoint oS = [self convertScreenToBase: r.origin];
- oS.y = viewFrame.size.height - oS.y; // y-flip
- return oS;
-}
-
-- (BOOL) isMouseInside
-{
- NSView* view = [self contentView];
- NSRect viewFrame = [view frame];
- NSPoint l1 = [NSEvent mouseLocation];
- NSPoint l0 = [self screenPos2NewtClientWinPos: l1];
- return 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) ;
-}
-
-- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus
-{
- mouseVisible = v;
- mouseInside = [self isMouseInside];
- 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];
- }
-}
-
-- (void) setPointerIcon:(NSCursor*)c
-{
- DBG_PRINT( "setPointerIcon: mouseInside cursor: %p -> %p (glob %p), mouseInside %d\n", customCursor, c, [NSCursor currentCursor], (int)mouseInside);
- if(YES == mouseInside) {
- if( NULL != c ) {
- DBG_PRINT( "setPointerIcon push: %p\n", c);
- [c push];
- } else if( NULL != customCursor ) {
- if ( NO == [customCursor isKindOfClass:[NSCursor class]] ) {
- DBG_PRINT( "setPointerIcon0 NSCursor %p - is of invalid type (2)\n", customCursor);
- if( [NSCursor currentCursor] == customCursor ) {
- [NSCursor pop];
- }
- } else if( [NSCursor currentCursor] == customCursor ) {
- DBG_PRINT( "setPointerIcon pop: %p\n", customCursor);
- [customCursor pop];
- }
- }
- }
- customCursor = c;
-}
-
-- (void) cursorHide:(BOOL)v enter:(int)enterState
-{
- DBG_PRINT( "cursorHide: %d -> %d, enter %d\n", cursorIsHidden, v, enterState);
- if( NULL != customCursor ) {
- if ( NO == [customCursor isKindOfClass:[NSCursor class]] ) {
- DBG_PRINT( "setPointerIcon0 NSCursor %p - is of invalid type (3)\n", customCursor);
- if( [NSCursor currentCursor] == customCursor ) {
- [NSCursor pop];
- }
- } else {
- if( 1 == enterState && [NSCursor currentCursor] != customCursor ) {
- DBG_PRINT( "cursorHide.PointerIcon push: %p\n", customCursor);
- [customCursor push];
- } else if( -1 == enterState && [NSCursor currentCursor] == customCursor ) {
- DBG_PRINT( "cursorHide.PointerIcon pop: %p\n", customCursor);
- [customCursor pop];
- }
- }
- }
- 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) setMousePosition:(NSPoint)p
-{
- NSScreen* screen = [self screen];
- NSRect screenRect = [screen frame];
-
- CGPoint pt = { p.x, screenRect.size.height - p.y }; // y-flip (CG is top-left origin)
- CGEventRef ev = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, pt, kCGMouseButtonLeft);
- CGEventPost (kCGHIDEventTap, ev);
-}
-
-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;
-}
-
-- (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
+- (void) focusChanged: (BOOL) gained
{
- NSView* nsview = [self contentView];
- if( ! [nsview isKindOfClass:[NewtView class]] ) {
+ DBG_PRINT( "focusChanged: gained %d\n", gained);
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( ! [newtView isKindOfClass:[NewtView class]] ) {
return;
}
- NewtView* view = (NewtView *) nsview;
- jobject javaWindowObject = [view getJavaWindowObject];
+ jobject javaWindowObject = [newtView getJavaWindowObject];
if (javaWindowObject == NULL) {
- DBG_PRINT("sendKeyEvent: null javaWindowObject\n");
+ DBG_PRINT("focusChanged: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
- JavaVM *jvmHandle = [view getJVMHandle];
+ JavaVM *jvmHandle = [newtView getJVMHandle];
JNIEnv* env;
if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
} else {
env = NULL;
}
if(NULL==env) {
- DBG_PRINT("sendKeyEvent: JVM %p JNIEnv %p\n", jvmHandle, env);
+ DBG_PRINT("focusChanged: JVM %p JNIEnv %p\n", jvmHandle, env);
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 -> keySymChar 0x%X\n", i, len, (int)keyCode, (int)keyChar, (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);
- }
+ (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
/* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
} */
}
-- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType
+- (void) keyDown: (NSEvent*) theEvent
{
- NSView* nsview = [self contentView];
- if( ! [nsview isKindOfClass:[NewtView class]] ) {
- return;
- }
- NewtView* view = (NewtView *) nsview;
- jobject javaWindowObject = [view getJavaWindowObject];
- if (javaWindowObject == NULL) {
- DBG_PRINT("sendMouseEvent: null javaWindowObject\n");
- return;
- }
- int shallBeDetached = 0;
- JavaVM *jvmHandle = [view getJVMHandle];
- JNIEnv* env;
- if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
- } else {
- env = NULL;
- }
- if(NULL==env) {
- DBG_PRINT("sendMouseEvent: JVM %p JNIEnv %p\n", jvmHandle, env);
- 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 = 0;
- 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;
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( [newtView isKindOfClass:[NewtView class]] ) {
+ [newtView sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_PRESSED];
}
+}
- 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);
+- (void) keyUp: (NSEvent*) theEvent
+{
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( [newtView isKindOfClass:[NewtView class]] ) {
+ [newtView sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_RELEASED];
}
-
- NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]];
-
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, JNI_FALSE,
- evType, javaMods[0],
- (jint) location.x, (jint) location.y,
- javaButtonNum, scrollDeltaY);
-
- /* if (shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
- } */
}
-- (void) focusChanged: (BOOL) gained
+- (void) flagsChanged:(NSEvent *) theEvent
{
- DBG_PRINT( "focusChanged: gained %d\n", gained);
- NSView* nsview = [self contentView];
- if( ! [nsview isKindOfClass:[NewtView class]] ) {
- return;
- }
- NewtView* view = (NewtView *) nsview;
- jobject javaWindowObject = [view getJavaWindowObject];
- if (javaWindowObject == NULL) {
- DBG_PRINT("focusChanged: null javaWindowObject\n");
- return;
- }
- int shallBeDetached = 0;
- JavaVM *jvmHandle = [view getJVMHandle];
- JNIEnv* env;
- if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
- } else {
- env = NULL;
- }
- if(NULL==env) {
- DBG_PRINT("focusChanged: JVM %p JNIEnv %p\n", jvmHandle, env);
- return;
+ NSUInteger mods = [theEvent modifierFlags];
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( [newtView isKindOfClass:[NewtView class]] ) {
+ [newtView handleFlagsChanged: mods];
}
+}
- (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
+- (BOOL) acceptsMouseMovedEvents
+{
+ return YES;
+}
- /* if (shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
- } */
+- (BOOL) acceptsFirstResponder
+{
+ return YES;
}
- (BOOL) becomeFirstResponder
{
- DBG_PRINT( "*************** becomeFirstResponder\n");
+ DBG_PRINT( "*************** Win.becomeFirstResponder\n");
return [super becomeFirstResponder];
}
- (BOOL) resignFirstResponder
{
- DBG_PRINT( "*************** resignFirstResponder\n");
+ DBG_PRINT( "*************** Win.resignFirstResponder\n");
return [super resignFirstResponder];
}
@@ -965,9 +1128,12 @@ static jint mods2JavaMods(NSUInteger mods)
- (void) windowDidBecomeKey: (NSNotification *) notification
{
DBG_PRINT( "*************** windowDidBecomeKey\n");
- mouseInside = [self isMouseInside];
- if(YES == mouseInside) {
- [self cursorHide: !mouseVisible enter: 0];
+ 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];
}
@@ -979,128 +1145,6 @@ static jint mods2JavaMods(NSUInteger mods)
[self focusChanged: NO];
}
-- (void) keyDown: (NSEvent*) theEvent
-{
- [self sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_PRESSED];
-}
-
-- (void) keyUp: (NSEvent*) theEvent
-{
- [self sendKeyEvent: theEvent eventType: (jshort)EVENT_KEY_RELEASED];
-}
-
-#define kVK_Shift 0x38
-#define kVK_Option 0x3A
-#define kVK_Control 0x3B
-#define kVK_Command 0x37
-
-- (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) flagsChanged:(NSEvent *) theEvent
-{
- NSUInteger mods = [theEvent modifierFlags];
-
- // BOOL modsDown[4]; // shift, ctrl, alt/option, win/command
-
- [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) mouseEntered: (NSEvent*) theEvent
-{
- DBG_PRINT( "mouseEntered: confined %d, visible %d\n", mouseConfined, mouseVisible);
- mouseInside = YES;
- [self cursorHide: !mouseVisible enter: 1];
- if(NO == mouseConfined) {
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED];
- }
-}
-
-- (void) mouseExited: (NSEvent*) theEvent
-{
- DBG_PRINT( "mouseExited: confined %d, visible %d\n", mouseConfined, mouseVisible);
- if(NO == mouseConfined) {
- mouseInside = NO;
- [self cursorHide: NO enter: -1];
- [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED];
- } else {
- [self setMousePosition: lastInsideMousePosition];
- }
-}
-
-- (void) mouseMoved: (NSEvent*) theEvent
-{
- 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
-{
- [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)windowDidResize: (NSNotification*) notification
{
JNIEnv* env = NULL;
@@ -1108,14 +1152,13 @@ static jint mods2JavaMods(NSUInteger mods)
int shallBeDetached = 0;
JavaVM *jvmHandle = NULL;
- NSView* nsview = [self contentView];
- if( [nsview isKindOfClass:[NewtView class]] ) {
- NewtView* view = (NewtView *) nsview;
- javaWindowObject = [view getJavaWindowObject];
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( [newtView isKindOfClass:[NewtView class]] ) {
+ javaWindowObject = [newtView getJavaWindowObject];
if (javaWindowObject != NULL) {
- jvmHandle = [view getJVMHandle];
+ jvmHandle = [newtView getJVMHandle];
if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
}
}
}
@@ -1139,21 +1182,20 @@ static jint mods2JavaMods(NSUInteger mods)
- (void)windowDidMove: (NSNotification*) notification
{
- NSView* nsview = [self contentView];
- if( ! [nsview isKindOfClass:[NewtView class]] ) {
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( ! [newtView isKindOfClass:[NewtView class]] ) {
return;
}
- NewtView* view = (NewtView *) nsview;
- jobject javaWindowObject = [view getJavaWindowObject];
+ jobject javaWindowObject = [newtView getJavaWindowObject];
if (javaWindowObject == NULL) {
DBG_PRINT("windowDidMove: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
- JavaVM *jvmHandle = [view getJVMHandle];
+ JavaVM *jvmHandle = [newtView getJVMHandle];
JNIEnv* env;
if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
} else {
env = NULL;
}
@@ -1186,32 +1228,31 @@ static jint mods2JavaMods(NSUInteger mods)
jboolean closed = JNI_FALSE;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [self cursorHide: NO enter: -1];
-
- NSView* nsview = [self contentView];
- if( ! [nsview isKindOfClass:[NewtView class]] ) {
+ NewtView* newtView = (NewtView *) [self contentView];
+ if( ! [newtView isKindOfClass:[NewtView class]] ) {
return NO;
}
- NewtView* view = (NewtView *) nsview;
- if( false == [view getDestroyNotifySent] ) {
- jobject javaWindowObject = [view getJavaWindowObject];
+ [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");
return NO;
}
int shallBeDetached = 0;
- JavaVM *jvmHandle = [view getJVMHandle];
+ JavaVM *jvmHandle = [newtView getJVMHandle];
JNIEnv* env = NULL;
NS_DURING
if( NULL != jvmHandle ) {
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
+ env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
}
NS_HANDLER
jvmHandle = NULL;
env = NULL;
- [view setJVMHandle: NULL];
+ [newtView setJVMHandle: NULL];
DBG_PRINT("windowWillClose: JVMHandler Exception\n");
NS_ENDHANDLER
DBG_PRINT("windowWillClose: JVM %p JNIEnv %p\n", jvmHandle, env);
@@ -1219,11 +1260,11 @@ NS_ENDHANDLER
return NO;
}
- [view setDestroyNotifySent: true]; // earmark assumption of being closed
+ [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
- [view setDestroyNotifySent: false];
+ [newtView setDestroyNotifySent: false];
}
/* if (shallBeDetached) {