/* * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #import "common.h" #import "com_sun_glass_events_KeyEvent.h" #import "com_sun_glass_ui_mac_MacApplication.h" #import "GlassApplication.h" #import "GlassMacros.h" #import "GlassKey.h" //#define VERBOSE #ifndef VERBOSE #define LOG(MSG, ...) #else #define LOG(MSG, ...) GLASS_LOG(MSG, ## __VA_ARGS__); #endif struct KeyMapEntry { unsigned short keyCode; jint jKeyCode; BOOL sendJavaChars; }; static const struct KeyMapEntry gKeyMap[] = { {0x00, com_sun_glass_events_KeyEvent_VK_A, YES}, {0x01, com_sun_glass_events_KeyEvent_VK_S, YES}, {0x02, com_sun_glass_events_KeyEvent_VK_D, YES}, {0x03, com_sun_glass_events_KeyEvent_VK_F, YES}, {0x04, com_sun_glass_events_KeyEvent_VK_H, YES}, {0x05, com_sun_glass_events_KeyEvent_VK_G, YES}, {0x06, com_sun_glass_events_KeyEvent_VK_Z, YES}, {0x07, com_sun_glass_events_KeyEvent_VK_X, YES}, {0x08, com_sun_glass_events_KeyEvent_VK_C, YES}, {0x09, com_sun_glass_events_KeyEvent_VK_V, YES}, {0x0A, com_sun_glass_events_KeyEvent_VK_BACK_QUOTE, YES}, {0x0B, com_sun_glass_events_KeyEvent_VK_B, YES}, {0x0C, com_sun_glass_events_KeyEvent_VK_Q, YES}, {0x0D, com_sun_glass_events_KeyEvent_VK_W, YES}, {0x0E, com_sun_glass_events_KeyEvent_VK_E, YES}, {0x0F, com_sun_glass_events_KeyEvent_VK_R, YES}, {0x10, com_sun_glass_events_KeyEvent_VK_Y, YES}, {0x11, com_sun_glass_events_KeyEvent_VK_T, YES}, {0x12, com_sun_glass_events_KeyEvent_VK_1, YES}, {0x13, com_sun_glass_events_KeyEvent_VK_2, YES}, {0x14, com_sun_glass_events_KeyEvent_VK_3, YES}, {0x15, com_sun_glass_events_KeyEvent_VK_4, YES}, {0x16, com_sun_glass_events_KeyEvent_VK_6, YES}, {0x17, com_sun_glass_events_KeyEvent_VK_5, YES}, {0x18, com_sun_glass_events_KeyEvent_VK_EQUALS, YES}, {0x19, com_sun_glass_events_KeyEvent_VK_9, YES}, {0x1A, com_sun_glass_events_KeyEvent_VK_7, YES}, {0x1B, com_sun_glass_events_KeyEvent_VK_MINUS, YES}, {0x1C, com_sun_glass_events_KeyEvent_VK_8, YES}, {0x1D, com_sun_glass_events_KeyEvent_VK_0, YES}, {0x1E, com_sun_glass_events_KeyEvent_VK_CLOSE_BRACKET, YES}, {0x1F, com_sun_glass_events_KeyEvent_VK_O, YES}, {0x20, com_sun_glass_events_KeyEvent_VK_U, YES}, {0x21, com_sun_glass_events_KeyEvent_VK_OPEN_BRACKET, YES}, {0x22, com_sun_glass_events_KeyEvent_VK_I, YES}, {0x23, com_sun_glass_events_KeyEvent_VK_P, YES}, {0x24, com_sun_glass_events_KeyEvent_VK_ENTER, YES}, {0x25, com_sun_glass_events_KeyEvent_VK_L, YES}, {0x26, com_sun_glass_events_KeyEvent_VK_J, YES}, {0x27, com_sun_glass_events_KeyEvent_VK_QUOTE, YES}, {0x28, com_sun_glass_events_KeyEvent_VK_K, YES}, {0x29, com_sun_glass_events_KeyEvent_VK_SEMICOLON, YES}, {0x2A, com_sun_glass_events_KeyEvent_VK_BACK_SLASH, YES}, {0x2B, com_sun_glass_events_KeyEvent_VK_COMMA, YES}, {0x2C, com_sun_glass_events_KeyEvent_VK_SLASH, YES}, {0x2D, com_sun_glass_events_KeyEvent_VK_N, YES}, {0x2E, com_sun_glass_events_KeyEvent_VK_M, YES}, {0x2F, com_sun_glass_events_KeyEvent_VK_PERIOD, YES}, {0x30, com_sun_glass_events_KeyEvent_VK_TAB, YES}, {0x31, com_sun_glass_events_KeyEvent_VK_SPACE, YES}, {0x32, com_sun_glass_events_KeyEvent_VK_BACK_QUOTE, YES}, {0x33, com_sun_glass_events_KeyEvent_VK_BACKSPACE, NO}, {0x34, com_sun_glass_events_KeyEvent_VK_ENTER, YES}, {0x35, com_sun_glass_events_KeyEvent_VK_ESCAPE, NO}, {0x36, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x37, com_sun_glass_events_KeyEvent_VK_COMMAND, NO}, {0x38, com_sun_glass_events_KeyEvent_VK_SHIFT, NO}, {0x39, com_sun_glass_events_KeyEvent_VK_CAPS_LOCK, NO}, {0x3A, com_sun_glass_events_KeyEvent_VK_ALT, NO}, {0x3B, com_sun_glass_events_KeyEvent_VK_CONTROL, NO}, {0x3C, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x3D, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x3E, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x3F, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x40, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x41, com_sun_glass_events_KeyEvent_VK_DECIMAL, YES}, {0x42, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x43, com_sun_glass_events_KeyEvent_VK_MULTIPLY, YES}, {0x44, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x45, com_sun_glass_events_KeyEvent_VK_ADD, YES}, {0x46, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x47, com_sun_glass_events_KeyEvent_VK_CLEAR, NO}, {0x48, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x49, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x4A, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x4B, com_sun_glass_events_KeyEvent_VK_DIVIDE, YES}, {0x4C, com_sun_glass_events_KeyEvent_VK_ENTER, YES}, {0x4D, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x4E, com_sun_glass_events_KeyEvent_VK_SUBTRACT, YES}, {0x4F, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x50, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x51, com_sun_glass_events_KeyEvent_VK_EQUALS, YES}, {0x52, com_sun_glass_events_KeyEvent_VK_NUMPAD0, YES}, {0x53, com_sun_glass_events_KeyEvent_VK_NUMPAD1, YES}, {0x54, com_sun_glass_events_KeyEvent_VK_NUMPAD2, YES}, {0x55, com_sun_glass_events_KeyEvent_VK_NUMPAD3, YES}, {0x56, com_sun_glass_events_KeyEvent_VK_NUMPAD4, YES}, {0x57, com_sun_glass_events_KeyEvent_VK_NUMPAD5, YES}, {0x58, com_sun_glass_events_KeyEvent_VK_NUMPAD6, YES}, {0x59, com_sun_glass_events_KeyEvent_VK_NUMPAD7, YES}, {0x5A, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x5B, com_sun_glass_events_KeyEvent_VK_NUMPAD8, YES}, {0x5C, com_sun_glass_events_KeyEvent_VK_NUMPAD9, YES}, {0x5D, com_sun_glass_events_KeyEvent_VK_BACK_SLASH, YES}, {0x5E, com_sun_glass_events_KeyEvent_VK_UNDERSCORE, YES}, {0x5F, com_sun_glass_events_KeyEvent_VK_COMMA, YES}, {0x60, com_sun_glass_events_KeyEvent_VK_F5, NO}, {0x61, com_sun_glass_events_KeyEvent_VK_F6, NO}, {0x62, com_sun_glass_events_KeyEvent_VK_F7, NO}, {0x63, com_sun_glass_events_KeyEvent_VK_F3, NO}, {0x64, com_sun_glass_events_KeyEvent_VK_F8, NO}, {0x65, com_sun_glass_events_KeyEvent_VK_F9, NO}, // {0x66, com_sun_glass_events_KeyEvent_VK_ALPHANUMERIC, NO}, {0x67, com_sun_glass_events_KeyEvent_VK_F11, NO}, // {0x68, com_sun_glass_events_KeyEvent_VK_KATAKANA, NO}, // {0x69, com_sun_glass_events_KeyEvent_VK_F13, NO}, // {0x6A, com_sun_glass_events_KeyEvent_VK_F16, NO}, // {0x6B, com_sun_glass_events_KeyEvent_VK_F14, NO}, {0x6C, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x6D, com_sun_glass_events_KeyEvent_VK_F10, NO}, {0x6E, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, {0x6F, com_sun_glass_events_KeyEvent_VK_F12, NO}, {0x70, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, // {0x71, com_sun_glass_events_KeyEvent_VK_F15, NO}, {0x72, com_sun_glass_events_KeyEvent_VK_HELP, NO}, {0x73, com_sun_glass_events_KeyEvent_VK_HOME, NO}, {0x74, com_sun_glass_events_KeyEvent_VK_PAGE_UP, NO}, {0x75, com_sun_glass_events_KeyEvent_VK_DELETE, NO}, {0x76, com_sun_glass_events_KeyEvent_VK_F4, NO}, {0x77, com_sun_glass_events_KeyEvent_VK_END, NO}, {0x78, com_sun_glass_events_KeyEvent_VK_F2, NO}, {0x79, com_sun_glass_events_KeyEvent_VK_PAGE_DOWN, NO}, {0x7A, com_sun_glass_events_KeyEvent_VK_F1, NO}, {0x7B, com_sun_glass_events_KeyEvent_VK_LEFT, NO}, {0x7C, com_sun_glass_events_KeyEvent_VK_RIGHT, NO}, {0x7D, com_sun_glass_events_KeyEvent_VK_DOWN, NO}, {0x7E, com_sun_glass_events_KeyEvent_VK_UP, NO}, {0x7F, com_sun_glass_events_KeyEvent_VK_UNDEFINED, NO}, }; static const int gKeyMapSize = sizeof(gKeyMap) / sizeof(struct KeyMapEntry); jint GetJavaKeyModifiers(NSEvent *event) { jint jModifiers = 0; NSUInteger modifierFlags = ([event modifierFlags] & NSDeviceIndependentModifierFlagsMask); if (((modifierFlags & NSShiftKeyMask) != 0) == YES) { jModifiers |= com_sun_glass_events_KeyEvent_MODIFIER_SHIFT; } if (((modifierFlags & NSFunctionKeyMask) != 0) == YES) { jModifiers |= com_sun_glass_events_KeyEvent_MODIFIER_FUNCTION; } if (((modifierFlags & NSControlKeyMask) != 0) == YES) { jModifiers |= com_sun_glass_events_KeyEvent_MODIFIER_CONTROL; } if (((modifierFlags & NSAlternateKeyMask) != 0) == YES) { jModifiers |= com_sun_glass_events_KeyEvent_MODIFIER_OPTION; } if (((modifierFlags & NSCommandKeyMask) != 0) == YES) { jModifiers |= com_sun_glass_events_KeyEvent_MODIFIER_COMMAND; } return jModifiers; } jint GetJavaMouseModifiers(NSUInteger buttons) { jint jModifiers = 0; if (buttons & (1 << 0)) { jModifiers |= com_sun_glass_events_KeyEvent_MODIFIER_BUTTON_PRIMARY; } if (buttons & (1 << 1)) { jModifiers |= com_sun_glass_events_KeyEvent_MODIFIER_BUTTON_SECONDARY; } if (buttons & (1 << 2)) { jModifiers |= com_sun_glass_events_KeyEvent_MODIFIER_BUTTON_MIDDLE; } return jModifiers; } jint GetJavaModifiers(NSEvent *event) { return GetJavaKeyModifiers(event) | GetJavaMouseModifiers([NSEvent pressedMouseButtons]); } jint GetJavaKeyCodeFor(unsigned short keyCode) { // Not the fastest implementation... for (int i=0; iNewCharArray(env, 0); } jchar jc[16]; [chars getCharacters:jc range:NSMakeRange(0, [chars length])]; jcharArray jChars = (*env)->NewCharArray(env, (jsize)[chars length]); (*env)->SetCharArrayRegion(env, jChars, 0, (jsize)[chars length], jc); GLASS_CHECK_EXCEPTION(env); return jChars; } BOOL GetMacKey(jint javaKeyCode, unsigned short *outMacKeyCode) { for (int index=0; index