ModifierPermutation.java revision 8729:0242fce0f717
1/* 2 * Copyright (c) 2008, 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 presses buttons in all permutations and verifies modifiers 28 @author Andrei Dmitriev : area=awt.mouse 29 @run main ModifierPermutation 30 */ 31//package modifierpermutation; 32 33/* 34The test will try to press-release every button present on the mouse in different order. 35Here are some abbreviations: 36 BUTTON1 press = P1 37 BUTTON2 press = P2 etc. 38 BUTTON1 release = R1 39 BUTTON2 release = R2 etc. 40Only sequences alike below are possible : <P1, P2, R2, R1>. 41Sequences like <P1, P2, R1, R2> will not be covered by this test due to its probable complexity. 42 */ 43 44import java.awt.*; 45import sun.awt.SunToolkit; 46import java.awt.event.*; 47import java.util.Arrays; 48 49public class ModifierPermutation { 50 static boolean failed = false; 51 final static int BUTTONSNUMBER = MouseInfo.getNumberOfButtons(); 52 53/* 54 * Because of some problems with BUTTONx_MASK 55 * (they are not ordered. Instead, their values are: 16 8 4) 56 * We have to use array [1..n] and make every permutation on its 57 * containment. After each permutation, make the same thing with 58 * array of buttons and array of expected modifiers. 59 */ 60 static SunToolkit st = (SunToolkit)(Toolkit.getDefaultToolkit()); 61 //all button masks 62 static int [] mouseButtons = new int [BUTTONSNUMBER]; //BUTTONx_MASK 63 static int [] mouseButtonsDown = new int [BUTTONSNUMBER]; //BUTTONx_DOWN_MASK 64 65 //used to store mouse buttons sequences to press/to release 66 static int [] affectedButtonsToPressRelease; 67// static int [] buttonsToRelease; 68// static int [] modifiersToVerifyOnPressRelease; 69 70 static Robot robot; 71 static CheckingAdapter adapterTest1; 72 static Frame f; 73 74 static { 75 for (int i = 0; i < BUTTONSNUMBER; i++){ 76 mouseButtons[i] = InputEvent.getMaskForButton(i+1); //then change first three elements here to BUTTONx_MASK 77 mouseButtonsDown[i] = InputEvent.getMaskForButton(i+1); 78 } 79 //mouseButtons initially has following values : 16 8 4. 80/* mouseButtons[0] = InputEvent.BUTTON1_MASK; 81 mouseButtons[1] = InputEvent.BUTTON2_MASK; 82 mouseButtons[2] = InputEvent.BUTTON3_MASK; 83 */ 84 } 85 86 public static void main(String s[]){ 87 init(); 88 89 try { 90 robot = new Robot(); 91 } catch (Exception e){ 92 e.printStackTrace(); 93 throw new RuntimeException("Test failed.", e); 94 } 95 robot.delay(500); 96 robot.mouseMove(f.getLocationOnScreen().x + f.getWidth()/2, f.getLocationOnScreen().y + f.getHeight()/2); 97 robot.delay(500); 98 //Top limit is the factorial of the number of existing buttons 99 for (int k = 0; k < factorial(mouseButtons.length)-1; k++){ 100 //now we will press 2 up to maximum buttons and release them in different order and listen for 101 // PRESSED events and check it's ExModifiers 102 for (int buttonsToPressNumber = 2; buttonsToPressNumber <= BUTTONSNUMBER; buttonsToPressNumber++ ){ 103 System.out.println(">>>"); 104 105 //Now get the slice of affected buttons 106 affectedButtonsToPressRelease = Arrays.copyOf(mouseButtons, buttonsToPressNumber); 107// modifiersToVerifyOnPressRelease = Arrays.copyOf(mouseButtons, buttonsToPressNumber); 108 109 //Now press all these buttons in the order as they are in array affectedButtonsToPressRelease 110 //And release all these buttons in back order. 111 112 dumpArray("Affected Buttons ", affectedButtonsToPressRelease); 113 pressAllButtons(affectedButtonsToPressRelease); 114 releaseAllButtonsForwardOrder(affectedButtonsToPressRelease); 115// nextPermutation(i, buttonsToRelease); 116 //TODO: press buttons and release them backward 117 //All I have to add is : 118// pressAllButtons(affectedButtonsToPressRelease); 119// releaseAllButtonsBackwardOrder(affectedButtonsToPressRelease); 120 121 System.out.println("<<<"); 122 } 123 nextPermutation(k, mouseButtons); 124// PermutationGenerator.nextPermutation(k, mouseButtonsDown); 125 dumpArray("mouseButtons (step="+k+")", mouseButtons); 126// dumpArray("mouseButtonsDown (step="+k+")", mouseButtonsDown); 127 } 128 } 129 130 private static void init(){ 131 adapterTest1 = new CheckingAdapter(); 132 f = new Frame("Robot presses mouse here"); 133 f.setSize(300, 300); 134 f.setVisible(true); 135 f.addMouseListener(adapterTest1); 136 } 137 public static int factorial(int t){ 138 if (t <=1 ) { 139 return 1; 140 } else { 141 return t*factorial(t-1); 142 } 143 } 144 145 // use this variable to get current button on EDT in checkModifiers() 146 static volatile int currentButtonIndexUnderAction; 147 148 public static void pressAllButtons(int []array){ 149 for (int i = 0; i <array.length; i ++){ 150 if (failed) { 151 throw new RuntimeException("PRESSED_EVENT is not filled with correct values. Review messaage above."); 152 } 153 System.out.println("Pressing button = " + array[i]); 154 currentButtonIndexUnderAction = i; 155 robot.mousePress(array[i]); 156 System.out.println("currentButtonIndexUnderAction ="+currentButtonIndexUnderAction); 157 st.realSync(); 158 // robot.delay(100); 159 } 160 } 161 162 public static void releaseAllButtonsForwardOrder(int []array){ 163 for (int i = 0; i <array.length; i ++){ 164 System.out.println("Releasing button = " + array[i]); 165 currentButtonIndexUnderAction = i; 166 robot.mouseRelease(array[i]); 167 System.out.println("currentButtonIndexUnderAction ="+currentButtonIndexUnderAction); 168 st.realSync(); 169 // robot.delay(100); 170 } 171 } 172 173 public static void checkModifiersOnPress(MouseEvent e){ 174 System.out.println("checkModifiers. currentButtonIndexUnderAction ="+currentButtonIndexUnderAction); 175 for (int i = 0; i<= currentButtonIndexUnderAction; i++){ 176 if ((e.getModifiersEx() & affectedButtonsToPressRelease[i]) == 0){ 177 System.out.println("ERROR["+i+"]: PRESSED_EVENT is not filled with correct values. affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i] +" Event = "+e); 178 ModifierPermutation.failed = true; 179 } else { 180 System.out.println("CORRECT["+i+"]: affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i]+ " Event = "+e); 181 } 182 } 183 } 184 185 /*======================================================================*/ 186 public static void dumpValues(int button, int modifiers, int modifiersStandard, int modifiersEx, int modifiersExStandard){ 187 System.out.println("Button = "+button + "Modifiers = "+ modifiers + " standard = "+ modifiersStandard); 188 System.out.println(" ModifiersEx = "+ modifiersEx + " standardEx = "+ modifiersExStandard); 189 } 190 191 public static void dumpArray(String id, int [] array){ 192 System.out.print(id); 193 for (int i = 0; i < array.length; i++){ 194 System.out.print(array[i]+" "); 195 } 196 System.out.println(); 197 } 198 public static void nextPermutation(int step, int []array){ 199 int i; 200 int leftEl = 0; 201 int rightEl = 0; 202 203 i = array.length - 2; 204 while (i>=0) { 205 if (array[i] < array[i+1]){ 206 leftEl = i; 207 // System.out.println("leftEl = "+leftEl); 208 break; 209 } 210 i--; 211 } 212 213 i = array.length - 1; 214 while (i>=0) { 215 if (array[i] > array[leftEl]) { 216 rightEl = i; 217 // System.out.println("rightEl = "+rightEl); 218 break; 219 } 220 i--; 221 } 222 swapElements(array, leftEl, rightEl); 223 if (leftEl + 2 < array.length){ 224 // System.out.println("sort"); 225 Arrays.sort(array, leftEl + 1 , array.length); 226 } 227 } 228 229 public static void swapElements(int [] array, int leftEl, int rightEl){ 230 int tmp = array[leftEl]; 231 array[leftEl] = array[rightEl]; 232 array[rightEl] = tmp; 233 } 234 235 public static void checkModifiersOnRelease(MouseEvent e){ 236 System.out.println("CheckModifiersOnRelease. currentButtonIndexUnderAction ="+currentButtonIndexUnderAction); 237 for (int i = currentButtonIndexUnderAction+1; i<affectedButtonsToPressRelease.length; i++){ 238 if ((e.getModifiersEx() & affectedButtonsToPressRelease[i]) == 0){ 239 System.out.println("ERROR["+i+"]: RELEASED_EVENT is not filled with correct values. affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i] +" Event = "+e); 240 ModifierPermutation.failed = true; 241 } else { 242 System.out.println("CORRECT["+i+"]: affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i]+ " Event = "+e); 243 } 244 } 245 } 246 247 public static void checkModifiersOnClick(MouseEvent e){ 248 System.out.println("CheckModifiersOnClick. currentButtonIndexUnderAction ="+currentButtonIndexUnderAction); 249//Actually the same as in checkModifiersOnRelease() 250 for (int i = currentButtonIndexUnderAction+1; i<affectedButtonsToPressRelease.length; i++){ 251 if ((e.getModifiersEx() & affectedButtonsToPressRelease[i]) == 0){ 252 System.out.println("ERROR["+i+"]: CLICK_EVENT is not filled with correct values. affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i] +" Event = "+e); 253 ModifierPermutation.failed = true; 254 } else { 255 System.out.println("CORRECT["+i+"]: affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i]+ " Event = "+e); 256 } 257 } 258 } 259} 260///~ ModifierPermutation clas 261 262/* A class that invoke appropriate verification 263 * routine with current modifier. 264 */ 265class CheckingAdapter extends MouseAdapter{ 266 public CheckingAdapter(){} 267 268 public void mousePressed(MouseEvent e) { 269 System.out.println("PRESSED "+e); 270 ModifierPermutation.checkModifiersOnPress(e); 271 } 272 public void mouseReleased(MouseEvent e) { 273 System.out.println("RELEASED "+e); 274 ModifierPermutation.checkModifiersOnRelease(e); 275 276 } 277 public void mouseClicked(MouseEvent e) { 278 System.out.println("CLICKED "+e); 279 ModifierPermutation.checkModifiersOnClick(e); 280 } 281} 282 283// A class that could make a standard permutation with no regard to the 284// values of array passed in. 285// It uses a buttonIndicesToPermutate array with [1..N] values to perform 286// these permutations. 287//Note that nextPermutation is a static method and you can't keep track 288// of more the single permutation sequence. 289/* 290class PermutationGenerator{ 291 final static int BUTTONSNUMBER = MouseInfo.getNumberOfButtons(); 292 static int [] buttonIndicesToPermutate = new int [BUTTONSNUMBER];; 293 public PermutationGenerator(){ 294 for (int i = 0; i < BUTTONSNUMBER; i++){ 295 buttonIndicesToPermutate[i] = i+1; //fill it with [1..N] values 296 } 297 } 298 299 public static void nextPermutation(int step, int []array){ 300 if (array.length != buttonIndicesToPermutate.length) { 301 throw new IllegalArgumentException("Array should have length equals to mouse buttons number."); 302 } 303 int i; 304 int leftEl = 0; 305 int rightEl = 0; 306 307 i = array.length - 2; 308 while (i>=0) { 309 if (buttonIndicesToPermutate[i] < buttonIndicesToPermutate[i+1]){ 310 leftEl = i; 311 // System.out.println("leftEl = "+leftEl); 312 break; 313 } 314 i--; 315 } 316 317 i = array.length - 1; 318 while (i>=0) { 319 if (buttonIndicesToPermutate[i] >buttonIndicesToPermutate[leftEl]) { 320 rightEl = i; 321 // System.out.println("rightEl = "+rightEl); 322 break; 323 } 324 i--; 325 } 326 swapElements(array, leftEl, rightEl); 327 swapElements(buttonIndicesToPermutate, leftEl, rightEl); 328 329 if (leftEl + 2 < array.length){ 330 // System.out.println("sort"); 331//need to make our own sorting because arraysort makes this on actual values in array... 332 Arrays.sort(array, leftEl + 1 , array.length); 333 Arrays.sort(buttonIndicesToPermutate, leftEl + 1 , buttonIndicesToPermutate.length); 334// sortArray(array, leftEl + 1 , array.length); 335 } 336 } 337 public static void swapElements(int [] array, int leftEl, int rightEl){ 338 int tmp = array[leftEl]; 339 array[leftEl] = array[rightEl]; 340 array[rightEl] = tmp; 341 } 342} 343*/ 344