2 Copyright (C) 1998, 1999, 2005 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 standard (string targets) shared with GtkSelection. */
49 GtkClipboard
*cp_gtk_clipboard
;
51 jstring cp_gtk_stringTarget
;
52 jstring cp_gtk_imageTarget
;
53 jstring cp_gtk_filesTarget
;
55 /* Simple id to keep track of the selection we are currently managing. */
56 #if SIZEOF_VOID_P == 8
57 static long current_selection
= 0;
59 static int current_selection
= 0;
62 /* Whether we "own" the clipboard. And may clear it. */
65 static jclass gtk_clipboard_class
;
66 static jmethodID setSystemContentsID
;
68 static jobject gtk_clipboard_instance
= NULL
;
69 static jmethodID provideContentID
;
70 static jmethodID provideTextID
;
71 static jmethodID provideImageID
;
72 static jmethodID provideURIsID
;
74 /* Called when clipboard owner changes. Used to update available targets. */
75 #if GTK_MINOR_VERSION > 4
77 clipboard_owner_change_cb (GtkClipboard
*clipboard
__attribute__((unused
)),
78 GdkEvent
*event
__attribute__((unused
)),
79 gpointer user_data
__attribute__((unused
)))
81 /* These are only interesting when we are not the owner. Otherwise
82 we will have the set and clear functions doing the updating. */
83 JNIEnv
*env
= cp_gtk_gdk_env ();
85 (*env
)->CallStaticVoidMethod (env
, gtk_clipboard_class
,
90 JNIEXPORT jboolean JNICALL
91 Java_gnu_java_awt_peer_gtk_GtkClipboard_initNativeState (JNIEnv
*env
,
100 gtk_clipboard_class
= gtkclipboard
;
101 setSystemContentsID
= (*env
)->GetStaticMethodID (env
, gtk_clipboard_class
,
104 if (setSystemContentsID
== NULL
)
107 cp_gtk_stringTarget
= (*env
)->NewGlobalRef(env
, string
);
108 cp_gtk_imageTarget
= (*env
)->NewGlobalRef(env
, image
);
109 cp_gtk_filesTarget
= (*env
)->NewGlobalRef(env
, files
);
111 gdk_threads_enter ();
112 cp_gtk_clipboard
= gtk_clipboard_get (GDK_SELECTION_CLIPBOARD
);
114 display
= gtk_clipboard_get_display (cp_gtk_clipboard
);
115 /* Check for support for clipboard owner changes. */
116 #if GTK_MINOR_VERSION > 4
117 if (gdk_display_supports_selection_notification (display
))
119 g_signal_connect (cp_gtk_clipboard
, "owner-change",
120 G_CALLBACK (clipboard_owner_change_cb
), NULL
);
121 gdk_display_request_selection_notification (display
,
122 GDK_SELECTION_CLIPBOARD
);
123 can_cache
= JNI_TRUE
;
127 can_cache
= JNI_FALSE
;
128 gdk_threads_leave ();
134 clipboard_get_func (GtkClipboard
*clipboard
__attribute__((unused
)),
135 GtkSelectionData
*selection
,
137 gpointer user_data
__attribute__((unused
)))
139 JNIEnv
*env
= cp_gtk_gdk_env ();
141 if (info
== OBJECT_TARGET
)
143 const gchar
*target_name
;
144 jstring target_string
;
149 target_name
= gdk_atom_name (selection
->target
);
150 if (target_name
== NULL
)
152 target_string
= (*env
)->NewStringUTF (env
, target_name
);
153 if (target_string
== NULL
)
155 bytes
= (*env
)->CallObjectMethod(env
,
156 gtk_clipboard_instance
,
161 len
= (*env
)->GetArrayLength(env
, bytes
);
164 barray
= (*env
)->GetByteArrayElements(env
, bytes
, NULL
);
167 gtk_selection_data_set (selection
, selection
->target
, 8,
168 (guchar
*) barray
, len
);
170 (*env
)->ReleaseByteArrayElements(env
, bytes
, barray
, 0);
173 else if (info
== TEXT_TARGET
)
178 string
= (*env
)->CallObjectMethod(env
,
179 gtk_clipboard_instance
,
183 len
= (*env
)->GetStringUTFLength (env
, string
);
186 text
= (*env
)->GetStringUTFChars (env
, string
, NULL
);
190 gtk_selection_data_set_text (selection
, text
, len
);
191 (*env
)->ReleaseStringUTFChars (env
, string
, text
);
193 /* Images and URIs/Files support only available with gtk+2.6 or higher. */
194 #if GTK_MINOR_VERSION > 4
195 else if (info
== IMAGE_TARGET
)
198 GdkPixbuf
*pixbuf
= NULL
;
200 gtkimage
= (*env
)->CallObjectMethod(env
,
201 gtk_clipboard_instance
,
203 if (gtkimage
== NULL
)
206 pixbuf
= cp_gtk_image_get_pixbuf (env
, gtkimage
);
209 gtk_selection_data_set_pixbuf (selection
, pixbuf
);
211 /* if the GtkImage is offscreen, this is a temporary pixbuf
212 which should be thrown out. */
213 if(cp_gtk_image_is_offscreen (env
, gtkimage
) == JNI_TRUE
)
214 gdk_pixbuf_unref (pixbuf
);
217 else if (info
== URI_TARGET
)
224 uris
= (*env
)->CallObjectMethod(env
,
225 gtk_clipboard_instance
,
229 count
= (*env
)->GetArrayLength (env
, uris
);
233 list
= (gchar
**) JCL_malloc (env
, (count
+ 1) * sizeof (gchar
*));
234 for (i
= 0; i
< count
; i
++)
239 /* Mark NULL in so case of some error we can find the end. */
241 uri
= (*env
)->GetObjectArrayElement (env
, uris
, i
);
244 text
= (*env
)->GetStringUTFChars (env
, uri
, NULL
);
247 list
[i
] = strdup (text
);
248 (*env
)->ReleaseStringUTFChars (env
, uri
, text
);
254 gtk_selection_data_set_uris (selection
, list
);
257 for (i
= 0; list
[i
] != NULL
; i
++)
259 JCL_free (env
, list
);
265 clipboard_clear_func (GtkClipboard
*clipboard
__attribute__((unused
)),
268 #if SIZEOF_VOID_P == 8
269 if (owner
&& (long) user_data
== current_selection
)
271 if (owner
&& (int) user_data
== current_selection
)
274 JNIEnv
*env
= cp_gtk_gdk_env();
276 (*env
)->CallStaticVoidMethod (env
, gtk_clipboard_class
,
277 setSystemContentsID
);
281 JNIEXPORT
void JNICALL
282 Java_gnu_java_awt_peer_gtk_GtkClipboard_advertiseContent
285 jobjectArray mime_array
,
286 #if GTK_MINOR_VERSION > 4
287 jboolean add_text
, jboolean add_images
, jboolean add_uris
)
289 jboolean add_text
__attribute__((unused
)),
290 jboolean add_images
__attribute__((unused
)),
291 jboolean add_uris
__attribute__((unused
)))
294 GtkTargetList
*target_list
;
296 GtkTargetEntry
*targets
;
299 gdk_threads_enter ();
300 target_list
= gtk_target_list_new (NULL
, 0);
302 if (mime_array
!= NULL
)
304 n
= (*env
)->GetArrayLength (env
, mime_array
);
305 for (i
= 0; i
< n
; i
++)
311 target
= (*env
)->GetObjectArrayElement (env
, mime_array
, i
);
314 text
= (*env
)->GetStringUTFChars (env
, target
, NULL
);
318 atom
= gdk_atom_intern (text
, FALSE
);
319 gtk_target_list_add (target_list
, atom
, 0, OBJECT_TARGET
);
321 (*env
)->ReleaseStringUTFChars (env
, target
, text
);
325 /* Add extra targets that gtk+ can provide/translate for us. */
326 #if GTK_MINOR_VERSION > 4
328 gtk_target_list_add_text_targets (target_list
, TEXT_TARGET
);
330 gtk_target_list_add_image_targets (target_list
, IMAGE_TARGET
, TRUE
);
332 gtk_target_list_add_uri_targets (target_list
, URI_TARGET
);
335 gtk_target_list_add (target_list
,
336 gdk_atom_intern ("STRING", FALSE
),
341 /* Turn list into a target table. */
342 n
= g_list_length (target_list
->list
);
345 targets
= g_new (GtkTargetEntry
, n
);
346 for (list
= target_list
->list
, i
= 0;
348 list
= list
->next
, i
++)
350 GtkTargetPair
*pair
= (GtkTargetPair
*) list
->data
;
351 targets
[i
].target
= gdk_atom_name (pair
->target
);
352 targets
[i
].flags
= pair
->flags
;
353 targets
[i
].info
= pair
->info
;
356 /* Set the targets plus callback functions and ask for the clipboard
357 to be stored when the application exists if supported. */
359 if (gtk_clipboard_set_with_data (cp_gtk_clipboard
, targets
, n
,
361 clipboard_clear_func
,
362 (gpointer
) current_selection
))
365 if (gtk_clipboard_instance
== NULL
)
367 JNIEnv
*env
= cp_gtk_gdk_env ();
368 gtk_clipboard_instance
= (*env
)->NewGlobalRef(env
, instance
);
371 = (*env
)->GetMethodID (env
, gtk_clipboard_class
,
373 "(Ljava/lang/String;)[B");
374 if (provideContentID
== NULL
)
378 = (*env
)->GetMethodID (env
, gtk_clipboard_class
,
379 "provideText", "()Ljava/lang/String;");
380 if (provideTextID
== NULL
)
384 = (*env
)->GetMethodID (env
, gtk_clipboard_class
,
386 "()Lgnu/java/awt/peer/gtk/GtkImage;");
387 if (provideImageID
== NULL
)
391 = (*env
)->GetMethodID (env
, gtk_clipboard_class
,
393 "()[Ljava/lang/String;");
394 if (provideURIsID
== NULL
)
397 #if GTK_MINOR_VERSION > 4
398 gtk_clipboard_set_can_store (cp_gtk_clipboard
, NULL
, 0);
404 (*env
)->CallStaticVoidMethod (env
, gtk_clipboard_class
,
405 setSystemContentsID
);
408 for (i
= 0; i
< n
; i
++)
409 g_free (targets
[i
].target
);
414 gtk_clipboard_clear (cp_gtk_clipboard
);
418 gtk_target_list_unref (target_list
);
419 gdk_threads_leave ();