Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/native_NOTIOS/sun/awt/CMenuBar.m
38829 views
1
/*
2
* Copyright (c) 2011, 2016, 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 <AppKit/AppKit.h>
27
#import <JavaNativeFoundation/JavaNativeFoundation.h>
28
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
29
30
31
#import "CMenuBar.h"
32
#import "CMenu.h"
33
#import "ThreadUtilities.h"
34
35
#import "sun_lwawt_macosx_CMenuBar.h"
36
37
__attribute__((visibility("default")))
38
NSString *CMenuBarDidReuseItemNotification =
39
@"CMenuBarDidReuseItemNotification";
40
41
static CMenuBar *sActiveMenuBar = nil;
42
static NSMenu *sDefaultHelpMenu = nil;
43
static BOOL sSetupHelpMenu = NO;
44
45
@interface CMenuBar (CMenuBar_Private)
46
+ (void) addDefaultHelpMenu;
47
@end
48
49
@implementation CMenuBar
50
51
+ (void)clearMenuBarExcludingAppleMenu_OnAppKitThread:(BOOL) excludingAppleMenu {
52
AWT_ASSERT_APPKIT_THREAD;
53
// Remove all Java menus from the main bar.
54
NSMenu *theMainMenu = [NSApp mainMenu];
55
NSUInteger i, menuCount = [theMainMenu numberOfItems];
56
57
for (i = menuCount; i > 1; i--) {
58
NSUInteger index = i-1;
59
60
NSMenuItem *currItem = [theMainMenu itemAtIndex:index];
61
NSMenu *currMenu = [currItem submenu];
62
63
if (excludingAppleMenu && ![currMenu isJavaMenu]) {
64
continue;
65
}
66
[currItem setSubmenu:nil];
67
[theMainMenu removeItemAtIndex:index];
68
}
69
70
[CMenuBar addDefaultHelpMenu];
71
}
72
73
+ (BOOL) isActiveMenuBar:(CMenuBar *)inMenuBar {
74
return (sActiveMenuBar == inMenuBar);
75
}
76
77
- (id) initWithPeer:(jobject)peer {
78
AWT_ASSERT_APPKIT_THREAD;
79
self = [super initWithPeer: peer];
80
if (self) {
81
fMenuList = [[NSMutableArray alloc] init];
82
}
83
return self;
84
}
85
86
-(void) dealloc {
87
[fMenuList release];
88
fMenuList = nil;
89
90
[fHelpMenu release];
91
fHelpMenu = nil;
92
93
[super dealloc];
94
}
95
96
+ (void) activate:(CMenuBar *)menubar modallyDisabled:(BOOL)modallyDisabled {
97
AWT_ASSERT_APPKIT_THREAD;
98
99
if (!menubar) {
100
[CMenuBar clearMenuBarExcludingAppleMenu_OnAppKitThread:YES];
101
return;
102
}
103
104
@synchronized([CMenuBar class]) {
105
sActiveMenuBar = menubar;
106
}
107
108
@synchronized(menubar) {
109
menubar->fModallyDisabled = modallyDisabled;
110
}
111
112
NSUInteger i = 0, newMenuListSize = [menubar->fMenuList count];
113
114
NSMenu *theMainMenu = [NSApp mainMenu];
115
NSUInteger menuIndex, menuCount = [theMainMenu numberOfItems];
116
117
NSUInteger cmenuIndex = 0, cmenuCount = newMenuListSize;
118
NSMutableArray *removedMenuArray = [NSMutableArray array];
119
120
for (menuIndex = 0; menuIndex < menuCount; menuIndex++) {
121
NSMenuItem *currItem = [theMainMenu itemAtIndex:menuIndex];
122
NSMenu *currMenu = [currItem submenu];
123
124
if ([currMenu isJavaMenu]) {
125
// Ready to replace, find next candidate
126
CMenu *newMenu = nil;
127
if (cmenuIndex < cmenuCount) {
128
newMenu = (CMenu *)[menubar->fMenuList objectAtIndex:cmenuIndex];
129
if (newMenu == menubar->fHelpMenu) {
130
cmenuIndex++;
131
if (cmenuIndex < cmenuCount) {
132
newMenu = (CMenu *)[menubar->fMenuList objectAtIndex:cmenuIndex];
133
}
134
}
135
}
136
if (newMenu) {
137
NSMenu *menuToAdd = [newMenu menu];
138
if ([theMainMenu indexOfItemWithSubmenu:menuToAdd] == -1) {
139
[[NSNotificationCenter defaultCenter] postNotificationName:CMenuBarDidReuseItemNotification object:theMainMenu];
140
141
[currItem setSubmenu:menuToAdd];
142
[currItem setTitle:[menuToAdd title]];
143
cmenuIndex++;
144
}
145
146
BOOL newEnabledState = [newMenu isEnabled] && !menubar->fModallyDisabled;
147
[currItem setEnabled:newEnabledState];
148
} else {
149
[removedMenuArray addObject:[NSNumber numberWithInteger:menuIndex]];
150
}
151
}
152
}
153
154
// Clean up extra items
155
NSUInteger removedIndex, removedCount = [removedMenuArray count];
156
for (removedIndex=removedCount; removedIndex > 0; removedIndex--) {
157
NSUInteger index = [[removedMenuArray objectAtIndex:(removedIndex-1)] integerValue];
158
NSMenuItem *currItem = [theMainMenu itemAtIndex:index];
159
[currItem setSubmenu:nil];
160
[theMainMenu removeItemAtIndex:index];
161
}
162
163
i = cmenuIndex;
164
165
// Add all of the menus in the menu list.
166
for (; i < newMenuListSize; i++) {
167
CMenu *newMenu = (CMenu *)[menubar->fMenuList objectAtIndex:i];
168
169
if (newMenu != menubar->fHelpMenu) {
170
NSArray *args = [NSArray arrayWithObjects:newMenu, [NSNumber numberWithInt:-1], nil];
171
[menubar nativeAddMenuAtIndex_OnAppKitThread:args];
172
}
173
}
174
175
// Add the help menu last.
176
if (menubar->fHelpMenu) {
177
NSArray *args = [NSArray arrayWithObjects:menubar->fHelpMenu, [NSNumber numberWithInt:-1], nil];
178
[menubar nativeAddMenuAtIndex_OnAppKitThread:args];
179
} else {
180
[CMenuBar addDefaultHelpMenu];
181
}
182
}
183
184
-(void) deactivate {
185
AWT_ASSERT_APPKIT_THREAD;
186
187
@synchronized([CMenuBar class]) {
188
sActiveMenuBar = nil;
189
}
190
191
@synchronized(self) {
192
fModallyDisabled = NO;
193
}
194
}
195
196
-(void) javaAddMenu: (CMenu *)theMenu {
197
@synchronized(self) {
198
[fMenuList addObject: theMenu];
199
}
200
201
if (self == sActiveMenuBar) {
202
NSArray *args = [[NSArray alloc] initWithObjects:theMenu, [NSNumber numberWithInt:-1], nil];
203
[ThreadUtilities performOnMainThread:@selector(nativeAddMenuAtIndex_OnAppKitThread:) on:self withObject:args waitUntilDone:YES];
204
[args release];
205
}
206
}
207
208
// This method is a special case for use by the screen menu bar.
209
// See ScreenMenuBar.java -- used to implement setVisible(boolean) by
210
// removing or adding the menu from the current menu bar's list.
211
-(void) javaAddMenu: (CMenu *)theMenu atIndex:(jint)index {
212
@synchronized(self) {
213
if (index == -1){
214
[fMenuList addObject:theMenu];
215
}else{
216
[fMenuList insertObject:theMenu atIndex:index];
217
}
218
}
219
220
if (self == sActiveMenuBar) {
221
NSArray *args = [[NSArray alloc] initWithObjects:theMenu, [NSNumber numberWithInt:index], nil];
222
[ThreadUtilities performOnMainThread:@selector(nativeAddMenuAtIndex_OnAppKitThread:) on:self withObject:args waitUntilDone:YES];
223
[args release];
224
}
225
}
226
227
- (NSInteger) javaIndexToNSMenuIndex_OnAppKitThread:(jint)javaIndex {
228
AWT_ASSERT_APPKIT_THREAD;
229
NSInteger returnValue = -1;
230
NSMenu *theMainMenu = [NSApp mainMenu];
231
232
if (javaIndex == -1) {
233
if (fHelpMenu) {
234
returnValue = [theMainMenu indexOfItemWithSubmenu:[fHelpMenu menu]];
235
}
236
} else {
237
CMenu *requestedMenu = [fMenuList objectAtIndex:javaIndex];
238
239
if (requestedMenu == fHelpMenu) {
240
returnValue = [theMainMenu indexOfItemWithSubmenu:[fHelpMenu menu]];
241
} else {
242
NSUInteger i, menuCount = [theMainMenu numberOfItems];
243
jint currJavaMenuIndex = 0;
244
for (i = 0; i < menuCount; i++) {
245
NSMenuItem *currItem = [theMainMenu itemAtIndex:i];
246
NSMenu *currMenu = [currItem submenu];
247
248
if ([currMenu isJavaMenu]) {
249
if (javaIndex == currJavaMenuIndex) {
250
returnValue = i;
251
break;
252
}
253
254
currJavaMenuIndex++;
255
}
256
}
257
}
258
}
259
260
return returnValue;
261
}
262
263
- (void) nativeAddMenuAtIndex_OnAppKitThread:(NSArray *)args {
264
AWT_ASSERT_APPKIT_THREAD;
265
CMenu *theNewMenu = (CMenu*)[args objectAtIndex:0];
266
jint index = [(NSNumber*)[args objectAtIndex:1] intValue];
267
NSApplication *theApp = [NSApplication sharedApplication];
268
NSMenu *theMainMenu = [theApp mainMenu];
269
NSMenu *menuToAdd = [theNewMenu menu];
270
271
if ([theMainMenu indexOfItemWithSubmenu:menuToAdd] == -1) {
272
NSMenuItem *newItem = [[NSMenuItem alloc] init];
273
[newItem setSubmenu:[theNewMenu menu]];
274
[newItem setTitle:[[theNewMenu menu] title]];
275
276
NSInteger nsMenuIndex = [self javaIndexToNSMenuIndex_OnAppKitThread:index];
277
278
if (nsMenuIndex == -1) {
279
[theMainMenu addItem:newItem];
280
} else {
281
[theMainMenu insertItem:newItem atIndex:nsMenuIndex];
282
}
283
284
BOOL newEnabledState = [theNewMenu isEnabled] && !fModallyDisabled;
285
[newItem setEnabled:newEnabledState];
286
[newItem release];
287
}
288
}
289
290
- (void) javaDeleteMenu: (jint)index {
291
if (self == sActiveMenuBar) {
292
[ThreadUtilities performOnMainThread:@selector(nativeDeleteMenu_OnAppKitThread:) on:self withObject:[NSNumber numberWithInt:index] waitUntilDone:YES];
293
}
294
295
@synchronized(self) {
296
CMenu *menuToRemove = [fMenuList objectAtIndex:index];
297
298
if (menuToRemove == fHelpMenu) {
299
[fHelpMenu release];
300
fHelpMenu = nil;
301
}
302
303
[fMenuList removeObjectAtIndex:index];
304
}
305
}
306
307
- (void) nativeDeleteMenu_OnAppKitThread:(id)indexObj {
308
AWT_ASSERT_APPKIT_THREAD;
309
NSApplication *theApp = [NSApplication sharedApplication];
310
NSMenu *theMainMenu = [theApp mainMenu];
311
jint menuToRemove = [(NSNumber *)indexObj intValue];
312
NSInteger nsMenuToRemove = [self javaIndexToNSMenuIndex_OnAppKitThread:menuToRemove];
313
314
if (nsMenuToRemove != -1) {
315
[theMainMenu removeItemAtIndex:nsMenuToRemove];
316
}
317
}
318
319
- (void) javaSetHelpMenu:(CMenu *)theMenu {
320
@synchronized(self) {
321
[theMenu retain];
322
[fHelpMenu release];
323
fHelpMenu = theMenu;
324
}
325
}
326
327
+ (void) addDefaultHelpMenu {
328
AWT_ASSERT_APPKIT_THREAD;
329
330
// Look for a help book tag. If it's there, add the help menu.
331
@synchronized ([CMenuBar class]) {
332
if (!sSetupHelpMenu) {
333
if (sDefaultHelpMenu == nil) {
334
// If we are embedded, don't make a help menu.
335
// TODO(cpc): we don't have NSApplicationAWT yet...
336
//if (![NSApp isKindOfClass:[NSApplicationAWT class]]) {
337
// sSetupHelpMenu = YES;
338
// return;
339
//}
340
341
// If the developer specified a NIB, don't make a help menu.
342
// TODO(cpc): usingDefaultNib only defined on NSApplicationAWT
343
//if (![NSApp usingDefaultNib]) {
344
// sSetupHelpMenu = YES;
345
// return;
346
//}
347
348
// TODO: not implemented
349
}
350
351
sSetupHelpMenu = YES;
352
}
353
}
354
355
if (sDefaultHelpMenu) {
356
NSMenu *theMainMenu = [NSApp mainMenu];
357
358
if ([theMainMenu indexOfItemWithSubmenu:sDefaultHelpMenu] == -1) {
359
// Since we're re-using this NSMenu, we need to clear its parent before
360
// adding it to a new menu item, or else AppKit will complain.
361
[sDefaultHelpMenu setSupermenu:nil];
362
363
// Add the help menu to the main menu.
364
NSMenuItem *newItem = [[NSMenuItem alloc] init];
365
[newItem setSubmenu:sDefaultHelpMenu];
366
[newItem setTitle:[sDefaultHelpMenu title]];
367
[theMainMenu addItem:newItem];
368
369
// Release it so the main menu owns it.
370
[newItem release];
371
}
372
}
373
}
374
375
@end
376
377
/*
378
* Class: sun_lwawt_macosx_CMenuBar
379
* Method: nativeCreateMenuBar
380
* Signature: ()J
381
*/
382
JNIEXPORT jlong JNICALL
383
Java_sun_lwawt_macosx_CMenuBar_nativeCreateMenuBar
384
(JNIEnv *env, jobject peer)
385
{
386
__block CMenuBar *aCMenuBar = nil;
387
JNF_COCOA_ENTER(env);
388
389
jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);
390
391
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
392
393
aCMenuBar = [[CMenuBar alloc] initWithPeer:cPeerObjGlobal];
394
// the aCMenuBar is released in CMenuComponent.dispose()
395
}];
396
if (aCMenuBar == nil) {
397
return 0L;
398
}
399
400
JNF_COCOA_EXIT(env);
401
return ptr_to_jlong(aCMenuBar);
402
}
403
404
/*
405
* Class: sun_lwawt_macosx_CMenuBar
406
* Method: nativeAddAtIndex
407
* Signature: (JJI)V
408
*/
409
JNIEXPORT void JNICALL
410
Java_sun_lwawt_macosx_CMenuBar_nativeAddAtIndex
411
(JNIEnv *env, jobject peer,
412
jlong menuBarObject, jlong menuObject, jint index)
413
{
414
JNF_COCOA_ENTER(env);
415
// Remove the specified item.
416
[((CMenuBar *) jlong_to_ptr(menuBarObject)) javaAddMenu:(CMenu *) jlong_to_ptr(menuObject) atIndex:index];
417
JNF_COCOA_EXIT(env);
418
}
419
420
/*
421
* Class: sun_lwawt_macosx_CMenuBar
422
* Method: nativeDelMenu
423
* Signature: (JI)V
424
*/
425
JNIEXPORT void JNICALL
426
Java_sun_lwawt_macosx_CMenuBar_nativeDelMenu
427
(JNIEnv *env, jobject peer, jlong menuBarObject, jint index)
428
{
429
JNF_COCOA_ENTER(env);
430
// Remove the specified item.
431
[((CMenuBar *) jlong_to_ptr(menuBarObject)) javaDeleteMenu: index];
432
JNF_COCOA_EXIT(env);
433
}
434
435
/*
436
* Class: sun_lwawt_macosx_CMenuBar
437
* Method: nativeSetHelpMenu
438
* Signature: (JJ)V
439
*/
440
JNIEXPORT void JNICALL
441
Java_sun_lwawt_macosx_CMenuBar_nativeSetHelpMenu
442
(JNIEnv *env, jobject peer, jlong menuBarObject, jlong menuObject)
443
{
444
JNF_COCOA_ENTER(env);
445
// Remove the specified item.
446
[((CMenuBar *) jlong_to_ptr(menuBarObject)) javaSetHelpMenu: ((CMenu *)jlong_to_ptr(menuObject))];
447
JNF_COCOA_EXIT(env);
448
}
449
450