4632N/A/*
4632N/A * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
4632N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4632N/A *
4632N/A * This code is free software; you can redistribute it and/or modify it
4632N/A * under the terms of the GNU General Public License version 2 only, as
4632N/A * published by the Free Software Foundation. Oracle designates this
4632N/A * particular file as subject to the "Classpath" exception as provided
4632N/A * by Oracle in the LICENSE file that accompanied this code.
4632N/A *
4632N/A * This code is distributed in the hope that it will be useful, but WITHOUT
4632N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4632N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4632N/A * version 2 for more details (a copy is included in the LICENSE file that
4632N/A * accompanied this code).
4632N/A *
4632N/A * You should have received a copy of the GNU General Public License version
4632N/A * 2 along with this work; if not, write to the Free Software Foundation,
4632N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4632N/A *
4632N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4632N/A * or visit www.oracle.com if you need additional information or have any
4632N/A * questions.
4632N/A */
4632N/A
4632N/Apackage sun.lwawt;
4632N/A
4632N/Aimport java.awt.Component;
4632N/Aimport java.awt.Container;
4632N/Aimport java.awt.Cursor;
4632N/Aimport java.awt.Point;
4632N/A
4632N/Aimport java.util.concurrent.atomic.AtomicBoolean;
4632N/A
4632N/Aimport sun.awt.SunToolkit;
4632N/A
4632N/Apublic abstract class LWCursorManager {
4632N/A
5137N/A /**
5137N/A * A flag to indicate if the update is scheduled, so we don't process it
5137N/A * twice.
5137N/A */
5137N/A private final AtomicBoolean updatePending = new AtomicBoolean(false);
4632N/A
4632N/A protected LWCursorManager() {
4632N/A }
4632N/A
5137N/A /**
4632N/A * Sets the cursor to correspond the component currently under mouse.
4632N/A *
4632N/A * This method should not be executed on the toolkit thread as it
4632N/A * calls to user code (e.g. Container.findComponentAt).
4632N/A */
5137N/A public final void updateCursor() {
4632N/A updatePending.set(false);
4632N/A updateCursorImpl();
4632N/A }
4632N/A
5137N/A /**
4632N/A * Schedules updating the cursor on the corresponding event dispatch
4632N/A * thread for the given window.
4632N/A *
4632N/A * This method is called on the toolkit thread as a result of a
4632N/A * native update cursor request (e.g. WM_SETCURSOR on Windows).
4632N/A */
5137N/A public final void updateCursorLater(final LWWindowPeer window) {
4632N/A if (updatePending.compareAndSet(false, true)) {
4632N/A Runnable r = new Runnable() {
4632N/A @Override
4632N/A public void run() {
4632N/A updateCursor();
4632N/A }
4632N/A };
4632N/A SunToolkit.executeOnEventHandlerThread(window.getTarget(), r);
4632N/A }
4632N/A }
4632N/A
4632N/A private void updateCursorImpl() {
5137N/A final Point cursorPos = getCursorPosition();
5137N/A final Component c = findComponent(cursorPos);
5137N/A final Cursor cursor;
5137N/A final Object peer = LWToolkit.targetToPeer(c);
5137N/A if (peer instanceof LWComponentPeer) {
5137N/A final LWComponentPeer<?, ?> lwpeer = (LWComponentPeer<?, ?>) peer;
5137N/A final Point p = lwpeer.getLocationOnScreen();
5137N/A cursor = lwpeer.getCursor(new Point(cursorPos.x - p.x,
5137N/A cursorPos.y - p.y));
5137N/A } else {
5137N/A cursor = (c != null) ? c.getCursor() : null;
4632N/A }
5137N/A setCursor(cursor);
5137N/A }
5137N/A
5137N/A /**
5137N/A * Returns the first visible, enabled and showing component under cursor.
5139N/A * Returns null for modal blocked windows.
5137N/A *
5137N/A * @param cursorPos Current cursor position.
5139N/A * @return Component or null.
5137N/A */
5137N/A private static final Component findComponent(final Point cursorPos) {
5137N/A final LWComponentPeer<?, ?> peer = LWWindowPeer.getPeerUnderCursor();
5137N/A Component c = null;
5139N/A if (peer != null && peer.getWindowPeerOrSelf().getBlocker() == null) {
5137N/A c = peer.getTarget();
4632N/A if (c instanceof Container) {
5137N/A final Point p = peer.getLocationOnScreen();
5137N/A c = ((Container) c).findComponentAt(cursorPos.x - p.x,
5137N/A cursorPos.y - p.y);
4632N/A }
4632N/A while (c != null) {
4632N/A if (c.isVisible() && c.isEnabled() && (c.getPeer() != null)) {
4632N/A break;
4632N/A }
4632N/A c = c.getParent();
4632N/A }
4632N/A }
5137N/A return c;
4632N/A }
4632N/A
5137N/A /**
4632N/A * Returns the current cursor position.
4632N/A */
4632N/A // TODO: make it public to reuse for MouseInfo
4632N/A protected abstract Point getCursorPosition();
4632N/A
5137N/A /**
5137N/A * Sets a cursor. The cursor can be null if the mouse is not over a Java
5137N/A * window.
5137N/A * @param cursor the new {@code Cursor}.
4632N/A */
5137N/A protected abstract void setCursor(Cursor cursor);
4632N/A}