1 /*
   2  * Copyright (c) 2007, 2016, 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 
  24 import java.awt.BorderLayout;
  25 import java.awt.Canvas;
  26 import java.awt.EventQueue;
  27 import java.awt.Frame;
  28 import java.awt.event.FocusAdapter;
  29 import java.awt.event.FocusEvent;
  30 import java.awt.event.InputEvent;
  31 import java.awt.event.KeyAdapter;
  32 import java.awt.event.KeyEvent;
  33 import java.awt.event.MouseEvent;
  34 
  35 import static jdk.testlibrary.Asserts.assertTrue;
  36 
  37 /*
  38  * @test 8155742
  39  * @summary Make sure that modifier key mask is set when robot press
  40  *          some key with one or more modifiers.
  41  * @library ../../../../lib/testlibrary/
  42  * @build ExtendedRobot
  43  * @run main ModifierRobotKeyTest
  44  */
  45 
  46 public class ModifierRobotKeyTest extends KeyAdapter {
  47 
  48     private boolean focusGained = false;
  49     private boolean startTest = false;
  50     private ExtendedRobot robot;
  51     private Frame frame;
  52     private Canvas canvas;
  53 
  54     private volatile boolean tempPress = false;
  55 
  56     private int[] textKeys, modifierKeys, inputMasks;
  57     private boolean[] modifierStatus, textStatus;
  58 
  59     private final static int waitDelay = 5000;
  60     private Object tempLock = new Object();
  61     private Object keyLock = new Object();
  62 
  63     public static void main(String[] args) throws Exception {
  64         ModifierRobotKeyTest test = new ModifierRobotKeyTest();
  65         test.doTest();
  66     }
  67 
  68     public ModifierRobotKeyTest() throws Exception {
  69         modifierKeys =  new int[4];
  70         modifierKeys[0] = KeyEvent.VK_SHIFT;
  71         modifierKeys[1] = KeyEvent.VK_CONTROL;
  72         modifierKeys[2] = KeyEvent.VK_ALT;
  73         modifierKeys[3] = KeyEvent.VK_ALT_GRAPH;
  74 
  75         inputMasks = new int[4];
  76         inputMasks[0] =  InputEvent.SHIFT_MASK;
  77         inputMasks[1] =  InputEvent.CTRL_MASK;
  78         inputMasks[2] =  InputEvent.ALT_MASK;
  79         inputMasks[3] =  InputEvent.ALT_GRAPH_MASK;
  80 
  81         modifierStatus = new boolean[modifierKeys.length];
  82 
  83         textKeys = new int[2];
  84         textKeys[0] = KeyEvent.VK_A;
  85 
  86         String os = System.getProperty("os.name").toLowerCase();
  87 
  88         if (os.contains("solaris") || os.contains("sunos"))
  89             textKeys[1] = KeyEvent.VK_S;
  90         else if (os.contains("os x"))
  91             textKeys[1] = KeyEvent.VK_K;
  92         else
  93             textKeys[1] = KeyEvent.VK_I;
  94 
  95         textStatus = new boolean[textKeys.length];
  96 
  97         EventQueue.invokeAndWait( () -> { initializeGUI(); });
  98     }
  99 
 100     public void keyPressed(KeyEvent event) {
 101 
 102         tempPress = true;
 103         synchronized (tempLock) { tempLock.notifyAll(); }
 104 
 105         if (! startTest) {
 106             return;
 107         }
 108         for (int x = 0; x < inputMasks.length; x++) {
 109             if ((event.getModifiers() & inputMasks[x]) != 0) {
 110                 System.out.println("Modifier set: " + event.getKeyModifiersText(inputMasks[x]));
 111                 modifierStatus[x] = true;
 112             }
 113         }
 114         for (int x = 0; x < textKeys.length; x++) {
 115             if (event.getKeyCode() == textKeys[x]) {
 116                 System.out.println("Text set: " + event.getKeyText(textKeys[x]));
 117                 textStatus[x] = true;
 118             }
 119         }
 120 
 121         synchronized (keyLock) { keyLock.notifyAll(); }
 122     }
 123 
 124     private void initializeGUI() {
 125         frame = new Frame("Test frame");
 126         canvas = new Canvas();
 127         canvas.addFocusListener(new FocusAdapter() {
 128             public void focusGained(FocusEvent event) { focusGained = true; }
 129         });
 130         canvas.addKeyListener(this);
 131         frame.setLayout(new BorderLayout());
 132         frame.add(canvas);
 133         frame.setSize(200, 200);
 134         frame.setVisible(true);
 135     }
 136 
 137     public void doTest() throws Exception {
 138         robot = new ExtendedRobot();
 139 
 140         robot.mouseMove((int) frame.getLocationOnScreen().getX() + frame.getSize().width / 2,
 141                         (int) frame.getLocationOnScreen().getY() + frame.getSize().height / 2);
 142         robot.click(MouseEvent.BUTTON1_MASK);
 143         robot.waitForIdle();
 144 
 145         assertTrue(focusGained, "FAIL: Canvas gained focus!");
 146 
 147         for (int i = 0; i < modifierKeys.length; i++) {
 148             for (int j = 0; j < textKeys.length; j++) {
 149                 tempPress = false;
 150                 robot.keyPress(modifierKeys[i]);
 151                 robot.waitForIdle();
 152                 if (! tempPress) {
 153                     synchronized (tempLock) { tempLock.wait(waitDelay); }
 154                 }
 155                 assertTrue(tempPress, "FAIL: keyPressed triggered for i=" + i);
 156 
 157                 resetStatus();
 158                 startTest = true;
 159                 robot.keyPress(textKeys[j]);
 160                 robot.waitForIdle();
 161                 if (! modifierStatus[i] || ! textStatus[j]) {
 162                     synchronized (keyLock) { keyLock.wait(waitDelay); }
 163                 }
 164 
 165 
 166                 assertTrue(modifierStatus[i] && textStatus[j],
 167                         "FAIL: KeyEvent not proper!"+
 168                         "Key checked: i=" + i + "; j=" + j+
 169                         "ModifierStatus = " + modifierStatus[i]+
 170                         "TextStatus = " + textStatus[j]);
 171                 startTest = false;
 172                 robot.keyRelease(textKeys[j]);
 173                 robot.waitForIdle();
 174                 robot.keyRelease(modifierKeys[i]);
 175                 robot.waitForIdle();
 176             }
 177         }
 178 
 179         for (int i = 0; i < modifierKeys.length; i++) {
 180             for (int j = i + 1; j < modifierKeys.length; j++) {
 181                 for (int k = 0; k < textKeys.length; k++) {
 182                     tempPress = false;
 183                     robot.keyPress(modifierKeys[i]);
 184                     robot.waitForIdle();
 185                     if (! tempPress) {
 186                         synchronized (tempLock) { tempLock.wait(waitDelay); }
 187                     }
 188 
 189                     assertTrue(tempPress, "FAIL: MultiKeyTest: keyPressed triggered for i=" + i);
 190 
 191                     tempPress = false;
 192                     robot.keyPress(modifierKeys[j]);
 193                     robot.waitForIdle();
 194                     if (! tempPress) {
 195                         synchronized (tempLock) { tempLock.wait(waitDelay); }
 196                     }
 197                     assertTrue(tempPress, "FAIL: MultiKeyTest keyPressed triggered for j=" + j);
 198 
 199                     resetStatus();
 200                     startTest = true;
 201                     robot.keyPress(textKeys[k]);
 202                     robot.waitForIdle();
 203                     if (! modifierStatus[i] || ! modifierStatus[j] || ! textStatus[k]) {
 204                         synchronized (keyLock) {
 205                             keyLock.wait(waitDelay);
 206                         }
 207                     }
 208                     assertTrue(modifierStatus[i] && modifierStatus[j] && textStatus[k],
 209                             "FAIL: KeyEvent not proper!"+
 210                             "Key checked: i=" + i + "; j=" + j + "; k=" + k+
 211                             "Modifier1Status = " + modifierStatus[i]+
 212                             "Modifier2Status = " + modifierStatus[j]+
 213                             "TextStatus = " + textStatus[k]);
 214 
 215                     startTest = false;
 216                     robot.keyRelease(textKeys[k]);
 217                     robot.waitForIdle();
 218                     robot.keyRelease(modifierKeys[j]);
 219                     robot.waitForIdle();
 220                     robot.keyRelease(modifierKeys[i]);
 221                     robot.waitForIdle();
 222                 }
 223             }
 224         }
 225 
 226         frame.dispose();
 227     }
 228 
 229     private void resetStatus() {
 230         for (int i = 0; i < modifierStatus.length; i++) {
 231             modifierStatus[i] = false;
 232         }
 233         for (int i = 0; i < textStatus.length; i++) {
 234             textStatus[i] = false;
 235         }
 236     }
 237 
 238 }