/* test %I% %E% @bug 6315717 @summary presses buttons in all permutations and verifies modifiers @author Andrei Dmitriev : area=awt.mouse @run main ModifierPermutation */ //package modifierpermutation; /* The test will try to press-release every button present on the mouse in different order. Here are some abbreviations: BUTTON1 press = P1 BUTTON2 press = P2 etc. BUTTON1 release = R1 BUTTON2 release = R2 etc. Only sequences alike below are possible : <P1, P2, R2, R1>. Sequences like <P1, P2, R1, R2> will not be covered by this test due to its probable complexity. */ import java.awt.*; import sun.awt.SunToolkit; import java.awt.event.*; import java.util.Arrays; public class ModifierPermutation { static boolean failed = false; final static int BUTTONSNUMBER = MouseInfo.getNumberOfButtons(); /* * Because of some problems with BUTTONx_MASK * (they are not ordered. Instead, their values are: 16 8 4) * We have to use array [1..n] and make every permutation on its * containment. After each permutation, make the same thing with * array of buttons and array of expected modifiers. */ static SunToolkit st = (SunToolkit)(Toolkit.getDefaultToolkit()); //all button masks static int [] mouseButtons = new int [BUTTONSNUMBER]; //BUTTONx_MASK static int [] mouseButtonsDown = new int [BUTTONSNUMBER]; //BUTTONx_DOWN_MASK //used to store mouse buttons sequences to press/to release static int [] affectedButtonsToPressRelease; // static int [] buttonsToRelease; // static int [] modifiersToVerifyOnPressRelease; static Robot robot; static CheckingAdapter adapterTest1; static Frame f; static { for (int i = 0; i < BUTTONSNUMBER; i++){ mouseButtons[i] = InputEvent.getMaskForButton(i+1); //then change first three elements here to BUTTONx_MASK mouseButtonsDown[i] = InputEvent.getMaskForButton(i+1); } //mouseButtons initially has following values : 16 8 4. /* mouseButtons[0] = InputEvent.BUTTON1_MASK; mouseButtons[1] = InputEvent.BUTTON2_MASK; mouseButtons[2] = InputEvent.BUTTON3_MASK; */ } public static void main(String s[]){ init(); try { robot = new Robot(); } catch (Exception e){ e.printStackTrace(); throw new RuntimeException("Test failed.", e); } robot.delay(500); robot.mouseMove(f.getLocationOnScreen().x + f.getWidth()/2, f.getLocationOnScreen().y + f.getHeight()/2); robot.delay(500); //Top limit is the factorial of the number of existing buttons for (int k = 0; k < factorial(mouseButtons.length)-1; k++){ //now we will press 2 up to maximum buttons and release them in different order and listen for // PRESSED events and check it's ExModifiers for (int buttonsToPressNumber = 2; buttonsToPressNumber <= BUTTONSNUMBER; buttonsToPressNumber++ ){ System.out.println(">>>"); //Now get the slice of affected buttons affectedButtonsToPressRelease = Arrays.copyOf(mouseButtons, buttonsToPressNumber); // modifiersToVerifyOnPressRelease = Arrays.copyOf(mouseButtons, buttonsToPressNumber); //Now press all these buttons in the order as they are in array affectedButtonsToPressRelease //And release all these buttons in back order. dumpArray("Affected Buttons ", affectedButtonsToPressRelease); pressAllButtons(affectedButtonsToPressRelease); releaseAllButtonsForwardOrder(affectedButtonsToPressRelease); // nextPermutation(i, buttonsToRelease); //TODO: press buttons and release them backward //All I have to add is : // pressAllButtons(affectedButtonsToPressRelease); // releaseAllButtonsBackwardOrder(affectedButtonsToPressRelease); System.out.println("<<<"); } nextPermutation(k, mouseButtons); // PermutationGenerator.nextPermutation(k, mouseButtonsDown); dumpArray("mouseButtons (step="+k+")", mouseButtons); // dumpArray("mouseButtonsDown (step="+k+")", mouseButtonsDown); } } private static void init(){ adapterTest1 = new CheckingAdapter(); f = new Frame("Robot presses mouse here"); f.setSize(300, 300); f.setVisible(true); f.addMouseListener(adapterTest1); } public static int factorial(int t){ if (t <=1 ) { return 1; } else { return t*factorial(t-1); } } // use this variable to get current button on EDT in checkModifiers() static volatile int currentButtonIndexUnderAction; public static void pressAllButtons(int []array){ for (int i = 0; i <array.length; i ++){ if (failed) { throw new RuntimeException("PRESSED_EVENT is not filled with correct values. Review messaage above."); } System.out.println("Pressing button = " + array[i]); currentButtonIndexUnderAction = i; robot.mousePress(array[i]); System.out.println("currentButtonIndexUnderAction ="+currentButtonIndexUnderAction); st.realSync(); // robot.delay(100); } } public static void releaseAllButtonsForwardOrder(int []array){ for (int i = 0; i <array.length; i ++){ System.out.println("Releasing button = " + array[i]); currentButtonIndexUnderAction = i; robot.mouseRelease(array[i]); System.out.println("currentButtonIndexUnderAction ="+currentButtonIndexUnderAction); st.realSync(); // robot.delay(100); } } public static void checkModifiersOnPress(MouseEvent e){ System.out.println("checkModifiers. currentButtonIndexUnderAction ="+currentButtonIndexUnderAction); for (int i = 0; i<= currentButtonIndexUnderAction; i++){ if ((e.getModifiersEx() & affectedButtonsToPressRelease[i]) == 0){ System.out.println("ERROR["+i+"]: PRESSED_EVENT is not filled with correct values. affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i] +" Event = "+e); ModifierPermutation.failed = true; } else { System.out.println("CORRECT["+i+"]: affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i]+ " Event = "+e); } } } /*======================================================================*/ public static void dumpValues(int button, int modifiers, int modifiersStandard, int modifiersEx, int modifiersExStandard){ System.out.println("Button = "+button + "Modifiers = "+ modifiers + " standard = "+ modifiersStandard); System.out.println(" ModifiersEx = "+ modifiersEx + " standardEx = "+ modifiersExStandard); } public static void dumpArray(String id, int [] array){ System.out.print(id); for (int i = 0; i < array.length; i++){ System.out.print(array[i]+" "); } System.out.println(); } public static void nextPermutation(int step, int []array){ int i; int leftEl = 0; int rightEl = 0; i = array.length - 2; while (i>=0) { if (array[i] < array[i+1]){ leftEl = i; // System.out.println("leftEl = "+leftEl); break; } i--; } i = array.length - 1; while (i>=0) { if (array[i] > array[leftEl]) { rightEl = i; // System.out.println("rightEl = "+rightEl); break; } i--; } swapElements(array, leftEl, rightEl); if (leftEl + 2 < array.length){ // System.out.println("sort"); Arrays.sort(array, leftEl + 1 , array.length); } } public static void swapElements(int [] array, int leftEl, int rightEl){ int tmp = array[leftEl]; array[leftEl] = array[rightEl]; array[rightEl] = tmp; } public static void checkModifiersOnRelease(MouseEvent e){ System.out.println("CheckModifiersOnRelease. currentButtonIndexUnderAction ="+currentButtonIndexUnderAction); for (int i = currentButtonIndexUnderAction+1; i<affectedButtonsToPressRelease.length; i++){ if ((e.getModifiersEx() & affectedButtonsToPressRelease[i]) == 0){ System.out.println("ERROR["+i+"]: RELEASED_EVENT is not filled with correct values. affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i] +" Event = "+e); ModifierPermutation.failed = true; } else { System.out.println("CORRECT["+i+"]: affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i]+ " Event = "+e); } } } public static void checkModifiersOnClick(MouseEvent e){ System.out.println("CheckModifiersOnClick. currentButtonIndexUnderAction ="+currentButtonIndexUnderAction); //Actually the same as in checkModifiersOnRelease() for (int i = currentButtonIndexUnderAction+1; i<affectedButtonsToPressRelease.length; i++){ if ((e.getModifiersEx() & affectedButtonsToPressRelease[i]) == 0){ System.out.println("ERROR["+i+"]: CLICK_EVENT is not filled with correct values. affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i] +" Event = "+e); ModifierPermutation.failed = true; } else { System.out.println("CORRECT["+i+"]: affectedButtonsToPressRelease[i]= "+affectedButtonsToPressRelease[i]+ " Event = "+e); } } } } ///~ ModifierPermutation clas /* A class that invoke appropriate verification * routine with current modifier. */ class CheckingAdapter extends MouseAdapter{ public CheckingAdapter(){} public void mousePressed(MouseEvent e) { System.out.println("PRESSED "+e); ModifierPermutation.checkModifiersOnPress(e); } public void mouseReleased(MouseEvent e) { System.out.println("RELEASED "+e); ModifierPermutation.checkModifiersOnRelease(e); } public void mouseClicked(MouseEvent e) { System.out.println("CLICKED "+e); ModifierPermutation.checkModifiersOnClick(e); } } // A class that could make a standard permutation with no regard to the // values of array passed in. // It uses a buttonIndicesToPermutate array with [1..N] values to perform // these permutations. //Note that nextPermutation is a static method and you can't keep track // of more the single permutation sequence. /* class PermutationGenerator{ final static int BUTTONSNUMBER = MouseInfo.getNumberOfButtons(); static int [] buttonIndicesToPermutate = new int [BUTTONSNUMBER];; public PermutationGenerator(){ for (int i = 0; i < BUTTONSNUMBER; i++){ buttonIndicesToPermutate[i] = i+1; //fill it with [1..N] values } } public static void nextPermutation(int step, int []array){ if (array.length != buttonIndicesToPermutate.length) { throw new IllegalArgumentException("Array should have length equals to mouse buttons number."); } int i; int leftEl = 0; int rightEl = 0; i = array.length - 2; while (i>=0) { if (buttonIndicesToPermutate[i] < buttonIndicesToPermutate[i+1]){ leftEl = i; // System.out.println("leftEl = "+leftEl); break; } i--; } i = array.length - 1; while (i>=0) { if (buttonIndicesToPermutate[i] >buttonIndicesToPermutate[leftEl]) { rightEl = i; // System.out.println("rightEl = "+rightEl); break; } i--; } swapElements(array, leftEl, rightEl); swapElements(buttonIndicesToPermutate, leftEl, rightEl); if (leftEl + 2 < array.length){ // System.out.println("sort"); //need to make our own sorting because arraysort makes this on actual values in array... Arrays.sort(array, leftEl + 1 , array.length); Arrays.sort(buttonIndicesToPermutate, leftEl + 1 , buttonIndicesToPermutate.length); // sortArray(array, leftEl + 1 , array.length); } } public static void swapElements(int [] array, int leftEl, int rightEl){ int tmp = array[leftEl]; array[leftEl] = array[rightEl]; array[rightEl] = tmp; } } */