aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/native/MacWindow.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/native/MacWindow.m')
-rw-r--r--src/newt/native/MacWindow.m504
1 files changed, 504 insertions, 0 deletions
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
new file mode 100644
index 000000000..e5021dcad
--- /dev/null
+++ b/src/newt/native/MacWindow.m
@@ -0,0 +1,504 @@
+/*
+ * 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_jogamp_newt_impl_macosx_MacWindow.h"
+#import "NewtMacWindow.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;
+}
+
+void setFrameTopLeftPoint(NSWindow* pwin, NSWindow* win, jint x, jint y)
+{
+ NSScreen* screen = [NSScreen mainScreen];
+
+ // this allows for better compatibility with awt behavior
+ NSRect visibleRect; // either screen or parent-window
+ NSPoint pt;
+ int d_pty=0; // parent titlebar height
+ int d_ptx=0;
+
+ if(NULL==pwin) {
+ visibleRect = [screen frame];
+ } else {
+ visibleRect = [pwin frame];
+ NSView* pview = [pwin contentView];
+ NSRect viewRect = [pview frame];
+ d_pty = visibleRect.size.height - viewRect.size.height;
+ (void) d_ptx;
+ //d_pty = visibleRect.origin.y - viewRect.size.height;
+ //d_ptx = visibleRect.size.height - viewRect.size.height;
+ fprintf(stderr, "pwin %lf/%lf %lfx%lf, pview %lf/%lf %lfx%lf -> %d/%d\n",
+ visibleRect.origin.x,
+ visibleRect.origin.y,
+ visibleRect.size.width,
+ visibleRect.size.height,
+ viewRect.origin.x,
+ viewRect.origin.y,
+ viewRect.size.width,
+ viewRect.size.height,
+ (int)x, (int)y);
+
+ }
+
+ pt = NSMakePoint(visibleRect.origin.x + x, visibleRect.origin.y + visibleRect.size.height - y - d_pty);
+
+ [win setFrameTopLeftPoint: pt];
+}
+
+static NewtView * changeContentView(JNIEnv *env, jobject javaWindowObject, NSWindow *pwin, NSWindow *win, NewtView *newView) {
+ NSView* oldNSView = [win contentView];
+ NewtView* oldView = NULL;
+
+ if(NULL!=oldNSView) {
+NS_DURING
+ // Available >= 10.5 - Makes the menubar disapear
+ if([oldNSView isInFullScreenMode]) {
+ [oldNSView exitFullScreenModeWithOptions: NULL];
+ }
+NS_HANDLER
+NS_ENDHANDLER
+ if( [oldNSView isMemberOfClass:[NewtView class]] ) {
+ oldView = (NewtView *) oldNSView;
+
+ jobject globJavaWindowObject = [oldView getJavaWindowObject];
+ (*env)->DeleteGlobalRef(env, globJavaWindowObject);
+ [oldView setJavaWindowObject: NULL];
+ }
+ /** FIXME: Tried child window: auto clip or message reception ..
+ if(NULL!=pwin) {
+ [oldView removeFromSuperview];
+ } */
+ }
+ if(NULL!=newView) {
+ jobject globJavaWindowObject = (*env)->NewGlobalRef(env, javaWindowObject);
+ [newView setJavaWindowObject: globJavaWindowObject];
+ [newView setJNIEnv: env];
+
+ /** FIXME: Tried child window: auto clip or message reception ..
+ if(NULL!=pwin) {
+ NSView* pview = [pwin contentView];
+ [pview addSubview: newView];
+ } */
+ }
+ [win setContentView: newView];
+
+ // make sure the insets are updated in the java object
+ NewtMacWindow* newtw = (NewtMacWindow*)win;
+ [newtw updateInsets: env];
+
+ return oldView;
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacDisplay
+ * Method: initIDs
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_macosx_MacDisplay_initNSApplication0
+ (JNIEnv *env, jclass clazz)
+{
+ static int initialized = 0;
+
+ if(initialized) return JNI_TRUE;
+ initialized = 1;
+
+ // 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) JNI_TRUE;
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacDisplay
+ * Method: dispatchMessages0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_macosx_MacDisplay_dispatchMessages0
+ (JNIEnv *env, jobject unused)
+{
+ NSEvent* event = NULL;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+NS_DURING
+
+ int num_events = 0;
+
+ // Periodically take a break
+ 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];
+
+ num_events++;
+ }
+ } while (num_events<100 && event != NULL);
+
+NS_HANDLER
+
+ // just ignore it ..
+
+NS_ENDHANDLER
+
+ [pool release];
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacScreen
+ * Method: getWidthImpl
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_macosx_MacScreen_getWidthImpl0
+ (JNIEnv *env, jclass clazz, jint screen_idx)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ NSArray *screens = [NSScreen screens];
+ if(screen_idx<0) screen_idx=0;
+ if(screen_idx>=[screens count]) screen_idx=0;
+ NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx];
+ NSRect rect = [screen frame];
+
+ [pool release];
+
+ return (jint) (rect.size.width);
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacScreen
+ * Method: getHeightImpl
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_macosx_MacScreen_getHeightImpl0
+ (JNIEnv *env, jclass clazz, jint screen_idx)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ NSArray *screens = [NSScreen screens];
+ if(screen_idx<0) screen_idx=0;
+ if(screen_idx>=[screens count]) screen_idx=0;
+ NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx];
+ NSRect rect = [screen frame];
+
+ [pool release];
+
+ return (jint) (rect.size.height);
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacWindow
+ * Method: initIDs
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_initIDs0
+ (JNIEnv *env, jclass clazz)
+{
+ static int initialized = 0;
+
+ if(initialized) return JNI_TRUE;
+ initialized = 1;
+
+ // 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_jogamp_newt_impl_macosx_MacWindow
+ * Method: createWindow0
+ * Signature: (JIIIIZIIIJ)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_createWindow0
+ (JNIEnv *env, jobject jthis, jlong parent, jint x, jint y, jint w, jint h, jboolean fullscreen, jint styleMask,
+ jint bufferingType, jint screen_idx, jlong jview)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSRect rect = NSMakeRect(x, y, w, h);
+
+ NSArray *screens = [NSScreen screens];
+ if(screen_idx<0) screen_idx=0;
+ if(screen_idx>=[screens count]) screen_idx=0;
+ NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx];
+
+ if (fullscreen) {
+ styleMask = NSBorderlessWindowMask;
+ NSRect rect = [screen frame];
+ w = (jint) (rect.size.width);
+ h = (jint) (rect.size.height);
+ }
+
+ // Allocate the window
+ NSWindow* window = [[[NewtMacWindow alloc] initWithContentRect: rect
+ styleMask: (NSUInteger) styleMask
+ backing: (NSBackingStoreType) bufferingType
+ screen: screen] retain];
+
+ NSObject *nsParentObj = (NSObject*) ((intptr_t) parent);
+ NSWindow* parentWindow = NULL;
+ if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSWindow class]] ) {
+ parentWindow = (NSWindow*) nsParentObj;
+ } else if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSView class]] ) {
+ NSView* view = (NSView*) nsParentObj;
+ parentWindow = [view window];
+ fprintf(stderr, "createWindow0 - Parent is NSView : %p -> %p (win) \n", nsParentObj, parentWindow);
+ } else {
+ fprintf(stderr, "createWindow0 - Parent is neither NSWindow nor NSView : %p\n", nsParentObj);
+ }
+ if(NULL!=parentWindow) {
+ [parentWindow addChildWindow: window ordered: NSWindowAbove];
+ [window setParentWindow: parentWindow];
+ }
+
+ if (fullscreen) {
+ [window setOpaque: YES];
+ } else {
+ // If the window is undecorated, assume we want the possibility of
+ // a shaped window, so make it non-opaque and the background color clear
+ if ((styleMask & NSTitledWindowMask) == 0) {
+ [window setOpaque: NO];
+ [window setBackgroundColor: [NSColor clearColor]];
+ }
+ }
+
+ // Immediately re-position the window based on an upper-left coordinate system
+ setFrameTopLeftPoint(parentWindow, window, x, y);
+
+ // specify we want mouse-moved events
+ [window setAcceptsMouseMovedEvents:YES];
+
+ // Use given NewtView or allocate an NewtView if NULL
+ NewtView* view = (0==jview)? [[NewtView alloc] initWithFrame: rect] : (NewtView*) ((intptr_t) jview) ;
+
+ // Set the content view
+ (void) changeContentView(env, jthis, parentWindow, window, view);
+
+NS_DURING
+ // Available >= 10.5 - Makes the menubar disapear
+ if(fullscreen) {
+ [view enterFullScreenMode: screen withOptions:NULL];
+ }
+NS_HANDLER
+NS_ENDHANDLER
+
+ // Set the next responder to be the window so that we can forward
+ // right mouse button down events
+ [view setNextResponder: window];
+
+ [pool release];
+
+ return (jlong) ((intptr_t) window);
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacWindow
+ * Method: makeKeyAndOrderFront
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_makeKeyAndOrderFront0
+ (JNIEnv *env, jobject unused, jlong window)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* win = (NSWindow*) ((intptr_t) window);
+ [win makeKeyAndOrderFront: win];
+ [pool release];
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacWindow
+ * Method: makeKey
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_makeKey0
+ (JNIEnv *env, jobject unused, jlong window)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* win = (NSWindow*) ((intptr_t) window);
+ [win makeKeyWindow];
+ [pool release];
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacWindow
+ * Method: orderOut
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_orderOut0
+ (JNIEnv *env, jobject unused, jlong window)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* win = (NSWindow*) ((intptr_t) window);
+ [win orderOut: win];
+ [pool release];
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacWindow
+ * Method: close0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_close0
+ (JNIEnv *env, jobject unused, jlong window)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* win = (NSWindow*) ((intptr_t) window);
+ NSView* view = [win contentView];
+ [win orderOut: win];
+NS_DURING
+ if(NULL!=view) {
+ // Available >= 10.5 - Makes the menubar disapear
+ if([view isInFullScreenMode]) {
+ [view exitFullScreenModeWithOptions: NULL];
+ }
+ }
+NS_HANDLER
+NS_ENDHANDLER
+ [win close];
+ [pool release];
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacWindow
+ * Method: setTitle0
+ * Signature: (JLjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_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_jogamp_newt_impl_macosx_MacWindow
+ * Method: contentView
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_contentView0
+ (JNIEnv *env, jobject unused, jlong window)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* win = (NSWindow*) ((intptr_t) window);
+ jlong res = (jlong) ((intptr_t) [win contentView]);
+ [pool release];
+ return res;
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacWindow
+ * Method: changeContentView
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_changeContentView0
+ (JNIEnv *env, jobject jthis, jlong parent, jlong window, jlong jview)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* pwin = (NewtMacWindow*) ((intptr_t) parent);
+ NSWindow* win = (NewtMacWindow*) ((intptr_t) window);
+ NewtView* newView = (NewtView *) ((intptr_t) jview);
+
+ NewtView* oldView = changeContentView(env, jthis, pwin, win, newView);
+
+ [pool release];
+
+ return (jlong) ((intptr_t) oldView);
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacWindow
+ * Method: setContentSize
+ * Signature: (JII)V
+ */
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_setContentSize0
+ (JNIEnv *env, jobject unused, jlong window, jint w, jint h)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* win = (NSWindow*) ((intptr_t) window);
+ NSSize sz = NSMakeSize(w, h);
+ [win setContentSize: sz];
+ [pool release];
+}
+
+/*
+ * Class: com_jogamp_newt_impl_macosx_MacWindow
+ * Method: setFrameTopLeftPoint
+ * Signature: (JII)V
+ */
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_setFrameTopLeftPoint0
+ (JNIEnv *env, jobject unused, jlong parent, jlong window, jint x, jint y)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* pwin = (NSWindow*) ((intptr_t) parent);
+ NSWindow* win = (NSWindow*) ((intptr_t) window);
+ setFrameTopLeftPoint(pwin, win, x, y);
+ [pool release];
+}
+