undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,190 @@
/*
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @key headful
* @bug 6315717
* @summary Verifies that the mouse drag events received for every button if the property is set to true
* @run main ExtraButtonDrag
*/
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.InvocationTargetException;
public class ExtraButtonDrag {
private static Frame frame;
private static Robot robot;
private static volatile boolean dragged = false;
private static volatile boolean moved = false;
private static volatile Point centerFrame;
private static volatile Point outboundsFrame;
private static final String OS_NAME = System.getProperty("os.name");
private static MouseAdapter mAdapter = new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
dragged = true;
}
@Override
public void mouseMoved(MouseEvent e) {
moved = true;
}
};
public static void initializeGUI() {
frame = new Frame("ExtraButtonDrag");
frame.addMouseMotionListener(mAdapter);
frame.addMouseListener(mAdapter);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void doTest()
throws InvocationTargetException, InterruptedException {
int[] buttonMask = new int[MouseInfo.getNumberOfButtons()];
for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++) {
buttonMask[i] = InputEvent.getMaskForButton(i + 1);
}
EventQueue.invokeAndWait(() -> {
Point location = frame.getLocationOnScreen();
Dimension size = frame.getSize();
centerFrame = new Point(location.x + size.width / 2,
location.y + size.height / 2);
outboundsFrame = new Point(location.x + size.width * 3 / 2,
location.y + size.height / 2);
});
System.out.println("areExtraMouseButtonsEnabled() == "
+ Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled());
for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++) {
System.out.println("button to drag = " + (i + 1)
+ " : value passed to robot = " + buttonMask[i]);
try {
dragMouse(buttonMask[i], centerFrame.x, centerFrame.y,
outboundsFrame.x, outboundsFrame.y);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Test failed. Exception occured.",
e);
}
// this is a choice-case for X protocol issue: native events from
// extra buttons doesn't contain
// the correct state so it's unable to decide if there is a drag or
// move. By default we send MOVED event.
// XToolkit: extra buttons should report MOVED events only
// WToolkit: extra buttons should report DRAGGED events only
if (i > 2) { // extra buttons only
if (OS_NAME.equals("Linux")) {
if (!moved || dragged) {
throw new RuntimeException("Test failed." + OS_NAME
+ " Button = " + (i + 1) + " moved = " + moved
+ " : dragged = " + dragged);
}
} else { // WToolkit
if (moved || !dragged) {
throw new RuntimeException("Test failed." + OS_NAME
+ " Button = " + (i + 1) + " moved = " + moved
+ " : dragged = " + dragged);
}
}
} else {
if (moved || !dragged) {
throw new RuntimeException(
"Test failed. Button = " + (i + 1) + " not dragged.");
}
}
}
}
public static void dragMouse(int button, int x0, int y0, int x1, int y1) {
int curX = x0;
int curY = y0;
int dx = x0 < x1 ? 1 : -1;
int dy = y0 < y1 ? 1 : -1;
robot.mouseMove(x0, y0);
robot.delay(200);
dragged = false;
moved = false;
robot.mousePress(button);
while (curX != x1) {
curX += dx;
robot.mouseMove(curX, curY);
robot.delay(5);
}
while (curY != y1) {
curY += dy;
robot.mouseMove(curX, curY);
robot.delay(5);
}
robot.mouseRelease(button);
}
public static void main(String[] s)
throws InvocationTargetException, InterruptedException, AWTException {
try {
robot = new Robot();
robot.setAutoDelay(10);
robot.setAutoWaitForIdle(true);
EventQueue.invokeAndWait(ExtraButtonDrag::initializeGUI);
robot.waitForIdle();
robot.delay(100);
doTest();
System.out.println("Test Passed");
} finally {
EventQueue.invokeAndWait(ExtraButtonDrag::disposeFrame);
}
}
public static void disposeFrame() {
if (frame != null) {
frame.dispose();
frame = null;
}
}
}

View file

@ -0,0 +1,343 @@
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
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;
}
}
*/

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.MouseInfo;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
/**
* @test
* @key headful
* @bug 8143054
*/
public final class MouseModifiersInKeyEvent {
private static int modifiersEX = 0;
private static int modifiers = 0;
private static JFrame f;
private static Rectangle bounds;
public static void main(final String[] args) throws Exception {
for (int i = 1; i <= MouseInfo.getNumberOfButtons(); ++i) {
test(InputEvent.getMaskForButton(i));
}
}
private static void test(final int mask) throws Exception {
final Robot r = new Robot();
r.setAutoDelay(100);
r.setAutoWaitForIdle(true);
EventQueue.invokeAndWait(MouseModifiersInKeyEvent::createAndShowGUI);
r.waitForIdle();
EventQueue.invokeAndWait(() -> bounds = f.getBounds());
r.mouseMove(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
r.mousePress(mask);
r.keyPress(KeyEvent.VK_A);
r.keyRelease(KeyEvent.VK_A);
EventQueue.invokeAndWait(() -> f.dispose());
r.mouseRelease(mask);
// all extended modifiers should work
if (modifiersEX != mask) {
System.err.println("Expected modifiersEX: " + mask);
System.err.println("Actual modifiersEX: " + modifiersEX);
throw new RuntimeException();
}
// old modifiers work only for button1
if (modifiersEX == InputEvent.BUTTON1_DOWN_MASK) {
if (modifiers != InputEvent.BUTTON1_MASK) {
System.err.println("Expected modifiers: " + InputEvent.BUTTON1_MASK);
System.err.println("Actual modifiers: " + modifiers);
throw new RuntimeException();
}
}
modifiersEX = 0;
modifiers = 0;
}
private static void createAndShowGUI() {
f = new JFrame();
final Component component = new JTextField();
component.addKeyListener(new MyKeyListener());
f.add(component);
f.setSize(300, 300);
f.setLocationRelativeTo(null);
f.setAlwaysOnTop(true);
f.setVisible(true);
}
static final class MyKeyListener extends KeyAdapter {
public void keyPressed(final KeyEvent e) {
modifiersEX = e.getModifiersEx();
modifiers = e.getModifiers();
}
}
}

View file

@ -0,0 +1,517 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
@test %I% %E%
@key headful
@bug 6315717
@summary verifies that modifiers are correct for extra buttons
@author Andrei Dmitriev : area=awt.mouse
@library /test/lib
@build jdk.test.lib.Platform
@run main MouseModifiersUnitTest_Extra
*/
import jdk.test.lib.Platform;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.Vector;
// will process extra buttons only
// asking parameters from CMD: manual/automatic, modifier to test
public class MouseModifiersUnitTest_Extra extends Frame {
static final int NONE = 0;
static final int SHIFT = 1;
static final int CTRL = 2;
static final int ALT = 3;
static CheckingModifierAdapterExtra adapterTest1;
static CheckingModifierAdapterExtra adapterTest2;
static CheckingModifierAdapterExtra adapterTest3;
static CheckingModifierAdapterExtra adapterTest4;
static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception
static boolean autorun = false; //use robot or manual run
static int testModifier = NONE;
static int [] mouseButtonDownMasks;
//an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them
static int [] modifiersExStandard;
static int [] modifiersExStandardSHIFT;
static int [] modifiersExStandardCTRL;
static int [] modifiersExStandardALT;
private final static String SHIFT_MODIFIER = Platform.isOSX() ?
"\u21e7" : "Shift";
private final static String ALT_MODIFIER = Platform.isOSX() ?
"\u2325" : "Alt";
private final static String CTRL_MODIFIER = Platform.isOSX() ?
"\u2303" : "Ctrl";
// BUTTON1, 2, 3 press-release.
final static int modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK;
public static void checkPressedModifiersTest(int testModifier, MouseEvent event){
int [] curStandardExModifiers = getStandardExArray(testModifier);
int button = event.getButton();
int modifiers = event.getModifiers();
int modifiersEx = event.getModifiersEx();
int index = (button - 4)*3;
dumpValues(button, modifiers, modifiersStandard, modifiersEx, curStandardExModifiers[index]);
if (modifiers != modifiersStandard){
MessageLogger.reportError("Test failed : Pressed. modifiers != modifiersStandard");
}
if (modifiersEx != curStandardExModifiers[index]){
// System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers");
MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers. Got: "
+ modifiersEx + " , Expected: " + curStandardExModifiers[index]);
}
//check event.paramString() output
HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
System.out.println(event.paramString());
checkButton(paramStringElements, button);
checkModifiers(testModifier, paramStringElements, button);
checkExtModifiersOnPress(testModifier, paramStringElements, button);
}
public static void checkExtModifiersOnReleaseClick(int testModifier, HashMap<String, String> h, int button){
String ethalon = "";
switch (testModifier){
case SHIFT:{
ethalon = SHIFT_MODIFIER;
break;
}
case ALT:{
ethalon = ALT_MODIFIER;
break;
}
case CTRL:{
ethalon = CTRL_MODIFIER;
break;
}
}
if (h.get("extModifiers") == null){
h.put("extModifiers", "");
}
if (!ethalon.equals(h.get("extModifiers"))) {
MessageLogger.reportError("Test failed : Released/Clicked. extModifiers = "
+ h.get("extModifiers") + " instead of : " + ethalon);
}
}
public static void checkExtModifiersOnPress(int testModifier, HashMap<String, String> h, int button){
String ethalon = "";
switch (testModifier){
case SHIFT:{
ethalon = SHIFT_MODIFIER + "+";
break;
}
case ALT:{
ethalon = ALT_MODIFIER + "+";
break;
}
case CTRL:{
ethalon = CTRL_MODIFIER + "+";
break;
}
}
ethalon = ethalon + "Button" +button;
if (!h.get("extModifiers").equals(ethalon)) {
MessageLogger.reportError("Test failed : Pressed. extModifiers = " +h.get("extModifiers")+" instead of : "
+ ethalon);
}
}
public static void checkModifiers(int testModifier, HashMap<String, String> h, int button){
// none of modifiers for extra button should be null
if (h.get("modifiers") != null) {
MessageLogger.reportError("Test failed : modifiers != null");
}
}
public static void checkButton(HashMap<String, String> h, int button){
if (h.get("button") == null) {
MessageLogger.reportError("Test failed : checkButton(). button is absent in paramString()");
}
if (Integer.parseInt(h.get("button")) != button) {
MessageLogger.reportError("Test failed : checkButton. button in paramString() doesn't equal to button being pressed.");
}
}
public static HashMap<String, String> tokenizeParamString(String param){
HashMap <String, String> params = new HashMap<>();
StringTokenizer st = new StringTokenizer(param, ",=");
while (st.hasMoreTokens()){
String tmp = st.nextToken();
// System.out.println("PARSER : "+tmp);
if (tmp.equals("button") ||
tmp.equals("modifiers") ||
tmp.equals("extModifiers")) {
params.put(tmp, st.nextToken());
}
}
return params;
}
public static Vector<String> tokenizeModifiers(String modifierList){
Vector<String> modifiers = new Vector<>();
StringTokenizer st = new StringTokenizer(modifierList, "+");
while (st.hasMoreTokens()){
String tmp = st.nextToken();
modifiers.addElement(tmp);
System.out.println("MODIFIER PARSER : "+tmp);
}
return modifiers;
}
public static void checkReleasedModifiersTest(int testModifier, MouseEvent event){
int [] curStandardExModifiers = getStandardExArray(testModifier);
int button = event.getButton();
int modifiers = event.getModifiers();
int modifiersEx = event.getModifiersEx();
int index = (button - 4)*3 + 1;
dumpValues(button, modifiers, modifiersStandard, modifiersEx, curStandardExModifiers[index]);
if (modifiers != modifiersStandard){
MessageLogger.reportError("Test failed : Released. modifiers != modifiersStandard");
}
if (modifiersEx != curStandardExModifiers[index]){
MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers. Got: "
+ modifiersEx + " , Expected: " + curStandardExModifiers[index]);
}
//check event.paramString() output
HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
checkButton(paramStringElements, button);
checkModifiers(testModifier, paramStringElements, button);
System.out.println("paramStringElements = "+paramStringElements);
checkExtModifiersOnReleaseClick(testModifier, paramStringElements, button);
}
public static void checkClickedModifiersTest(int testModifier, MouseEvent event){
int [] curStandardExModifiers = getStandardExArray(testModifier);
int button = event.getButton();
int modifiers = event.getModifiers();
int modifiersEx = event.getModifiersEx();
int index = (button - 4)*3 + 2;
dumpValues(button, modifiers, modifiersStandard, modifiersEx, curStandardExModifiers[index]);
if (modifiers != modifiersStandard){
MessageLogger.reportError("Test failed : Clicked. modifiers != modifiersStandard");
}
if (modifiersEx != curStandardExModifiers[index]){
MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers. Got: "
+ modifiersEx + " , Expected: " + curStandardExModifiers[index]);
}
//check event.paramString() output
HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
checkButton(paramStringElements, button);
checkModifiers(testModifier, paramStringElements, button);
checkExtModifiersOnReleaseClick(testModifier, paramStringElements, button);
}
private static int[] getStandardExArray(int testModifier) {
int [] curStandardExModifiers;
switch (testModifier){
case SHIFT:
curStandardExModifiers = modifiersExStandardSHIFT;
break;
case CTRL:
curStandardExModifiers = modifiersExStandardCTRL;
break;
case ALT:
curStandardExModifiers = modifiersExStandardALT;
break;
default: //NONE by default
curStandardExModifiers = modifiersExStandard;
}
return curStandardExModifiers;
}
static Robot robot;
public void init() {
this.setLayout(new BorderLayout());
try {
robot = new Robot();
robot.setAutoDelay(100);
robot.setAutoWaitForIdle(true);
} catch (Exception e) {
MessageLogger.reportError("Test failed. "+e);
}
}//End init()
public void start() {
//Get things going. Request focus, set size, et cetera
setSize(200,200);
setVisible(true);
validate();
if (autorun) {
testNONE();
testSHIFT();
testCTRL();
testALT();
} else {
switch (testModifier){
case SHIFT:
this.addMouseListener(adapterTest2);
break;
case CTRL:
this.addMouseListener(adapterTest3);
break;
case ALT:
this.addMouseListener(adapterTest4);
break;
default: //NONE by default
this.addMouseListener(adapterTest1);
}
}
}// start()
//000000000000000000000000000000000000000000000000000000000000000
public void testNONE(){
this.addMouseListener(adapterTest1);
robot.delay(1000);
robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
for (int i = 3; i< mouseButtonDownMasks.length; i++){
System.out.println("testNONE() => " + mouseButtonDownMasks[i]);
robot.mousePress(mouseButtonDownMasks[i]);
robot.mouseRelease(mouseButtonDownMasks[i]);
}
robot.delay(1000);
this.removeMouseListener(adapterTest1);
}
public void testSHIFT(){
this.addMouseListener(adapterTest2);
robot.delay(1000);
robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
for (int i = 3; i< mouseButtonDownMasks.length; i++){
robot.keyPress(KeyEvent.VK_SHIFT);
System.out.println("testSHIFT() => " + mouseButtonDownMasks[i]);
robot.mousePress(mouseButtonDownMasks[i]);
robot.mouseRelease(mouseButtonDownMasks[i]);
robot.keyRelease(KeyEvent.VK_SHIFT);
}
robot.delay(1000);
this.removeMouseListener(adapterTest2);
}
public void testCTRL(){
this.addMouseListener(adapterTest3);
robot.delay(1000);
robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
for (int i = 3; i< mouseButtonDownMasks.length; i++){
robot.keyPress(KeyEvent.VK_CONTROL);
System.out.println("testCTRL() => " + mouseButtonDownMasks[i]);
robot.mousePress(mouseButtonDownMasks[i]);
robot.mouseRelease(mouseButtonDownMasks[i]);
robot.keyRelease(KeyEvent.VK_CONTROL);
}
robot.delay(1000);
this.removeMouseListener(adapterTest3);
}
public void testALT(){
this.addMouseListener(adapterTest4);
robot.delay(1000);
robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
for (int i = 3; i< mouseButtonDownMasks.length; i++){
robot.keyPress(KeyEvent.VK_ALT);
System.out.println("testALT() => " + mouseButtonDownMasks[i]);
robot.mousePress(mouseButtonDownMasks[i]);
robot.mouseRelease(mouseButtonDownMasks[i]);
robot.keyRelease(KeyEvent.VK_ALT);
}
robot.delay(1000);
this.removeMouseListener(adapterTest4);
}
//**************************************************************************************************
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("Button = "+button + "ModifiersEx = "+ modifiersEx + "standardEx = "+ modifiersExStandard);
}
public static void initParams(String []s){
if (s.length != 3){
autorun = true;
debug = false;
testModifier = NONE;
} else {
autorun = Boolean.valueOf(s[0]);
debug = Boolean.valueOf(s[1]);
if (s[2].equals("NONE")){
testModifier = NONE;
}
if (s[2].equals("SHIFT")){
testModifier = SHIFT;
}
if (s[2].equals("CTRL")){
testModifier = CTRL;
}
if (s[2].equals("ALT")){
testModifier = ALT;
}
}
MessageLogger.setDebug(debug);
System.out.println("Autorun : " +autorun);
System.out.println("Debug mode : " +debug);
System.out.println("Modifier to verify : " + testModifier);
}
public static void initAdapters(){
adapterTest1 = new CheckingModifierAdapterExtra(NONE);
adapterTest2 = new CheckingModifierAdapterExtra(SHIFT);
adapterTest3 = new CheckingModifierAdapterExtra(CTRL);
adapterTest4 = new CheckingModifierAdapterExtra(ALT);
}
public static void initVars(){
//Init the array of the mouse button masks. It will be used for generating mouse events.
mouseButtonDownMasks = new int [MouseInfo.getNumberOfButtons()];
for (int i = 0; i < mouseButtonDownMasks.length; i++){
mouseButtonDownMasks[i] = InputEvent.getMaskForButton(i+1);
System.out.println("MouseArray [i] == "+mouseButtonDownMasks[i]);
}
// So we need to get the number of extra buttons on the mouse: "MouseInfo.getNumberOfButtons() - 3"
// and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK.
int [] tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
//Fill array of expected results for the case when mouse buttons are only used (no-modifier keys)
Arrays.fill(tmp, 0);
for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
tmp[i] = mouseButtonDownMasks[j];
}
modifiersExStandard = Arrays.copyOf(tmp, tmp.length);
//Fill array of expected results for the case when mouse buttons are only used with SHIFT modifier key
Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK);
for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
System.out.println("modifiersExStandardSHIFT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
tmp[i] = tmp[i] | mouseButtonDownMasks[j];
}
modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length);
//Fill array of expected results for the case when mouse buttons are only used with CTRL modifier key
Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK);
for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
System.out.println("modifiersExStandardCTRL FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
tmp[i] = tmp[i] | mouseButtonDownMasks[j];
}
modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length);
//Fill array of expected results for the case when mouse buttons are only used with ALT modifier key
Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK);
for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
System.out.println("modifiersExStandardALT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
tmp[i] = tmp[i] | mouseButtonDownMasks[j];
}
modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length);
}
public static void main(String []s){
if (MouseInfo.getNumberOfButtons() < 4){
System.out.println("There are less than 4 buttons on the mouse. The test may not be accomplished. Skipping.");
return;
}
initVars();
MouseModifiersUnitTest_Extra frame = new MouseModifiersUnitTest_Extra();
frame.initParams(s);
frame.init();
initAdapters();
frame.start();
}
}// class
/* A class that invoke appropriate verification
* routine with current modifier.
*/
class CheckingModifierAdapterExtra extends MouseAdapter{
int modifier;
public CheckingModifierAdapterExtra(int modifier){
this.modifier = modifier;
}
public void mousePressed(MouseEvent e) {
System.out.println("PRESSED "+e);
if (e.getButton() <= MouseEvent.BUTTON3) {
System.out.println("Standard button affected. Skip.");
} else {
MouseModifiersUnitTest_Extra.checkPressedModifiersTest(modifier, e);
}
}
public void mouseReleased(MouseEvent e) {
System.out.println("RELEASED "+e);
if (e.getButton() <= MouseEvent.BUTTON3) {
System.out.println("Standard button affected. Skip.");
} else {
MouseModifiersUnitTest_Extra.checkReleasedModifiersTest(modifier, e);
}
}
public void mouseClicked(MouseEvent e) {
System.out.println("CLICKED "+e);
if (e.getButton() <= MouseEvent.BUTTON3) {
System.out.println("Standard button affected. Skip.");
} else {
MouseModifiersUnitTest_Extra.checkClickedModifiersTest(modifier, e);
}
}
}
//Utility class that could report a message depending on current purpose of the test run
class MessageLogger{
private static boolean debug;
public static void setDebug(boolean d){
debug = d;
log("Switch to "+ ((debug)?"debug":"trial") +" mode");
}
public static void log(String message){
System.out.println(message);
}
public static void reportError(String message){
if (debug){
System.out.println(message);
} else {
throw new RuntimeException(message);
}
}
}

View file

@ -0,0 +1,622 @@
/*
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
@test %I% %E%
@key headful
@bug 6315717
@summary verifies that modifiers are correct for standard (1, 2, 3, wheel) mouse buttons
@author Andrei Dmitriev : area=awt.mouse
@run main MouseModifiersUnitTest_Standard
*/
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.Vector;
//the test verifies:
// 1) verifies that modifiers are correct for standard (1, 2, 3) mouse buttons
// TODO: 2) verifies that modifiers are correct for wheel
// TODO: 3)
// Case1. the test posts BUTTONx_MASK and verifies that paramString() contains correct modifiers and exModifiers
// Case2. the test posts BUTTONx_DOWN_MASK and verifies that paramString() contains correct modifiers and exModifiers
// Case3. the test posts getMaskForButton(n) and verifies that paramString() contains correct modifiers and exModifiers
// repeat all cases with SHIFT/ALT/CTRL modifiers verify that paramString() contains correct modifiers and exModifiers
// I'm verifying button, modifiers and extModifiers for now.
public class MouseModifiersUnitTest_Standard {
static final int NONE = 0;
static final int SHIFT = 1;
static final int CTRL = 2;
static final int ALT = 3;
static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception
static boolean autorun = false; //use robot or manual run
static int testModifier = NONE;
// static String testModifier = "NONE";
static CheckingModifierAdapter adapterTest1;
static CheckingModifierAdapter adapterTest2;
static CheckingModifierAdapter adapterTest3;
static CheckingModifierAdapter adapterTest4;
static Frame f;
final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK};
// BUTTON1, 2, 3 press-release.
final static int [] modifiersStandardTestNONE = new int[] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON1_MASK,
MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON2_MASK,
MouseEvent.BUTTON3_MASK, MouseEvent.BUTTON3_MASK, MouseEvent.BUTTON3_MASK };
final static int [] modifiersExStandardTestNONE = new int[] {MouseEvent.BUTTON1_DOWN_MASK, 0, 0,
MouseEvent.BUTTON2_DOWN_MASK, 0, 0,
MouseEvent.BUTTON3_DOWN_MASK, 0, 0};
// BUTTON1, 2, 3 press-release with shift modifier
final static int [] modifiersStandardTestSHIFT = new int[] {MouseEvent.BUTTON1_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON1_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON1_MASK|InputEvent.SHIFT_MASK,
MouseEvent.BUTTON2_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON2_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON2_MASK|InputEvent.SHIFT_MASK,
MouseEvent.BUTTON3_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON3_MASK|InputEvent.SHIFT_MASK, MouseEvent.BUTTON3_MASK|InputEvent.SHIFT_MASK };
final static int [] modifiersExStandardTestSHIFT = new int[] {MouseEvent.BUTTON1_DOWN_MASK|InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK,
MouseEvent.BUTTON2_DOWN_MASK|InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK,
MouseEvent.BUTTON3_DOWN_MASK|InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK};
// BUTTON1, 2, 3 press-release with CTRL modifier
final static int [] modifiersStandardTestCTRL = new int[] {MouseEvent.BUTTON1_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON1_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON1_MASK|InputEvent.CTRL_MASK,
MouseEvent.BUTTON2_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON2_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON2_MASK|InputEvent.CTRL_MASK,
MouseEvent.BUTTON3_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON3_MASK|InputEvent.CTRL_MASK, MouseEvent.BUTTON3_MASK|InputEvent.CTRL_MASK };
final static int [] modifiersExStandardTestCTRL = new int[] {MouseEvent.BUTTON1_DOWN_MASK|InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK,
MouseEvent.BUTTON2_DOWN_MASK|InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK,
MouseEvent.BUTTON3_DOWN_MASK|InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK, InputEvent.CTRL_DOWN_MASK};
// BUTTON1, 2, 3 press-release with ALT modifier
final static int [] modifiersStandardTestALT = new int[] {MouseEvent.BUTTON1_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON1_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON1_MASK|InputEvent.ALT_MASK,
MouseEvent.BUTTON2_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON2_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON2_MASK|InputEvent.ALT_MASK,
MouseEvent.BUTTON3_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON3_MASK|InputEvent.ALT_MASK, MouseEvent.BUTTON3_MASK|InputEvent.ALT_MASK };
final static int [] modifiersExStandardTestALT = new int[] {MouseEvent.BUTTON1_DOWN_MASK|InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK,
MouseEvent.BUTTON2_DOWN_MASK|InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK,
MouseEvent.BUTTON3_DOWN_MASK|InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK, InputEvent.ALT_DOWN_MASK};
static Robot robot;
public static void main(String s[]){
initParams(s);
initAdapters();
f = new Frame();
final int [] modifiers = {InputEvent.SHIFT_MASK, InputEvent.CTRL_MASK};
final String [] modifierNames = {"InputEvent.SHIFT_MASK", "InputEvent.CTRL_MASK"};
f.setLayout(new FlowLayout());
f.addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
System.out.println("WHEEL "+e);
}
});
f.setSize(300, 300);
f.setVisible(true);
try {
robot = new Robot();
robot.delay(500);
robot.mouseMove(f.getLocationOnScreen().x + f.getWidth()/2, f.getLocationOnScreen().y + f.getHeight()/2);
if (autorun) {
//testing buttons 1, 2, 3 only
testPlainButtons();
robot.delay(500);
//testing buttons 1, 2, 3 with SHIFT, CTRL, ALT keyboard modifiers
testButtonsWithShift();
robot.delay(500);
testButtonsWithControl();
robot.delay(500);
testButtonsWithAlt();
robot.delay(500);
} else {
switch (testModifier){
case SHIFT:
f.addMouseListener(adapterTest2);
break;
case CTRL:
f.addMouseListener(adapterTest3);
break;
case ALT:
f.addMouseListener(adapterTest4);
break;
default: //NONE inclusive
f.addMouseListener(adapterTest1);
}
}
} catch (Exception e){
throw new RuntimeException("Test failed.");
}
}
public static void initAdapters(){
adapterTest1 = new CheckingModifierAdapter(NONE);
adapterTest2 = new CheckingModifierAdapter(SHIFT);
adapterTest3 = new CheckingModifierAdapter(CTRL);
adapterTest4 = new CheckingModifierAdapter(ALT);
}
/*======================================================================*/
public static void checkPressedModifiersTest(int testModifier, MouseEvent event){
int [] curStandardModifiers = getStandardArray(testModifier);
int [] curStandardExModifiers = getStandardExArray(testModifier);
int button = event.getButton();
int modifiers = event.getModifiers();
int modifiersEx = event.getModifiersEx();
int index = (button - 1)*3;
// int index = (button - 4)*3;
dumpValues(button, modifiers, curStandardModifiers[index], modifiersEx, curStandardExModifiers[index]);
if (modifiers != curStandardModifiers[index]){
if (debug){
System.out.println("Test failed : Pressed. modifiers != modifiersStandard");
} else {
throw new RuntimeException("Test failed : Pressed. modifiers != modifiersStandard");
}
}
if (modifiersEx != curStandardExModifiers[index]){
// System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers");
if (debug){
System.out.println("Test failed : Pressed. modifiersEx != curStandardExModifiers");
} else {
throw new RuntimeException("Test failed : Pressed. modifiersEx != curStandardExModifiers");
}
}
HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
System.out.println(event.paramString());
checkButton(paramStringElements, button);
checkModifiers(testModifier, paramStringElements, button);
checkExtModifiersOnPress(testModifier, paramStringElements, button);
}
public static void checkButton(HashMap<String, String> h, int button){
if (h.get("button") == null) {
throw new RuntimeException("Test failed : Clicked. button is absent in paramString()");
}
if (Integer.parseInt(h.get("button")) != button) {
throw new RuntimeException("Test failed : Clicked. button in paramString() doesn't equal to button being pressed.");
}
}
public static void checkExtModifiersOnPress(int testModifier, HashMap h, int button){
String ethalon = "";
if (h.get("extModifiers") == null) {
System.out.println("Test failed : Pressed. extModifiers == null");
throw new RuntimeException("Test failed : Pressed. extModifiers == null");
}
switch (testModifier){
case SHIFT:{
ethalon = "Shift+";
break;
}
case ALT:{
ethalon = "Alt+";
break;
}
case CTRL:{
ethalon = "Ctrl+";
break;
}
default: {
ethalon = "";
}
ethalon = ethalon + "Button" +button;
if (!h.get("extModifiers").equals(ethalon)) {
System.out.println("Test failed : Pressed. extModifiers = " +h.get("extModifiers")+" instead of : "+ethalon);
throw new RuntimeException("Test failed : Pressed. extModifiers = " +h.get("extModifiers")+" instead of : "+ethalon);
}
}
}
public static void checkModifiers(int testModifier, HashMap<String, String> h, int button){
// none of modifiers should be null
if (h.get("modifiers") == null) {
System.out.println("Test failed : modifiers == null");
throw new RuntimeException("Test failed : modifiers == null");
}
Vector <String> modifierElements = tokenizeModifiers(h.get("modifiers"));
//check that ButtonX is there
String buttonEthalon = "Button" + button;
if (modifierElements.contains(buttonEthalon)){
modifierElements.remove(buttonEthalon);
} else {
System.out.println("Test failed : modifiers doesn't contain Button "+h.get("modifiers"));
throw new RuntimeException("Test failed : modifiers doesn't contain Button "+h.get("modifiers"));
}
//Check all explicitly pressed modifires
// boolean altIncluded = false; //don't duplicate Alt when ALT is pressed and BUTTON2_MASK.
String excplicitModifier = "";
boolean altIncluded = false;
switch (testModifier){
case SHIFT:{
excplicitModifier = "Shift";
break;
}
case ALT:{
excplicitModifier = "Alt";
altIncluded = true; //there should be only on "Alt" for two modifiers. So check it.
break;
}
case CTRL:{
excplicitModifier = "Ctrl";
break;
}
}
if (!excplicitModifier.equals("")){
if (modifierElements.contains(excplicitModifier)){
modifierElements.remove(excplicitModifier);
} else {
System.out.println("Test failed : modifiers doesn't contain explicit modifier "+excplicitModifier + " in "+ h.get("modifiers"));
throw new RuntimeException("Test failed : modifiers doesn't contain explicit modifier "+excplicitModifier + " in "+ h.get("modifiers"));
}
}
//Button 2 and 3 reports about Alt+Button2 and Meta+Button3 respectively.
//Check these values too
String extraModifiers = "";
String extraModifiersButton3 = "";
switch (button){
//BUTTON1 with ALT reports about Alt+Button1+Button2.
//We should fix this but I would not change this.
case 1: {
//Alt+Button1+Button2:
// 1) we already handled "Alt" in excplicitModifier
// 2) we already took "Button1" in buttonEthalon
// 3) so "Button2" is only remained.
// This should only happen when ALT+Button1 is pressed
if (altIncluded){
extraModifiers = "Button2";
}
break;
}
case 2: {
//Alt+Button2 report about "Alt+Button2".
extraModifiers = "Alt";
break;
}
case 3: {
//ALT+BUTTON3 reports about "Alt+Meta+Button2+Button3"
// This should only happen when ALT+Button3 is pressed
extraModifiers = "Meta";
if (altIncluded){
extraModifiersButton3 = "Button2";
}
break;
}
}//switch
if (!extraModifiers.equals("")){
if (modifierElements.contains(extraModifiers)){
modifierElements.remove(extraModifiers);
} else {
//we may already removed "Alt" when filtered explicit modifiers.
//Here is no failure in this case.
if (!altIncluded) {
System.out.println("Test failed : modifiers doesn't contain a modifier from BUTTON2 or BUTTON3 "+extraModifiers + " in "+ h.get("modifiers"));
throw new RuntimeException("Test failed : modifiers doesn't contain a modifier from BUTTON2 or BUTTON3 "+extraModifiers + " in "+ h.get("modifiers"));
}
}
}
if (!extraModifiersButton3.equals("")){
if (modifierElements.contains(extraModifiersButton3)){
modifierElements.remove(extraModifiersButton3);
} else {
System.out.println("Test failed : modifiers doesn't contain a modifier from BUTTON2 or BUTTON3 "+extraModifiersButton3 + " in "+ h.get("modifiers"));
throw new RuntimeException("Test failed : modifiers doesn't contain a modifier from BUTTON2 or BUTTON3 "+extraModifiersButton3 + " in "+ h.get("modifiers"));
}
}
//the length of vector should now be zero
if (!modifierElements.isEmpty()){
System.out.println("Test failed : there is some more elements in modifiers that shouldn't be there: "+h.get("modifiers"));
throw new RuntimeException("Test failed : there is some more elements in modifiers that shouldn't be there: "+h.get("modifiers"));
}
}
public static void checkExtModifiersOnReleaseClick(int testModifier, HashMap h, int button){
String ethalon = "";
switch (testModifier){
case SHIFT:{
ethalon = "Shift+";
break;
}
case ALT:{
ethalon = "Alt+";
break;
}
case CTRL:{
ethalon = "Ctrl+";
break;
}
default: {
if (h.get("extModifiers") != null) {
System.out.println("Test failed : Released. extModifiers != null but no modifiers keys are pressed");
throw new RuntimeException("Test failed : Released. extModifiers != null but no modifiers keys are pressed");
} else {
//no modifiers
return;
}
}
}
if (h.get("extModifiers").equals(ethalon)) {
System.out.println("Test failed : Released. extModifiers = "+ h.get("extModifiers") +" instead of : "+ethalon);
throw new RuntimeException("Test failed : Released. extModifiers = "+ h.get("extModifiers") +" instead of : "+ethalon);
}
}
public static void checkReleasedModifiersTest(int testModifier, MouseEvent event){
int [] curStandardModifiers = getStandardArray(testModifier);
int [] curStandardExModifiers = getStandardExArray(testModifier);
// int index = (button - 4)*3 + 1;
int button = event.getButton();
int modifiers = event.getModifiers();
int modifiersEx = event.getModifiersEx();
int index = (button - 1)*3 + 1;
dumpValues(button, modifiers, curStandardModifiers[index], modifiersEx, curStandardExModifiers[index]);
if (modifiers != curStandardModifiers[index]){
if (debug){
System.out.println("Test failed : Released. modifiers != modifiersStandard");
} else {
throw new RuntimeException("Test failed : Released. modifiers != modifiersStandard");
}
}
if (modifiersEx != curStandardExModifiers[index]){
if (debug){
System.out.println("Test failed : Released. modifiersEx != curStandardExModifiers");
} else {
throw new RuntimeException("Test failed : Released. modifiersEx != curStandardExModifiers");
}
}
HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
System.out.println(event.paramString());
checkButton(paramStringElements, button);
checkModifiers(testModifier, paramStringElements, button);
checkExtModifiersOnReleaseClick(testModifier, paramStringElements, button);
}
public static void checkClickedModifiersTest(int testModifier, MouseEvent event){
int [] curStandardModifiers = getStandardArray(testModifier);
int [] curStandardExModifiers = getStandardExArray(testModifier);
// int index = (button - 4)*3 + 2;
int button = event.getButton();
int modifiers = event.getModifiers();
int modifiersEx = event.getModifiersEx();
int index = (button - 1)*3 + 2;
dumpValues(button, modifiers, curStandardModifiers[index], modifiersEx, curStandardExModifiers[index]);
if (modifiers != curStandardModifiers[index]){
if (debug){
System.out.println("Test failed : Clicked. modifiers != modifiersStandard");
} else {
throw new RuntimeException("Test failed : Clicked. modifiers != modifiersStandard");
}
}
if (modifiersEx != curStandardExModifiers[index]){
if (debug){
System.out.println("Test failed : Clicked. modifiersEx != curStandardExModifiers");
} else {
throw new RuntimeException("Test failed : Clicked. modifiersEx != curStandardExModifiers");
}
}
HashMap <String, String> paramStringElements = tokenizeParamString(event.paramString());
checkButton(paramStringElements, button);
checkModifiers(testModifier, paramStringElements, button);
checkExtModifiersOnReleaseClick(testModifier, paramStringElements, button);
}
/*======================================================================*/
public static HashMap<String, String> tokenizeParamString(String param){
HashMap <String, String> params = new HashMap<String, String>();
StringTokenizer st = new StringTokenizer(param, ",=");
while (st.hasMoreTokens()){
String tmp = st.nextToken();
// System.out.println("PARSER : "+tmp);
if (tmp.equals("button") ||
tmp.equals("modifiers") ||
tmp.equals("extModifiers")) {
params.put(tmp, st.nextToken());
}
}
return params;
}
public static Vector<String> tokenizeModifiers(String modifierList){
Vector<String> modifiers = new Vector<String>();
StringTokenizer st = new StringTokenizer(modifierList, "+");
while (st.hasMoreTokens()){
String tmp = st.nextToken();
modifiers.addElement(tmp);
System.out.println("MODIFIER PARSER : "+tmp);
}
return modifiers;
}
//test BUTTON1, 2 and 3 without any modifiers keys
public static void testPlainButtons(){
System.out.println("Testing buttons without modifiers.");
f.addMouseListener(adapterTest1);
for (int button : mouseButtons){
robot.mousePress(button);
robot.delay(100);
robot.mouseRelease(button);
}
robot.delay(1000);
f.removeMouseListener(adapterTest1);
}
//test BUTTON1, 2 and 3 with SHIFT key
public static void testButtonsWithShift(){
System.out.println("Testing buttons with SHIFT modifier.");
f.addMouseListener(adapterTest2);
for (int button : mouseButtons){
robot.keyPress(KeyEvent.VK_SHIFT);
robot.mousePress(button);
robot.delay(100);
robot.mouseRelease(button);
robot.keyRelease(KeyEvent.VK_SHIFT);
}
robot.delay(1000);
f.removeMouseListener(adapterTest2);
}
//test BUTTON1, 2 and 3 with CTRL key
public static void testButtonsWithControl(){
System.out.println("Testing buttons with CONTROL modifier.");
f.addMouseListener(adapterTest3);
for (int button : mouseButtons){
robot.keyPress(KeyEvent.VK_CONTROL);
robot.mousePress(button);
robot.delay(100);
robot.mouseRelease(button);
robot.keyRelease(KeyEvent.VK_CONTROL);
}
robot.delay(1000);
f.removeMouseListener(adapterTest3);
}
//test BUTTON1, 2 and 3 with ALT key
public static void testButtonsWithAlt(){
System.out.println("Testing buttons with ALT modifier.");
f.addMouseListener(adapterTest4);
for (int button : mouseButtons){
robot.keyPress(KeyEvent.VK_ALT);
robot.mousePress(button);
robot.delay(100);
robot.mouseRelease(button);
robot.keyRelease(KeyEvent.VK_ALT);
}
robot.delay(1000);
f.removeMouseListener(adapterTest4);
}
public static void initParams(String []s){
if (s.length != 3){
autorun = true;
debug = false;
testModifier = NONE;
} else {
autorun = Boolean.valueOf(s[0]);
debug = Boolean.valueOf(s[1]);
if (s[2].equals("NONE")){
testModifier = NONE;
}
if (s[2].equals("SHIFT")){
testModifier = SHIFT;
}
if (s[2].equals("CTRL")){
testModifier = CTRL;
}
if (s[2].equals("ALT")){
testModifier = ALT;
}
}
System.out.println("Autorun : " +autorun);
System.out.println("Debug mode : " +debug);
System.out.println("Modifier to verify : " + testModifier);
}
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);
}
private static int[] getStandardExArray(int testModifier) {
int [] curStandardExModifiers;
switch (testModifier){
case SHIFT:
curStandardExModifiers = modifiersExStandardTestSHIFT;
break;
case CTRL:
curStandardExModifiers = modifiersExStandardTestCTRL;
break;
case ALT:
curStandardExModifiers = modifiersExStandardTestALT;
break;
default: //NONE by default
curStandardExModifiers = modifiersExStandardTestNONE;
}
return curStandardExModifiers;
}
private static int[] getStandardArray(int testModifier) {
int [] curStandardModifiers;
switch (testModifier){
case SHIFT:
curStandardModifiers = modifiersStandardTestSHIFT;
break;
case CTRL:
curStandardModifiers = modifiersStandardTestCTRL;
break;
case ALT:
curStandardModifiers = modifiersStandardTestALT;
break;
default: //NONE by default
curStandardModifiers = modifiersStandardTestNONE;
}
return curStandardModifiers;
}
}
/* A class that invoke appropriate verification
* routine with current modifier.
*/
class CheckingModifierAdapter extends MouseAdapter{
int modifier;
public CheckingModifierAdapter(int modifier){
this.modifier = modifier;
}
public void mousePressed(MouseEvent e) {
System.out.println("PRESSED "+e);
if (e.getButton() > MouseEvent.BUTTON3) {
System.out.println("Extra button affected. Skip.");
} else {
MouseModifiersUnitTest_Standard.checkPressedModifiersTest(modifier, e); // e.getButton(), e.getModifiers(), e.getModifiersEx(),
}
}
public void mouseReleased(MouseEvent e) {
System.out.println("RELEASED "+e);
if (e.getButton() > MouseEvent.BUTTON3) {
System.out.println("Extra button affected. Skip.");
} else {
MouseModifiersUnitTest_Standard.checkReleasedModifiersTest(modifier, e); // e.getButton(), e.getModifiers(), e.getModifiersEx()
}
}
public void mouseClicked(MouseEvent e) {
System.out.println("CLICKED "+e);
if (e.getButton() > MouseEvent.BUTTON3) {
System.out.println("Extra button affected. Skip.");
} else {
MouseModifiersUnitTest_Standard.checkClickedModifiersTest(modifier, e); //e.getButton(), e.getModifiers(), e.getModifiersEx()
}
}
}