1 /* 2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #import "ApplicationDelegate.h" 27 28 #import "com_apple_eawt_Application.h" 29 #import "com_apple_eawt__AppDockIconHandler.h" 30 #import "com_apple_eawt__AppEventHandler.h" 31 #import "com_apple_eawt__AppMenuBarHandler.h" 32 #import "com_apple_eawt__AppMenuBarHandler.h" 33 #import "com_apple_eawt__AppMiscHandlers.h" 34 35 #import <JavaNativeFoundation/JavaNativeFoundation.h> 36 37 #import "CPopupMenu.h" 38 #import "ThreadUtilities.h" 39 #import "NSApplicationAWT.h" 40 41 42 #pragma mark App Menu helpers 43 44 // The following is a AWT convention? 45 #define PREFERENCES_TAG 42 46 47 static void addMenuItem(NSMenuItem* menuItem, NSInteger index) { 48 AWT_ASSERT_APPKIT_THREAD; 49 50 NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu]; 51 NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu]; 52 53 [appMenu insertItem:menuItem atIndex:index]; 54 [appMenu insertItem:[NSMenuItem separatorItem] atIndex:index + 1]; // Add the following separator 55 } 56 57 static void removeMenuItem(NSMenuItem* menuItem) { 58 AWT_ASSERT_APPKIT_THREAD; 59 60 NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu]; 61 NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu]; 62 63 NSInteger index = [appMenu indexOfItem:menuItem]; 64 if (index < 0) return; // something went wrong 65 66 [appMenu removeItemAtIndex:index + 1]; // Get the following separator 67 [appMenu removeItem:menuItem]; 68 } 69 70 @interface NSBundle (EAWTOverrides) 71 - (BOOL)_hasEAWTOverride:(NSString *)key; 72 @end 73 74 75 @implementation NSBundle (EAWTOverrides) 76 77 - (BOOL)_hasEAWTOverride:(NSString *)key { 78 return [[[[self objectForInfoDictionaryKey:@"Java"] objectForKey:@"EAWTOverride"] objectForKey:key] boolValue]; 79 } 80 81 @end 82 83 84 // used by JavaRuntimeSupport.framework's [JRSAppKitAWT awtAppDelegate] 85 // to expose our app delegate to the SWT or other apps that have knoledge 86 // of Java's AWT and want to install their own app delegate that will delegate 87 // to the AWT for some operations 88 89 @interface JavaAWTAppDelegateLoader : NSObject { } 90 @end 91 92 @implementation JavaAWTAppDelegateLoader 93 + (ApplicationDelegate *) awtAppDelegate { 94 return [ApplicationDelegate sharedDelegate]; 95 } 96 @end 97 98 99 @implementation ApplicationDelegate 100 101 @synthesize fPreferencesMenu; 102 @synthesize fAboutMenu; 103 104 @synthesize fDockMenu; 105 @synthesize fDefaultMenuBar; 106 107 108 + (ApplicationDelegate *)sharedDelegate { 109 static ApplicationDelegate *sApplicationDelegate = nil; 110 static BOOL checked = NO; 111 112 if (sApplicationDelegate != nil) return sApplicationDelegate; 113 if (checked) return nil; 114 115 AWT_ASSERT_APPKIT_THREAD; 116 117 // don't install the EAWT delegate if another kind of NSApplication is installed, like say, Safari 118 BOOL shouldInstall = NO; 119 if (NSApp != nil) { 120 if ([NSApp isMemberOfClass:[NSApplication class]]) shouldInstall = YES; 121 if ([NSApp isKindOfClass:[NSApplicationAWT class]]) shouldInstall = YES; 122 } 123 checked = YES; 124 if (!shouldInstall) return nil; 125 126 sApplicationDelegate = [[ApplicationDelegate alloc] init]; 127 return sApplicationDelegate; 128 } 129 130 - (void)_updatePreferencesMenu:(BOOL)prefsAvailable enabled:(BOOL)prefsEnabled { 131 AWT_ASSERT_APPKIT_THREAD; 132 133 if (prefsAvailable) { 134 // Make sure Prefs is around 135 if ([self.fPreferencesMenu menu] == nil) { 136 // Position of Prefs depends upon About availability. 137 NSInteger index = ([self.fAboutMenu menu] != nil) ? 2 : 0; 138 139 addMenuItem(self.fPreferencesMenu, index); 140 } 141 142 if (prefsEnabled) { 143 [self.fPreferencesMenu setEnabled:YES]; 144 [self.fPreferencesMenu setTarget:self]; 145 [self.fPreferencesMenu setAction:@selector(_preferencesMenuHandler)]; 146 } else { 147 [self.fPreferencesMenu setEnabled:NO]; 148 [self.fPreferencesMenu setTarget:nil]; 149 [self.fPreferencesMenu setAction:nil]; 150 } 151 } else { 152 if ([self.fPreferencesMenu menu] == nil) return; 153 154 // Remove the preferences item 155 removeMenuItem(self.fPreferencesMenu); 156 } 157 } 158 159 - (void)_updateAboutMenu:(BOOL)aboutAvailable enabled:(BOOL)aboutEnabled { 160 AWT_ASSERT_APPKIT_THREAD; 161 162 if (aboutAvailable) { 163 // Make sure About is around 164 if ([self.fAboutMenu menu] == nil) { 165 addMenuItem(self.fAboutMenu, 0); 166 } 167 168 if (aboutEnabled) { 169 [self.fAboutMenu setEnabled:YES]; 170 [self.fAboutMenu setTarget:self]; 171 [self.fAboutMenu setAction:@selector(_aboutMenuHandler)]; 172 } else { 173 [self.fAboutMenu setEnabled:NO]; 174 [self.fAboutMenu setTarget:nil]; 175 [self.fAboutMenu setAction:nil]; 176 } 177 } else { 178 if ([self.fAboutMenu menu] == nil) return; 179 180 // Remove About item. 181 removeMenuItem(self.fAboutMenu); 182 } 183 } 184 185 - (id) init { 186 AWT_ASSERT_APPKIT_THREAD; 187 188 self = [super init]; 189 if (!self) return self; 190 191 // Prep for about and preferences menu 192 BOOL usingDefaultNib = YES; 193 if ([NSApp isKindOfClass:[NSApplicationAWT class]]) { 194 usingDefaultNib = [NSApp usingDefaultNib]; 195 } 196 if (!usingDefaultNib) return self; 197 198 NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu]; 199 NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu]; 200 201 self.fPreferencesMenu = (NSMenuItem*)[appMenu itemWithTag:PREFERENCES_TAG]; 202 self.fAboutMenu = (NSMenuItem*)[appMenu itemAtIndex:0]; 203 204 // If the java application has a bundle with an Info.plist file with 205 // a CFBundleDocumentTypes entry, then it is set up to handle Open Doc 206 // and Print Doc commands for these files. Therefore java AWT will 207 // cache Open Doc and Print Doc events that are sent prior to a 208 // listener being installed by the client java application. 209 NSBundle *bundle = [NSBundle mainBundle]; 210 fHandlesDocumentTypes = [bundle objectForInfoDictionaryKey:@"CFBundleDocumentTypes"] != nil || [bundle _hasEAWTOverride:@"DocumentHandler"]; 211 fHandlesURLTypes = [bundle objectForInfoDictionaryKey:@"CFBundleURLTypes"] != nil || [bundle _hasEAWTOverride:@"URLHandler"]; 212 if (fHandlesURLTypes) { 213 [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self 214 andSelector:@selector(_handleOpenURLEvent:withReplyEvent:) 215 forEventClass:kInternetEventClass 216 andEventID:kAEGetURL]; 217 } 218 219 // By HIG, Preferences are not available unless there is a handler. By default in Mac OS X, 220 // there is not a handler, but it is in the nib file for convenience. 221 removeMenuItem(self.fPreferencesMenu); 222 223 [self _updateAboutMenu:YES enabled:YES]; 224 225 // Now that the AppKit objects are known and set up, initialize the model data 226 BOOL aboutAvailable = ([self.fAboutMenu menu] != nil); 227 BOOL aboutEnabled = (aboutAvailable && [self.fAboutMenu isEnabled] && ([self.fAboutMenu target] != nil)); 228 229 BOOL prefsAvailable = ([self.fPreferencesMenu menu] != nil); 230 BOOL prefsEnabled = (prefsAvailable && [self.fPreferencesMenu isEnabled] && ([self.fPreferencesMenu target] != nil)); 231 232 JNIEnv *env = [ThreadUtilities getJNIEnv]; 233 static JNF_CLASS_CACHE(sjc_AppMenuBarHandler, "com/apple/eawt/_AppMenuBarHandler"); 234 static JNF_STATIC_MEMBER_CACHE(sjm_initMenuStates, sjc_AppMenuBarHandler, "initMenuStates", "(ZZZZ)V"); 235 JNFCallStaticVoidMethod(env, sjm_initMenuStates, aboutAvailable, aboutEnabled, prefsAvailable, prefsEnabled); 236 237 // register for the finish launching and system power off notifications by default 238 NSNotificationCenter *ctr = [NSNotificationCenter defaultCenter]; 239 Class clz = [ApplicationDelegate class]; 240 [ctr addObserver:clz selector:@selector(_willFinishLaunching) name:NSApplicationWillFinishLaunchingNotification object:nil]; 241 [ctr addObserver:clz selector:@selector(_systemWillPowerOff) name:NSWorkspaceWillPowerOffNotification object:nil]; 242 [ctr addObserver:clz selector:@selector(_appDidActivate) name:NSApplicationDidBecomeActiveNotification object:nil]; 243 [ctr addObserver:clz selector:@selector(_appDidDeactivate) name:NSApplicationDidResignActiveNotification object:nil]; 244 [ctr addObserver:clz selector:@selector(_appDidHide) name:NSApplicationDidHideNotification object:nil]; 245 [ctr addObserver:clz selector:@selector(_appDidUnhide) name:NSApplicationDidUnhideNotification object:nil]; 246 247 return self; 248 } 249 250 - (void)dealloc { 251 self.fPreferencesMenu = nil; 252 self.fAboutMenu = nil; 253 self.fDockMenu = nil; 254 self.fDefaultMenuBar = nil; 255 256 [super dealloc]; 257 } 258 259 #pragma mark Callbacks from AppKit 260 261 static JNF_CLASS_CACHE(sjc_AppEventHandler, "com/apple/eawt/_AppEventHandler"); 262 263 - (void)_handleOpenURLEvent:(NSAppleEventDescriptor *)openURLEvent withReplyEvent:(NSAppleEventDescriptor *)replyEvent { 264 AWT_ASSERT_APPKIT_THREAD; 265 if (!fHandlesURLTypes) return; 266 267 NSString *url = [[openURLEvent paramDescriptorForKeyword:keyDirectObject] stringValue]; 268 269 //fprintf(stderr,"jm_handleOpenURL\n"); 270 JNIEnv *env = [ThreadUtilities getJNIEnv]; 271 jstring jURL = JNFNSToJavaString(env, url); 272 static JNF_STATIC_MEMBER_CACHE(jm_handleOpenURI, sjc_AppEventHandler, "handleOpenURI", "(Ljava/lang/String;)V"); 273 JNFCallStaticVoidMethod(env, jm_handleOpenURI, jURL); // AWT_THREADING Safe (event) 274 (*env)->DeleteLocalRef(env, jURL); 275 276 [replyEvent insertDescriptor:[NSAppleEventDescriptor nullDescriptor] atIndex:0]; 277 } 278 279 // Helper for both open file and print file methods 280 // Creates a Java list of files from a native list of files 281 - (jobject)_createFilePathArrayFrom:(NSArray *)filenames withEnv:(JNIEnv *)env { 282 static JNF_CLASS_CACHE(sjc_ArrayList, "java/util/ArrayList"); 283 static JNF_CTOR_CACHE(jm_ArrayList_ctor, sjc_ArrayList, "(I)V"); 284 static JNF_MEMBER_CACHE(jm_ArrayList_add, sjc_ArrayList, "add", "(Ljava/lang/Object;)Z"); 285 286 jobject jFileNamesArray = JNFNewObject(env, jm_ArrayList_ctor, (jint)[filenames count]); // AWT_THREADING Safe (known object) 287 for (NSString *filename in filenames) { 288 jstring jFileName = JNFNormalizedJavaStringForPath(env, filename); 289 JNFCallVoidMethod(env, jFileNamesArray, jm_ArrayList_add, jFileName); 290 } 291 292 return jFileNamesArray; 293 } 294 295 // Open file handler 296 - (void)application:(NSApplication *)theApplication openFiles:(NSArray *)fileNames { 297 AWT_ASSERT_APPKIT_THREAD; 298 if (!fHandlesDocumentTypes) { 299 [theApplication replyToOpenOrPrint:NSApplicationDelegateReplyCancel]; 300 return; 301 } 302 303 //fprintf(stderr,"jm_handleOpenFile\n"); 304 JNIEnv *env = [ThreadUtilities getJNIEnv]; 305 306 // if these files were opened from a Spotlight query, try to get the search text from the current AppleEvent 307 NSAppleEventDescriptor *currentEvent = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent]; 308 NSString *searchString = [[currentEvent paramDescriptorForKeyword:keyAESearchText] stringValue]; 309 jstring jSearchString = JNFNSToJavaString(env, searchString); 310 311 // convert the file names array 312 jobject jFileNamesArray = [self _createFilePathArrayFrom:fileNames withEnv:env]; 313 314 static JNF_STATIC_MEMBER_CACHE(jm_handleOpenFiles, sjc_AppEventHandler, "handleOpenFiles", "(Ljava/util/List;Ljava/lang/String;)V"); 315 JNFCallStaticVoidMethod(env, jm_handleOpenFiles, jFileNamesArray, jSearchString); 316 (*env)->DeleteLocalRef(env, jFileNamesArray); 317 (*env)->DeleteLocalRef(env, jSearchString); 318 319 [theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; 320 } 321 322 // Print handler 323 - (NSApplicationPrintReply)application:(NSApplication *)application printFiles:(NSArray *)fileNames withSettings:(NSDictionary *)printSettings showPrintPanels:(BOOL)showPrintPanels { 324 AWT_ASSERT_APPKIT_THREAD; 325 if (!fHandlesDocumentTypes) return NSPrintingCancelled; 326 327 //fprintf(stderr,"jm_handlePrintFile\n"); 328 JNIEnv *env = [ThreadUtilities getJNIEnv]; 329 jobject jFileNamesArray = [self _createFilePathArrayFrom:fileNames withEnv:env]; 330 static JNF_STATIC_MEMBER_CACHE(jm_handlePrintFile, sjc_AppEventHandler, "handlePrintFiles", "(Ljava/util/List;)V"); 331 JNFCallStaticVoidMethod(env, jm_handlePrintFile, jFileNamesArray); // AWT_THREADING Safe (event) 332 (*env)->DeleteLocalRef(env, jFileNamesArray); 333 334 return NSPrintingSuccess; 335 } 336 337 // Open app handler, registered in -init 338 + (void)_notifyJava:(jint)notificationType { 339 AWT_ASSERT_APPKIT_THREAD; 340 341 //fprintf(stderr,"jm_handleOpenApplication\n"); 342 JNIEnv *env = [ThreadUtilities getJNIEnv]; 343 static JNF_STATIC_MEMBER_CACHE(jm_handleNativeNotification, sjc_AppEventHandler, "handleNativeNotification", "(I)V"); 344 JNFCallStaticVoidMethod(env, jm_handleNativeNotification, notificationType); // AWT_THREADING Safe (event) 345 } 346 347 // About menu handler 348 - (void)_aboutMenuHandler { 349 [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_ABOUT]; 350 } 351 352 // Preferences handler 353 - (void)_preferencesMenuHandler { 354 [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_PREFS]; 355 } 356 357 // Open app handler, registered in -init 358 + (void)_willFinishLaunching { 359 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_OPEN_APP]; 360 } 361 362 // ReOpen app handler 363 - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag { 364 [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_REOPEN_APP]; 365 return YES; 366 } 367 368 // Quit handler 369 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app { 370 [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_QUIT]; 371 return NSTerminateLater; 372 } 373 374 + (void)_systemWillPowerOff { 375 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SHUTDOWN]; 376 } 377 378 + (void)_appDidActivate { 379 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_ACTIVE_APP_GAINED]; 380 } 381 382 + (void)_appDidDeactivate { 383 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_ACTIVE_APP_LOST]; 384 } 385 386 + (void)_appDidHide { 387 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_APP_HIDDEN]; 388 } 389 390 + (void)_appDidUnhide { 391 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_APP_SHOWN]; 392 } 393 394 + (void)_sessionDidActivate { 395 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_USER_SESSION_ACTIVE]; 396 } 397 398 + (void)_sessionDidDeactivate { 399 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_USER_SESSION_INACTIVE]; 400 } 401 402 + (void)_screenDidSleep { 403 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SCREEN_SLEEP]; 404 } 405 406 + (void)_screenDidWake { 407 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SCREEN_WAKE]; 408 } 409 410 + (void)_systemDidSleep { 411 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SYSTEM_SLEEP]; 412 } 413 414 + (void)_systemDidWake { 415 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SYSTEM_WAKE]; 416 } 417 418 + (void)_registerForNotification:(NSNumber *)notificationTypeNum { 419 NSNotificationCenter *ctr = [[NSWorkspace sharedWorkspace] notificationCenter]; 420 Class clz = [ApplicationDelegate class]; 421 422 jint notificationType = [notificationTypeNum intValue]; 423 switch (notificationType) { 424 case com_apple_eawt__AppEventHandler_REGISTER_USER_SESSION: 425 [ctr addObserver:clz selector:@selector(_sessionDidActivate) name:NSWorkspaceSessionDidBecomeActiveNotification object:nil]; 426 [ctr addObserver:clz selector:@selector(_sessionDidDeactivate) name:NSWorkspaceSessionDidResignActiveNotification object:nil]; 427 break; 428 case com_apple_eawt__AppEventHandler_REGISTER_SCREEN_SLEEP: 429 [ctr addObserver:clz selector:@selector(_screenDidSleep) name:NSWorkspaceScreensDidSleepNotification object:nil]; 430 [ctr addObserver:clz selector:@selector(_screenDidWake) name:NSWorkspaceScreensDidWakeNotification object:nil]; 431 break; 432 case com_apple_eawt__AppEventHandler_REGISTER_SYSTEM_SLEEP: 433 [ctr addObserver:clz selector:@selector(_systemDidSleep) name:NSWorkspaceWillSleepNotification object:nil]; 434 [ctr addObserver:clz selector:@selector(_systemDidWake) name:NSWorkspaceDidWakeNotification object:nil]; 435 break; 436 default: 437 NSLog(@"EAWT attempting to register for unknown notification: %d", (int)notificationType); 438 break; 439 } 440 } 441 442 // Retrieves the menu to be attached to the Dock icon (AppKit callback) 443 - (NSMenu *)applicationDockMenu:(NSApplication *)sender { 444 AWT_ASSERT_APPKIT_THREAD; 445 return self.fDockMenu; 446 } 447 448 - (CMenuBar *)defaultMenuBar { 449 return [[self.fDefaultMenuBar retain] autorelease]; 450 } 451 452 453 #pragma mark Helpers called on the main thread from Java 454 455 // Sets a new NSImageView on the Dock tile 456 + (void)_setDockIconImage:(NSImage *)image { 457 AWT_ASSERT_APPKIT_THREAD; 458 459 NSDockTile *dockTile = [NSApp dockTile]; 460 if (image == nil) { 461 [dockTile setContentView:nil]; 462 return; 463 } 464 465 // setup an image view for the dock tile 466 NSRect frame = NSMakeRect(0, 0, dockTile.size.width, dockTile.size.height); 467 NSImageView *dockImageView = [[NSImageView alloc] initWithFrame: frame]; 468 [dockImageView setImageScaling:NSImageScaleProportionallyUpOrDown]; 469 [dockImageView setImage:image]; 470 471 // add it to the NSDockTile 472 [dockTile setContentView: dockImageView]; 473 [dockTile display]; 474 475 [dockImageView release]; 476 } 477 478 // Obtains the image of the Dock icon, either manually set, a drawn copy, or the default NSApplicationIcon 479 + (NSImage *)_dockIconImage { 480 AWT_ASSERT_APPKIT_THREAD; 481 482 NSDockTile *dockTile = [NSApp dockTile]; 483 NSView *view = [dockTile contentView]; 484 485 if ([view isKindOfClass:[NSImageView class]]) { 486 NSImage *img = [((NSImageView *)view) image]; 487 if (img) return img; 488 } 489 490 if (view == nil) { 491 return [NSImage imageNamed:@"NSApplicationIcon"]; 492 } 493 494 NSRect frame = [view frame]; 495 NSImage *image = [[NSImage alloc] initWithSize:frame.size]; 496 [image lockFocus]; 497 [view drawRect:frame]; 498 [image unlockFocus]; 499 [image autorelease]; 500 return image; 501 } 502 503 @end 504 505 506 #pragma mark Native JNI calls 507 508 /* 509 * Class: com_apple_eawt_Application 510 * Method: nativeInitializeApplicationDelegate 511 * Signature: ()V 512 */ 513 JNIEXPORT void JNICALL Java_com_apple_eawt_Application_nativeInitializeApplicationDelegate 514 (JNIEnv *env, jclass clz) 515 { 516 JNF_COCOA_ENTER(env); 517 // Force initialization to happen on AppKit thread! 518 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ 519 [ApplicationDelegate sharedDelegate]; 520 }]; 521 JNF_COCOA_EXIT(env); 522 } 523 524 /* 525 * Class: com_apple_eawt__AppEventHandler 526 * Method: nativeOpenCocoaAboutWindow 527 * Signature: ()V 528 */ 529 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeOpenCocoaAboutWindow 530 (JNIEnv *env, jclass clz) 531 { 532 JNF_COCOA_ENTER(env); 533 534 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ 535 [NSApp orderFrontStandardAboutPanel:nil]; 536 }]; 537 538 JNF_COCOA_EXIT(env); 539 } 540 541 /* 542 * Class: com_apple_eawt__AppEventHandler 543 * Method: nativeReplyToAppShouldTerminate 544 * Signature: (Z)V 545 */ 546 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeReplyToAppShouldTerminate 547 (JNIEnv *env, jclass clz, jboolean doTerminate) 548 { 549 JNF_COCOA_ENTER(env); 550 551 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ 552 [NSApp replyToApplicationShouldTerminate:doTerminate]; 553 }]; 554 555 JNF_COCOA_EXIT(env); 556 } 557 558 /* 559 * Class: com_apple_eawt__AppEventHandler 560 * Method: nativeRegisterForNotification 561 * Signature: (I)V 562 */ 563 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeRegisterForNotification 564 (JNIEnv *env, jclass clz, jint notificationType) 565 { 566 JNF_COCOA_ENTER(env); 567 [ThreadUtilities performOnMainThread:@selector(_registerForNotification:) 568 on:[ApplicationDelegate class] 569 withObject:[NSNumber numberWithInt:notificationType] 570 waitUntilDone:NO]; // AWT_THREADING Safe (non-blocking) 571 JNF_COCOA_EXIT(env); 572 } 573 574 /* 575 * Class: com_apple_eawt__AppDockIconHandler 576 * Method: nativeSetDockMenu 577 * Signature: (J)V 578 */ 579 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockMenu 580 (JNIEnv *env, jclass clz, jlong nsMenuPtr) 581 { 582 JNF_COCOA_ENTER(env); 583 584 NSMenu *menu = (NSMenu *)jlong_to_ptr(nsMenuPtr); 585 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ 586 [ApplicationDelegate sharedDelegate].fDockMenu = menu; 587 }]; 588 589 JNF_COCOA_EXIT(env); 590 } 591 592 /* 593 * Class: com_apple_eawt__AppDockIconHandler 594 * Method: nativeSetDockIconImage 595 * Signature: (J)V 596 */ 597 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconImage 598 (JNIEnv *env, jclass clz, jlong nsImagePtr) 599 { 600 JNF_COCOA_ENTER(env); 601 602 NSImage *_image = (NSImage *)jlong_to_ptr(nsImagePtr); 603 [ThreadUtilities performOnMainThread:@selector(_setDockIconImage:) 604 on:[ApplicationDelegate class] 605 withObject:_image 606 waitUntilDone:NO]; 607 608 JNF_COCOA_EXIT(env); 609 } 610 611 /* 612 * Class: com_apple_eawt__AppDockIconHandler 613 * Method: nativeGetDockIconImage 614 * Signature: ()J 615 */ 616 JNIEXPORT jlong JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeGetDockIconImage 617 (JNIEnv *env, jclass clz) 618 { 619 __block NSImage *image = nil; 620 621 JNF_COCOA_ENTER(env); 622 623 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ 624 image = [[ApplicationDelegate _dockIconImage] retain]; 625 }]; 626 627 JNF_COCOA_EXIT(env); 628 629 return ptr_to_jlong(image); 630 } 631 632 /* 633 * Class: com_apple_eawt__AppDockIconHandler 634 * Method: nativeSetDockIconBadge 635 * Signature: (Ljava/lang/String;)V 636 */ 637 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconBadge 638 (JNIEnv *env, jclass clz, jstring badge) 639 { 640 JNF_COCOA_ENTER(env); 641 642 NSString *badgeString = JNFJavaToNSString(env, badge); 643 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ 644 NSDockTile *dockTile = [NSApp dockTile]; 645 [dockTile setBadgeLabel:badgeString]; 646 [dockTile display]; 647 }]; 648 649 JNF_COCOA_EXIT(env); 650 } 651 652 /* 653 * Class: com_apple_eawt__AppMiscHandlers 654 * Method: nativeRequestActivation 655 * Signature: (Z)V 656 */ 657 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeRequestActivation 658 (JNIEnv *env, jclass clz, jboolean allWindows) 659 { 660 JNF_COCOA_ENTER(env); 661 662 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ 663 NSApplicationActivationOptions options = allWindows ? NSApplicationActivateAllWindows : 0; 664 options |= NSApplicationActivateIgnoringOtherApps; // without this, nothing happens! 665 [[NSRunningApplication currentApplication] activateWithOptions:options]; 666 }]; 667 668 JNF_COCOA_EXIT(env); 669 } 670 671 /* 672 * Class: com_apple_eawt__AppMiscHandlers 673 * Method: nativeRequestUserAttention 674 * Signature: (Z)V 675 */ 676 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeRequestUserAttention 677 (JNIEnv *env, jclass clz, jboolean critical) 678 { 679 JNF_COCOA_ENTER(env); 680 681 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ 682 [NSApp requestUserAttention:critical ? NSCriticalRequest : NSInformationalRequest]; 683 }]; 684 685 JNF_COCOA_EXIT(env); 686 } 687 688 /* 689 * Class: com_apple_eawt__AppMiscHandlers 690 * Method: nativeOpenHelpViewer 691 * Signature: ()V 692 */ 693 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeOpenHelpViewer 694 (JNIEnv *env, jclass clz) 695 { 696 JNF_COCOA_ENTER(env); 697 698 [ThreadUtilities performOnMainThread:@selector(showHelp:) 699 on:NSApp 700 withObject:nil 701 waitUntilDone:NO]; 702 703 JNF_COCOA_EXIT(env); 704 } 705 706 /* 707 * Class: com_apple_eawt__AppMiscHandlers 708 * Method: nativeEnableSuddenTermination 709 * Signature: ()V 710 */ 711 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeEnableSuddenTermination 712 (JNIEnv *env, jclass clz) 713 { 714 JNF_COCOA_ENTER(env); 715 716 [[NSProcessInfo processInfo] enableSuddenTermination]; // Foundation thread-safe 717 718 JNF_COCOA_EXIT(env); 719 } 720 721 /* 722 * Class: com_apple_eawt__AppMiscHandlers 723 * Method: nativeDisableSuddenTermination 724 * Signature: ()V 725 */ 726 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeDisableSuddenTermination 727 (JNIEnv *env, jclass clz) 728 { 729 JNF_COCOA_ENTER(env); 730 731 [[NSProcessInfo processInfo] disableSuddenTermination]; // Foundation thread-safe 732 733 JNF_COCOA_EXIT(env); 734 } 735 736 /* 737 * Class: com_apple_eawt__AppMenuBarHandler 738 * Method: nativeSetMenuState 739 * Signature: (IZZ)V 740 */ 741 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMenuBarHandler_nativeSetMenuState 742 (JNIEnv *env, jclass clz, jint menuID, jboolean visible, jboolean enabled) 743 { 744 JNF_COCOA_ENTER(env); 745 746 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ 747 ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate]; 748 switch (menuID) { 749 case com_apple_eawt__AppMenuBarHandler_MENU_ABOUT: 750 [delegate _updateAboutMenu:visible enabled:enabled]; 751 break; 752 case com_apple_eawt__AppMenuBarHandler_MENU_PREFS: 753 [delegate _updatePreferencesMenu:visible enabled:enabled]; 754 break; 755 } 756 }]; 757 758 JNF_COCOA_EXIT(env); 759 } 760 761 /* 762 * Class: com_apple_eawt__AppMenuBarHandler 763 * Method: nativeSetDefaultMenuBar 764 * Signature: (J)V 765 */ 766 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMenuBarHandler_nativeSetDefaultMenuBar 767 (JNIEnv *env, jclass clz, jlong cMenuBarPtr) 768 { 769 JNF_COCOA_ENTER(env); 770 771 CMenuBar *menu = (CMenuBar *)jlong_to_ptr(cMenuBarPtr); 772 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ 773 [ApplicationDelegate sharedDelegate].fDefaultMenuBar = menu; 774 }]; 775 776 JNF_COCOA_EXIT(env); 777 }