Index: configure.ac =================================================================== RCS file: /cvsroot/classpath/classpath/configure.ac,v retrieving revision 1.66 diff -u -r1.66 configure.ac --- configure.ac 2 Jan 2005 20:08:50 -0000 1.66 +++ configure.ac 3 Jan 2005 12:20:36 -0000 @@ -224,6 +224,7 @@ dnl Check for AWT related gthread/gtk/libart_lgpl if test "x${COMPILE_GTK_PEER}" = xyes; then + AC_PATH_XTRA PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.4 gthread-2.0 >= 2.2 libart-2.0) AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) Index: gnu/java/awt/ClasspathToolkit.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/ClasspathToolkit.java,v retrieving revision 1.5 diff -u -r1.5 ClasspathToolkit.java --- gnu/java/awt/ClasspathToolkit.java 13 Oct 2004 14:32:33 -0000 1.5 +++ gnu/java/awt/ClasspathToolkit.java 3 Jan 2005 12:20:36 -0000 @@ -41,12 +41,14 @@ import gnu.java.awt.peer.ClasspathFontPeer; import gnu.java.awt.peer.ClasspathTextLayoutPeer; +import java.awt.AWTException; import java.awt.Image; import java.awt.Dimension; import java.awt.DisplayMode; import java.awt.Font; import java.awt.FontMetrics; import java.awt.GraphicsEnvironment; +import java.awt.GraphicsDevice; import java.awt.Toolkit; import java.awt.font.FontRenderContext; import java.awt.image.ColorModel; @@ -58,6 +60,7 @@ import java.text.AttributedString; import java.util.HashMap; import java.util.Map; +import java.awt.peer.RobotPeer; /** @@ -348,4 +351,7 @@ { return null; } + + public abstract RobotPeer createRobot (GraphicsDevice screen) + throws AWTException; } Index: gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java,v retrieving revision 1.4 diff -u -r1.4 GdkGraphicsEnvironment.java --- gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java 22 Oct 2004 10:11:11 -0000 1.4 +++ gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java 3 Jan 2005 12:20:36 -0000 @@ -42,6 +42,7 @@ import java.awt.Graphics2D; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.HeadlessException; import java.awt.Rectangle; import java.awt.Shape; import java.awt.image.BufferedImage; @@ -61,7 +62,10 @@ public GraphicsDevice getDefaultScreenDevice () { - throw new java.lang.UnsupportedOperationException (); + if (GraphicsEnvironment.isHeadless ()) + throw new HeadlessException (); + + return new GdkScreenGraphicsDevice (); } public Graphics2D createGraphics (BufferedImage image) Index: gnu/java/awt/peer/gtk/GdkRobotPeer.java =================================================================== RCS file: gnu/java/awt/peer/gtk/GdkRobotPeer.java diff -N gnu/java/awt/peer/gtk/GdkRobotPeer.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gnu/java/awt/peer/gtk/GdkRobotPeer.java 3 Jan 2005 12:20:36 -0000 @@ -0,0 +1,95 @@ +/* GdkRobot.java -- an XTest implementation of RobotPeer + Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA +02111-1307 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 gnu.java.awt.peer.gtk; + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.GraphicsDevice; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.Rectangle; +import java.awt.peer.RobotPeer; + +/** + * Implements the RobotPeer interface using the XTest extension. + * + * @author Thomas Fitzsimmons + */ +public class GdkRobotPeer implements RobotPeer +{ + // gdk-pixbuf provides data in RGBA format + static final ColorModel cm = new DirectColorModel (32, 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff); + + public GdkRobotPeer (GraphicsDevice screen) throws AWTException + { + // FIXME: make use of screen parameter when GraphicsDevice is + // implemented. + if (!initXTest ()) + throw new AWTException ("XTest extension not supported"); + } + + native boolean initXTest (); + + // RobotPeer methods + public native void mouseMove (int x, int y); + public native void mousePress (int buttons); + public native void mouseRelease (int buttons); + public native void mouseWheel (int wheelAmt); + public native void keyPress (int keycode); + public native void keyRelease (int keycode); + native int[] nativeGetRGBPixels (int x, int y, int width, int height); + + public int getRGBPixel (int x, int y) + { + return cm.getRGB (nativeGetRGBPixels (x, y, 1, 1)[0]); + } + + public int[] getRGBPixels (Rectangle r) + { + int[] gdk_pixels = nativeGetRGBPixels (r.x, r.y, r.width, r.height); + int[] pixels = new int[r.width * r.height]; + + for (int i = 0; i < r.width * r.height; i++) + pixels[i] = cm.getRGB (gdk_pixels[i]); + + return pixels; + } +} Index: gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java =================================================================== RCS file: gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java diff -N gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java 3 Jan 2005 12:20:36 -0000 @@ -0,0 +1,73 @@ +/* GdkScreenGraphicsDevice.java -- information about a screen device + Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA +02111-1307 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 gnu.java.awt.peer.gtk; + +import java.awt.GraphicsDevice; +import java.awt.GraphicsConfiguration; + +public class GdkScreenGraphicsDevice extends GraphicsDevice +{ + public GdkScreenGraphicsDevice () + { + super (); + } + + public int getType () + { + return GraphicsDevice.TYPE_RASTER_SCREEN; + } + + public String getIDstring () + { + // FIXME: query X for this string + return "default GDK device ID string"; + } + + public GraphicsConfiguration[] getConfigurations () + { + // FIXME: query X for the list of possible configurations + return null; + } + + public GraphicsConfiguration getDefaultConfiguration () + { + // FIXME: query X for default configuration + return null; + } +} Index: gnu/java/awt/peer/gtk/GtkToolkit.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java,v retrieving revision 1.60 diff -u -r1.60 GtkToolkit.java --- gnu/java/awt/peer/gtk/GtkToolkit.java 30 Dec 2004 16:51:20 -0000 1.60 +++ gnu/java/awt/peer/gtk/GtkToolkit.java 3 Jan 2005 12:20:36 -0000 @@ -622,4 +622,9 @@ { throw new UnsupportedOperationException(); } + + public RobotPeer createRobot (GraphicsDevice screen) throws AWTException + { + return new GdkRobotPeer (screen); + } } Index: java/awt/Robot.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/awt/Robot.java,v retrieving revision 1.3 diff -u -r1.3 Robot.java --- java/awt/Robot.java 9 Jun 2003 15:48:11 -0000 1.3 +++ java/awt/Robot.java 3 Jan 2005 12:20:36 -0000 @@ -1,5 +1,5 @@ -/* Robot.java -- - Copyright (C) 2002 Free Software Foundation, Inc. +/* Robot.java -- a native input event generator + Copyright (C) 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,112 +38,383 @@ package java.awt; +import java.awt.event.InputEvent; import java.awt.image.BufferedImage; +import java.awt.peer.RobotPeer; +import gnu.java.awt.ClasspathToolkit; /** + * 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 address@hidden AWTEvents} on the AWT event queue, its use + * is not restricted to Java programs. It can be to programatically + * drive any graphical application. + * + * This implementation requires an X server that supports the XTest + * extension. + * + * @author Thomas Fitzsimmons (address@hidden) + * * @since 1.3 */ -/** STUB CLASS ONLY */ public class Robot { - private GraphicsDevice screen; private boolean waitForIdle; private int autoDelay; - + private RobotPeer peer; + /** - * Creates a Robot object. - * - * @exception AWTException If GraphicsEnvironment.isHeadless() returns true. - * @exception SecurityException If createRobot permission is not granted. + * 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 + public Robot () throws AWTException { - throw new Error("not implemented"); + 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 ()); } /** - * Creates a Robot object. - * - * @exception AWTException If GraphicsEnvironment.isHeadless() returns true. - * @exception IllegalArgumentException If screen is not a screen - * GraphicsDevice. - * @exception SecurityException If createRobot permission is not granted. + * 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 + public Robot (GraphicsDevice screen) throws AWTException { - this(); - this.screen = screen; + 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); } - public void mousePress(int buttons) + /** + * Press one or more mouse buttons. + * + * @param buttons the buttons to press; a bitmask of one or more of + * these address@hidden InputEvent} fields: + * + * + * + * @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 address@hidden InputEvent} fields: + * + * + * + * @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); } - public void mouseWheel(int wheelAmt) + /** + * 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); } - public void keyPress(int keycode) + /** + * Press a key. + * + * @param keycode key to press, a address@hidden 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); } - public void keyRelease(int keycode) + /** + * Release a key. + * + * @param keycode key to release, a address@hidden 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); } - - public Color getPixelColor(int x, int y) + + /** + * 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 (x, y) + */ + public Color getPixelColor (int x, int y) { - return null; + return new Color (peer.getRGBPixel (x, y)); } - public BufferedImage createScreenCapture(Rectangle screen) + /** + * 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) { - return null; + 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; } - - public boolean isAutoWaitForIdle() + + /** + * Check if this Robot automatically calls address@hidden waitForIdle} after + * generating an event. + * + * @return true if waitForIdle is automatically called + */ + public boolean isAutoWaitForIdle () { return waitForIdle; } - - public void setAutoWaitForIdle(boolean value) + + /** + * Set whether or not this Robot automatically calls address@hidden + * waitForIdle} after generating an event. + * + * @param isOn true if waitForIdle should be called automatically + */ + public void setAutoWaitForIdle (boolean isOn) { - waitForIdle = value; + waitForIdle = isOn; } - - public int getAutoDelay() + + /** + * Retrieve the length of time this Robot sleeps after generating an + * event. + * + * @return the length of time in milliseconds + */ + public int getAutoDelay () { return autoDelay; } - - public void setAutoDelay(int ms) + + /** + * 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(); - + if (ms <= 0 || ms >= 60000) + throw new IllegalArgumentException ("Robot: delay length out-of-bounds"); + autoDelay = ms; } - public void delay(int 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(); + throw new IllegalArgumentException ("Robot: delay length out-of-bounds"); + + try + { + Thread.sleep (ms); + } + catch (InterruptedException e) + { + System.err.println ("Robot: delay interrupted"); + } } - public void waitForIdle() + /** + * Wait until the event dispatch thread is idle. + */ + public void waitForIdle () { + if (EventQueue.isDispatchThread ()) + throw new IllegalThreadStateException ("Robot: waitForIdle called from " + + "the event dispatch thread"); + + EventQueue q = Toolkit.getDefaultToolkit ().getSystemEventQueue (); + + while (q.peekEvent () != null) + { + try + { + wait (); + } + catch (InterruptedException e) + { + System.err.println ("Robot: waitForIdle interrupted"); + } + } } - public String toString() + /** + * Return a string representation of this Robot. + * + * @return a string representation + */ + public String toString () { - return "unimplemented"; + return getClass ().getName () + + "[ autoDelay = " + autoDelay + ", autoWaitForIdle = " + + waitForIdle + " ]"; } -} // class Robot +} Index: java/awt/peer/RobotPeer.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/awt/peer/RobotPeer.java,v retrieving revision 1.2 diff -u -r1.2 RobotPeer.java --- java/awt/peer/RobotPeer.java 12 Oct 2003 13:53:40 -0000 1.2 +++ java/awt/peer/RobotPeer.java 3 Jan 2005 12:20:36 -0000 @@ -43,12 +43,12 @@ public interface RobotPeer { void mouseMove (int x, int y); - void mousePress (int x); - void mouseRelease (int x); - void mouseWheel (int x); - void keyPress (int x); - void keyRelease (int x); + void mousePress (int buttons); + void mouseRelease (int buttons); + void mouseWheel (int wheelAmt); + void keyPress (int keycode); + void keyRelease (int keycode); int getRGBPixel (int x, int y); - int[] getRGBPixels (Rectangle r); + int[] getRGBPixels (Rectangle screen); } // interface RobotPeer Index: include/Makefile.am =================================================================== RCS file: /cvsroot/classpath/classpath/include/Makefile.am,v retrieving revision 1.35 diff -u -r1.35 Makefile.am --- include/Makefile.am 29 Dec 2004 21:39:36 -0000 1.35 +++ include/Makefile.am 3 Jan 2005 12:20:36 -0000 @@ -34,6 +34,7 @@ $(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkGraphics2D.h \ $(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h \ $(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkPixbufDecoder.h \ +$(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkRobotPeer.h \ $(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkTextLayout.h \ $(top_srcdir)/include/gnu_java_awt_peer_gtk_GtkButtonPeer.h \ $(top_srcdir)/include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h \ Index: include/gnu_java_awt_peer_gtk_GdkRobotPeer.h =================================================================== RCS file: include/gnu_java_awt_peer_gtk_GdkRobotPeer.h diff -N include/gnu_java_awt_peer_gtk_GdkRobotPeer.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ include/gnu_java_awt_peer_gtk_GdkRobotPeer.h 3 Jan 2005 12:20:36 -0000 @@ -0,0 +1,26 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ + +#ifndef __gnu_java_awt_peer_gtk_GdkRobotPeer__ +#define __gnu_java_awt_peer_gtk_GdkRobotPeer__ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GdkRobotPeer_initXTest (JNIEnv *env, jobject); +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseMove (JNIEnv *env, jobject, jint, jint); +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mousePress (JNIEnv *env, jobject, jint); +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseRelease (JNIEnv *env, jobject, jint); +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseWheel (JNIEnv *env, jobject, jint); +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkRobotPeer_keyPress (JNIEnv *env, jobject, jint); +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkRobotPeer_keyRelease (JNIEnv *env, jobject, jint); +JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkRobotPeer_nativeGetRGBPixels (JNIEnv *env, jobject, jint, jint, jint, jint); + +#ifdef __cplusplus +} +#endif + +#endif /* __gnu_java_awt_peer_gtk_GdkRobotPeer__ */ Index: native/jni/gtk-peer/Makefile.am =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/Makefile.am,v retrieving revision 1.19 diff -u -r1.19 Makefile.am --- native/jni/gtk-peer/Makefile.am 27 Oct 2004 00:03:10 -0000 1.19 +++ native/jni/gtk-peer/Makefile.am 3 Jan 2005 12:20:36 -0000 @@ -16,6 +16,7 @@ gnu_java_awt_peer_gtk_GdkGraphics.c \ gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c \ gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \ + gnu_java_awt_peer_gtk_GdkRobotPeer.c \ gnu_java_awt_peer_gtk_GdkTextLayout.c \ gnu_java_awt_peer_gtk_GtkButtonPeer.c \ gnu_java_awt_peer_gtk_GtkCanvasPeer.c \ @@ -55,7 +56,7 @@ libgtkpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/native_state.lo -AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @CAIRO_LIBS@ @PANGOFT2_LIBS@ +AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @CAIRO_LIBS@ @PANGOFT2_LIBS@ @X_LIBS@ -lXtst AM_CPPFLAGS = @CLASSPATH_INCLUDES@ # Just the WARNING_CFLAGS. We cannot use the strict flags since the gtk Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c =================================================================== RCS file: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c diff -N native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c 3 Jan 2005 12:20:36 -0000 @@ -0,0 +1,325 @@ +/* gdkrobotpeer.c + Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA +02111-1307 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. */ + +#include "gtkpeer.h" +#include "gnu_java_awt_peer_gtk_GdkRobotPeer.h" +#include +#include + +static int +awt_button_mask_to_num (int buttons) +{ + switch (buttons) + { + case AWT_BUTTON1_MASK: + return 1; + case AWT_BUTTON2_MASK: + return 2; + case AWT_BUTTON3_MASK: + return 3; + } + + return 0; +} + +JNIEXPORT jboolean JNICALL +Java_gnu_java_awt_peer_gtk_GdkRobotPeer_initXTest + (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused))) +{ + GdkDisplay *display; + Display *xdisplay; + int event_basep; + int error_basep; + int majorp; + int minorp; + jboolean result; + + gdk_threads_enter (); + + display = gdk_display_get_default (); + xdisplay = GDK_DISPLAY_XDISPLAY (display); + + result = XTestQueryExtension (xdisplay, + &event_basep, + &error_basep, + &majorp, + &minorp); + + gdk_threads_leave (); + + return result; +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseMove + (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint x, jint y) +{ + GdkDisplay *display; + Display *xdisplay; + int result; + + gdk_threads_enter (); + + display = gdk_display_get_default (); + xdisplay = GDK_DISPLAY_XDISPLAY (display); + + result = XTestFakeMotionEvent (xdisplay, + -1, + x, y, CurrentTime); + + XFlush (xdisplay); + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mousePress + (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint buttons) +{ + GdkDisplay *display; + Display *xdisplay; + int result; + + gdk_threads_enter (); + + display = gdk_display_get_default (); + xdisplay = GDK_DISPLAY_XDISPLAY (display); + + result = XTestFakeButtonEvent (xdisplay, + awt_button_mask_to_num (buttons), + True, CurrentTime); + + XFlush (xdisplay); + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseRelease + (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint buttons) +{ + GdkDisplay *display; + Display *xdisplay; + int result; + + gdk_threads_enter (); + + display = gdk_display_get_default (); + xdisplay = GDK_DISPLAY_XDISPLAY (display); + + result = XTestFakeButtonEvent (xdisplay, + awt_button_mask_to_num (buttons), + False, CurrentTime); + + XFlush (xdisplay); + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseWheel + (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint wheelAmt) +{ + GdkDisplay *display; + Display *xdisplay; + int i = 0; + + gdk_threads_enter (); + + display = gdk_display_get_default (); + xdisplay = GDK_DISPLAY_XDISPLAY (display); + + if (wheelAmt < 0) + for (i = 0; i < -wheelAmt; i++) + { + XTestFakeButtonEvent (xdisplay, + 4, + True, CurrentTime); + XTestFakeButtonEvent (xdisplay, + 4, + False, CurrentTime); + } + else + for (i = 0; i < wheelAmt; i++) + { + XTestFakeButtonEvent (xdisplay, + 5, + True, CurrentTime); + XTestFakeButtonEvent (xdisplay, + 5, + False, CurrentTime); + } + + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GdkRobotPeer_keyPress + (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint keycode) +{ + GdkDisplay *display; + Display *xdisplay; + GdkKeymapKey *keymap_keys = NULL; + gint n_keys = 0; + guint lookup_keyval = 0; + int result; + + gdk_threads_enter (); + + display = gdk_display_get_default (); + xdisplay = GDK_DISPLAY_XDISPLAY (display); + + lookup_keyval = awt_keycode_to_keysym (keycode, AWT_KEY_LOCATION_LEFT); + + if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (), + lookup_keyval, + &keymap_keys, + &n_keys)) + { + /* No matching keymap entry was found. */ + g_printerr ("No matching keymap entries were found\n"); + gdk_threads_leave (); + return; + } + + /* If n_keys > 1 then there are multiple hardware keycodes that + translate to lookup_keyval. We arbitrarily choose the first + hardware keycode from the list returned by + gdk_keymap_get_entries_for_keyval. */ + result = XTestFakeKeyEvent (xdisplay, + keymap_keys[0].keycode, + True, CurrentTime); + + g_free (keymap_keys); + + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GdkRobotPeer_keyRelease + (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint keycode) +{ + GdkDisplay *display; + Display *xdisplay; + GdkKeymapKey *keymap_keys = NULL; + gint n_keys = 0; + guint lookup_keyval = 0; + int result; + + gdk_threads_enter (); + + display = gdk_display_get_default (); + xdisplay = GDK_DISPLAY_XDISPLAY (display); + + lookup_keyval = awt_keycode_to_keysym (keycode, AWT_KEY_LOCATION_LEFT); + + if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (), + lookup_keyval, + &keymap_keys, + &n_keys)) + { + /* No matching keymap entry was found. */ + g_printerr ("No matching keymap entries were found\n"); + gdk_threads_leave (); + return; + } + + /* If n_keys > 1 then there are multiple hardware keycodes that + translate to lookup_keyval. We arbitrarily choose the first + hardware keycode from the list returned by + gdk_keymap_get_entries_for_keyval. */ + result = XTestFakeKeyEvent (xdisplay, + keymap_keys[0].keycode, + False, CurrentTime); + + g_free (keymap_keys); + + gdk_threads_leave (); +} + +JNIEXPORT jintArray JNICALL +Java_gnu_java_awt_peer_gtk_GdkRobotPeer_nativeGetRGBPixels + (JNIEnv *env, jobject obj __attribute__((unused)), jint x, jint y, + jint width, jint height) +{ + jint stride_bytes, stride_pixels, n_channels, n_pixels; + jintArray jpixels; + jint *java_pixels; + guchar *gdk_pixels; + GdkPixbuf *pixbuf_no_alpha = NULL; + GdkPixbuf *pixbuf = NULL; + +#ifndef WORDS_BIGENDIAN + int i; +#endif + + gdk_threads_enter (); + + pixbuf_no_alpha = gdk_pixbuf_get_from_drawable (NULL, + gdk_get_default_root_window (), + NULL, x, y, 0, 0, + width, height); + + pixbuf = gdk_pixbuf_add_alpha(pixbuf_no_alpha, FALSE, 0, 0, 0); + g_assert (gdk_pixbuf_get_has_alpha (pixbuf)); + + stride_bytes = gdk_pixbuf_get_rowstride (pixbuf); + n_channels = gdk_pixbuf_get_n_channels (pixbuf); + stride_pixels = stride_bytes / n_channels; + n_pixels = height * stride_pixels; + gdk_pixels = gdk_pixbuf_get_pixels (pixbuf); + + jpixels = (*env)->NewIntArray (env, n_pixels); + java_pixels = (*env)->GetIntArrayElements (env, jpixels, NULL); + + memcpy (java_pixels, + gdk_pixels, + (height * stride_bytes)); + +#ifndef WORDS_BIGENDIAN + /* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */ + for (i = 0; i < n_pixels; ++i) + { + java_pixels[i] = SWAPU32 ((unsigned)java_pixels[i]); + } +#endif + + g_object_unref (pixbuf); + + (*env)->ReleaseIntArrayElements (env, jpixels, java_pixels, 0); + + gdk_threads_leave (); + + return jpixels; +} Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c,v retrieving revision 1.40 diff -u -r1.40 gnu_java_awt_peer_gtk_GtkComponentPeer.c --- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c 28 Oct 2004 20:58:25 -0000 1.40 +++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c 3 Jan 2005 12:20:36 -0000 @@ -60,7 +60,7 @@ #ifdef __GNUC__ __inline #endif -static guint +guint awt_keycode_to_keysym (jint keyCode, jint keyLocation) { /* GDK_A through GDK_Z */ Index: native/jni/gtk-peer/gtkpeer.h =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gtkpeer.h,v retrieving revision 1.27 diff -u -r1.27 gtkpeer.h --- native/jni/gtk-peer/gtkpeer.h 26 Oct 2004 23:50:04 -0000 1.27 +++ native/jni/gtk-peer/gtkpeer.h 3 Jan 2005 12:20:36 -0000 @@ -147,6 +147,10 @@ #define AWT_BUTTON2_DOWN_MASK (1 << 11) #define AWT_BUTTON3_DOWN_MASK (1 << 12) +#define AWT_BUTTON1_MASK (1 << 4) +#define AWT_BUTTON2_MASK (1 << 3) +#define AWT_BUTTON3_MASK (1 << 2) + #define MULTI_CLICK_TIME 250 /* as opposed to a MULTI_PASS_TIME :) */ @@ -480,6 +484,8 @@ jint keyevent_state_to_awt_mods (GdkEvent *event); +guint awt_keycode_to_keysym (jint keyCode, jint keyLocation); + struct item_event_hook_info { jobject peer_obj;