From 295225d57e61ce41afa4e2e9b1b7f6670b948cbb Mon Sep 17 00:00:00 2001
From: Petr Pchelko <pchelko@openjdk.org>
Date: Fri, 13 Sep 2013 11:58:39 +0400
Subject: [PATCH] 8024170: [SwingNode] Implement cursor change

Reviewed-by: anthony, ant
---
 .../sun/lwawt/LWLightweightFramePeer.java     | 12 ++++----
 .../classes/sun/swing/JLightweightFrame.java  | 30 ++++++++++++++++++-
 .../classes/sun/swing/LightweightContent.java |  8 +++++
 .../classes/sun/swing/SwingAccessor.java      | 29 ++++++++++++++++++
 .../sun/awt/X11/XLightweightFramePeer.java    |  7 +++++
 .../sun/awt/windows/WComponentPeer.java       |  2 +-
 .../awt/windows/WLightweightFramePeer.java    |  7 +++++
 7 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/jdk/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java b/jdk/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java
index 90e2e88c441..624be6bfc10 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java
@@ -34,6 +34,8 @@ import java.awt.dnd.DropTarget;
 
 import sun.awt.CausedFocusEvent;
 import sun.awt.LightweightFrame;
+import sun.swing.JLightweightFrame;
+import sun.swing.SwingAccessor;
 
 public class LWLightweightFramePeer extends LWWindowPeer {
 
@@ -90,11 +92,6 @@ public class LWLightweightFramePeer extends LWWindowPeer {
         setBounds(x, y, w, h, op, true, false);
     }
 
-    @Override
-    public void updateCursorImmediately() {
-        // TODO: tries to switch to the awt/fx toolkit thread and causes a deadlock on macosx
-    }
-
     @Override
     public void addDropTarget(DropTarget dt) {
     }
@@ -112,4 +109,9 @@ public class LWLightweightFramePeer extends LWWindowPeer {
     public void ungrab() {
         getLwTarget().ungrabFocus();
     }
+
+    @Override
+    public void updateCursorImmediately() {
+        SwingAccessor.getJLightweightFrameAccessor().updateCursor((JLightweightFrame)getLwTarget());
+    }
 }
diff --git a/jdk/src/share/classes/sun/swing/JLightweightFrame.java b/jdk/src/share/classes/sun/swing/JLightweightFrame.java
index 36bb1c351b7..e9a655309e2 100644
--- a/jdk/src/share/classes/sun/swing/JLightweightFrame.java
+++ b/jdk/src/share/classes/sun/swing/JLightweightFrame.java
@@ -33,8 +33,9 @@ import java.awt.Dimension;
 import java.awt.EventQueue;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
+import java.awt.MouseInfo;
+import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.event.ComponentListener;
 import java.awt.event.ContainerEvent;
 import java.awt.event.ContainerListener;
 import java.awt.image.BufferedImage;
@@ -48,6 +49,7 @@ import javax.swing.JPanel;
 import javax.swing.JRootPane;
 import javax.swing.LayoutFocusTraversalPolicy;
 import javax.swing.RootPaneContainer;
+import javax.swing.SwingUtilities;
 
 import sun.awt.LightweightFrame;
 import sun.security.action.GetPropertyAction;
@@ -88,6 +90,15 @@ public final class JLightweightFrame extends LightweightFrame implements RootPan
 
     private PropertyChangeListener layoutSizeListener;
 
+    static {
+        SwingAccessor.setJLightweightFrameAccessor(new SwingAccessor.JLightweightFrameAccessor() {
+            @Override
+            public void updateCursor(JLightweightFrame frame) {
+                frame.updateClientCursor();
+            }
+        });
+    }
+
     /**
      * Constructs a new, initially invisible {@code JLightweightFrame}
      * instance.
@@ -358,4 +369,21 @@ public final class JLightweightFrame extends LightweightFrame implements RootPan
     public Component getGlassPane() {
         return getRootPane().getGlassPane();
     }
+
+
+    /*
+     * Notifies client toolkit that it should change a cursor.
+     *
+     * Called from the peer via SwingAccessor, because the
+     * Component.updateCursorImmediately method is final
+     * and could not be overridden.
+     */
+    private void updateClientCursor() {
+        Point p = MouseInfo.getPointerInfo().getLocation();
+        SwingUtilities.convertPointFromScreen(p, this);
+        Component target = SwingUtilities.getDeepestComponentAt(this, p.x, p.y);
+        if (target != null) {
+            content.setCursor(target.getCursor());
+        }
+    }
 }
diff --git a/jdk/src/share/classes/sun/swing/LightweightContent.java b/jdk/src/share/classes/sun/swing/LightweightContent.java
index 256262dded1..dd3373aea1a 100644
--- a/jdk/src/share/classes/sun/swing/LightweightContent.java
+++ b/jdk/src/share/classes/sun/swing/LightweightContent.java
@@ -26,6 +26,7 @@
 package sun.swing;
 
 import javax.swing.JComponent;
+import java.awt.Cursor;
 
 /**
  * The interface by means of which the {@link JLightweightFrame} class
@@ -179,4 +180,11 @@ public interface LightweightContent {
      * application that the content minimum size has changed.
      */
     public void minimumSizeChanged(int width, int height);
+
+    /**
+     * {@code JLightweightFrame} calls this method to notify the client
+     * application that in needs to set a cursor
+     * @param cursor a cursor to set
+     */
+    default public void setCursor(Cursor cursor) { }
 }
diff --git a/jdk/src/share/classes/sun/swing/SwingAccessor.java b/jdk/src/share/classes/sun/swing/SwingAccessor.java
index 7e5100df6b7..72d15f41bd0 100644
--- a/jdk/src/share/classes/sun/swing/SwingAccessor.java
+++ b/jdk/src/share/classes/sun/swing/SwingAccessor.java
@@ -71,6 +71,16 @@ public final class SwingAccessor {
                                Object state, boolean forDrop);
     }
 
+    /**
+     * An accessor for the JLightweightFrame class.
+     */
+    public interface JLightweightFrameAccessor {
+        /**
+         * Notifies the JLightweight frame that it needs to update a cursor
+         */
+        void updateCursor(JLightweightFrame frame);
+    }
+
     /**
      * The javax.swing.text.JTextComponent class accessor object.
      */
@@ -93,4 +103,23 @@ public final class SwingAccessor {
 
         return jtextComponentAccessor;
     }
+
+    /**
+     * The JLightweightFrame class accessor object
+     */
+    private static JLightweightFrameAccessor jLightweightFrameAccessor;
+
+    /**
+     * Set an accessor object for the JLightweightFrame class.
+     */
+    public static void setJLightweightFrameAccessor(JLightweightFrameAccessor accessor) {
+        jLightweightFrameAccessor = accessor;
+    }
+
+    /**
+     * Retrieve the accessor object for the JLightweightFrame class
+     */
+    public static JLightweightFrameAccessor getJLightweightFrameAccessor() {
+        return jLightweightFrameAccessor;
+    }
 }
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java b/jdk/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java
index 6292482acdf..49d48c806ae 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XLightweightFramePeer.java
@@ -28,6 +28,8 @@ package sun.awt.X11;
 import java.awt.Graphics;
 
 import sun.awt.LightweightFrame;
+import sun.swing.JLightweightFrame;
+import sun.swing.SwingAccessor;
 
 public class XLightweightFramePeer extends XFramePeer {
 
@@ -62,4 +64,9 @@ public class XLightweightFramePeer extends XFramePeer {
             getLwTarget().ungrabFocus();
         }
     }
+
+    @Override
+    public void updateCursorImmediately() {
+        SwingAccessor.getJLightweightFrameAccessor().updateCursor((JLightweightFrame)getLwTarget());
+    }
 }
diff --git a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java
index db62ab477ed..da4135ec033 100644
--- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java
+++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java
@@ -656,7 +656,7 @@ public abstract class WComponentPeer extends WObjectPeer
         _setFont(f);
     }
     public synchronized native void _setFont(Font f);
-    public final void updateCursorImmediately() {
+    public void updateCursorImmediately() {
         WGlobalCursorManager.getCursorManager().updateCursorImmediately();
     }
 
diff --git a/jdk/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java b/jdk/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java
index c2c1604bef4..ae5afdc56e7 100644
--- a/jdk/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java
+++ b/jdk/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java
@@ -31,6 +31,8 @@ import java.awt.event.ComponentEvent;
 import java.awt.event.MouseEvent;
 
 import sun.awt.LightweightFrame;
+import sun.swing.JLightweightFrame;
+import sun.swing.SwingAccessor;
 
 public class WLightweightFramePeer extends WFramePeer {
 
@@ -83,4 +85,9 @@ public class WLightweightFramePeer extends WFramePeer {
     public void ungrab() {
         getLwTarget().ungrabFocus();
     }
+
+    @Override
+    public void updateCursorImmediately() {
+        SwingAccessor.getJLightweightFrameAccessor().updateCursor((JLightweightFrame)getLwTarget());
+    }
 }