diff --git a/jdk/make/sun/xawt/mapfile-vers b/jdk/make/sun/xawt/mapfile-vers index d62f344fac9b2d43b16945f19acec3a2ba78da10..87d274b5f2b492c68843ad4fa99c897bd2b08d40 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 94c71283cee338bcfafe55ae63fd5201adeffd6a..f7a40c740bc00c80ac7831ed9d63c08dc0fd411b 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 5f892464a26bebd25430b65e6fbb61808cf47327..06492d1d0f09773a9ad666b7a9a3b0718d3e5e20 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 c530b1ebd5ab682aade3f4d24abc97accfe44cf0..a7372f2b8b4b95cff1e0e0e8e5f55430f6302f6e 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 ce50ed587959ae34205143b7a8702d8a1bead8e4..ca1f1d4414e3444b57c5302760a69b41036f89e6 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 a6e1cb1247b1aa874ebce1ef2b1988c259685950..fb554ef789fe8e3892a66056a0230e1806601bd3 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 46491e04c1d67436750e5a6c3eae93f4aa2953ad..07a4fc7c2651d6493ceca29889aae9fdaf41d0b0 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 a079fdb2babd5d468553806adc57e57b35179edf..4186628c4040125cfbd207afaa23572a49ec729f 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 2bfe6854f3fc6fc5eb637b969f04acdc159cb18f..663c0ed8a04e82f56b35a1a2a5120cea1cb97fef 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 8dcf91a3325c6ba2c48aea9d95bd2acd912fc78a..1739e6724f17b0ff38a44a2159f832ef2e654787 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 751287145105e46ce928e3460afc83f471d9e979..f1c3c675b6c4db50b4033c7fe02a69ca07d313d8 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 66d4818c29e4c2b34dc06218c2d7fe6bfea864af..b1646413b796409480b1f5cbade9f7658105ca1f 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 672e6e2bcce34e5cb27cbadf040aea81736f6c28..8f9f6115f30d1c9bf1834777b3f9a867a7ef9e2b 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 737f9ad5e79c6d0101b3bf592880d7d4b0b1bc99..ba4d244a11ca94d334b077a064615d8595511e30 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 6fce85dc7bc1e468a549c2ac1f123ab1d2a5043b..18aa1554b9824a8658fd35694db626ac7602a7a7 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 5e0e421061c61980a164be0a8662e5ac9a7e100c..d8875ab54f1cb4a92174c1e8ccb9e9a9ea95764b 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 4cd3d2d3c263307e29246551d0f8e115de7cfe22..fb6673a4b3b05d0df5998ff811ca8877d1b66e01 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 62011b9b85c33a872723740e6150b7c3fcc225cc..6e12209f94c433759df660ebb4047fdaed740f14 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 e774f5160dbb60d11acc781de0e3ef1fc3ada656..5005635f8b56fac5ce17dd90e7b9436d4223d552 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 4a7cc16c5fa6b59e0ec89178e3d54f6d45b377e2..bbc49b84a9b606ebbd284f8953917209380ff370 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); +}