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