/*
 * Copyright (c) 2011, 2014, 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 <JavaNativeFoundation/JavaNativeFoundation.h>
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
#import <sys/time.h>

#import "jni_util.h" 
#import "LWCToolkit.h"
#import "ThreadUtilities.h"

#import "java_awt_event_InputEvent.h"
#import "java_awt_event_KeyEvent.h"
#import "java_awt_event_MouseEvent.h"

/*
 * Table to map typed characters to their Java virtual key equivalent and back.
 * We use the incoming unichar (ignoring all modifiers) and try to figure out
 * which virtual key code is appropriate. A lot of them just have direct
 * mappings (the function keys, arrow keys, etc.) so they aren't a problem.
 * We had to do something a little funky to catch the keys on the numeric
 * key pad (i.e. using event mask to distinguish between period on regular
 * keyboard and decimal on keypad). We also have to do something incredibly
 * hokey with regards to the shifted punctuation characters. For examples,
 * consider '&' which is usually Shift-7.  For the Java key typed events,
 * that's no problem, we just say pass the unichar. But for the
 * KeyPressed/Released events, we need to identify the virtual key code
 * (which roughly correspond to hardware keys) which means we are supposed
 * to say the virtual 7 key was pressed.  But how are we supposed to know
 * when we get a punctuation char what was the real hardware key was that
 * was pressed?  Although '&' often comes from Shift-7 the keyboard can be
 * remapped!  I don't think there really is a good answer, and hopefully
 * all good applets are only interested in logical key typed events not
 * press/release.  Meanwhile, we are hard-coding the shifted punctuation
 * to trigger the virtual keys that are the expected ones under a standard
 * keymapping. Looking at Windows & Mac, they don't actually do this, the
 * Mac seems to just put the ascii code in for the shifted punctuation
 * (which means they actually end up with bogus key codes on the Java side),
 * Windows I can't even figure out what it's doing.
 */
#define KL_STANDARD java_awt_event_KeyEvent_KEY_LOCATION_STANDARD
#define KL_NUMPAD   java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD
#define KL_UNKNOWN  java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN
static struct _key
{
    unsigned short keyCode;
    BOOL postsTyped;
    jint javaKeyLocation;
    jint javaKeyCode;
}
const keyTable[] =
{
    {0x00, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_A},
    {0x01, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_S},
    {0x02, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_D},
    {0x03, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_F},
    {0x04, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_H},
    {0x05, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_G},
    {0x06, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Z},
    {0x07, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_X},
    {0x08, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_C},
    {0x09, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_V},
    {0x0A, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_QUOTE},
    {0x0B, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_B},
    {0x0C, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Q},
    {0x0D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_W},
    {0x0E, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_E},
    {0x0F, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_R},
    {0x10, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_Y},
    {0x11, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_T},
    {0x12, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_1},
    {0x13, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_2},
    {0x14, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_3},
    {0x15, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_4},
    {0x16, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_6},
    {0x17, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_5},
    {0x18, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_EQUALS},
    {0x19, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_9},
    {0x1A, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_7},
    {0x1B, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_MINUS},
    {0x1C, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_8},
    {0x1D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_0},
    {0x1E, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_CLOSE_BRACKET},
    {0x1F, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_O},
    {0x20, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_U},
    {0x21, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_OPEN_BRACKET},
    {0x22, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_I},
    {0x23, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_P},
    {0x24, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_ENTER},
    {0x25, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_L},
    {0x26, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_J},
    {0x27, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_QUOTE},
    {0x28, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_K},
    {0x29, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SEMICOLON},
    {0x2A, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SLASH},
    {0x2B, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_COMMA},
    {0x2C, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SLASH},
    {0x2D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_N},
    {0x2E, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_M},
    {0x2F, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_PERIOD},
    {0x30, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_TAB},
    {0x31, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_SPACE},
    {0x32, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_QUOTE},
    {0x33, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SPACE},
    {0x34, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_ENTER},
    {0x35, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_ESCAPE},
    {0x36, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x37, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_META},      // ****
    {0x38, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_SHIFT},     // ****
    {0x39, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_CAPS_LOCK},
    {0x3A, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_ALT},       // ****
    {0x3B, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_CONTROL},   // ****
    {0x3C, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x3D, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x3E, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x3F, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED}, // the 'fn' key on PowerBooks
    {0x40, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x41, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_DECIMAL},
    {0x42, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x43, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_MULTIPLY},
    {0x44, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x45, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_ADD},
    {0x46, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x47, NO,  KL_NUMPAD,   java_awt_event_KeyEvent_VK_CLEAR},
    {0x48, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x49, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x4A, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x4B, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_DIVIDE},
    {0x4C, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_ENTER},
    {0x4D, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x4E, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_SUBTRACT},
    {0x4F, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x50, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x51, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_EQUALS},
    {0x52, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_NUMPAD0},
    {0x53, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_NUMPAD1},
    {0x54, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_NUMPAD2},
    {0x55, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_NUMPAD3},
    {0x56, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_NUMPAD4},
    {0x57, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_NUMPAD5},
    {0x58, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_NUMPAD6},
    {0x59, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_NUMPAD7},
    {0x5A, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x5B, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_NUMPAD8},
    {0x5C, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_NUMPAD9},
    {0x5D, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_BACK_SLASH}, // This is a combo yen/backslash on JIS keyboards.
    {0x5E, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_UNDERSCORE},
    {0x5F, YES, KL_NUMPAD,   java_awt_event_KeyEvent_VK_COMMA},
    {0x60, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F5},
    {0x61, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F6},
    {0x62, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F7},
    {0x63, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F3},
    {0x64, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F8},
    {0x65, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F9},
    {0x66, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_ALPHANUMERIC},
    {0x67, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F11},
    {0x68, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_KATAKANA},
    {0x69, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F13},
    {0x6A, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F16},
    {0x6B, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F14},
    {0x6C, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x6D, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F10},
    {0x6E, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x6F, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F12},
    {0x70, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
    {0x71, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F15},
    {0x72, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_HELP},
    {0x73, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_HOME},
    {0x74, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_PAGE_UP},
    {0x75, YES, KL_STANDARD, java_awt_event_KeyEvent_VK_DELETE},
    {0x76, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F4},
    {0x77, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_END},
    {0x78, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F2},
    {0x79, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_PAGE_DOWN},
    {0x7A, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_F1},
    {0x7B, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_LEFT},
    {0x7C, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_RIGHT},
    {0x7D, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_DOWN},
    {0x7E, NO,  KL_STANDARD, java_awt_event_KeyEvent_VK_UP},
    {0x7F, NO,  KL_UNKNOWN,  java_awt_event_KeyEvent_VK_UNDEFINED},
};

/*
 * This table was stolen from the Windows implementation for mapping
 * Unicode values to VK codes for dead keys.  On Windows, some layouts
 * return ASCII punctuation for dead accents, while some return spacing
 * accent chars, so both should be listed.  However, in all of the
 * keyboard layouts I tried only the Unicode values are used.
 */
struct CharToVKEntry {
    UniChar c;
    jint javaKey;
};
static const struct CharToVKEntry charToDeadVKTable[] = {
    {0x0060, java_awt_event_KeyEvent_VK_DEAD_GRAVE},
    {0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE},
    {0x0384, java_awt_event_KeyEvent_VK_DEAD_ACUTE}, // Unicode "GREEK TONOS" -- Greek keyboard, semicolon key
    {0x005E, java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX},
    {0x007E, java_awt_event_KeyEvent_VK_DEAD_TILDE},
    {0x02DC, java_awt_event_KeyEvent_VK_DEAD_TILDE}, // Unicode "SMALL TILDE"
    {0x00AF, java_awt_event_KeyEvent_VK_DEAD_MACRON},
    {0x02D8, java_awt_event_KeyEvent_VK_DEAD_BREVE},
    {0x02D9, java_awt_event_KeyEvent_VK_DEAD_ABOVEDOT},
    {0x00A8, java_awt_event_KeyEvent_VK_DEAD_DIAERESIS},
    {0x02DA, java_awt_event_KeyEvent_VK_DEAD_ABOVERING},
    {0x02DD, java_awt_event_KeyEvent_VK_DEAD_DOUBLEACUTE},
    {0x02C7, java_awt_event_KeyEvent_VK_DEAD_CARON},
    {0x00B8, java_awt_event_KeyEvent_VK_DEAD_CEDILLA},
    {0x02DB, java_awt_event_KeyEvent_VK_DEAD_OGONEK},
    {0x037A, java_awt_event_KeyEvent_VK_DEAD_IOTA},
    {0x309B, java_awt_event_KeyEvent_VK_DEAD_VOICED_SOUND},
    {0x309C, java_awt_event_KeyEvent_VK_DEAD_SEMIVOICED_SOUND},
    {0,0}
};

// TODO: some constants below are part of CGS (private interfaces)...
// for now we will look at the raw key code to determine left/right status
// but not sure this is foolproof...
static struct _nsKeyToJavaModifier
{
    NSUInteger nsMask;
    //NSUInteger cgsLeftMask;
    //NSUInteger cgsRightMask;
    unsigned short leftKeyCode;
    unsigned short rightKeyCode;
    jint javaExtMask;
    jint javaMask;
    jint javaKey;
}
const nsKeyToJavaModifierTable[] =
{
    {
        NSAlphaShiftKeyMask,
        0,
        0,
        0, // no Java equivalent
        0, // no Java equivalent
        java_awt_event_KeyEvent_VK_CAPS_LOCK
    },
    {
        NSShiftKeyMask,
        //kCGSFlagsMaskAppleShiftKey,
        //kCGSFlagsMaskAppleRightShiftKey,
        56,
        60,
        java_awt_event_InputEvent_SHIFT_DOWN_MASK,
        java_awt_event_InputEvent_SHIFT_MASK,
        java_awt_event_KeyEvent_VK_SHIFT
    },
    {
        NSControlKeyMask,
        //kCGSFlagsMaskAppleControlKey,
        //kCGSFlagsMaskAppleRightControlKey,
        59,
        62,
        java_awt_event_InputEvent_CTRL_DOWN_MASK,
        java_awt_event_InputEvent_CTRL_MASK,
        java_awt_event_KeyEvent_VK_CONTROL
    },
    {
        NSAlternateKeyMask,
        //kCGSFlagsMaskAppleLeftAlternateKey,
        //kCGSFlagsMaskAppleRightAlternateKey,
        58,
        61,
        java_awt_event_InputEvent_ALT_DOWN_MASK,
        java_awt_event_InputEvent_ALT_MASK,
        java_awt_event_KeyEvent_VK_ALT
    },
    {
        NSCommandKeyMask,
        //kCGSFlagsMaskAppleLeftCommandKey,
        //kCGSFlagsMaskAppleRightCommandKey,
        55,
        54,
        java_awt_event_InputEvent_META_DOWN_MASK,
        java_awt_event_InputEvent_META_MASK,
        java_awt_event_KeyEvent_VK_META
    },
    // NSNumericPadKeyMask
    {
        NSHelpKeyMask,
        0,
        0,
        0, // no Java equivalent
        0, // no Java equivalent
        java_awt_event_KeyEvent_VK_HELP
    },
    // NSFunctionKeyMask
    {0, 0, 0, 0, 0, 0}
};

static unichar NsGetDeadKeyChar(unsigned short keyCode)
{
    TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
    CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
    if (uchr == nil) { return 0; }
    const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr);
    // Carbon modifiers should be used instead of NSEvent modifiers
    UInt32 modifierKeyState = (GetCurrentEventKeyModifiers() >> 8) & 0xFF;

    if (keyboardLayout) {
        UInt32 deadKeyState = 0;
        UniCharCount maxStringLength = 255;
        UniCharCount actualStringLength = 0;
        UniChar unicodeString[maxStringLength];

        // get the deadKeyState
        OSStatus status = UCKeyTranslate(keyboardLayout,
                                         keyCode, kUCKeyActionDown, modifierKeyState,
                                         LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
                                         &deadKeyState,
                                         maxStringLength,
                                         &actualStringLength, unicodeString);

        if (status == noErr && deadKeyState != 0) {
            // Press SPACE to get the dead key char
            status = UCKeyTranslate(keyboardLayout,
                                    kVK_Space, kUCKeyActionDown, 0,
                                    LMGetKbdType(), 0,
                                    &deadKeyState,
                                    maxStringLength,
                                    &actualStringLength, unicodeString);

            if (status == noErr && actualStringLength > 0) {
                return unicodeString[0];
            }
        }
    }
    return 0;
}

static NSDictionary* getDiacriticUnicharToVkCodeDictionary() {

    static NSDictionary* diacriticUnicharToVkCodeDictionary = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
         diacriticUnicharToVkCodeDictionary =
             [NSDictionary dictionaryWithObjectsAndKeys:
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_A_WITH_GRAVE], @"à",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_A_WITH_ACUTE], @"á",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_A_WITH_CIRCUMFLEX], @"â",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_A_WITH_TILDE], @"ã",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_A_WITH_DIAERESIS], @"ä",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_A_WITH_RING_ABOVE], @"å",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_AE], @"æ",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_C_WITH_CEDILLA], @"ç",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_E_WITH_GRAVE], @"è",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_E_WITH_ACUTE], @"é",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_E_WITH_CIRCUMFLEX], @"ê",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_E_WITH_DIAERESIS], @"ë",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_I_WITH_GRAVE], @"ì",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_I_WITH_ACUTE], @"í",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_I_WITH_CIRCUMFLEX], @"î",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_I_WITH_DIAERESIS], @"ï",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_ETH], @"ð",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_N_WITH_TILDE], @"ñ",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_O_WITH_GRAVE], @"ò",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_O_WITH_ACUTE], @"ó",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_O_WITH_CIRCUMFLEX], @"ô",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_O_WITH_TILDE], @"õ",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_O_WITH_DIAERESIS], @"ö",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_DIVISION_SIGN], @"÷",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_O_WITH_SLASH], @"ø",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_U_WITH_GRAVE], @"ù",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_U_WITH_ACUTE], @"ú",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_U_WITH_CIRCUMFLEX], @"û",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_U_WITH_DIAERESIS], @"ü",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_Y_WITH_ACUTE], @"ý",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_THORN], @"þ",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_Y_WITH_DIAERESIS], @"ÿ",
                  [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_ESZETT], @"ß",
                  nil
             ];
             // This is ok to retain a singleton object
             [diacriticUnicharToVkCodeDictionary retain];
    });
    return diacriticUnicharToVkCodeDictionary;
}

static NSDictionary* getUnicharToVkCodeDictionary() {

    static NSDictionary* unicharToVkCodeDictionary = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
         unicharToVkCodeDictionary =
             [NSDictionary dictionaryWithObjectsAndKeys:
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_BACK_QUOTE], @"`",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_1], @"1",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_2], @"2",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_3], @"3",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_4], @"4",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_5], @"5",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_6], @"6",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_7], @"7",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_8], @"8",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_9], @"9",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_0], @"0",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_EQUALS], @"=",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_MINUS], @"-",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_CLOSE_BRACKET], @"]",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_OPEN_BRACKET], @"[",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_QUOTE], @"\'",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_SEMICOLON], @";",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_COLON], @":",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_BACK_SLASH], @"\\",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_COMMA], @",",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_SLASH], @"/",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_PERIOD], @".",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_MULTIPLY], @"*",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_ADD], @"+",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_EQUALS], @"=",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_COMMA], @",",
                 [NSNumber numberWithInt:java_awt_event_KeyEvent_VK_NUMBER_SIGN], @"#",
                 nil
             ];
             // This is ok to retain a singleton object
             [unicharToVkCodeDictionary retain];
    });

    return unicharToVkCodeDictionary;
}

/*
 * This is the function that uses the table above to take incoming
 * NSEvent keyCodes and translate to the Java virtual key code.
 */
static void
NsCharToJavaVirtualKeyCodeOld(unichar ch, BOOL isDeadChar,
                           NSUInteger flags, unsigned short key,
                           jint *keyCode, jint *keyLocation, BOOL *postsTyped, unichar *deadChar)
{
    static size_t size = sizeof(keyTable) / sizeof(struct _key);
    NSInteger offset;

    if (isDeadChar) {
        unichar testDeadChar = NsGetDeadKeyChar(key);
        const struct CharToVKEntry *map;
        for (map = charToDeadVKTable; map->c != 0; ++map) {
            if (testDeadChar == map->c) {
                *keyCode = map->javaKey;
                *postsTyped = NO;
                // TODO: use UNKNOWN here?
                *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
                *deadChar = testDeadChar;
                return;
            }
        }
        // If we got here, we keep looking for a normal key.
    }

    if ([[NSCharacterSet letterCharacterSet] characterIsMember:ch]) {
        // key is an alphabetic character
        unichar lower;
        lower = tolower(ch);
        offset = lower - 'a';
        if (offset >= 0 && offset <= 25) {
            // some chars in letter set are NOT actually A-Z characters?!
            // skip them...
            *postsTyped = YES;
            // do quick conversion
            *keyCode = java_awt_event_KeyEvent_VK_A + offset;
            *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
            return;
        }
    }

    if ([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:ch]) {
        // key is a digit
        offset = ch - '0';
        // make sure in range for decimal digits
        if (offset >= 0 && offset <= 9)    {
            jboolean numpad = (flags & NSNumericPadKeyMask) != 0;
            *postsTyped = YES;
            if (numpad) {
                *keyCode = offset + java_awt_event_KeyEvent_VK_NUMPAD0;
                *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD;
            } else {
                *keyCode = offset + java_awt_event_KeyEvent_VK_0;
                *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
            }
            return;
        }
    }

    if (key < size) {
        *postsTyped = keyTable[key].postsTyped;
        *keyCode = keyTable[key].javaKeyCode;
        *keyLocation = keyTable[key].javaKeyLocation;
    } else {
        // Should we report this? This means we've got a keyboard
        // we don't know about...
        *postsTyped = NO;
        *keyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
        *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
    }
}

/*
 * This is the function that uses the table above to take incoming
 * NSEvent keyCodes and translate to the Java virtual key code.
 */
static void
NsCharToJavaVirtualKeyCode(unichar ch, BOOL isDeadChar,
                           NSUInteger flags, unsigned short key,
                           jint *keyCode, jint *keyLocation, BOOL *postsTyped, unichar *deadChar)
{
    static size_t size = sizeof(keyTable) / sizeof(struct _key);
    NSInteger offset;

    if (isDeadChar) {
        //NSLog(@"This is a dead char");
        unichar testDeadChar = NsGetDeadKeyChar(key);
        const struct CharToVKEntry *map;
        for (map = charToDeadVKTable; map->c != 0; ++map) {
            if (testDeadChar == map->c) {
                *keyCode = map->javaKey;
                *postsTyped = NO;
                // TODO: use UNKNOWN here?
                *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
                *deadChar = testDeadChar;
                return;
            }
        }
        // If we got here, we keep looking for a normal key.
    }



    if ([[NSCharacterSet letterCharacterSet] characterIsMember:ch]) {
        // key is an alphabetic character
        unichar lower;
        lower = tolower(ch);
        offset = lower - 'a';
        //NSLog(@"letter offset: %d", offset);
        if (offset >= 0 && offset <= 25) {
            // some chars in letter set are NOT actually A-Z characters?!
            // skip them...
            *postsTyped = YES;
            // do quick conversion
            *keyCode = java_awt_event_KeyEvent_VK_A + offset;
            //NSLog(@"A code is  %d", java_awt_event_KeyEvent_VK_A);
            //NSLog(@"so key code is: %d", *keyCode);
            *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
            return;
        }
    }

    if ([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:ch]) {
        // key is a digit
        offset = ch - '0';
        // make sure in range for decimal digits
        //NSLog(@"This is a decimal digit");
        if (offset >= 0 && offset <= 9)    {
            jboolean numpad = (flags & NSNumericPadKeyMask) != 0;
            *postsTyped = YES;
            if (numpad) {
                *keyCode = offset + java_awt_event_KeyEvent_VK_NUMPAD0;
                *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD;
            } else {
                *keyCode = offset + java_awt_event_KeyEvent_VK_0;
                *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
            }
            return;
        }
    }

    NSDictionary* unicharToVkCodeDictionary = getUnicharToVkCodeDictionary();
    if ([[NSCharacterSet punctuationCharacterSet] characterIsMember:ch] ||
         [[NSCharacterSet symbolCharacterSet] characterIsMember:ch])
    {
         //NSLog(@"This is a punctuation char");
         *keyCode = [[unicharToVkCodeDictionary objectForKey:[NSString stringWithFormat:@"%C",ch]] intValue];
         //NSLog(@"key code %d for char %@", *keyCode,[NSString stringWithFormat:@"%C",ch]);
         // we cannot find key location from a char, so let's use key code
         *postsTyped = YES;
         *keyLocation = keyTable[key].javaKeyLocation;
         return;
    }

    NSDictionary* diacriticUnicharToVkCodeDictionary = getDiacriticUnicharToVkCodeDictionary();
    NSNumber * jkc = [diacriticUnicharToVkCodeDictionary objectForKey:[NSString stringWithFormat:@"%C",ch]];
    if (jkc != nil) {
        //NSLog(@"This is a Diacritic Unichar");
        *keyCode = [jkc intValue];
        // we cannot find key location from a char, so let's use key code
        *postsTyped = YES;
        *keyLocation = keyTable[key].javaKeyLocation;
        return;
    }

    *postsTyped = keyTable[key].postsTyped;
    *keyCode = keyTable[key].javaKeyCode;
    *keyLocation = keyTable[key].javaKeyLocation;

}

/*
 * This returns the java key data for the key NSEvent modifiers
 * (after NSFlagChanged).
 */
static void
NsKeyModifiersToJavaKeyInfo(NSUInteger nsFlags, unsigned short eventKeyCode,
                            jint *javaKeyCode,
                            jint *javaKeyLocation,
                            jint *javaKeyType)
{
    static NSUInteger sPreviousNSFlags = 0;

    const struct _nsKeyToJavaModifier* cur;
    NSUInteger oldNSFlags = sPreviousNSFlags;
    NSUInteger changedNSFlags = oldNSFlags ^ nsFlags;
    sPreviousNSFlags = nsFlags;

    *javaKeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
    *javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
    *javaKeyType = java_awt_event_KeyEvent_KEY_PRESSED;

    for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) {
        if (changedNSFlags & cur->nsMask) {
            *javaKeyCode = cur->javaKey;
            *javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_STANDARD;
            // TODO: uses SPI...
            //if (changedNSFlags & cur->cgsLeftMask) {
            //    *javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_LEFT;
            //} else if (changedNSFlags & cur->cgsRightMask) {
            //    *javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_RIGHT;
            //}
            if (eventKeyCode == cur->leftKeyCode) {
                *javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_LEFT;
            } else if (eventKeyCode == cur->rightKeyCode) {
                *javaKeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_RIGHT;
            }
            *javaKeyType = (cur->nsMask & nsFlags) ?
                java_awt_event_KeyEvent_KEY_PRESSED :
                java_awt_event_KeyEvent_KEY_RELEASED;
            break;
        }
    }
}

/*
 * This returns the java modifiers for a key NSEvent.
 */
jint NsKeyModifiersToJavaModifiers(NSUInteger nsFlags, BOOL isExtMods)
{
    jint javaModifiers = 0;
    const struct _nsKeyToJavaModifier* cur;

    for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) {
        if ((cur->nsMask & nsFlags) != 0) {
            javaModifiers |= isExtMods? cur->javaExtMask : cur->javaMask;
        }
    }

    return javaModifiers;
}

/*
 * This returns the NSEvent flags for java key modifiers.
 */
NSUInteger JavaModifiersToNsKeyModifiers(jint javaModifiers, BOOL isExtMods)
{
    NSUInteger nsFlags = 0;
    const struct _nsKeyToJavaModifier* cur;

    for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) {
        jint mask = isExtMods? cur->javaExtMask : cur->javaMask;
        if ((mask & javaModifiers) != 0) {
            nsFlags |= cur->nsMask;
        }
    }

    // special case
    jint mask = isExtMods? java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK :
                           java_awt_event_InputEvent_ALT_GRAPH_MASK;

    if ((mask & javaModifiers) != 0) {
        nsFlags |= NSAlternateKeyMask;
    }

    return nsFlags;
}


jint GetJavaMouseModifiers(NSInteger button, NSUInteger modifierFlags)
{
    // Mousing needs the key modifiers
    jint modifiers = NsKeyModifiersToJavaModifiers(modifierFlags, YES);


    /*
     * Ask Quartz about mouse buttons state
     */

    if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState,
                                 kCGMouseButtonLeft)) {
        modifiers |= java_awt_event_InputEvent_BUTTON1_DOWN_MASK;
    }

    if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState,
                                 kCGMouseButtonRight)) {
        modifiers |= java_awt_event_InputEvent_BUTTON3_DOWN_MASK;
    }

    if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState,
                                 kCGMouseButtonCenter)) {
        modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK;
    }

    NSInteger extraButton = 3;
    for (; extraButton < gNumberOfButtons; extraButton++) {
        if (CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState,
                                 extraButton)) {
            modifiers |= gButtonDownMasks[extraButton];
        }
    }

    return modifiers;
}

jlong UTC(NSEvent *event) {
    struct timeval tv;
    if (gettimeofday(&tv, NULL) == 0) {
        long long sec = (long long)tv.tv_sec;
        return (sec*1000) + (tv.tv_usec/1000);
    }
    return 0;
}

JNIEXPORT void JNICALL
Java_java_awt_AWTEvent_nativeSetSource
    (JNIEnv *env, jobject self, jobject newSource)
{
}

/*
 * Class:     sun_lwawt_macosx_NSEvent
 * Method:    nsToJavaMouseModifiers
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL
Java_sun_lwawt_macosx_NSEvent_nsToJavaMouseModifiers
(JNIEnv *env, jclass cls, jint buttonNumber, jint modifierFlags)
{
    jint jmodifiers = 0;

JNF_COCOA_ENTER(env);

    jmodifiers = GetJavaMouseModifiers(buttonNumber, modifierFlags);

JNF_COCOA_EXIT(env);

    return jmodifiers;
}

/*
 * Class:     sun_lwawt_macosx_NSEvent
 * Method:    nsToJavaKeyModifiers
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL
Java_sun_lwawt_macosx_NSEvent_nsToJavaKeyModifiers
(JNIEnv *env, jclass cls, jint modifierFlags)
{
    jint jmodifiers = 0;

JNF_COCOA_ENTER(env);

    jmodifiers = NsKeyModifiersToJavaModifiers(modifierFlags, YES);

JNF_COCOA_EXIT(env);

    return jmodifiers;
}

/*
 * Class:     sun_lwawt_macosx_NSEvent
 * Method:    nsToJavaKeyInfo
 * Signature: ([I[I)Z
 */
JNIEXPORT jboolean JNICALL
Java_sun_lwawt_macosx_NSEvent_nsToJavaKeyInfoOld
(JNIEnv *env, jclass cls, jintArray inData, jintArray outData)
{
    BOOL postsTyped = NO;

JNF_COCOA_ENTER(env);

    jboolean copy = JNI_FALSE;
    jint *data = (*env)->GetIntArrayElements(env, inData, &copy);
    CHECK_NULL_RETURN(data, postsTyped);

    // in  = [testChar, testDeadChar, modifierFlags, keyCode]
    jchar testChar = (jchar)data[0];
    jint modifierFlags = data[1];
    BOOL isDeadChar = (data[2] != 0);
    jshort keyCode = (jshort)data[3];

    jint jkeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
    jint jkeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
    jchar testDeadChar = 0;

    NsCharToJavaVirtualKeyCodeOld((unichar)testChar, isDeadChar,
                               (NSUInteger)modifierFlags, (unsigned short)keyCode,
                               &jkeyCode, &jkeyLocation, &postsTyped, &testDeadChar);

    // out = [jkeyCode, jkeyLocation];
    (*env)->SetIntArrayRegion(env, outData, 0, 1, &jkeyCode);
    (*env)->SetIntArrayRegion(env, outData, 1, 1, &jkeyLocation);
    (*env)->SetIntArrayRegion(env, outData, 2, 1, (jint *)&testDeadChar);

    (*env)->ReleaseIntArrayElements(env, inData, data, 0);

JNF_COCOA_EXIT(env);

    return postsTyped;
}

/*
 * Class:     sun_lwawt_macosx_NSEvent
 * Method:    nsToJavaKeyInfo
 * Signature: ([I[I)Z
 */
JNIEXPORT jboolean JNICALL
Java_sun_lwawt_macosx_NSEvent_nsToJavaKeyInfo
(JNIEnv *env, jclass cls, jintArray inData, jintArray outData)
{
    BOOL postsTyped = NO;

JNF_COCOA_ENTER(env);

    jboolean copy = JNI_FALSE;
    jint *data = (*env)->GetIntArrayElements(env, inData, &copy);
    CHECK_NULL_RETURN(data, postsTyped);

    // in  = [testChar, testDeadChar, modifierFlags, keyCode]
    jchar testChar = (jchar)data[0];
    jint modifierFlags = data[1];
    BOOL isDeadChar = (data[2] != 0);
    jshort keyCode = (jshort)data[3];

    jint jkeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
    jint jkeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
    jchar testDeadChar = 0;

    NsCharToJavaVirtualKeyCode((unichar)testChar, isDeadChar,
                               (NSUInteger)modifierFlags, (unsigned short)keyCode,
                               &jkeyCode, &jkeyLocation, &postsTyped, &testDeadChar);

    // out = [jkeyCode, jkeyLocation];
    (*env)->SetIntArrayRegion(env, outData, 0, 1, &jkeyCode);
    (*env)->SetIntArrayRegion(env, outData, 1, 1, &jkeyLocation);
    (*env)->SetIntArrayRegion(env, outData, 2, 1, (jint *)&testDeadChar);

    (*env)->ReleaseIntArrayElements(env, inData, data, 0);

JNF_COCOA_EXIT(env);

    return postsTyped;
}

/*
 * Class:     sun_lwawt_macosx_NSEvent
 * Method:    nsKeyModifiersToJavaKeyInfo
 * Signature: ([I[I)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_NSEvent_nsKeyModifiersToJavaKeyInfo
(JNIEnv *env, jclass cls, jintArray inData, jintArray outData)
{
JNF_COCOA_ENTER(env);

    jboolean copy = JNI_FALSE;
    jint *data = (*env)->GetIntArrayElements(env, inData, &copy);
    CHECK_NULL(data);

    // in  = [modifierFlags, keyCode]
    jint modifierFlags = data[0];
    jshort keyCode = (jshort)data[1];

    jint jkeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
    jint jkeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
    jint jkeyType = java_awt_event_KeyEvent_KEY_PRESSED;

    NsKeyModifiersToJavaKeyInfo(modifierFlags,
                                keyCode,
                                &jkeyCode,
                                &jkeyLocation,
                                &jkeyType);

    // out = [jkeyCode, jkeyLocation, jkeyType];
    (*env)->SetIntArrayRegion(env, outData, 0, 1, &jkeyCode);
    (*env)->SetIntArrayRegion(env, outData, 1, 1, &jkeyLocation);
    (*env)->SetIntArrayRegion(env, outData, 2, 1, &jkeyType);

    (*env)->ReleaseIntArrayElements(env, inData, data, 0);

JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_NSEvent
 * Method:    nsToJavaChar
 * Signature: (CI)Ljava/lang/String
 */
JNIEXPORT jstring JNICALL
Java_sun_lwawt_macosx_NSEvent_nsToJavaChar
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags)
{
    jstring charAsString = NULL;

JNF_COCOA_ENTER(env);

    NSString * nsStr = [NSString stringWithFormat: @"%C", nsChar];
    charAsString = JNFNSToJavaString(env,  nsStr);


JNF_COCOA_EXIT(env);

    return charAsString;
}

/*
 * Almost all unicode characters just go from NS to Java with no translation.
 *  For the few exceptions, we handle it here with this small table.
 */
#define ALL_NS_KEY_MODIFIERS_MASK \
    (NSShiftKeyMask | NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask)

static struct _char {
    NSUInteger modifier;
    unichar nsChar;
    unichar javaChar;
}
const charTable[] = {
    // map enter on keypad to same as return key
    {0,                         NSEnterCharacter,          NSNewlineCharacter},

    // [3134616] return newline instead of carriage return
    {0,                         NSCarriageReturnCharacter, NSNewlineCharacter},

    // "delete" means backspace in Java
    {ALL_NS_KEY_MODIFIERS_MASK, NSDeleteCharacter,         NSBackspaceCharacter},
    {ALL_NS_KEY_MODIFIERS_MASK, NSDeleteFunctionKey,       NSDeleteCharacter},

    // back-tab is only differentiated from tab by Shift flag
    {NSShiftKeyMask,            NSBackTabCharacter,        NSTabCharacter},

    {0, 0, 0}
};

unichar NsCharToJavaChar(unichar nsChar, NSUInteger modifiers)
{
    const struct _char *cur;
    // Mask off just the keyboard modifiers from the event modifier mask.
    NSUInteger testableFlags = (modifiers & ALL_NS_KEY_MODIFIERS_MASK);

    // walk through table & find the match
    for (cur = charTable; cur->nsChar != 0 ; cur++) {
        // <rdar://Problem/3476426> Need to determine if we are looking at
        // a plain keypress or a modified keypress.  Don't adjust the
        // character of a keypress with a modifier.
        if (cur->nsChar == nsChar) {
            if (cur->modifier == 0 && testableFlags == 0) {
                // If the modifier field is 0, that means to transform
                // this character if no additional keyboard modifiers are set.
                // This lets ctrl-C be reported as ctrl-C and not transformed
                // into Newline.
                return cur->javaChar;
            } else if (cur->modifier != 0 &&
                       (testableFlags & cur->modifier) == testableFlags)
            {
                // Likewise, if the modifier field is nonzero, that means
                // transform this character if only these modifiers are
                // set in the testable flags.
                return cur->javaChar;
            }
        }
    }

    if (nsChar >= NSUpArrowFunctionKey && nsChar <= NSModeSwitchFunctionKey) {
        return java_awt_event_KeyEvent_CHAR_UNDEFINED;
    }

    // otherwise return character unchanged
    return nsChar;
}

/*
 * Class:     sun_lwawt_macosx_NSEvent
 * Method:    nsToJavaChar
 * Signature: (CI)C
 */
JNIEXPORT jint JNICALL
Java_sun_lwawt_macosx_NSEvent_nsToJavaCharOld
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags)
{
    jchar javaChar = 0;

JNF_COCOA_ENTER(env);

    javaChar = NsCharToJavaChar(nsChar, modifierFlags);

JNF_COCOA_EXIT(env);

    return javaChar;
}
