diff options
Diffstat (limited to 'libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c')
-rw-r--r-- | libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c new file mode 100644 index 00000000000..6b1b4a9f3b5 --- /dev/null +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c @@ -0,0 +1,328 @@ +/* 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 <gdk/gdkx.h> +#include <X11/extensions/XTest.h> + +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); + } + + XFlush (xdisplay); + 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); + + XFlush (xdisplay); + 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); + + XFlush (xdisplay); + 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; +} |