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