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