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/CMenuItem.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 <JavaNativeFoundation/JavaNativeFoundation.h>
27
28
#import "CMenuItem.h"
29
#import "CMenu.h"
30
#import "AWTEvent.h"
31
#import "ThreadUtilities.h"
32
33
#import "java_awt_Event.h"
34
#import "java_awt_event_KeyEvent.h"
35
#import "sun_lwawt_macosx_CMenuItem.h"
36
37
#define NOT_A_CHECKBOXMENU -2
38
39
40
@implementation CMenuItem
41
42
- (id) initWithPeer:(jobject)peer asSeparator: (BOOL) asSeparator{
43
AWT_ASSERT_APPKIT_THREAD;
44
self = [super initWithPeer:peer];
45
if (self) {
46
if (asSeparator) {
47
fMenuItem = (NSMenuItem*)[NSMenuItem separatorItem];
48
[fMenuItem retain];
49
} else {
50
fMenuItem = [[NSMenuItem alloc] init];
51
[fMenuItem setAction:@selector(handleAction:)];
52
[fMenuItem setTarget:self];
53
}
54
fIsCheckbox = NO;
55
fIsEnabled = YES;
56
}
57
return self;
58
}
59
60
// This is because NSApplication doesn't check the target's window when sending
61
// actions; they only check the target itself. We always return YES,
62
// since we shouldn't even be installed unless our window is active.
63
- (BOOL) worksWhenModal {
64
return YES;
65
}
66
67
// Events
68
- (void)handleAction:(NSMenuItem *)sender {
69
AWT_ASSERT_APPKIT_THREAD;
70
JNIEnv *env = [ThreadUtilities getJNIEnv];
71
JNF_COCOA_ENTER(env);
72
73
// If we are called as a result of user pressing a shortcut, do nothing,
74
// because AVTView has already sent corresponding key event to the Java
75
// layer from performKeyEquivalent.
76
// There is an exception from the rule above, though: if a window with
77
// a menu gets minimized by user and there are no other windows to take
78
// focus, the window's menu won't be removed from the global menu bar.
79
// However, the Java layer won't handle invocation by a shortcut coming
80
// from this "frameless" menu, because there are no active windows. This
81
// means we have to handle it here.
82
NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent];
83
if ([currEvent type] == NSKeyDown) {
84
NSString *menuKey = [sender keyEquivalent];
85
NSString *eventKey = [currEvent charactersIgnoringModifiers];
86
87
// Apple uses characters from private Unicode range for some of the
88
// keys, so we need to do the same translation here that we do
89
// for the regular key down events
90
if ([eventKey length] == 1) {
91
unichar origChar = [eventKey characterAtIndex:0];
92
unichar newChar = NsCharToJavaChar(origChar, 0);
93
if (newChar == java_awt_event_KeyEvent_CHAR_UNDEFINED) {
94
newChar = origChar;
95
}
96
97
eventKey = [NSString stringWithCharacters: &newChar length: 1];
98
}
99
100
NSWindow *keyWindow = [NSApp keyWindow];
101
if ([menuKey isEqualToString:eventKey] && keyWindow != nil) {
102
return;
103
}
104
}
105
106
if (fIsCheckbox) {
107
static JNF_CLASS_CACHE(jc_CCheckboxMenuItem, "sun/lwawt/macosx/CCheckboxMenuItem");
108
static JNF_MEMBER_CACHE(jm_ckHandleAction, jc_CCheckboxMenuItem, "handleAction", "(Z)V");
109
110
// Send the opposite of what's currently checked -- the action
111
// indicates what state we're going to.
112
NSInteger state = [sender state];
113
jboolean newState = (state == NSOnState ? JNI_FALSE : JNI_TRUE);
114
JNFCallVoidMethod(env, fPeer, jm_ckHandleAction, newState);
115
} else {
116
static JNF_CLASS_CACHE(jc_CMenuItem, "sun/lwawt/macosx/CMenuItem");
117
static JNF_MEMBER_CACHE(jm_handleAction, jc_CMenuItem, "handleAction", "(JI)V"); // AWT_THREADING Safe (event)
118
119
NSUInteger modifiers = [currEvent modifierFlags];
120
jint javaModifiers = NsKeyModifiersToJavaModifiers(modifiers, NO);
121
122
JNFCallVoidMethod(env, fPeer, jm_handleAction, UTC(currEvent), javaModifiers); // AWT_THREADING Safe (event)
123
}
124
JNF_COCOA_EXIT(env);
125
}
126
127
- (void) setJavaLabel:(NSString *)theLabel shortcut:(NSString *)theKeyEquivalent modifierMask:(jint)modifiers {
128
129
NSUInteger modifierMask = 0;
130
131
if (![theKeyEquivalent isEqualToString:@""]) {
132
// Force the key equivalent to lower case if not using the shift key.
133
// Otherwise AppKit will draw a Shift glyph in the menu.
134
if ((modifiers & java_awt_event_KeyEvent_SHIFT_MASK) == 0) {
135
theKeyEquivalent = [theKeyEquivalent lowercaseString];
136
}
137
138
// Hack for the question mark -- SHIFT and / means use the question mark.
139
if ((modifiers & java_awt_event_KeyEvent_SHIFT_MASK) != 0 &&
140
[theKeyEquivalent isEqualToString:@"/"])
141
{
142
theKeyEquivalent = @"?";
143
modifiers &= ~java_awt_event_KeyEvent_SHIFT_MASK;
144
}
145
146
modifierMask = JavaModifiersToNsKeyModifiers(modifiers, NO);
147
}
148
149
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
150
[fMenuItem setKeyEquivalent:theKeyEquivalent];
151
[fMenuItem setKeyEquivalentModifierMask:modifierMask];
152
[fMenuItem setTitle:theLabel];
153
}];
154
}
155
156
- (void) setJavaImage:(NSImage *)theImage {
157
158
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
159
[fMenuItem setImage:theImage];
160
}];
161
}
162
163
- (void) setJavaToolTipText:(NSString *)theText {
164
165
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
166
[fMenuItem setToolTip:theText];
167
}];
168
}
169
170
171
- (void)setJavaEnabled:(BOOL) enabled {
172
173
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
174
@synchronized(self) {
175
fIsEnabled = enabled;
176
177
// Warning: This won't work if the parent menu is disabled.
178
// See [CMenu syncFromJava]. We still need to call it here so
179
// the NSMenuItem itself gets properly updated.
180
[fMenuItem setEnabled:fIsEnabled];
181
}
182
}];
183
}
184
185
- (BOOL)isEnabled {
186
187
BOOL enabled = NO;
188
@synchronized(self) {
189
enabled = fIsEnabled;
190
}
191
return enabled;
192
}
193
194
195
- (void)setJavaState:(BOOL)newState {
196
197
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
198
[fMenuItem setState:(newState ? NSOnState : NSOffState)];
199
}];
200
}
201
202
- (void)dealloc {
203
[fMenuItem setAction:NULL];
204
[fMenuItem setTarget:nil];
205
[fMenuItem release];
206
fMenuItem = nil;
207
208
[super dealloc];
209
}
210
211
- (void)addNSMenuItemToMenu:(NSMenu *)inMenu {
212
[inMenu addItem:fMenuItem];
213
}
214
215
- (NSMenuItem *)menuItem {
216
return [[fMenuItem retain] autorelease];
217
}
218
219
- (void)setIsCheckbox {
220
fIsCheckbox = YES;
221
}
222
223
- (NSString *)description {
224
return [NSString stringWithFormat:@"CMenuItem[ %@ ]", fMenuItem];
225
}
226
227
@end
228
229
/** Convert a Java keycode for SetMenuItemCmd */
230
static unichar AWTKeyToMacShortcut(jint awtKey, BOOL doShift) {
231
unichar macKey = 0;
232
233
if ((awtKey >= java_awt_event_KeyEvent_VK_0 && awtKey <= java_awt_event_KeyEvent_VK_9) ||
234
(awtKey >= java_awt_event_KeyEvent_VK_A && awtKey <= java_awt_event_KeyEvent_VK_Z))
235
{
236
// These ranges are the same in ASCII
237
macKey = awtKey;
238
} else if (awtKey >= java_awt_event_KeyEvent_VK_F1 && awtKey <= java_awt_event_KeyEvent_VK_F12) {
239
// Support for F1 - F12 has been around since Java 1.0 and fall into a lower range.
240
macKey = awtKey - java_awt_event_KeyEvent_VK_F1 + NSF1FunctionKey;
241
} else if (awtKey >= java_awt_event_KeyEvent_VK_F13 && awtKey <= java_awt_event_KeyEvent_VK_F24) {
242
// Support for F13-F24 came in Java 1.2 and are at a different range.
243
macKey = awtKey - java_awt_event_KeyEvent_VK_F13 + NSF13FunctionKey;
244
} else {
245
// Special characters
246
switch (awtKey) {
247
case java_awt_event_KeyEvent_VK_BACK_QUOTE : macKey = '`'; break;
248
case java_awt_event_KeyEvent_VK_QUOTE : macKey = '\''; break;
249
250
case java_awt_event_KeyEvent_VK_ESCAPE : macKey = 0x1B; break;
251
// case java_awt_event_KeyEvent_VK_SPACE : macKey = kMenuSpaceGlyph; break;
252
case java_awt_event_KeyEvent_VK_PAGE_UP : macKey = NSPageUpFunctionKey; break;
253
case java_awt_event_KeyEvent_VK_PAGE_DOWN : macKey = NSPageDownFunctionKey; break;
254
case java_awt_event_KeyEvent_VK_END : macKey = NSEndFunctionKey; break;
255
case java_awt_event_KeyEvent_VK_HOME : macKey = NSHomeFunctionKey; break;
256
257
case java_awt_event_KeyEvent_VK_LEFT : macKey = NSLeftArrowFunctionKey; break;
258
case java_awt_event_KeyEvent_VK_UP : macKey = NSUpArrowFunctionKey; break;
259
case java_awt_event_KeyEvent_VK_RIGHT : macKey = NSRightArrowFunctionKey; break;
260
case java_awt_event_KeyEvent_VK_DOWN : macKey = NSDownArrowFunctionKey; break;
261
262
case java_awt_event_KeyEvent_VK_COMMA : macKey = ','; break;
263
264
// Mac OS doesn't distinguish between the two '-' keys...
265
case java_awt_event_KeyEvent_VK_MINUS :
266
case java_awt_event_KeyEvent_VK_SUBTRACT : macKey = '-'; break;
267
268
// or the two '.' keys...
269
case java_awt_event_KeyEvent_VK_DECIMAL :
270
case java_awt_event_KeyEvent_VK_PERIOD : macKey = '.'; break;
271
272
// or the two '/' keys.
273
case java_awt_event_KeyEvent_VK_DIVIDE :
274
case java_awt_event_KeyEvent_VK_SLASH : macKey = '/'; break;
275
276
case java_awt_event_KeyEvent_VK_SEMICOLON : macKey = ';'; break;
277
case java_awt_event_KeyEvent_VK_EQUALS : macKey = '='; break;
278
279
case java_awt_event_KeyEvent_VK_OPEN_BRACKET : macKey = '['; break;
280
case java_awt_event_KeyEvent_VK_BACK_SLASH : macKey = '\\'; break;
281
case java_awt_event_KeyEvent_VK_CLOSE_BRACKET : macKey = ']'; break;
282
283
case java_awt_event_KeyEvent_VK_MULTIPLY : macKey = '*'; break;
284
case java_awt_event_KeyEvent_VK_ADD : macKey = '+'; break;
285
286
case java_awt_event_KeyEvent_VK_HELP : macKey = NSHelpFunctionKey; break;
287
case java_awt_event_KeyEvent_VK_TAB : macKey = NSTabCharacter; break;
288
case java_awt_event_KeyEvent_VK_ENTER : macKey = NSNewlineCharacter; break;
289
case java_awt_event_KeyEvent_VK_BACK_SPACE : macKey = NSBackspaceCharacter; break;
290
case java_awt_event_KeyEvent_VK_DELETE : macKey = NSDeleteCharacter; break;
291
case java_awt_event_KeyEvent_VK_CLEAR : macKey = NSClearDisplayFunctionKey; break;
292
case java_awt_event_KeyEvent_VK_AMPERSAND : macKey = '&'; break;
293
case java_awt_event_KeyEvent_VK_ASTERISK : macKey = '*'; break;
294
case java_awt_event_KeyEvent_VK_QUOTEDBL : macKey = '\"'; break;
295
case java_awt_event_KeyEvent_VK_LESS : macKey = '<'; break;
296
case java_awt_event_KeyEvent_VK_GREATER : macKey = '>'; break;
297
case java_awt_event_KeyEvent_VK_BRACELEFT : macKey = '{'; break;
298
case java_awt_event_KeyEvent_VK_BRACERIGHT : macKey = '}'; break;
299
case java_awt_event_KeyEvent_VK_AT : macKey = '@'; break;
300
case java_awt_event_KeyEvent_VK_COLON : macKey = ':'; break;
301
case java_awt_event_KeyEvent_VK_CIRCUMFLEX : macKey = '^'; break;
302
case java_awt_event_KeyEvent_VK_DOLLAR : macKey = '$'; break;
303
case java_awt_event_KeyEvent_VK_EXCLAMATION_MARK : macKey = '!'; break;
304
case java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS : macKey = '('; break;
305
case java_awt_event_KeyEvent_VK_NUMBER_SIGN : macKey = '#'; break;
306
case java_awt_event_KeyEvent_VK_PLUS : macKey = '+'; break;
307
case java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS: macKey = ')'; break;
308
case java_awt_event_KeyEvent_VK_UNDERSCORE : macKey = '_'; break;
309
}
310
}
311
return macKey;
312
}
313
314
/*
315
* Class: sun_lwawt_macosx_CMenuItem
316
* Method: nativeSetLabel
317
* Signature: (JLjava/lang/String;CII)V
318
*/
319
JNIEXPORT void JNICALL
320
Java_sun_lwawt_macosx_CMenuItem_nativeSetLabel
321
(JNIEnv *env, jobject peer,
322
jlong menuItemObj, jstring label,
323
jchar shortcutKey, jint shortcutKeyCode, jint mods)
324
{
325
JNF_COCOA_ENTER(env);
326
NSString *theLabel = JNFJavaToNSString(env, label);
327
NSString *theKeyEquivalent = nil;
328
unichar macKey = shortcutKey;
329
330
if (macKey == 0) {
331
macKey = AWTKeyToMacShortcut(shortcutKeyCode, (mods & java_awt_event_KeyEvent_SHIFT_MASK) != 0);
332
}
333
334
if (macKey != 0) {
335
unichar equivalent[1] = {macKey};
336
theKeyEquivalent = [NSString stringWithCharacters:equivalent length:1];
337
} else {
338
theKeyEquivalent = @"";
339
}
340
341
[((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaLabel:theLabel shortcut:theKeyEquivalent modifierMask:mods];
342
JNF_COCOA_EXIT(env);
343
}
344
345
/*
346
* Class: sun_lwawt_macosx_CMenuItem
347
* Method: nativeSetTooltip
348
* Signature: (JLjava/lang/String;)V
349
*/
350
JNIEXPORT void JNICALL
351
Java_sun_lwawt_macosx_CMenuItem_nativeSetTooltip
352
(JNIEnv *env, jobject peer, jlong menuItemObj, jstring tooltip)
353
{
354
JNF_COCOA_ENTER(env);
355
NSString *theTooltip = JNFJavaToNSString(env, tooltip);
356
[((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaToolTipText:theTooltip];
357
JNF_COCOA_EXIT(env);
358
}
359
360
/*
361
* Class: sun_lwawt_macosx_CMenuItem
362
* Method: nativeSetImage
363
* Signature: (JJ)V
364
*/
365
JNIEXPORT void JNICALL
366
Java_sun_lwawt_macosx_CMenuItem_nativeSetImage
367
(JNIEnv *env, jobject peer, jlong menuItemObj, jlong image)
368
{
369
JNF_COCOA_ENTER(env);
370
[((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaImage:(NSImage*)jlong_to_ptr(image)];
371
JNF_COCOA_EXIT(env);
372
}
373
374
/*
375
* Class: sun_lwawt_macosx_CMenuItem
376
* Method: nativeCreate
377
* Signature: (JZ)J
378
*/
379
JNIEXPORT jlong JNICALL
380
Java_sun_lwawt_macosx_CMenuItem_nativeCreate
381
(JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator)
382
{
383
384
__block CMenuItem *aCMenuItem = nil;
385
BOOL asSeparator = (isSeparator == JNI_TRUE) ? YES: NO;
386
CMenu *parentCMenu = (CMenu *)jlong_to_ptr(parentCMenuObj);
387
JNF_COCOA_ENTER(env);
388
389
jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);
390
391
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
392
aCMenuItem = [[CMenuItem alloc] initWithPeer: cPeerObjGlobal
393
asSeparator: asSeparator];
394
// the CMenuItem is released in CMenuComponent.dispose()
395
}];
396
397
if (aCMenuItem == nil) {
398
return 0L;
399
}
400
401
// and add it to the parent item.
402
[parentCMenu addJavaMenuItem: aCMenuItem];
403
404
// setLabel will be called after creation completes.
405
406
JNF_COCOA_EXIT(env);
407
return ptr_to_jlong(aCMenuItem);
408
}
409
410
/*
411
* Class: sun_lwawt_macosx_CMenuItem
412
* Method: nativeSetEnabled
413
* Signature: (JZ)V
414
*/
415
JNIEXPORT void JNICALL
416
Java_sun_lwawt_macosx_CMenuItem_nativeSetEnabled
417
(JNIEnv *env, jobject peer, jlong menuItemObj, jboolean enable)
418
{
419
JNF_COCOA_ENTER(env);
420
CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
421
[item setJavaEnabled: (enable == JNI_TRUE)];
422
JNF_COCOA_EXIT(env);
423
}
424
425
/*
426
* Class: sun_lwawt_macosx_CCheckboxMenuItem
427
* Method: nativeSetState
428
* Signature: (IZ)V
429
*/
430
JNIEXPORT void JNICALL
431
Java_sun_lwawt_macosx_CCheckboxMenuItem_nativeSetState
432
(JNIEnv *env, jobject peer, jlong menuItemObj, jboolean state)
433
{
434
JNF_COCOA_ENTER(env);
435
CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
436
[item setJavaState: (state == JNI_TRUE)];
437
JNF_COCOA_EXIT(env);
438
}
439
440
/*
441
* Class: sun_lwawt_macosx_CCheckboxMenuItem
442
* Method: nativeSetState
443
* Signature: (IZ)V
444
*/
445
JNIEXPORT void JNICALL
446
Java_sun_lwawt_macosx_CCheckboxMenuItem_nativeSetIsCheckbox
447
(JNIEnv *env, jobject peer, jlong menuItemObj)
448
{
449
JNF_COCOA_ENTER(env);
450
CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
451
[item setIsCheckbox];
452
JNF_COCOA_EXIT(env);
453
}
454
455