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/AWTEvent.m
38829 views
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 <JavaNativeFoundation/JavaNativeFoundation.h>
27
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
28
#import <sys/time.h>
29
#include <Carbon/Carbon.h>
30
31
#import "jni_util.h"
32
#import "LWCToolkit.h"
33
#import "ThreadUtilities.h"
34
35
#import "java_awt_event_InputEvent.h"
36
#import "java_awt_event_KeyEvent.h"
37
#import "java_awt_event_MouseEvent.h"
38
39
/*
40
* Table to map typed characters to their Java virtual key equivalent and back.
41
* We use the incoming unichar (ignoring all modifiers) and try to figure out
42
* which virtual key code is appropriate. A lot of them just have direct
43
* mappings (the function keys, arrow keys, etc.) so they aren't a problem.
44
* We had to do something a little funky to catch the keys on the numeric
45
* key pad (i.e. using event mask to distinguish between period on regular
46
* keyboard and decimal on keypad). We also have to do something incredibly
47
* hokey with regards to the shifted punctuation characters. For examples,
48
* consider '&' which is usually Shift-7. For the Java key typed events,
49
* that's no problem, we just say pass the unichar. But for the
50
* KeyPressed/Released events, we need to identify the virtual key code
51
* (which roughly correspond to hardware keys) which means we are supposed
52
* to say the virtual 7 key was pressed. But how are we supposed to know
53
* when we get a punctuation char what was the real hardware key was that
54
* was pressed? Although '&' often comes from Shift-7 the keyboard can be
55
* remapped! I don't think there really is a good answer, and hopefully
56
* all good applets are only interested in logical key typed events not
57
* press/release. Meanwhile, we are hard-coding the shifted punctuation
58
* to trigger the virtual keys that are the expected ones under a standard
59
* keymapping. Looking at Windows & Mac, they don't actually do this, the
60
* Mac seems to just put the ascii code in for the shifted punctuation
61
* (which means they actually end up with bogus key codes on the Java side),
62
* Windows I can't even figure out what it's doing.
63
*/
64
#define KL_STANDARD java_awt_event_KeyEvent_KEY_LOCATION_STANDARD
65
#define KL_NUMPAD java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD
66
#define KL_UNKNOWN java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN
67
static struct _key
68
{
69
unsigned short keyCode;
70
BOOL postsTyped;
71
jint javaKeyLocation;
72
jint javaKeyCode;
73
}
74
const keyTable[] =
75
{
76
{0x00, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_A},
77
{0x01, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_S},
78
{0x02, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_D},
79
{0x03, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_F},
80
{0x04, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_H},
81
{0x05, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_G},
82
{0x06, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Z},
83
{0x07, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_X},
84
{0x08, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_C},
85
{0x09, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_V},
86
{0x0A, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_QUOTE},
87
{0x0B, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_B},
88
{0x0C, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Q},
89
{0x0D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_W},
90
{0x0E, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_E},
91
{0x0F, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_R},
92
{0x10, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Y},
93
{0x11, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_T},
94
{0x12, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_1},
95
{0x13, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_2},
96
{0x14, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_3},
97
{0x15, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_4},
98
{0x16, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_6},
99
{0x17, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_5},
100
{0x18, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_EQUALS},
101
{0x19, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_9},
102
{0x1A, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_7},
103
{0x1B, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_MINUS},
104
{0x1C, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_8},
105
{0x1D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_0},
106
{0x1E, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_CLOSE_BRACKET},
107
{0x1F, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_O},
108
{0x20, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_U},
109
{0x21, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_OPEN_BRACKET},
110
{0x22, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_I},
111
{0x23, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_P},
112
{0x24, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_ENTER},
113
{0x25, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_L},
114
{0x26, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_J},
115
{0x27, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_QUOTE},
116
{0x28, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_K},
117
{0x29, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SEMICOLON},
118
{0x2A, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SLASH},
119
{0x2B, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_COMMA},
120
{0x2C, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SLASH},
121
{0x2D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_N},
122
{0x2E, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_M},
123
{0x2F, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_PERIOD},
124
{0x30, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_TAB},
125
{0x31, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SPACE},
126
{0x32, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_QUOTE},
127
{0x33, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SPACE},
128
{0x34, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_ENTER},
129
{0x35, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_ESCAPE},
130
{0x36, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
131
{0x37, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_META}, // ****
132
{0x38, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_SHIFT}, // ****
133
{0x39, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_CAPS_LOCK},
134
{0x3A, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_ALT}, // ****
135
{0x3B, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_CONTROL}, // ****
136
{0x3C, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
137
{0x3D, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
138
{0x3E, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
139
{0x3F, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED}, // the 'fn' key on PowerBooks
140
{0x40, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
141
{0x41, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_DECIMAL},
142
{0x42, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
143
{0x43, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_MULTIPLY},
144
{0x44, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
145
{0x45, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_ADD},
146
{0x46, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
147
{0x47, NO, KL_NUMPAD, java_awt_event_KeyEvent_VK_CLEAR},
148
{0x48, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
149
{0x49, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
150
{0x4A, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
151
{0x4B, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_DIVIDE},
152
{0x4C, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_ENTER},
153
{0x4D, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
154
{0x4E, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_SUBTRACT},
155
{0x4F, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
156
{0x50, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
157
{0x51, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_EQUALS},
158
{0x52, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD0},
159
{0x53, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD1},
160
{0x54, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD2},
161
{0x55, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD3},
162
{0x56, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD4},
163
{0x57, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD5},
164
{0x58, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD6},
165
{0x59, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD7},
166
{0x5A, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
167
{0x5B, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD8},
168
{0x5C, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_NUMPAD9},
169
{0x5D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SLASH}, // This is a combo yen/backslash on JIS keyboards.
170
{0x5E, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_UNDERSCORE},
171
{0x5F, YES, KL_NUMPAD, java_awt_event_KeyEvent_VK_COMMA},
172
{0x60, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F5},
173
{0x61, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F6},
174
{0x62, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F7},
175
{0x63, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F3},
176
{0x64, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F8},
177
{0x65, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F9},
178
{0x66, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_ALPHANUMERIC},
179
{0x67, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F11},
180
{0x68, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_KATAKANA},
181
{0x69, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F13},
182
{0x6A, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F16},
183
{0x6B, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F14},
184
{0x6C, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
185
{0x6D, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F10},
186
{0x6E, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
187
{0x6F, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F12},
188
{0x70, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
189
{0x71, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F15},
190
{0x72, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_HELP},
191
{0x73, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_HOME},
192
{0x74, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_PAGE_UP},
193
{0x75, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_DELETE},
194
{0x76, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F4},
195
{0x77, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_END},
196
{0x78, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F2},
197
{0x79, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_PAGE_DOWN},
198
{0x7A, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_F1},
199
{0x7B, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_LEFT},
200
{0x7C, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_RIGHT},
201
{0x7D, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_DOWN},
202
{0x7E, NO, KL_STANDARD, java_awt_event_KeyEvent_VK_UP},
203
{0x7F, NO, KL_UNKNOWN, java_awt_event_KeyEvent_VK_UNDEFINED},
204
};
205
206
/*
207
* This table was stolen from the Windows implementation for mapping
208
* Unicode values to VK codes for dead keys. On Windows, some layouts
209
* return ASCII punctuation for dead accents, while some return spacing
210
* accent chars, so both should be listed. However, in all of the
211
* keyboard layouts I tried only the Unicode values are used.
212
*/
213
struct CharToVKEntry {
214
UniChar c;
215
jint javaKey;
216
};
217
static const struct CharToVKEntry charToDeadVKTable[] = {
218
{0x0060, java_awt_event_KeyEvent_VK_DEAD_GRAVE},
219
{0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE},
220
{0x0384, java_awt_event_KeyEvent_VK_DEAD_ACUTE}, // Unicode "GREEK TONOS" -- Greek keyboard, semicolon key
221
{0x005E, java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX},
222
{0x007E, java_awt_event_KeyEvent_VK_DEAD_TILDE},
223
{0x02DC, java_awt_event_KeyEvent_VK_DEAD_TILDE}, // Unicode "SMALL TILDE"
224
{0x00AF, java_awt_event_KeyEvent_VK_DEAD_MACRON},
225
{0x02D8, java_awt_event_KeyEvent_VK_DEAD_BREVE},
226
{0x02D9, java_awt_event_KeyEvent_VK_DEAD_ABOVEDOT},
227
{0x00A8, java_awt_event_KeyEvent_VK_DEAD_DIAERESIS},
228
{0x02DA, java_awt_event_KeyEvent_VK_DEAD_ABOVERING},
229
{0x02DD, java_awt_event_KeyEvent_VK_DEAD_DOUBLEACUTE},
230
{0x02C7, java_awt_event_KeyEvent_VK_DEAD_CARON},
231
{0x00B8, java_awt_event_KeyEvent_VK_DEAD_CEDILLA},
232
{0x02DB, java_awt_event_KeyEvent_VK_DEAD_OGONEK},
233
{0x037A, java_awt_event_KeyEvent_VK_DEAD_IOTA},
234
{0x309B, java_awt_event_KeyEvent_VK_DEAD_VOICED_SOUND},
235
{0x309C, java_awt_event_KeyEvent_VK_DEAD_SEMIVOICED_SOUND},
236
{0,0}
237
};
238
239
// TODO: some constants below are part of CGS (private interfaces)...
240
// for now we will look at the raw key code to determine left/right status
241
// but not sure this is foolproof...
242
static struct _nsKeyToJavaModifier
243
{
244
NSUInteger nsMask;
245
//NSUInteger cgsLeftMask;
246
//NSUInteger cgsRightMask;
247
unsigned short leftKeyCode;
248
unsigned short rightKeyCode;
249
jint javaExtMask;
250
jint javaMask;
251
jint javaKey;
252
}
253
const nsKeyToJavaModifierTable[] =
254
{
255
{
256
NSAlphaShiftKeyMask,
257
0,
258
0,
259
0, // no Java equivalent
260
0, // no Java equivalent
261
java_awt_event_KeyEvent_VK_CAPS_LOCK
262
},
263
{
264
NSShiftKeyMask,
265
//kCGSFlagsMaskAppleShiftKey,
266
//kCGSFlagsMaskAppleRightShiftKey,
267
56,
268
60,
269
java_awt_event_InputEvent_SHIFT_DOWN_MASK,
270
java_awt_event_InputEvent_SHIFT_MASK,
271
java_awt_event_KeyEvent_VK_SHIFT
272
},
273
{
274
NSControlKeyMask,
275
//kCGSFlagsMaskAppleControlKey,
276
//kCGSFlagsMaskAppleRightControlKey,
277
59,
278
62,
279
java_awt_event_InputEvent_CTRL_DOWN_MASK,
280
java_awt_event_InputEvent_CTRL_MASK,
281
java_awt_event_KeyEvent_VK_CONTROL
282
},
283
{
284
NSAlternateKeyMask,
285
//kCGSFlagsMaskAppleLeftAlternateKey,
286
//kCGSFlagsMaskAppleRightAlternateKey,
287
58,
288
61,
289
java_awt_event_InputEvent_ALT_DOWN_MASK,
290
java_awt_event_InputEvent_ALT_MASK,
291
java_awt_event_KeyEvent_VK_ALT
292
},
293
{
294
NSCommandKeyMask,
295
//kCGSFlagsMaskAppleLeftCommandKey,
296
//kCGSFlagsMaskAppleRightCommandKey,
297
55,
298
54,
299
java_awt_event_InputEvent_META_DOWN_MASK,
300
java_awt_event_InputEvent_META_MASK,
301
java_awt_event_KeyEvent_VK_META
302
},
303
// NSNumericPadKeyMask
304
{
305
NSHelpKeyMask,
306
0,
307
0,
308
0, // no Java equivalent
309
0, // no Java equivalent
310
java_awt_event_KeyEvent_VK_HELP
311
},
312
// NSFunctionKeyMask
313
{0, 0, 0, 0, 0, 0}
314
};
315
316
/*
317
* Almost all unicode characters just go from NS to Java with no translation.
318
* For the few exceptions, we handle it here with this small table.
319
*/
320
#define ALL_NS_KEY_MODIFIERS_MASK \
321
(NSShiftKeyMask | NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask)
322
323
static struct _char {
324
NSUInteger modifier;
325
unichar nsChar;
326
unichar javaChar;
327
}
328
const charTable[] = {
329
// map enter on keypad to same as return key
330
{0, NSEnterCharacter, NSNewlineCharacter},
331
332
// [3134616] return newline instead of carriage return
333
{0, NSCarriageReturnCharacter, NSNewlineCharacter},
334
335
// "delete" means backspace in Java
336
{ALL_NS_KEY_MODIFIERS_MASK, NSDeleteCharacter, NSBackspaceCharacter},
337
{ALL_NS_KEY_MODIFIERS_MASK, NSDeleteFunctionKey, NSDeleteCharacter},
338
339
// back-tab is only differentiated from tab by Shift flag
340
{NSShiftKeyMask, NSBackTabCharacter, NSTabCharacter},
341
342
{0, 0, 0}
343
};
344
345
unichar NsCharToJavaChar(unichar nsChar, NSUInteger modifiers)
346
{
347
const struct _char *cur;
348
// Mask off just the keyboard modifiers from the event modifier mask.
349
NSUInteger testableFlags = (modifiers & ALL_NS_KEY_MODIFIERS_MASK);
350
351
// walk through table & find the match
352
for (cur = charTable; cur->nsChar != 0 ; cur++) {
353
// <rdar://Problem/3476426> Need to determine if we are looking at
354
// a plain keypress or a modified keypress. Don't adjust the
355
// character of a keypress with a modifier.
356
if (cur->nsChar == nsChar) {
357
if (cur->modifier == 0 && testableFlags == 0) {
358
// If the modifier field is 0, that means to transform
359
// this character if no additional keyboard modifiers are set.
360
// This lets ctrl-C be reported as ctrl-C and not transformed
361
// into Newline.
362
return cur->javaChar;
363
} else if (cur->modifier != 0 &&
364
(testableFlags & cur->modifier) == testableFlags)
365
{
366
// Likewise, if the modifier field is nonzero, that means
367
// transform this character if only these modifiers are
368
// set in the testable flags.
369
return cur->javaChar;
370
}
371
}
372
}
373
374
if (nsChar >= NSUpArrowFunctionKey && nsChar <= NSModeSwitchFunctionKey) {
375
return java_awt_event_KeyEvent_CHAR_UNDEFINED;
376
}
377
378
// otherwise return character unchanged
379
return nsChar;
380
}
381
382
static unichar NsGetDeadKeyChar(unsigned short keyCode)
383
{
384
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
385
CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
386
if (uchr == nil) { return 0; }
387
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr);
388
// Carbon modifiers should be used instead of NSEvent modifiers
389
UInt32 modifierKeyState = (GetCurrentEventKeyModifiers() >> 8) & 0xFF;
390
391
if (keyboardLayout) {
392
UInt32 deadKeyState = 0;
393
UniCharCount maxStringLength = 255;
394
UniCharCount actualStringLength = 0;
395
UniChar unicodeString[maxStringLength];
396
397
// get the deadKeyState
398
OSStatus status = UCKeyTranslate(keyboardLayout,
399
keyCode, kUCKeyActionDown, modifierKeyState,
400
LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
401
&deadKeyState,
402
maxStringLength,
403
&actualStringLength, unicodeString);
404
405
if (status == noErr && deadKeyState != 0) {
406
// Press SPACE to get the dead key char
407
status = UCKeyTranslate(keyboardLayout,
408
kVK_Space, kUCKeyActionDown, 0,
409
LMGetKbdType(), 0,
410
&deadKeyState,
411
maxStringLength,
412
&actualStringLength, unicodeString);
413
414
if (status == noErr && actualStringLength > 0) {
415
return unicodeString[0];
416
}
417
}
418
}
419
return 0;
420
}
421
422
/*
423
* This is the function that uses the table above to take incoming
424
* NSEvent keyCodes and translate to the Java virtual key code.
425
*/
426
static void
427
NsCharToJavaVirtualKeyCode(unichar ch, BOOL isDeadChar,
428
NSUInteger flags, unsigned short key,
429
jint *keyCode, jint *keyLocation, BOOL *postsTyped, unichar *deadChar)
430
{
431
static size_t size = sizeof(keyTable) / sizeof(struct _key);
432
NSInteger offset;
433
434
if (isDeadChar) {
435
unichar testDeadChar = NsGetDeadKeyChar(key);
436
const struct CharToVKEntry *map;
437
for (map = charToDeadVKTable; map->c != 0; ++map) {
438
if (testDeadChar == map->c) {
439
*keyCode = map->javaKey;
440
*postsTyped = NO;
441
// TODO: use UNKNOWN here?
442
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
443
*deadChar = testDeadChar;
444
return;
445
}
446
}
447
// If we got here, we keep looking for a normal key.
448
}
449
450
if ([[NSCharacterSet letterCharacterSet] characterIsMember:ch]) {
451
// key is an alphabetic character
452
unichar lower;
453
lower = tolower(ch);
454
offset = lower - 'a';
455
if (offset >= 0 && offset <= 25) {
456
// some chars in letter set are NOT actually A-Z characters?!
457
// skip them...
458
*postsTyped = YES;
459
// do quick conversion
460
*keyCode = java_awt_event_KeyEvent_VK_A + offset;
461
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
462
return;
463
}
464
}
465
466
if ([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:ch]) {
467
// key is a digit
468
offset = ch - '0';
469
// make sure in range for decimal digits
470
if (offset >= 0 && offset <= 9) {
471
jboolean numpad = (flags & NSNumericPadKeyMask) != 0;
472
*postsTyped = YES;
473
if (numpad) {
474
*keyCode = offset + java_awt_event_KeyEvent_VK_NUMPAD0;
475
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD;
476
} else {
477
*keyCode = offset + java_awt_event_KeyEvent_VK_0;
478
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
479
}
480
return;
481
}
482
}
483
484
if (key < size) {
485
*postsTyped = keyTable[key].postsTyped;
486
*keyCode = keyTable[key].javaKeyCode;
487
*keyLocation = keyTable[key].javaKeyLocation;
488
} else {
489
// Should we report this? This means we've got a keyboard
490
// we don't know about...
491
*postsTyped = NO;
492
*keyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
493
*keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
494
}
495
}
496
497
/*
498
* This returns the java key data for the key NSEvent modifiers
499
* (after NSFlagChanged).
500
*/
501
static void
502
NsKeyModifiersToJavaKeyInfo(NSUInteger nsFlags, unsigned short eventKeyCode,
503
jint *javaKeyCode,
504
jint *javaKeyLocation,
505
jint *javaKeyType)
506
{
507
static NSUInteger sPreviousNSFlags = 0;
508
509
const struct _nsKeyToJavaModifier* cur;
510
NSUInteger oldNSFlags = sPreviousNSFlags;
511
NSUInteger changedNSFlags = oldNSFlags ^ nsFlags;
512
sPreviousNSFlags = nsFlags;
513
514
*javaKeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
515
*javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
516
*javaKeyType = java_awt_event_KeyEvent_KEY_PRESSED;
517
518
for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) {
519
if (changedNSFlags & cur->nsMask) {
520
*javaKeyCode = cur->javaKey;
521
*javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
522
// TODO: uses SPI...
523
//if (changedNSFlags & cur->cgsLeftMask) {
524
// *javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_LEFT;
525
//} else if (changedNSFlags & cur->cgsRightMask) {
526
// *javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_RIGHT;
527
//}
528
if (eventKeyCode == cur->leftKeyCode) {
529
*javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_LEFT;
530
} else if (eventKeyCode == cur->rightKeyCode) {
531
*javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_RIGHT;
532
}
533
*javaKeyType = (cur->nsMask & nsFlags) ?
534
java_awt_event_KeyEvent_KEY_PRESSED :
535
java_awt_event_KeyEvent_KEY_RELEASED;
536
break;
537
}
538
}
539
}
540
541
/*
542
* This returns the java modifiers for a key NSEvent.
543
*/
544
jint NsKeyModifiersToJavaModifiers(NSUInteger nsFlags, BOOL isExtMods)
545
{
546
jint javaModifiers = 0;
547
const struct _nsKeyToJavaModifier* cur;
548
549
for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) {
550
if ((cur->nsMask & nsFlags) != 0) {
551
javaModifiers |= isExtMods? cur->javaExtMask : cur->javaMask;
552
}
553
}
554
555
return javaModifiers;
556
}
557
558
/*
559
* This returns the NSEvent flags for java key modifiers.
560
*/
561
NSUInteger JavaModifiersToNsKeyModifiers(jint javaModifiers, BOOL isExtMods)
562
{
563
NSUInteger nsFlags = 0;
564
const struct _nsKeyToJavaModifier* cur;
565
566
for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) {
567
jint mask = isExtMods? cur->javaExtMask : cur->javaMask;
568
if ((mask & javaModifiers) != 0) {
569
nsFlags |= cur->nsMask;
570
}
571
}
572
573
// special case
574
jint mask = isExtMods? java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK :
575
java_awt_event_InputEvent_ALT_GRAPH_MASK;
576
577
if ((mask & javaModifiers) != 0) {
578
nsFlags |= NSAlternateKeyMask;
579
}
580
581
return nsFlags;
582
}
583
584
585
jint GetJavaMouseModifiers(NSInteger button, NSUInteger modifierFlags)
586
{
587
// Mousing needs the key modifiers
588
jint modifiers = NsKeyModifiersToJavaModifiers(modifierFlags, YES);
589
590
591
/*
592
* Ask Quartz about mouse buttons state
593
*/
594
595
if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState,
596
kCGMouseButtonLeft)) {
597
modifiers |= java_awt_event_InputEvent_BUTTON1_DOWN_MASK;
598
}
599
600
if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState,
601
kCGMouseButtonRight)) {
602
modifiers |= java_awt_event_InputEvent_BUTTON3_DOWN_MASK;
603
}
604
605
if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState,
606
kCGMouseButtonCenter)) {
607
modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK;
608
}
609
610
NSInteger extraButton = 3;
611
for (; extraButton < gNumberOfButtons; extraButton++) {
612
if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState,
613
extraButton)) {
614
modifiers |= gButtonDownMasks[extraButton];
615
}
616
}
617
618
return modifiers;
619
}
620
621
jlong UTC(NSEvent *event) {
622
struct timeval tv;
623
if (gettimeofday(&tv, NULL) == 0) {
624
long long sec = (long long)tv.tv_sec;
625
return (sec*1000) + (tv.tv_usec/1000);
626
}
627
return 0;
628
}
629
630
JNIEXPORT void JNICALL
631
Java_java_awt_AWTEvent_nativeSetSource
632
(JNIEnv *env, jobject self, jobject newSource)
633
{
634
}
635
636
/*
637
* Class: sun_lwawt_macosx_NSEvent
638
* Method: nsToJavaMouseModifiers
639
* Signature: (II)I
640
*/
641
JNIEXPORT jint JNICALL
642
Java_sun_lwawt_macosx_NSEvent_nsToJavaMouseModifiers
643
(JNIEnv *env, jclass cls, jint buttonNumber, jint modifierFlags)
644
{
645
jint jmodifiers = 0;
646
647
JNF_COCOA_ENTER(env);
648
649
jmodifiers = GetJavaMouseModifiers(buttonNumber, modifierFlags);
650
651
JNF_COCOA_EXIT(env);
652
653
return jmodifiers;
654
}
655
656
/*
657
* Class: sun_lwawt_macosx_NSEvent
658
* Method: nsToJavaKeyModifiers
659
* Signature: (I)I
660
*/
661
JNIEXPORT jint JNICALL
662
Java_sun_lwawt_macosx_NSEvent_nsToJavaKeyModifiers
663
(JNIEnv *env, jclass cls, jint modifierFlags)
664
{
665
jint jmodifiers = 0;
666
667
JNF_COCOA_ENTER(env);
668
669
jmodifiers = NsKeyModifiersToJavaModifiers(modifierFlags, YES);
670
671
JNF_COCOA_EXIT(env);
672
673
return jmodifiers;
674
}
675
676
/*
677
* Class: sun_lwawt_macosx_NSEvent
678
* Method: nsToJavaKeyInfo
679
* Signature: ([I[I)Z
680
*/
681
JNIEXPORT jboolean JNICALL
682
Java_sun_lwawt_macosx_NSEvent_nsToJavaKeyInfo
683
(JNIEnv *env, jclass cls, jintArray inData, jintArray outData)
684
{
685
BOOL postsTyped = NO;
686
687
JNF_COCOA_ENTER(env);
688
689
jboolean copy = JNI_FALSE;
690
jint *data = (*env)->GetIntArrayElements(env, inData, &copy);
691
CHECK_NULL_RETURN(data, postsTyped);
692
693
// in = [testChar, testDeadChar, modifierFlags, keyCode]
694
jchar testChar = (jchar)data[0];
695
BOOL isDeadChar = (data[1] != 0);
696
jint modifierFlags = data[2];
697
jshort keyCode = (jshort)data[3];
698
699
jint jkeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
700
jint jkeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
701
jchar testDeadChar = 0;
702
703
NsCharToJavaVirtualKeyCode((unichar)testChar, isDeadChar,
704
(NSUInteger)modifierFlags, (unsigned short)keyCode,
705
&jkeyCode, &jkeyLocation, &postsTyped, &testDeadChar);
706
707
// out = [jkeyCode, jkeyLocation];
708
(*env)->SetIntArrayRegion(env, outData, 0, 1, &jkeyCode);
709
(*env)->SetIntArrayRegion(env, outData, 1, 1, &jkeyLocation);
710
(*env)->SetIntArrayRegion(env, outData, 2, 1, (jint *)&testDeadChar);
711
712
(*env)->ReleaseIntArrayElements(env, inData, data, 0);
713
714
JNF_COCOA_EXIT(env);
715
716
return postsTyped;
717
}
718
719
/*
720
* Class: sun_lwawt_macosx_NSEvent
721
* Method: nsKeyModifiersToJavaKeyInfo
722
* Signature: ([I[I)V
723
*/
724
JNIEXPORT void JNICALL
725
Java_sun_lwawt_macosx_NSEvent_nsKeyModifiersToJavaKeyInfo
726
(JNIEnv *env, jclass cls, jintArray inData, jintArray outData)
727
{
728
JNF_COCOA_ENTER(env);
729
730
jboolean copy = JNI_FALSE;
731
jint *data = (*env)->GetIntArrayElements(env, inData, &copy);
732
CHECK_NULL(data);
733
734
// in = [modifierFlags, keyCode]
735
jint modifierFlags = data[0];
736
jshort keyCode = (jshort)data[1];
737
738
jint jkeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
739
jint jkeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
740
jint jkeyType = java_awt_event_KeyEvent_KEY_PRESSED;
741
742
NsKeyModifiersToJavaKeyInfo(modifierFlags,
743
keyCode,
744
&jkeyCode,
745
&jkeyLocation,
746
&jkeyType);
747
748
// out = [jkeyCode, jkeyLocation, jkeyType];
749
(*env)->SetIntArrayRegion(env, outData, 0, 1, &jkeyCode);
750
(*env)->SetIntArrayRegion(env, outData, 1, 1, &jkeyLocation);
751
(*env)->SetIntArrayRegion(env, outData, 2, 1, &jkeyType);
752
753
(*env)->ReleaseIntArrayElements(env, inData, data, 0);
754
755
JNF_COCOA_EXIT(env);
756
}
757
758
/*
759
* Class: sun_lwawt_macosx_NSEvent
760
* Method: nsToJavaChar
761
* Signature: (CI)C
762
*/
763
JNIEXPORT jint JNICALL
764
Java_sun_lwawt_macosx_NSEvent_nsToJavaChar
765
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags)
766
{
767
jchar javaChar = 0;
768
769
JNF_COCOA_ENTER(env);
770
771
javaChar = NsCharToJavaChar(nsChar, modifierFlags);
772
773
JNF_COCOA_EXIT(env);
774
775
return javaChar;
776
}
777
778