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 + " ]";
 | |
|   }
 | |
| }
 |