26 package java.awt;
27
28 import java.awt.event.InputEvent;
29 import java.awt.event.KeyEvent;
30 import java.awt.geom.AffineTransform;
31 import java.awt.image.BaseMultiResolutionImage;
32 import java.awt.image.BufferedImage;
33 import java.awt.image.DataBufferInt;
34 import java.awt.image.DirectColorModel;
35 import java.awt.image.MultiResolutionImage;
36 import java.awt.image.Raster;
37 import java.awt.image.WritableRaster;
38 import java.awt.peer.RobotPeer;
39
40 import sun.awt.AWTPermissions;
41 import sun.awt.ComponentFactory;
42 import sun.awt.SunToolkit;
43 import sun.awt.image.SunWritableRaster;
44 import sun.java2d.SunGraphicsEnvironment;
45
46 /**
47 * This class is used to generate native system input events
48 * for the purposes of test automation, self-running demos, and
49 * other applications where control of the mouse and keyboard
50 * is needed. The primary purpose of Robot is to facilitate
51 * automated testing of Java platform implementations.
52 * <p>
53 * Using the class to generate input events differs from posting
54 * events to the AWT event queue or AWT components in that the
55 * events are generated in the platform's native input
56 * queue. For example, {@code Robot.mouseMove} will actually move
57 * the mouse cursor instead of just generating mouse move events.
58 * <p>
59 * Note that some platforms require special privileges or extensions
60 * to access low-level input control. If the current platform configuration
61 * does not allow input control, an {@code AWTException} will be thrown
62 * when trying to construct Robot objects. For example, X-Window systems
63 * will throw the exception if the XTEST 2.2 standard extension is not supported
64 * (or not enabled) by the X server.
65 * <p>
368 }
369
370 private static void checkKeycodeArgument(int keycode) {
371 // rather than build a big table or switch statement here, we'll
372 // just check that the key isn't VK_UNDEFINED and assume that the
373 // peer implementations will throw an exception for other bogus
374 // values e.g. -1, 999999
375 if (keycode == KeyEvent.VK_UNDEFINED) {
376 throw new IllegalArgumentException("Invalid key code");
377 }
378 }
379
380 /**
381 * Returns the color of a pixel at the given screen coordinates.
382 * @param x X position of pixel
383 * @param y Y position of pixel
384 * @return Color of the pixel
385 */
386 public synchronized Color getPixelColor(int x, int y) {
387 checkScreenCaptureAllowed();
388 AffineTransform tx = GraphicsEnvironment.
389 getLocalGraphicsEnvironment().getDefaultScreenDevice().
390 getDefaultConfiguration().getDefaultTransform();
391 x = (int) (x * tx.getScaleX());
392 y = (int) (y * tx.getScaleY());
393 Color color = new Color(peer.getRGBPixel(x, y));
394 return color;
395 }
396
397 /**
398 * Creates an image containing pixels read from the screen. This image does
399 * not include the mouse cursor.
400 * @param screenRect Rect to capture in screen coordinates
401 * @return The captured image
402 * @throws IllegalArgumentException if {@code screenRect} width and height are not greater than zero
403 * @throws SecurityException if {@code readDisplayPixels} permission is not granted
404 * @see SecurityManager#checkPermission
405 * @see AWTPermission
406 */
407 public synchronized BufferedImage createScreenCapture(Rectangle screenRect) {
408 return createCompatibleImage(screenRect, false)[0];
409 }
410
411 /**
412 * Creates an image containing pixels read from the screen.
413 * This image does not include the mouse cursor.
414 * This method can be used in case there is a scaling transform
506
507 if (uiScaleX == 1 && uiScaleY == 1) {
508
509 pixels = peer.getRGBPixels(screenRect);
510 buffer = new DataBufferInt(pixels, pixels.length);
511
512 bandmasks[0] = screenCapCM.getRedMask();
513 bandmasks[1] = screenCapCM.getGreenMask();
514 bandmasks[2] = screenCapCM.getBlueMask();
515
516 raster = Raster.createPackedRaster(buffer, screenRect.width,
517 screenRect.height, screenRect.width, bandmasks, null);
518 SunWritableRaster.makeTrackable(buffer);
519
520 highResolutionImage = new BufferedImage(screenCapCM, raster,
521 false, null);
522 imageArray = new BufferedImage[1];
523 imageArray[0] = highResolutionImage;
524
525 } else {
526
527 int sX = (int) Math.floor(screenRect.x * uiScaleX);
528 int sY = (int) Math.floor(screenRect.y * uiScaleY);
529 int sWidth = (int) Math.ceil(screenRect.width * uiScaleX);
530 int sHeight = (int) Math.ceil(screenRect.height * uiScaleY);
531 int[] temppixels;
532 Rectangle scaledRect = new Rectangle(sX, sY, sWidth, sHeight);
533 temppixels = peer.getRGBPixels(scaledRect);
534
535 // HighResolutionImage
536 pixels = temppixels;
537 buffer = new DataBufferInt(pixels, pixels.length);
538 raster = Raster.createPackedRaster(buffer, scaledRect.width,
539 scaledRect.height, scaledRect.width, bandmasks, null);
540 SunWritableRaster.makeTrackable(buffer);
541
542 highResolutionImage = new BufferedImage(screenCapCM, raster,
543 false, null);
544
545
546 // LowResolutionImage
547 lowResolutionImage = new BufferedImage(screenRect.width,
548 screenRect.height, highResolutionImage.getType());
549 Graphics2D g = lowResolutionImage.createGraphics();
550 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
551 RenderingHints.VALUE_INTERPOLATION_BILINEAR);
552 g.setRenderingHint(RenderingHints.KEY_RENDERING,
553 RenderingHints.VALUE_RENDER_QUALITY);
554 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
555 RenderingHints.VALUE_ANTIALIAS_ON);
556 g.drawImage(highResolutionImage, 0, 0,
|
26 package java.awt;
27
28 import java.awt.event.InputEvent;
29 import java.awt.event.KeyEvent;
30 import java.awt.geom.AffineTransform;
31 import java.awt.image.BaseMultiResolutionImage;
32 import java.awt.image.BufferedImage;
33 import java.awt.image.DataBufferInt;
34 import java.awt.image.DirectColorModel;
35 import java.awt.image.MultiResolutionImage;
36 import java.awt.image.Raster;
37 import java.awt.image.WritableRaster;
38 import java.awt.peer.RobotPeer;
39
40 import sun.awt.AWTPermissions;
41 import sun.awt.ComponentFactory;
42 import sun.awt.SunToolkit;
43 import sun.awt.image.SunWritableRaster;
44 import sun.java2d.SunGraphicsEnvironment;
45
46 import static sun.java2d.SunGraphicsEnvironment.toDeviceSpace;
47 import static sun.java2d.SunGraphicsEnvironment.toDeviceSpaceAbs;
48
49 /**
50 * This class is used to generate native system input events
51 * for the purposes of test automation, self-running demos, and
52 * other applications where control of the mouse and keyboard
53 * is needed. The primary purpose of Robot is to facilitate
54 * automated testing of Java platform implementations.
55 * <p>
56 * Using the class to generate input events differs from posting
57 * events to the AWT event queue or AWT components in that the
58 * events are generated in the platform's native input
59 * queue. For example, {@code Robot.mouseMove} will actually move
60 * the mouse cursor instead of just generating mouse move events.
61 * <p>
62 * Note that some platforms require special privileges or extensions
63 * to access low-level input control. If the current platform configuration
64 * does not allow input control, an {@code AWTException} will be thrown
65 * when trying to construct Robot objects. For example, X-Window systems
66 * will throw the exception if the XTEST 2.2 standard extension is not supported
67 * (or not enabled) by the X server.
68 * <p>
371 }
372
373 private static void checkKeycodeArgument(int keycode) {
374 // rather than build a big table or switch statement here, we'll
375 // just check that the key isn't VK_UNDEFINED and assume that the
376 // peer implementations will throw an exception for other bogus
377 // values e.g. -1, 999999
378 if (keycode == KeyEvent.VK_UNDEFINED) {
379 throw new IllegalArgumentException("Invalid key code");
380 }
381 }
382
383 /**
384 * Returns the color of a pixel at the given screen coordinates.
385 * @param x X position of pixel
386 * @param y Y position of pixel
387 * @return Color of the pixel
388 */
389 public synchronized Color getPixelColor(int x, int y) {
390 checkScreenCaptureAllowed();
391 Point point = peer.useAbsoluteCoordinates() ? toDeviceSpaceAbs(x, y)
392 : toDeviceSpace(x, y);
393 return new Color(peer.getRGBPixel(point.x, point.y));
394 }
395
396 /**
397 * Creates an image containing pixels read from the screen. This image does
398 * not include the mouse cursor.
399 * @param screenRect Rect to capture in screen coordinates
400 * @return The captured image
401 * @throws IllegalArgumentException if {@code screenRect} width and height are not greater than zero
402 * @throws SecurityException if {@code readDisplayPixels} permission is not granted
403 * @see SecurityManager#checkPermission
404 * @see AWTPermission
405 */
406 public synchronized BufferedImage createScreenCapture(Rectangle screenRect) {
407 return createCompatibleImage(screenRect, false)[0];
408 }
409
410 /**
411 * Creates an image containing pixels read from the screen.
412 * This image does not include the mouse cursor.
413 * This method can be used in case there is a scaling transform
505
506 if (uiScaleX == 1 && uiScaleY == 1) {
507
508 pixels = peer.getRGBPixels(screenRect);
509 buffer = new DataBufferInt(pixels, pixels.length);
510
511 bandmasks[0] = screenCapCM.getRedMask();
512 bandmasks[1] = screenCapCM.getGreenMask();
513 bandmasks[2] = screenCapCM.getBlueMask();
514
515 raster = Raster.createPackedRaster(buffer, screenRect.width,
516 screenRect.height, screenRect.width, bandmasks, null);
517 SunWritableRaster.makeTrackable(buffer);
518
519 highResolutionImage = new BufferedImage(screenCapCM, raster,
520 false, null);
521 imageArray = new BufferedImage[1];
522 imageArray[0] = highResolutionImage;
523
524 } else {
525 Rectangle scaledRect;
526 if (peer.useAbsoluteCoordinates()) {
527 scaledRect = toDeviceSpaceAbs(gc, screenRect.x,
528 screenRect.y, screenRect.width, screenRect.height);
529 } else {
530 scaledRect = toDeviceSpace(gc, screenRect.x,
531 screenRect.y, screenRect.width, screenRect.height);
532 }
533 // HighResolutionImage
534 pixels = peer.getRGBPixels(scaledRect);
535 buffer = new DataBufferInt(pixels, pixels.length);
536 raster = Raster.createPackedRaster(buffer, scaledRect.width,
537 scaledRect.height, scaledRect.width, bandmasks, null);
538 SunWritableRaster.makeTrackable(buffer);
539
540 highResolutionImage = new BufferedImage(screenCapCM, raster,
541 false, null);
542
543
544 // LowResolutionImage
545 lowResolutionImage = new BufferedImage(screenRect.width,
546 screenRect.height, highResolutionImage.getType());
547 Graphics2D g = lowResolutionImage.createGraphics();
548 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
549 RenderingHints.VALUE_INTERPOLATION_BILINEAR);
550 g.setRenderingHint(RenderingHints.KEY_RENDERING,
551 RenderingHints.VALUE_RENDER_QUALITY);
552 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
553 RenderingHints.VALUE_ANTIALIAS_ON);
554 g.drawImage(highResolutionImage, 0, 0,
|