1 /* 2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 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.awt.windows; 27 28 import sun.awt.CustomCursor; 29 import java.awt.*; 30 import java.awt.image.*; 31 import sun.awt.image.ImageRepresentation; 32 import sun.awt.image.IntegerComponentRaster; 33 import sun.awt.image.ToolkitImage; 34 35 /** 36 * A class to encapsulate a custom image-based cursor. 37 * 38 * @see Component#setCursor 39 * @author ThomasBall 40 */ 41 @SuppressWarnings("serial") // JDK-implementation class 42 final class WCustomCursor extends CustomCursor { 43 44 WCustomCursor(Image cursor, Point hotSpot, String name) 45 throws IndexOutOfBoundsException { 46 super(cursor, hotSpot, name); 47 } 48 49 @Override 50 protected void createNativeCursor(Image im, int[] pixels, int w, int h, 51 int xHotSpot, int yHotSpot) { 52 BufferedImage bimage = new BufferedImage(w, h, 53 BufferedImage.TYPE_INT_RGB); 54 Graphics g = bimage.getGraphics(); 55 try { 56 if (im instanceof ToolkitImage) { 57 ImageRepresentation ir = ((ToolkitImage)im).getImageRep(); 58 ir.reconstruct(ImageObserver.ALLBITS); 59 } 60 g.drawImage(im, 0, 0, w, h, null); 61 } finally { 62 g.dispose(); 63 } 64 Raster raster = bimage.getRaster(); 65 DataBuffer buffer = raster.getDataBuffer(); 66 // REMIND: native code should use ScanStride _AND_ width 67 int[] data = ((DataBufferInt)buffer).getData(); 68 69 byte[] andMask = new byte[w * h / 8]; 70 int npixels = pixels.length; 71 for (int i = 0; i < npixels; i++) { 72 int ibyte = i / 8; 73 int omask = 1 << (7 - (i % 8)); 74 if ((pixels[i] & 0xff000000) == 0) { 75 // Transparent bit 76 andMask[ibyte] |= omask; 77 } 78 } 79 80 { 81 int ficW = raster.getWidth(); 82 if( raster instanceof IntegerComponentRaster ) { 83 ficW = ((IntegerComponentRaster)raster).getScanlineStride(); 84 } 85 createCursorIndirect( 86 ((DataBufferInt)bimage.getRaster().getDataBuffer()).getData(), 87 andMask, ficW, raster.getWidth(), raster.getHeight(), 88 xHotSpot, yHotSpot); 89 } 90 } 91 92 private native void createCursorIndirect(int[] rData, byte[] andMask, 93 int nScanStride, int width, 94 int height, int xHotSpot, 95 int yHotSpot); 96 /** 97 * Return the current value of SM_CXCURSOR. 98 */ 99 static native int getCursorWidth(); 100 101 /** 102 * Return the current value of SM_CYCURSOR. 103 */ 104 static native int getCursorHeight(); 105 }