/* * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #import "ApplicationDelegate.h" #import "com_apple_eawt_Application.h" #import "com_apple_eawt__AppDockIconHandler.h" #import "com_apple_eawt__AppEventHandler.h" #import "com_apple_eawt__AppMenuBarHandler.h" #import "com_apple_eawt__AppMenuBarHandler.h" #import "com_apple_eawt__AppMiscHandlers.h" #import #import "CPopupMenu.h" #import "ThreadUtilities.h" #import "NSApplicationAWT.h" #pragma mark App Menu helpers // The following is a AWT convention? #define PREFERENCES_TAG 42 static void addMenuItem(NSMenuItem* menuItem, NSInteger index) { AWT_ASSERT_APPKIT_THREAD; NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu]; NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu]; [appMenu insertItem:menuItem atIndex:index]; [appMenu insertItem:[NSMenuItem separatorItem] atIndex:index + 1]; // Add the following separator } static void removeMenuItem(NSMenuItem* menuItem) { AWT_ASSERT_APPKIT_THREAD; NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu]; NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu]; NSInteger index = [appMenu indexOfItem:menuItem]; if (index < 0) return; // something went wrong [appMenu removeItemAtIndex:index + 1]; // Get the following separator [appMenu removeItem:menuItem]; } @interface NSBundle (EAWTOverrides) - (BOOL)_hasEAWTOverride:(NSString *)key; @end @implementation NSBundle (EAWTOverrides) - (BOOL)_hasEAWTOverride:(NSString *)key { return [[[[self objectForInfoDictionaryKey:@"Java"] objectForKey:@"EAWTOverride"] objectForKey:key] boolValue]; } @end // used by JavaRuntimeSupport.framework's [JRSAppKitAWT awtAppDelegate] // to expose our app delegate to the SWT or other apps that have knoledge // of Java's AWT and want to install their own app delegate that will delegate // to the AWT for some operations @interface JavaAWTAppDelegateLoader : NSObject { } @end @implementation JavaAWTAppDelegateLoader + (ApplicationDelegate *) awtAppDelegate { return [ApplicationDelegate sharedDelegate]; } @end @implementation ApplicationDelegate @synthesize fPreferencesMenu; @synthesize fAboutMenu; @synthesize fDockMenu; @synthesize fDefaultMenuBar; + (ApplicationDelegate *)sharedDelegate { static ApplicationDelegate *sApplicationDelegate = nil; static BOOL checked = NO; if (sApplicationDelegate != nil) return sApplicationDelegate; if (checked) return nil; AWT_ASSERT_APPKIT_THREAD; // don't install the EAWT delegate if another kind of NSApplication is installed, like say, Safari BOOL shouldInstall = NO; if (NSApp != nil) { if ([NSApp isMemberOfClass:[NSApplication class]]) shouldInstall = YES; if ([NSApp isKindOfClass:[NSApplicationAWT class]]) shouldInstall = YES; } checked = YES; if (!shouldInstall) return nil; sApplicationDelegate = [[ApplicationDelegate alloc] init]; return sApplicationDelegate; } - (void)_updatePreferencesMenu:(BOOL)prefsAvailable enabled:(BOOL)prefsEnabled { AWT_ASSERT_APPKIT_THREAD; if (prefsAvailable) { // Make sure Prefs is around if ([self.fPreferencesMenu menu] == nil) { // Position of Prefs depends upon About availability. NSInteger index = ([self.fAboutMenu menu] != nil) ? 2 : 0; addMenuItem(self.fPreferencesMenu, index); } if (prefsEnabled) { [self.fPreferencesMenu setEnabled:YES]; [self.fPreferencesMenu setTarget:self]; [self.fPreferencesMenu setAction:@selector(_preferencesMenuHandler)]; } else { [self.fPreferencesMenu setEnabled:NO]; [self.fPreferencesMenu setTarget:nil]; [self.fPreferencesMenu setAction:nil]; } } else { if ([self.fPreferencesMenu menu] == nil) return; // Remove the preferences item removeMenuItem(self.fPreferencesMenu); } } - (void)_updateAboutMenu:(BOOL)aboutAvailable enabled:(BOOL)aboutEnabled { AWT_ASSERT_APPKIT_THREAD; if (aboutAvailable) { // Make sure About is around if ([self.fAboutMenu menu] == nil) { addMenuItem(self.fAboutMenu, 0); } if (aboutEnabled) { [self.fAboutMenu setEnabled:YES]; [self.fAboutMenu setTarget:self]; [self.fAboutMenu setAction:@selector(_aboutMenuHandler)]; } else { [self.fAboutMenu setEnabled:NO]; [self.fAboutMenu setTarget:nil]; [self.fAboutMenu setAction:nil]; } } else { if ([self.fAboutMenu menu] == nil) return; // Remove About item. removeMenuItem(self.fAboutMenu); } } - (id) init { AWT_ASSERT_APPKIT_THREAD; self = [super init]; if (!self) return self; // Prep for about and preferences menu BOOL usingDefaultNib = YES; if ([NSApp isKindOfClass:[NSApplicationAWT class]]) { usingDefaultNib = [NSApp usingDefaultNib]; } if (!usingDefaultNib) return self; NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu]; NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu]; self.fPreferencesMenu = (NSMenuItem*)[appMenu itemWithTag:PREFERENCES_TAG]; self.fAboutMenu = (NSMenuItem*)[appMenu itemAtIndex:0]; // If the java application has a bundle with an Info.plist file with // a CFBundleDocumentTypes entry, then it is set up to handle Open Doc // and Print Doc commands for these files. Therefore java AWT will // cache Open Doc and Print Doc events that are sent prior to a // listener being installed by the client java application. NSBundle *bundle = [NSBundle mainBundle]; fHandlesDocumentTypes = [bundle objectForInfoDictionaryKey:@"CFBundleDocumentTypes"] != nil || [bundle _hasEAWTOverride:@"DocumentHandler"]; fHandlesURLTypes = [bundle objectForInfoDictionaryKey:@"CFBundleURLTypes"] != nil || [bundle _hasEAWTOverride:@"URLHandler"]; if (fHandlesURLTypes) { [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(_handleOpenURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; } // By HIG, Preferences are not available unless there is a handler. By default in Mac OS X, // there is not a handler, but it is in the nib file for convenience. removeMenuItem(self.fPreferencesMenu); [self _updateAboutMenu:YES enabled:YES]; // Now that the AppKit objects are known and set up, initialize the model data BOOL aboutAvailable = ([self.fAboutMenu menu] != nil); BOOL aboutEnabled = (aboutAvailable && [self.fAboutMenu isEnabled] && ([self.fAboutMenu target] != nil)); BOOL prefsAvailable = ([self.fPreferencesMenu menu] != nil); BOOL prefsEnabled = (prefsAvailable && [self.fPreferencesMenu isEnabled] && ([self.fPreferencesMenu target] != nil)); JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_CLASS_CACHE(sjc_AppMenuBarHandler, "com/apple/eawt/_AppMenuBarHandler"); static JNF_STATIC_MEMBER_CACHE(sjm_initMenuStates, sjc_AppMenuBarHandler, "initMenuStates", "(ZZZZ)V"); JNFCallStaticVoidMethod(env, sjm_initMenuStates, aboutAvailable, aboutEnabled, prefsAvailable, prefsEnabled); // register for the finish launching and system power off notifications by default NSNotificationCenter *ctr = [NSNotificationCenter defaultCenter]; Class clz = [ApplicationDelegate class]; [ctr addObserver:clz selector:@selector(_willFinishLaunching) name:NSApplicationWillFinishLaunchingNotification object:nil]; [ctr addObserver:clz selector:@selector(_systemWillPowerOff) name:NSWorkspaceWillPowerOffNotification object:nil]; [ctr addObserver:clz selector:@selector(_appDidActivate) name:NSApplicationDidBecomeActiveNotification object:nil]; [ctr addObserver:clz selector:@selector(_appDidDeactivate) name:NSApplicationDidResignActiveNotification object:nil]; [ctr addObserver:clz selector:@selector(_appDidHide) name:NSApplicationDidHideNotification object:nil]; [ctr addObserver:clz selector:@selector(_appDidUnhide) name:NSApplicationDidUnhideNotification object:nil]; return self; } - (void)dealloc { self.fPreferencesMenu = nil; self.fAboutMenu = nil; self.fDockMenu = nil; self.fDefaultMenuBar = nil; [super dealloc]; } //- (void)finalize { [super finalize]; } // GC #pragma mark Callbacks from AppKit static JNF_CLASS_CACHE(sjc_AppEventHandler, "com/apple/eawt/_AppEventHandler"); - (void)_handleOpenURLEvent:(NSAppleEventDescriptor *)openURLEvent withReplyEvent:(NSAppleEventDescriptor *)replyEvent { AWT_ASSERT_APPKIT_THREAD; if (!fHandlesURLTypes) return; NSString *url = [[openURLEvent paramDescriptorForKeyword:keyDirectObject] stringValue]; //fprintf(stderr,"jm_handleOpenURL\n"); JNIEnv *env = [ThreadUtilities getJNIEnv]; jstring jURL = JNFNSToJavaString(env, url); static JNF_STATIC_MEMBER_CACHE(jm_handleOpenURI, sjc_AppEventHandler, "handleOpenURI", "(Ljava/lang/String;)V"); JNFCallStaticVoidMethod(env, jm_handleOpenURI, jURL); // AWT_THREADING Safe (event) (*env)->DeleteLocalRef(env, jURL); [replyEvent insertDescriptor:[NSAppleEventDescriptor nullDescriptor] atIndex:0]; } // Helper for both open file and print file methods // Creates a Java list of files from a native list of files - (jobject)_createFilePathArrayFrom:(NSArray *)filenames withEnv:(JNIEnv *)env { static JNF_CLASS_CACHE(sjc_ArrayList, "java/util/ArrayList"); static JNF_CTOR_CACHE(jm_ArrayList_ctor, sjc_ArrayList, "(I)V"); static JNF_MEMBER_CACHE(jm_ArrayList_add, sjc_ArrayList, "add", "(Ljava/lang/Object;)Z"); jobject jFileNamesArray = JNFNewObject(env, jm_ArrayList_ctor, (jint)[filenames count]); // AWT_THREADING Safe (known object) for (NSString *filename in filenames) { jstring jFileName = JNFNormalizedJavaStringForPath(env, filename); JNFCallVoidMethod(env, jFileNamesArray, jm_ArrayList_add, jFileName); } return jFileNamesArray; } // Open file handler - (void)application:(NSApplication *)theApplication openFiles:(NSArray *)fileNames { AWT_ASSERT_APPKIT_THREAD; if (!fHandlesDocumentTypes) { [theApplication replyToOpenOrPrint:NSApplicationDelegateReplyCancel]; return; } //fprintf(stderr,"jm_handleOpenFile\n"); JNIEnv *env = [ThreadUtilities getJNIEnv]; // if these files were opened from a Spotlight query, try to get the search text from the current AppleEvent NSAppleEventDescriptor *currentEvent = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent]; NSString *searchString = [[currentEvent paramDescriptorForKeyword:keyAESearchText] stringValue]; jstring jSearchString = JNFNSToJavaString(env, searchString); // convert the file names array jobject jFileNamesArray = [self _createFilePathArrayFrom:fileNames withEnv:env]; static JNF_STATIC_MEMBER_CACHE(jm_handleOpenFiles, sjc_AppEventHandler, "handleOpenFiles", "(Ljava/util/List;Ljava/lang/String;)V"); JNFCallStaticVoidMethod(env, jm_handleOpenFiles, jFileNamesArray, jSearchString); (*env)->DeleteLocalRef(env, jFileNamesArray); (*env)->DeleteLocalRef(env, jSearchString); [theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; } // Print handler - (NSApplicationPrintReply)application:(NSApplication *)application printFiles:(NSArray *)fileNames withSettings:(NSDictionary *)printSettings showPrintPanels:(BOOL)showPrintPanels { AWT_ASSERT_APPKIT_THREAD; if (!fHandlesDocumentTypes) return NSPrintingCancelled; //fprintf(stderr,"jm_handlePrintFile\n"); JNIEnv *env = [ThreadUtilities getJNIEnv]; jobject jFileNamesArray = [self _createFilePathArrayFrom:fileNames withEnv:env]; static JNF_STATIC_MEMBER_CACHE(jm_handlePrintFile, sjc_AppEventHandler, "handlePrintFiles", "(Ljava/util/List;)V"); JNFCallStaticVoidMethod(env, jm_handlePrintFile, jFileNamesArray); // AWT_THREADING Safe (event) (*env)->DeleteLocalRef(env, jFileNamesArray); return NSPrintingSuccess; } // Open app handler, registered in -init + (void)_notifyJava:(jint)notificationType { AWT_ASSERT_APPKIT_THREAD; //fprintf(stderr,"jm_handleOpenApplication\n"); JNIEnv *env = [ThreadUtilities getJNIEnv]; static JNF_STATIC_MEMBER_CACHE(jm_handleNativeNotification, sjc_AppEventHandler, "handleNativeNotification", "(I)V"); JNFCallStaticVoidMethod(env, jm_handleNativeNotification, notificationType); // AWT_THREADING Safe (event) } // About menu handler - (void)_aboutMenuHandler { [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_ABOUT]; } // Preferences handler - (void)_preferencesMenuHandler { [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_PREFS]; } // Open app handler, registered in -init + (void)_willFinishLaunching { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_OPEN_APP]; } // ReOpen app handler - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag { [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_REOPEN_APP]; return YES; } // Quit handler - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app { [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_QUIT]; return NSTerminateLater; } + (void)_systemWillPowerOff { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SHUTDOWN]; } + (void)_appDidActivate { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_ACTIVE_APP_GAINED]; } + (void)_appDidDeactivate { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_ACTIVE_APP_LOST]; } + (void)_appDidHide { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_APP_HIDDEN]; } + (void)_appDidUnhide { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_APP_SHOWN]; } + (void)_sessionDidActivate { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_USER_SESSION_ACTIVE]; } + (void)_sessionDidDeactivate { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_USER_SESSION_INACTIVE]; } + (void)_screenDidSleep { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SCREEN_SLEEP]; } + (void)_screenDidWake { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SCREEN_WAKE]; } + (void)_systemDidSleep { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SYSTEM_SLEEP]; } + (void)_systemDidWake { [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SYSTEM_WAKE]; } + (void)_registerForNotification:(NSNumber *)notificationTypeNum { NSNotificationCenter *ctr = [[NSWorkspace sharedWorkspace] notificationCenter]; Class clz = [ApplicationDelegate class]; jint notificationType = [notificationTypeNum intValue]; switch (notificationType) { case com_apple_eawt__AppEventHandler_REGISTER_USER_SESSION: [ctr addObserver:clz selector:@selector(_sessionDidActivate) name:NSWorkspaceSessionDidBecomeActiveNotification object:nil]; [ctr addObserver:clz selector:@selector(_sessionDidDeactivate) name:NSWorkspaceSessionDidResignActiveNotification object:nil]; break; case com_apple_eawt__AppEventHandler_REGISTER_SCREEN_SLEEP: [ctr addObserver:clz selector:@selector(_screenDidSleep) name:NSWorkspaceScreensDidSleepNotification object:nil]; [ctr addObserver:clz selector:@selector(_screenDidWake) name:NSWorkspaceScreensDidWakeNotification object:nil]; break; case com_apple_eawt__AppEventHandler_REGISTER_SYSTEM_SLEEP: [ctr addObserver:clz selector:@selector(_systemDidSleep) name:NSWorkspaceWillSleepNotification object:nil]; [ctr addObserver:clz selector:@selector(_systemDidWake) name:NSWorkspaceDidWakeNotification object:nil]; break; default: NSLog(@"EAWT attempting to register for unknown notification: %d", (int)notificationType); break; } } // Retrieves the menu to be attached to the Dock icon (AppKit callback) - (NSMenu *)applicationDockMenu:(NSApplication *)sender { AWT_ASSERT_APPKIT_THREAD; return self.fDockMenu; } - (CMenuBar *)defaultMenuBar { return [[self.fDefaultMenuBar retain] autorelease]; } #pragma mark Helpers called on the main thread from Java // Sets a new NSImageView on the Dock tile + (void)_setDockIconImage:(NSImage *)image { AWT_ASSERT_APPKIT_THREAD; NSDockTile *dockTile = [NSApp dockTile]; if (image == nil) { [dockTile setContentView:nil]; return; } // setup an image view for the dock tile NSRect frame = NSMakeRect(0, 0, dockTile.size.width, dockTile.size.height); NSImageView *dockImageView = [[NSImageView alloc] initWithFrame: frame]; [dockImageView setImageScaling:NSImageScaleProportionallyUpOrDown]; [dockImageView setImage:image]; // add it to the NSDockTile [dockTile setContentView: dockImageView]; [dockTile display]; [dockImageView release]; } // Obtains the image of the Dock icon, either manually set, a drawn copy, or the default NSApplicationIcon + (NSImage *)_dockIconImage { AWT_ASSERT_APPKIT_THREAD; NSDockTile *dockTile = [NSApp dockTile]; NSView *view = [dockTile contentView]; if ([view isKindOfClass:[NSImageView class]]) { NSImage *img = [((NSImageView *)view) image]; if (img) return img; } if (view == nil) { return [NSImage imageNamed:@"NSApplicationIcon"]; } NSRect frame = [view frame]; NSImage *image = [[NSImage alloc] initWithSize:frame.size]; [image lockFocus]; [view drawRect:frame]; [image unlockFocus]; [image autorelease]; return image; } @end #pragma mark Native JNI calls /* * Class: com_apple_eawt_Application * Method: nativeInitializeApplicationDelegate * Signature: ()V */ JNIEXPORT void JNICALL Java_com_apple_eawt_Application_nativeInitializeApplicationDelegate (JNIEnv *env, jclass clz) { JNF_COCOA_ENTER(env); // Force initialization to happen on AppKit thread! [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ [ApplicationDelegate sharedDelegate]; }]; JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppEventHandler * Method: nativeOpenCocoaAboutWindow * Signature: ()V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeOpenCocoaAboutWindow (JNIEnv *env, jclass clz) { JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ [NSApp orderFrontStandardAboutPanel:nil]; }]; JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppEventHandler * Method: nativeReplyToAppShouldTerminate * Signature: (Z)V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeReplyToAppShouldTerminate (JNIEnv *env, jclass clz, jboolean doTerminate) { JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ [NSApp replyToApplicationShouldTerminate:doTerminate]; }]; JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppEventHandler * Method: nativeRegisterForNotification * Signature: (I)V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeRegisterForNotification (JNIEnv *env, jclass clz, jint notificationType) { JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(_registerForNotification:) on:[ApplicationDelegate class] withObject:[NSNumber numberWithInt:notificationType] waitUntilDone:NO]; // AWT_THREADING Safe (non-blocking) JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppDockIconHandler * Method: nativeSetDockMenu * Signature: (J)V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockMenu (JNIEnv *env, jclass clz, jlong nsMenuPtr) { JNF_COCOA_ENTER(env); NSMenu *menu = (NSMenu *)jlong_to_ptr(nsMenuPtr); [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ [ApplicationDelegate sharedDelegate].fDockMenu = menu; }]; JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppDockIconHandler * Method: nativeSetDockIconImage * Signature: (J)V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconImage (JNIEnv *env, jclass clz, jlong nsImagePtr) { JNF_COCOA_ENTER(env); NSImage *_image = (NSImage *)jlong_to_ptr(nsImagePtr); [ThreadUtilities performOnMainThread:@selector(_setDockIconImage:) on:[ApplicationDelegate class] withObject:_image waitUntilDone:NO]; JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppDockIconHandler * Method: nativeGetDockIconImage * Signature: ()J */ JNIEXPORT jlong JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeGetDockIconImage (JNIEnv *env, jclass clz) { __block NSImage *image = nil; JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ image = [ApplicationDelegate _dockIconImage]; CFRetain(image); }]; JNF_COCOA_EXIT(env); return ptr_to_jlong(image); } /* * Class: com_apple_eawt__AppDockIconHandler * Method: nativeSetDockIconBadge * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconBadge (JNIEnv *env, jclass clz, jstring badge) { JNF_COCOA_ENTER(env); NSString *badgeString = JNFJavaToNSString(env, badge); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ NSDockTile *dockTile = [NSApp dockTile]; [dockTile setBadgeLabel:badgeString]; [dockTile display]; }]; JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppMiscHandlers * Method: nativeRequestActivation * Signature: (Z)V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeRequestActivation (JNIEnv *env, jclass clz, jboolean allWindows) { JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ NSApplicationActivationOptions options = allWindows ? NSApplicationActivateAllWindows : 0; options |= NSApplicationActivateIgnoringOtherApps; // without this, nothing happens! [[NSRunningApplication currentApplication] activateWithOptions:options]; }]; JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppMiscHandlers * Method: nativeRequestUserAttention * Signature: (Z)V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeRequestUserAttention (JNIEnv *env, jclass clz, jboolean critical) { JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ [NSApp requestUserAttention:critical ? NSCriticalRequest : NSInformationalRequest]; }]; JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppMiscHandlers * Method: nativeOpenHelpViewer * Signature: ()V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeOpenHelpViewer (JNIEnv *env, jclass clz) { JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThread:@selector(showHelp:) on:NSApp withObject:nil waitUntilDone:NO]; JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppMiscHandlers * Method: nativeEnableSuddenTermination * Signature: ()V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeEnableSuddenTermination (JNIEnv *env, jclass clz) { JNF_COCOA_ENTER(env); [[NSProcessInfo processInfo] enableSuddenTermination]; // Foundation thread-safe JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppMiscHandlers * Method: nativeDisableSuddenTermination * Signature: ()V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeDisableSuddenTermination (JNIEnv *env, jclass clz) { JNF_COCOA_ENTER(env); [[NSProcessInfo processInfo] disableSuddenTermination]; // Foundation thread-safe JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppMenuBarHandler * Method: nativeSetMenuState * Signature: (IZZ)V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMenuBarHandler_nativeSetMenuState (JNIEnv *env, jclass clz, jint menuID, jboolean visible, jboolean enabled) { JNF_COCOA_ENTER(env); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate]; switch (menuID) { case com_apple_eawt__AppMenuBarHandler_MENU_ABOUT: [delegate _updateAboutMenu:visible enabled:enabled]; break; case com_apple_eawt__AppMenuBarHandler_MENU_PREFS: [delegate _updatePreferencesMenu:visible enabled:enabled]; break; } }]; JNF_COCOA_EXIT(env); } /* * Class: com_apple_eawt__AppMenuBarHandler * Method: nativeSetDefaultMenuBar * Signature: (J)V */ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMenuBarHandler_nativeSetDefaultMenuBar (JNIEnv *env, jclass clz, jlong cMenuBarPtr) { JNF_COCOA_ENTER(env); CMenuBar *menu = (CMenuBar *)jlong_to_ptr(cMenuBarPtr); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ [ApplicationDelegate sharedDelegate].fDefaultMenuBar = menu; }]; JNF_COCOA_EXIT(env); }