mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			424 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			424 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
/* Robot.java -- a native input event generator
 | 
						|
   Copyright (C) 2004, 2005  Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath 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 for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
 | 
						|
package java.awt;
 | 
						|
 | 
						|
import gnu.java.awt.ClasspathToolkit;
 | 
						|
 | 
						|
import java.lang.reflect.InvocationTargetException;
 | 
						|
import java.awt.event.InputEvent;
 | 
						|
import java.awt.image.BufferedImage;
 | 
						|
import java.awt.peer.RobotPeer;
 | 
						|
 | 
						|
/**
 | 
						|
 * The Robot class is used to simulate user interaction with graphical
 | 
						|
 * programs.  It can generate native windowing system input events and
 | 
						|
 * retrieve image data from the current screen.  Robot is used to test
 | 
						|
 * the AWT and Swing library implementations; it can also be used to
 | 
						|
 * create self-running demo programs.
 | 
						|
 *
 | 
						|
 * Since Robot generates native windowing system events, rather than
 | 
						|
 * simply inserting {@link AWTEvent}s on the AWT event queue, its use
 | 
						|
 * is not restricted to Java programs.  It can be used to
 | 
						|
 * programatically drive any graphical application.
 | 
						|
 *
 | 
						|
 * This implementation requires an X server that supports the XTest
 | 
						|
 * extension.
 | 
						|
 *
 | 
						|
 * @author Thomas Fitzsimmons (fitzsim@redhat.com)
 | 
						|
 *
 | 
						|
 * @since 1.3
 | 
						|
 */
 | 
						|
public class Robot
 | 
						|
{
 | 
						|
  private boolean waitForIdle;
 | 
						|
  private int autoDelay;
 | 
						|
  private RobotPeer peer;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Construct a Robot object that operates on the default screen.
 | 
						|
   *
 | 
						|
   * @exception AWTException if GraphicsEnvironment.isHeadless()
 | 
						|
   * returns true or if the X server does not support the XTest
 | 
						|
   * extension
 | 
						|
   * @exception SecurityException if createRobot permission is not
 | 
						|
   * granted
 | 
						|
   */
 | 
						|
  public Robot () throws AWTException
 | 
						|
  {
 | 
						|
    if (GraphicsEnvironment.isHeadless ())
 | 
						|
      throw new AWTException ("Robot: headless graphics environment");
 | 
						|
 | 
						|
    SecurityManager sm = System.getSecurityManager ();
 | 
						|
    if (sm != null)
 | 
						|
      sm.checkPermission (new AWTPermission ("createRobot"));
 | 
						|
 | 
						|
    ClasspathToolkit tk = (ClasspathToolkit) Toolkit.getDefaultToolkit ();
 | 
						|
 | 
						|
    // createRobot will throw AWTException if XTest is not supported.
 | 
						|
    peer = tk.createRobot (GraphicsEnvironment.getLocalGraphicsEnvironment ()
 | 
						|
                           .getDefaultScreenDevice ());
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Construct a Robot object that operates on the specified screen.
 | 
						|
   *
 | 
						|
   * @exception AWTException if GraphicsEnvironment.isHeadless()
 | 
						|
   * returns true or if the X server does not support the XTest
 | 
						|
   * extension
 | 
						|
   * @exception IllegalArgumentException if screen is not a screen
 | 
						|
   * GraphicsDevice
 | 
						|
   * @exception SecurityException if createRobot permission is not
 | 
						|
   * granted
 | 
						|
   */
 | 
						|
  public Robot (GraphicsDevice screen) throws AWTException
 | 
						|
  {
 | 
						|
    if (GraphicsEnvironment.isHeadless ())
 | 
						|
      throw new AWTException ("Robot: headless graphics environment");
 | 
						|
 | 
						|
    if (screen.getType () != GraphicsDevice.TYPE_RASTER_SCREEN)
 | 
						|
      throw new IllegalArgumentException ("Robot: graphics"
 | 
						|
                                          + " device is not a screen");
 | 
						|
 | 
						|
    SecurityManager sm = System.getSecurityManager ();
 | 
						|
    if (sm != null)
 | 
						|
      sm.checkPermission (new AWTPermission ("createRobot"));
 | 
						|
 | 
						|
    ClasspathToolkit tk = (ClasspathToolkit) Toolkit.getDefaultToolkit ();
 | 
						|
 | 
						|
    // createRobot will throw AWTException if XTest is not supported.
 | 
						|
    peer = tk.createRobot (screen);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Move the mouse pointer to absolute coordinates (x, y).
 | 
						|
   *
 | 
						|
   * @param x the destination x coordinate
 | 
						|
   * @param y the destination y coordinate
 | 
						|
   */
 | 
						|
  public void mouseMove(int x, int y)
 | 
						|
  {
 | 
						|
    peer.mouseMove (x, y);
 | 
						|
 | 
						|
    if (waitForIdle)
 | 
						|
      waitForIdle ();
 | 
						|
 | 
						|
    if (autoDelay > 0)
 | 
						|
      delay (autoDelay);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Press one or more mouse buttons.
 | 
						|
   *
 | 
						|
   * @param buttons the buttons to press; a bitmask of one or more of
 | 
						|
   * these {@link InputEvent} fields:
 | 
						|
   *
 | 
						|
   * <ul>
 | 
						|
   *   <li>BUTTON1_MASK</li>
 | 
						|
   *   <li>BUTTON2_MASK</li>
 | 
						|
   *   <li>BUTTON3_MASK</li>
 | 
						|
   * </ul>
 | 
						|
   *
 | 
						|
   * @exception IllegalArgumentException if the button mask is invalid
 | 
						|
   */
 | 
						|
  public void mousePress (int buttons)
 | 
						|
  {
 | 
						|
    if ((buttons & InputEvent.BUTTON1_MASK) == 0
 | 
						|
        && (buttons & InputEvent.BUTTON2_MASK) == 0
 | 
						|
        && (buttons & InputEvent.BUTTON3_MASK) == 0)
 | 
						|
      throw new IllegalArgumentException ("Robot: mousePress:"
 | 
						|
                                          + " invalid button mask");
 | 
						|
 | 
						|
    peer.mousePress (buttons);
 | 
						|
 | 
						|
    if (waitForIdle)
 | 
						|
      waitForIdle ();
 | 
						|
 | 
						|
    if (autoDelay > 0)
 | 
						|
      delay (autoDelay);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Release one or more mouse buttons.
 | 
						|
   *
 | 
						|
   * @param buttons the buttons to release; a bitmask of one or more
 | 
						|
   * of these {@link InputEvent} fields:
 | 
						|
   *
 | 
						|
   * <ul>
 | 
						|
   *   <li>BUTTON1_MASK</li>
 | 
						|
   *   <li>BUTTON2_MASK</li>
 | 
						|
   *   <li>BUTTON3_MASK</li>
 | 
						|
   * </ul>
 | 
						|
   *
 | 
						|
   * @exception IllegalArgumentException if the button mask is invalid
 | 
						|
   */
 | 
						|
  public void mouseRelease(int buttons)
 | 
						|
  {
 | 
						|
    if ((buttons & InputEvent.BUTTON1_MASK) == 0
 | 
						|
        && (buttons & InputEvent.BUTTON2_MASK) == 0
 | 
						|
        && (buttons & InputEvent.BUTTON3_MASK) == 0)
 | 
						|
      throw new IllegalArgumentException ("Robot: mouseRelease:"
 | 
						|
                                          + " invalid button mask");
 | 
						|
 | 
						|
    peer.mouseRelease (buttons);
 | 
						|
 | 
						|
    if (waitForIdle)
 | 
						|
      waitForIdle ();
 | 
						|
 | 
						|
    if (autoDelay > 0)
 | 
						|
      delay (autoDelay);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Rotate the mouse scroll wheel.
 | 
						|
   *
 | 
						|
   * @param wheelAmt number of steps to rotate mouse wheel.  negative
 | 
						|
   * to rotate wheel up (away from the user), positive to rotate wheel
 | 
						|
   * down (toward the user).
 | 
						|
   *
 | 
						|
   * @since 1.4
 | 
						|
   */
 | 
						|
  public void mouseWheel (int wheelAmt)
 | 
						|
  {
 | 
						|
    peer.mouseWheel (wheelAmt);
 | 
						|
 | 
						|
    if (waitForIdle)
 | 
						|
      waitForIdle ();
 | 
						|
 | 
						|
    if (autoDelay > 0)
 | 
						|
      delay (autoDelay);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Press a key.
 | 
						|
   *
 | 
						|
   * @param keycode key to press, a {@link java.awt.event.KeyEvent} VK_ constant
 | 
						|
   *
 | 
						|
   * @exception IllegalArgumentException if keycode is not a valid key
 | 
						|
   */
 | 
						|
  public void keyPress (int keycode)
 | 
						|
  {
 | 
						|
    peer.keyPress (keycode);
 | 
						|
 | 
						|
    if (waitForIdle)
 | 
						|
      waitForIdle ();
 | 
						|
 | 
						|
    if (autoDelay > 0)
 | 
						|
      delay (autoDelay);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Release a key.
 | 
						|
   *
 | 
						|
   * @param keycode key to release, a {@link java.awt.event.KeyEvent} VK_
 | 
						|
   *                constant
 | 
						|
   *
 | 
						|
   * @exception IllegalArgumentException if keycode is not a valid key
 | 
						|
   */
 | 
						|
  public void keyRelease (int keycode)
 | 
						|
  {
 | 
						|
    peer.keyRelease (keycode);
 | 
						|
 | 
						|
    if (waitForIdle)
 | 
						|
      waitForIdle ();
 | 
						|
 | 
						|
    if (autoDelay > 0)
 | 
						|
      delay (autoDelay);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Return the color of the pixel at the given screen coordinates.
 | 
						|
   *
 | 
						|
   * @param x the x coordinate of the pixel
 | 
						|
   * @param y the y coordinate of the pixel
 | 
						|
   *
 | 
						|
   * @return the Color of the pixel at screen coodinates <code>(x, y)</code>
 | 
						|
   */
 | 
						|
  public Color getPixelColor (int x, int y)
 | 
						|
  {
 | 
						|
    return new Color (peer.getRGBPixel (x, y));
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Create an image containing pixels read from the screen.  The
 | 
						|
   * image does not include the mouse pointer.
 | 
						|
   *
 | 
						|
   * @param screenRect the rectangle of pixels to capture, in screen
 | 
						|
   * coordinates
 | 
						|
   *
 | 
						|
   * @return a BufferedImage containing the requested pixels
 | 
						|
   *
 | 
						|
   * @exception IllegalArgumentException if requested width and height
 | 
						|
   * are not both greater than zero
 | 
						|
   * @exception SecurityException if readDisplayPixels permission is
 | 
						|
   * not granted
 | 
						|
   */
 | 
						|
  public BufferedImage createScreenCapture (Rectangle screenRect)
 | 
						|
  {
 | 
						|
    if (screenRect.width <= 0)
 | 
						|
      throw new IllegalArgumentException ("Robot: capture width is <= 0");
 | 
						|
 | 
						|
    if (screenRect.height <= 0)
 | 
						|
      throw new IllegalArgumentException ("Robot: capture height is <= 0");
 | 
						|
 | 
						|
    SecurityManager sm = System.getSecurityManager ();
 | 
						|
    if (sm != null)
 | 
						|
      sm.checkPermission (new AWTPermission ("readDisplayPixels"));
 | 
						|
 | 
						|
    int[] pixels = peer.getRGBPixels (screenRect);
 | 
						|
 | 
						|
    BufferedImage bufferedImage =
 | 
						|
      new BufferedImage (screenRect.width, screenRect.height,
 | 
						|
                         BufferedImage.TYPE_INT_ARGB);
 | 
						|
 | 
						|
    bufferedImage.setRGB (0, 0, screenRect.width, screenRect.height,
 | 
						|
                          pixels, 0, screenRect.width);
 | 
						|
 | 
						|
    return bufferedImage;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Check if this Robot automatically calls {@link #waitForIdle()} after
 | 
						|
   * generating an event.
 | 
						|
   *
 | 
						|
   * @return true if waitForIdle is automatically called
 | 
						|
   */
 | 
						|
  public boolean isAutoWaitForIdle ()
 | 
						|
  {
 | 
						|
    return waitForIdle;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set whether or not this Robot automatically calls {@link
 | 
						|
   * #waitForIdle()} after generating an event.
 | 
						|
   *
 | 
						|
   * @param isOn true if waitForIdle should be called automatically
 | 
						|
   */
 | 
						|
  public void setAutoWaitForIdle (boolean isOn)
 | 
						|
  {
 | 
						|
    waitForIdle = isOn;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Retrieve the length of time this Robot sleeps after generating an
 | 
						|
   * event.
 | 
						|
   *
 | 
						|
   * @return the length of time in milliseconds
 | 
						|
   */
 | 
						|
  public int getAutoDelay ()
 | 
						|
  {
 | 
						|
    return autoDelay;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the length of time this Robot sleeps after generating an
 | 
						|
   * event.
 | 
						|
   *
 | 
						|
   * @param ms the length of time in milliseconds
 | 
						|
   *
 | 
						|
   * @exception IllegalArgumentException if ms is not between 0 and
 | 
						|
   * 60,000 milliseconds inclusive
 | 
						|
   */
 | 
						|
  public void setAutoDelay (int ms)
 | 
						|
  {
 | 
						|
    if (ms <= 0 || ms >= 60000)
 | 
						|
      throw new IllegalArgumentException ("Robot: delay length out-of-bounds");
 | 
						|
 | 
						|
    autoDelay = ms;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sleep for a specified length of time.
 | 
						|
   *
 | 
						|
   * @param ms the length of time in milliseconds
 | 
						|
   *
 | 
						|
   * @exception IllegalArgumentException if ms is not between 0 and
 | 
						|
   * 60,000 milliseconds inclusive
 | 
						|
   */
 | 
						|
  public void delay (int ms)
 | 
						|
  {
 | 
						|
    if (ms < 0 || ms > 60000)
 | 
						|
      throw new IllegalArgumentException ("Robot: delay length out-of-bounds");
 | 
						|
 | 
						|
    try
 | 
						|
      {
 | 
						|
        Thread.sleep (ms);
 | 
						|
      }
 | 
						|
    catch (InterruptedException e)
 | 
						|
      {
 | 
						|
        System.err.println ("Robot: delay interrupted");
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Wait until all events currently on the event queue have been
 | 
						|
   * dispatched.
 | 
						|
   */
 | 
						|
  public void waitForIdle ()
 | 
						|
  {
 | 
						|
    if (EventQueue.isDispatchThread ())
 | 
						|
      throw new IllegalThreadStateException ("Robot: waitForIdle called from "
 | 
						|
                                             + "the event dispatch thread");
 | 
						|
 | 
						|
    try
 | 
						|
      {
 | 
						|
        EventQueue.invokeAndWait (new Runnable () { public void run () { } });
 | 
						|
      }
 | 
						|
    catch (InterruptedException e)
 | 
						|
      {
 | 
						|
        System.err.println ("Robot: waitForIdle interrupted");
 | 
						|
      }
 | 
						|
    catch (InvocationTargetException e)
 | 
						|
      {
 | 
						|
        System.err.println ("Robot: waitForIdle cannot invoke target");
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Return a string representation of this Robot.
 | 
						|
   *
 | 
						|
   * @return a string representation
 | 
						|
   */
 | 
						|
  public String toString ()
 | 
						|
  {
 | 
						|
    return getClass ().getName ()
 | 
						|
        + "[ autoDelay = " + autoDelay + ", autoWaitForIdle = "
 | 
						|
        + waitForIdle + " ]";
 | 
						|
  }
 | 
						|
}
 |