Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/classes/sun/lwawt/macosx/CCustomCursor.java
38830 views
/*1* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.lwawt.macosx;2627import java.awt.*;28import java.awt.image.BufferedImage;2930public class CCustomCursor extends Cursor {31static Dimension sMaxCursorSize;32static Dimension getMaxCursorSize() {33if (sMaxCursorSize != null) return sMaxCursorSize;34final Rectangle bounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getBounds();35return sMaxCursorSize = new Dimension(bounds.width / 2, bounds.height / 2);36}3738Image fImage;39Point fHotspot;40int fWidth;41int fHeight;4243public CCustomCursor(final Image cursor, final Point hotSpot, final String name) throws IndexOutOfBoundsException, HeadlessException {44super(name);45fImage = cursor;46fHotspot = hotSpot;4748// This chunk of code is copied from sun.awt.CustomCursor49final Toolkit toolkit = Toolkit.getDefaultToolkit();5051// Make sure image is fully loaded.52final Component c = new Canvas(); // for its imageUpdate method53final MediaTracker tracker = new MediaTracker(c);54// MediaTracker loads resolution variants from MultiResolution Toolkit image55tracker.addImage(fImage, 0);56try {57tracker.waitForAll();58} catch (final InterruptedException e) {}5960int width = fImage.getWidth(c);61int height = fImage.getHeight(c);6263// Fix for bug 4212593 The Toolkit.createCustomCursor does not64// check absence of the image of cursor65// If the image is invalid, the cursor will be hidden (made completely66// transparent).67if (tracker.isErrorAny() || width < 0 || height < 0) {68fHotspot.x = fHotspot.y = 0;69width = height = 1;70fImage = createTransparentImage(width, height);71} else {72// Get the nearest supported cursor size73final Dimension nativeSize = toolkit.getBestCursorSize(width, height);74width = nativeSize.width;75height = nativeSize.height;76}7778fWidth = width;79fHeight = height;8081// NOTE: this was removed for 3169146, but in 1.5 the JCK tests for an exception and fails if one isn't thrown.82// See what JBuilder does.83// Verify that the hotspot is within cursor bounds.84if (fHotspot.x >= width || fHotspot.y >= height || fHotspot.x < 0 || fHotspot.y < 0) {85throw new IndexOutOfBoundsException("invalid hotSpot");86}8788// Must normalize the hotspot89if (fHotspot.x >= width) {90fHotspot.x = width - 1; // it is zero based.91} else if (fHotspot.x < 0) {92fHotspot.x = 0;93}94if (fHotspot.y >= height) {95fHotspot.y = height - 1; // it is zero based.96} else if (fHotspot.y < 0) {97fHotspot.y = 0;98}99}100101private static BufferedImage createTransparentImage(int w, int h) {102GraphicsEnvironment ge =103GraphicsEnvironment.getLocalGraphicsEnvironment();104GraphicsDevice gs = ge.getDefaultScreenDevice();105GraphicsConfiguration gc = gs.getDefaultConfiguration();106107BufferedImage img = gc.createCompatibleImage(w, h, Transparency.BITMASK);108Graphics2D g = (Graphics2D)img.getGraphics();109g.setBackground(new Color(0, 0, 0, 0));110g.clearRect(0, 0, w, h);111g.dispose();112113return img;114}115116public static Dimension getBestCursorSize(final int preferredWidth, final int preferredHeight) {117// With Panther, cursors have no limit on their size. So give the client their118// preferred size, but no larger than half the dimensions of the main screen119// This will allow large cursors, but not cursors so large that they cover the120// screen. Since solaris nor windows allow cursors this big, this shouldn't be121// a limitation.122// JCK triggers an overflow in the int -- if we get a bizarre value normalize it.123final Dimension maxCursorSize = getMaxCursorSize();124final Dimension d = new Dimension(Math.max(1, Math.abs(preferredWidth)), Math.max(1, Math.abs(preferredHeight)));125return new Dimension(Math.min(d.width, maxCursorSize.width), Math.min(d.height, maxCursorSize.height));126}127128// Called from native when the cursor is set129CImage fCImage;130long getImageData() {131if (fCImage != null) {132return fCImage.ptr;133}134135try {136fCImage = CImage.getCreator().createFromImage(fImage);137if (fCImage == null) {138// Something unexpected happened: CCustomCursor constructor139// takes care of invalid cursor images, yet createFromImage()140// failed to do its job. Return null to keep the cursor unchanged.141return 0L;142} else {143fCImage.resizeRepresentations(fWidth, fHeight);144return fCImage.ptr;145}146} catch (IllegalArgumentException iae) {147// see comment above148return 0L;149}150}151152Point getHotSpot() {153return fHotspot;154}155}156157158