2 Copyright (C) 1998, 1999, 2005, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 #include "gnu_java_awt_peer_gtk_GtkClipboard.h"
43 #define OBJECT_TARGET 1
45 #define IMAGE_TARGET 3
48 /* The clipboard and selection plus corresponding GtkClipboard objects. */
49 GtkClipboard *cp_gtk_clipboard;
50 GtkClipboard *cp_gtk_selection;
52 jobject cp_gtk_clipboard_instance;
53 jobject cp_gtk_selection_instance;
55 /* Standard (string targets) shared with GtkSelection. */
56 jstring cp_gtk_stringTarget;
57 jstring cp_gtk_imageTarget;
58 jstring cp_gtk_filesTarget;
60 static jclass gtk_clipboard_class;
62 static jmethodID setSystemContentsID;
63 static jmethodID provideContentID;
64 static jmethodID provideTextID;
65 static jmethodID provideImageID;
66 static jmethodID provideURIsID;
68 /* Called when clipboard owner changes. Used to update available targets. */
69 #if GTK_MINOR_VERSION > 4
71 clipboard_owner_change_cb (GtkClipboard *clipboard,
72 GdkEvent *event __attribute__((unused)),
73 gpointer user_data __attribute__((unused)))
75 JNIEnv *env = cp_gtk_gdk_env ();
76 if (clipboard == cp_gtk_clipboard)
77 (*env)->CallVoidMethod (env, cp_gtk_clipboard_instance,
78 setSystemContentsID, JNI_FALSE);
80 (*env)->CallVoidMethod (env, cp_gtk_selection_instance,
81 setSystemContentsID, JNI_FALSE);
86 JNIEXPORT jboolean JNICALL
87 Java_gnu_java_awt_peer_gtk_GtkClipboard_initNativeState (JNIEnv *env,
98 gtk_clipboard_class = clz;
99 setSystemContentsID = (*env)->GetMethodID (env, gtk_clipboard_class,
102 if (setSystemContentsID == NULL)
105 provideContentID = (*env)->GetMethodID (env, gtk_clipboard_class,
107 "(Ljava/lang/String;)[B");
108 if (provideContentID == NULL)
111 provideTextID = (*env)->GetMethodID (env, gtk_clipboard_class,
113 "()Ljava/lang/String;");
114 if (provideTextID == NULL)
117 provideImageID = (*env)->GetMethodID (env, gtk_clipboard_class,
119 "()Lgnu/java/awt/peer/gtk/GtkImage;");
120 if (provideImageID == NULL)
123 provideURIsID = (*env)->GetMethodID (env, gtk_clipboard_class,
125 "()[Ljava/lang/String;");
126 if (provideURIsID == NULL)
129 cp_gtk_clipboard_instance = (*env)->NewGlobalRef(env, gtkclipboard);
130 cp_gtk_selection_instance = (*env)->NewGlobalRef(env, gtkselection);
132 cp_gtk_stringTarget = (*env)->NewGlobalRef(env, string);
133 cp_gtk_imageTarget = (*env)->NewGlobalRef(env, image);
134 cp_gtk_filesTarget = (*env)->NewGlobalRef(env, files);
136 gdk_threads_enter ();
137 cp_gtk_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
138 cp_gtk_selection = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
140 display = gtk_clipboard_get_display (cp_gtk_clipboard);
141 /* Check for support for clipboard owner changes. */
142 #if GTK_MINOR_VERSION > 4
143 if (gdk_display_supports_selection_notification (display))
145 g_signal_connect (cp_gtk_clipboard, "owner-change",
146 G_CALLBACK (clipboard_owner_change_cb), NULL);
147 g_signal_connect (cp_gtk_selection, "owner-change",
148 G_CALLBACK (clipboard_owner_change_cb), NULL);
149 gdk_display_request_selection_notification (display,
150 GDK_SELECTION_CLIPBOARD);
151 gdk_display_request_selection_notification (display,
152 GDK_SELECTION_PRIMARY);
153 can_cache = JNI_TRUE;
157 can_cache = JNI_FALSE;
159 gdk_threads_leave ();
165 clipboard_get_func (GtkClipboard *clipboard,
166 GtkSelectionData *selection,
168 gpointer user_data __attribute__((unused)))
170 jobject gtk_clipboard_instance;
171 JNIEnv *env = cp_gtk_gdk_env ();
173 if (clipboard == cp_gtk_clipboard)
174 gtk_clipboard_instance = cp_gtk_clipboard_instance;
176 gtk_clipboard_instance = cp_gtk_selection_instance;
178 if (info == OBJECT_TARGET)
180 const gchar *target_name;
181 jstring target_string;
186 target_name = gdk_atom_name (selection->target);
187 if (target_name == NULL)
189 target_string = (*env)->NewStringUTF (env, target_name);
190 if (target_string == NULL)
192 bytes = (*env)->CallObjectMethod(env,
193 gtk_clipboard_instance,
198 len = (*env)->GetArrayLength(env, bytes);
201 barray = (*env)->GetByteArrayElements(env, bytes, NULL);
204 gtk_selection_data_set (selection, selection->target, 8,
205 (guchar *) barray, len);
207 (*env)->ReleaseByteArrayElements(env, bytes, barray, 0);
210 else if (info == TEXT_TARGET)
215 string = (*env)->CallObjectMethod(env,
216 gtk_clipboard_instance,
220 len = (*env)->GetStringUTFLength (env, string);
223 text = (*env)->GetStringUTFChars (env, string, NULL);
227 gtk_selection_data_set_text (selection, text, len);
228 (*env)->ReleaseStringUTFChars (env, string, text);
230 /* Images and URIs/Files support only available with gtk+2.6 or higher. */
231 #if GTK_MINOR_VERSION > 4
232 else if (info == IMAGE_TARGET)
235 GdkPixbuf *pixbuf = NULL;
237 gtkimage = (*env)->CallObjectMethod(env,
238 gtk_clipboard_instance,
240 if (gtkimage == NULL)
243 pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage);
245 gtk_selection_data_set_pixbuf (selection, pixbuf);
247 else if (info == URI_TARGET)
254 uris = (*env)->CallObjectMethod(env,
255 gtk_clipboard_instance,
259 count = (*env)->GetArrayLength (env, uris);
263 list = (gchar **) JCL_malloc (env, (count + 1) * sizeof (gchar *));
264 for (i = 0; i < count; i++)
269 /* Mark NULL in so case of some error we can find the end. */
271 uri = (*env)->GetObjectArrayElement (env, uris, i);
274 text = (*env)->GetStringUTFChars (env, uri, NULL);
277 list[i] = strdup (text);
278 (*env)->ReleaseStringUTFChars (env, uri, text);
284 gtk_selection_data_set_uris (selection, list);
287 for (i = 0; list[i] != NULL; i++)
289 JCL_free (env, list);
295 clipboard_clear_func (GtkClipboard *clipboard,
296 gpointer user_data __attribute__((unused)))
298 JNIEnv *env = cp_gtk_gdk_env();
299 if (clipboard == cp_gtk_clipboard)
300 (*env)->CallVoidMethod (env, cp_gtk_clipboard_instance,
301 setSystemContentsID, JNI_TRUE);
303 (*env)->CallVoidMethod (env, cp_gtk_selection_instance,
304 setSystemContentsID, JNI_TRUE);
308 JNIEXPORT void JNICALL
309 Java_gnu_java_awt_peer_gtk_GtkClipboard_advertiseContent
312 jobjectArray mime_array,
313 #if GTK_MINOR_VERSION > 4
314 jboolean add_text, jboolean add_images, jboolean add_uris)
316 jboolean add_text __attribute__((unused)),
317 jboolean add_images __attribute__((unused)),
318 jboolean add_uris __attribute__((unused)))
321 GtkTargetList *target_list;
323 GtkTargetEntry *targets;
326 gdk_threads_enter ();
327 target_list = gtk_target_list_new (NULL, 0);
329 if (mime_array != NULL)
331 n = (*env)->GetArrayLength (env, mime_array);
332 for (i = 0; i < n; i++)
338 target = (*env)->GetObjectArrayElement (env, mime_array, i);
341 text = (*env)->GetStringUTFChars (env, target, NULL);
345 atom = gdk_atom_intern (text, FALSE);
346 gtk_target_list_add (target_list, atom, 0, OBJECT_TARGET);
348 (*env)->ReleaseStringUTFChars (env, target, text);
352 /* Add extra targets that gtk+ can provide/translate for us. */
353 #if GTK_MINOR_VERSION > 4
355 gtk_target_list_add_text_targets (target_list, TEXT_TARGET);
357 gtk_target_list_add_image_targets (target_list, IMAGE_TARGET, TRUE);
359 gtk_target_list_add_uri_targets (target_list, URI_TARGET);
362 gtk_target_list_add (target_list,
363 gdk_atom_intern ("STRING", FALSE),
368 /* Turn list into a target table. */
369 n = g_list_length (target_list->list);
372 targets = g_new (GtkTargetEntry, n);
373 for (list = target_list->list, i = 0;
375 list = list->next, i++)
377 GtkTargetPair *pair = (GtkTargetPair *) list->data;
378 targets[i].target = gdk_atom_name (pair->target);
379 targets[i].flags = pair->flags;
380 targets[i].info = pair->info;
383 /* Set the targets plus callback functions and ask for the clipboard
384 to be stored when the application exists if supported. */
385 if ((*env)->IsSameObject(env, instance, cp_gtk_clipboard_instance))
387 if (gtk_clipboard_set_with_data (cp_gtk_clipboard, targets, n,
389 clipboard_clear_func,
392 #if GTK_MINOR_VERSION > 4
393 gtk_clipboard_set_can_store (cp_gtk_clipboard, NULL, 0);
399 if (gtk_clipboard_set_with_data (cp_gtk_selection, targets, n,
401 clipboard_clear_func,
404 #if GTK_MINOR_VERSION > 4
405 gtk_clipboard_set_can_store (cp_gtk_selection, NULL, 0);
410 for (i = 0; i < n; i++)
411 g_free (targets[i].target);
415 gtk_target_list_unref (target_list);
416 gdk_threads_leave ();