1 /* 2 * Copyright (c) 2013, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 import java.awt.BorderLayout; 24 import java.awt.Color; 25 import java.awt.Cursor; 26 import java.awt.Dialog; 27 import java.awt.Frame; 28 import java.awt.Graphics; 29 import java.awt.Graphics2D; 30 import java.awt.Image; 31 import java.awt.Label; 32 import java.awt.Point; 33 import java.awt.TextArea; 34 import java.awt.Toolkit; 35 import java.awt.image.BufferedImage; 36 import java.util.LinkedList; 37 import java.util.List; 38 import javax.swing.JApplet; 39 import jdk.testlibrary.OSInfo; 40 import sun.awt.image.MultiResolutionImage; 41 42 /** 43 * @test 44 * @bug 8028212 45 * @summary [macosx] Custom Cursor HiDPI support 46 * @author Alexander Scherbatiy 47 * @library ../../../../lib/testlibrary 48 * @build jdk.testlibrary.OSInfo 49 * @run applet/manual=yesno MultiResolutionCursorTest.html 50 */ 51 public class MultiResolutionCursorTest extends JApplet { 52 //Declare things used in the test, like buttons and labels here 53 54 static final int sizes[] = {16, 32, 128}; 55 static final Color colors[] = {Color.WHITE, Color.RED, Color.GREEN, Color.BLUE}; 56 57 public void init() { 58 //Create instructions for the user here, as well as set up 59 // the environment -- set the layout manager, add buttons, 60 // etc. 61 this.setLayout(new BorderLayout()); 62 63 if (OSInfo.getOSType().equals(OSInfo.OSType.MACOSX)) { 64 String[] instructions = { 65 "Verify that high resolution custom cursor is used" 66 + " on HiDPI displays.", 67 "1) Run the test on Retina display or enable the Quartz Debug" 68 + " and select the screen resolution with (HiDPI) label", 69 "2) Move the cursor to the Test Frame", 70 "3) Check that cursor has red, green or blue color", 71 "If so, press PASS, else press FAIL." 72 }; 73 Sysout.createDialogWithInstructions(instructions); 74 75 } else { 76 String[] instructions = { 77 "This test is not applicable to the current platform. Press PASS." 78 }; 79 Sysout.createDialogWithInstructions(instructions); 80 } 81 }//End init() 82 83 public void start() { 84 //Get things going. Request focus, set size, et cetera 85 setSize(200, 200); 86 setVisible(true); 87 validate(); 88 89 final Image image = new MultiResolutionCursor(); 90 91 int center = sizes[0] / 2; 92 Cursor cursor = Toolkit.getDefaultToolkit().createCustomCursor( 93 image, new Point(center, center), "multi-resolution cursor"); 94 95 Frame frame = new Frame("Test Frame"); 96 frame.setSize(300, 300); 97 frame.setLocation(300, 50); 98 frame.add(new Label("Move cursor here")); 99 frame.setCursor(cursor); 100 frame.setVisible(true); 101 }// start() 102 103 104 static class MultiResolutionCursor extends BufferedImage implements MultiResolutionImage { 105 106 List<Image> highResolutionImages; 107 108 public MultiResolutionCursor() { 109 super(sizes[0], sizes[0], BufferedImage.TYPE_INT_RGB); 110 111 draw(getGraphics(), 0); 112 highResolutionImages = new LinkedList<>(); 113 highResolutionImages.add(this); 114 115 for (int i = 1; i < sizes.length; i++) { 116 BufferedImage highResolutionImage = 117 new BufferedImage(sizes[i], sizes[i], BufferedImage.TYPE_INT_RGB); 118 draw(highResolutionImage.getGraphics(), i); 119 highResolutionImages.add(highResolutionImage); 120 } 121 } 122 123 @Override 124 public Image getResolutionVariant(int width, int height) { 125 126 for (int i = 0; i < sizes.length; i++) { 127 Image image = highResolutionImages.get(i); 128 int w = image.getWidth(null); 129 int h = image.getHeight(null); 130 131 if (width <= w && height <= h) { 132 return image; 133 } 134 } 135 136 return highResolutionImages.get(highResolutionImages.size() - 1); 137 } 138 139 void draw(Graphics graphics, int index) { 140 Graphics2D g2 = (Graphics2D) graphics; 141 Color color = colors[index]; 142 g2.setColor(color); 143 g2.fillRect(0, 0, sizes[index], sizes[index]); 144 } 145 146 @Override 147 public List<Image> getResolutionVariants() { 148 return highResolutionImages; 149 } 150 } 151 }// class BlockedWindowTest 152 153 /* Place other classes related to the test after this line */ 154 /** 155 * ************************************************** 156 * Standard Test Machinery DO NOT modify anything below -- it's a standard chunk 157 * of code whose purpose is to make user interaction uniform, and thereby make 158 * it simpler to read and understand someone else's test. 159 * ************************************************** 160 */ 161 /** 162 * This is part of the standard test machinery. It creates a dialog (with the 163 * instructions), and is the interface for sending text messages to the user. To 164 * print the instructions, send an array of strings to Sysout.createDialog 165 * WithInstructions method. Put one line of instructions per array entry. To 166 * display a message for the tester to see, simply call Sysout.println with the 167 * string to be displayed. This mimics System.out.println but works within the 168 * test harness as well as standalone. 169 */ 170 class Sysout { 171 172 private static TestDialog dialog; 173 174 public static void createDialogWithInstructions(String[] instructions) { 175 dialog = new TestDialog(new Frame(), "Instructions"); 176 dialog.printInstructions(instructions); 177 dialog.setVisible(true); 178 println("Any messages for the tester will display here."); 179 } 180 181 public static void createDialog() { 182 dialog = new TestDialog(new Frame(), "Instructions"); 183 String[] defInstr = {"Instructions will appear here. ", ""}; 184 dialog.printInstructions(defInstr); 185 dialog.setVisible(true); 186 println("Any messages for the tester will display here."); 187 } 188 189 public static void printInstructions(String[] instructions) { 190 dialog.printInstructions(instructions); 191 } 192 193 public static void println(String messageIn) { 194 dialog.displayMessage(messageIn); 195 } 196 }// Sysout class 197 198 /** 199 * This is part of the standard test machinery. It provides a place for the test 200 * instructions to be displayed, and a place for interactive messages to the 201 * user to be displayed. To have the test instructions displayed, see Sysout. To 202 * have a message to the user be displayed, see Sysout. Do not call anything in 203 * this dialog directly. 204 */ 205 class TestDialog extends Dialog { 206 207 TextArea instructionsText; 208 TextArea messageText; 209 int maxStringLength = 80; 210 211 //DO NOT call this directly, go through Sysout 212 public TestDialog(Frame frame, String name) { 213 super(frame, name); 214 int scrollBoth = TextArea.SCROLLBARS_BOTH; 215 instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); 216 add("North", instructionsText); 217 218 messageText = new TextArea("", 5, maxStringLength, scrollBoth); 219 add("Center", messageText); 220 221 pack(); 222 223 setVisible(true); 224 }// TestDialog() 225 226 //DO NOT call this directly, go through Sysout 227 public void printInstructions(String[] instructions) { 228 //Clear out any current instructions 229 instructionsText.setText(""); 230 231 //Go down array of instruction strings 232 233 String printStr, remainingStr; 234 for (int i = 0; i < instructions.length; i++) { 235 //chop up each into pieces maxSringLength long 236 remainingStr = instructions[ i]; 237 while (remainingStr.length() > 0) { 238 //if longer than max then chop off first max chars to print 239 if (remainingStr.length() >= maxStringLength) { 240 //Try to chop on a word boundary 241 int posOfSpace = remainingStr.lastIndexOf(' ', maxStringLength - 1); 242 243 if (posOfSpace <= 0) { 244 posOfSpace = maxStringLength - 1; 245 } 246 247 printStr = remainingStr.substring(0, posOfSpace + 1); 248 remainingStr = remainingStr.substring(posOfSpace + 1); 249 } //else just print 250 else { 251 printStr = remainingStr; 252 remainingStr = ""; 253 } 254 255 instructionsText.append(printStr + "\n"); 256 257 }// while 258 259 }// for 260 261 }//printInstructions() 262 263 //DO NOT call this directly, go through Sysout 264 public void displayMessage(String messageIn) { 265 messageText.append(messageIn + "\n"); 266 System.out.println(messageIn); 267 } 268 }// Te