6799099: All automatic regression tests that create Robot fail on X11
Reviewed-by: art, ant
This commit is contained in:
parent
b02a9e2e05
commit
072ba357bf
@ -155,7 +155,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_sun_awt_X11_XToolkit_getNumberOfButtonsImpl;
|
||||
Java_java_awt_Component_initIDs;
|
||||
Java_java_awt_Container_initIDs;
|
||||
Java_java_awt_Button_initIDs;
|
||||
|
@ -96,9 +96,13 @@ 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);
|
||||
if (Toolkit.getDefaultToolkit() instanceof SunToolkit) {
|
||||
final int buttonsNumber = ((SunToolkit)(Toolkit.getDefaultToolkit())).getNumberOfButtons();
|
||||
for (int i = 0; i < buttonsNumber; i++){
|
||||
tmpMask |= InputEvent.getMaskForButton(i+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
tmpMask |= InputEvent.BUTTON1_MASK|
|
||||
|
@ -157,6 +157,8 @@ public abstract class InputEvent extends ComponentEvent {
|
||||
/**
|
||||
* An array of extended modifiers for additional buttons.
|
||||
* @see getButtonDownMasks
|
||||
* There are twenty buttons fit into 4byte space.
|
||||
* one more bit is reserved for FIRST_HIGH_BIT.
|
||||
* @since 7.0
|
||||
*/
|
||||
private static final int [] BUTTON_DOWN_MASK = new int [] { BUTTON1_DOWN_MASK,
|
||||
@ -169,7 +171,16 @@ public abstract class InputEvent extends ComponentEvent {
|
||||
1<<18,
|
||||
1<<19,
|
||||
1<<20,
|
||||
1<<21 };
|
||||
1<<21,
|
||||
1<<22,
|
||||
1<<23,
|
||||
1<<24,
|
||||
1<<25,
|
||||
1<<26,
|
||||
1<<27,
|
||||
1<<28,
|
||||
1<<29,
|
||||
1<<30};
|
||||
|
||||
/**
|
||||
* A method to access an array of extended modifiers for additional buttons.
|
||||
@ -240,7 +251,7 @@ public abstract class InputEvent extends ComponentEvent {
|
||||
// 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 << 22;
|
||||
static final int FIRST_HIGH_BIT = 1 << 31;
|
||||
|
||||
static final int JDK_1_3_MODIFIERS = SHIFT_DOWN_MASK - 1;
|
||||
static final int HIGH_MODIFIERS = ~( FIRST_HIGH_BIT - 1 );
|
||||
|
@ -33,6 +33,7 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.awt.IllegalComponentStateException;
|
||||
import java.awt.MouseInfo;
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
/**
|
||||
* An event which indicates that a mouse action occurred in a component.
|
||||
@ -379,12 +380,25 @@ public class MouseEvent extends InputEvent {
|
||||
*/
|
||||
private static final long serialVersionUID = -991214153494842848L;
|
||||
|
||||
/**
|
||||
* A number of buttons available on the mouse at the {@code Toolkit} machinery startup.
|
||||
*/
|
||||
private static int cachedNumberOfButtons;
|
||||
|
||||
static {
|
||||
/* ensure that the necessary native libraries are loaded */
|
||||
NativeLibLoader.loadLibraries();
|
||||
if (!GraphicsEnvironment.isHeadless()) {
|
||||
initIDs();
|
||||
}
|
||||
final Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
if (tk instanceof SunToolkit) {
|
||||
cachedNumberOfButtons = ((SunToolkit)tk).getNumberOfButtons();
|
||||
} else {
|
||||
//It's expected that some toolkits (Headless,
|
||||
//whatever besides SunToolkit) could also operate.
|
||||
cachedNumberOfButtons = 3;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -411,15 +425,6 @@ 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
|
||||
@ -735,7 +740,6 @@ public class MouseEvent extends InputEvent {
|
||||
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);
|
||||
|
@ -121,11 +121,4 @@ public interface RobotPeer
|
||||
* Disposes the robot peer when it is not needed anymore.
|
||||
*/
|
||||
void dispose();
|
||||
|
||||
/**
|
||||
* Returns the number of buttons that the robot simulates.
|
||||
*
|
||||
* @return the number of buttons that the robot simulates
|
||||
*/
|
||||
int getNumberOfButtons();
|
||||
}
|
||||
|
@ -89,6 +89,25 @@ public abstract class SunToolkit extends Toolkit
|
||||
*/
|
||||
private static final String POST_EVENT_QUEUE_KEY = "PostEventQueue";
|
||||
|
||||
/**
|
||||
* Number of buttons.
|
||||
* By default it's taken from the system. If system value does not
|
||||
* fit into int type range, use our own MAX_BUTTONS_SUPPORT value.
|
||||
*/
|
||||
protected static int numberOfButtons = 0;
|
||||
|
||||
|
||||
/* XFree standard mention 24 buttons as maximum:
|
||||
* http://www.xfree86.org/current/mouse.4.html
|
||||
* We workaround systems supporting more than 24 buttons.
|
||||
* Otherwise, we have to use long type values as masks
|
||||
* which leads to API change.
|
||||
* InputEvent.BUTTON_DOWN_MASK may contain only 21 masks due to
|
||||
* the 4-bytes limit for the int type. (CR 6799099)
|
||||
* One more bit is reserved for FIRST_HIGH_BIT.
|
||||
*/
|
||||
public final static int MAX_BUTTONS_SUPPORTED = 20;
|
||||
|
||||
public SunToolkit() {
|
||||
/* If awt.threadgroup is set to class name the instance of
|
||||
* this class is created (should be subclass of ThreadGroup)
|
||||
@ -2079,6 +2098,12 @@ public abstract class SunToolkit extends Toolkit
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Descendants of the SunToolkit should override and put their own logic here.
|
||||
*/
|
||||
public int getNumberOfButtons(){
|
||||
return 3;
|
||||
}
|
||||
} // class SunToolkit
|
||||
|
||||
|
||||
|
@ -989,8 +989,17 @@ public class XBaseWindow {
|
||||
*/
|
||||
public void handleButtonPressRelease(XEvent xev) {
|
||||
XButtonEvent xbe = xev.get_xbutton();
|
||||
/*
|
||||
* Ignore the buttons above 20 due to the bit limit for
|
||||
* InputEvent.BUTTON_DOWN_MASK.
|
||||
* One more bit is reserved for FIRST_HIGH_BIT.
|
||||
*/
|
||||
if (xbe.get_button() > SunToolkit.MAX_BUTTONS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
int buttonState = 0;
|
||||
for (int i = 0; i<XToolkit.getNumMouseButtons(); i++){
|
||||
final int buttonsNumber = ((SunToolkit)(Toolkit.getDefaultToolkit())).getNumberOfButtons();
|
||||
for (int i = 0; i<buttonsNumber; 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]);
|
||||
@ -1026,7 +1035,9 @@ public class XBaseWindow {
|
||||
* Checks ButtonRelease released all Mouse buttons
|
||||
*/
|
||||
static boolean isFullRelease(int buttonState, int button) {
|
||||
if (button < 0 || button > XToolkit.getNumMouseButtons()) {
|
||||
final int buttonsNumber = ((SunToolkit)(Toolkit.getDefaultToolkit())).getNumberOfButtons();
|
||||
|
||||
if (button < 0 || button > buttonsNumber) {
|
||||
return buttonState == 0;
|
||||
} else {
|
||||
return buttonState == XConstants.buttonsMask[button - 1];
|
||||
|
@ -42,6 +42,7 @@ import sun.awt.ComponentAccessor;
|
||||
|
||||
import sun.awt.dnd.SunDragSourceContextPeer;
|
||||
import sun.awt.dnd.SunDropTargetContextPeer;
|
||||
import sun.awt.SunToolkit;
|
||||
|
||||
/**
|
||||
* The XDragSourceContextPeer class is the class responsible for handling
|
||||
@ -665,6 +666,15 @@ public final class XDragSourceContextPeer
|
||||
return true;
|
||||
case XConstants.ButtonRelease: {
|
||||
XButtonEvent xbutton = ev.get_xbutton();
|
||||
/*
|
||||
* Ignore the buttons above 20 due to the bit limit for
|
||||
* InputEvent.BUTTON_DOWN_MASK.
|
||||
* One more bit is reserved for FIRST_HIGH_BIT.
|
||||
*/
|
||||
if (xbutton.get_button() > SunToolkit.MAX_BUTTONS_SUPPORTED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* On some X servers it could happen that ButtonRelease coordinates
|
||||
* differ from the latest MotionNotify coordinates, so we need to
|
||||
|
@ -81,16 +81,11 @@ 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);
|
||||
|
@ -84,21 +84,6 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
//Set to true by default.
|
||||
private static boolean areExtraMouseButtonsEnabled = true;
|
||||
|
||||
/**
|
||||
* Number of buttons.
|
||||
* By default it's taken from the system. If system value does not
|
||||
* fit into int type range, use our own MAX_BUTTONS_SUPPORT value.
|
||||
*/
|
||||
private static int numberOfButtons = 0;
|
||||
|
||||
/* XFree standard mention 24 buttons as maximum:
|
||||
* http://www.xfree86.org/current/mouse.4.html
|
||||
* We workaround systems supporting more than 24 buttons.
|
||||
* Otherwise, we have to use long type values as masks
|
||||
* which leads to API change.
|
||||
*/
|
||||
private static int MAX_BUTTONS_SUPPORT = 24;
|
||||
|
||||
/**
|
||||
* True when the x settings have been loaded.
|
||||
*/
|
||||
@ -1458,19 +1443,26 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
desktopProperties.put("awt.multiClickInterval",
|
||||
Integer.valueOf(getMultiClickTime()));
|
||||
desktopProperties.put("awt.mouse.numButtons",
|
||||
Integer.valueOf(getNumMouseButtons()));
|
||||
Integer.valueOf(getNumberOfButtons()));
|
||||
}
|
||||
}
|
||||
|
||||
public static int getNumMouseButtons() {
|
||||
/**
|
||||
* This method runs through the XPointer and XExtendedPointer array.
|
||||
* XExtendedPointer has priority because on some systems XPointer
|
||||
* (which is assigned to the virtual pointer) reports the maximum
|
||||
* capabilities of the mouse pointer (i.e. 32 physical buttons).
|
||||
*/
|
||||
private native synchronized int getNumberOfButtonsImpl();
|
||||
|
||||
@Override
|
||||
public int getNumberOfButtons(){
|
||||
awtLock();
|
||||
try {
|
||||
if (numberOfButtons == 0) {
|
||||
numberOfButtons = Math.min(
|
||||
XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), 0, 0),
|
||||
MAX_BUTTONS_SUPPORT);
|
||||
numberOfButtons = getNumberOfButtonsImpl();
|
||||
}
|
||||
return numberOfButtons;
|
||||
return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
|
||||
} finally {
|
||||
awtUnlock();
|
||||
}
|
||||
|
@ -677,6 +677,14 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
int button=0;
|
||||
boolean wheel_mouse = false;
|
||||
int lbutton = xbe.get_button();
|
||||
/*
|
||||
* Ignore the buttons above 20 due to the bit limit for
|
||||
* InputEvent.BUTTON_DOWN_MASK.
|
||||
* One more bit is reserved for FIRST_HIGH_BIT.
|
||||
*/
|
||||
if (lbutton > SunToolkit.MAX_BUTTONS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
int type = xev.get_type();
|
||||
when = xbe.get_time();
|
||||
long jWhen = XToolkit.nowMillisUTC_offset(when);
|
||||
@ -795,8 +803,9 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
//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++){
|
||||
final int buttonsNumber = ((SunToolkit)(Toolkit.getDefaultToolkit())).getNumberOfButtons();
|
||||
|
||||
for (int i = 0; i < buttonsNumber; 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]);
|
||||
|
@ -1894,7 +1894,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
}
|
||||
if (isGrabbed()) {
|
||||
boolean dragging = false;
|
||||
for (int i = 0; i<XToolkit.getNumMouseButtons(); i++){
|
||||
final int buttonsNumber = ((SunToolkit)(Toolkit.getDefaultToolkit())).getNumberOfButtons();
|
||||
|
||||
for (int i = 0; i < buttonsNumber; 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);
|
||||
@ -1940,6 +1942,15 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
|
||||
public void handleButtonPressRelease(XEvent xev) {
|
||||
XButtonEvent xbe = xev.get_xbutton();
|
||||
|
||||
/*
|
||||
* Ignore the buttons above 20 due to the bit limit for
|
||||
* InputEvent.BUTTON_DOWN_MASK.
|
||||
* One more bit is reserved for FIRST_HIGH_BIT.
|
||||
*/
|
||||
if (xbe.get_button() > SunToolkit.MAX_BUTTONS_SUPPORTED) {
|
||||
return;
|
||||
}
|
||||
if (grabLog.isLoggable(Level.FINE)) {
|
||||
grabLog.log(Level.FINE, "{0}, when grabbed {1}, contains {2} ({3}, {4}, {5}x{6})",
|
||||
new Object[] {xbe, isGrabbed(), containsGlobal(xbe.get_x_root(), xbe.get_y_root()), getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight()});
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1995-2009 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
|
||||
@ -624,7 +624,6 @@ public class MToolkit extends UNIXToolkit implements Runnable {
|
||||
}
|
||||
|
||||
private native int getMulticlickTime();
|
||||
private native int getNumMouseButtons();
|
||||
|
||||
protected void initializeDesktopProperties() {
|
||||
desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50));
|
||||
@ -643,7 +642,7 @@ public class MToolkit extends UNIXToolkit implements Runnable {
|
||||
desktopProperties.put("awt.multiClickInterval",
|
||||
Integer.valueOf(getMulticlickTime()));
|
||||
desktopProperties.put("awt.mouse.numButtons",
|
||||
Integer.valueOf(getNumMouseButtons()));
|
||||
Integer.valueOf(getNumberOfButtons()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3166,21 +3166,6 @@ JNIEXPORT jint JNICALL Java_sun_awt_motif_MToolkit_getMulticlickTime
|
||||
return awt_multiclick_time;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_motif_MToolkit
|
||||
* Method: getNumMouseButtons
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_sun_awt_motif_MToolkit_getNumMouseButtons
|
||||
(JNIEnv *env, jobject this)
|
||||
{
|
||||
jint res = 0;
|
||||
AWT_LOCK();
|
||||
res = XGetPointerMapping(awt_display, NULL, 0);
|
||||
AWT_UNLOCK();
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_motif_MToolkit
|
||||
* Method: loadXSettings
|
||||
|
@ -51,9 +51,8 @@
|
||||
|
||||
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;
|
||||
extern int32_t getNumButtons();
|
||||
|
||||
static jint * masks;
|
||||
|
||||
static int32_t isXTestAvailable() {
|
||||
@ -90,46 +89,6 @@ static int32_t isXTestAvailable() {
|
||||
return isXTestAvailable;
|
||||
}
|
||||
|
||||
static void getNumButtons() {
|
||||
int32_t major_opcode, first_event, first_error;
|
||||
int32_t xinputAvailable;
|
||||
int32_t numDevices, devIdx, clsIdx;
|
||||
XDeviceInfo* devices;
|
||||
XDeviceInfo* aDevice;
|
||||
XButtonInfo* bInfo;
|
||||
|
||||
/* 4700242:
|
||||
* If XTest is asked to press a non-existant mouse button
|
||||
* (i.e. press Button3 on a system configured with a 2-button mouse),
|
||||
* then a crash may happen. To avoid this, we use the XInput
|
||||
* extension to query for the number of buttons on the XPointer, and check
|
||||
* before calling XTestFakeButtonEvent().
|
||||
*/
|
||||
xinputAvailable = XQueryExtension(awt_display, INAME, &major_opcode, &first_event, &first_error);
|
||||
DTRACE_PRINTLN3("RobotPeer: XQueryExtension(XINPUT) returns major_opcode = %d, first_event = %d, first_error = %d",
|
||||
major_opcode, first_event, first_error);
|
||||
if (xinputAvailable) {
|
||||
devices = XListInputDevices(awt_display, &numDevices);
|
||||
for (devIdx = 0; devIdx < numDevices; devIdx++) {
|
||||
aDevice = &(devices[devIdx]);
|
||||
if (aDevice->use == IsXPointer) {
|
||||
for (clsIdx = 0; clsIdx < aDevice->num_classes; clsIdx++) {
|
||||
if (aDevice->inputclassinfo[clsIdx].class == ButtonClass) {
|
||||
bInfo = (XButtonInfo*)(&(aDevice->inputclassinfo[clsIdx]));
|
||||
num_buttons = bInfo->num_buttons;
|
||||
DTRACE_PRINTLN1("RobotPeer: XPointer has %d buttons", num_buttons);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
XFreeDeviceList(devices);
|
||||
}
|
||||
else {
|
||||
DTRACE_PRINTLN1("RobotPeer: XINPUT extension is unavailable, assuming %d mouse buttons", num_buttons);
|
||||
}
|
||||
}
|
||||
|
||||
static XImage *getWindowImage(Display * display, Window window,
|
||||
int32_t x, int32_t y,
|
||||
@ -241,17 +200,10 @@ Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls) {
|
||||
return;
|
||||
}
|
||||
|
||||
getNumButtons();
|
||||
finally:
|
||||
AWT_UNLOCK();
|
||||
}
|
||||
|
||||
JNIEXPORT jint 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,
|
||||
@ -386,6 +338,8 @@ void mouseAction(JNIEnv *env,
|
||||
{
|
||||
AWT_LOCK();
|
||||
|
||||
int32_t num_buttons = getNumButtons(); //from XToolkit.c
|
||||
|
||||
DTRACE_PRINTLN1("RobotPeer: mouseAction(%i)", buttonMask);
|
||||
DTRACE_PRINTLN1("RobotPeer: mouseAction, press = %d", isMousePress);
|
||||
|
||||
|
@ -45,10 +45,14 @@
|
||||
#include "sun_awt_X11_XToolkit.h"
|
||||
#include "java_awt_SystemColor.h"
|
||||
#include "java_awt_TrayIcon.h"
|
||||
#include <X11/extensions/XTest.h>
|
||||
|
||||
uint32_t awt_NumLockMask = 0;
|
||||
Boolean awt_ModLockIsShiftLock = False;
|
||||
|
||||
static int32_t num_buttons = 0;
|
||||
int32_t getNumButtons();
|
||||
|
||||
extern JavaVM *jvm;
|
||||
|
||||
// Tracing level
|
||||
@ -908,3 +912,78 @@ Java_java_awt_Cursor_finalizeImpl(JNIEnv *env, jclass clazz, jlong pData)
|
||||
AWT_UNLOCK();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_awt_X11_XToolkit
|
||||
* Method: getNumberOfButtonsImpl
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_sun_awt_X11_XToolkit_getNumberOfButtonsImpl
|
||||
(JNIEnv * env, jobject cls){
|
||||
if (num_buttons == 0) {
|
||||
num_buttons = getNumButtons();
|
||||
}
|
||||
return num_buttons;
|
||||
}
|
||||
|
||||
int32_t getNumButtons() {
|
||||
int32_t major_opcode, first_event, first_error;
|
||||
int32_t xinputAvailable;
|
||||
int32_t numDevices, devIdx, clsIdx;
|
||||
XDeviceInfo* devices;
|
||||
XDeviceInfo* aDevice;
|
||||
XButtonInfo* bInfo;
|
||||
int32_t local_num_buttons = 0;
|
||||
|
||||
/* 4700242:
|
||||
* If XTest is asked to press a non-existant mouse button
|
||||
* (i.e. press Button3 on a system configured with a 2-button mouse),
|
||||
* then a crash may happen. To avoid this, we use the XInput
|
||||
* extension to query for the number of buttons on the XPointer, and check
|
||||
* before calling XTestFakeButtonEvent().
|
||||
*/
|
||||
xinputAvailable = XQueryExtension(awt_display, INAME, &major_opcode, &first_event, &first_error);
|
||||
DTRACE_PRINTLN3("RobotPeer: XQueryExtension(XINPUT) returns major_opcode = %d, first_event = %d, first_error = %d",
|
||||
major_opcode, first_event, first_error);
|
||||
if (xinputAvailable) {
|
||||
devices = XListInputDevices(awt_display, &numDevices);
|
||||
for (devIdx = 0; devIdx < numDevices; devIdx++) {
|
||||
aDevice = &(devices[devIdx]);
|
||||
if (aDevice->use == IsXExtensionPointer) {
|
||||
for (clsIdx = 0; clsIdx < aDevice->num_classes; clsIdx++) {
|
||||
if (aDevice->inputclassinfo[clsIdx].class == ButtonClass) {
|
||||
bInfo = (XButtonInfo*)(&(aDevice->inputclassinfo[clsIdx]));
|
||||
local_num_buttons = bInfo->num_buttons;
|
||||
DTRACE_PRINTLN1("RobotPeer: XPointer has %d buttons", num_buttons);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (local_num_buttons <= 0 ) {
|
||||
if (aDevice->use == IsXPointer) {
|
||||
for (clsIdx = 0; clsIdx < aDevice->num_classes; clsIdx++) {
|
||||
if (aDevice->inputclassinfo[clsIdx].class == ButtonClass) {
|
||||
bInfo = (XButtonInfo*)(&(aDevice->inputclassinfo[clsIdx]));
|
||||
local_num_buttons = bInfo->num_buttons;
|
||||
DTRACE_PRINTLN1("RobotPeer: XPointer has %d buttons", num_buttons);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XFreeDeviceList(devices);
|
||||
}
|
||||
else {
|
||||
DTRACE_PRINTLN1("RobotPeer: XINPUT extension is unavailable, assuming %d mouse buttons", num_buttons);
|
||||
}
|
||||
if (local_num_buttons == 0 ) {
|
||||
local_num_buttons = 3;
|
||||
}
|
||||
|
||||
return local_num_buttons;
|
||||
}
|
||||
|
@ -60,8 +60,6 @@ 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);
|
||||
|
@ -982,6 +982,16 @@ public class WToolkit extends SunToolkit implements Runnable {
|
||||
return areExtraMouseButtonsEnabled;
|
||||
}
|
||||
|
||||
private native synchronized int getNumberOfButtonsImpl();
|
||||
|
||||
@Override
|
||||
public int getNumberOfButtons(){
|
||||
if (numberOfButtons == 0) {
|
||||
numberOfButtons = getNumberOfButtonsImpl();
|
||||
}
|
||||
return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWindowOpacitySupported() {
|
||||
// supported in Win2K and later
|
||||
|
@ -437,9 +437,3 @@ 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);
|
||||
}
|
||||
|
@ -2259,3 +2259,8 @@ extern "C" JNIEXPORT void JNICALL Java_sun_awt_windows_WToolkit_setExtraMouseBut
|
||||
void AwtToolkit::setExtraMouseButtonsEnabled(BOOL enable) {
|
||||
m_areExtraMouseButtonsEnabled = enable;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl
|
||||
(JNIEnv *, jobject self) {
|
||||
return GetSystemMetrics(SM_CMOUSEBUTTONS);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user