From 7dd8d4d644756052d57ecc03c107cb81c1d6abc2 Mon Sep 17 00:00:00 2001 From: dav Date: Fri, 22 May 2009 16:09:45 +0400 Subject: [PATCH] 6799099: All automatic regression tests that create Robot fail on X11 Reviewed-by: art, ant --- jdk/make/sun/xawt/mapfile-vers | 2 +- jdk/src/share/classes/java/awt/Robot.java | 8 +- .../classes/java/awt/event/InputEvent.java | 15 +++- .../classes/java/awt/event/MouseEvent.java | 24 +++--- .../classes/java/awt/peer/RobotPeer.java | 7 -- jdk/src/share/classes/sun/awt/SunToolkit.java | 25 ++++++ .../classes/sun/awt/X11/XBaseWindow.java | 15 +++- .../sun/awt/X11/XDragSourceContextPeer.java | 10 +++ .../classes/sun/awt/X11/XRobotPeer.java | 5 -- .../solaris/classes/sun/awt/X11/XToolkit.java | 34 +++----- .../solaris/classes/sun/awt/X11/XWindow.java | 13 ++- .../classes/sun/awt/X11/XWindowPeer.java | 13 ++- .../classes/sun/awt/motif/MToolkit.java | 5 +- jdk/src/solaris/native/sun/awt/awt_MToolkit.c | 15 ---- jdk/src/solaris/native/sun/awt/awt_Robot.c | 54 +------------ jdk/src/solaris/native/sun/xawt/XToolkit.c | 79 +++++++++++++++++++ .../classes/sun/awt/windows/WRobotPeer.java | 2 - .../classes/sun/awt/windows/WToolkit.java | 10 +++ .../windows/native/sun/windows/awt_Robot.cpp | 6 -- .../native/sun/windows/awt_Toolkit.cpp | 5 ++ 20 files changed, 218 insertions(+), 129 deletions(-) diff --git a/jdk/make/sun/xawt/mapfile-vers b/jdk/make/sun/xawt/mapfile-vers index d62f344fac..87d274b5f2 100644 --- a/jdk/make/sun/xawt/mapfile-vers +++ b/jdk/make/sun/xawt/mapfile-vers @@ -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; diff --git a/jdk/src/share/classes/java/awt/Robot.java b/jdk/src/share/classes/java/awt/Robot.java index 94c71283ce..f7a40c740b 100644 --- a/jdk/src/share/classes/java/awt/Robot.java +++ b/jdk/src/share/classes/java/awt/Robot.java @@ -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| diff --git a/jdk/src/share/classes/java/awt/event/InputEvent.java b/jdk/src/share/classes/java/awt/event/InputEvent.java index 5f892464a2..06492d1d0f 100644 --- a/jdk/src/share/classes/java/awt/event/InputEvent.java +++ b/jdk/src/share/classes/java/awt/event/InputEvent.java @@ -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 ); diff --git a/jdk/src/share/classes/java/awt/event/MouseEvent.java b/jdk/src/share/classes/java/awt/event/MouseEvent.java index c530b1ebd5..a7372f2b8b 100644 --- a/jdk/src/share/classes/java/awt/event/MouseEvent.java +++ b/jdk/src/share/classes/java/awt/event/MouseEvent.java @@ -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); diff --git a/jdk/src/share/classes/java/awt/peer/RobotPeer.java b/jdk/src/share/classes/java/awt/peer/RobotPeer.java index ce50ed5879..ca1f1d4414 100644 --- a/jdk/src/share/classes/java/awt/peer/RobotPeer.java +++ b/jdk/src/share/classes/java/awt/peer/RobotPeer.java @@ -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(); } diff --git a/jdk/src/share/classes/sun/awt/SunToolkit.java b/jdk/src/share/classes/sun/awt/SunToolkit.java index a6e1cb1247..fb554ef789 100644 --- a/jdk/src/share/classes/sun/awt/SunToolkit.java +++ b/jdk/src/share/classes/sun/awt/SunToolkit.java @@ -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 diff --git a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java index 46491e04c1..07a4fc7c26 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java @@ -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()) { + final int buttonsNumber = ((SunToolkit)(Toolkit.getDefaultToolkit())).getNumberOfButtons(); + + if (button < 0 || button > buttonsNumber) { return buttonState == 0; } else { return buttonState == XConstants.buttonsMask[button - 1]; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java index a079fdb2ba..4186628c40 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDragSourceContextPeer.java @@ -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 diff --git a/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java index 2bfe6854f3..663c0ed8a0 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java @@ -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); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java index 8dcf91a332..1739e6724f 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -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(); } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java index 7512871451..f1c3c675b6 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java @@ -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]); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java index 66d4818c29..b1646413b7 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java @@ -1894,7 +1894,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, } if (isGrabbed()) { boolean dragging = false; - for (int i = 0; i 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()}); diff --git a/jdk/src/solaris/classes/sun/awt/motif/MToolkit.java b/jdk/src/solaris/classes/sun/awt/motif/MToolkit.java index 672e6e2bcc..8f9f6115f3 100644 --- a/jdk/src/solaris/classes/sun/awt/motif/MToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/motif/MToolkit.java @@ -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())); } } diff --git a/jdk/src/solaris/native/sun/awt/awt_MToolkit.c b/jdk/src/solaris/native/sun/awt/awt_MToolkit.c index 737f9ad5e7..ba4d244a11 100644 --- a/jdk/src/solaris/native/sun/awt/awt_MToolkit.c +++ b/jdk/src/solaris/native/sun/awt/awt_MToolkit.c @@ -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 diff --git a/jdk/src/solaris/native/sun/awt/awt_Robot.c b/jdk/src/solaris/native/sun/awt/awt_Robot.c index 6fce85dc7b..18aa1554b9 100644 --- a/jdk/src/solaris/native/sun/awt/awt_Robot.c +++ b/jdk/src/solaris/native/sun/awt/awt_Robot.c @@ -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); diff --git a/jdk/src/solaris/native/sun/xawt/XToolkit.c b/jdk/src/solaris/native/sun/xawt/XToolkit.c index 5e0e421061..d8875ab54f 100644 --- a/jdk/src/solaris/native/sun/xawt/XToolkit.c +++ b/jdk/src/solaris/native/sun/xawt/XToolkit.c @@ -45,10 +45,14 @@ #include "sun_awt_X11_XToolkit.h" #include "java_awt_SystemColor.h" #include "java_awt_TrayIcon.h" +#include 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; +} diff --git a/jdk/src/windows/classes/sun/awt/windows/WRobotPeer.java b/jdk/src/windows/classes/sun/awt/windows/WRobotPeer.java index 4cd3d2d3c2..fb6673a4b3 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WRobotPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WRobotPeer.java @@ -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); diff --git a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java index 62011b9b85..6e12209f94 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java +++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java @@ -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 diff --git a/jdk/src/windows/native/sun/windows/awt_Robot.cpp b/jdk/src/windows/native/sun/windows/awt_Robot.cpp index e774f5160d..5005635f8b 100644 --- a/jdk/src/windows/native/sun/windows/awt_Robot.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Robot.cpp @@ -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); -} diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp index 4a7cc16c5f..bbc49b84a9 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -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); +} -- GitLab