提交 aea6bd2a 编写于 作者: D dav

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
上级 c8f086e1
......@@ -151,6 +151,7 @@ SUNWprivate_1.1 {
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;
......
......@@ -70,10 +70,7 @@ public class Robot {
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 @@ public class Robot {
}
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 @@ public class Robot {
/**
* 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
* 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.
*
* @param buttons the Button mask; a combination of one or more
* of these flags:
* The valid combination also depends on a
* {@link Toolkit#areExtraMouseButtonsEnabled() Toolkit.areExtraMouseButtonsEnabled()} value as follows:
* <ul>
* <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>
* <p>
* The following standard button masks are also accepted:
* <ul>
* <li><code>InputEvent.BUTTON1_MASK</code>
* <li><code>InputEvent.BUTTON2_MASK</code>
* <li><code>InputEvent.BUTTON3_MASK</code>
* <li>{@code InputEvent.BUTTON1_MASK}
* <li>{@code InputEvent.BUTTON2_MASK}
* <li>{@code InputEvent.BUTTON3_MASK}
* </ul>
* @throws IllegalArgumentException if the button mask is not a
* valid combination
* 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 @@ public class Robot {
/**
* 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> 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</code>
* <li><code>InputEvent.BUTTON2_MASK</code>
* <li><code>InputEvent.BUTTON3_MASK</code>
* <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);
......
/*
* 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 @@ public abstract class Toolkit {
}
}
}
/**
* 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();
}
}
<!--
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 @@ here, and their value types.
<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 @@ So to determine if there are per-device settings it is sufficient to
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>
......@@ -31,6 +31,7 @@ import java.awt.GraphicsEnvironment;
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 abstract class InputEvent extends ComponentEvent {
*/
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 @@ public abstract class InputEvent extends ComponentEvent {
* 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 @@ public abstract class InputEvent extends ComponentEvent {
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 '+'
......
......@@ -32,6 +32,7 @@ import java.awt.Toolkit;
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 @@ import java.awt.IllegalComponentStateException;
* 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 @@ public class MouseEvent extends InputEvent {
/**
* 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;
......@@ -384,6 +411,15 @@ public class MouseEvent extends InputEvent {
return new Point(xAbs, yAbs);
}
/**
* 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
......@@ -421,7 +457,8 @@ public class MouseEvent extends InputEvent {
/**
* 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 @@ public class MouseEvent extends InputEvent {
* @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 @@ public class MouseEvent extends InputEvent {
/**
* 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 @@ public class MouseEvent extends InputEvent {
}
/* 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 @@ public class MouseEvent extends InputEvent {
* @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 @@ public class MouseEvent extends InputEvent {
* @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 @@ public class MouseEvent extends InputEvent {
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 @@ public class MouseEvent extends InputEvent {
/**
* 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 @@ public class MouseEvent extends InputEvent {
* 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 @@ public class MouseEvent extends InputEvent {
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 @@ public class MouseEvent extends InputEvent {
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);
......
/*
* 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 interface RobotPeer
public int [] getRGBPixels(Rectangle bounds);
public void dispose();
public int getNumberOfButtons();
}
/*
* 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 @@ public class HeadlessToolkit extends Toolkit
throws HeadlessException{
throw new HeadlessException();
}
public boolean areExtraMouseButtonsEnabled() throws HeadlessException{
throw new HeadlessException();
}
}
......@@ -979,8 +979,13 @@ public class XBaseWindow {
*/
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 @@ public class XBaseWindow {
* 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) {
......
......@@ -197,12 +197,30 @@ final public class XConstants {
/* 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 @@ final public class XConstants {
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 */
......
......@@ -694,8 +694,8 @@ public final class XDragSourceContextPeer
} 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)
......
/*
* 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 @@ class XRobotPeer implements RobotPeer {
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);
......
......@@ -74,6 +74,10 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
// 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 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
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 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
}
}
private int getNumMouseButtons() {
public static int getNumMouseButtons() {
awtLock();
try {
return XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), 0, 0);
......@@ -2166,4 +2173,8 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
}
public static native void setNoisyXErrorHandler();
public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
return areExtraMouseButtonsEnabled;
}
}
......@@ -553,6 +553,10 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
}
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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
}
}
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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
/* 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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
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;
......
......@@ -1936,7 +1936,13 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
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 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
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
......
/*
* 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 @@ extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
// 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 @@ JNIEXPORT void JNICALL
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,10 +242,17 @@ Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls) {
}
getNumButtons();
finally:
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
Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
jclass cls,
......@@ -352,6 +380,8 @@ JNIEXPORT void JNICALL
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 @@ Java_sun_awt_X11_XRobotPeer_mousePressImpl (JNIEnv *env,
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 @@ Java_sun_awt_X11_XRobotPeer_mouseReleaseImpl (JNIEnv *env,
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,
......
/*
* 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 @@ class WRobotPeer extends WObjectPeer implements RobotPeer
}
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);
......
......@@ -80,6 +80,10 @@ public class WToolkit extends SunToolkit implements Runnable {
// 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 @@ public class WToolkit extends SunToolkit implements Runnable {
// 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 @@ public class WToolkit extends SunToolkit implements Runnable {
return new WDesktopPeer();
}
public static native void setExtraMouseButtonsEnabledNative(boolean enable);
public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
return areExtraMouseButtonsEnabled;
}
}
......@@ -187,6 +187,8 @@ LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0));
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 @@ void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) {
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 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
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 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
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 @@ MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y)
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 @@ AwtComponent::GetJavaModifiers()
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 @@ AwtComponent::GetJavaModifiers()
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 @@ AwtComponent::GetButton(int mouseButton)
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 @@ AwtComponent::GetButtonMK(int mouseButton)
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 @@ AwtComponent::GetButtonMK(int mouseButton)
#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 @@ void AwtComponent::SynthesizeMouseMessage(JNIEnv *env, jobject mouseEvent)
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 @@ JNIEXPORT void JNICALL
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");
......
......@@ -53,6 +53,22 @@ const UINT MAX_ACP_STR_LEN = 7; // ANSI CP identifiers are no longer than this
#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 @@ enum MsgRouting {
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 @@ public:
static jmethodID replaceSurfaceDataLaterMID;
static const UINT WmAwtIsComponent;
static jint * masks; //InputEvent mask array
AwtComponent();
virtual ~AwtComponent();
......
......@@ -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 @@ void AwtRobot::MousePress( jint buttonMask )
// 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 @@ void AwtRobot::MouseRelease( jint buttonMask )
// 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 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WRobotPeer_keyRelease(
CATCH_BAD_ALLOC;
}
JNIEXPORT jint JNICALL Java_sun_awt_windows_WRobotPeer_getNumberOfButtons(
JNIEnv *, jobject self)
{
return GetSystemMetrics(SM_CMOUSEBUTTONS);
}
/*
* 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 @@ class AwtRobot : public AwtObject
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:
......
......@@ -322,6 +322,7 @@ AwtToolkit::AwtToolkit() {
m_vmSignalled = FALSE;
m_isDynamicLayoutSet = FALSE;
m_areExtraMouseButtonsEnabled = TRUE;
m_verifyComponents = FALSE;
m_breakOnError = FALSE;
......@@ -2092,3 +2093,26 @@ Java_sun_awt_SunToolkit_closeSplashScreen(JNIEnv *env, jclass cls)
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;
}
......@@ -175,6 +175,8 @@ public:
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 @@ private:
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
......
......@@ -393,7 +393,7 @@ MsgRouting AwtTrayIcon::WmMouseMove(UINT flags, int x, int y)
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,
......
/*
@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);
}
}
/*
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;
}
}
*/
/*
@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);
}
}
}
/*
@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);
}
}
}
/*
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
/*
@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);
}
}
}
/*
@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.");
}
}
/*
@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.");
}
}
/*
@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.");
}
}
/*
@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.");
}
}
/*
@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.");
}
}
/*
@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;
}
}
}
/*
@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;
}
}
}
/*
@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);
}
}
}
/*
@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);
}
}
/*
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 );
}
}
/*
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 );
}
}
/*
@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.");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册