1 /*
   2  * Copyright (c) 2013, 2015, 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.Graphics2D;
  29 import java.awt.Image;
  30 import java.awt.Label;
  31 import java.awt.Point;
  32 import java.awt.TextArea;
  33 import java.awt.Toolkit;
  34 import java.awt.image.BaseMultiResolutionImage;
  35 import java.awt.image.BufferedImage;
  36 import javax.swing.JApplet;
  37 import jdk.testlibrary.OSInfo;
  38 
  39 /**
  40  * @test
  41  * @bug 8028212
  42  * @summary [macosx] Custom Cursor HiDPI support
  43  * @author Alexander Scherbatiy
  44  * @library ../../../../lib/testlibrary
  45  * @modules java.desktop/sun.awt.image
  46  * @build jdk.testlibrary.OSInfo
  47  * @run applet/manual=yesno MultiResolutionCursorTest.html
  48  */
  49 public class MultiResolutionCursorTest extends JApplet {
  50     //Declare things used in the test, like buttons and labels here
  51 
  52     static final int sizes[] = {8, 16, 32, 128};
  53     static final Color colors[] = {Color.WHITE, Color.RED, Color.GREEN, Color.BLUE};
  54 
  55     public void init() {
  56         //Create instructions for the user here, as well as set up
  57         // the environment -- set the layout manager, add buttons,
  58         // etc.
  59         this.setLayout(new BorderLayout());
  60 
  61         if (OSInfo.getOSType().equals(OSInfo.OSType.MACOSX)) {
  62             String[] instructions = {
  63                 "Verify that high resolution custom cursor is used"
  64                 + " on HiDPI displays.",
  65                 "1) Run the test on Retina display or enable the Quartz Debug"
  66                 + " and select the screen resolution with (HiDPI) label",
  67                 "2) Move the cursor to the Test Frame",
  68                 "3) Check that cursor has red, green or blue color",
  69                 "If so, press PASS, else press FAIL."
  70             };
  71             Sysout.createDialogWithInstructions(instructions);
  72 
  73         } else {
  74             String[] instructions = {
  75                 "This test is not applicable to the current platform. Press PASS."
  76             };
  77             Sysout.createDialogWithInstructions(instructions);
  78         }
  79     }//End  init()
  80 
  81     public void start() {
  82         //Get things going.  Request focus, set size, et cetera
  83         setSize(200, 200);
  84         setVisible(true);
  85         validate();
  86 
  87         final Image image = new BaseMultiResolutionImage(
  88                 createResolutionVariant(0),
  89                 createResolutionVariant(1),
  90                 createResolutionVariant(2),
  91                 createResolutionVariant(3)
  92         );
  93 
  94         int center = sizes[0] / 2;
  95         Cursor cursor = Toolkit.getDefaultToolkit().createCustomCursor(
  96                 image, new Point(center, center), "multi-resolution cursor");
  97 
  98         Frame frame = new Frame("Test Frame");
  99         frame.setSize(300, 300);
 100         frame.setLocation(300, 50);
 101         frame.add(new Label("Move cursor here"));
 102         frame.setCursor(cursor);
 103         frame.setVisible(true);
 104     }// start()
 105 
 106     static BufferedImage createResolutionVariant(int i) {
 107         BufferedImage resolutionVariant = new BufferedImage(sizes[i], sizes[i],
 108                 BufferedImage.TYPE_INT_RGB);
 109         Graphics2D g2 = resolutionVariant.createGraphics();
 110         g2.setColor(colors[i]);
 111         g2.fillRect(0, 0, sizes[i], sizes[i]);
 112         g2.dispose();
 113         return resolutionVariant;
 114     }
 115 }// class BlockedWindowTest
 116 
 117 /* Place other classes related to the test after this line */
 118 /**
 119  * **************************************************
 120  * Standard Test Machinery DO NOT modify anything below -- it's a standard chunk
 121  * of code whose purpose is to make user interaction uniform, and thereby make
 122  * it simpler to read and understand someone else's test.
 123  * **************************************************
 124  */
 125 /**
 126  * This is part of the standard test machinery. It creates a dialog (with the
 127  * instructions), and is the interface for sending text messages to the user. To
 128  * print the instructions, send an array of strings to Sysout.createDialog
 129  * WithInstructions method. Put one line of instructions per array entry. To
 130  * display a message for the tester to see, simply call Sysout.println with the
 131  * string to be displayed. This mimics System.out.println but works within the
 132  * test harness as well as standalone.
 133  */
 134 class Sysout {
 135 
 136     private static TestDialog dialog;
 137 
 138     public static void createDialogWithInstructions(String[] instructions) {
 139         dialog = new TestDialog(new Frame(), "Instructions");
 140         dialog.printInstructions(instructions);
 141         dialog.setVisible(true);
 142         println("Any messages for the tester will display here.");
 143     }
 144 
 145     public static void createDialog() {
 146         dialog = new TestDialog(new Frame(), "Instructions");
 147         String[] defInstr = {"Instructions will appear here. ", ""};
 148         dialog.printInstructions(defInstr);
 149         dialog.setVisible(true);
 150         println("Any messages for the tester will display here.");
 151     }
 152 
 153     public static void printInstructions(String[] instructions) {
 154         dialog.printInstructions(instructions);
 155     }
 156 
 157     public static void println(String messageIn) {
 158         dialog.displayMessage(messageIn);
 159     }
 160 }// Sysout  class
 161 
 162 /**
 163  * This is part of the standard test machinery. It provides a place for the test
 164  * instructions to be displayed, and a place for interactive messages to the
 165  * user to be displayed. To have the test instructions displayed, see Sysout. To
 166  * have a message to the user be displayed, see Sysout. Do not call anything in
 167  * this dialog directly.
 168  */
 169 class TestDialog extends Dialog {
 170 
 171     TextArea instructionsText;
 172     TextArea messageText;
 173     int maxStringLength = 80;
 174 
 175     //DO NOT call this directly, go through Sysout
 176     public TestDialog(Frame frame, String name) {
 177         super(frame, name);
 178         int scrollBoth = TextArea.SCROLLBARS_BOTH;
 179         instructionsText = new TextArea("", 15, maxStringLength, scrollBoth);
 180         add("North", instructionsText);
 181 
 182         messageText = new TextArea("", 5, maxStringLength, scrollBoth);
 183         add("Center", messageText);
 184 
 185         pack();
 186 
 187         setVisible(true);
 188     }// TestDialog()
 189 
 190     //DO NOT call this directly, go through Sysout
 191     public void printInstructions(String[] instructions) {
 192         //Clear out any current instructions
 193         instructionsText.setText("");
 194 
 195         //Go down array of instruction strings
 196 
 197         String printStr, remainingStr;
 198         for (int i = 0; i < instructions.length; i++) {
 199             //chop up each into pieces maxSringLength long
 200             remainingStr = instructions[ i];
 201             while (remainingStr.length() > 0) {
 202                 //if longer than max then chop off first max chars to print
 203                 if (remainingStr.length() >= maxStringLength) {
 204                     //Try to chop on a word boundary
 205                     int posOfSpace = remainingStr.lastIndexOf(' ', maxStringLength - 1);
 206 
 207                     if (posOfSpace <= 0) {
 208                         posOfSpace = maxStringLength - 1;
 209                     }
 210 
 211                     printStr = remainingStr.substring(0, posOfSpace + 1);
 212                     remainingStr = remainingStr.substring(posOfSpace + 1);
 213                 } //else just print
 214                 else {
 215                     printStr = remainingStr;
 216                     remainingStr = "";
 217                 }
 218 
 219                 instructionsText.append(printStr + "\n");
 220 
 221             }// while
 222 
 223         }// for
 224 
 225     }//printInstructions()
 226 
 227     //DO NOT call this directly, go through Sysout
 228     public void displayMessage(String messageIn) {
 229         messageText.append(messageIn + "\n");
 230         System.out.println(messageIn);
 231     }
 232 }// Te