6315717: Support for mouse with multiple scroll wheels and 4 or more buttons
Summary: implementation of the more mouse buttons support
Reviewed-by: art, dcherepanov
--- a/jdk/make/sun/xawt/mapfile-vers Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/make/sun/xawt/mapfile-vers Tue Sep 16 12:17:02 2008 +0400
@@ -151,6 +151,7 @@
Java_sun_awt_X11_XRobotPeer_mouseReleaseImpl;
Java_sun_awt_X11_XRobotPeer_mouseWheelImpl;
Java_sun_awt_X11_XRobotPeer_setup;
+ Java_sun_awt_X11_XRobotPeer_getNumberOfButtonsImpl;
Java_java_awt_Component_initIDs;
Java_java_awt_Container_initIDs;
Java_java_awt_Button_initIDs;
--- a/jdk/src/share/classes/java/awt/Robot.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/Robot.java Tue Sep 16 12:17:02 2008 +0400
@@ -70,10 +70,7 @@
private RobotPeer peer;
private boolean isAutoWaitForIdle = false;
private int autoDelay = 0;
- private static final int LEGAL_BUTTON_MASK =
- InputEvent.BUTTON1_MASK|
- InputEvent.BUTTON2_MASK|
- InputEvent.BUTTON3_MASK;
+ private static int LEGAL_BUTTON_MASK;
// location of robot's GC, used in mouseMove(), getPixelColor() and captureScreenImage()
private Point gdLoc;
@@ -98,6 +95,19 @@
}
init(GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice());
+ int tmpMask = 0;
+ if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+ for (int i = 0; i < peer.getNumberOfButtons(); i++){
+ tmpMask |= InputEvent.getMaskForButton(i+1);
+ }
+ }
+ tmpMask |= InputEvent.BUTTON1_MASK|
+ InputEvent.BUTTON2_MASK|
+ InputEvent.BUTTON3_MASK|
+ InputEvent.BUTTON1_DOWN_MASK|
+ InputEvent.BUTTON2_DOWN_MASK|
+ InputEvent.BUTTON3_DOWN_MASK;
+ LEGAL_BUTTON_MASK = tmpMask;
}
/**
@@ -187,18 +197,55 @@
/**
* Presses one or more mouse buttons. The mouse buttons should
- * be released using the <code>mouseRelease</code> method.
+ * be released using the {@link #mouseRelease(int)} method.
*
- * @param buttons the Button mask; a combination of one or more
- * of these flags:
+ * @param buttons the Button mask; a combination of one or more
+ * mouse button masks.
+ * <p>
+ * It is allowed to use only a combination of valid values as a {@code buttons} parameter.
+ * A valid combination consists of {@code InputEvent.BUTTON1_DOWN_MASK},
+ * {@code InputEvent.BUTTON2_DOWN_MASK}, {@code InputEvent.BUTTON3_DOWN_MASK}
+ * and values returned by the
+ * {@link InputEvent#getMaskForButton(int) InputEvent.getMaskForButton(button)} method.
+ *
+ * The valid combination also depends on a
+ * {@link Toolkit#areExtraMouseButtonsEnabled() Toolkit.areExtraMouseButtonsEnabled()} value as follows:
* <ul>
- * <li><code>InputEvent.BUTTON1_MASK</code>
- * <li><code>InputEvent.BUTTON2_MASK</code>
- * <li><code>InputEvent.BUTTON3_MASK</code>
+ * <li> If support for extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+ * then it is allowed to use only the following standard button masks:
+ * {@code InputEvent.BUTTON1_DOWN_MASK}, {@code InputEvent.BUTTON2_DOWN_MASK},
+ * {@code InputEvent.BUTTON3_DOWN_MASK}.
+ * <li> If support for extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
+ * then it is allowed to use the standard button masks
+ * and masks for existing extended mouse buttons, if the mouse has more then three buttons.
+ * In that way, it is allowed to use the button masks corresponding to the buttons
+ * in the range from 1 to {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}.
+ * <br>
+ * It is recommended to use the {@link InputEvent#getMaskForButton(int) InputEvent.getMaskForButton(button)}
+ * method to obtain the mask for any mouse button by its number.
* </ul>
- * @throws IllegalArgumentException if the button mask is not a
- * valid combination
+ * <p>
+ * The following standard button masks are also accepted:
+ * <ul>
+ * <li>{@code InputEvent.BUTTON1_MASK}
+ * <li>{@code InputEvent.BUTTON2_MASK}
+ * <li>{@code InputEvent.BUTTON3_MASK}
+ * </ul>
+ * However, it is recommended to use {@code InputEvent.BUTTON1_DOWN_MASK},
+ * {@code InputEvent.BUTTON2_DOWN_MASK}, {@code InputEvent.BUTTON3_DOWN_MASK} instead.
+ * Either extended {@code _DOWN_MASK} or old {@code _MASK} values
+ * should be used, but both those models should not be mixed.
+ * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button
+ * and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+ * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button
+ * that does not exist on the mouse and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
* @see #mouseRelease(int)
+ * @see InputEvent#getMaskForButton(int)
+ * @see Toolkit#areExtraMouseButtonsEnabled()
+ * @see java.awt.MouseInfo#getNumberOfButtons()
+ * @see java.awt.event.MouseEvent
*/
public synchronized void mousePress(int buttons) {
checkButtonsArgument(buttons);
@@ -209,16 +256,53 @@
/**
* Releases one or more mouse buttons.
*
- * @param buttons the Button mask; a combination of one or more
- * of these flags:
+ * @param buttons the Button mask; a combination of one or more
+ * mouse button masks.
+ * <p>
+ * It is allowed to use only a combination of valid values as a {@code buttons} parameter.
+ * A valid combination consists of {@code InputEvent.BUTTON1_DOWN_MASK},
+ * {@code InputEvent.BUTTON2_DOWN_MASK}, {@code InputEvent.BUTTON3_DOWN_MASK}
+ * and values returned by the
+ * {@link InputEvent#getMaskForButton(int) InputEvent.getMaskForButton(button)} method.
+ *
+ * The valid combination also depends on a
+ * {@link Toolkit#areExtraMouseButtonsEnabled() Toolkit.areExtraMouseButtonsEnabled()} value as follows:
* <ul>
- * <li><code>InputEvent.BUTTON1_MASK</code>
- * <li><code>InputEvent.BUTTON2_MASK</code>
- * <li><code>InputEvent.BUTTON3_MASK</code>
+ * <li> If the support for extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+ * then it is allowed to use only the following standard button masks:
+ * {@code InputEvent.BUTTON1_DOWN_MASK}, {@code InputEvent.BUTTON2_DOWN_MASK},
+ * {@code InputEvent.BUTTON3_DOWN_MASK}.
+ * <li> If the support for extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
+ * then it is allowed to use the standard button masks
+ * and masks for existing extended mouse buttons, if the mouse has more then three buttons.
+ * In that way, it is allowed to use the button masks corresponding to the buttons
+ * in the range from 1 to {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}.
+ * <br>
+ * It is recommended to use the {@link InputEvent#getMaskForButton(int) InputEvent.getMaskForButton(button)}
+ * method to obtain the mask for any mouse button by its number.
* </ul>
+ * <p>
+ * The following standard button masks are also accepted:
+ * <ul>
+ * <li>{@code InputEvent.BUTTON1_MASK}
+ * <li>{@code InputEvent.BUTTON2_MASK}
+ * <li>{@code InputEvent.BUTTON3_MASK}
+ * </ul>
+ * However, it is recommended to use {@code InputEvent.BUTTON1_DOWN_MASK},
+ * {@code InputEvent.BUTTON2_DOWN_MASK}, {@code InputEvent.BUTTON3_DOWN_MASK} instead.
+ * Either extended {@code _DOWN_MASK} or old {@code _MASK} values
+ * should be used, but both those models should not be mixed.
+ * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button
+ * and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+ * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button
+ * that does not exist on the mouse and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
* @see #mousePress(int)
- * @throws IllegalArgumentException if the button mask is not a valid
- * combination
+ * @see InputEvent#getMaskForButton(int)
+ * @see Toolkit#areExtraMouseButtonsEnabled()
+ * @see java.awt.MouseInfo#getNumberOfButtons()
+ * @see java.awt.event.MouseEvent
*/
public synchronized void mouseRelease(int buttons) {
checkButtonsArgument(buttons);
--- a/jdk/src/share/classes/java/awt/Toolkit.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/Toolkit.java Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1995-2008 Sun Microsystems, Inc. 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
@@ -2550,4 +2550,37 @@
}
}
}
+
+ /**
+ * Reports whether events from extra mouse buttons are allowed to be processed and posted into
+ * {@code EventQueue}.
+ * <br>
+ * To change the returned value it is necessary to set the {@code sun.awt.enableExtraMouseButtons}
+ * property before the {@code Toolkit} class initialization. This setting could be done on the application
+ * startup by the following command:
+ * <pre>
+ * java -Dsun.awt.enableExtraMouseButtons=false Application
+ * </pre>
+ * Alternatively, the property could be set in the application by using the following code:
+ * <pre>
+ * System.setProperty("sun.awt.enableExtraMouseButtons", "true");
+ * </pre>
+ * before the {@code Toolkit} class initialization.
+ * If not set by the time of the {@code Toolkit} class initialization, this property will be
+ * initialized with {@code true}.
+ * Changing this value after the {@code Toolkit} class initialization will have no effect.
+ * <p>
+ * The current value could be queried by using the
+ * {@code System.getProperty("sun.awt.enableExtraMouseButtons")} method.
+ * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
+ * @return {@code true} if events from extra mouse buttons are allowed to be processed and posted;
+ * {@code false} otherwise
+ * @see System#getProperty(String propertyName)
+ * @see System#setProperty(String propertyName, String value)
+ * @see java.awt.EventQueue
+ * @since 1.7
+ */
+ public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
+ return Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled();
+ }
}
--- a/jdk/src/share/classes/java/awt/doc-files/DesktopProperties.html Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/doc-files/DesktopProperties.html Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
<!--
- Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
+ Copyright 2005-2008 Sun Microsystems, Inc. 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
@@ -64,6 +64,11 @@
<td valign="TOP"><a href="../../util/Map.html">java.util.Map<a/></td>
<td valign="TOP">Font smoothing (text antialiasing) settings.<a/></td>
</tr>
+<tr>
+<td valign="TOP"><A href=#"sun.awt.enableExtraMouseButtons">sun.awt.enableExtraMouseButtons</A</td>
+<td valign="TOP"><a href="../../lang/Boolean.html">java.lang.Boolean<a/></td>
+<td valign="TOP">Controls if mouse events from extra buttons are to be generated or not<a/></td>
+</tr>
</table>
<p>
<h2>Desktop Font Rendering Hints</h2>
@@ -219,5 +224,50 @@
determine that there is a non-null return for any screen device using
the per-device property name.
</ul>
+<h2>Mouse Functionality</h2>
+<b>Desktop Property: <A name="sun.awt.enableExtraMouseButtons">"sun.awt.enableExtraMouseButtons"</A></b>
+<p>
+This property determines if events from extra mouse buttons (if they are exist and are
+enabled by the underlying operating system) are allowed to be processed and posted into
+{@code EventQueue}.
+<br>
+The value could be changed by passing "sun.awt.enableExtraMouseButtons"
+property value into java before application starts. This could be done with the following command:
+<pre>
+java -Dsun.awt.enableExtraMouseButtons=false Application
+</pre>
+Once set on application startup, it is impossible to change this value after.
+<br>
+Current value could also be queried using getDesktopProperty("sun.awt.enableExtraMouseButtons")
+method.
+<br>
+If the property is set to {@code true} then
+<ul>
+<li> it is still legal to create {@code MouseEvent} objects with
+standard buttons and, if the mouse has more
+then three buttons, it is also legal to use buttons from the range started
+from 0 up to {@link java.awt.MouseInfo#getNumberOfButtons() getNumberOfButtons()}.
+
+<li> it is legal to use standard button masks when using {@code Robot.mousePress()}
+and {@code Robot.mouseRelease()} methods and, if the mouse has more then three buttons,
+it is also legal to use masks for existing extended mouse buttons.
+That way, if there are more then three buttons on the mouse then it is allowed to
+use button masks corresponding to the buttons
+in the range from 1 up to {@link java.awt.MouseInfo#getNumberOfButtons() getNumberOfButtons()}
+</ul>
+<br>
+If the property is set to {@code false} then
+<ul>
+<li> it is legal to create {@code MouseEvent} objects with standard buttons
+only: {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2} and
+{@code BUTTON3}
+<li> it is legal to use standard button masks only:
+{@code InputEvent.BUTTON1_DOWN_MASK}, {@code InputEvent.BUTTON2_DOWN_MASK},
+{@code InputEvent.BUTTON3_DOWN_MASK}
+</ul>
+
+This property should be used when there is no need in listening mouse events fired as a result of
+activity with extra mouse button.
+By default this property is set to {@code true}.
</body>
</html>
--- a/jdk/src/share/classes/java/awt/event/InputEvent.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/event/InputEvent.java Tue Sep 16 12:17:02 2008 +0400
@@ -31,6 +31,7 @@
import java.awt.Toolkit;
import java.util.logging.Logger;
import java.util.logging.Level;
+import java.util.Arrays;
/**
* The root event class for all component-level input events.
@@ -153,13 +154,93 @@
*/
public static final int ALT_GRAPH_DOWN_MASK = 1 << 13;
+ /**
+ * An array of extended modifiers for additional buttons.
+ * @see getButtonDownMasks
+ * @since 7.0
+ */
+ private static final int [] BUTTON_DOWN_MASK = new int [] { BUTTON1_DOWN_MASK,
+ BUTTON2_DOWN_MASK,
+ BUTTON3_DOWN_MASK,
+ 1<<14, //4th phisical button (this is not a wheel!)
+ 1<<15, //(this is not a wheel!)
+ 1<<16,
+ 1<<17,
+ 1<<18,
+ 1<<19,
+ 1<<20,
+ 1<<21 };
+
+ /**
+ * A method to access an array of extended modifiers for additional buttons.
+ * @since 7.0
+ */
+ private static int [] getButtonDownMasks(){
+ return Arrays.copyOf(BUTTON_DOWN_MASK, BUTTON_DOWN_MASK.length);
+ }
+
+
+ /**
+ * A method to obtain a mask for any existing mouse button.
+ * The returned mask may be used for different purposes. Following are some of them:
+ * <ul>
+ * <li> {@link java.awt.Robot#mousePress(int) mousePress(buttons)} and
+ * {@link java.awt.Robot#mouseRelease(int) mouseRelease(buttons)}
+ * <li> as a {@code modifiers} parameter when creating a new {@link MouseEvent} instance
+ * <li> to check {@link MouseEvent#getModifiersEx() modifiersEx} of existing {@code MouseEvent}
+ * </ul>
+ * @param button is a number to represent a button starting from 1.
+ * For example,
+ * <pre>
+ * int button = InputEvent.getMaskForButton(1);
+ * </pre>
+ * will have the same meaning as
+ * <pre>
+ * int button = InputEvent.getMaskForButton(MouseEvent.BUTTON1);
+ * </pre>
+ * because {@link MouseEvent#BUTTON1 MouseEvent.BUTTON1} equals to 1.
+ * If a mouse has three enabled buttons(see {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()})
+ * then the values from the left column passed into the method will return
+ * corresponding values from the right column:
+ * <PRE>
+ * <b>button </b> <b>returned mask</b>
+ * {@link MouseEvent#BUTTON1 BUTTON1} {@link MouseEvent#BUTTON1_DOWN_MASK BUTTON1_DOWN_MASK}
+ * {@link MouseEvent#BUTTON2 BUTTON2} {@link MouseEvent#BUTTON2_DOWN_MASK BUTTON2_DOWN_MASK}
+ * {@link MouseEvent#BUTTON3 BUTTON3} {@link MouseEvent#BUTTON3_DOWN_MASK BUTTON3_DOWN_MASK}
+ * </PRE>
+ * If a mouse has more than three enabled buttons then more values
+ * are admissible (4, 5, etc.). There is no assigned constants for these extended buttons.
+ * The button masks for the extra buttons returned by this method have no assigned names like the
+ * first three button masks.
+ * <p>
+ * This method has the following implementation restriction.
+ * It returns masks for a limited number of buttons only. The maximum number is
+ * implementation dependent and may vary.
+ * This limit is defined by the relevant number
+ * of buttons that may hypothetically exist on the mouse but it is greater than the
+ * {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}.
+ * <p>
+ * @throws IllegalArgumentException if {@code button} is less than zero or greater than the number
+ * of button masks reserved for buttons
+ * @since 7.0
+ * @see java.awt.MouseInfo#getNumberOfButtons()
+ * @see Toolkit#areExtraMouseButtonsEnabled()
+ * @see MouseEvent#getModifiers()
+ * @see MouseEvent#getModifiersEx()
+ */
+ public static int getMaskForButton(int button) {
+ if (button <= 0 || button > BUTTON_DOWN_MASK.length) {
+ throw new IllegalArgumentException("button doesn\'t exist " + button);
+ }
+ return BUTTON_DOWN_MASK[button - 1];
+ }
+
// the constant below MUST be updated if any extra modifier
// bits are to be added!
// in fact, it is undesirable to add modifier bits
// to the same field as this may break applications
// see bug# 5066958
-
- static final int FIRST_HIGH_BIT = 1 << 14;
+ static final int FIRST_HIGH_BIT = 1 << 22;
static final int JDK_1_3_MODIFIERS = SHIFT_DOWN_MASK - 1;
static final int HIGH_MODIFIERS = ~( FIRST_HIGH_BIT - 1 );
@@ -382,7 +463,7 @@
* cause the returning an empty string.
*
* @param modifiers a modifier mask describing the extended
- * modifier keys and mouse buttons for the event
+ * modifier keys and mouse buttons for the event
* @return a text description of the combination of extended
* modifier keys and mouse buttons that were held down
* during the event.
@@ -410,17 +491,14 @@
buf.append(Toolkit.getProperty("AWT.altGraph", "Alt Graph"));
buf.append("+");
}
- if ((modifiers & InputEvent.BUTTON1_DOWN_MASK) != 0) {
- buf.append(Toolkit.getProperty("AWT.button1", "Button1"));
- buf.append("+");
- }
- if ((modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0) {
- buf.append(Toolkit.getProperty("AWT.button2", "Button2"));
- buf.append("+");
- }
- if ((modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0) {
- buf.append(Toolkit.getProperty("AWT.button3", "Button3"));
- buf.append("+");
+
+ int buttonNumber = 1;
+ for (int mask : InputEvent.BUTTON_DOWN_MASK){
+ if ((modifiers & mask) != 0) {
+ buf.append(Toolkit.getProperty("AWT.button"+buttonNumber, "Button"+buttonNumber));
+ buf.append("+");
+ }
+ buttonNumber++;
}
if (buf.length() > 0) {
buf.setLength(buf.length()-1); // remove trailing '+'
--- a/jdk/src/share/classes/java/awt/event/MouseEvent.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/event/MouseEvent.java Tue Sep 16 12:17:02 2008 +0400
@@ -32,6 +32,7 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.awt.IllegalComponentStateException;
+import java.awt.MouseInfo;
/**
* An event which indicates that a mouse action occurred in a component.
@@ -135,7 +136,15 @@
* for <code>BUTTON2_MASK</code> arrives first,
* followed by the pair for <code>BUTTON1_MASK</code>.
* <p>
- *
+ * Some extra mouse buttons are added to extend the standard set of buttons
+ * represented by the following constants:{@code BUTTON1}, {@code BUTTON2}, and {@code BUTTON3}.
+ * Extra buttons have no assigned {@code BUTTONx}
+ * constants as well as their button masks have no assigned {@code BUTTONx_DOWN_MASK}
+ * constants. Nevertheless, ordinal numbers starting from 4 may be
+ * used as button numbers (button ids). Values obtained by the
+ * {@link InputEvent#getMaskForButton(int) getMaskForButton(button)} method may be used
+ * as button masks.
+ * <p>
* <code>MOUSE_DRAGGED</code> events are delivered to the <code>Component</code>
* in which the mouse button was pressed until the mouse button is released
* (regardless of whether the mouse position is within the bounds of the
@@ -324,13 +333,31 @@
/**
* Indicates which, if any, of the mouse buttons has changed state.
*
- * The only legal values are the following constants:
- * <code>NOBUTTON</code>,
- * <code>BUTTON1</code>,
- * <code>BUTTON2</code> or
- * <code>BUTTON3</code>.
+ * The valid values are ranged from 0 to the value returned by the
+ * {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()} method.
+ * This range already includes constants {@code NOBUTTON}, {@code BUTTON1},
+ * {@code BUTTON2}, and {@code BUTTON3}
+ * if these buttons are present. So it is allowed to use these constants too.
+ * For example, for a mouse with two buttons this field may contain the following values:
+ * <ul>
+ * <li> 0 ({@code NOBUTTON})
+ * <li> 1 ({@code BUTTON1})
+ * <li> 2 ({@code BUTTON2})
+ * </ul>
+ * If a mouse has 5 buttons, this field may contain the following values:
+ * <ul>
+ * <li> 0 ({@code NOBUTTON})
+ * <li> 1 ({@code BUTTON1})
+ * <li> 2 ({@code BUTTON2})
+ * <li> 3 ({@code BUTTON3})
+ * <li> 4
+ * <li> 5
+ * </ul>
+ * If support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled()} disabled by Java
+ * then the field may not contain the value larger than {@code BUTTON3}.
* @serial
- * @see #getButton().
+ * @see #getButton()
+ * @see java.awt.Toolkit#areExtraMouseButtonsEnabled()
*/
int button;
@@ -385,6 +412,15 @@
}
/**
+ * A number of buttons available on the mouse at the {@code Toolkit} machinery startup.
+ */
+ private static int cachedNumberOfButtons;
+
+ static {
+ cachedNumberOfButtons = MouseInfo.getNumberOfButtons();
+ }
+
+ /**
* Returns the absolute horizontal x position of the event.
* In a virtual device multi-screen environment in which the
* desktop area could span multiple physical screen devices,
@@ -421,7 +457,8 @@
/**
* Constructs a <code>MouseEvent</code> object with the
* specified source component,
- * type, modifiers, coordinates, and click count.
+ * type, time, modifiers, coordinates, click count, popupTrigger flag,
+ * and button number.
* <p>
* Creating an invalid event (such
* as by using more than one of the old _MASKs, or modifier/button
@@ -464,7 +501,33 @@
* @param popupTrigger A boolean that equals {@code true} if this event
* is a trigger for a popup menu
* @param button An integer that indicates, which of the mouse buttons has
- * changed its state
+ * changed its state.
+ * The following rules are applied to this parameter:
+ * <ul>
+ * <li>If support for the extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+ * then it is allowed to create {@code MouseEvent} objects only with the standard buttons:
+ * {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2}, and
+ * {@code BUTTON3}.
+ * <li> If support for the extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
+ * then it is allowed to create {@code MouseEvent} objects with
+ * the standard buttons.
+ * In case the support for extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java, then
+ * in addition to the standard buttons, {@code MouseEvent} objects can be created
+ * using buttons from the range starting from 4 to
+ * {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}
+ * if the mouse has more than three buttons.
+ * </ul>
+ * @throws IllegalArgumentException if {@code button} is less then zero
+ * @throws IllegalArgumentException if <code>source</code> is null
+ * @throws IllegalArgumentException if {@code button} is greater then BUTTON3 and the support for extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+ * @throws IllegalArgumentException if {@code button} is greater then the
+ * {@link java.awt.MouseInfo#getNumberOfButtons() current number of buttons} and the support
+ * for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled}
+ * by Java
* @throws IllegalArgumentException if an invalid <code>button</code>
* value is passed in
* @throws IllegalArgumentException if <code>source</code> is null
@@ -498,7 +561,7 @@
/**
* Constructs a <code>MouseEvent</code> object with the
* specified source component,
- * type, modifiers, coordinates, and click count.
+ * type, modifiers, coordinates, click count, and popupTrigger flag.
* An invocation of the form
* <tt>MouseEvent(source, id, when, modifiers, x, y, clickCount, popupTrigger)</tt>
* behaves in exactly the same way as the invocation
@@ -551,10 +614,26 @@
}
+ /* if the button is an extra button and it is released or clicked then in Xsystem its state
+ is not modified. Exclude this button number from ExtModifiers mask.*/
+ transient private boolean shouldExcludeButtonFromExtModifiers = false;
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getModifiersEx() {
+ int tmpModifiers = modifiers;
+ if (shouldExcludeButtonFromExtModifiers) {
+ tmpModifiers &= ~(InputEvent.getMaskForButton(getButton()));
+ }
+ return tmpModifiers & ~JDK_1_3_MODIFIERS;
+ }
+
/**
* Constructs a <code>MouseEvent</code> object with the
* specified source component,
- * type, modifiers, coordinates, absolute coordinates, and click count.
+ * type, time, modifiers, coordinates, absolute coordinates, click count, popupTrigger flag,
+ * and button number.
* <p>
* Creating an invalid event (such
* as by using more than one of the old _MASKs, or modifier/button
@@ -595,7 +674,33 @@
* @param popupTrigger A boolean that equals {@code true} if this event
* is a trigger for a popup menu
* @param button An integer that indicates, which of the mouse buttons has
- * changed its state
+ * changed its state.
+ * The following rules are applied to this parameter:
+ * <ul>
+ * <li>If support for the extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+ * then it is allowed to create {@code MouseEvent} objects only with the standard buttons:
+ * {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2}, and
+ * {@code BUTTON3}.
+ * <li> If support for the extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java
+ * then it is allowed to create {@code MouseEvent} objects with
+ * the standard buttons.
+ * In case the support for extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java, then
+ * in addition to the standard buttons, {@code MouseEvent} objects can be created
+ * using buttons from the range starting from 4 to
+ * {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}
+ * if the mouse has more than three buttons.
+ * </ul>
+ * @throws IllegalArgumentException if {@code button} is less then zero
+ * @throws IllegalArgumentException if <code>source</code> is null
+ * @throws IllegalArgumentException if {@code button} is greater then BUTTON3 and the support for extended mouse buttons is
+ * {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+ * @throws IllegalArgumentException if {@code button} is greater then the
+ * {@link java.awt.MouseInfo#getNumberOfButtons() current number of buttons} and the support
+ * for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled}
+ * by Java
* @throws IllegalArgumentException if an invalid <code>button</code>
* value is passed in
* @throws IllegalArgumentException if <code>source</code> is null
@@ -610,6 +715,10 @@
* @see #getClickCount()
* @see #isPopupTrigger()
* @see #getButton()
+ * @see #button
+ * @see Toolkit#areExtraMouseButtonsEnabled()
+ * @see java.awt.MouseInfo#getNumberOfButtons()
+ * @see InputEvent#getMaskForButton(int)
* @since 1.6
*/
public MouseEvent(Component source, int id, long when, int modifiers,
@@ -623,14 +732,41 @@
this.yAbs = yAbs;
this.clickCount = clickCount;
this.popupTrigger = popupTrigger;
- if (button < NOBUTTON || button >BUTTON3) {
- throw new IllegalArgumentException("Invalid button value");
+ if (button < NOBUTTON){
+ throw new IllegalArgumentException("Invalid button value :" + button);
}
+ //TODO: initialize MouseInfo.cachedNumber on toolkit creation.
+ if (button > BUTTON3) {
+ if (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+ throw new IllegalArgumentException("Extra mouse events are disabled " + button);
+ } else {
+ if (button > cachedNumberOfButtons) {
+ throw new IllegalArgumentException("Nonexistent button " + button);
+ }
+ }
+ // XToolkit: extra buttons are not reporting about their state correctly.
+ // Being pressed they report the state=0 both on the press and on the release.
+ // For 1-3 buttons the state value equals zero on press and non-zero on release.
+ // Other modifiers like Shift, ALT etc seem report well with extra buttons.
+ // The problem reveals as follows: one button is pressed and then another button is pressed and released.
+ // So, the getModifiersEx() would not be zero due to a first button and we will skip this modifier.
+ // This may have to be moved into the peer code instead if possible.
+
+ if (getModifiersEx() != 0) { //There is at least one more button in a pressed state.
+ if (id == MouseEvent.MOUSE_RELEASED || id == MouseEvent.MOUSE_CLICKED){
+ System.out.println("MEvent. CASE!");
+ shouldExcludeButtonFromExtModifiers = true;
+ }
+ }
+ }
+
this.button = button;
+
if ((getModifiers() != 0) && (getModifiersEx() == 0)) {
setNewModifiers();
} else if ((getModifiers() == 0) &&
- (getModifiersEx() != 0 || button != NOBUTTON))
+ (getModifiersEx() != 0 || button != NOBUTTON) &&
+ (button <= BUTTON3))
{
setOldModifiers();
}
@@ -701,13 +837,55 @@
/**
* Returns which, if any, of the mouse buttons has changed state.
+ * The returned value is ranged
+ * from 0 to the {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}
+ * value.
+ * The returned value includes at least the following constants:
+ * <ul>
+ * <li> {@code NOBUTTON}
+ * <li> {@code BUTTON1}
+ * <li> {@code BUTTON2}
+ * <li> {@code BUTTON3}
+ * </ul>
+ * It is allowed to use those constants to compare with the returned button number in the application.
+ * For example,
+ * <pre>
+ * if (anEvent.getButton() == MouseEvent.BUTTON1) {
+ * </pre>
+ * In particular, for a mouse with one, two, or three buttons this method may return the following values:
+ * <ul>
+ * <li> 0 ({@code NOBUTTON})
+ * <li> 1 ({@code BUTTON1})
+ * <li> 2 ({@code BUTTON2})
+ * <li> 3 ({@code BUTTON3})
+ * </ul>
+ * Button numbers greater then {@code BUTTON3} have no constant identifier. So if a mouse with five buttons is
+ * installed, this method may return the following values:
+ * <ul>
+ * <li> 0 ({@code NOBUTTON})
+ * <li> 1 ({@code BUTTON1})
+ * <li> 2 ({@code BUTTON2})
+ * <li> 3 ({@code BUTTON3})
+ * <li> 4
+ * <li> 5
+ * </ul>
+ * <p>
+ * Note: If support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
+ * then the AWT event subsystem does not produce mouse events for the extended mouse
+ * buttons. So it is not expected that this method returns anything except {@code NOBUTTON}, {@code BUTTON1},
+ * {@code BUTTON2}, {@code BUTTON3}.
*
- * @return one of the following constants:
- * <code>NOBUTTON</code>,
- * <code>BUTTON1</code>,
- * <code>BUTTON2</code> or
- * <code>BUTTON3</code>.
+ * @return one of the values from 0 to {@link java.awt.MouseInfo#getNumberOfButtons() MouseInfo.getNumberOfButtons()}
+ * if support for the extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java.
+ * That range includes {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2}, {@code BUTTON3};
+ * <br>
+ * {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2} or {@code BUTTON3}
+ * if support for the extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
* @since 1.4
+ * @see Toolkit#areExtraMouseButtonsEnabled()
+ * @see java.awt.MouseInfo#getNumberOfButtons()
+ * @see #MouseEvent(Component, int, long, int, int, int, int, int, int, boolean, int)
+ * @see InputEvent#getMaskForButton(int)
*/
public int getButton() {
return button;
@@ -746,7 +924,7 @@
* and will cause the returning an unspecified string.
* Zero parameter means that no modifiers were passed and will
* cause the returning an empty string.
- *
+ * <p>
* @param modifiers A modifier mask describing the modifier keys and
* mouse buttons that were down during the event
* @return string string text description of the combination of modifier
@@ -788,6 +966,24 @@
buf.append(Toolkit.getProperty("AWT.button3", "Button3"));
buf.append("+");
}
+
+ int mask;
+
+ // TODO: add a toolkit field that holds a number of button on the mouse.
+ // As the method getMouseModifiersText() is static and obtain
+ // an integer as a parameter then we may not restrict this with the number
+ // of buttons installed on the mouse.
+ // It's a temporary solution. We need to somehow hold the number of buttons somewhere else.
+ for (int i = 1; i <= cachedNumberOfButtons; i++){
+ mask = InputEvent.getMaskForButton(i);
+ if ((modifiers & mask) != 0 &&
+ buf.indexOf(Toolkit.getProperty("AWT.button"+i, "Button"+i)) == -1) //1,2,3 buttons may already be there; so don't duplicate it.
+ {
+ buf.append(Toolkit.getProperty("AWT.button"+i, "Button"+i));
+ buf.append("+");
+ }
+ }
+
if (buf.length() > 0) {
buf.setLength(buf.length()-1); // remove trailing '+'
}
@@ -836,14 +1032,18 @@
str.append(",(").append(x).append(",").append(y).append(")");
str.append(",absolute(").append(xAbs).append(",").append(yAbs).append(")");
- str.append(",button=").append(getButton());
+ if (id != MOUSE_DRAGGED && id != MOUSE_MOVED){
+ str.append(",button=").append(getButton());
+ }
if (getModifiers() != 0) {
str.append(",modifiers=").append(getMouseModifiersText(modifiers));
}
if (getModifiersEx() != 0) {
- str.append(",extModifiers=").append(getModifiersExText(modifiers));
+ //Using plain "modifiers" here does show an excluded extended buttons in the string event representation.
+ //getModifiersEx() solves the problem.
+ str.append(",extModifiers=").append(getModifiersExText(getModifiersEx()));
}
str.append(",clickCount=").append(clickCount);
--- a/jdk/src/share/classes/java/awt/peer/RobotPeer.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/java/awt/peer/RobotPeer.java Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc. 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
@@ -52,4 +52,5 @@
public int [] getRGBPixels(Rectangle bounds);
public void dispose();
+ public int getNumberOfButtons();
}
--- a/jdk/src/share/classes/sun/awt/HeadlessToolkit.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/share/classes/sun/awt/HeadlessToolkit.java Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc. 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
@@ -468,4 +468,8 @@
throws HeadlessException{
throw new HeadlessException();
}
+
+ public boolean areExtraMouseButtonsEnabled() throws HeadlessException{
+ throw new HeadlessException();
+ }
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java Tue Sep 16 12:17:02 2008 +0400
@@ -979,8 +979,13 @@
*/
public void handleButtonPressRelease(XEvent xev) {
XButtonEvent xbe = xev.get_xbutton();
- final int buttonState = xbe.get_state() & (XConstants.Button1Mask | XConstants.Button2Mask
- | XConstants.Button3Mask | XConstants.Button4Mask | XConstants.Button5Mask);
+ int buttonState = 0;
+ for (int i = 0; i<XToolkit.getNumMouseButtons(); i++){
+ // A bug in WM implementation: extra buttons doesn't have state!=0 as they should on Release message.
+ if ((i != 4) && (i != 5)){
+ buttonState |= (xbe.get_state() & XConstants.buttonsMask[i]);
+ }
+ }
switch (xev.get_type()) {
case XConstants.ButtonPress:
if (buttonState == 0) {
@@ -1011,19 +1016,11 @@
* Checks ButtonRelease released all Mouse buttons
*/
static boolean isFullRelease(int buttonState, int button) {
- switch (button) {
- case XConstants.Button1:
- return buttonState == XConstants.Button1Mask;
- case XConstants.Button2:
- return buttonState == XConstants.Button2Mask;
- case XConstants.Button3:
- return buttonState == XConstants.Button3Mask;
- case XConstants.Button4:
- return buttonState == XConstants.Button4Mask;
- case XConstants.Button5:
- return buttonState == XConstants.Button5Mask;
+ if (button < 0 || button > XToolkit.getNumMouseButtons()) {
+ return buttonState == 0;
+ } else {
+ return buttonState == XConstants.buttonsMask[button - 1];
}
- return buttonState == 0;
}
static boolean isGrabbedEvent(XEvent ev, XBaseWindow target) {
--- a/jdk/src/solaris/classes/sun/awt/X11/XConstants.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XConstants.java Tue Sep 16 12:17:02 2008 +0400
@@ -197,12 +197,30 @@
/* button masks. Used in same manner as Key masks above. Not to be confused
with button names below. */
-
- public static final int Button1Mask = (1<<8) ;
- public static final int Button2Mask = (1<<9) ;
- public static final int Button3Mask = (1<<10) ;
- public static final int Button4Mask = (1<<11) ;
- public static final int Button5Mask = (1<<12) ;
+ public static final int [] buttonsMask = new int []{ 1<<8,
+ 1<<9,
+ 1<<10,
+ 1<<11,
+ 1<<12,
+ 1<<13,
+ 1<<14,
+ 1<<15,
+ 1<<16,
+ 1<<17,
+ 1<<18,
+ 1<<19,
+ 1<<20,
+ 1<<21,
+ 1<<22,
+ 1<<23,
+ 1<<24,
+ 1<<25,
+ 1<<26,
+ 1<<27,
+ 1<<28,
+ 1<<29,
+ 1<<30,
+ 1<<31 };
public static final int AnyModifier = (1<<15) ; /* used in GrabButton, GrabKey */
@@ -211,11 +229,7 @@
and ButtonRelease events. Not to be confused with button masks above.
Note that 0 is already defined above as "AnyButton". */
- public static final int Button1 = 1 ;
- public static final int Button2 = 2 ;
- public static final int Button3 = 3 ;
- public static final int Button4 = 4 ;
- public static final int Button5 = 5 ;
+ public static final int buttons [] = new int [] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
/* Notify modes */
--- a/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java Tue Sep 16 12:17:02 2008 +0400
@@ -694,8 +694,8 @@
} finally {
xmotion.dispose();
}
- if (xbutton.get_button() == XConstants.Button1
- || xbutton.get_button() == XConstants.Button2) {
+ if (xbutton.get_button() == XConstants.buttons[0]
+ || xbutton.get_button() == XConstants.buttons[1]) {
// drag is initiated with Button1 or Button2 pressed and
// ended on release of either of these buttons (as the same
// behavior was with our old Motif DnD-based implementation)
--- a/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc. 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
@@ -81,11 +81,16 @@
return pixelArray;
}
+ public int getNumberOfButtons(){
+ return getNumberOfButtonsImpl();
+ }
+
private static native synchronized void setup();
private static native synchronized void mouseMoveImpl(X11GraphicsConfig xgc, int x, int y);
private static native synchronized void mousePressImpl(int buttons);
private static native synchronized void mouseReleaseImpl(int buttons);
+ private static native synchronized int getNumberOfButtonsImpl();
private static native synchronized void mouseWheelImpl(int wheelAmt);
private static native synchronized void keyPressImpl(int keycode);
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Tue Sep 16 12:17:02 2008 +0400
@@ -74,6 +74,10 @@
// Dynamic Layout Resize client code setting
protected static boolean dynamicLayoutSetting = false;
+ //Is it allowed to generate events assigned to extra mouse buttons.
+ //Set to true by default.
+ private static boolean areExtraMouseButtonsEnabled = true;
+
/**
* True when the x settings have been loaded.
*/
@@ -273,6 +277,9 @@
arrowCursor = XlibWrapper.XCreateFontCursor(XToolkit.getDisplay(),
XCursorFontConstants.XC_arrow);
+ areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
+ //set system property if not yet assigned
+ System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
} finally {
awtUnlock();
}
@@ -1383,7 +1390,7 @@
}
}
- private int getNumMouseButtons() {
+ public static int getNumMouseButtons() {
awtLock();
try {
return XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), 0, 0);
@@ -2166,4 +2173,8 @@
}
public static native void setNoisyXErrorHandler();
+
+ public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
+ return areExtraMouseButtonsEnabled;
+ }
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Tue Sep 16 12:17:02 2008 +0400
@@ -553,6 +553,10 @@
}
static int getModifiers(int state, int button, int keyCode) {
+ return getModifiers(state, button, keyCode, 0, false);
+ }
+
+ static int getModifiers(int state, int button, int keyCode, int type, boolean wheel_mouse) {
int modifiers = 0;
if (((state & XConstants.ShiftMask) != 0) ^ (keyCode == KeyEvent.VK_SHIFT)) {
@@ -570,14 +574,23 @@
if (((state & XToolkit.modeSwitchMask) != 0) ^ (keyCode == KeyEvent.VK_ALT_GRAPH)) {
modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
}
- if (((state & XConstants.Button1Mask) != 0) ^ (button == MouseEvent.BUTTON1)) {
- modifiers |= InputEvent.BUTTON1_DOWN_MASK;
- }
- if (((state & XConstants.Button2Mask) != 0) ^ (button == MouseEvent.BUTTON2)) {
- modifiers |= InputEvent.BUTTON2_DOWN_MASK;
- }
- if (((state & XConstants.Button3Mask) != 0) ^ (button == MouseEvent.BUTTON3)) {
- modifiers |= InputEvent.BUTTON3_DOWN_MASK;
+ //InputEvent.BUTTON_DOWN_MASK array is starting from BUTTON1_DOWN_MASK on index == 0.
+ // button currently reflects a real button number and starts from 1. (except NOBUTTON which is zero )
+
+ /* this is an attempt to refactor button IDs in : MouseEvent, InputEvent, XlibWrapper and XWindow.*/
+
+ //reflects a button number similar to MouseEvent.BUTTON1, 2, 3 etc.
+ for (int i = 0; i < XConstants.buttonsMask.length; i ++){
+ //modifier should be added if :
+ // 1) current button is now still in PRESSED state (means that user just pressed mouse but not released yet) or
+ // 2) if Xsystem reports that "state" represents that button was just released. This only happens on RELEASE with 1,2,3 buttons.
+ // ONLY one of these conditions should be TRUE to add that modifier.
+ if (((state & XConstants.buttonsMask[i]) != 0) != (button == XConstants.buttons[i])){
+ //exclude wheel buttons from adding their numbers as modifiers
+ if (!wheel_mouse) {
+ modifiers |= InputEvent.getMaskForButton(i+1);
+ }
+ }
}
return modifiers;
}
@@ -603,17 +616,6 @@
return res;
}
- private static int getButtonMask(long mouseButton) {
- if (mouseButton == XConstants.Button1) {
- return XConstants.Button1Mask;
- } else if (mouseButton == XConstants.Button2) {
- return XConstants.Button2Mask;
- } else if (mouseButton == XConstants.Button3) {
- return XConstants.Button3Mask;
- }
- return 0;
- }
-
/**
* Returns true if this event is disabled and shouldn't be passed to Java.
* Default implementation returns false for all events.
@@ -648,7 +650,7 @@
boolean popupTrigger = false;
int button=0;
boolean wheel_mouse = false;
- long lbutton = xbe.get_button();
+ int lbutton = xbe.get_button();
int type = xev.get_type();
when = xbe.get_time();
long jWhen = XToolkit.nowMillisUTC_offset(when);
@@ -663,7 +665,7 @@
if (type == XConstants.ButtonPress) {
//Allow this mouse button to generate CLICK event on next ButtonRelease
- mouseButtonClickAllowed |= getButtonMask(lbutton);
+ mouseButtonClickAllowed |= XConstants.buttonsMask[lbutton];
XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null);
/*
multiclick checking
@@ -693,21 +695,22 @@
}
}
- if (lbutton == XConstants.Button1)
- button = MouseEvent.BUTTON1;
- else if (lbutton == XConstants.Button2 )
- button = MouseEvent.BUTTON2;
- else if (lbutton == XConstants.Button3)
- button = MouseEvent.BUTTON3;
- else if (lbutton == XConstants.Button4) {
- button = 4;
- wheel_mouse = true;
- } else if (lbutton == XConstants.Button5) {
- button = 5;
+ button = XConstants.buttons[lbutton - 1];
+ // 4 and 5 buttons are usually considered assigned to a first wheel
+ if (lbutton == XConstants.buttons[3] ||
+ lbutton == XConstants.buttons[4]) {
wheel_mouse = true;
}
- modifiers = getModifiers(xbe.get_state(),button,0);
+ // mapping extra buttons to numbers starting from 4.
+ if ((button > XConstants.buttons[4]) && (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled())){
+ return;
+ }
+
+ if (button > XConstants.buttons[4]){
+ button -= 2;
+ }
+ modifiers = getModifiers(xbe.get_state(),button,0, type, wheel_mouse);
if (!wheel_mouse) {
MouseEvent me = new MouseEvent((Component)getEventSource(),
@@ -720,7 +723,7 @@
postEventToEventQueue(me);
if ((type == XConstants.ButtonRelease) &&
- ((mouseButtonClickAllowed & getButtonMask(lbutton)) != 0) ) // No up-button in the drag-state
+ ((mouseButtonClickAllowed & XConstants.buttonsMask[lbutton]) != 0) ) // No up-button in the drag-state
{
postEventToEventQueue(me = new MouseEvent((Component)getEventSource(),
MouseEvent.MOUSE_CLICKED,
@@ -750,7 +753,7 @@
/* Update the state variable AFTER the CLICKED event post. */
if (type == XConstants.ButtonRelease) {
/* Exclude this mouse button from allowed list.*/
- mouseButtonClickAllowed &= ~getButtonMask(lbutton);
+ mouseButtonClickAllowed &= ~XConstants.buttonsMask[lbutton];
}
}
@@ -761,7 +764,19 @@
return;
}
- int mouseKeyState = (xme.get_state() & (XConstants.Button1Mask | XConstants.Button2Mask | XConstants.Button3Mask));
+ int mouseKeyState = 0; //(xme.get_state() & (XConstants.buttonsMask[0] | XConstants.buttonsMask[1] | XConstants.buttonsMask[2]));
+
+ //this doesn't work for extra buttons because Xsystem is sending state==0 for every extra button event.
+ // we can't correct it in MouseEvent class as we done it with modifiers, because exact type (DRAG|MOVE)
+ // should be passed from XWindow.
+ //TODO: eliminate it with some other value obtained w/o AWTLock.
+ for (int i = 0; i < XToolkit.getNumMouseButtons(); i++){
+ // TODO : here is the bug in WM: extra buttons doesn't have state!=0 as they should.
+ if ((i != 4) && (i != 5)) {
+ mouseKeyState = mouseKeyState | (xme.get_state() & XConstants.buttonsMask[i]);
+ }
+ }
+
boolean isDragging = (mouseKeyState != 0);
int mouseEventType = 0;
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Tue Sep 16 12:17:02 2008 +0400
@@ -1936,7 +1936,13 @@
new Object[] {xme, isGrabbed(), containsGlobal(xme.get_x_root(), xme.get_y_root())});
}
if (isGrabbed()) {
- boolean dragging = (xme.get_state() & (XConstants.Button1Mask | XConstants.Button2Mask | XConstants.Button3Mask)) != 0;
+ boolean dragging = false;
+ for (int i = 0; i<XToolkit.getNumMouseButtons(); i++){
+ // here is the bug in WM: extra buttons doesn't have state!=0 as they should.
+ if ((i != 4) && (i != 5)){
+ dragging = dragging || ((xme.get_state() & XConstants.buttonsMask[i]) != 0);
+ }
+ }
// When window is grabbed, all events are dispatched to
// it. Retarget them to the corresponding windows (notice
// that XBaseWindow.dispatchEvent does the opposite
@@ -1990,12 +1996,12 @@
try {
grabLog.log(Level.FINER, " - Grab event target {0} (press target {1})", new Object[] {target, pressTarget});
if (xbe.get_type() == XConstants.ButtonPress
- && xbe.get_button() == XConstants.Button1)
+ && xbe.get_button() == XConstants.buttons[0])
{
// need to keep it to retarget mouse release
pressTarget = target;
} else if (xbe.get_type() == XConstants.ButtonRelease
- && xbe.get_button() == XConstants.Button1
+ && xbe.get_button() == XConstants.buttons[0]
&& pressTarget != target)
{
// during grab we do receive mouse release on different component (not on the source
--- a/jdk/src/solaris/native/sun/awt/awt_Robot.c Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/solaris/native/sun/awt/awt_Robot.c Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2008 Sun Microsystems, Inc. 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
@@ -54,6 +54,7 @@
// 2 would be more correct, however that's how Robot originally worked
// and tests start to fail if this value is changed
static int32_t num_buttons = 3;
+static jint * masks;
static int32_t isXTestAvailable() {
int32_t major_opcode, first_event, first_error;
@@ -208,6 +209,26 @@
Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls) {
int32_t xtestAvailable;
+// this should be called from XRobotPeer constructor
+ jclass inputEventClazz = (*env)->FindClass(env, "java/awt/event/InputEvent");
+ jmethodID getButtonDownMasksID = (*env)->GetStaticMethodID(env, inputEventClazz, "getButtonDownMasks", "()[I");
+ jintArray obj = (jintArray)(*env)->CallStaticObjectMethod(env, inputEventClazz, getButtonDownMasksID);
+ jsize len = (*env)->GetArrayLength(env, obj);
+ jint * tmp = (*env)->GetIntArrayElements(env, obj, JNI_FALSE);
+
+ masks = (jint *)malloc(sizeof(jint)*len);
+ if (masks == (jint *) NULL) {
+ JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL);
+ goto finally;
+ }
+
+ int i;
+ for (i = 0; i < len; i++) {
+ masks[i] = tmp[i];
+ }
+ (*env)->ReleaseIntArrayElements(env, obj, tmp, 0);
+ (*env)->DeleteLocalRef(env, obj);
+
DTRACE_PRINTLN("RobotPeer: setup()");
AWT_LOCK();
@@ -221,8 +242,15 @@
}
getNumButtons();
+ finally:
+ AWT_UNLOCK();
+}
- AWT_UNLOCK();
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_XRobotPeer_getNumberOfButtonsImpl(JNIEnv *env,
+ jclass cls) {
+ // At the moment this routine being called we already should have an initialized num_buttons variable.
+ return num_buttons;
}
JNIEXPORT void JNICALL
@@ -352,6 +380,8 @@
Java_sun_awt_X11_XRobotPeer_mousePressImpl (JNIEnv *env,
jclass cls,
jint buttonMask) {
+ mouseAction(env, cls, buttonMask, True);
+/*
AWT_LOCK();
DTRACE_PRINTLN1("RobotPeer: mousePressImpl(%i)", buttonMask);
@@ -370,12 +400,15 @@
XSync(awt_display, False);
AWT_UNLOCK();
+*/
}
JNIEXPORT void JNICALL
Java_sun_awt_X11_XRobotPeer_mouseReleaseImpl (JNIEnv *env,
jclass cls,
jint buttonMask) {
+ mouseAction(env, cls, buttonMask, False);
+/*
AWT_LOCK();
DTRACE_PRINTLN1("RobotPeer: mouseReleaseImpl(%i)", buttonMask);
@@ -394,8 +427,57 @@
XSync(awt_display, False);
AWT_UNLOCK();
+*/
}
+/*
+ * Function joining the code of mousePressImpl and mouseReleaseImpl
+ */
+void mouseAction(JNIEnv *env,
+ jclass cls,
+ jint buttonMask,
+ Bool isMousePress)
+{
+ AWT_LOCK();
+
+ DTRACE_PRINTLN1("RobotPeer: mouseAction(%i)", buttonMask);
+ DTRACE_PRINTLN1("RobotPeer: mouseAction, press = %d", isMousePress);
+
+ if (buttonMask & java_awt_event_InputEvent_BUTTON1_MASK ||
+ buttonMask & java_awt_event_InputEvent_BUTTON1_DOWN_MASK )
+ {
+ XTestFakeButtonEvent(awt_display, 1, isMousePress, CurrentTime);
+ }
+ if ((buttonMask & java_awt_event_InputEvent_BUTTON2_MASK ||
+ buttonMask & java_awt_event_InputEvent_BUTTON2_DOWN_MASK) &&
+ (num_buttons >= 2)) {
+ XTestFakeButtonEvent(awt_display, 2, isMousePress, CurrentTime);
+ }
+ if ((buttonMask & java_awt_event_InputEvent_BUTTON3_MASK ||
+ buttonMask & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) &&
+ (num_buttons >= 3)) {
+ XTestFakeButtonEvent(awt_display, 3, isMousePress, CurrentTime);
+ }
+
+ if (num_buttons > 3){
+ int32_t i;
+ int32_t button = 0;
+ for (i = 3; i<num_buttons; i++){
+ if ((buttonMask & masks[i])) {
+ // arrays starts from zero index => +1
+ // users wants to affect 4 or 5 button but they are assigned
+ // to the wheel so => we have to shift it to the right by 2.
+ button = i + 3;
+ XTestFakeButtonEvent(awt_display, button, isMousePress, CurrentTime);
+ }
+ }
+ }
+
+ XSync(awt_display, False);
+ AWT_UNLOCK();
+}
+
+
JNIEXPORT void JNICALL
Java_sun_awt_X11_XRobotPeer_mouseWheelImpl (JNIEnv *env,
jclass cls,
--- a/jdk/src/windows/classes/sun/awt/windows/WRobotPeer.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WRobotPeer.java Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc. 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
@@ -60,6 +60,8 @@
}
public native int getRGBPixelImpl(int x, int y);
+ public native int getNumberOfButtons();
+
public int [] getRGBPixels(Rectangle bounds) {
int pixelArray[] = new int[bounds.width*bounds.height];
getRGBPixels(bounds.x, bounds.y, bounds.width, bounds.height, pixelArray);
--- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java Tue Sep 16 12:17:02 2008 +0400
@@ -80,6 +80,10 @@
// Dynamic Layout Resize client code setting
protected boolean dynamicLayoutSetting = false;
+ //Is it allowed to generate events assigned to extra mouse buttons.
+ //Set to true by default.
+ private static boolean areExtraMouseButtonsEnabled = true;
+
/**
* Initialize JNI field and method IDs
*/
@@ -249,6 +253,11 @@
// Enabled "live resizing" by default. It remains controlled
// by the native system though.
setDynamicLayout(true);
+
+ areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
+ //set system property if not yet assigned
+ System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
+ setExtraMouseButtonsEnabledNative(areExtraMouseButtonsEnabled);
}
public void run() {
@@ -961,4 +970,9 @@
return new WDesktopPeer();
}
+ public static native void setExtraMouseButtonsEnabledNative(boolean enable);
+
+ public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
+ return areExtraMouseButtonsEnabled;
+ }
}
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp Tue Sep 16 12:17:02 2008 +0400
@@ -187,6 +187,8 @@
UINT AwtComponent::m_CodePage
= AwtComponent::LangToCodePage(m_idLang);
+jint *AwtComponent::masks;
+
static BOOL bLeftShiftIsDown = false;
static BOOL bRightShiftIsDown = false;
static UINT lastShiftKeyPressed = 0; // init to safe value
@@ -1177,6 +1179,9 @@
WIN_MSG(WM_MBUTTONDOWN)
WIN_MSG(WM_MBUTTONUP)
WIN_MSG(WM_MBUTTONDBLCLK)
+ WIN_MSG(WM_XBUTTONDBLCLK)
+ WIN_MSG(WM_XBUTTONDOWN)
+ WIN_MSG(WM_XBUTTONUP)
WIN_MSG(WM_MOUSEWHEEL)
WIN_MSG(WM_PARENTNOTIFY)
WIN_MSG(WM_ENTERMENULOOP)
@@ -1612,6 +1617,9 @@
case WM_MBUTTONDOWN:
case WM_MBUTTONDBLCLK:
case WM_MBUTTONUP:
+ case WM_XBUTTONDBLCLK:
+ case WM_XBUTTONDOWN:
+ case WM_XBUTTONUP:
case WM_MOUSEMOVE:
case WM_MOUSEWHEEL:
case WM_AWT_MOUSEENTER:
@@ -1642,6 +1650,31 @@
mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
MIDDLE_BUTTON);
break;
+ case WM_XBUTTONDOWN:
+ case WM_XBUTTONDBLCLK:
+ if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) {
+ if (HIWORD(wParam) == 1) {
+ mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
+ X1_BUTTON);
+ }
+ if (HIWORD(wParam) == 2) {
+ mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
+ X2_BUTTON);
+ }
+ }
+ break;
+ case WM_XBUTTONUP:
+ if (AwtToolkit::GetInstance().areExtraMouseButtonsEnabled()) {
+ if (HIWORD(wParam) == 1) {
+ mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,
+ X1_BUTTON);
+ }
+ if (HIWORD(wParam) == 2) {
+ mr = WmMouseUp(static_cast<UINT>(wParam), myPos.x, myPos.y,
+ X2_BUTTON);
+ }
+ }
+ break;
case WM_RBUTTONDOWN:
case WM_RBUTTONDBLCLK:
mr = WmMouseDown(static_cast<UINT>(wParam), myPos.x, myPos.y,
@@ -2549,8 +2582,12 @@
lastComp = this;
lastX = x;
lastY = y;
-
- if ( (flags & ALL_MK_BUTTONS) != 0 ) {
+ BOOL extraButtonsEnabled = AwtToolkit::GetInstance().areExtraMouseButtonsEnabled();
+ if (((flags & (ALL_MK_BUTTONS)) != 0) ||
+ (extraButtonsEnabled && (flags & (X_BUTTONS)) != 0))
+// if (( extraButtonsEnabled && ( (flags & (ALL_MK_BUTTONS | X_BUTTONS)) != 0 )) ||
+// ( !extraButtonsEnabled && (((flags & (ALL_MK_BUTTONS)) != 0 )) && ((flags & (X_BUTTONS)) == 0) ))
+ {
// 6404008 : if Dragged event fired we shouldn't fire
// Clicked event: m_firstDragSent set to TRUE.
// This is a partial backout of 5039416 fix.
@@ -2728,7 +2765,7 @@
modifiers |= java_awt_event_InputEvent_ALT_DOWN_MASK;
}
if (HIBYTE(::GetKeyState(VK_MBUTTON)) != 0) {
- modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK;
+ modifiers |= java_awt_event_InputEvent_BUTTON2_DOWN_MASK;
}
if (HIBYTE(::GetKeyState(VK_RBUTTON)) != 0) {
modifiers |= java_awt_event_InputEvent_BUTTON3_DOWN_MASK;
@@ -2736,6 +2773,13 @@
if (HIBYTE(::GetKeyState(VK_LBUTTON)) != 0) {
modifiers |= java_awt_event_InputEvent_BUTTON1_DOWN_MASK;
}
+
+ if (HIBYTE(::GetKeyState(VK_XBUTTON1)) != 0) {
+ modifiers |= masks[3];
+ }
+ if (HIBYTE(::GetKeyState(VK_XBUTTON2)) != 0) {
+ modifiers |= masks[4];
+ }
return modifiers;
}
@@ -2750,6 +2794,11 @@
return java_awt_event_MouseEvent_BUTTON2;
case RIGHT_BUTTON:
return java_awt_event_MouseEvent_BUTTON3;
+ case X1_BUTTON: //16 :
+ //just assign 4 and 5 numbers because MouseEvent class doesn't contain const identifier for them now
+ return 4;
+ case X2_BUTTON: //32
+ return 5;
}
return java_awt_event_MouseEvent_NOBUTTON;
}
@@ -2764,6 +2813,10 @@
return MK_MBUTTON;
case RIGHT_BUTTON:
return MK_RBUTTON;
+ case X1_BUTTON:
+ return MK_XBUTTON1;
+ case X2_BUTTON:
+ return MK_XBUTTON2;
}
return 0;
}
@@ -2781,6 +2834,14 @@
#define VK_NONCONVERT 0x1D
#endif
+#ifndef VK_XBUTTON1
+#define VK_XBUTTON1 0x05
+#endif
+
+#ifndef VK_XBUTTON2
+#define VK_XBUTTON2 0x06
+#endif
+
typedef struct {
UINT javaKey;
UINT windowsKey;
@@ -5068,7 +5129,12 @@
if (modifiers & java_awt_event_InputEvent_BUTTON3_DOWN_MASK) {
wLow |= MK_MBUTTON;
}
-
+ if (modifiers & X1_BUTTON) {
+ wLow |= GetButtonMK(X1_BUTTON);
+ }
+ if (modifiers & X2_BUTTON) {
+ wLow |= GetButtonMK(X2_BUTTON);
+ }
wheelAmt = (jint)JNU_CallMethodByName(env,
NULL,
@@ -6165,6 +6231,18 @@
Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
{
TRY;
+ jclass inputEventClazz = env->FindClass("java/awt/event/InputEvent");
+ jmethodID getButtonDownMasksID = env->GetStaticMethodID(inputEventClazz, "getButtonDownMasks", "()[I");
+ jintArray obj = (jintArray)env->CallStaticObjectMethod(inputEventClazz, getButtonDownMasksID);
+ jint * tmp = env->GetIntArrayElements(obj, JNI_FALSE);
+
+ jsize len = env->GetArrayLength(obj);
+ AwtComponent::masks = new jint[len];
+ for (int i = 0; i < len; i++) {
+ AwtComponent::masks[i] = tmp[i];
+ }
+ env->ReleaseIntArrayElements(obj, tmp, 0);
+ env->DeleteLocalRef(obj);
/* class ids */
jclass peerCls = env->FindClass("sun/awt/windows/WComponentPeer");
--- a/jdk/src/windows/native/sun/windows/awt_Component.h Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Component.h Tue Sep 16 12:17:02 2008 +0400
@@ -53,6 +53,22 @@
#define MIDDLE_BUTTON 2
#define RIGHT_BUTTON 4
#define DBL_CLICK 8
+#define X1_BUTTON 16
+#define X2_BUTTON 32
+
+#ifndef MK_XBUTTON1
+#define MK_XBUTTON1 0x0020
+#endif
+
+#ifndef MK_XBUTTON2
+#define MK_XBUTTON2 0x0040
+#endif
+
+// combination of standard mouse button flags
+const int ALL_MK_BUTTONS = MK_LBUTTON|MK_MBUTTON|MK_RBUTTON;
+const int X_BUTTONS = MK_XBUTTON1|MK_XBUTTON2;
+
+
// Whether to check for embedded frame and adjust location
#define CHECK_EMBEDDED 0
@@ -81,11 +97,6 @@
class AwtComponent : public AwtObject {
public:
- enum {
- // combination of all mouse button flags
- ALL_MK_BUTTONS = MK_LBUTTON|MK_MBUTTON|MK_RBUTTON
- };
-
/* java.awt.Component fields and method IDs */
static jfieldID peerID;
static jfieldID xID;
@@ -112,6 +123,7 @@
static jmethodID replaceSurfaceDataLaterMID;
static const UINT WmAwtIsComponent;
+ static jint * masks; //InputEvent mask array
AwtComponent();
virtual ~AwtComponent();
--- a/jdk/src/windows/native/sun/windows/awt_Robot.cpp Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Robot.cpp Tue Sep 16 12:17:02 2008 +0400
@@ -31,8 +31,6 @@
#include "java_awt_event_InputEvent.h"
#include <winuser.h>
-static const int MOUSE_MAX = 65535;
-
AwtRobot::AwtRobot( jobject peer )
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -103,19 +101,38 @@
// left handed mouse setup
BOOL bSwap = ::GetSystemMetrics(SM_SWAPBUTTON);
- if ( buttonMask & java_awt_event_InputEvent_BUTTON1_MASK ) {
+ if ( buttonMask & java_awt_event_InputEvent_BUTTON1_MASK ||
+ buttonMask & java_awt_event_InputEvent_BUTTON1_DOWN_MASK)
+ {
dwFlags |= !bSwap ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN;
}
- if ( buttonMask & java_awt_event_InputEvent_BUTTON3_MASK ) {
+ if ( buttonMask & java_awt_event_InputEvent_BUTTON3_MASK ||
+ buttonMask & java_awt_event_InputEvent_BUTTON3_DOWN_MASK)
+ {
dwFlags |= !bSwap ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN;
}
- if ( buttonMask & java_awt_event_InputEvent_BUTTON2_MASK ) {
+ if ( buttonMask & java_awt_event_InputEvent_BUTTON2_MASK ||
+ buttonMask & java_awt_event_InputEvent_BUTTON2_DOWN_MASK)
+ {
dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
}
- mouse_event(dwFlags, 0, 0, 0, 0 );
+ INPUT mouseInput = {0};
+ mouseInput.type = INPUT_MOUSE;
+ mouseInput.mi.time = 0;
+ mouseInput.mi.dwFlags = dwFlags;
+ if ( buttonMask & AwtComponent::masks[3] ) {
+ mouseInput.mi.dwFlags = mouseInput.mi.dwFlags | MOUSEEVENTF_XDOWN;
+ mouseInput.mi.mouseData = XBUTTON1;
+ }
+
+ if ( buttonMask & AwtComponent::masks[4] ) {
+ mouseInput.mi.dwFlags = mouseInput.mi.dwFlags | MOUSEEVENTF_XDOWN;
+ mouseInput.mi.mouseData = XBUTTON2;
+ }
+ ::SendInput(1, &mouseInput, sizeof(mouseInput));
}
void AwtRobot::MouseRelease( jint buttonMask )
@@ -126,19 +143,39 @@
// left handed mouse setup
BOOL bSwap = ::GetSystemMetrics(SM_SWAPBUTTON);
- if ( buttonMask & java_awt_event_InputEvent_BUTTON1_MASK ) {
+ if ( buttonMask & java_awt_event_InputEvent_BUTTON1_MASK ||
+ buttonMask & java_awt_event_InputEvent_BUTTON1_DOWN_MASK)
+ {
dwFlags |= !bSwap ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
}
- if ( buttonMask & java_awt_event_InputEvent_BUTTON3_MASK ) {
+ if ( buttonMask & java_awt_event_InputEvent_BUTTON3_MASK ||
+ buttonMask & java_awt_event_InputEvent_BUTTON3_DOWN_MASK)
+ {
dwFlags |= !bSwap ? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP;
}
- if ( buttonMask & java_awt_event_InputEvent_BUTTON2_MASK ) {
+ if ( buttonMask & java_awt_event_InputEvent_BUTTON2_MASK ||
+ buttonMask & java_awt_event_InputEvent_BUTTON2_DOWN_MASK)
+ {
dwFlags |= MOUSEEVENTF_MIDDLEUP;
}
- mouse_event(dwFlags, 0, 0, 0, 0 );
+ INPUT mouseInput = {0};
+ mouseInput.type = INPUT_MOUSE;
+ mouseInput.mi.time = 0;
+ mouseInput.mi.dwFlags = dwFlags;
+
+ if ( buttonMask & AwtComponent::masks[3] ) {
+ mouseInput.mi.dwFlags = mouseInput.mi.dwFlags | MOUSEEVENTF_XUP;
+ mouseInput.mi.mouseData = XBUTTON1;
+ }
+
+ if ( buttonMask & AwtComponent::masks[4] ) {
+ mouseInput.mi.dwFlags = mouseInput.mi.dwFlags | MOUSEEVENTF_XUP;
+ mouseInput.mi.mouseData = XBUTTON2;
+ }
+ ::SendInput(1, &mouseInput, sizeof(mouseInput));
}
void AwtRobot::MouseWheel (jint wheelAmt) {
@@ -400,3 +437,9 @@
CATCH_BAD_ALLOC;
}
+
+JNIEXPORT jint JNICALL Java_sun_awt_windows_WRobotPeer_getNumberOfButtons(
+ JNIEnv *, jobject self)
+{
+ return GetSystemMetrics(SM_CMOUSEBUTTONS);
+}
--- a/jdk/src/windows/native/sun/windows/awt_Robot.h Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Robot.h Tue Sep 16 12:17:02 2008 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc. 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
@@ -42,13 +42,13 @@
void MouseRelease( jint buttonMask );
void MouseWheel(jint wheelAmt);
+ jint getNumberOfButtons();
jint GetRGBPixel( jint x, jint y);
void GetRGBPixels(jint x, jint y, jint width, jint height, jintArray pixelArray);
void KeyPress( jint key );
void KeyRelease( jint key );
-
static AwtRobot * GetRobot( jobject self );
private:
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp Tue Sep 16 12:17:02 2008 +0400
@@ -322,6 +322,7 @@
m_vmSignalled = FALSE;
m_isDynamicLayoutSet = FALSE;
+ m_areExtraMouseButtonsEnabled = TRUE;
m_verifyComponents = FALSE;
m_breakOnError = FALSE;
@@ -2092,3 +2093,26 @@
splashClose();
}
}
+
+/*
+ * accessible from awt_Component
+ */
+BOOL AwtToolkit::areExtraMouseButtonsEnabled() {
+ return m_areExtraMouseButtonsEnabled;
+}
+
+/*
+ * Class: sun_awt_windows_WToolkit
+ * Method: setExtraMouseButtonsEnabledNative
+ * Signature: (Z)V
+ */
+extern "C" JNIEXPORT void JNICALL Java_sun_awt_windows_WToolkit_setExtraMouseButtonsEnabledNative
+(JNIEnv *env, jclass self, jboolean enable){
+ TRY;
+ AwtToolkit::GetInstance().setExtraMouseButtonsEnabled(enable);
+ CATCH_BAD_ALLOC;
+}
+
+void AwtToolkit::setExtraMouseButtonsEnabled(BOOL enable) {
+ m_areExtraMouseButtonsEnabled = enable;
+}
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h Tue Sep 16 12:17:02 2008 +0400
@@ -175,6 +175,8 @@
BOOL IsDynamicLayoutSet();
BOOL IsDynamicLayoutSupported();
BOOL IsDynamicLayoutActive();
+ BOOL areExtraMouseButtonsEnabled();
+ void setExtraMouseButtonsEnabled(BOOL enable);
INLINE BOOL localPump() { return m_localPump; }
INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag
@@ -351,6 +353,7 @@
BOOL m_verbose;
BOOL m_isActive; // set to FALSE at beginning of Dispose
BOOL m_isDisposed; // set to TRUE at end of Dispose
+ BOOL m_areExtraMouseButtonsEnabled;
BOOL m_vmSignalled; // set to TRUE if QUERYENDSESSION has successfully
// raised SIGTERM
--- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp Thu Sep 11 10:38:00 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp Tue Sep 16 12:17:02 2008 +0400
@@ -393,7 +393,7 @@
lastX = x;
lastY = y;
AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
- if ((flags & AwtComponent::ALL_MK_BUTTONS) != 0) {
+ if ((flags & ALL_MK_BUTTONS) != 0) {
m_mouseButtonClickAllowed = 0;
} else {
SendMouseEvent(java_awt_event_MouseEvent_MOUSE_MOVED, TimeHelper::windowsToUTC(::GetTickCount()), x, y,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/ExtraButtonDrag.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,131 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that drag events are coming for every button if the property is set to true
+ @author Andrei Dmitriev : area=awt.mouse
+ @run main ExtraButtonDrag
+ */
+
+//events from standard should also come
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class ExtraButtonDrag extends Frame {
+ static String tk = Toolkit.getDefaultToolkit().getClass().getName();
+ static Robot robot;
+ static int [] buttonsPressed;
+ static int [] buttonsReleased;
+ static int [] buttonsClicked;
+ volatile static boolean dragged = false;
+ volatile static boolean moved = false;
+
+ public ExtraButtonDrag(){
+ super("ExtraButtonDrag");
+ }
+
+ public static void main(String []s){
+ Frame frame = new ExtraButtonDrag();
+
+ MouseAdapter ma = new MouseAdapter() {
+ public void mouseDragged(MouseEvent e) {
+ System.out.println("Dragged "+e);// +" : "+ e.getButton() + " : " +e.getButtonState(e.getButton()));
+ dragged = true;
+ }
+ public void mouseMoved(MouseEvent e) {
+ System.out.println("Moved "+e);
+ moved = true;
+ }
+ public void mousePressed(MouseEvent e) {
+ System.out.println(">>> "+e);
+ }
+ public void mouseReleased(MouseEvent e) {
+ System.out.println(">>> "+e);
+ }
+
+ };
+
+ frame.addMouseMotionListener(ma);
+ frame.addMouseListener(ma);
+
+ frame.setSize(300, 300);
+ frame.setVisible(true);
+
+ int [] buttonMask = new int [MouseInfo.getNumberOfButtons()]; //InputEvent.getButtonMasks();
+
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ buttonMask[i] = InputEvent.getMaskForButton(i+1);
+ // System.out.println("TEST: "+tmp[i]);
+ }
+
+ try {
+ robot = new Robot();
+ robot.delay(1000);
+ Point centerFrame = new Point(frame.getLocationOnScreen().x + frame.getWidth()/2, frame.getLocationOnScreen().y + frame.getHeight()/2);
+ Point outboundsFrame = new Point(frame.getLocationOnScreen().x + frame.getWidth()*3/2, frame.getLocationOnScreen().y + frame.getHeight()/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);
+ }
+
+ robot.delay(500);
+ //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 (tk.equals("sun.awt.X11.XToolkit") || tk.equals("sun.awt.motif.MToolkit")) {
+ if (!moved || dragged) {
+ throw new RuntimeException("Test failed."+ tk +" Button = " +(i+1) + " moved = "+moved +" : dragged = " +dragged);
+ }
+ } else { //WToolkit
+ if (moved || !dragged) {
+ throw new RuntimeException("Test failed."+ tk +" Button = " +(i+1) + " moved = "+moved +" : dragged = " +dragged);
+ }
+ }
+ } else {
+ if (moved || !dragged){
+ throw new RuntimeException("Test failed. Button = " +(i+1) + " not dragged.");
+ }
+ }
+ }
+ } catch (Exception e){
+ throw new RuntimeException("", e);
+ }
+ }
+
+ 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);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/ModifierPermutation.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,320 @@
+/*
+ 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;
+ }
+}
+*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,490 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that modifiers are correct for extra buttons
+ @author Andrei Dmitriev : area=awt.mouse
+ @run main MouseModifiersUnitTest_Extra
+ */
+
+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 CheckingModifierAdapter adapterTest1;
+ static CheckingModifierAdapter adapterTest2;
+ static CheckingModifierAdapter adapterTest3;
+ static CheckingModifierAdapter 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 [] mouseButtons;
+ 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;
+
+ // final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK};
+ // 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");
+ }
+
+ //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 h, int button){
+ String ethalon = "";
+ switch (testModifier){
+ case SHIFT:{
+ ethalon = "Shift";
+ break;
+ }
+ case ALT:{
+ ethalon = "Alt";
+ break;
+ }
+ case CTRL:{
+ ethalon = "Ctrl";
+ 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 h, int button){
+ String ethalon = "";
+ switch (testModifier){
+ case SHIFT:{
+ ethalon = "Shift+";
+ break;
+ }
+ case ALT:{
+ ethalon = "Alt+";
+ break;
+ }
+ case CTRL:{
+ ethalon = "Ctrl+";
+ 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<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;
+ }
+
+ 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");
+ }
+
+ //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");
+ }
+
+ //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());
+
+ String[] instructions =
+ {
+ "This test should be used with the mouse having more then three buttons.",
+ "Currently, " + MouseInfo.getNumberOfButtons() +" buttons are available.",
+ "If there are less then three buttons, press PASS.",
+ "1. Press each extra mouse button.",
+ "2. For each mouse event its modifiers and ExModifiers will be printed.",
+ "3. Verify that they are correct.",
+ "4. Press Pass or Fail accordingly."
+ };
+// Sysout.createDialogWithInstructions( instructions );
+
+// addMouseListener(adapterTest1);
+ try {
+ robot = new Robot();
+ } 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< mouseButtons.length; i++){
+ System.out.println("testNONE() => " +mouseButtons[i] );
+ robot.mousePress(mouseButtons[i]);
+ robot.delay(100);
+ robot.mouseRelease(mouseButtons[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< mouseButtons.length; i++){
+ robot.keyPress(KeyEvent.VK_SHIFT);
+ System.out.println("testSHIFT() => " +mouseButtons[i] );
+ robot.mousePress(mouseButtons[i]);
+ robot.delay(100);
+ robot.mouseRelease(mouseButtons[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< mouseButtons.length; i++){
+ robot.keyPress(KeyEvent.VK_CONTROL);
+ System.out.println("testCTRL() => " +mouseButtons[i] );
+ robot.mousePress(mouseButtons[i]);
+ robot.delay(100);
+ robot.mouseRelease(mouseButtons[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< mouseButtons.length; i++){
+ robot.keyPress(KeyEvent.VK_ALT);
+ System.out.println("testALT() => " +mouseButtons[i] );
+ robot.mousePress(mouseButtons[i]);
+ robot.delay(100);
+ robot.mouseRelease(mouseButtons[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 CheckingModifierAdapter(NONE);
+ adapterTest2 = new CheckingModifierAdapter(SHIFT);
+ adapterTest3 = new CheckingModifierAdapter(CTRL);
+ adapterTest4 = new CheckingModifierAdapter(ALT);
+ }
+
+ public static void initVars(){
+ int [] tmp = new int [MouseInfo.getNumberOfButtons()];
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ tmp[i] = InputEvent.getMaskForButton(i+1);
+ // System.out.println("TEST: "+tmp[i]);
+ }
+
+ mouseButtons = Arrays.copyOf(tmp, tmp.length);
+
+ for (int i = 0; i < mouseButtons.length; i++){
+ System.out.println("MouseArray [i] == "+mouseButtons[i]);
+ }
+
+ mouseButtonDownMasks = Arrays.copyOf(tmp, tmp.length);
+
+ // 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.
+ tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
+ 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);
+
+ Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK);
+ for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
+ tmp[i] = tmp[j] | mouseButtonDownMasks[j];
+ }
+ modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length);
+
+ Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK);
+ for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
+ tmp[i] = tmp[j] | mouseButtonDownMasks[j];
+ }
+ modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length);
+
+ Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK);
+ for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
+ tmp[i] = tmp[j] | mouseButtonDownMasks[j];
+ }
+ modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length);
+ }
+
+ public static void main(String []s){
+ if (MouseInfo.getNumberOfButtons() < 4){
+ System.out.println("There are less then 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 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("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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Standard.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,598 @@
+/*
+ @test %I% %E%
+ @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()
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Robot/AcceptExtraMouseButtons/AcceptExtraMouseButtons.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,118 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that Robot is accepting extra mouse buttons
+ @author Andrei Dmitriev : area=awt.mouse
+ @library ../../regtesthelpers
+ @build Util
+ @run main AcceptExtraMouseButtons
+ */
+
+//if we do robot.mousePress(InputEvent.BUTTON1_DOWN_MASK) the test must
+// 1) accept it (i.e. don't throw an IllegalArgumentException
+// 2) actually post a MouseEvent
+// Also, Robot should still accept InputEvent.BUTTONx_MASKs
+
+import java.awt.*;
+import java.awt.event.*;
+import sun.awt.SunToolkit;
+import test.java.awt.regtesthelpers.Util;
+
+public class AcceptExtraMouseButtons extends Frame {
+ static String tk = Toolkit.getDefaultToolkit().getClass().getName();
+ static Robot robot;
+ static int [] standardButtonMasks = {InputEvent.BUTTON1_MASK,
+ InputEvent.BUTTON2_MASK,
+ InputEvent.BUTTON3_MASK};
+ static int [] buttonsPressed;
+ static int [] buttonsReleased;
+ static int [] buttonsClicked;
+
+ static int buttonsNum = MouseInfo.getNumberOfButtons();
+
+ public static void main(String []s){
+
+ //MouseInfo.getNumberOfButtons() reports two more buttons on XToolkit
+ //as they reserved for wheel (both directions).
+ if (tk.equals("sun.awt.X11.XToolkit") || tk.equals("sun.awt.motif.MToolkit")) {
+ buttonsNum = buttonsNum - 2;
+ }
+ System.out.println("Number Of Buttons = "+ buttonsNum);
+ if (buttonsNum < 3) {
+ System.out.println("Linux and Windows systems should emulate three buttons if even there are only 1 or 2 are phsically available. Setting number of buttons to 3.");
+ buttonsNum = 3;
+ }
+
+ buttonsPressed = new int [buttonsNum];
+ buttonsReleased = new int [buttonsNum];
+ buttonsClicked = new int [buttonsNum];
+
+ AcceptExtraMouseButtons frame = new AcceptExtraMouseButtons();
+
+ MouseAdapter ma1 = new MouseAdapter() {
+ public void mousePressed(MouseEvent e) {
+ buttonsPressed[e.getButton() - 1] += 1;
+ System.out.println("PRESSED "+e);
+ }
+ public void mouseReleased(MouseEvent e) {
+ buttonsReleased[e.getButton() - 1] += 1;
+ System.out.println("RELEASED "+e);
+ }
+ public void mouseClicked(MouseEvent e) {
+ buttonsClicked[e.getButton() - 1] += 1;
+ System.out.println("CLICKED "+e);
+ }
+ };
+ frame.addMouseListener(ma1);
+
+ frame.setSize(300, 300);
+ frame.setVisible(true);
+
+ Util.waitForIdle(robot); //a time to show a Frame
+
+ try {
+ robot = new Robot();
+ robot.delay(1000);
+ robot.mouseMove(frame.getLocationOnScreen().x + frame.getWidth()/2,
+ frame.getLocationOnScreen().y + frame.getHeight()/2);
+
+ //TestCase 1: verify that all BUTTONx_DOWN_MASKs are accepted by the Robot.
+
+ for (int i = 0; i < buttonsNum; i++){
+ int buttonMask = InputEvent.getMaskForButton(i+1);
+ System.out.println("button to press = " +(i+1) + " : value passed to robot = " +buttonMask);
+ robot.mousePress(buttonMask);
+ robot.delay(30);
+ robot.mouseRelease(buttonMask);
+ Util.waitForIdle(robot);
+ }
+ for (int i = 0; i < buttonsNum; i++){
+ if (buttonsPressed[i] != 1 || buttonsReleased[i] != 1 || buttonsClicked[i] !=1 ) {
+ throw new RuntimeException("TESTCASE 1 FAILED : button " + (i+1) + " wasn't single pressed|released|clicked : "+ buttonsPressed[i] +" : "+ buttonsReleased[i] +" : "+ buttonsClicked[i]);
+ }
+ }
+
+ java.util.Arrays.fill(buttonsPressed, 0);
+ java.util.Arrays.fill(buttonsReleased, 0);
+ java.util.Arrays.fill(buttonsClicked, 0);
+ //TestCase 2: verify that all BUTTONx_MASKs are accepted by the Robot.
+ for (int i = 0; i < standardButtonMasks.length; i++){
+ int buttonMask = standardButtonMasks[i];
+ System.out.println("button to press = " +(i+1) + " : value passed to robot = " +buttonMask);
+ robot.mousePress(buttonMask);
+ robot.delay(30);
+ robot.mouseRelease(buttonMask);
+ Util.waitForIdle(robot);
+ }
+ for (int i = 0; i < standardButtonMasks.length; i++){
+ if (buttonsPressed[i] != 1 || buttonsReleased[i] != 1 || buttonsClicked[i] !=1 ) {
+ throw new RuntimeException("TESTCASE 2 FAILED : button " + (i+1) + " wasn't single pressed|released|clicked : "+ buttonsPressed[i] +" : "+ buttonsReleased[i] +" : "+ buttonsClicked[i]);
+ }
+ }
+
+ } catch (Exception e){
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Robot/ManualInstructions/ManualInstructions.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,305 @@
+/*
+ test %W% %E% %I%, %G%
+ @bug 6315717
+ @summary manual control over the Robot
+ @author Andrei Dmitriev : area=awt.robot
+ @run applet/manual=yesno ManualInstructions.html
+*/
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class ManualInstructions extends Applet
+{
+ final static long SEND_DELAY = 1000;
+
+ public static void main(String s[]){
+ ManualInstructions mi = new ManualInstructions();
+ mi.init();
+ mi.start();
+ }
+
+ static Robot robot;
+ Point mouseLocation; //where mouse should be pressed each time
+ Panel target = new Panel();
+ Button pressOn = new Button("press on ...");
+ Button releaseOn = new Button("release on ...");
+ Button clickOn = new Button("click on ...");
+ Choice buttonNumber = new Choice();
+
+ public void init()
+ {
+ try {
+ robot = new Robot();
+ } catch (AWTException ex) {
+ ex.printStackTrace();
+ throw new RuntimeException(ex);
+ }
+ this.setLayout (new BorderLayout ());
+
+ target.setBackground(Color.green);
+ target.setName("GreenBox");//for the ease of debug
+ target.setPreferredSize(new Dimension(100, 100));
+ String toolkit = Toolkit.getDefaultToolkit().getClass().getName();
+
+ // on X systems two buttons are reserved for wheel though they are countable by MouseInfo.
+ int buttonsNumber = toolkit.equals("sun.awt.windows.WToolkit")?MouseInfo.getNumberOfButtons():MouseInfo.getNumberOfButtons()-2;
+
+ for (int i = 0; i < 8; i++){
+ buttonNumber.add("BUTTON"+(i+1)+"_MASK");
+ }
+
+ pressOn.addActionListener(new ActionListener(){
+ public void actionPerformed(ActionEvent e){
+ System.out.println("Now pressing : " + (buttonNumber.getSelectedIndex()+1));
+
+ Timer timer = new Timer();
+ TimerTask robotInteraction = new TimerTask(){
+ public void run(){
+ robot.mouseMove(updateTargetLocation().x, updateTargetLocation().y);
+ robot.mousePress(getMask(buttonNumber.getSelectedIndex()+1));
+ }
+ };
+ timer.schedule(robotInteraction, SEND_DELAY);
+ }
+ });
+
+ releaseOn.addActionListener(new ActionListener(){
+ public void actionPerformed(ActionEvent e){
+ System.out.println("Now releasing : " + (buttonNumber.getSelectedIndex()+1));
+ Timer timer = new Timer();
+ TimerTask robotInteraction = new TimerTask(){
+ public void run(){
+ robot.mouseMove(updateTargetLocation().x, updateTargetLocation().y);
+ robot.mouseRelease(getMask(buttonNumber.getSelectedIndex()+1));
+ }
+ };
+ timer.schedule(robotInteraction, SEND_DELAY);
+ }
+ });
+
+ clickOn.addActionListener(new ActionListener(){
+ public void actionPerformed(ActionEvent e){
+ System.out.println("Now clicking : " + (buttonNumber.getSelectedIndex()+1));
+ Timer timer = new Timer();
+ TimerTask robotInteraction = new TimerTask(){
+ public void run(){
+ robot.mouseMove(updateTargetLocation().x, updateTargetLocation().y);
+ robot.mousePress(getMask(buttonNumber.getSelectedIndex()+1));
+ robot.mouseRelease(getMask(buttonNumber.getSelectedIndex()+1));
+ }
+ };
+ timer.schedule(robotInteraction, SEND_DELAY);
+ }
+
+ });
+ target.addMouseListener(new MouseAdapter(){
+ public void mousePressed(MouseEvent e){
+ Sysout.println(""+e);
+ }
+ public void mouseReleased(MouseEvent e){
+ Sysout.println(""+e);
+ }
+ public void mouseClicked(MouseEvent e){
+ Sysout.println(""+e);
+ }
+ });
+
+ String[] instructions =
+ {
+ "Do provide an instruction to the robot by",
+ "choosing the button number to act and ",
+ "pressing appropriate java.awt.Button on the left.",
+ "Inspect an output in the TextArea below.",
+ "Please don't generate non-natural sequences like Release-Release, etc.",
+ "If you use keyboard be sure that you released the keyboard shortly.",
+ "If events are generated well press Pass, otherwise Fail."
+ };
+ Sysout.createDialogWithInstructions( instructions );
+
+ }//End init()
+
+ private int getMask(int button){
+ return InputEvent.getMaskForButton(button);
+
+ /*
+ //this only works for standard buttons and for old JDK builds
+ int mask = 0;
+ switch (button){
+ case 1: {
+ mask = InputEvent.BUTTON1_MASK;
+ break;
+ }
+ case 2: {
+ mask = InputEvent.BUTTON2_MASK;
+ break;
+ }
+ case 3: {
+ mask = InputEvent.BUTTON3_MASK;
+ break;
+ }
+ }
+ return mask;
+ */
+ }
+
+ private Point updateTargetLocation() {
+ return new Point(target.getLocationOnScreen().x + target.getWidth()/2, target.getLocationOnScreen().y + target.getHeight()/2);
+ }
+
+ public void start ()
+ {
+ //Get things going. Request focus, set size, et cetera
+ setSize (200,200);
+ setVisible(true);
+ validate();
+ Frame f = new Frame ("Set action for Robot here.");
+ f.setLayout(new FlowLayout());
+ f.add(buttonNumber);
+ f.add(pressOn);
+ f.add(releaseOn);
+ f.add(clickOn);
+ f.add(target);
+ f.pack();
+ f.setVisible(true);
+ }// start()
+}// class
+
+/* Place other classes related to the test after this line */
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ dialog.displayMessage( messageIn );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 120;
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+ }// while
+ }// for
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Robot/RobotExtraButton/RobotExtraButton.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,79 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that robot could accept extra buttons
+ @author Andrei Dmitriev : area=awt.mouse
+ @library ../../regtesthelpers
+ @build Util
+ @run main RobotExtraButton
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class RobotExtraButton extends Frame {
+ static Robot robot;
+ public static void main(String []s){
+ RobotExtraButton frame = new RobotExtraButton();
+ frame.setSize(300, 300);
+ frame.setVisible(true);
+ frame.addMouseListener(new MouseAdapter() {
+ public void mousePressed(MouseEvent e) {
+ System.out.println("PRESSED "+e);
+ }
+ public void mouseReleased(MouseEvent e) {
+ System.out.println("RELEASED "+e);
+ }
+ public void mouseClicked(MouseEvent e) {
+ System.out.println("CLICKED "+e);
+ }
+ });
+ Util.waitForIdle(robot);
+ int [] buttonMask = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ buttonMask[i] = InputEvent.getMaskForButton(i+1);
+ System.out.println("TEST: "+buttonMask[i]);
+ }
+
+ try {
+ robot = new Robot();
+ robot.mouseMove(frame.getLocationOnScreen().x + frame.getWidth()/2, frame.getLocationOnScreen().y + frame.getHeight()/2);
+ /*
+ if (MouseInfo.getNumberOfButtons() <= 3) {
+ System.out.println("Number Of Buttons = "+ MouseInfo.getNumberOfButtons() +". Finish!");
+ return;
+ }*/
+
+ System.out.println("TEST: press 1");
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.delay(50);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ Util.waitForIdle(robot);
+
+ System.out.println("TEST: press 2");
+
+ robot.mousePress(InputEvent.BUTTON2_MASK);
+ robot.delay(50);
+ robot.mouseRelease(InputEvent.BUTTON2_MASK);
+ Util.waitForIdle(robot);
+ System.out.println("TEST: press 3");
+
+ robot.mousePress(InputEvent.BUTTON3_MASK);
+ robot.delay(50);
+ robot.mouseRelease(InputEvent.BUTTON3_MASK);
+ Util.waitForIdle(robot);
+ System.out.println("--------------------------------------------------");
+ for (int i = 0; i < buttonMask.length; i++){
+ System.out.println("button would = " +i + " : value = " +buttonMask[i]);
+ robot.mousePress(buttonMask[i]);
+ robot.delay(50);
+ robot.mouseRelease(buttonMask[i]);
+ Util.waitForIdle(robot);
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+ throw new RuntimeException("Test failed.", e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_1.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,36 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that system property sun.awt.enableExtraMouseButtons is true by default
+ @author Andrei Dmitriev : area=awt.mouse
+ @run main SystemPropTest_1
+ */
+//1) Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns false initially.
+//2) Verifies that Toolkit.areExtraMouseButtonsEnabled() returns true by default.
+// This must initlizes the Toolkit class.
+//3) Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns true (default).
+import java.awt.*;
+
+public class SystemPropTest_1 {
+
+ public static void main(String []s){
+ boolean propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+ System.out.println("1. System.getProperty = " + propValue);
+ if (propValue){
+ throw new RuntimeException("TEST FAILED(1) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+ }
+ if (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+ throw new RuntimeException("TEST FAILED : Toolkit.areExtraMouseButtonsEnabled() returns false");
+ }
+
+ System.getProperties().list(System.out);
+ System.out.println("XXXX. System.getProperty = " + System.getProperty("sun.awt.enableExtraMouseButtons"));
+
+ propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+ System.out.println("2. System.getProperty = " + propValue);
+ if (!propValue){
+ throw new RuntimeException("TEST FAILED(2) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+ }
+ System.out.println("Test passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_2.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,25 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that system property sun.awt.enableExtraMouseButtons might be set to true by the command line
+ @author Andrei Dmitriev : area=awt.mouse
+ @run main/othervm -Dsun.awt.enableExtraMouseButtons=true SystemPropTest_2
+ */
+//1) Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns true if set through the command line.
+//2) Verifies that Toolkit.areExtraMouseButtonsEnabled() returns true if the proprty is set through the command line.
+import java.awt.*;
+
+public class SystemPropTest_2 {
+
+ public static void main(String []s){
+ boolean propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+ System.out.println("System.getProperty = " + propValue);
+ if (!propValue){
+ throw new RuntimeException("TEST FAILED : System property sun.awt.enableExtraMouseButtons = " + propValue);
+ }
+ if (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+ throw new RuntimeException("TEST FAILED : Toolkit.areExtraMouseButtonsEnabled() returns false");
+ }
+ System.out.println("Test passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_3.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,26 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that system property sun.awt.enableExtraMouseButtons might be set to false by the command line
+ @author Andrei Dmitriev : area=awt.mouse
+ @run main/othervm -Dsun.awt.enableExtraMouseButtons=false SystemPropTest_3
+ */
+//1) Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns false if set through the command line.
+//2) Verifies that Toolkit.areExtraMouseButtonsEnabled() returns false if the proprty is set through the command line.
+import java.awt.*;
+
+public class SystemPropTest_3 {
+
+ public static void main(String []s){
+ boolean propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+ System.out.println("Test System.getProperty = " + System.getProperty("sun.awt.enableExtraMouseButtons"));
+ System.out.println("System.getProperty = " + propValue);
+ if (propValue){
+ throw new RuntimeException("TEST FAILED : System property sun.awt.enableExtraMouseButtons = " + propValue);
+ }
+ if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+ throw new RuntimeException("TEST FAILED : Toolkit.areExtraMouseButtonsEnabled() returns true");
+ }
+ System.out.println("Test passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_4.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,42 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that system property sun.awt.enableExtraMouseButtons might be set to true by the System class API.
+ @author Andrei Dmitriev : area=awt.mouse
+ @run main SystemPropTest_4
+ */
+//1)
+// - Use System.setProperty("sun.awt.enableExtraMouseButtons", "true")
+// - Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns true
+// - Verifies that Toolkit.areExtraMouseButtonsEnabled() returns true.
+//2)
+// - Use System.setProperty("sun.awt.enableExtraMouseButtons", "false")
+// - Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns false
+// - Verifies that Toolkit.areExtraMouseButtonsEnabled() returns true still.
+
+import java.awt.*;
+
+public class SystemPropTest_4 {
+ public static void main(String []s){
+ System.out.println("STAGE 1");
+ System.setProperty("sun.awt.enableExtraMouseButtons", "true");
+ boolean propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+ if (!propValue){
+ throw new RuntimeException("TEST FAILED(1) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+ }
+ if (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+ throw new RuntimeException("TEST FAILED(1) : Toolkit.areExtraMouseButtonsEnabled() returns false");
+ }
+
+ System.out.println("STAGE 2");
+ System.setProperty("sun.awt.enableExtraMouseButtons", "false");
+ propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+ if (propValue){
+ throw new RuntimeException("TEST FAILED(2) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+ }
+ if (!Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+ throw new RuntimeException("TEST FAILED(2) : Toolkit.areExtraMouseButtonsEnabled() returns false");
+ }
+ System.out.println("Test passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/SystemPropTest_5.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,42 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that system property sun.awt.enableExtraMouseButtons might be set to false by the System class API.
+ @author Andrei Dmitriev : area=awt.mouse
+ @run main SystemPropTest_5
+ */
+//1)
+// - Use System.setProperty("sun.awt.enableExtraMouseButtons", "false")
+// - Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns false
+// - Verifies that Toolkit.areExtraMouseButtonsEnabled() returns false.
+//2)
+// - Use System.setProperty("sun.awt.enableExtraMouseButtons", "true")
+// - Verifies that System.getProperty("sun.awt.enableExtraMouseButtons") returns true
+// - Verifies that Toolkit.areExtraMouseButtonsEnabled() returns false still.
+
+import java.awt.*;
+
+public class SystemPropTest_5 {
+ public static void main(String []s){
+ System.out.println("STAGE 1");
+ System.setProperty("sun.awt.enableExtraMouseButtons", "false");
+ boolean propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+ if (propValue){
+ throw new RuntimeException("TEST FAILED(1) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+ }
+ if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+ throw new RuntimeException("TEST FAILED(1) : Toolkit.areExtraMouseButtonsEnabled() returns true");
+ }
+
+ System.out.println("STAGE 2");
+ System.setProperty("sun.awt.enableExtraMouseButtons", "true");
+ propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+ if (!propValue){
+ throw new RuntimeException("TEST FAILED(2) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+ }
+ if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled()){
+ throw new RuntimeException("TEST FAILED(2) : Toolkit.areExtraMouseButtonsEnabled() returns true");
+ }
+ System.out.println("Test passed.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Disable.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,143 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that sun.awt.enableExtraMouseButtons = false consumes extra events
+ @author Andrei Dmitriev : area=awt.mouse
+ @run main/othervm -Dsun.awt.enableExtraMouseButtons=false ToolkitPropertyTest_Disable
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+// Testcase 1: set to FALSE and check
+// Testcase 2: set to FALSE and check that extra events are not coming
+// check that standard events are coming
+
+public class ToolkitPropertyTest_Disable extends Frame {
+ static boolean propValue;
+ static Robot robot;
+ static int [] buttonsPressed;
+ static int [] buttonsReleased;
+ static int [] buttonsClicked;
+
+ static boolean lessThenFourButtons;
+
+ public static void main(String []s){
+ propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+ buttonsPressed = new int [MouseInfo.getNumberOfButtons()];
+ buttonsReleased = new int [MouseInfo.getNumberOfButtons()];
+ buttonsClicked = new int [MouseInfo.getNumberOfButtons()];
+
+ ToolkitPropertyTest_Disable frame = new ToolkitPropertyTest_Disable();
+ frame.setSize(300, 300);
+ frame.setVisible(true);
+
+ MouseAdapter ma1 = new MouseAdapter() {
+ public void mousePressed(MouseEvent e) {
+ buttonsPressed[e.getButton() - 1] += 1;
+ System.out.println("PRESSED "+e);
+ }
+ public void mouseReleased(MouseEvent e) {
+ buttonsReleased[e.getButton() - 1] += 1;
+ System.out.println("RELEASED "+e);
+ }
+ public void mouseClicked(MouseEvent e) {
+ buttonsClicked[e.getButton() - 1] += 1;
+ System.out.println("CLICKED "+e);
+ }
+ };
+
+ try {
+ robot = new Robot();
+ robot.delay(1000);
+ robot.mouseMove(frame.getLocationOnScreen().x + frame.getWidth()/2, frame.getLocationOnScreen().y + frame.getHeight()/2);
+
+ System.out.println("Property = " + propValue);
+ testCase0();
+
+ testCase1();
+ System.out.println("Number Of Buttons = "+ MouseInfo.getNumberOfButtons());
+
+ lessThenFourButtons = (MouseInfo.getNumberOfButtons() <= 3);
+ if ( !lessThenFourButtons ) {
+ frame.addMouseListener(ma1);
+ testCase2();
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+// throw new RuntimeException(e);
+ } finally {
+// frame.removeMouseListener(ma1);
+ }
+ }
+
+ public static void testCase0(){
+ if (propValue){
+ throw new RuntimeException("TEST FAILED (0): System property sun.awt.enableExtraMouseButtons = " + propValue);
+ }
+ }
+
+ public static void testCase1(){
+ if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled() == true){
+ throw new RuntimeException("TEST FAILED (1): setting to FALSE. Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled() = " + Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled());
+ }
+ }
+
+ public static void testCase2(){
+ emptyArrays();
+ int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ buttonMasks[i] = InputEvent.getMaskForButton(i+1);
+ System.out.println("TEST: "+buttonMasks[i]);
+ }
+
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ System.out.println("button to press = " +(i+1) + " : value passed to robot = " +buttonMasks[i]);
+ try {
+ robot.mousePress(buttonMasks[i]);
+ robot.delay(70);
+ robot.mouseRelease(buttonMasks[i]);
+ robot.delay(200);
+ //no exception is thrown
+ if (i >= 3) {
+ throw new RuntimeException("TESTCASE 2 FAILED : robot accepted the extra button " + (i+1) + " instead of throwing an exception.");
+ }
+ } catch (IllegalArgumentException e){
+ if (i >= 3) {
+ System.out.println("Passed: an exception caught for extra button.");
+ } else {
+ throw new RuntimeException("TESTCASE 2 FAILED : exception happen on standard button.", e);
+ }
+ }
+ }
+ robot.delay(2000);
+ if (MouseInfo.getNumberOfButtons() < 3) {
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ if (buttonsPressed[i] != 1 || buttonsReleased[i] != 1 || buttonsClicked[i] !=1 ) {
+ throw new RuntimeException("TESTCASE 2 FAILED : button " + (i+1) + " wasn't single pressed.");
+ }
+ }
+ } else {
+ for (int i = 0; i < 3; i++){
+ if (buttonsPressed[i] != 1 || buttonsReleased[i] != 1 || buttonsClicked[i] !=1 ) {
+ throw new RuntimeException("TESTCASE 2 FAILED : button " + (i+1) + " wasn't single pressed.");
+ }
+ }
+
+ for (int i = 3; i < MouseInfo.getNumberOfButtons(); i++){
+ if (buttonsPressed[i] != 0 || buttonsReleased[i] != 0 || buttonsClicked[i] != 0 ) {
+ throw new RuntimeException("TESTCASE 2 FAILED : button " + (i+1) + " was pressed.");
+ }
+ }
+ }
+ }
+
+ public static void emptyArrays(){
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ buttonsPressed[i] = 0;
+ buttonsReleased[i] = 0;
+ buttonsClicked[i] = 0;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,120 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that sun.awt.enableExtraMouseButtons is working
+ @author Andrei Dmitriev : area=awt.mouse
+ @run main/othervm -Dsun.awt.enableExtraMouseButtons=true ToolkitPropertyTest_Enable
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+// Testcase 1: set to TRUE (via jtreg option)
+// Testcase 2: set to TRUE and check that extra events are coming
+// check that standard events are coming
+
+public class ToolkitPropertyTest_Enable extends Frame {
+ static boolean propValue;
+ static Robot robot;
+ static int [] buttonsPressed;
+ static int [] buttonsReleased;
+ static int [] buttonsClicked;
+
+ public static void main(String []s){
+ propValue = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons"));
+ buttonsPressed = new int [MouseInfo.getNumberOfButtons()];
+ buttonsReleased = new int [MouseInfo.getNumberOfButtons()];
+ buttonsClicked = new int [MouseInfo.getNumberOfButtons()];
+
+ ToolkitPropertyTest_Enable frame = new ToolkitPropertyTest_Enable();
+ frame.setSize(300, 300);
+ frame.setVisible(true);
+
+ MouseAdapter ma1 = new MouseAdapter() {
+ public void mousePressed(MouseEvent e) {
+ buttonsPressed[e.getButton() - 1] += 1;
+ System.out.println("PRESSED "+e);
+ }
+ public void mouseReleased(MouseEvent e) {
+ buttonsReleased[e.getButton() - 1] += 1;
+ System.out.println("RELEASED "+e);
+ }
+ public void mouseClicked(MouseEvent e) {
+ buttonsClicked[e.getButton() - 1] += 1;
+ System.out.println("CLICKED "+e);
+ }
+ };
+ // frame.addMouseListener(ma1);
+
+ try {
+ robot = new Robot();
+ robot.delay(1000);
+ robot.mouseMove(frame.getLocationOnScreen().x + frame.getWidth()/2, frame.getLocationOnScreen().y + frame.getHeight()/2);
+
+ System.out.println("Property = " + propValue);
+ testCase0();
+
+ testCase1();
+ System.out.println("Number Of Buttons = "+ MouseInfo.getNumberOfButtons());
+
+ boolean lessThenFourButtons = (MouseInfo.getNumberOfButtons() <= 3);
+ if ( !lessThenFourButtons ) {
+ frame.addMouseListener(ma1);
+ testCase2();
+ // testCase3();
+ // testCase4();
+ frame.removeMouseListener(ma1);
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ public static void testCase0(){
+ if (!propValue){
+ throw new RuntimeException("TEST FAILED (0) : System property sun.awt.enableExtraMouseButtons = " + propValue);
+ }
+ }
+
+ public static void testCase1(){
+ if (Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled() == false){
+ throw new RuntimeException("TEST FAILED (1) : setting to TRUE. enabled = " + Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled());
+ }
+ }
+
+ public static void testCase2(){
+ emptyArrays();
+ //we can't post a message from an unexistent button
+ int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ buttonMasks[i] = InputEvent.getMaskForButton(i+1);
+ System.out.println("TEST: "+buttonMasks[i]);
+ }
+
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ System.out.println("button to press = " +(i+1) + " : value passed to robot = " +buttonMasks[i]);
+ robot.mousePress(buttonMasks[i]);
+ robot.delay(70);
+ robot.mouseRelease(buttonMasks[i]);
+ robot.delay(200);
+ }
+ robot.delay(1000);
+
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ if (buttonsPressed[i] != 1 || buttonsReleased[i] != 1 || buttonsClicked[i] !=1 ) {
+ throw new RuntimeException("TESTCASE 2 FAILED : button " + (i+1) + " wasn't single pressed|released|clicked : "+ buttonsPressed[i] +" : "+ buttonsReleased[i] +" : "+ buttonsClicked[i]);
+ }
+ }
+ }
+
+ public static void emptyArrays(){
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ buttonsPressed[i] = 0;
+ buttonsReleased[i] = 0;
+ buttonsClicked[i] = 0;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/InputEvent/ButtonArraysEquality/ButtonArraysEquality.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,83 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that InputEvents button masks arrays are the same
+ @author Andrei Dmitriev : area=awt.event
+ @run main ButtonArraysEquality
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+// get array InputEvent.BUTTON_MASK via reflection
+// get array InputEvent.BUTTON_DOWN_MASK via reflection
+// compare their lengths and values
+
+public class ButtonArraysEquality {
+ static int [] eventDownMask = new int []{InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON2_DOWN_MASK, InputEvent.BUTTON3_DOWN_MASK};
+
+ public static void main(String []s){
+ int [] buttonDownMasksAPI = new int [MouseInfo.getNumberOfButtons()];
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ buttonDownMasksAPI[i] = InputEvent.getMaskForButton(i+1);
+ System.out.println("TEST: "+buttonDownMasksAPI[i]);
+ }
+
+ // getButtonDownMasks()
+ Object obj = AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ try {
+ Class clazz = Class.forName("java.awt.event.InputEvent");
+ Method method = clazz.getDeclaredMethod("getButtonDownMasks",new Class [] {});
+ if (method != null) {
+ method.setAccessible(true);
+ return method.invoke(null, (Object[])null);
+ }
+ }catch (Exception e){
+ throw new RuntimeException("Test failed. Exception occured:", e);
+ }
+ return null;
+ }
+ });
+
+ int [] buttonDownMasks = new int [Array.getLength(obj)];
+ checkNullAndPutValuesToArray(buttonDownMasks, obj);
+
+ //check lengths: array shouldn't contain less elements then the number of buttons on a mouse
+ if (buttonDownMasks.length < buttonDownMasksAPI.length){
+ throw new RuntimeException("Test failed. The lengths array is less then the number of buttons");
+ }
+
+ // verify values for first three buttons
+ for (int i = 0; i < 3; i++) {
+ if (eventDownMask[i] != buttonDownMasks[i])
+ {
+ System.out.println("Test : "+ i + " | " + " | " +eventDownMask[i] + " | "+ buttonDownMasks[i]);
+ throw new RuntimeException("Failure: masks are not correct for standard buttons");
+ }
+ }
+
+ // verify values for extra buttons if any
+ for (int i = 3; i < MouseInfo.getNumberOfButtons(); i++) {
+ if (buttonDownMasksAPI[i] != buttonDownMasks[i]) {
+ throw new RuntimeException("Failure: masks are not the same for extra buttons");
+ }
+ }
+ System.out.println("Test passed.");
+ }
+
+ public static void checkNullAndPutValuesToArray(int [] array, Object obj){
+ if (obj == null){
+ throw new RuntimeException("Test failed. The array obtained via reflection is "+obj);
+ }
+
+ for (int i = 0; i < Array.getLength(obj); i++){
+ System.out.println("Test (Reflection): "+ Array.getInt(obj, i));
+ array[i] = Array.getInt(obj, i);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/MouseEvent/AcceptExtraButton/AcceptExtraButton.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,53 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that MouseEvent CTOR accepts extra mouse button numbers
+ @author Andrei Dmitriev : area=awt.event
+ @run main AcceptExtraButton
+ */
+
+//package acceptextrabutton;
+
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseAdapter;
+
+public class AcceptExtraButton extends Frame {
+ static int [] eventID = new int []{MouseEvent.MOUSE_PRESSED, MouseEvent.MOUSE_RELEASED, MouseEvent.MOUSE_CLICKED};
+
+ public static void main(String []s){
+ AcceptExtraButton f = new AcceptExtraButton();
+ f.setSize(300, 300);
+ f.setVisible(true);
+
+ for (int buttonId = 0; buttonId<eventID.length; buttonId++) {
+ for (int button = 0; button <= MouseInfo.getNumberOfButtons(); button++){
+ System.out.println("button == "+button);
+ MouseEvent me = new MouseEvent(f,
+ eventID[buttonId],
+ System.currentTimeMillis(),
+ 0, //MouseEvent.BUTTON1_DOWN_MASK, modifiers
+ 100, 100, // x, y
+ 150, 150, // x, y on screen
+ 1, //clickCount
+ false, //popupTrigger
+ button );// MouseEvent.NOBUTTON : button
+
+ System.out.println("dispatching >>>"+me);
+ f.dispatchEvent( ( AWTEvent )me );
+ }
+ }
+ MouseAdapter ma1 = new MouseAdapter() {
+ public void mousePressed(MouseEvent e) {
+ System.out.println("PRESSED "+e);
+ }
+ public void mouseReleased(MouseEvent e) {
+ System.out.println("RELEASED "+e);
+ }
+ public void mouseClicked(MouseEvent e) {
+ System.out.println("CLICKED "+e);
+ }
+ };
+ f.addMouseListener(ma1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/MouseEvent/CTORRestrictions/CTORRestrictions.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,89 @@
+/*
+ test %I% %E%
+ @bug 6315717
+ @summary verifies that MouseEvent could be constructed correctly for mouse extra buttons in regard to sun.awt.enableExtraMouseButtons property
+ @author Andrei Dmitriev : area=awt.event
+ @run main CTORRestrictions
+ */
+
+/*
+ * verify that user can create the MouseEvent? with button1|2|3|4|5|... when property "sun.awt.enableExtraMouseButtons" is true by default
+ */
+import java.awt.*;
+import java.awt.event.*;
+
+public class CTORRestrictions{
+ static Frame frame = new Frame("MouseEvent Test Frame");
+ static Point mousePosition;
+ static Point mousePositionOnScreen;
+
+ public static void main(String []s){
+ Robot robot = null;
+ try {
+ robot = new Robot();
+ } catch (AWTException ex) {
+ throw new RuntimeException("Test Failed", ex);
+ }
+ frame.setSize (200,200);
+ frame.setLocation (300, 400);
+ frame.setVisible(true);
+ robot.delay(1000);
+ System.out.println("sun.awt.enableExtraMouseButtons = "+Toolkit.getDefaultToolkit().getDesktopProperty("sun.awt.enableExtraMouseButtons"));
+ mousePosition = new Point(100, 100);
+ mousePositionOnScreen = new Point(frame.getLocationOnScreen().x + mousePosition.x,
+ frame.getLocationOnScreen().y + mousePosition.y);
+
+ /*
+ * On Linux the native system count a wheel (both directions) as two more buttons on a mouse.
+ * So, MouseInfo.getNumberOfButtons() would report 5 buttons on a three-button mouse.
+ * On Windows it would still report that MouseInfo.getNumberOfButtons() == 3.
+ * We should handle XToolkit case and iterate through the buttons
+ * up to (MouseInfo.getNumberOfButtons() - 2) value.
+ */
+ int numberOfButtons;
+ if (Toolkit.getDefaultToolkit().getClass().getName().equals("sun.awt.windows.WToolkit")){
+ numberOfButtons = MouseInfo.getNumberOfButtons();
+ } else {
+ numberOfButtons = MouseInfo.getNumberOfButtons() - 2;
+ }
+ System.out.println("Stage 1. Number of buttons = "+ numberOfButtons);
+
+ for (int buttonId = 1; buttonId <= numberOfButtons; buttonId++){
+ postMouseEventNewCtor(buttonId);
+ }
+
+ System.out.println("Stage 2. Number of buttons = "+ numberOfButtons);
+ for (int buttonId = 1; buttonId <= numberOfButtons; buttonId++){
+ postMouseEventOldCtor(buttonId);
+ }
+ System.out.println("Test passed.");
+ }
+
+ public static void postMouseEventNewCtor(int buttonId) {
+ MouseEvent me = new MouseEvent(frame,
+ MouseEvent.MOUSE_PRESSED,
+ System.currentTimeMillis(),
+ MouseEvent.BUTTON1_DOWN_MASK,
+ mousePosition.x, mousePosition.y,
+ mousePositionOnScreen.x,
+ mousePositionOnScreen.y,
+ 1,
+ false, //popupTrigger
+ buttonId //button
+ );
+ frame.dispatchEvent( ( AWTEvent )me );
+ }
+
+ public static void postMouseEventOldCtor(int buttonId) {
+ MouseEvent meOld = new MouseEvent(frame,
+ MouseEvent.MOUSE_PRESSED,
+ System.currentTimeMillis(),
+ MouseEvent.BUTTON1_DOWN_MASK,
+ mousePosition.x, mousePosition.y,
+ 1,
+ false, //popupTrigger
+ buttonId //button
+ );
+ frame.dispatchEvent( ( AWTEvent )meOld );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/MouseEvent/CTORRestrictions/CTORRestrictions_Disable.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,101 @@
+/*
+ test %I% %E%
+ @bug 6315717
+ @summary verifies that MouseEvent could be constructed correctly for mouse extra buttons in regard to sun.awt.enableExtraMouseButtons property
+ @author Andrei Dmitriev : area=awt.event
+ @run main/othervm -Dsun.awt.enableExtraMouseButtons=false CTORRestrictions_Disable
+ */
+
+/*
+ * verify that user can't create the MouseEvent? with button4|5|... when property "sun.awt.enableExtraMouseButtons"=false
+ * verify that user can create the MouseEvent? with button1|2|3 when property "sun.awt.enableExtraMouseButtons"=false
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class CTORRestrictions_Disable {
+ static Frame frame = new Frame("MouseEvent Test Frame");
+ static Point mousePosition;
+ static Point mousePositionOnScreen;
+
+ public static void main(String []s){
+ Robot robot = null;
+ try {
+ robot = new Robot();
+ } catch (AWTException ex) {
+ throw new RuntimeException("Test Failed", ex);
+ }
+ frame.setSize (200,200);
+ frame.setLocation (300, 400);
+ frame.setVisible(true);
+ robot.delay(1000);
+ System.out.println(Toolkit.getDefaultToolkit().getDesktopProperty("sun.awt.enableExtraMouseButtons"));
+ mousePosition = new Point(100, 100);
+ mousePositionOnScreen = new Point(frame.getLocationOnScreen().x + mousePosition.x,
+ frame.getLocationOnScreen().y + mousePosition.y);
+
+ System.out.println("Stage 1");
+ for (int buttonId = 1; buttonId <= MouseInfo.getNumberOfButtons(); buttonId++){
+ try {
+ postMouseEventNewCtor(buttonId);
+ if (buttonId > 3) {
+ throw new RuntimeException("Stage 1 FAILED: MouseEvent CTOR accepted the extra button " + (buttonId+1) + " instead of throwing an exception.");
+ }
+ } catch (IllegalArgumentException e){
+ if (buttonId > 3) {
+ System.out.println("Passed: an exception caught for extra button.");
+ } else {
+ throw new RuntimeException("Stage 1 FAILED : exception happen on standard button.", e);
+ }
+ }
+ }
+
+ System.out.println("Stage 2");
+ for (int buttonId = 1; buttonId <= MouseInfo.getNumberOfButtons(); buttonId++){
+ try {
+ postMouseEventOldCtor(buttonId);
+ if (buttonId > 3) {
+ throw new RuntimeException("Stage 2 FAILED: MouseEvent CTOR accepted the extra button " + (buttonId+1) + " instead of throwing an exception.");
+ }
+ } catch (IllegalArgumentException e){
+ if (buttonId > 3) {
+ System.out.println("Passed: an exception caught for extra button.");
+ } else {
+ throw new RuntimeException("Stage 2 FAILED : exception happen on standard button.", e);
+ }
+ }
+ }
+ System.out.println("Test passed.");
+ }
+
+ public static void postMouseEventNewCtor(int buttonId) {
+ MouseEvent me = new MouseEvent(frame,
+ MouseEvent.MOUSE_PRESSED,
+ System.currentTimeMillis(),
+ MouseEvent.BUTTON1_DOWN_MASK,
+ mousePosition.x, mousePosition.y,
+ mousePositionOnScreen.x,
+ mousePositionOnScreen.y,
+ 1,
+ false, //popupTrigger
+ buttonId //button
+ );
+ frame.dispatchEvent( ( AWTEvent )me );
+ }
+
+ public static void postMouseEventOldCtor(int buttonId) {
+ MouseEvent meOld = new MouseEvent(frame,
+ MouseEvent.MOUSE_PRESSED,
+ System.currentTimeMillis(),
+ MouseEvent.BUTTON1_DOWN_MASK,
+ mousePosition.x, mousePosition.y,
+ 1,
+ false, //popupTrigger
+ buttonId //button
+ );
+ frame.dispatchEvent( ( AWTEvent )meOld );
+ }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/MouseEvent/CheckGetMaskForButton/CheckGetMaskForButton.java Tue Sep 16 12:17:02 2008 +0400
@@ -0,0 +1,65 @@
+/*
+ @test %I% %E%
+ @bug 6315717
+ @summary verifies that InputEvent.getMaskForButton() returns the same values as in InputEvent.BUTTON_DOWN_MASK
+ @author Andrei Dmitriev : area=awt.event
+ @run main CheckGetMaskForButton
+*/
+
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class CheckGetMaskForButton{
+ static Robot robot;
+
+ public static void main(String []s){
+ System.out.println("Number Of Buttons = "+ MouseInfo.getNumberOfButtons());
+ CheckGetMaskForButton f = new CheckGetMaskForButton();
+ int [] buttonMasksViaAPI = new int[MouseInfo.getNumberOfButtons()];
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ buttonMasksViaAPI[i] = InputEvent.getMaskForButton(i+1);
+ System.out.println("Test (API): "+ buttonMasksViaAPI[i]);
+ }
+
+ //get same array via reflection
+ Object obj = AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ try {
+ Class clazz = Class.forName("java.awt.event.InputEvent");
+ Method method = clazz.getDeclaredMethod("getButtonDownMasks",new Class [] {});
+ if (method != null) {
+ method.setAccessible(true);
+ return method.invoke(null, (Object[])null);
+ }
+ }catch (Exception e){
+ throw new RuntimeException("Test failed. Exception occured:", e);
+ }
+ return null;
+ }
+ });
+
+ if (obj == null){
+ throw new RuntimeException("Test failed. The value obtained via reflection is "+obj);
+ }
+
+ int [] buttonDownMasksViaReflection = new int [Array.getLength(obj)];
+ //check that length of API array greater or equals then Reflect array.
+ if (Array.getLength(obj) < buttonMasksViaAPI.length){
+ throw new RuntimeException("Test failed. The length of API array greater or equals then the length of Reflect array.");
+ }
+
+ //Check that the values obtained via reflection from InputEvent.BUTTON_DOWN_MASK are the
+ // same as for standard API.
+ for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
+ System.out.println("Test (Reflection): "+ Array.getInt(obj, i));
+ if (buttonMasksViaAPI[i] != Array.getInt(obj, i)){
+ throw new RuntimeException("Test failed. Values of InputEvent array are different for API and Reflection invocations");
+ }
+ }
+ System.out.println("Test passed.");
+ }
+}