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