changeset 4651:d7e5eb51caa3

7124335: [macosx] Need a java.awt.EmbeddedFrame subclass Reviewed-by: art
author dcherepanov
date Wed, 11 Jan 2012 19:07:01 +0300
parents d201644bbdb0
children c4b4f0b11530
files make/sun/lwawt/FILES_export_macosx.gmk src/macosx/classes/sun/lwawt/LWToolkit.java src/macosx/classes/sun/lwawt/LWWindowPeer.java src/macosx/classes/sun/lwawt/PlatformWindow.java src/macosx/classes/sun/lwawt/macosx/CDropTarget.java src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java src/macosx/classes/sun/lwawt/macosx/CInputMethod.java src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java src/macosx/classes/sun/lwawt/macosx/CPlatformView.java src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java src/macosx/classes/sun/lwawt/macosx/CocoaConstants.java src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java src/macosx/classes/sun/lwawt/macosx/event/NSEvent.java src/macosx/native/sun/awt/AWTEvent.h src/macosx/native/sun/awt/AWTEvent.m src/macosx/native/sun/awt/AWTView.m
diffstat 18 files changed, 826 insertions(+), 148 deletions(-) [+]
line wrap: on
line diff
--- a/make/sun/lwawt/FILES_export_macosx.gmk	Tue Jan 10 07:34:06 2012 -0800
+++ b/make/sun/lwawt/FILES_export_macosx.gmk	Wed Jan 11 19:07:01 2012 +0300
@@ -145,6 +145,9 @@
         sun/lwawt/macosx/CPlatformView.java \
         sun/lwawt/macosx/CPlatformWindow.java \
         sun/lwawt/macosx/CPlatformComponent.java \
+        sun/lwawt/macosx/CEmbeddedFrame.java \
+        sun/lwawt/macosx/CPlatformEmbeddedFrame.java \
+        sun/lwawt/macosx/CPlatformResponder.java \
         sun/lwawt/macosx/CPopupMenu.java \
         sun/lwawt/macosx/CRobot.java \
         sun/lwawt/macosx/CSystemTray.java \
--- a/src/macosx/classes/sun/lwawt/LWToolkit.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/LWToolkit.java	Wed Jan 11 19:07:01 2012 +0300
@@ -236,6 +236,11 @@
         return createDelegatedPeer(target, platformComponent, platformWindow);
     }
 
+    public LWWindowPeer createEmbeddedFrame(CEmbeddedFrame target) {
+        PlatformComponent platformComponent = createPlatformComponent();
+        PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.EMBEDDEDFRAME);
+        return createDelegatedPeer(target, platformComponent, platformWindow);
+    }
 
     CPrinterDialogPeer createCPrinterDialog(CPrinterDialog target) {
         PlatformComponent platformComponent = createPlatformComponent();
--- a/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Wed Jan 11 19:07:01 2012 +0300
@@ -500,7 +500,7 @@
 
     @Override
     public void setBoundsPrivate(int x, int y, int width, int height) {
-        throw new RuntimeException("not implemented");
+        setBounds(x, y, width, height, SET_BOUNDS | NO_EMBEDDED_CHECK);
     }
 
     @Override
@@ -1122,4 +1122,8 @@
     public void exitFullScreenMode() {
         platformWindow.exitFullScreenMode();
     }
+
+    public long getLayerPtr() {
+        return getPlatformWindow().getLayerPtr();
+    }
 }
--- a/src/macosx/classes/sun/lwawt/PlatformWindow.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/PlatformWindow.java	Wed Jan 11 19:07:01 2012 +0300
@@ -143,4 +143,8 @@
     public void exitFullScreenMode();
 
     public void setWindowState(int windowState);
+
+    public long getLayerPtr();
+
+    public LWWindowPeer getPeer();
 }
--- a/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java	Wed Jan 11 19:07:01 2012 +0300
@@ -56,13 +56,16 @@
 
         // Get model pointer (CButton.m and such) and its native peer:
         LWComponentPeer model = (LWComponentPeer) peer;
-        CPlatformWindow platformWindow = (CPlatformWindow) model.getPlatformWindow();
-        long nativePeer = platformWindow.getNSWindowPtr();
+        if (model.getPlatformWindow() instanceof CPlatformWindow) {
+            CPlatformWindow platformWindow = (CPlatformWindow) model.getPlatformWindow();
+            long nativePeer = platformWindow.getNSWindowPtr();
 
-        // Create native dragging destination:
-        fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer);
-        if (fNativeDropTarget == 0)
-            throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed.");
+            // Create native dragging destination:
+            fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer);
+            if (fNativeDropTarget == 0) {
+                throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed.");
+            }
+        }
     }
 
     public DropTarget getDropTarget() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Wed Jan 11 19:07:01 2012 +0300
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+package sun.lwawt.macosx;
+
+import sun.lwawt.LWToolkit;
+import sun.lwawt.LWWindowPeer;
+import sun.lwawt.macosx.CocoaConstants;
+import sun.lwawt.macosx.event.NSEvent;
+
+import sun.awt.EmbeddedFrame;
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class CEmbeddedFrame extends EmbeddedFrame {
+
+    private CPlatformResponder responder;
+
+    public CEmbeddedFrame() {
+        show();
+    }
+
+    public void addNotify() {
+        if (getPeer() == null) {
+            LWToolkit toolkit = (LWToolkit)Toolkit.getDefaultToolkit();
+            LWWindowPeer peer = toolkit.createEmbeddedFrame(this);
+            setPeer(peer);
+            responder = new CPlatformResponder(peer, true);
+        }
+        super.addNotify();
+    }
+
+    public void registerAccelerator(AWTKeyStroke stroke) {}
+
+    public void unregisterAccelerator(AWTKeyStroke stroke) {}
+
+    protected long getLayerPtr() {
+        LWWindowPeer peer = (LWWindowPeer)getPeer();
+        return peer.getLayerPtr();
+    }
+
+    // -----------------------------------------------------------------------
+    //                          SYNTHETIC EVENT DELIVERY
+    // -----------------------------------------------------------------------
+
+    public void handleMouseEvent(int eventType, int modifierFlags, double pluginX,
+                                 double pluginY, int buttonNumber, int clickCount) {
+        int x = (int)pluginX;
+        int y = (int)pluginY;
+        Point locationOnScreen = getLocationOnScreen();
+        int screenX = locationOnScreen.x + x;
+        int screenY = locationOnScreen.y + y;
+
+        responder.handleMouseEvent(eventType, modifierFlags, buttonNumber,
+                                   clickCount, x, y, screenX, screenY);
+    }
+
+    public void handleScrollEvent(double pluginX, double pluginY, int modifierFlags,
+                                  double deltaX, double deltaY, double deltaZ) {
+        int x = (int)pluginX;
+        int y = (int)pluginY;
+
+        responder.handleScrollEvent(x, y, modifierFlags, deltaX, deltaY);
+    }
+
+    public void handleKeyEvent(int eventType, int modifierFlags, String characters,
+                               String charsIgnoringMods, boolean isRepeat, short keyCode) {
+        responder.handleKeyEvent(eventType, modifierFlags, charsIgnoringMods, keyCode);
+    }
+
+    public void handleInputEvent(String text) {
+        new RuntimeException("Not implemented");
+    }
+}
--- a/src/macosx/classes/sun/lwawt/macosx/CInputMethod.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/CInputMethod.java	Wed Jan 11 19:07:01 2012 +0300
@@ -243,9 +243,13 @@
     }
 
     long getNativeViewPtr(LWComponentPeer peer) {
-        CPlatformWindow platformWindow = (CPlatformWindow) peer.getPlatformWindow();
-        CPlatformView platformView = platformWindow.getContentView();
-        return platformView.getAWTView();
+        if (peer.getPlatformWindow() instanceof CPlatformWindow) {
+            CPlatformWindow platformWindow = (CPlatformWindow) peer.getPlatformWindow();
+            CPlatformView platformView = platformWindow.getContentView();
+            return platformView.getAWTView();
+        } else {
+            return 0;
+        }
     }
 
     /**
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java	Wed Jan 11 19:07:01 2012 +0300
@@ -38,7 +38,7 @@
 
     Component target;
     LWComponentPeer peer;
-    CPlatformWindow platformWindow;
+    PlatformWindow platformWindow;
 
     private native long nativeCreateComponent(long windowLayer);
     private native long nativeSetBounds(long ptr, int x, int y, int width, int height);
@@ -54,9 +54,9 @@
     public void initialize(Component target, LWComponentPeer peer, PlatformWindow platformWindow) {
         this.target = target;
         this.peer = peer;
-        this.platformWindow = (CPlatformWindow)platformWindow;
+        this.platformWindow = platformWindow;
 
-        long windowLayerPtr = this.platformWindow.getContentView().getWindowLayerPtr();
+        long windowLayerPtr = platformWindow.getLayerPtr();
         setPtr(nativeCreateComponent(windowLayerPtr));
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Wed Jan 11 19:07:01 2012 +0300
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+package sun.lwawt.macosx;
+
+import sun.lwawt.PlatformWindow;
+import sun.lwawt.LWWindowPeer;
+
+import sun.java2d.opengl.CGLLayer;
+import sun.java2d.SurfaceData;
+
+import sun.awt.CGraphicsConfig;
+import sun.awt.CGraphicsDevice;
+
+import java.awt.*;
+import java.awt.BufferCapabilities.FlipContents;
+
+/*
+ * Provides a lightweight implementation of the EmbeddedFrame.
+ */
+public class CPlatformEmbeddedFrame implements PlatformWindow {
+
+    private CGLLayer windowLayer;
+    private LWWindowPeer peer;
+
+    private volatile int screenX = 0;
+    private volatile int screenY = 0;
+
+    @Override // PlatformWindow
+    public void initialize(Window target, final LWWindowPeer peer, PlatformWindow owner) {
+        this.peer = peer;
+        this.windowLayer = new CGLLayer(peer);
+    }
+
+    @Override
+    public LWWindowPeer getPeer() {
+        return peer;
+    }
+
+    @Override
+    public long getLayerPtr() {
+        return windowLayer.getPointer();
+    }
+
+    @Override
+    public void dispose() {
+        windowLayer.dispose();
+    }
+
+    @Override
+    public void setBounds(int x, int y, int w, int h) {
+        // This is a lightweight implementation of the EmbeddedFrame
+        // and we simply synthesize a reshape request.
+        screenX = x;
+        screenY = y;
+        peer.notifyReshape(x, y, w, h);
+    }
+
+    @Override
+    public int getScreenImOn() {
+        // REMIND: return the main screen for the initial implementation
+        CGraphicsConfig gc = (CGraphicsConfig)peer.getGraphicsConfiguration();
+        CGraphicsDevice device = gc.getDevice();
+        return device.getCoreGraphicsScreen();
+    }
+
+    @Override
+    public Point getLocationOnScreen() {
+        return new Point(screenX, screenY);
+    }
+
+    @Override
+    public FontMetrics getFontMetrics(Font f) {
+        throw new RuntimeException("Not implemented");
+    }
+
+    @Override
+    public SurfaceData getScreenSurface() {
+        return windowLayer.getSurfaceData();
+    }
+
+    @Override
+    public SurfaceData replaceSurfaceData() {
+        return windowLayer.replaceSurfaceData();
+    }
+
+    @Override
+    public Image createBackBuffer() {
+        Rectangle r = peer.getBounds();
+        Image im = null;
+        if (!r.isEmpty()) {
+            int transparency = (peer.isOpaque() ? Transparency.OPAQUE : Transparency.TRANSLUCENT);
+            im = peer.getGraphicsConfiguration().createCompatibleImage(r.width, r.height, transparency);
+        }
+        return im;
+    }
+
+    @Override
+    public void flip(int x1, int y1, int x2, int y2, FlipContents flipAction) {
+        throw new RuntimeException("Not implemented");
+    }
+
+    @Override
+    public void setVisible(boolean visible) {}
+
+    @Override
+    public void setTitle(String title) {}
+
+    @Override
+    public Insets getInsets() {
+        return new Insets(0, 0, 0, 0);
+    }
+
+    @Override
+    public void toFront() {}
+
+    @Override
+    public void toBack() {}
+
+    @Override
+    public void setMenuBar(MenuBar mb) {}
+
+    @Override
+    public void setAlwaysOnTop(boolean value) {}
+
+    @Override
+    public void updateFocusableWindowState() {}
+
+    @Override
+    public boolean requestWindowFocus(boolean isMouseEventCause) {
+        return true;
+    }
+
+    @Override
+    public void setResizable(boolean resizable) {}
+
+    @Override
+    public void setMinimumSize(int width, int height) {}
+
+    @Override
+    public Graphics transformGraphics(Graphics g) {
+        return g;
+    }
+
+    @Override
+    public void updateIconImages() {}
+
+    @Override
+    public void setOpacity(float opacity) {}
+
+    @Override
+    public void setOpaque(boolean isOpaque) {}
+
+    @Override
+    public void enterFullScreenMode() {}
+
+    @Override
+    public void exitFullScreenMode() {}
+
+    @Override
+    public void setWindowState(int windowState) {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java	Wed Jan 11 19:07:01 2012 +0300
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+package sun.lwawt.macosx;
+
+import sun.lwawt.LWWindowPeer;
+import sun.lwawt.macosx.event.NSEvent;
+
+import java.awt.event.MouseEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.KeyEvent;
+
+/*
+ * Translates NSEvents/NPCocoaEvents into AWT events.
+ */
+public class CPlatformResponder {
+
+    private LWWindowPeer peer;
+    private boolean isNpapiCallback;
+
+    public CPlatformResponder(LWWindowPeer peer, boolean isNpapiCallback) {
+        this.peer = peer;
+        this.isNpapiCallback = isNpapiCallback;
+    }
+
+    /*
+     * Handles mouse events.
+     */
+    public void handleMouseEvent(int eventType, int modifierFlags, int buttonNumber,
+                                 int clickCount, int x, int y, int absoluteX, int absoluteY) {
+        int jeventType = isNpapiCallback ? NSEvent.npEventTypeToJavaEventType(eventType) :
+                                           NSEvent.nsEventTypeToJavaEventType(eventType);
+
+        int jbuttonNumber = MouseEvent.NOBUTTON;
+        int jclickCount = 0;
+
+        if (jeventType != MouseEvent.MOUSE_MOVED &&
+            jeventType != MouseEvent.MOUSE_ENTERED &&
+            jeventType != MouseEvent.MOUSE_EXITED)
+        {
+            jbuttonNumber = NSEvent.nsButtonToJavaButton(buttonNumber);
+            jclickCount = clickCount;
+        }
+
+        int jmodifiers = NSEvent.nsMouseModifiersToJavaMouseModifiers(buttonNumber, modifierFlags);
+        boolean jpopupTrigger = NSEvent.isPopupTrigger(jmodifiers);
+
+        peer.dispatchMouseEvent(jeventType, System.currentTimeMillis(), jbuttonNumber,
+                                x, y, absoluteX, absoluteY, jmodifiers, jclickCount,
+                                jpopupTrigger, null);
+    }
+
+    /*
+     * Handles scroll events.
+     */
+    public void handleScrollEvent(int x, int y, int modifierFlags,
+                                  double deltaX, double deltaY) {
+        int buttonNumber = CocoaConstants.kCGMouseButtonCenter;
+        int jmodifiers = NSEvent.nsMouseModifiersToJavaMouseModifiers(buttonNumber, modifierFlags);
+
+        double wheelDelta = deltaY;
+
+        // Shirt+vertical wheel scroll produces horizontal scroll
+        if ((jmodifiers & InputEvent.SHIFT_DOWN_MASK) != 0) {
+            wheelDelta = deltaX;
+        }
+        // Wheel amount "oriented" inside out
+        wheelDelta = -wheelDelta;
+
+        peer.dispatchMouseWheelEvent(System.currentTimeMillis(), x, y, jmodifiers,
+                                     MouseWheelEvent.WHEEL_UNIT_SCROLL, 3, // WHEEL_SCROLL_AMOUNT
+                                     (int)wheelDelta, wheelDelta, null);
+    }
+
+    /*
+     * Handles key events.
+     */
+    public void handleKeyEvent(int eventType, int modifierFlags, String charsIgnoringMods,
+                               short keyCode) {
+        boolean isFlagsChangedEvent =
+            isNpapiCallback ? (eventType == CocoaConstants.NPCocoaEventFlagsChanged) :
+                              (eventType == CocoaConstants.NSFlagsChanged);
+
+        int jeventType = KeyEvent.KEY_PRESSED;
+        int jkeyCode = KeyEvent.VK_UNDEFINED;
+        int jkeyLocation = KeyEvent.KEY_LOCATION_UNKNOWN;
+        boolean postsTyped = false;
+
+        char testChar = KeyEvent.CHAR_UNDEFINED;
+        char testDeadChar = 0;
+
+        if (isFlagsChangedEvent) {
+            int[] in = new int[] {modifierFlags, keyCode};
+            int[] out = new int[3]; // [jkeyCode, jkeyLocation, jkeyType]
+
+            NSEvent.nsKeyModifiersToJavaKeyInfo(in, out);
+
+            jkeyCode = out[0];
+            jkeyLocation = out[1];
+            jeventType = out[2];
+        } else {
+            if (charsIgnoringMods != null && charsIgnoringMods.length() > 0) {
+                testChar = charsIgnoringMods.charAt(0);
+            }
+
+            int[] in = new int[] {testChar, testDeadChar, modifierFlags, keyCode};
+            int[] out = new int[2]; // [jkeyCode, jkeyLocation]
+
+            postsTyped = NSEvent.nsKeyInfoToJavaKeyInfo(in, out);
+
+            jkeyCode = out[0];
+            jkeyLocation = out[1];
+            jeventType = isNpapiCallback ? NSEvent.npEventTypeToJavaEventType(eventType) :
+                                           NSEvent.nsEventTypeToJavaEventType(eventType);
+        }
+
+        int jmodifiers = NSEvent.nsKeyModifiersToJavaKeyModifiers(modifierFlags);
+
+        peer.dispatchKeyEvent(jeventType, System.currentTimeMillis(), jmodifiers,
+                              jkeyCode, testChar, jkeyLocation);
+
+        // That's the reaction on the PRESSED (not RELEASED) event as it comes to
+        // appear in MacOSX.
+        // Modifier keys (shift, etc) don't want to send TYPED events.
+        // On the other hand we don't want to generate keyTyped events
+        // for clipboard related shortcuts like Meta + [CVX]
+        boolean isMetaDown = (jmodifiers & KeyEvent.META_DOWN_MASK) != 0;
+        if (jeventType == KeyEvent.KEY_PRESSED && postsTyped && !isMetaDown) {
+            boolean isCtrlDown = (jmodifiers & KeyEvent.CTRL_DOWN_MASK) != 0;
+            boolean isShiftDown = (jmodifiers & KeyEvent.SHIFT_DOWN_MASK) != 0;
+
+            // emulating the codes from the ASCII table
+            int shift = isCtrlDown ? isShiftDown ? 64 : 96 : 0;
+            peer.dispatchKeyEvent(KeyEvent.KEY_TYPED, System.currentTimeMillis(), jmodifiers,
+                                  KeyEvent.VK_UNDEFINED, (char) (testChar - shift),
+                                  KeyEvent.KEY_LOCATION_UNKNOWN);
+        }
+    }
+}
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java	Wed Jan 11 19:07:01 2012 +0300
@@ -43,6 +43,7 @@
     private LWWindowPeer peer;
     private SurfaceData surfaceData;
     private CGLLayer windowLayer;
+    private CPlatformResponder responder;
 
     public CPlatformView() {
         super(0, true);
@@ -50,6 +51,7 @@
 
     public void initialize(LWWindowPeer peer) {
         this.peer = peer;
+        this.responder = new CPlatformResponder(peer, false);
 
         if (!LWCToolkit.getSunAwtDisableCALayers()) {
             this.windowLayer = new CGLLayer(peer);
@@ -182,92 +184,22 @@
     // NATIVE CALLBACKS
     // ----------------------------------------------------------------------
 
-    // This code uses peer's API which is a no-no on the AppKit thread.
-    // TODO: post onto the EDT.
     private void deliverMouseEvent(NSEvent event) {
-        int jModifiers = event.getModifiers();
-        int jX = event.getX();
-        // a difference in coordinate systems
-        int jY = getBounds().height - event.getY();
-        int jAbsX = event.getAbsX();
-        int jAbsY = event.getAbsY();
-        int jButton = NSEvent.nsButtonToJavaButton(event);
-        int jClickCount = event.getClickCount();
-        double wheelDeltaY = event.getScrollDeltaY();
-        double wheelDeltaX = event.getScrollDeltaX();
-        boolean isPopupTrigger = event.isPopupTrigger();
+        int x = event.getX();
+        int y = getBounds().height - event.getY();
 
-        int jEventType;
-        switch (event.getType()) {
-            case CocoaConstants.NSLeftMouseDown:
-            case CocoaConstants.NSRightMouseDown:
-            case CocoaConstants.NSOtherMouseDown:
-                jEventType = MouseEvent.MOUSE_PRESSED;
-                break;
-            case CocoaConstants.NSLeftMouseUp:
-            case CocoaConstants.NSRightMouseUp:
-            case CocoaConstants.NSOtherMouseUp:
-                jEventType = MouseEvent.MOUSE_RELEASED;
-                break;
-            case CocoaConstants.NSMouseMoved:
-                jEventType = MouseEvent.MOUSE_MOVED;
-                break;
-
-            case CocoaConstants.NSLeftMouseDragged:
-            case CocoaConstants.NSRightMouseDragged:
-            case CocoaConstants.NSOtherMouseDragged:
-                jEventType = MouseEvent.MOUSE_DRAGGED;
-                break;
-            case CocoaConstants.NSMouseEntered:
-                jEventType = MouseEvent.MOUSE_ENTERED;
-                break;
-            case CocoaConstants.NSMouseExited:
-                jEventType = MouseEvent.MOUSE_EXITED;
-                break;
-            case CocoaConstants.NSScrollWheel:
-                jEventType = MouseEvent.MOUSE_WHEEL;
-                double wheelDelta = wheelDeltaY;
-
-                // shift+vertical wheel scroll produces horizontal scroll
-                // we convert it to vertical
-                if ((jModifiers & InputEvent.SHIFT_DOWN_MASK) != 0) {
-                    wheelDelta = wheelDeltaX;
-                }
-
-                // Wheel amount "oriented" inside out
-                wheelDelta = -wheelDelta;
-                peer.dispatchMouseWheelEvent(System.currentTimeMillis(), jX, jY, jModifiers, MouseWheelEvent.WHEEL_UNIT_SCROLL, 3, // WHEEL_SCROLL_AMOUNT
-                        (int)wheelDelta, wheelDelta, null);
-                return;
-            default:
-                return;
+        if (event.getType() == CocoaConstants.NSScrollWheel) {
+            responder.handleScrollEvent(x, y, event.getModifierFlags(),
+                                        event.getScrollDeltaX(), event.getScrollDeltaY());
+        } else {
+            responder.handleMouseEvent(event.getType(), event.getModifierFlags(), event.getButtonNumber(),
+                                       event.getClickCount(), x, y, event.getAbsX(), event.getAbsY());
         }
-        peer.dispatchMouseEvent(jEventType, System.currentTimeMillis(), jButton, jX, jY, jAbsX, jAbsY, jModifiers, jClickCount, isPopupTrigger, null);
     }
 
-    private void deliverKeyEvent(final int javaKeyType, final int javaModifiers, final char testChar, final int javaKeyCode, final int javaKeyLocation) {
-        // TODO: there is no focus owner installed now, get back to this once we assign it properly.
-        java.awt.EventQueue.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                peer.dispatchKeyEvent(javaKeyType, System.currentTimeMillis(), javaModifiers, javaKeyCode, testChar, javaKeyLocation);
-
-                // That's the reaction on the PRESSED (not RELEASED) event as it comes to
-                // appear in MacOSX.
-                // Modifier keys (shift, etc) don't want to send TYPED events.
-                // On the other hand we don't want to generate keyTyped events
-                // for clipboard related shortcuts like Meta + [CVX]
-                boolean isMetaDown = (javaModifiers & KeyEvent.META_DOWN_MASK) != 0;
-                if (!isMetaDown && javaKeyType == KeyEvent.KEY_PRESSED && testChar != KeyEvent.CHAR_UNDEFINED) {
-                    boolean isCtrlDown = (javaModifiers & KeyEvent.CTRL_DOWN_MASK) != 0;
-                    boolean isShiftDown = (javaModifiers & KeyEvent.SHIFT_DOWN_MASK) != 0;
-                    // emulating the codes from the ASCII table
-                    int shift = isCtrlDown ? isShiftDown ? 64 : 96 : 0;
-                    peer.dispatchKeyEvent(KeyEvent.KEY_TYPED, System.currentTimeMillis(), javaModifiers,
-                            KeyEvent.VK_UNDEFINED, (char) (testChar - shift), KeyEvent.KEY_LOCATION_UNKNOWN);
-                }
-            }
-        });
+    private void deliverKeyEvent(NSEvent event) {
+        responder.handleKeyEvent(event.getType(), event.getModifierFlags(),
+                                 event.getCharactersIgnoringModifiers(), event.getKeyCode());
     }
 
     private void deliverWindowDidExposeEvent() {
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Jan 11 19:07:01 2012 +0300
@@ -222,8 +222,9 @@
     public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner) {
         this.peer = _peer;
         this.target = _target;
-        this.owner = (CPlatformWindow)_owner;
-
+        if (_owner instanceof CPlatformWindow) {
+            this.owner = (CPlatformWindow)_owner;
+        }
         final Font font = target.getFont();
         if (font == null) {
             target.setFont(DEFAULT_FONT);
@@ -737,6 +738,7 @@
     /*
      * Returns LWWindowPeer associated with this delegate.
      */
+    @Override
     public LWWindowPeer getPeer() {
         return peer;
     }
@@ -745,6 +747,11 @@
         return contentView;
     }
 
+    @Override
+    public long getLayerPtr() {
+        return contentView.getWindowLayerPtr();
+    }
+
     private void validateSurface() {
         SurfaceData surfaceData = getSurfaceData();
         if (surfaceData instanceof CGLSurfaceData) {
--- a/src/macosx/classes/sun/lwawt/macosx/CocoaConstants.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/CocoaConstants.java	Wed Jan 11 19:07:01 2012 +0300
@@ -78,4 +78,27 @@
     NSEventTypeBeginGesture = 19,
     NSEventTypeEndGesture   = 20
     */
+
+    // See http://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html
+
+    public final static int kCGMouseButtonLeft   = 0;
+    public final static int kCGMouseButtonRight  = 1;
+    public final static int kCGMouseButtonCenter = 2;
+
+    // See https://wiki.mozilla.org/NPAPI:CocoaEventModel
+
+    public final static int NPCocoaEventDrawRect           = 1;
+    public final static int NPCocoaEventMouseDown          = 2;
+    public final static int NPCocoaEventMouseUp            = 3;
+    public final static int NPCocoaEventMouseMoved         = 4;
+    public final static int NPCocoaEventMouseEntered       = 5;
+    public final static int NPCocoaEventMouseExited        = 6;
+    public final static int NPCocoaEventMouseDragged       = 7;
+    public final static int NPCocoaEventKeyDown            = 8;
+    public final static int NPCocoaEventKeyUp              = 9;
+    public final static int NPCocoaEventFlagsChanged       = 10;
+    public final static int NPCocoaEventFocusChanged       = 11;
+    public final static int NPCocoaEventWindowFocusChanged = 12;
+    public final static int NPCocoaEventScrollWheel        = 13;
+    public final static int NPCocoaEventTextInput          = 14;
 }
--- a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Wed Jan 11 19:07:01 2012 +0300
@@ -148,8 +148,11 @@
 
     @Override
     protected PlatformWindow createPlatformWindow(PeerType peerType) {
-        // TODO: window type
-        return new CPlatformWindow(peerType);
+        if (peerType == PeerType.EMBEDDEDFRAME) {
+            return new CPlatformEmbeddedFrame();
+        } else {
+            return new CPlatformWindow(peerType);
+        }
     }
 
     @Override
--- a/src/macosx/classes/sun/lwawt/macosx/event/NSEvent.java	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/classes/sun/lwawt/macosx/event/NSEvent.java	Wed Jan 11 19:07:01 2012 +0300
@@ -36,13 +36,11 @@
 
 public final class NSEvent {
     private int type;
+    private int modifierFlags;
 
-    /*
-     * Java-level modifiers
-     */
-    private int modifiers;
+    // Mouse event information
     private int clickCount;
-    private int button;
+    private int buttonNumber;
     private int x;
     private int y;
     private double scrollDeltaY;
@@ -50,14 +48,24 @@
     private int absX;
     private int absY;
 
-    public NSEvent(int type, int modifiers, int clickCount, int button,
-            int x, int y,
-            int absX, int absY,
-            double scrollDeltaY, double scrollDeltaX) {
+    // Key event information
+    private short keyCode;
+    private String charactersIgnoringModifiers;
+
+    public NSEvent(int type, int modifierFlags, short keyCode, String charactersIgnoringModifiers) {
         this.type = type;
-        this.modifiers = modifiers;
+        this.modifierFlags = modifierFlags;
+        this.keyCode = keyCode;
+        this.charactersIgnoringModifiers = charactersIgnoringModifiers;
+    }
+
+    public NSEvent(int type, int modifierFlags, int clickCount, int buttonNumber,
+                   int x, int y, int absX, int absY,
+                   double scrollDeltaY, double scrollDeltaX) {
+        this.type = type;
+        this.modifierFlags = modifierFlags;
         this.clickCount = clickCount;
-        this.button = button;
+        this.buttonNumber = buttonNumber;
         this.x = x;
         this.y = y;
         this.absX = absX;
@@ -70,16 +78,16 @@
         return type;
     }
 
-    public int getModifiers() {
-        return modifiers;
+    public int getModifierFlags() {
+        return modifierFlags;
     }
 
     public int getClickCount() {
         return clickCount;
     }
 
-    public int getButton() {
-        return button;
+    public int getButtonNumber() {
+        return buttonNumber;
     }
 
     public int getX() {
@@ -106,40 +114,143 @@
         return absY;
     }
 
+    public short getKeyCode() {
+        return keyCode;
+    }
+
+    public String getCharactersIgnoringModifiers() {
+        return charactersIgnoringModifiers;
+    }
+
     @Override
     public String toString() {
-        return "NSEvent[" + getType() + " ," + getModifiers() + " ,"
-                + getClickCount() + " ," + getButton() + " ," + getX() + " ,"
-                + getY() + " ," + absX + " ," + absY+ "]";
+        return "NSEvent[" + getType() + " ," + getModifierFlags() + " ,"
+                + getClickCount() + " ," + getButtonNumber() + " ," + getX() + " ,"
+                + getY() + " ," + getAbsX() + " ," + getAbsY()+ " ," + getKeyCode() + " ,"
+                + getCharactersIgnoringModifiers() + "]";
     }
 
     /*
      * Converts an NSEvent button number to a MouseEvent constant.
      */
-    public static int nsButtonToJavaButton(NSEvent event) {
-        int nsButtonNumber = event.getButton();
-        int jbutton = MouseEvent.NOBUTTON;
-
-        if (event.getType() != CocoaConstants.NSMouseMoved) {
-            if (nsButtonNumber == 0) { // left
-                jbutton = MouseEvent.BUTTON1;
-            } else if (nsButtonNumber == 1) { // right
-                jbutton = MouseEvent.BUTTON3;
-            } else if (nsButtonNumber == 2) { // middle
-                jbutton = MouseEvent.BUTTON2;
-            }
+    public static int nsButtonToJavaButton(int buttonNumber) {
+        int jbuttonNumber = MouseEvent.NOBUTTON;
+        switch (buttonNumber) {
+            case CocoaConstants.kCGMouseButtonLeft:
+                jbuttonNumber = MouseEvent.BUTTON1;
+                break;
+            case CocoaConstants.kCGMouseButtonRight:
+                jbuttonNumber = MouseEvent.BUTTON3;
+                break;
+            case CocoaConstants.kCGMouseButtonCenter:
+                jbuttonNumber = MouseEvent.BUTTON2;
+                break;
         }
-
-        return jbutton;
+        return jbuttonNumber;
     }
 
-    // utility methods
+    /*
+     * Converts NPCocoaEvent types to AWT event types.
+     */
+    public static int npEventTypeToJavaEventType(int npEventType) {
+        int jeventType = 0;
+        switch (npEventType) {
+            case CocoaConstants.NPCocoaEventMouseDown:
+                jeventType = MouseEvent.MOUSE_PRESSED;
+                break;
+            case CocoaConstants.NPCocoaEventMouseUp:
+                jeventType = MouseEvent.MOUSE_RELEASED;
+                break;
+            case CocoaConstants.NPCocoaEventMouseMoved:
+                jeventType = MouseEvent.MOUSE_MOVED;
+                break;
+            case CocoaConstants.NPCocoaEventMouseEntered:
+                jeventType = MouseEvent.MOUSE_ENTERED;
+                break;
+            case CocoaConstants.NPCocoaEventMouseExited:
+                jeventType = MouseEvent.MOUSE_EXITED;
+                break;
+            case CocoaConstants.NPCocoaEventMouseDragged:
+                jeventType = MouseEvent.MOUSE_DRAGGED;
+                break;
+            case CocoaConstants.NPCocoaEventKeyDown:
+                jeventType = KeyEvent.KEY_PRESSED;
+                break;
+            case CocoaConstants.NPCocoaEventKeyUp:
+                jeventType = KeyEvent.KEY_RELEASED;
+                break;
+        }
+        return jeventType;
+    }
 
-    public boolean isPopupTrigger() {
-        final int mods = getModifiers();
-        final boolean isRightButtonDown = ((mods & InputEvent.BUTTON3_DOWN_MASK) != 0);
-        final boolean isLeftButtonDown = ((mods & InputEvent.BUTTON1_DOWN_MASK) != 0);
-        final boolean isControlDown = ((mods & InputEvent.CTRL_DOWN_MASK) != 0);
+    /*
+     * Converts NSEvent types to AWT event types.
+     */
+    public static int nsEventTypeToJavaEventType(int nsEventType) {
+        int jeventType = 0;
+        switch (nsEventType) {
+            case CocoaConstants.NSLeftMouseDown:
+            case CocoaConstants.NSRightMouseDown:
+            case CocoaConstants.NSOtherMouseDown:
+                jeventType = MouseEvent.MOUSE_PRESSED;
+                break;
+            case CocoaConstants.NSLeftMouseUp:
+            case CocoaConstants.NSRightMouseUp:
+            case CocoaConstants.NSOtherMouseUp:
+                jeventType = MouseEvent.MOUSE_RELEASED;
+                break;
+            case CocoaConstants.NSMouseMoved:
+                jeventType = MouseEvent.MOUSE_MOVED;
+                break;
+            case CocoaConstants.NSLeftMouseDragged:
+            case CocoaConstants.NSRightMouseDragged:
+            case CocoaConstants.NSOtherMouseDragged:
+                jeventType = MouseEvent.MOUSE_DRAGGED;
+                break;
+            case CocoaConstants.NSMouseEntered:
+                jeventType = MouseEvent.MOUSE_ENTERED;
+                break;
+            case CocoaConstants.NSMouseExited:
+                jeventType = MouseEvent.MOUSE_EXITED;
+                break;
+            case CocoaConstants.NSScrollWheel:
+                jeventType = MouseEvent.MOUSE_WHEEL;
+                break;
+            case CocoaConstants.NSKeyDown:
+                jeventType = KeyEvent.KEY_PRESSED;
+                break;
+            case CocoaConstants.NSKeyUp:
+                jeventType = KeyEvent.KEY_RELEASED;
+                break;
+        }
+        return jeventType;
+    }
+
+    /*
+     * Converts NSEvent mouse modifiers to AWT mouse modifiers.
+     */
+    public static native int nsMouseModifiersToJavaMouseModifiers(int buttonNumber,
+                                                                  int modifierFlags);
+
+    /*
+     * Converts NSEvent key modifiers to AWT key modifiers.
+     */
+    public static native int nsKeyModifiersToJavaKeyModifiers(int modifierFlags);
+
+    /*
+     * Converts NSEvent key info to AWT key info.
+     */
+    public static native boolean nsKeyInfoToJavaKeyInfo(int[] in, int[] out);
+
+    /*
+     * Converts NSEvent key modifiers to AWT key info.
+     */
+    public static native void nsKeyModifiersToJavaKeyInfo(int[] in, int[] out);
+
+    public static boolean isPopupTrigger(int jmodifiers) {
+        final boolean isRightButtonDown = ((jmodifiers & InputEvent.BUTTON3_DOWN_MASK) != 0);
+        final boolean isLeftButtonDown = ((jmodifiers & InputEvent.BUTTON1_DOWN_MASK) != 0);
+        final boolean isControlDown = ((jmodifiers & InputEvent.CTRL_DOWN_MASK) != 0);
         return isRightButtonDown || (isControlDown && isLeftButtonDown);
     }
 }
--- a/src/macosx/native/sun/awt/AWTEvent.h	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/native/sun/awt/AWTEvent.h	Wed Jan 11 19:07:01 2012 +0300
@@ -32,6 +32,6 @@
 void DeliverJavaKeyEvent(JNIEnv *env, NSEvent *event, jobject peer);
 void DeliverJavaMouseEvent(JNIEnv *env, NSEvent *event, jobject peer);
 void SendAdditionalJavaEvents(JNIEnv *env, NSEvent *nsEvent, jobject peer);
-jint GetJavaMouseModifiers(NSEvent *event);
+jint GetJavaMouseModifiers(NSInteger button, NSUInteger modifierFlags);
 
 #endif /* __AWTEVENT_H */
--- a/src/macosx/native/sun/awt/AWTEvent.m	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/native/sun/awt/AWTEvent.m	Wed Jan 11 19:07:01 2012 +0300
@@ -626,6 +626,10 @@
 }
 */
 
+
+// REMIND: The fix for MACOSX_PORT-539 introduces Java-level implementation
+// of the function below (see CPlatformResponder). Consider removing this code.
+
 void
 DeliverJavaKeyEvent(JNIEnv *env, NSEvent *event, jobject peer)
 {
@@ -704,17 +708,16 @@
     }
 }
 
-jint GetJavaMouseModifiers(NSEvent *event)
+jint GetJavaMouseModifiers(NSInteger button, NSUInteger modifierFlags)
 {
     static NSInteger sMaxMouseButton = 2;
 
-    NSInteger button = [event buttonNumber];
     if (button > sMaxMouseButton) {
         sMaxMouseButton = button;
     }
 
     // Mousing needs the key modifiers
-    jint modifiers = NsKeyModifiersToJavaModifiers([event modifierFlags]);
+    jint modifiers = NsKeyModifiersToJavaModifiers(modifierFlags);
 
 
     /*
@@ -776,7 +779,7 @@
     NSPoint pt = [event locationInWindow];
     NSPoint pOnScreen = [NSEvent mouseLocation];
     jint etype = java_awt_event_MouseEvent_MOUSE_CLICKED;
-    jint modifiers = GetJavaMouseModifiers(event);
+    jint modifiers = GetJavaMouseModifiers([event buttonNumber], [event modifierFlags]);
     jint clickCount = [event clickCount];
     jint button = NSButtonToJavaButton([event buttonNumber]);
 
@@ -973,3 +976,117 @@
     (JNIEnv *env, jobject self, jobject newSource)
 {
 }
+
+/*
+ * Class:     sun_lwawt_macosx_event_NSEvent
+ * Method:    nsMouseModifiersToJavaMouseModifiers
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL
+Java_sun_lwawt_macosx_event_NSEvent_nsMouseModifiersToJavaMouseModifiers
+(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_event_NSEvent
+ * Method:    nsKeyModifiersToJavaKeyModifiers
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL
+Java_sun_lwawt_macosx_event_NSEvent_nsKeyModifiersToJavaKeyModifiers
+(JNIEnv *env, jclass cls, jint modifierFlags)
+{
+    jint jmodifiers = 0;
+
+JNF_COCOA_ENTER(env);
+    
+    jmodifiers = NsKeyModifiersToJavaModifiers(modifierFlags);
+    
+JNF_COCOA_EXIT(env);
+    
+    return jmodifiers;
+}
+
+/*
+ * Class:     sun_lwawt_macosx_event_NSEvent
+ * Method:    nsKeyInfoToJavaKeyInfo
+ * Signature: ([I[I)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_lwawt_macosx_event_NSEvent_nsKeyInfoToJavaKeyInfo
+(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);
+
+    // in  = [testChar, testDeadChar, modifierFlags, keyCode]
+    jchar testChar = (jchar)data[0];
+    jchar testDeadChar = (jchar)data[1];
+    jint modifierFlags = data[2];
+    jshort keyCode = (jshort)data[3];
+
+    jint jkeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
+    jint jkeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
+    
+    NsCharToJavaVirtualKeyCode((unichar)testChar, (unichar)testDeadChar,
+                               (NSUInteger)modifierFlags, (unsigned short)keyCode,
+                               &jkeyCode, &jkeyLocation, &postsTyped);    
+
+    // out = [jkeyCode, jkeyLocation];
+    (*env)->SetIntArrayRegion(env, outData, 0, 1, &jkeyCode);
+    (*env)->SetIntArrayRegion(env, outData, 1, 1, &jkeyLocation);
+    
+JNF_COCOA_EXIT(env);
+
+    return postsTyped;
+}
+
+/*
+ * Class:     sun_lwawt_macosx_event_NSEvent
+ * Method:    nsKeyModifiersToJavaKeyInfo
+ * Signature: ([I[I)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_lwawt_macosx_event_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);
+    
+    // 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);
+    
+JNF_COCOA_EXIT(env);
+}
--- a/src/macosx/native/sun/awt/AWTView.m	Tue Jan 10 07:34:06 2012 -0800
+++ b/src/macosx/native/sun/awt/AWTView.m	Wed Jan 11 19:07:01 2012 +0300
@@ -198,7 +198,7 @@
         [self deliverJavaMouseEvent: event];
     }
 }
-
+    
 - (void) mouseUp: (NSEvent *)event {
     [self deliverJavaMouseEvent: event];
 }
@@ -326,13 +326,12 @@
     } else {
         clickCount = [event clickCount];
     }
-    
-    jint modifiers = GetJavaMouseModifiers(event);
+
     static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/event/NSEvent");
     static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDD)V");
     jobject jEvent = JNFNewObject(env, jctor_NSEvent,
-                                  type, 
-                                  modifiers,
+                                  [event type], 
+                                  [event modifierFlags],
                                   clickCount,
                                   [event buttonNumber],
                                   (jint)localPoint.x, (jint)localPoint.y,
@@ -373,8 +372,28 @@
 -(void) deliverJavaKeyEventHelper: (NSEvent *) event {
     [AWTToolkit eventCountPlusPlus];
     JNIEnv *env = [ThreadUtilities getJNIEnv];
-    // Pulled as-is as it's highly-depend on native code.
-    DeliverJavaKeyEvent(env, event, m_cPlatformView);
+
+    jstring charactersIgnoringModifiers = NULL;
+    if ([event type] != NSFlagsChanged) {
+        charactersIgnoringModifiers = JNFNSToJavaString(env, [event charactersIgnoringModifiers]);    
+    }
+
+    static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/event/NSEvent");
+    static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IISLjava/lang/String;)V");
+    jobject jevent = JNFNewObject(env, jctor_NSEvent,
+                                  [event type],
+                                  [event modifierFlags],
+                                  [event keyCode],
+                                  charactersIgnoringModifiers);
+
+    static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
+    static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView,
+                            "deliverKeyEvent", "(Lsun/lwawt/macosx/event/NSEvent;)V");
+    JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jevent);
+    
+    if (charactersIgnoringModifiers != NULL) {
+        (*env)->DeleteLocalRef(env, charactersIgnoringModifiers);
+    }
 }
 
 - (void) drawRect:(NSRect)dirtyRect {