author | anashaty |
Tue, 20 Jan 2015 19:26:14 +0300 | |
changeset 28990 | 2656e19f0cd6 |
parent 26751 | 70bac69b37c9 |
child 36903 | addc2e9d4bd4 |
permissions | -rw-r--r-- |
12047 | 1 |
/* |
23651
e41298d0da2f
8037099: [macosx] Remove all references to GC from native OBJ-C code
pchelko
parents:
23010
diff
changeset
|
2 |
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. |
12047 | 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! |
|
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
518 |
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){ |
12047 | 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 |
||
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
534 |
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){ |
12047 | 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 |
||
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
551 |
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){ |
12047 | 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:) |
|
15985
b9e25a486549
8006634: Unify LWCToolkit.invokeAndWait() and sun.awt.datatransfer.ToolkitThreadBlockedHandler
pchelko
parents:
15322
diff
changeset
|
568 |
on:[ApplicationDelegate class] |
12047 | 569 |
withObject:[NSNumber numberWithInt:notificationType] |
15985
b9e25a486549
8006634: Unify LWCToolkit.invokeAndWait() and sun.awt.datatransfer.ToolkitThreadBlockedHandler
pchelko
parents:
15322
diff
changeset
|
570 |
waitUntilDone:NO]; // AWT_THREADING Safe (non-blocking) |
12047 | 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); |
|
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
585 |
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){ |
12047 | 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); |
|
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
603 |
[ThreadUtilities performOnMainThread:@selector(_setDockIconImage:) |
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
604 |
on:[ApplicationDelegate class] |
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
605 |
withObject:_image |
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
606 |
waitUntilDone:NO]; |
12047 | 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 |
||
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
623 |
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){ |
23651
e41298d0da2f
8037099: [macosx] Remove all references to GC from native OBJ-C code
pchelko
parents:
23010
diff
changeset
|
624 |
image = [[ApplicationDelegate _dockIconImage] retain]; |
12047 | 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); |
|
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
643 |
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){ |
12047 | 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 |
||
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
662 |
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){ |
12047 | 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 |
||
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
681 |
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){ |
12047 | 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 |
||
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
698 |
[ThreadUtilities performOnMainThread:@selector(showHelp:) |
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
699 |
on:NSApp |
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
700 |
withObject:nil |
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
701 |
waitUntilDone:NO]; |
12047 | 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 |
||
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
746 |
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){ |
12047 | 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); |
|
15322
3638f33225ec
7179050: [macosx] Make LWAWT be able to run on AppKit thread
serb
parents:
12047
diff
changeset
|
772 |
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){ |
12047 | 773 |
[ApplicationDelegate sharedDelegate].fDefaultMenuBar = menu; |
774 |
}]; |
|
775 |
||
776 |
JNF_COCOA_EXIT(env); |
|
777 |
} |