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