summaryrefslogtreecommitdiff
path: root/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c')
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c422
1 files changed, 422 insertions, 0 deletions
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
new file mode 100644
index 000000000..0b076f864
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
@@ -0,0 +1,422 @@
+/* gtkclipboard.c
+ Copyright (C) 1998, 1999, 2005, 2006 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. */
+
+
+#include "jcl.h"
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkClipboard.h"
+
+#define OBJECT_TARGET 1
+#define TEXT_TARGET 2
+#define IMAGE_TARGET 3
+#define URI_TARGET 4
+
+/* The clipboard and selection plus corresponding GtkClipboard objects. */
+GtkClipboard *cp_gtk_clipboard;
+GtkClipboard *cp_gtk_selection;
+
+jobject cp_gtk_clipboard_instance;
+jobject cp_gtk_selection_instance;
+
+/* Standard (string targets) shared with GtkSelection. */
+jstring cp_gtk_stringTarget;
+jstring cp_gtk_imageTarget;
+jstring cp_gtk_filesTarget;
+
+static jclass gtk_clipboard_class;
+
+static jmethodID setSystemContentsID;
+static jmethodID provideContentID;
+static jmethodID provideTextID;
+static jmethodID provideImageID;
+static jmethodID provideURIsID;
+
+/* Called when clipboard owner changes. Used to update available targets. */
+#if GTK_MINOR_VERSION > 4
+static void
+clipboard_owner_change_cb (GtkClipboard *clipboard,
+ GdkEvent *event __attribute__((unused)),
+ gpointer user_data __attribute__((unused)))
+{
+ JNIEnv *env = cp_gtk_gdk_env ();
+ if (clipboard == cp_gtk_clipboard)
+ (*env)->CallVoidMethod (env, cp_gtk_clipboard_instance,
+ setSystemContentsID, JNI_FALSE);
+ else
+ (*env)->CallVoidMethod (env, cp_gtk_selection_instance,
+ setSystemContentsID, JNI_FALSE);
+
+}
+#endif
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_GtkClipboard_initNativeState (JNIEnv *env,
+ jclass clz,
+ jobject gtkclipboard,
+ jobject gtkselection,
+ jstring string,
+ jstring image,
+ jstring files)
+{
+ GdkDisplay* display;
+ jboolean can_cache;
+
+ gtk_clipboard_class = clz;
+ setSystemContentsID = (*env)->GetMethodID (env, gtk_clipboard_class,
+ "setSystemContents",
+ "(Z)V");
+ if (setSystemContentsID == NULL)
+ return JNI_FALSE;
+
+ provideContentID = (*env)->GetMethodID (env, gtk_clipboard_class,
+ "provideContent",
+ "(Ljava/lang/String;)[B");
+ if (provideContentID == NULL)
+ return JNI_FALSE;
+
+ provideTextID = (*env)->GetMethodID (env, gtk_clipboard_class,
+ "provideText",
+ "()Ljava/lang/String;");
+ if (provideTextID == NULL)
+ return JNI_FALSE;
+
+ provideImageID = (*env)->GetMethodID (env, gtk_clipboard_class,
+ "provideImage",
+ "()Lgnu/java/awt/peer/gtk/GtkImage;");
+ if (provideImageID == NULL)
+ return JNI_FALSE;
+
+ provideURIsID = (*env)->GetMethodID (env, gtk_clipboard_class,
+ "provideURIs",
+ "()[Ljava/lang/String;");
+ if (provideURIsID == NULL)
+ return JNI_FALSE;
+
+ cp_gtk_clipboard_instance = (*env)->NewGlobalRef(env, gtkclipboard);
+ cp_gtk_selection_instance = (*env)->NewGlobalRef(env, gtkselection);
+
+ cp_gtk_stringTarget = (*env)->NewGlobalRef(env, string);
+ cp_gtk_imageTarget = (*env)->NewGlobalRef(env, image);
+ cp_gtk_filesTarget = (*env)->NewGlobalRef(env, files);
+
+ gdk_threads_enter ();
+ cp_gtk_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ cp_gtk_selection = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+
+ display = gtk_clipboard_get_display (cp_gtk_clipboard);
+ /* Check for support for clipboard owner changes. */
+#if GTK_MINOR_VERSION > 4
+ if (gdk_display_supports_selection_notification (display))
+ {
+ g_signal_connect (cp_gtk_clipboard, "owner-change",
+ G_CALLBACK (clipboard_owner_change_cb), NULL);
+ g_signal_connect (cp_gtk_selection, "owner-change",
+ G_CALLBACK (clipboard_owner_change_cb), NULL);
+ gdk_display_request_selection_notification (display,
+ GDK_SELECTION_CLIPBOARD);
+ gdk_display_request_selection_notification (display,
+ GDK_SELECTION_PRIMARY);
+ can_cache = JNI_TRUE;
+ }
+ else
+#endif
+ can_cache = JNI_FALSE;
+
+ gdk_threads_leave ();
+
+ return can_cache;
+}
+
+static void
+clipboard_get_func (GtkClipboard *clipboard,
+ GtkSelectionData *selection,
+ guint info,
+ gpointer user_data __attribute__((unused)))
+{
+ jobject gtk_clipboard_instance;
+ JNIEnv *env = cp_gtk_gdk_env ();
+
+ if (clipboard == cp_gtk_clipboard)
+ gtk_clipboard_instance = cp_gtk_clipboard_instance;
+ else
+ gtk_clipboard_instance = cp_gtk_selection_instance;
+
+ if (info == OBJECT_TARGET)
+ {
+ const gchar *target_name;
+ jstring target_string;
+ jbyteArray bytes;
+ jint len;
+ jbyte *barray;
+
+ target_name = gdk_atom_name (selection->target);
+ if (target_name == NULL)
+ return;
+ target_string = (*env)->NewStringUTF (env, target_name);
+ if (target_string == NULL)
+ return;
+ bytes = (*env)->CallObjectMethod(env,
+ gtk_clipboard_instance,
+ provideContentID,
+ target_string);
+ (*env)->DeleteLocalRef(env, target_string);
+ if (bytes == NULL)
+ return;
+ len = (*env)->GetArrayLength(env, bytes);
+ if (len <= 0)
+ return;
+ barray = (*env)->GetByteArrayElements(env, bytes, NULL);
+ if (barray == NULL)
+ return;
+ gtk_selection_data_set (selection, selection->target, 8,
+ (guchar *) barray, len);
+
+ (*env)->ReleaseByteArrayElements(env, bytes, barray, 0);
+
+ }
+ else if (info == TEXT_TARGET)
+ {
+ jstring string;
+ const gchar *text;
+ int len;
+ string = (*env)->CallObjectMethod(env,
+ gtk_clipboard_instance,
+ provideTextID);
+ if (string == NULL)
+ return;
+ len = (*env)->GetStringUTFLength (env, string);
+ if (len == -1)
+ return;
+ text = (*env)->GetStringUTFChars (env, string, NULL);
+ if (text == NULL)
+ return;
+
+ gtk_selection_data_set_text (selection, text, len);
+ (*env)->ReleaseStringUTFChars (env, string, text);
+ }
+ /* Images and URIs/Files support only available with gtk+2.6 or higher. */
+#if GTK_MINOR_VERSION > 4
+ else if (info == IMAGE_TARGET)
+ {
+ jobject gtkimage;
+ GdkPixbuf *pixbuf = NULL;
+
+ gtkimage = (*env)->CallObjectMethod(env,
+ gtk_clipboard_instance,
+ provideImageID);
+ if (gtkimage == NULL)
+ return;
+
+ pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage);
+ if (pixbuf != NULL)
+ gtk_selection_data_set_pixbuf (selection, pixbuf);
+ }
+ else if (info == URI_TARGET)
+ {
+ jobjectArray uris;
+ jint count;
+ int i;
+ gchar **list;
+
+ uris = (*env)->CallObjectMethod(env,
+ gtk_clipboard_instance,
+ provideURIsID);
+ if (uris == NULL)
+ return;
+ count = (*env)->GetArrayLength (env, uris);
+ if (count <= 0)
+ return;
+
+ list = (gchar **) JCL_malloc (env, (count + 1) * sizeof (gchar *));
+ for (i = 0; i < count; i++)
+ {
+ const char *text;
+ jstring uri;
+
+ /* Mark NULL in so case of some error we can find the end. */
+ list[i] = NULL;
+ uri = (*env)->GetObjectArrayElement (env, uris, i);
+ if (uri == NULL)
+ break;
+ text = (*env)->GetStringUTFChars (env, uri, NULL);
+ if (text == NULL)
+ {
+ (*env)->DeleteLocalRef(env, uri);
+ break;
+ }
+ list[i] = strdup (text);
+ (*env)->ReleaseStringUTFChars (env, uri, text);
+ (*env)->DeleteLocalRef(env, uri);
+ }
+
+ if (i == count)
+ {
+ list[count] = NULL;
+ gtk_selection_data_set_uris (selection, list);
+ }
+
+ for (i = 0; list[i] != NULL; i++)
+ free (list[i]);
+ JCL_free (env, list);
+ }
+#endif
+}
+
+static void
+clipboard_clear_func (GtkClipboard *clipboard,
+ gpointer user_data __attribute__((unused)))
+{
+ JNIEnv *env = cp_gtk_gdk_env();
+ if (clipboard == cp_gtk_clipboard)
+ (*env)->CallVoidMethod (env, cp_gtk_clipboard_instance,
+ setSystemContentsID, JNI_TRUE);
+ else
+ (*env)->CallVoidMethod (env, cp_gtk_selection_instance,
+ setSystemContentsID, JNI_TRUE);
+
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkClipboard_advertiseContent
+(JNIEnv *env,
+ jobject instance,
+ jobjectArray mime_array,
+#if GTK_MINOR_VERSION > 4
+ jboolean add_text, jboolean add_images, jboolean add_uris)
+#else
+ jboolean add_text __attribute__((unused)),
+ jboolean add_images __attribute__((unused)),
+ jboolean add_uris __attribute__((unused)))
+#endif
+{
+ GtkTargetList *target_list;
+ GList *list;
+ GtkTargetEntry *targets;
+ gint n, i;
+
+ gdk_threads_enter ();
+ target_list = gtk_target_list_new (NULL, 0);
+
+ if (mime_array != NULL)
+ {
+ n = (*env)->GetArrayLength (env, mime_array);
+ for (i = 0; i < n; i++)
+ {
+ const char *text;
+ jstring target;
+ GdkAtom atom;
+
+ target = (*env)->GetObjectArrayElement (env, mime_array, i);
+ if (target == NULL)
+ break;
+ text = (*env)->GetStringUTFChars (env, target, NULL);
+ if (text == NULL)
+ break;
+
+ atom = gdk_atom_intern (text, FALSE);
+ gtk_target_list_add (target_list, atom, 0, OBJECT_TARGET);
+
+ (*env)->ReleaseStringUTFChars (env, target, text);
+ }
+ }
+
+ /* Add extra targets that gtk+ can provide/translate for us. */
+#if GTK_MINOR_VERSION > 4
+ if (add_text)
+ gtk_target_list_add_text_targets (target_list, TEXT_TARGET);
+ if (add_images)
+ gtk_target_list_add_image_targets (target_list, IMAGE_TARGET, TRUE);
+ if (add_uris)
+ gtk_target_list_add_uri_targets (target_list, URI_TARGET);
+#else
+ if (add_text)
+ gtk_target_list_add (target_list,
+ gdk_atom_intern ("STRING", FALSE),
+ 0, TEXT_TARGET);
+#endif
+
+
+ /* Turn list into a target table. */
+ n = g_list_length (target_list->list);
+ if (n > 0)
+ {
+ targets = g_new (GtkTargetEntry, n);
+ for (list = target_list->list, i = 0;
+ list != NULL;
+ list = list->next, i++)
+ {
+ GtkTargetPair *pair = (GtkTargetPair *) list->data;
+ targets[i].target = gdk_atom_name (pair->target);
+ targets[i].flags = pair->flags;
+ targets[i].info = pair->info;
+ }
+
+ /* Set the targets plus callback functions and ask for the clipboard
+ to be stored when the application exists if supported. */
+ if ((*env)->IsSameObject(env, instance, cp_gtk_clipboard_instance))
+ {
+ if (gtk_clipboard_set_with_data (cp_gtk_clipboard, targets, n,
+ clipboard_get_func,
+ clipboard_clear_func,
+ NULL))
+ {
+#if GTK_MINOR_VERSION > 4
+ gtk_clipboard_set_can_store (cp_gtk_clipboard, NULL, 0);
+#endif
+ }
+ }
+ else
+ {
+ if (gtk_clipboard_set_with_data (cp_gtk_selection, targets, n,
+ clipboard_get_func,
+ clipboard_clear_func,
+ NULL))
+ {
+#if GTK_MINOR_VERSION > 4
+ gtk_clipboard_set_can_store (cp_gtk_selection, NULL, 0);
+#endif
+ }
+ }
+
+ for (i = 0; i < n; i++)
+ g_free (targets[i].target);
+ g_free (targets);
+ }
+
+ gtk_target_list_unref (target_list);
+ gdk_threads_leave ();
+}