diff options
Diffstat (limited to 'src/native')
-rw-r--r--[-rwxr-xr-x] | src/native/newt/InputEvent.h (renamed from src/native/newt/MacWindow.c) | 26 | ||||
-rw-r--r-- | src/native/newt/MacWindow.m | 268 | ||||
-rw-r--r-- | src/native/newt/NewtMacWindow.h | 53 | ||||
-rw-r--r-- | src/native/newt/NewtMacWindow.m | 274 |
4 files changed, 604 insertions, 17 deletions
diff --git a/src/native/newt/MacWindow.c b/src/native/newt/InputEvent.h index 8de574ef3..1284a8535 100755..100644 --- a/src/native/newt/MacWindow.c +++ b/src/native/newt/InputEvent.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -31,21 +31,13 @@ * */ -#include "com_sun_javafx_newt_macosx_MacWindow.h" +#ifndef _INPUT_EVENT_H_ +#define _INPUT_EVENT_H_ -#include "EventListener.h" -#include "MouseEvent.h" -#include "KeyEvent.h" +#define EVENT_SHIFT_MASK 1 +#define EVENT_CTRL_MASK 2 +#define EVENT_META_MASK 4 +#define EVENT_ALT_MASK 8 +#define EVENT_ALT_GRAPH_MASK 32 -#include <stdio.h> - -/* - * Class: com_sun_javafx_newt_macosx_MacWindow - * Method: _initIDs - * Signature: ()Z - */ -JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_macosx_MacWindow__1initIDs - (JNIEnv *env, jclass clazz) -{ - return JNI_TRUE; -} +#endif diff --git a/src/native/newt/MacWindow.m b/src/native/newt/MacWindow.m new file mode 100644 index 000000000..f6b2bf5b2 --- /dev/null +++ b/src/native/newt/MacWindow.m @@ -0,0 +1,268 @@ +/* + * 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 <inttypes.h> + +#import "com_sun_javafx_newt_macosx_MacWindow.h" +#import "NewtMacWindow.h" + +#import "EventListener.h" +#import "MouseEvent.h" +#import "KeyEvent.h" + +#import <ApplicationServices/ApplicationServices.h> + +#import <stdio.h> + +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 BOOL initializedMenuHeight = NO; +static CGFloat menuHeight = 0; + +void setFrameTopLeftPoint(NSWindow* win, jint x, jint y) +{ + NSScreen* screen = [NSScreen mainScreen]; + NSRect screenRect = [screen frame]; + NSPoint pt; + + if (!initializedMenuHeight) { + NSMenu* menu = [NSApp mainMenu]; + BOOL mustRelease = NO; + + if (menu == nil) { + printf("main menu was nil, trying services menu\n"); + menu = [NSApp servicesMenu]; + } + + if (menu == nil) { + printf("services menu was nil, trying an empty menu instance\n"); + menu = [[[NSMenu alloc] initWithTitle: @"Foo"] retain]; + mustRelease = YES; + } + + menuHeight = [menu menuBarHeight]; + + if (mustRelease) { + [menu release]; + } + + initializedMenuHeight = YES; + } + + pt = NSMakePoint(x, screenRect.origin.y + screenRect.size.height - menuHeight - y); + [win setFrameTopLeftPoint: pt]; +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: initIDs + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_initIDs + (JNIEnv *env, jclass clazz) +{ + // This little bit of magic is needed in order to receive mouse + // motion events and allow key focus to be properly transferred. + // FIXME: are these Carbon APIs? They come from the + // ApplicationServices.framework. + ProcessSerialNumber psn; + if (GetCurrentProcess(&psn) == noErr) { + TransformProcessType(&psn, kProcessTransformToForegroundApplication); + SetFrontProcess(&psn); + } + + // Initialize the shared NSApplication instance + [NSApplication 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) [NewtMacWindow initNatives: env forClass: clazz]; +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: createWindow + * Signature: (IIIIIIZ)J + */ +JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_createWindow + (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, jint styleMask, jint bufferingType, jboolean deferCreation) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSRect rect = NSMakeRect(x, y, w, h); + jobject windowObj = (*env)->NewGlobalRef(env, jthis); + + // Allocate the window + NSWindow* window = [[[NewtMacWindow alloc] initWithContentRect: rect + styleMask: (NSUInteger) styleMask + backing: (NSBackingStoreType) bufferingType + defer: YES + javaWindowObject: windowObj] retain]; + + // Immediately re-position the window based on an upper-left coordinate system + setFrameTopLeftPoint(window, x, y); + + // Allocate an NSView + NSView* view = [[NSView alloc] initWithFrame: rect]; + + // specify we want mouse-moved events + [window setAcceptsMouseMovedEvents:YES]; + + // Set the content view + [window setContentView: view]; + + [pool release]; + + return (jlong) ((intptr_t) window); +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: makeKeyAndOrderFront + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_makeKeyAndOrderFront + (JNIEnv *env, jobject unused, jlong window) +{ + NSWindow* win = (NSWindow*) ((intptr_t) window); + [win makeKeyAndOrderFront: win]; +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: orderOut + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_orderOut + (JNIEnv *env, jobject unused, jlong window) +{ + NSWindow* win = (NSWindow*) ((intptr_t) window); + [win orderOut: win]; +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: close0 + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_close0 + (JNIEnv *env, jobject unused, jlong window) +{ + NSWindow* win = (NSWindow*) ((intptr_t) window); + [win close]; +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: setTitle0 + * Signature: (JLjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_setTitle0 + (JNIEnv *env, jobject unused, jlong window, jstring title) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSWindow* win = (NSWindow*) ((intptr_t) window); + NSString* str = jstringToNSString(env, title); + [str autorelease]; + [win setTitle: str]; + [pool release]; +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: dispatchMessages + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_dispatchMessages + (JNIEnv *env, jobject unused, jint eventMask) +{ + NSEvent* event = NULL; + + [NewtMacWindow setJNIEnv: env]; + do { + // FIXME: ignoring event mask for the time being + event = [NSApp nextEventMatchingMask: NSAnyEventMask + untilDate: [NSDate distantPast] + inMode: NSDefaultRunLoopMode + dequeue: YES]; + if (event != NULL) { + [NSApp sendEvent: event]; + } + } while (event != NULL); + [NewtMacWindow setJNIEnv: NULL]; +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: contentView + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_contentView + (JNIEnv *env, jobject unused, jlong window) +{ + NSWindow* win = (NSWindow*) ((intptr_t) window); + return (jlong) ((intptr_t) [win contentView]); +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: setContentSize + * Signature: (JII)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_setContentSize + (JNIEnv *env, jobject unused, jlong window, jint w, jint h) +{ + NSWindow* win = (NSWindow*) ((intptr_t) window); + NSSize sz = NSMakeSize(w, h); + [win setContentSize: sz]; +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: setFrameTopLeftPoint + * Signature: (JII)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_setFrameTopLeftPoint + (JNIEnv *env, jobject unused, jlong window, jint x, jint y) +{ + NSWindow* win = (NSWindow*) ((intptr_t) window); + setFrameTopLeftPoint(win, x, y); +} diff --git a/src/native/newt/NewtMacWindow.h b/src/native/newt/NewtMacWindow.h new file mode 100644 index 000000000..971661ebf --- /dev/null +++ b/src/native/newt/NewtMacWindow.h @@ -0,0 +1,53 @@ +/* + * 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 <AppKit/AppKit.h> +#import "jni.h" + +@interface NewtMacWindow : NSWindow +{ + jobject javaWindowObject; +} + ++ (BOOL) initNatives: (JNIEnv*) env forClass: (jobject) clazz; + +/* Set and cleared during event dispatching cycle */ ++ (void) setJNIEnv: (JNIEnv*) env; + +- (id) initWithContentRect: (NSRect) contentRect + styleMask: (NSUInteger) windowStyle + backing: (NSBackingStoreType) bufferingType + defer: (BOOL) deferCreation + javaWindowObject: (jobject) javaWindowObj; + +@end diff --git a/src/native/newt/NewtMacWindow.m b/src/native/newt/NewtMacWindow.m new file mode 100644 index 000000000..5655f2fa6 --- /dev/null +++ b/src/native/newt/NewtMacWindow.m @@ -0,0 +1,274 @@ +/* + * 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" + +static jmethodID sendMouseEventID = NULL; +static jmethodID sendKeyEventID = NULL; +static jmethodID sizeChangedID = NULL; +static jmethodID positionChangedID = NULL; +static jmethodID windowClosedID = NULL; + +// This is set while messages are being dispatched and cleared afterward +static JNIEnv* env = NULL; + +@implementation NewtMacWindow + ++ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz +{ + sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIII)V"); + sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); + positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); + windowClosedID = (*env)->GetMethodID(env, clazz, "windowClosed", "()V"); + if (sendMouseEventID && sendKeyEventID && sizeChangedID && positionChangedID && windowClosedID) { + return YES; + } + return NO; +} + ++ (void) setJNIEnv: (JNIEnv*) theEnv +{ + env = theEnv; +} + +- (id) initWithContentRect: (NSRect) contentRect + styleMask: (NSUInteger) windowStyle + backing: (NSBackingStoreType) bufferingType + defer: (BOOL) deferCreation + javaWindowObject: (jobject) javaWindowObj +{ + id res = [super initWithContentRect: contentRect + styleMask: windowStyle + backing: bufferingType + defer: deferCreation]; + javaWindowObject = javaWindowObj; + // Why is this necessary? Without it we don't get any of the + // delegate methods like resizing and window movement. + [self setDelegate: self]; + return res; +} + +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: (jint) evType +{ + int i; + jint keyCode = (jint) [event keyCode]; + NSString* chars = [event charactersIgnoringModifiers]; + int len = [chars length]; + jint javaMods = mods2JavaMods([event modifierFlags]); + + if (env == NULL) { + return; + } + + if (javaWindowObject == NULL) { + return; + } + + for (i = 0; i < len; i++) { + // Note: the key code in the NSEvent does not map to anything we can use + jchar keyChar = (jchar) [chars characterAtIndex: i]; + + (*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID, + evType, javaMods, keyCode, keyChar); + } +} + +- (void) keyDown: (NSEvent*) theEvent +{ + [self sendKeyEvent: theEvent eventType: EVENT_KEY_PRESSED]; +} + +- (void) keyUp: (NSEvent*) theEvent +{ + [self sendKeyEvent: theEvent eventType: EVENT_KEY_RELEASED]; +} + +- (void) sendMouseEvent: (NSEvent*) event eventType: (jint) evType +{ + jint javaMods = mods2JavaMods([event modifierFlags]); + NSPoint location = [event locationInWindow]; + NSRect frameRect = [self frame]; + NSRect contentRect = [self contentRectForFrameRect: frameRect]; + + if (env == NULL) { + return; + } + + if (javaWindowObject == NULL) { + return; + } + + // 1-base the button number + (*env)->CallVoidMethod(env, javaWindowObject, sendMouseEventID, + evType, javaMods, + (jint) location.x, + (jint) (contentRect.size.height - location.y), + (jint) (1 + [event buttonNumber])); +} + +- (void) mouseEntered: (NSEvent*) theEvent +{ + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED]; +} + +- (void) mouseExited: (NSEvent*) theEvent +{ + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED]; +} + +- (void) mouseMoved: (NSEvent*) theEvent +{ + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; +} + +- (void) mouseDown: (NSEvent*) theEvent +{ + [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; +} + +- (void) mouseDragged: (NSEvent*) theEvent +{ + // 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 +{ + // 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 +{ + // 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 +{ + NSRect frameRect = [self frame]; + NSRect contentRect = [self contentRectForFrameRect: frameRect]; + + if (env == NULL) { + return; + } + + if (javaWindowObject == NULL) { + return; + } + + (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, + (jint) contentRect.size.width, + (jint) contentRect.size.height); +} + +- (void)windowDidMove: (NSNotification*) notification +{ + NSRect rect = [self frame]; + + if (env == NULL) { + return; + } + + if (javaWindowObject == NULL) { + return; + } + + // FIXME: this result isn't consistent with setFrameTopLeftPoint + + (*env)->CallVoidMethod(env, javaWindowObject, positionChangedID, + (jint) rect.origin.x, + (jint) rect.origin.y); +} + +- (void)windowWillClose: (NSNotification*) notification +{ + if (env == NULL) { + return; + } + + if (javaWindowObject == NULL) { + return; + } + + (*env)->CallVoidMethod(env, javaWindowObject, windowClosedID); +} + +@end |