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
);
246 gtk_selection_data_set_pixbuf (selection
, pixbuf
);
248 /* if the GtkImage is offscreen, this is a temporary pixbuf
249 which should be thrown out. */
250 if(cp_gtk_image_is_offscreen (env
, gtkimage
) == JNI_TRUE
)
251 gdk_pixbuf_unref (pixbuf
);
254 else if (info
== URI_TARGET
)
261 uris
= (*env
)->CallObjectMethod(env
,
262 gtk_clipboard_instance
,
266 count
= (*env
)->GetArrayLength (env
, uris
);
270 list
= (gchar
**) JCL_malloc (env
, (count
+ 1) * sizeof (gchar
*));
271 for (i
= 0; i
< count
; i
++)
276 /* Mark NULL in so case of some error we can find the end. */
278 uri
= (*env
)->GetObjectArrayElement (env
, uris
, i
);
281 text
= (*env
)->GetStringUTFChars (env
, uri
, NULL
);
284 list
[i
] = strdup (text
);
285 (*env
)->ReleaseStringUTFChars (env
, uri
, text
);
291 gtk_selection_data_set_uris (selection
, list
);
294 for (i
= 0; list
[i
] != NULL
; i
++)
296 JCL_free (env
, list
);
302 clipboard_clear_func (GtkClipboard
*clipboard
,
303 gpointer user_data
__attribute__((unused
)))
305 JNIEnv
*env
= cp_gtk_gdk_env();
306 if (clipboard
== cp_gtk_clipboard
)
307 (*env
)->CallVoidMethod (env
, cp_gtk_clipboard_instance
,
308 setSystemContentsID
, JNI_TRUE
);
310 (*env
)->CallVoidMethod (env
, cp_gtk_selection_instance
,
311 setSystemContentsID
, JNI_TRUE
);
315 JNIEXPORT
void JNICALL
316 Java_gnu_java_awt_peer_gtk_GtkClipboard_advertiseContent
319 jobjectArray mime_array
,
320 #if GTK_MINOR_VERSION > 4
321 jboolean add_text
, jboolean add_images
, jboolean add_uris
)
323 jboolean add_text
__attribute__((unused
)),
324 jboolean add_images
__attribute__((unused
)),
325 jboolean add_uris
__attribute__((unused
)))
328 GtkTargetList
*target_list
;
330 GtkTargetEntry
*targets
;
333 gdk_threads_enter ();
334 target_list
= gtk_target_list_new (NULL
, 0);
336 if (mime_array
!= NULL
)
338 n
= (*env
)->GetArrayLength (env
, mime_array
);
339 for (i
= 0; i
< n
; i
++)
345 target
= (*env
)->GetObjectArrayElement (env
, mime_array
, i
);
348 text
= (*env
)->GetStringUTFChars (env
, target
, NULL
);
352 atom
= gdk_atom_intern (text
, FALSE
);
353 gtk_target_list_add (target_list
, atom
, 0, OBJECT_TARGET
);
355 (*env
)->ReleaseStringUTFChars (env
, target
, text
);
359 /* Add extra targets that gtk+ can provide/translate for us. */
360 #if GTK_MINOR_VERSION > 4
362 gtk_target_list_add_text_targets (target_list
, TEXT_TARGET
);
364 gtk_target_list_add_image_targets (target_list
, IMAGE_TARGET
, TRUE
);
366 gtk_target_list_add_uri_targets (target_list
, URI_TARGET
);
369 gtk_target_list_add (target_list
,
370 gdk_atom_intern ("STRING", FALSE
),
375 /* Turn list into a target table. */
376 n
= g_list_length (target_list
->list
);
379 targets
= g_new (GtkTargetEntry
, n
);
380 for (list
= target_list
->list
, i
= 0;
382 list
= list
->next
, i
++)
384 GtkTargetPair
*pair
= (GtkTargetPair
*) list
->data
;
385 targets
[i
].target
= gdk_atom_name (pair
->target
);
386 targets
[i
].flags
= pair
->flags
;
387 targets
[i
].info
= pair
->info
;
390 /* Set the targets plus callback functions and ask for the clipboard
391 to be stored when the application exists if supported. */
392 if ((*env
)->IsSameObject(env
, instance
, cp_gtk_clipboard_instance
))
394 if (gtk_clipboard_set_with_data (cp_gtk_clipboard
, targets
, n
,
396 clipboard_clear_func
,
399 #if GTK_MINOR_VERSION > 4
400 gtk_clipboard_set_can_store (cp_gtk_clipboard
, NULL
, 0);
406 if (gtk_clipboard_set_with_data (cp_gtk_selection
, targets
, n
,
408 clipboard_clear_func
,
411 #if GTK_MINOR_VERSION > 4
412 gtk_clipboard_set_can_store (cp_gtk_selection
, NULL
, 0);
417 for (i
= 0; i
< n
; i
++)
418 g_free (targets
[i
].target
);
422 gtk_target_list_unref (target_list
);
423 gdk_threads_leave ();