1 /* 2 * Copyright (c) 2008, 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 /* 25 @test %I% %E% 26 @key headful 27 @bug 6315717 28 @summary verifies that modifiers are correct for extra buttons 29 @author Andrei Dmitriev : area=awt.mouse 30 @run main MouseModifiersUnitTest_Extra 31 */ 32 33 import sun.awt.OSInfo; 34 35 import java.awt.*; 36 import java.awt.event.*; 37 import java.util.Arrays; 38 import java.util.HashMap; 39 import java.util.StringTokenizer; 40 import java.util.Vector; 41 42 // will process extra buttons only 43 // asking parameters from CMD: manual/automatic, modifier to test 44 45 public class MouseModifiersUnitTest_Extra extends Frame { 46 static final int NONE = 0; 47 static final int SHIFT = 1; 48 static final int CTRL = 2; 49 static final int ALT = 3; 50 static CheckingModifierAdapterExtra adapterTest1; 51 static CheckingModifierAdapterExtra adapterTest2; 52 static CheckingModifierAdapterExtra adapterTest3; 53 static CheckingModifierAdapterExtra adapterTest4; 54 55 static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception 56 static boolean autorun = false; //use robot or manual run 57 static int testModifier = NONE; 58 59 static int [] mouseButtonDownMasks; 60 61 //an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them 62 static int [] modifiersExStandard; 63 static int [] modifiersExStandardSHIFT; 64 static int [] modifiersExStandardCTRL; 65 static int [] modifiersExStandardALT; 66 67 private final static String SHIFT_MODIFIER = OSInfo.getOSType().equals(OSInfo.OSType.MACOSX) ? 68 "\u21e7" : "Shift"; 69 70 private final static String ALT_MODIFIER = OSInfo.getOSType().equals(OSInfo.OSType.MACOSX) ? 71 "\u2325" : "Alt"; 72 73 74 private final static String CTRL_MODIFIER = OSInfo.getOSType().equals(OSInfo.OSType.MACOSX) ? 75 "\u2303" : "Ctrl"; 76 77 78 // BUTTON1, 2, 3 press-release. 79 final static int modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK; 80 81 public static void checkPressedModifiersTest(int testModifier, MouseEvent event){ 82 int [] curStandardExModifiers = getStandardExArray(testModifier); 83 int button = event.getButton(); 84 int modifiers = event.getModifiers(); 85 int modifiersEx = event.getModifiersEx(); 86 int index = (button - 4)*3; 87 dumpValues(button, modifiers, modifiersStandard, modifiersEx, curStandardExModifiers[index]); 88 if (modifiers != modifiersStandard){ 89 MessageLogger.reportError("Test failed : Pressed. modifiers != modifiersStandard"); 90 } 91 92 if (modifiersEx != curStandardExModifiers[index]){ 93 // System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers"); 94 MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers. Got: " 95 + modifiersEx + " , Expected: " + curStandardExModifiers[index]); 96 } 97 98 //check event.paramString() output 99 HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString()); 100 System.out.println(event.paramString()); 101 checkButton(paramStringElements, button); 102 checkModifiers(testModifier, paramStringElements, button); 103 checkExtModifiersOnPress(testModifier, paramStringElements, button); 104 } 105 106 public static void checkExtModifiersOnReleaseClick(int testModifier, HashMap<String, String> h, int button){ 107 String ethalon = ""; 108 switch (testModifier){ 109 case SHIFT:{ 110 ethalon = SHIFT_MODIFIER; 111 break; 112 } 113 case ALT:{ 114 ethalon = ALT_MODIFIER; 115 break; 116 } 117 case CTRL:{ 118 ethalon = CTRL_MODIFIER; 119 break; 120 } 121 } 122 123 if (h.get("extModifiers") == null){ 124 h.put("extModifiers", ""); 125 } 126 127 if (!ethalon.equals(h.get("extModifiers"))) { 128 MessageLogger.reportError("Test failed : Released/Clicked. extModifiers = " 129 + h.get("extModifiers") + " instead of : " + ethalon); 130 } 131 } 132 133 public static void checkExtModifiersOnPress(int testModifier, HashMap<String, String> h, int button){ 134 String ethalon = ""; 135 switch (testModifier){ 136 case SHIFT:{ 137 ethalon = SHIFT_MODIFIER + "+"; 138 break; 139 } 140 case ALT:{ 141 ethalon = ALT_MODIFIER + "+"; 142 break; 143 } 144 case CTRL:{ 145 ethalon = CTRL_MODIFIER + "+"; 146 break; 147 } 148 } 149 ethalon = ethalon + "Button" +button; 150 151 if (!h.get("extModifiers").equals(ethalon)) { 152 MessageLogger.reportError("Test failed : Pressed. extModifiers = " +h.get("extModifiers")+" instead of : " 153 + ethalon); 154 } 155 } 156 157 public static void checkModifiers(int testModifier, HashMap<String, String> h, int button){ 158 // none of modifiers for extra button should be null 159 if (h.get("modifiers") != null) { 160 MessageLogger.reportError("Test failed : modifiers != null"); 161 } 162 } 163 164 public static void checkButton(HashMap<String, String> h, int button){ 165 if (h.get("button") == null) { 166 MessageLogger.reportError("Test failed : checkButton(). button is absent in paramString()"); 167 } 168 if (Integer.parseInt(h.get("button")) != button) { 169 MessageLogger.reportError("Test failed : checkButton. button in paramString() doesn't equal to button being pressed."); 170 } 171 } 172 public static HashMap<String, String> tokenizeParamString(String param){ 173 HashMap <String, String> params = new HashMap<>(); 174 StringTokenizer st = new StringTokenizer(param, ",="); 175 while (st.hasMoreTokens()){ 176 String tmp = st.nextToken(); 177 // System.out.println("PARSER : "+tmp); 178 if (tmp.equals("button") || 179 tmp.equals("modifiers") || 180 tmp.equals("extModifiers")) { 181 params.put(tmp, st.nextToken()); 182 } 183 } 184 return params; 185 } 186 187 public static Vector<String> tokenizeModifiers(String modifierList){ 188 Vector<String> modifiers = new Vector<>(); 189 StringTokenizer st = new StringTokenizer(modifierList, "+"); 190 while (st.hasMoreTokens()){ 191 String tmp = st.nextToken(); 192 modifiers.addElement(tmp); 193 System.out.println("MODIFIER PARSER : "+tmp); 194 } 195 return modifiers; 196 } 197 198 public static void checkReleasedModifiersTest(int testModifier, MouseEvent event){ 199 int [] curStandardExModifiers = getStandardExArray(testModifier); 200 int button = event.getButton(); 201 int modifiers = event.getModifiers(); 202 int modifiersEx = event.getModifiersEx(); 203 int index = (button - 4)*3 + 1; 204 dumpValues(button, modifiers, modifiersStandard, modifiersEx, curStandardExModifiers[index]); 205 if (modifiers != modifiersStandard){ 206 MessageLogger.reportError("Test failed : Released. modifiers != modifiersStandard"); 207 } 208 209 if (modifiersEx != curStandardExModifiers[index]){ 210 MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers. Got: " 211 + modifiersEx + " , Expected: " + curStandardExModifiers[index]); 212 } 213 214 //check event.paramString() output 215 HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString()); 216 checkButton(paramStringElements, button); 217 checkModifiers(testModifier, paramStringElements, button); 218 System.out.println("paramStringElements = "+paramStringElements); 219 checkExtModifiersOnReleaseClick(testModifier, paramStringElements, button); 220 } 221 222 public static void checkClickedModifiersTest(int testModifier, MouseEvent event){ 223 int [] curStandardExModifiers = getStandardExArray(testModifier); 224 int button = event.getButton(); 225 int modifiers = event.getModifiers(); 226 int modifiersEx = event.getModifiersEx(); 227 int index = (button - 4)*3 + 2; 228 dumpValues(button, modifiers, modifiersStandard, modifiersEx, curStandardExModifiers[index]); 229 if (modifiers != modifiersStandard){ 230 MessageLogger.reportError("Test failed : Clicked. modifiers != modifiersStandard"); 231 } 232 233 if (modifiersEx != curStandardExModifiers[index]){ 234 MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers. Got: " 235 + modifiersEx + " , Expected: " + curStandardExModifiers[index]); 236 } 237 238 //check event.paramString() output 239 HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString()); 240 checkButton(paramStringElements, button); 241 checkModifiers(testModifier, paramStringElements, button); 242 checkExtModifiersOnReleaseClick(testModifier, paramStringElements, button); 243 } 244 245 private static int[] getStandardExArray(int testModifier) { 246 int [] curStandardExModifiers; 247 switch (testModifier){ 248 case SHIFT: 249 curStandardExModifiers = modifiersExStandardSHIFT; 250 break; 251 case CTRL: 252 curStandardExModifiers = modifiersExStandardCTRL; 253 break; 254 case ALT: 255 curStandardExModifiers = modifiersExStandardALT; 256 break; 257 default: //NONE by default 258 curStandardExModifiers = modifiersExStandard; 259 } 260 return curStandardExModifiers; 261 } 262 263 static Robot robot; 264 public void init() { 265 this.setLayout(new BorderLayout()); 266 try { 267 robot = new Robot(); 268 robot.setAutoDelay(100); 269 robot.setAutoWaitForIdle(true); 270 } catch (Exception e) { 271 MessageLogger.reportError("Test failed. "+e); 272 } 273 }//End init() 274 275 public void start() { 276 //Get things going. Request focus, set size, et cetera 277 setSize(200,200); 278 setVisible(true); 279 validate(); 280 if (autorun) { 281 testNONE(); 282 testSHIFT(); 283 testCTRL(); 284 testALT(); 285 } else { 286 switch (testModifier){ 287 case SHIFT: 288 this.addMouseListener(adapterTest2); 289 break; 290 case CTRL: 291 this.addMouseListener(adapterTest3); 292 break; 293 case ALT: 294 this.addMouseListener(adapterTest4); 295 break; 296 default: //NONE by default 297 this.addMouseListener(adapterTest1); 298 } 299 } 300 }// start() 301 302 //000000000000000000000000000000000000000000000000000000000000000 303 public void testNONE(){ 304 this.addMouseListener(adapterTest1); 305 robot.delay(1000); 306 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); 307 for (int i = 3; i< mouseButtonDownMasks.length; i++){ 308 System.out.println("testNONE() => " + mouseButtonDownMasks[i]); 309 robot.mousePress(mouseButtonDownMasks[i]); 310 robot.mouseRelease(mouseButtonDownMasks[i]); 311 } 312 robot.delay(1000); 313 this.removeMouseListener(adapterTest1); 314 } 315 316 public void testSHIFT(){ 317 this.addMouseListener(adapterTest2); 318 robot.delay(1000); 319 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); 320 for (int i = 3; i< mouseButtonDownMasks.length; i++){ 321 robot.keyPress(KeyEvent.VK_SHIFT); 322 System.out.println("testSHIFT() => " + mouseButtonDownMasks[i]); 323 robot.mousePress(mouseButtonDownMasks[i]); 324 robot.mouseRelease(mouseButtonDownMasks[i]); 325 robot.keyRelease(KeyEvent.VK_SHIFT); 326 } 327 robot.delay(1000); 328 this.removeMouseListener(adapterTest2); 329 } 330 331 public void testCTRL(){ 332 this.addMouseListener(adapterTest3); 333 robot.delay(1000); 334 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); 335 for (int i = 3; i< mouseButtonDownMasks.length; i++){ 336 robot.keyPress(KeyEvent.VK_CONTROL); 337 System.out.println("testCTRL() => " + mouseButtonDownMasks[i]); 338 robot.mousePress(mouseButtonDownMasks[i]); 339 robot.mouseRelease(mouseButtonDownMasks[i]); 340 robot.keyRelease(KeyEvent.VK_CONTROL); 341 } 342 robot.delay(1000); 343 this.removeMouseListener(adapterTest3); 344 } 345 346 public void testALT(){ 347 this.addMouseListener(adapterTest4); 348 robot.delay(1000); 349 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); 350 for (int i = 3; i< mouseButtonDownMasks.length; i++){ 351 robot.keyPress(KeyEvent.VK_ALT); 352 System.out.println("testALT() => " + mouseButtonDownMasks[i]); 353 robot.mousePress(mouseButtonDownMasks[i]); 354 robot.mouseRelease(mouseButtonDownMasks[i]); 355 robot.keyRelease(KeyEvent.VK_ALT); 356 } 357 robot.delay(1000); 358 this.removeMouseListener(adapterTest4); 359 } 360 361 //************************************************************************************************** 362 public static void dumpValues(int button, int modifiers, int modifiersStandard, int modifiersEx, int modifiersExStandard){ 363 System.out.println("Button = "+button + "Modifiers = "+ modifiers + "standard = "+ modifiersStandard); 364 System.out.println("Button = "+button + "ModifiersEx = "+ modifiersEx + "standardEx = "+ modifiersExStandard); 365 } 366 367 public static void initParams(String []s){ 368 if (s.length != 3){ 369 autorun = true; 370 debug = false; 371 testModifier = NONE; 372 } else { 373 autorun = Boolean.valueOf(s[0]); 374 debug = Boolean.valueOf(s[1]); 375 376 if (s[2].equals("NONE")){ 377 testModifier = NONE; 378 } 379 if (s[2].equals("SHIFT")){ 380 testModifier = SHIFT; 381 } 382 if (s[2].equals("CTRL")){ 383 testModifier = CTRL; 384 } 385 if (s[2].equals("ALT")){ 386 testModifier = ALT; 387 } 388 } 389 MessageLogger.setDebug(debug); 390 System.out.println("Autorun : " +autorun); 391 System.out.println("Debug mode : " +debug); 392 System.out.println("Modifier to verify : " + testModifier); 393 } 394 395 public static void initAdapters(){ 396 adapterTest1 = new CheckingModifierAdapterExtra(NONE); 397 adapterTest2 = new CheckingModifierAdapterExtra(SHIFT); 398 adapterTest3 = new CheckingModifierAdapterExtra(CTRL); 399 adapterTest4 = new CheckingModifierAdapterExtra(ALT); 400 } 401 402 public static void initVars(){ 403 //Init the array of the mouse button masks. It will be used for generating mouse events. 404 mouseButtonDownMasks = new int [MouseInfo.getNumberOfButtons()]; 405 for (int i = 0; i < mouseButtonDownMasks.length; i++){ 406 mouseButtonDownMasks[i] = InputEvent.getMaskForButton(i+1); 407 System.out.println("MouseArray [i] == "+mouseButtonDownMasks[i]); 408 } 409 410 // So we need to get the number of extra buttons on the mouse: "MouseInfo.getNumberOfButtons() - 3" 411 // and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK. 412 int [] tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3]; 413 414 //Fill array of expected results for the case when mouse buttons are only used (no-modifier keys) 415 Arrays.fill(tmp, 0); 416 for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ 417 tmp[i] = mouseButtonDownMasks[j]; 418 } 419 modifiersExStandard = Arrays.copyOf(tmp, tmp.length); 420 421 //Fill array of expected results for the case when mouse buttons are only used with SHIFT modifier key 422 Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK); 423 for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ 424 System.out.println("modifiersExStandardSHIFT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); 425 tmp[i] = tmp[i] | mouseButtonDownMasks[j]; 426 } 427 modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length); 428 429 //Fill array of expected results for the case when mouse buttons are only used with CTRL modifier key 430 Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK); 431 for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ 432 System.out.println("modifiersExStandardCTRL FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); 433 tmp[i] = tmp[i] | mouseButtonDownMasks[j]; 434 } 435 modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length); 436 437 //Fill array of expected results for the case when mouse buttons are only used with ALT modifier key 438 Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK); 439 for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ 440 System.out.println("modifiersExStandardALT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); 441 tmp[i] = tmp[i] | mouseButtonDownMasks[j]; 442 } 443 modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length); 444 } 445 446 public static void main(String []s){ 447 if (MouseInfo.getNumberOfButtons() < 4){ 448 System.out.println("There are less then 4 buttons on the mouse. The test may not be accomplished. Skipping."); 449 return; 450 } 451 initVars(); 452 MouseModifiersUnitTest_Extra frame = new MouseModifiersUnitTest_Extra(); 453 frame.initParams(s); 454 frame.init(); 455 initAdapters(); 456 frame.start(); 457 } 458 459 }// class 460 461 /* A class that invoke appropriate verification 462 * routine with current modifier. 463 */ 464 class CheckingModifierAdapterExtra extends MouseAdapter{ 465 int modifier; 466 public CheckingModifierAdapterExtra(int modifier){ 467 this.modifier = modifier; 468 } 469 470 public void mousePressed(MouseEvent e) { 471 System.out.println("PRESSED "+e); 472 if (e.getButton() <= MouseEvent.BUTTON3) { 473 System.out.println("Standard button affected. Skip."); 474 } else { 475 MouseModifiersUnitTest_Extra.checkPressedModifiersTest(modifier, e); 476 } 477 } 478 public void mouseReleased(MouseEvent e) { 479 System.out.println("RELEASED "+e); 480 if (e.getButton() <= MouseEvent.BUTTON3) { 481 System.out.println("Standard button affected. Skip."); 482 } else { 483 MouseModifiersUnitTest_Extra.checkReleasedModifiersTest(modifier, e); 484 } 485 } 486 public void mouseClicked(MouseEvent e) { 487 System.out.println("CLICKED "+e); 488 if (e.getButton() <= MouseEvent.BUTTON3) { 489 System.out.println("Standard button affected. Skip."); 490 } else { 491 MouseModifiersUnitTest_Extra.checkClickedModifiersTest(modifier, e); 492 } 493 } 494 } 495 //Utility class that could report a message depending on current purpose of the test run 496 class MessageLogger{ 497 private static boolean debug; 498 499 public static void setDebug(boolean d){ 500 debug = d; 501 log("Switch to "+ ((debug)?"debug":"trial") +" mode"); 502 } 503 504 public static void log(String message){ 505 System.out.println(message); 506 } 507 508 public static void reportError(String message){ 509 if (debug){ 510 System.out.println(message); 511 } else { 512 throw new RuntimeException(message); 513 } 514 } 515 }