/[classpath]/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
ViewVC logotype

Diff of /classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by fitzsim, Thu Jul 14 22:07:02 2005 UTC revision 1.13 by mark, Tue Aug 16 18:16:27 2005 UTC
# Line 1  Line 1 
1  /* gtkclipboard.c  /* gtkclipboard.c
2     Copyright (C) 1998, 1999 Free Software Foundation, Inc.     Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 36  obligated to do so.  If you do not wish Line 36  obligated to do so.  If you do not wish
36  exception statement from your version. */  exception statement from your version. */
37    
38    
39    #include "jcl.h"
40  #include "gtkpeer.h"  #include "gtkpeer.h"
41  #include "gnu_java_awt_peer_gtk_GtkClipboard.h"  #include "gnu_java_awt_peer_gtk_GtkClipboard.h"
42    #include "gnu_java_awt_peer_gtk_GtkSelection.h"
43    
44  static jmethodID stringSelectionReceivedID;  #define OBJECT_TARGET 1
45  static jmethodID stringSelectionHandlerID;  #define TEXT_TARGET   2
46  static jmethodID selectionClearID;  #define IMAGE_TARGET  3
47    #define URI_TARGET    4
 static void selection_received_cb (GtkWidget *, GtkSelectionData *,  
                                    guint, gpointer);  
 static void selection_get_cb (GtkWidget *, GtkSelectionData *, guint,  
                               guint, gpointer);  
 static gint selection_clear_cb (GtkWidget *, GdkEventSelection *);  
48    
49  static GtkWidget *clipboard;  static GtkClipboard *clipboard;
 static jobject cb_obj;  
50    
51  JNIEXPORT void JNICALL  /* Simple id to keep track of the selection we are currently managing. */
52  Java_gnu_java_awt_peer_gtk_GtkClipboard_initNativeState (JNIEnv *env,  static int current_selection = 0;
53                                                           jobject obj)  
54    /* Whether we "own" the clipboard. And may clear it. */
55    static int owner = 0;
56    
57    static jclass gtk_clipboard_class;
58    static jmethodID setSystemContentsID;
59    
60    static jobject gtk_clipboard_instance = NULL;
61    static jmethodID provideContentID;
62    static jmethodID provideTextID;
63    static jmethodID provideImageID;
64    static jmethodID provideURIsID;
65    
66    static jstring stringTarget;
67    static jstring imageTarget;
68    static jstring filesTarget;
69    
70    static void
71    cp_gtk_clipboard_owner_change (GtkClipboard *clipboard __attribute__((unused)),
72                                   GdkEvent *event __attribute__((unused)),
73                                   gpointer user_data __attribute__((unused)))
74  {  {
75      /* These are only interesting when we are not the owner. Otherwise
76         we will have the set and clear functions doing the updating. */
77      JNIEnv *env = cp_gtk_gdk_env ();
78      if (!owner)
79        (*env)->CallStaticVoidMethod (env, gtk_clipboard_class,
80                                      setSystemContentsID);
81    }
82    
83    JNIEXPORT jboolean JNICALL
84    Java_gnu_java_awt_peer_gtk_GtkClipboard_initNativeState (JNIEnv *env,
85                                                             jclass gtkclipboard,
86                                                             jstring string,
87                                                             jstring image,
88                                                             jstring files)
89    {
90      GdkDisplay* display;
91      jboolean can_cache;
92    
93      gtk_clipboard_class = gtkclipboard;
94      setSystemContentsID = (*env)->GetStaticMethodID (env, gtk_clipboard_class,
95                                                       "setSystemContents",
96                                                       "()V");
97      if (setSystemContentsID == NULL)
98        return JNI_FALSE;
99    
100      stringTarget = (*env)->NewGlobalRef(env, string);
101      imageTarget = (*env)->NewGlobalRef(env, image);
102      filesTarget = (*env)->NewGlobalRef(env, files);
103    
104    gdk_threads_enter ();    gdk_threads_enter ();
105      clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
106    
107    if (!stringSelectionReceivedID)    display = gtk_clipboard_get_display (clipboard);
108      if (gdk_display_supports_selection_notification (display))
109      {      {
110        jclass gtkclipboard;        g_signal_connect (clipboard, "owner-change",
111                            G_CALLBACK (cp_gtk_clipboard_owner_change), NULL);
112        gtkclipboard = (*env)->FindClass (env,        gdk_display_request_selection_notification (display,
113                                          "gnu/java/awt/peer/gtk/GtkClipboard");                                                    GDK_SELECTION_CLIPBOARD);
114        stringSelectionReceivedID = (*env)->GetMethodID (env, gtkclipboard,        can_cache = JNI_TRUE;
                                                     "stringSelectionReceived",  
                                                     "(Ljava/lang/String;)V");  
       stringSelectionHandlerID = (*env)->GetMethodID (env, gtkclipboard,  
                                                       "stringSelectionHandler",  
                                                       "()Ljava/lang/String;");  
       selectionClearID = (*env)->GetMethodID (env, gtkclipboard,  
                                               "selectionClear", "()V");  
115      }      }
116      else
117        can_cache = JNI_FALSE;
118      gdk_threads_leave ();
119    
120    cb_obj = (*env)->NewGlobalRef (env, obj);    return can_cache;
121    }
   clipboard = gtk_window_new (GTK_WINDOW_TOPLEVEL);  
122    
123    g_signal_connect (G_OBJECT(clipboard), "selection_received",  static void
124                      G_CALLBACK (selection_received_cb), NULL);  cp_gtk_clipboard_get_func (GtkClipboard *clipboard __attribute__((unused)),
125                               GtkSelectionData *selection,
126                               guint info,
127                               gpointer user_data __attribute__((unused)))
128    {
129      JNIEnv *env = cp_gtk_gdk_env ();
130      
131      if (info == OBJECT_TARGET)
132        {
133          const gchar *target_name;
134          jstring target_string;
135          jbyteArray bytes;
136          jint len;
137          jbyte *barray;
138    
139          target_name = gdk_atom_name (selection->target);
140          if (target_name == NULL)
141            return;
142          target_string = (*env)->NewStringUTF (env, target_name);
143          if (target_string == NULL)
144            return;
145          bytes = (*env)->CallObjectMethod(env,
146                                           gtk_clipboard_instance,
147                                           provideContentID,
148                                           target_string);
149          if (bytes == NULL)
150            return;
151          len = (*env)->GetArrayLength(env, bytes);
152          if (len <= 0)
153            return;
154          barray = (*env)->GetByteArrayElements(env, bytes, NULL);
155          if (barray == NULL)
156            return;
157          gtk_selection_data_set (selection, selection->target, 8,
158                                  (guchar *) barray, len);
159    
160    g_signal_connect (G_OBJECT(clipboard), "selection_clear_event",        (*env)->ReleaseByteArrayElements(env, bytes, barray, 0);
                     G_CALLBACK (selection_clear_cb), NULL);  
161    
162    gtk_selection_add_target (clipboard, GDK_SELECTION_PRIMARY,      }
163                              GDK_TARGET_STRING, 0);    else if (info == TEXT_TARGET)
164        {
165          jstring string;
166          const gchar *text;
167          int len;
168          string = (*env)->CallObjectMethod(env,
169                                            gtk_clipboard_instance,
170                                            provideTextID);
171          if (string == NULL)
172            return;
173          len = (*env)->GetStringUTFLength (env, string);
174          if (len == -1)
175            return;
176          text = (*env)->GetStringUTFChars (env, string, NULL);
177          if (text == NULL)
178            return;
179    
180    g_signal_connect (G_OBJECT(clipboard), "selection_get",        gtk_selection_data_set_text (selection, text, len);
181                      G_CALLBACK (selection_get_cb), NULL);        (*env)->ReleaseStringUTFChars (env, string, text);
182        }
183      else if (info == IMAGE_TARGET)
184        {
185          jobject gtkimage;
186          GdkPixbuf *pixbuf = NULL;
187          
188          gtkimage = (*env)->CallObjectMethod(env,
189                                              gtk_clipboard_instance,
190                                              provideImageID);
191          if (gtkimage == NULL)
192            return;
193          
194          pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage);
195          if (pixbuf != NULL)
196            {
197              gtk_selection_data_set_pixbuf (selection, pixbuf);
198    
199              /* if the GtkImage is offscreen, this is a temporary pixbuf
200                 which should be thrown out. */
201              if(cp_gtk_image_is_offscreen (env, gtkimage) == JNI_TRUE)
202                gdk_pixbuf_unref (pixbuf);
203            }
204        }
205      else if (info == URI_TARGET)
206        {
207          jobjectArray uris;
208          jint count;
209          int i;
210          gchar **list;
211    
212          uris = (*env)->CallObjectMethod(env,
213                                          gtk_clipboard_instance,
214                                          provideURIsID);
215          if (uris == NULL)
216            return;
217          count = (*env)->GetArrayLength (env, uris);
218          if (count <= 0)
219            return;
220    
221          list = (gchar **) JCL_malloc (env, (count + 1) * sizeof (gchar *));
222          for (i = 0; i < count; i++)
223            {
224              const char *text;
225              jstring uri;
226              
227              /* Mark NULL in so case of some error we can find the end. */
228              list[i] = NULL;
229              uri = (*env)->GetObjectArrayElement (env, uris, i);
230              if (uri == NULL)
231                break;
232              text = (*env)->GetStringUTFChars (env, uri, NULL);
233              if (text == NULL)
234                break;
235              list[i] = strdup (text);
236              (*env)->ReleaseStringUTFChars (env, uri, text);
237            }
238    
239          if (i == count)
240            {
241              list[count] = NULL;
242              gtk_selection_data_set_uris (selection, list);
243            }
244    
245          for (i = 0; list[i] != NULL; i++)
246            free (list[i]);
247          JCL_free (env, list);
248        }
249    }
250    
251    gdk_threads_leave ();  static void
252    cp_gtk_clipboard_clear_func (GtkClipboard *clipboard __attribute__((unused)),
253                                 gpointer user_data)
254    {
255      if (owner && (int) user_data == current_selection)
256        {
257          JNIEnv *env = cp_gtk_gdk_env();
258          owner = 0;
259          (*env)->CallStaticVoidMethod (env, gtk_clipboard_class,
260                                        setSystemContentsID);
261        }
262  }  }
263    
264  JNIEXPORT void JNICALL  JNIEXPORT void JNICALL
265  Java_gnu_java_awt_peer_gtk_GtkClipboard_requestStringConversion  Java_gnu_java_awt_peer_gtk_GtkClipboard_advertiseContent
266    (JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused)))  (JNIEnv *env,
267     jobject instance,
268     jobjectArray mime_array,
269     jboolean add_text,
270     jboolean add_images __attribute__((unused)),
271     jboolean add_uris __attribute__((unused)))
272  {  {
273      GtkTargetList *target_list;
274      GList *list;
275      GtkTargetEntry *targets;
276      gint n, i;
277    
278    gdk_threads_enter ();    gdk_threads_enter ();
279      target_list = gtk_target_list_new (NULL, 0);
280    
281      if (mime_array != NULL)
282        {
283          n = (*env)->GetArrayLength (env, mime_array);
284          for (i = 0; i < n; i++)
285            {
286              const char *text;
287              jstring target;
288              GdkAtom atom;
289    
290              target = (*env)->GetObjectArrayElement (env, mime_array, i);
291              if (target == NULL)
292                break;
293              text = (*env)->GetStringUTFChars (env, target, NULL);
294              if (text == NULL)
295                break;
296    
297    gtk_selection_convert (clipboard, GDK_SELECTION_PRIMARY,            atom = gdk_atom_intern (text, FALSE);
298                           GDK_TARGET_STRING, GDK_CURRENT_TIME);            gtk_target_list_add (target_list, atom, 0, OBJECT_TARGET);
299    
300              (*env)->ReleaseStringUTFChars (env, target, text);
301            }
302        }
303    
304      /* Add extra targets that gtk+ can provide/translate for us. */
305      if (add_text)
306        gtk_target_list_add_text_targets (target_list, TEXT_TARGET);
307      if (add_images)
308        gtk_target_list_add_image_targets (target_list, IMAGE_TARGET, TRUE);
309      if (add_uris)
310        gtk_target_list_add_uri_targets (target_list, URI_TARGET);
311    
312      /* Turn list into a target table. */
313      n = g_list_length (target_list->list);
314      if (n > 0)
315        {
316          targets = g_new (GtkTargetEntry, n);
317          for (list = target_list->list, i = 0;
318               list != NULL;
319               list = list->next, i++)
320            {
321              GtkTargetPair *pair = (GtkTargetPair *) list->data;
322              targets[i].target = gdk_atom_name (pair->target);
323              targets[i].flags = pair->flags;
324              targets[i].info = pair->info;
325            }
326    
327          /* Set the targets plus callback functions and ask for the clipboard
328             to be stored when the application exists. */
329          current_selection++;
330          if (gtk_clipboard_set_with_data (clipboard, targets, n,
331                                           cp_gtk_clipboard_get_func,
332                                           cp_gtk_clipboard_clear_func,
333                                           (gpointer) current_selection))
334            {
335              owner = 1;
336              if (gtk_clipboard_instance == NULL)
337                {
338                  JNIEnv *env = cp_gtk_gdk_env ();
339                  gtk_clipboard_instance =  (*env)->NewGlobalRef(env, instance);
340    
341                  provideContentID
342                    = (*env)->GetMethodID (env, gtk_clipboard_class,
343                                           "provideContent",
344                                           "(Ljava/lang/String;)[B");
345                  if (provideContentID == NULL)
346                    return;
347    
348                  provideTextID
349                    = (*env)->GetMethodID (env, gtk_clipboard_class,
350                                           "provideText", "()Ljava/lang/String;");
351                  if (provideTextID == NULL)
352                    return;
353    
354                  provideImageID
355                    = (*env)->GetMethodID (env, gtk_clipboard_class,
356                                           "provideImage",
357                                           "()Lgnu/java/awt/peer/gtk/GtkImage;");
358                  if (provideImageID == NULL)
359                    return;
360    
361                  provideURIsID
362                    = (*env)->GetMethodID (env, gtk_clipboard_class,
363                                           "provideURIs",
364                                           "()[Ljava/lang/String;");
365                  if (provideURIsID == NULL)
366                    return;
367                }
368              gtk_clipboard_set_can_store (clipboard, NULL, 0);
369            }
370          else
371            {
372              owner = 0;
373              (*env)->CallStaticVoidMethod (env, gtk_clipboard_class,
374                                            setSystemContentsID);
375            }
376    
377          for (i = 0; i < n; i++)
378            g_free (targets[i].target);
379          g_free (targets);
380        }
381      else if (owner)
382        {
383          gtk_clipboard_clear (clipboard);
384          owner = 0;
385        }
386    
387      gtk_target_list_unref (target_list);
388    gdk_threads_leave ();    gdk_threads_leave ();
389  }  }
390    
391    
392    /* GtkSelection native methods. Put here for convenience since they
393       need access to the current clipboard. */
394    
395    static jmethodID mimeTypesAvailableID;
396    
397    /* Note this is actually just a GtkClipboardReceivedFunc, not a real
398       GtkClipboardTargetsReceivedFunc, see requestMimeTypes. */
399  static void  static void
400  selection_received_cb (GtkWidget *widget __attribute__((unused)),  cp_gtk_clipboard_targets_received (GtkClipboard *clipboard
401                         GtkSelectionData *selection_data __attribute__((unused)),                                     __attribute__((unused)),
402                         guint time __attribute__((unused)),                                     GtkSelectionData *target_data,
403                         gpointer data __attribute__((unused)))                                     gpointer selection)
404  {  {
405    /* Check to see if retrieval succeeded  */    GdkAtom *targets = NULL;
406    if (selection_data->length < 0    gint targets_len = 0;
407        || selection_data->type != GDK_SELECTION_TYPE_STRING)    gchar **target_strings = NULL;
408      jobjectArray strings = NULL;
409      int strings_len = 0;
410      gboolean include_text = FALSE;
411      gboolean include_image = FALSE;
412      gboolean include_uris = FALSE;
413      jobject selection_obj = (jobject) selection;
414      JNIEnv *env = cp_gtk_gdk_env ();
415    
416      if (target_data != NULL && target_data->length > 0)
417      {      {
418        gdk_threads_leave ();        include_text = gtk_selection_data_targets_include_text (target_data);
419          include_image = gtk_selection_data_targets_include_image (target_data,
420                                                                    TRUE);
421          if (gtk_selection_data_get_targets (target_data, &targets, &targets_len))
422            {
423              int i;
424              GdkAtom uri_list_atom = gdk_atom_intern ("text/uri-list", FALSE);
425              target_strings = g_new (gchar*, targets_len);
426              if (target_strings != NULL)
427                for (i = 0; i < targets_len; i++)
428                  {
429                    gchar *name =  gdk_atom_name (targets[i]);
430                    if (strchr (name, '/') != NULL)
431                      {
432                        target_strings[i] = name;
433                        strings_len++;
434                        if (! include_uris && targets[i] == uri_list_atom)
435                          include_uris = TRUE;
436                      }
437                    else
438                      target_strings[i] = NULL;
439                  }
440            }
441    
442          if (target_strings != NULL)
443            {
444              int i = 0, j = 0;
445              jclass stringClass;
446              
447              if (include_text)
448                strings_len++;
449              if (include_image)
450                strings_len++;
451              if (include_uris)
452                strings_len++;
453              
454              stringClass = (*env)->FindClass (env, "java/lang/String");
455              strings = (*env)->NewObjectArray (env, strings_len, stringClass,
456                                                NULL);
457              if (strings != NULL)
458                {
459                  if (include_text)
460                    (*env)->SetObjectArrayElement (env, strings, i++,
461                                                   stringTarget);
462                  if (include_image)
463                    (*env)->SetObjectArrayElement (env, strings, i++,
464                                                   imageTarget);
465                  if (include_uris)
466                    (*env)->SetObjectArrayElement (env, strings, i++,
467                                                   filesTarget);
468                  
469                  while(i < strings_len)
470                    {
471                      if (target_strings[j] == NULL)
472                        j++;
473                      else
474                        {
475                          jstring string;
476                          string = (*env)->NewStringUTF (env,
477                                                         target_strings[j++]);
478                          if (string == NULL)
479                            break;
480                          (*env)->SetObjectArrayElement (env, strings, i++,
481                                                         string);
482                        }
483                    }
484                }
485    
486              for (i = 0; i < targets_len; i++)
487                g_free (target_strings[i]);
488              g_free (target_strings);
489            }
490        }
491    
492      (*env)->CallVoidMethod (env, selection_obj,
493                              mimeTypesAvailableID,
494                              strings);
495      (*env)->DeleteGlobalRef (env, selection_obj);
496    }
497    
498        (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), cb_obj, stringSelectionReceivedID,  JNIEXPORT void JNICALL
499                                      NULL);  Java_gnu_java_awt_peer_gtk_GtkSelection_requestMimeTypes
500    (JNIEnv *env, jobject selection)
501    {
502      jobject selection_obj;
503      selection_obj = (*env)->NewGlobalRef(env, selection);
504      if (selection_obj == NULL)
505        return;
506    
507        gdk_threads_enter ();    if (mimeTypesAvailableID == NULL)
508        {
509          jclass gtk_selection_class;
510          gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
511          mimeTypesAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
512                                                    "mimeTypesAvailable",
513                                                    "([Ljava/lang/String;)V");
514          if (mimeTypesAvailableID == NULL)
515            return;
516      }      }
517    
518      /* We would have liked to call gtk_clipboard_request_targets ()
519         since that is more general. But the result of that, an array of
520         GdkAtoms, cannot be used with the
521         gtk_selection_data_targets_include_<x> functions (despite what
522         the name suggests). */
523      gdk_threads_enter ();
524      gtk_clipboard_request_contents (clipboard,
525                                      gdk_atom_intern ("TARGETS", FALSE),
526                                      cp_gtk_clipboard_targets_received,
527                                      (gpointer) selection_obj);
528      gdk_threads_leave ();
529    }
530    
531    
532    static jmethodID textAvailableID;
533    
534    static void
535    cp_gtk_clipboard_text_received (GtkClipboard *clipboard
536                                    __attribute__((unused)),
537                                    const gchar *text,
538                                    gpointer selection)
539    {
540      jstring string;
541      jobject selection_obj = (jobject) selection;
542    
543      JNIEnv *env = cp_gtk_gdk_env ();
544      if (text != NULL)
545        string = (*env)->NewStringUTF (env, text);
546    else    else
547      {      string = NULL;
       char *str = (char *) selection_data->data;  
         
       gdk_threads_leave ();  
548    
549        (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), cb_obj, stringSelectionReceivedID,    (*env)->CallVoidMethod (env, selection_obj,
550                                      (*cp_gtk_gdk_env())->NewStringUTF (cp_gtk_gdk_env(), str));                            textAvailableID,
551                              string);
552      (*env)->DeleteGlobalRef (env, selection_obj);
553    }
554    
555        gdk_threads_enter ();  JNIEXPORT void JNICALL
556    Java_gnu_java_awt_peer_gtk_GtkSelection_requestText
557    (JNIEnv *env, jobject selection)
558    {
559      jobject selection_obj;
560      selection_obj = (*env)->NewGlobalRef(env, selection);
561      if (selection_obj == NULL)
562        return;
563    
564      if (textAvailableID == NULL)
565        {
566          jclass gtk_selection_class;
567          gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
568          textAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
569                                                 "textAvailable",
570                                                 "(Ljava/lang/String;)V");
571          if (textAvailableID == NULL)
572            return;
573      }      }
574    
575    return;    gdk_threads_enter ();
576      gtk_clipboard_request_text (clipboard,
577                                  cp_gtk_clipboard_text_received,
578                                  (gpointer) selection_obj);
579      gdk_threads_leave ();
580  }  }
581    
582    static jmethodID imageAvailableID;
583    
584  static void  static void
585  selection_get_cb (GtkWidget *widget __attribute__((unused)),  cp_gtk_clipboard_image_received (GtkClipboard *clipboard
586                    GtkSelectionData *selection_data,                                   __attribute__((unused)),
587                    guint      info __attribute__((unused)),                                   GdkPixbuf *pixbuf,
588                    guint      time __attribute__((unused)),                                   gpointer selection)
                   gpointer   data __attribute__((unused)))  
589  {  {
590    jstring jstr;    jobject pointer = NULL;
591    const char *utf;    jobject selection_obj = (jobject) selection;
592    jsize utflen;    JNIEnv *env = cp_gtk_gdk_env ();
593    
594    gdk_threads_leave ();    if (pixbuf != NULL)
595        {
596          g_object_ref (pixbuf);
597          pointer = JCL_NewRawDataObject (env, (void *) pixbuf);
598        }
599    
600    jstr = (*cp_gtk_gdk_env())->CallObjectMethod (cp_gtk_gdk_env(), cb_obj,    (*env)->CallVoidMethod (env, selection_obj,
601                                         stringSelectionHandlerID);                            imageAvailableID,
602                              pointer);
603      (*env)->DeleteGlobalRef (env, selection_obj);
604    }
605    
606    gdk_threads_enter ();  JNIEXPORT void JNICALL
607    Java_gnu_java_awt_peer_gtk_GtkSelection_requestImage (JNIEnv *env, jobject obj)
608    {
609      jobject selection_obj;
610      selection_obj = (*env)->NewGlobalRef(env, obj);
611      if (selection_obj == NULL)
612        return;
613    
614    if (!jstr)    if (imageAvailableID == NULL)
615      {      {
616        gtk_selection_data_set (selection_data,        jclass gtk_selection_class;
617                                GDK_TARGET_STRING, 8, NULL, 0);        gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
618        return;        imageAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
619                                                 "imageAvailable",
620                                                 "(Lgnu/classpath/Pointer;)V");
621          if (imageAvailableID == NULL)
622            return;
623      }      }
624    
625    utflen = (*cp_gtk_gdk_env())->GetStringUTFLength (cp_gtk_gdk_env(), jstr);    gdk_threads_enter ();
626    utf = (*cp_gtk_gdk_env())->GetStringUTFChars (cp_gtk_gdk_env(), jstr, NULL);    gtk_clipboard_request_image (clipboard,
627                                   cp_gtk_clipboard_image_received,
628                                   (gpointer) selection_obj);
629      gdk_threads_leave ();
630    }
631    
632    gtk_selection_data_set (selection_data, GDK_TARGET_STRING, 8,  static jmethodID urisAvailableID;
633                            (const unsigned char*)utf, utflen);  
634    static void
635    cp_gtk_clipboard_uris_received (GtkClipboard *clipboard
636                                    __attribute__((unused)),
637                                    GtkSelectionData *uri_data,
638                                    gpointer selection)
639    {
640      gchar **uris = NULL;
641      jobjectArray strings = NULL;
642      jobject selection_obj = (jobject) selection;
643      JNIEnv *env = cp_gtk_gdk_env ();
644    
645      if (uri_data != NULL)
646        uris = gtk_selection_data_get_uris (uri_data);
647      
648      if (uris != NULL)
649        {
650          int len, i;
651          gchar **count = uris;
652          jclass stringClass = (*env)->FindClass (env, "java/lang/String");
653    
654          len = 0;
655          while (count[len])
656            len++;
657    
658          strings = (*env)->NewObjectArray (env, len, stringClass, NULL);
659          if (strings != NULL)
660            {
661              for (i = 0; i < len; i++)
662                {
663                  jstring string = (*env)->NewStringUTF (env, uris[i]);
664                  if (string == NULL)
665                    break;
666                  (*env)->SetObjectArrayElement (env, strings, i, string);
667                }
668            }
669          g_strfreev (uris);
670        }
671    
672    (*cp_gtk_gdk_env())->ReleaseStringUTFChars (cp_gtk_gdk_env(), jstr, utf);    (*env)->CallVoidMethod (env, selection_obj,
673                              urisAvailableID,
674                              strings);
675      (*env)->DeleteGlobalRef (env, selection_obj);
676  }  }
677    
678  JNIEXPORT void JNICALL  JNIEXPORT void JNICALL
679  Java_gnu_java_awt_peer_gtk_GtkClipboard_selectionGet  Java_gnu_java_awt_peer_gtk_GtkSelection_requestURIs (JNIEnv *env, jobject obj)
   (JNIEnv *env, jclass clazz __attribute__((unused)))  
680  {  {
681    GdkWindow *owner;    GdkAtom uri_atom;
682      jobject selection_obj;
683      selection_obj = (*env)->NewGlobalRef(env, obj);
684      if (selection_obj == NULL)
685        return;
686    
687      if (urisAvailableID == NULL)
688        {
689          jclass gtk_selection_class;
690          gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
691          urisAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
692                                                 "urisAvailable",
693                                                 "([Ljava/lang/String;)V");
694          if (urisAvailableID == NULL)
695            return;
696        }
697    
698      /* There is no real request_uris so we have to make one ourselves. */
699    gdk_threads_enter ();    gdk_threads_enter ();
700      uri_atom = gdk_atom_intern ("text/uri-list", FALSE);
701      gtk_clipboard_request_contents (clipboard,
702                                      uri_atom,
703                                      cp_gtk_clipboard_uris_received,
704                                      (gpointer) selection_obj);
705      gdk_threads_leave ();
706    }
707    
708    /* if we already own the clipboard, we need to tell the old data object  static jmethodID bytesAvailableID;
      that we're no longer going to be using him */  
   owner = gdk_selection_owner_get (GDK_SELECTION_PRIMARY);  
   if (owner && owner == clipboard->window)  
     (*env)->CallVoidMethod (env, cb_obj, selectionClearID);  
       
   gtk_selection_owner_set (clipboard, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);  
709    
710    gdk_threads_leave ();  static void
711    cp_gtk_clipboard_bytes_received (GtkClipboard *clipboard
712                                     __attribute__((unused)),
713                                     GtkSelectionData *selection_data,
714                                     gpointer selection)
715    {
716      jbyteArray bytes = NULL;
717      jobject selection_obj = (jobject) selection;
718      JNIEnv *env = cp_gtk_gdk_env ();
719    
720       if (selection_data != NULL && selection_data->length > 0)
721        {
722          bytes = (*env)->NewByteArray (env, selection_data->length);
723          if (bytes != NULL)
724            (*env)->SetByteArrayRegion(env, bytes, 0, selection_data->length,
725                                       (jbyte *) selection_data->data);
726        }
727    
728      (*env)->CallVoidMethod (env, selection_obj,
729                              bytesAvailableID,
730                              bytes);
731      (*env)->DeleteGlobalRef (env, selection_obj);
732  }  }
733    
734  static gint  JNIEXPORT void JNICALL
735  selection_clear_cb (GtkWidget *widget __attribute__((unused)),  Java_gnu_java_awt_peer_gtk_GtkSelection_requestBytes (JNIEnv *env,
736                      GdkEventSelection *event __attribute__((unused)))                                                        jobject obj,
737                                                          jstring target_string)
738  {  {
739    gdk_threads_leave ();    int len;
740      const gchar *target_text;
741      GdkAtom target_atom;
742      jobject selection_obj;
743      selection_obj = (*env)->NewGlobalRef(env, obj);
744      if (selection_obj == NULL)
745        return;
746    
747      if (bytesAvailableID == NULL)
748        {
749          jclass gtk_selection_class;
750          gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);
751          bytesAvailableID = (*env)->GetMethodID (env, gtk_selection_class,
752                                                  "bytesAvailable",
753                                                  "([B)V");
754          if (bytesAvailableID == NULL)
755            return;
756        }
757    
758    (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), cb_obj, selectionClearID);    len = (*env)->GetStringUTFLength (env, target_string);
759      if (len == -1)
760        return;
761      target_text = (*env)->GetStringUTFChars (env, target_string, NULL);
762      if (target_text == NULL)
763        return;
764    
765    gdk_threads_enter ();    gdk_threads_enter ();
766      target_atom = gdk_atom_intern (target_text, FALSE);
767      gtk_clipboard_request_contents (clipboard,
768                                      target_atom,
769                                      cp_gtk_clipboard_bytes_received,
770                                      (gpointer) selection_obj);
771      gdk_threads_leave ();
772    
773    return TRUE;    (*env)->ReleaseStringUTFChars (env, target_string, target_text);
774  }  }

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26