19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.lwawt.macosx; 27 28 import java.awt.*; 29 30 public class CCustomCursor extends Cursor { 31 static Dimension sMaxCursorSize; 32 static Dimension getMaxCursorSize() { 33 if (sMaxCursorSize != null) return sMaxCursorSize; 34 final Rectangle bounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getBounds(); 35 return sMaxCursorSize = new Dimension(bounds.width / 2, bounds.height / 2); 36 } 37 38 Image fImage; 39 Point fHotspot; 40 41 public CCustomCursor(final Image cursor, final Point hotSpot, final String name) throws IndexOutOfBoundsException, HeadlessException { 42 super(name); 43 fImage = cursor; 44 fHotspot = hotSpot; 45 46 // This chunk of code is copied from sun.awt.CustomCursor 47 final Toolkit toolkit = Toolkit.getDefaultToolkit(); 48 49 // Make sure image is fully loaded. 50 final Component c = new Canvas(); // for its imageUpdate method 51 final MediaTracker tracker = new MediaTracker(c); 52 tracker.addImage(fImage, 0); 53 try { 54 tracker.waitForAll(); 55 } catch (final InterruptedException e) {} 56 57 int width = fImage.getWidth(c); 58 int height = fImage.getHeight(c); 59 60 // Fix for bug 4212593 The Toolkit.createCustomCursor does not 61 // check absence of the image of cursor 62 // If the image is invalid, the cursor will be hidden (made completely 63 // transparent). In this case, getBestCursorSize() will adjust negative w and h, 64 // but we need to set the hotspot inside the image here. 65 if (tracker.isErrorAny() || width < 0 || height < 0) { 66 fHotspot.x = fHotspot.y = 0; 67 } 68 69 // Scale image to nearest supported size 70 final Dimension nativeSize = toolkit.getBestCursorSize(width, height); 71 if (nativeSize.width != width || nativeSize.height != height) { 72 fImage = fImage.getScaledInstance(nativeSize.width, nativeSize.height, Image.SCALE_DEFAULT); 73 width = nativeSize.width; 74 height = nativeSize.height; 75 } 76 77 // NOTE: this was removed for 3169146, but in 1.5 the JCK tests for an exception and fails if one isn't thrown. 78 // See what JBuilder does. 79 // Verify that the hotspot is within cursor bounds. 80 if (fHotspot.x >= width || fHotspot.y >= height || fHotspot.x < 0 || fHotspot.y < 0) { 81 throw new IndexOutOfBoundsException("invalid hotSpot"); 82 } 83 84 // Must normalize the hotspot 85 if (fHotspot.x >= width) { 86 fHotspot.x = width - 1; // it is zero based. 93 fHotspot.y = 0; 94 } 95 } 96 97 public static Dimension getBestCursorSize(final int preferredWidth, final int preferredHeight) { 98 // With Panther, cursors have no limit on their size. So give the client their 99 // preferred size, but no larger than half the dimensions of the main screen 100 // This will allow large cursors, but not cursors so large that they cover the 101 // screen. Since solaris nor windows allow cursors this big, this shouldn't be 102 // a limitation. 103 // JCK triggers an overflow in the int -- if we get a bizarre value normalize it. 104 final Dimension maxCursorSize = getMaxCursorSize(); 105 final Dimension d = new Dimension(Math.max(1, Math.abs(preferredWidth)), Math.max(1, Math.abs(preferredHeight))); 106 return new Dimension(Math.min(d.width, maxCursorSize.width), Math.min(d.height, maxCursorSize.height)); 107 } 108 109 // Called from native when the cursor is set 110 // Returns long array of [NSImage ptr, x hotspot, y hotspot] 111 CImage fCImage; 112 long getImageData() { 113 if (fCImage == null) { 114 try { 115 fCImage = CImage.getCreator().createFromImage(fImage); 116 } catch (IllegalArgumentException iae) { 117 // Silently return null - we want to hide cursor by providing an empty 118 // ByteArray or just null 119 return 0L; 120 } 121 } 122 123 return fCImage.ptr; 124 } 125 126 Point getHotSpot() { 127 return fHotspot; 128 } 129 } | 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.lwawt.macosx; 27 28 import java.awt.*; 29 30 public class CCustomCursor extends Cursor { 31 static Dimension sMaxCursorSize; 32 static Dimension getMaxCursorSize() { 33 if (sMaxCursorSize != null) return sMaxCursorSize; 34 final Rectangle bounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getBounds(); 35 return sMaxCursorSize = new Dimension(bounds.width / 2, bounds.height / 2); 36 } 37 38 Image fImage; 39 private boolean isImageOk = false; 40 Point fHotspot; 41 42 public CCustomCursor(final Image cursor, final Point hotSpot, final String name) throws IndexOutOfBoundsException, HeadlessException { 43 super(name); 44 fImage = cursor; 45 fHotspot = hotSpot; 46 47 // This chunk of code is copied from sun.awt.CustomCursor 48 final Toolkit toolkit = Toolkit.getDefaultToolkit(); 49 50 // Make sure image is fully loaded. 51 final Component c = new Canvas(); // for its imageUpdate method 52 final MediaTracker tracker = new MediaTracker(c); 53 tracker.addImage(fImage, 0); 54 try { 55 tracker.waitForAll(); 56 } catch (final InterruptedException e) {} 57 58 int width = fImage.getWidth(c); 59 int height = fImage.getHeight(c); 60 61 // Fix for bug 4212593 The Toolkit.createCustomCursor does not 62 // check absence of the image of cursor 63 // If the image is invalid, the cursor will be hidden (made completely 64 // transparent). In this case, getBestCursorSize() will adjust negative w and h, 65 // but we need to set the hotspot inside the image here. 66 if (tracker.isErrorAny() || width < 0 || height < 0) { 67 fHotspot.x = fHotspot.y = 0; 68 isImageOk = false; 69 } else { 70 isImageOk = true; 71 } 72 73 // Scale image to nearest supported size 74 final Dimension nativeSize = toolkit.getBestCursorSize(width, height); 75 if (nativeSize.width != width || nativeSize.height != height) { 76 fImage = fImage.getScaledInstance(nativeSize.width, nativeSize.height, Image.SCALE_DEFAULT); 77 width = nativeSize.width; 78 height = nativeSize.height; 79 } 80 81 // 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. 84 if (fHotspot.x >= width || fHotspot.y >= height || fHotspot.x < 0 || fHotspot.y < 0) { 85 throw new IndexOutOfBoundsException("invalid hotSpot"); 86 } 87 88 // Must normalize the hotspot 89 if (fHotspot.x >= width) { 90 fHotspot.x = width - 1; // it is zero based. 97 fHotspot.y = 0; 98 } 99 } 100 101 public static Dimension getBestCursorSize(final int preferredWidth, final int preferredHeight) { 102 // With Panther, cursors have no limit on their size. So give the client their 103 // preferred size, but no larger than half the dimensions of the main screen 104 // This will allow large cursors, but not cursors so large that they cover the 105 // screen. Since solaris nor windows allow cursors this big, this shouldn't be 106 // a limitation. 107 // JCK triggers an overflow in the int -- if we get a bizarre value normalize it. 108 final Dimension maxCursorSize = getMaxCursorSize(); 109 final Dimension d = new Dimension(Math.max(1, Math.abs(preferredWidth)), Math.max(1, Math.abs(preferredHeight))); 110 return new Dimension(Math.min(d.width, maxCursorSize.width), Math.min(d.height, maxCursorSize.height)); 111 } 112 113 // Called from native when the cursor is set 114 // Returns long array of [NSImage ptr, x hotspot, y hotspot] 115 CImage fCImage; 116 long getImageData() { 117 if (fCImage != null) { 118 return fCImage.ptr; 119 } 120 121 if (isImageOk) { 122 try { 123 fCImage = CImage.getCreator().createFromImage(fImage); 124 125 if (fCImage == null) { 126 isImageOk = false; 127 return 0L; 128 } else { 129 return fCImage.ptr; 130 } 131 } catch (IllegalArgumentException iae) { 132 // Silently return null - we want to hide cursor by providing an empty 133 // ByteArray or just null 134 return 0L; 135 } 136 } 137 138 return 0L; 139 } 140 141 Point getHotSpot() { 142 return fHotspot; 143 } 144 } |