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