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