diff --git a/src/macosx/native/sun/awt/CRobot.m b/src/macosx/native/sun/awt/CRobot.m index 3ec4f72638f945b4e6c203da198e564b18ac75a7..69a250c5fcf43efae438792ae4cd669992cf251c 100644 --- a/src/macosx/native/sun/awt/CRobot.m +++ b/src/macosx/native/sun/awt/CRobot.m @@ -187,9 +187,8 @@ Java_sun_lwawt_macosx_CRobot_mouseEvent // volatile, otherwise it warns that it might be clobbered by 'longjmp' volatile CGPoint point; - // Translate the device relative point into a valid global CGPoint. - point.x = mouseLastX + globalDeviceBounds.origin.x; - point.y = mouseLastY + globalDeviceBounds.origin.y; + point.x = mouseLastX; + point.y = mouseLastY; __block CGMouseButton button = kCGMouseButtonLeft; __block CGEventType type = kCGEventMouseMoved; diff --git a/src/share/classes/java/awt/Robot.java b/src/share/classes/java/awt/Robot.java index 019d2bce4bbf1b9985ee0c8c44adbbeeb99da402..b431e45bd9858a806830652fa17e9a4491368f6f 100644 --- a/src/share/classes/java/awt/Robot.java +++ b/src/share/classes/java/awt/Robot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. 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 @@ -72,9 +72,6 @@ public class Robot { private int autoDelay = 0; private static int LEGAL_BUTTON_MASK = 0; - // location of robot's GC, used in mouseMove(), getPixelColor() and captureScreenImage() - private Point gdLoc; - private DirectColorModel screenCapCM = null; /** @@ -132,7 +129,6 @@ public class Robot { private void init(GraphicsDevice screen) throws AWTException { checkRobotAllowed(); - gdLoc = screen.getDefaultConfiguration().getBounds().getLocation(); Toolkit toolkit = Toolkit.getDefaultToolkit(); if (toolkit instanceof ComponentFactory) { peer = ((ComponentFactory)toolkit).createRobot(this, screen); @@ -200,7 +196,7 @@ public class Robot { * @param y Y position */ public synchronized void mouseMove(int x, int y) { - peer.mouseMove(gdLoc.x + x, gdLoc.y + y); + peer.mouseMove(x, y); afterEvent(); } @@ -395,7 +391,7 @@ public class Robot { * @return Color of the pixel */ public synchronized Color getPixelColor(int x, int y) { - Color color = new Color(peer.getRGBPixel(gdLoc.x + x, gdLoc.y + y)); + Color color = new Color(peer.getRGBPixel(x, y)); return color; } @@ -412,10 +408,7 @@ public class Robot { public synchronized BufferedImage createScreenCapture(Rectangle screenRect) { checkScreenCaptureAllowed(); - // according to the spec, screenRect is relative to robot's GD - Rectangle translatedRect = new Rectangle(screenRect); - translatedRect.translate(gdLoc.x, gdLoc.y); - checkValidRect(translatedRect); + checkValidRect(screenRect); BufferedImage image; DataBufferInt buffer; @@ -441,14 +434,14 @@ public class Robot { int pixels[]; int[] bandmasks = new int[3]; - pixels = peer.getRGBPixels(translatedRect); + pixels = peer.getRGBPixels(screenRect); buffer = new DataBufferInt(pixels, pixels.length); bandmasks[0] = screenCapCM.getRedMask(); bandmasks[1] = screenCapCM.getGreenMask(); bandmasks[2] = screenCapCM.getBlueMask(); - raster = Raster.createPackedRaster(buffer, translatedRect.width, translatedRect.height, translatedRect.width, bandmasks, null); + raster = Raster.createPackedRaster(buffer, screenRect.width, screenRect.height, screenRect.width, bandmasks, null); SunWritableRaster.makeTrackable(buffer); image = new BufferedImage(screenCapCM, raster, false, null); diff --git a/test/java/awt/Multiscreen/MultiScreenLocationTest/MultiScreenLocationTest.java b/test/java/awt/Multiscreen/MultiScreenLocationTest/MultiScreenLocationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6937a108e037bdec312f802398d68e3ba54049a5 --- /dev/null +++ b/test/java/awt/Multiscreen/MultiScreenLocationTest/MultiScreenLocationTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 8013116 + @summary Robot moves mouse to point which differs from set in mouseMove on + Unity shell + @author Oleg Pekhovskiy + @library ../../regtesthelpers + @build Util + @run main MultiScreenLocationTest + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.Frame; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import test.java.awt.regtesthelpers.Util; + +public class MultiScreenLocationTest { + private static final Point mouseOffset = new Point(150, 150); + private static final Point frameOffset = new Point(100, 100); + private static final Color color = Color.YELLOW; + + private static String getErrorText(final String name, int screen) + { + return name + " test failed on Screen #" + screen + "!"; + } + + public static void main(String[] args) throws AWTException + { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gds = ge.getScreenDevices(); + if (gds.length < 2) { + System.out.println("It's a multiscreen test... skipping!"); + return; + } + + for (int i = 0; i < gds.length; ++i) { + GraphicsDevice gd = gds[i]; + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + Rectangle screen = gc.getBounds(); + Robot robot = new Robot(gd); + + // check Robot.mouseMove() + robot.mouseMove(screen.x + mouseOffset.x, screen.y + mouseOffset.y); + Point mouse = MouseInfo.getPointerInfo().getLocation(); + Point point = screen.getLocation(); + point.translate(mouseOffset.x, mouseOffset.y); + if (!point.equals(mouse)) { + throw new RuntimeException(getErrorText("Robot.mouseMove", i)); + } + + // check Robot.getPixelColor() + Frame frame = new Frame(gc); + frame.setUndecorated(true); + frame.setSize(100, 100); + frame.setLocation(screen.x + frameOffset.x, screen.y + frameOffset.y); + frame.setBackground(color); + frame.setVisible(true); + robot.waitForIdle(); + Rectangle bounds = frame.getBounds(); + if (!Util.testBoundsColor(bounds, color, 5, 1000, robot)) { + throw new RuntimeException(getErrorText("Robot.getPixelColor", i)); + } + + // check Robot.createScreenCapture() + BufferedImage image = robot.createScreenCapture(bounds); + int rgb = color.getRGB(); + if (image.getRGB(0, 0) != rgb + || image.getRGB(image.getWidth() - 1, 0) != rgb + || image.getRGB(image.getWidth() - 1, image.getHeight() - 1) != rgb + || image.getRGB(0, image.getHeight() - 1) != rgb) { + throw new RuntimeException( + getErrorText("Robot.createScreenCapture", i)); + } + frame.dispose(); + } + + System.out.println("Test PASSED!"); + } +} diff --git a/test/java/awt/regtesthelpers/Util.java b/test/java/awt/regtesthelpers/Util.java index 2a606bcc5a8e6fb8c901a15f4302c8d21c4dde15..95ad563f32885d2f3d3501359a25a6cf8a265279 100644 --- a/test/java/awt/regtesthelpers/Util.java +++ b/test/java/awt/regtesthelpers/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2014, Oracle and/or its affiliates. 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 @@ -51,6 +51,7 @@ import java.awt.Toolkit; import java.awt.IllegalComponentStateException; import java.awt.AWTException; import java.awt.AWTEvent; +import java.awt.Color; import java.awt.event.InputEvent; import java.awt.event.WindowAdapter; @@ -184,6 +185,57 @@ public final class Util { } } + /** + * Tests whether screen pixel has the expected color performing several + * attempts. This method is useful for asynchronous window manager where + * it's impossible to determine when drawing actually takes place. + * + * @param x X position of pixel + * @param y Y position of pixel + * @param color expected color + * @param attempts number of attempts to undertake + * @param delay delay before each attempt + * @param robot a robot to use for retrieving pixel color + * @return true if pixel color matches the color expected, otherwise false + */ + public static boolean testPixelColor(int x, int y, final Color color, int attempts, int delay, final Robot robot) { + while (attempts-- > 0) { + robot.delay(delay); + Color screen = robot.getPixelColor(x, y); + if (screen.equals(color)) { + return true; + } + } + return false; + } + + /** + * Tests whether the area within boundaries has the expected color + * performing several attempts. This method is useful for asynchronous + * window manager where it's impossible to determine when drawing actually + * takes place. + * + * @param bounds position of area + * @param color expected color + * @param attempts number of attempts to undertake + * @param delay delay before each attempt + * @param robot a robot to use for retrieving pixel color + * @return true if area color matches the color expected, otherwise false + */ + public static boolean testBoundsColor(final Rectangle bounds, final Color color, int attempts, int delay, final Robot robot) { + int right = bounds.x + bounds.width - 1; + int bottom = bounds.y + bounds.height - 1; + while (attempts-- > 0) { + if (testPixelColor(bounds.x, bounds.y, color, 1, delay, robot) + && testPixelColor(right, bounds.y, color, 1, 0, robot) + && testPixelColor(right, bottom, color, 1, 0, robot) + && testPixelColor(bounds.x, bottom, color, 1, 0, robot)) { + return true; + } + } + return false; + } + public static void waitForIdle(final Robot robot) { // we do not use robot for now, use SunToolkit.realSync() instead ((sun.awt.SunToolkit)Toolkit.getDefaultToolkit()).realSync();