Merge from mainline.
[official-gcc.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkSelection.c
blobbe03c45254e1457510ec80df8ef602140edaeec2
1 /* gtkselection.c -- Native C functions for GtkSelection class using gtk+.
2 Copyright (C) 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)
9 any later version.
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
19 02110-1301 USA.
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
24 combination.
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. */
39 #include "jcl.h"
40 #include "gtkpeer.h"
41 #include "gnu_java_awt_peer_gtk_GtkSelection.h"
43 static jmethodID mimeTypesAvailableID;
45 /* Note this is actually just a GtkClipboardReceivedFunc, not a real
46 GtkClipboardTargetsReceivedFunc, see requestMimeTypes. */
47 static void
48 clipboard_targets_received (GtkClipboard *clipboard
49 __attribute__((unused)),
50 GtkSelectionData *target_data,
51 gpointer selection)
53 GdkAtom *targets = NULL;
54 gint targets_len = 0;
55 gchar **target_strings = NULL;
56 jobjectArray strings = NULL;
57 int strings_len = 0;
58 gboolean include_text = FALSE;
59 gboolean include_image = FALSE;
60 gboolean include_uris = FALSE;
61 jobject selection_obj = (jobject) selection;
62 JNIEnv *env = cp_gtk_gdk_env ();
64 if (target_data != NULL && target_data->length > 0)
66 include_text = gtk_selection_data_targets_include_text (target_data);
68 #if GTK_MINOR_VERSION > 4
69 include_image = gtk_selection_data_targets_include_image (target_data,
70 TRUE);
71 #endif
72 if (gtk_selection_data_get_targets (target_data, &targets, &targets_len))
74 int i;
75 GdkAtom uri_list_atom = gdk_atom_intern ("text/uri-list", FALSE);
76 target_strings = g_new (gchar*, targets_len);
77 if (target_strings != NULL)
78 for (i = 0; i < targets_len; i++)
80 gchar *name = gdk_atom_name (targets[i]);
81 if (strchr (name, '/') != NULL)
83 target_strings[i] = name;
84 strings_len++;
85 if (! include_uris && targets[i] == uri_list_atom)
86 include_uris = TRUE;
88 else
89 target_strings[i] = NULL;
93 if (target_strings != NULL)
95 int i = 0, j = 0;
96 jclass stringClass;
98 if (include_text)
99 strings_len++;
100 if (include_image)
101 strings_len++;
102 if (include_uris)
103 strings_len++;
105 stringClass = (*env)->FindClass (env, "java/lang/String");
106 strings = (*env)->NewObjectArray (env, strings_len, stringClass,
107 NULL);
108 if (strings != NULL)
110 if (include_text)
111 (*env)->SetObjectArrayElement (env, strings, i++,
112 cp_gtk_stringTarget);
113 if (include_image)
114 (*env)->SetObjectArrayElement (env, strings, i++,
115 cp_gtk_imageTarget);
116 if (include_uris)
117 (*env)->SetObjectArrayElement (env, strings, i++,
118 cp_gtk_filesTarget);
120 while(i < strings_len)
122 if (target_strings[j] == NULL)
123 j++;
124 else
126 jstring string;
127 string = (*env)->NewStringUTF (env,
128 target_strings[j++]);
129 if (string == NULL)
130 break;
131 (*env)->SetObjectArrayElement (env, strings, i++,
132 string);
133 (*env)->DeleteLocalRef (env, string);
138 for (i = 0; i < targets_len; i++)
139 g_free (target_strings[i]);
140 g_free (target_strings);
144 (*env)->CallVoidMethod (env, selection_obj,
145 mimeTypesAvailableID,
146 strings);
147 (*env)->DeleteGlobalRef (env, selection_obj);
150 JNIEXPORT void JNICALL
151 Java_gnu_java_awt_peer_gtk_GtkSelection_requestMimeTypes
152 (JNIEnv *env, jobject selection, jboolean clipboard)
154 jobject selection_obj;
155 GtkClipboard *gtk_clipboard;
156 selection_obj = (*env)->NewGlobalRef(env, selection);
157 if (selection_obj == NULL)
158 return;
160 if (mimeTypesAvailableID == NULL)
162 jclass gtk_selection_class;
163 gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
164 mimeTypesAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
165 "mimeTypesAvailable",
166 "([Ljava/lang/String;)V");
167 if (mimeTypesAvailableID == NULL)
168 return;
171 if (clipboard)
172 gtk_clipboard = cp_gtk_clipboard;
173 else
174 gtk_clipboard = cp_gtk_selection;
176 /* We would have liked to call gtk_clipboard_request_targets ()
177 since that is more general. But the result of that, an array of
178 GdkAtoms, cannot be used with the
179 gtk_selection_data_targets_include_<x> functions (despite what
180 the name suggests). */
181 gdk_threads_enter ();
182 gtk_clipboard_request_contents (gtk_clipboard,
183 gdk_atom_intern ("TARGETS", FALSE),
184 clipboard_targets_received,
185 (gpointer) selection_obj);
186 gdk_threads_leave ();
190 static jmethodID textAvailableID;
192 static void
193 clipboard_text_received (GtkClipboard *clipboard
194 __attribute__((unused)),
195 const gchar *text,
196 gpointer selection)
198 jstring string;
199 jobject selection_obj = (jobject) selection;
201 JNIEnv *env = cp_gtk_gdk_env ();
202 if (text != NULL)
203 string = (*env)->NewStringUTF (env, text);
204 else
205 string = NULL;
207 (*env)->CallVoidMethod (env, selection_obj,
208 textAvailableID,
209 string);
210 (*env)->DeleteGlobalRef (env, selection_obj);
212 if (string != NULL)
213 (*env)->DeleteLocalRef (env, string);
217 JNIEXPORT void JNICALL
218 Java_gnu_java_awt_peer_gtk_GtkSelection_requestText
219 (JNIEnv *env, jobject selection, jboolean clipboard)
221 jobject selection_obj;
222 GtkClipboard *gtk_clipboard;
223 selection_obj = (*env)->NewGlobalRef(env, selection);
224 if (selection_obj == NULL)
225 return;
227 if (textAvailableID == NULL)
229 jclass gtk_selection_class;
230 gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
231 textAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
232 "textAvailable",
233 "(Ljava/lang/String;)V");
234 if (textAvailableID == NULL)
235 return;
238 if (clipboard)
239 gtk_clipboard = cp_gtk_clipboard;
240 else
241 gtk_clipboard = cp_gtk_selection;
243 gdk_threads_enter ();
244 gtk_clipboard_request_text (gtk_clipboard,
245 clipboard_text_received,
246 (gpointer) selection_obj);
247 gdk_threads_leave ();
250 static jmethodID imageAvailableID;
252 static void
253 clipboard_image_received (GtkClipboard *clipboard
254 __attribute__((unused)),
255 GdkPixbuf *pixbuf,
256 gpointer selection)
258 jobject pointer = NULL;
259 jobject selection_obj = (jobject) selection;
260 JNIEnv *env = cp_gtk_gdk_env ();
262 if (pixbuf != NULL)
264 g_object_ref (pixbuf);
265 pointer = JCL_NewRawDataObject (env, (void *) pixbuf);
268 (*env)->CallVoidMethod (env, selection_obj,
269 imageAvailableID,
270 pointer);
271 (*env)->DeleteGlobalRef (env, selection_obj);
274 JNIEXPORT void JNICALL
275 Java_gnu_java_awt_peer_gtk_GtkSelection_requestImage (JNIEnv *env,
276 jobject obj,
277 jboolean clipboard)
279 jobject selection_obj;
280 GtkClipboard *gtk_clipboard;
281 selection_obj = (*env)->NewGlobalRef(env, obj);
282 if (selection_obj == NULL)
283 return;
285 if (imageAvailableID == NULL)
287 jclass gtk_selection_class;
288 gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
289 imageAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
290 "imageAvailable",
291 "(Lgnu/classpath/Pointer;)V");
292 if (imageAvailableID == NULL)
293 return;
296 if (clipboard)
297 gtk_clipboard = cp_gtk_clipboard;
298 else
299 gtk_clipboard = cp_gtk_selection;
301 #if GTK_MINOR_VERSION > 4
302 gdk_threads_enter ();
303 gtk_clipboard_request_image (gtk_clipboard,
304 clipboard_image_received,
305 (gpointer) selection_obj);
306 gdk_threads_leave ();
307 #else
308 clipboard_image_received (gtk_clipboard, NULL, (gpointer) selection_obj);
309 #endif
312 static jmethodID urisAvailableID;
314 static void
315 clipboard_uris_received (GtkClipboard *clipboard
316 __attribute__((unused)),
317 GtkSelectionData *uri_data,
318 gpointer selection)
320 gchar **uris = NULL;
321 jobjectArray strings = NULL;
322 jobject selection_obj = (jobject) selection;
323 JNIEnv *env = cp_gtk_gdk_env ();
325 #if GTK_MINOR_VERSION > 4
326 if (uri_data != NULL)
327 uris = gtk_selection_data_get_uris (uri_data);
328 #else
329 if (uri_data != NULL)
330 uris = NULL;
331 #endif
333 if (uris != NULL)
335 int len, i;
336 gchar **count = uris;
337 jclass stringClass = (*env)->FindClass (env, "java/lang/String");
339 len = 0;
340 while (count[len])
341 len++;
343 strings = (*env)->NewObjectArray (env, len, stringClass, NULL);
344 if (strings != NULL)
346 for (i = 0; i < len; i++)
348 jstring string = (*env)->NewStringUTF (env, uris[i]);
349 if (string == NULL)
350 break;
351 (*env)->SetObjectArrayElement (env, strings, i, string);
352 (*env)->DeleteLocalRef (env, string);
355 g_strfreev (uris);
358 (*env)->CallVoidMethod (env, selection_obj,
359 urisAvailableID,
360 strings);
361 (*env)->DeleteGlobalRef (env, selection_obj);
364 JNIEXPORT void JNICALL
365 Java_gnu_java_awt_peer_gtk_GtkSelection_requestURIs (JNIEnv *env,
366 jobject obj,
367 jboolean clipboard)
369 #if GTK_MINOR_VERSION > 4
370 GdkAtom uri_atom;
371 #endif
372 jobject selection_obj;
373 GtkClipboard *gtk_clipboard;
374 selection_obj = (*env)->NewGlobalRef(env, obj);
375 if (selection_obj == NULL)
376 return;
378 if (urisAvailableID == NULL)
380 jclass gtk_selection_class;
381 gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
382 urisAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
383 "urisAvailable",
384 "([Ljava/lang/String;)V");
385 if (urisAvailableID == NULL)
386 return;
389 if (clipboard)
390 gtk_clipboard = cp_gtk_clipboard;
391 else
392 gtk_clipboard = cp_gtk_selection;
394 #if GTK_MINOR_VERSION > 4
395 /* There is no real request_uris so we have to make one ourselves. */
396 gdk_threads_enter ();
397 uri_atom = gdk_atom_intern ("text/uri-list", FALSE);
398 gtk_clipboard_request_contents (gtk_clipboard,
399 uri_atom,
400 clipboard_uris_received,
401 (gpointer) selection_obj);
402 gdk_threads_leave ();
403 #else
404 clipboard_uris_received (gtk_clipboard, NULL, (gpointer) selection_obj);
405 #endif
408 static jmethodID bytesAvailableID;
410 static void
411 clipboard_bytes_received (GtkClipboard *clipboard
412 __attribute__((unused)),
413 GtkSelectionData *selection_data,
414 gpointer selection)
416 jbyteArray bytes = NULL;
417 jobject selection_obj = (jobject) selection;
418 JNIEnv *env = cp_gtk_gdk_env ();
420 if (selection_data != NULL && selection_data->length > 0)
422 bytes = (*env)->NewByteArray (env, selection_data->length);
423 if (bytes != NULL)
424 (*env)->SetByteArrayRegion(env, bytes, 0, selection_data->length,
425 (jbyte *) selection_data->data);
428 (*env)->CallVoidMethod (env, selection_obj,
429 bytesAvailableID,
430 bytes);
431 (*env)->DeleteGlobalRef (env, selection_obj);
434 JNIEXPORT void JNICALL
435 Java_gnu_java_awt_peer_gtk_GtkSelection_requestBytes (JNIEnv *env,
436 jobject obj,
437 jboolean clipboard,
438 jstring target_string)
440 int len;
441 const gchar *target_text;
442 GdkAtom target_atom;
443 jobject selection_obj;
444 GtkClipboard *gtk_clipboard;
445 selection_obj = (*env)->NewGlobalRef(env, obj);
446 if (selection_obj == NULL)
447 return;
449 if (bytesAvailableID == NULL)
451 jclass gtk_selection_class;
452 gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
453 bytesAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
454 "bytesAvailable",
455 "([B)V");
456 if (bytesAvailableID == NULL)
457 return;
460 len = (*env)->GetStringUTFLength (env, target_string);
461 if (len == -1)
462 return;
463 target_text = (*env)->GetStringUTFChars (env, target_string, NULL);
464 if (target_text == NULL)
465 return;
467 if (clipboard)
468 gtk_clipboard = cp_gtk_clipboard;
469 else
470 gtk_clipboard = cp_gtk_selection;
472 gdk_threads_enter ();
473 target_atom = gdk_atom_intern (target_text, FALSE);
474 gtk_clipboard_request_contents (gtk_clipboard,
475 target_atom,
476 clipboard_bytes_received,
477 (gpointer) selection_obj);
478 gdk_threads_leave ();
480 (*env)->ReleaseStringUTFChars (env, target_string, target_text);