/[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.14 by fitzsim, Thu Aug 18 01:22:00 2005 UTC revision 1.15 by mark, Mon Aug 22 10:36:14 2005 UTC
# Line 39  exception statement from your version. * Line 39  exception statement from your version. *
39  #include "jcl.h"  #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"
 #include "gnu_java_awt_peer_gtk_GtkSelection.h"  
42    
43  #define OBJECT_TARGET 1  #define OBJECT_TARGET 1
44  #define TEXT_TARGET   2  #define TEXT_TARGET   2
45  #define IMAGE_TARGET  3  #define IMAGE_TARGET  3
46  #define URI_TARGET    4  #define URI_TARGET    4
47    
48  static GtkClipboard *clipboard;  /* The clipboard and standard (string targets) shared with GtkSelection. */
49    GtkClipboard *cp_gtk_clipboard;
50    
51    jstring cp_gtk_stringTarget;
52    jstring cp_gtk_imageTarget;
53    jstring cp_gtk_filesTarget;
54    
55  /* Simple id to keep track of the selection we are currently managing. */  /* Simple id to keep track of the selection we are currently managing. */
56  static int current_selection = 0;  static int current_selection = 0;
# Line 63  static jmethodID provideTextID; Line 67  static jmethodID provideTextID;
67  static jmethodID provideImageID;  static jmethodID provideImageID;
68  static jmethodID provideURIsID;  static jmethodID provideURIsID;
69    
 static jstring stringTarget;  
 static jstring imageTarget;  
 static jstring filesTarget;  
   
70  static void  static void
71  cp_gtk_clipboard_owner_change_cb (GtkClipboard *clipboard __attribute__((unused)),  clipboard_owner_change_cb (GtkClipboard *clipboard __attribute__((unused)),
72                                    GdkEvent *event __attribute__((unused)),                             GdkEvent *event __attribute__((unused)),
73                                    gpointer user_data __attribute__((unused)))                             gpointer user_data __attribute__((unused)))
74  {  {
75    /* These are only interesting when we are not the owner. Otherwise    /* These are only interesting when we are not the owner. Otherwise
76       we will have the set and clear functions doing the updating. */       we will have the set and clear functions doing the updating. */
# Line 97  Java_gnu_java_awt_peer_gtk_GtkClipboard_ Line 97  Java_gnu_java_awt_peer_gtk_GtkClipboard_
97    if (setSystemContentsID == NULL)    if (setSystemContentsID == NULL)
98      return JNI_FALSE;      return JNI_FALSE;
99    
100    stringTarget = (*env)->NewGlobalRef(env, string);    cp_gtk_stringTarget = (*env)->NewGlobalRef(env, string);
101    imageTarget = (*env)->NewGlobalRef(env, image);    cp_gtk_imageTarget = (*env)->NewGlobalRef(env, image);
102    filesTarget = (*env)->NewGlobalRef(env, files);    cp_gtk_filesTarget = (*env)->NewGlobalRef(env, files);
103    
104    gdk_threads_enter ();    gdk_threads_enter ();
105    clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);    cp_gtk_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
106    
107    display = gtk_clipboard_get_display (clipboard);    display = gtk_clipboard_get_display (cp_gtk_clipboard);
108    if (gdk_display_supports_selection_notification (display))    if (gdk_display_supports_selection_notification (display))
109      {      {
110        g_signal_connect (clipboard, "owner-change",        g_signal_connect (cp_gtk_clipboard, "owner-change",
111                          G_CALLBACK (cp_gtk_clipboard_owner_change_cb), NULL);                          G_CALLBACK (clipboard_owner_change_cb), NULL);
112        gdk_display_request_selection_notification (display,        gdk_display_request_selection_notification (display,
113                                                    GDK_SELECTION_CLIPBOARD);                                                    GDK_SELECTION_CLIPBOARD);
114        can_cache = JNI_TRUE;        can_cache = JNI_TRUE;
# Line 121  Java_gnu_java_awt_peer_gtk_GtkClipboard_ Line 121  Java_gnu_java_awt_peer_gtk_GtkClipboard_
121  }  }
122    
123  static void  static void
124  cp_gtk_clipboard_get_func (GtkClipboard *clipboard __attribute__((unused)),  clipboard_get_func (GtkClipboard *clipboard __attribute__((unused)),
125                             GtkSelectionData *selection,                      GtkSelectionData *selection,
126                             guint info,                      guint info,
127                             gpointer user_data __attribute__((unused)))                      gpointer user_data __attribute__((unused)))
128  {  {
129    JNIEnv *env = cp_gtk_gdk_env ();    JNIEnv *env = cp_gtk_gdk_env ();
130        
# Line 249  cp_gtk_clipboard_get_func (GtkClipboard Line 249  cp_gtk_clipboard_get_func (GtkClipboard
249  }  }
250    
251  static void  static void
252  cp_gtk_clipboard_clear_func (GtkClipboard *clipboard __attribute__((unused)),  clipboard_clear_func (GtkClipboard *clipboard __attribute__((unused)),
253                               gpointer user_data)                        gpointer user_data)
254  {  {
255    if (owner && (int) user_data == current_selection)    if (owner && (int) user_data == current_selection)
256      {      {
# Line 327  Java_gnu_java_awt_peer_gtk_GtkClipboard_ Line 327  Java_gnu_java_awt_peer_gtk_GtkClipboard_
327        /* Set the targets plus callback functions and ask for the clipboard        /* Set the targets plus callback functions and ask for the clipboard
328           to be stored when the application exists. */           to be stored when the application exists. */
329        current_selection++;        current_selection++;
330        if (gtk_clipboard_set_with_data (clipboard, targets, n,        if (gtk_clipboard_set_with_data (cp_gtk_clipboard, targets, n,
331                                         cp_gtk_clipboard_get_func,                                         clipboard_get_func,
332                                         cp_gtk_clipboard_clear_func,                                         clipboard_clear_func,
333                                         (gpointer) current_selection))                                         (gpointer) current_selection))
334          {          {
335            owner = 1;            owner = 1;
# Line 365  Java_gnu_java_awt_peer_gtk_GtkClipboard_ Line 365  Java_gnu_java_awt_peer_gtk_GtkClipboard_
365                if (provideURIsID == NULL)                if (provideURIsID == NULL)
366                  return;                  return;
367              }              }
368            gtk_clipboard_set_can_store (clipboard, NULL, 0);            gtk_clipboard_set_can_store (cp_gtk_clipboard, NULL, 0);
369          }          }
370        else        else
371          {          {
# Line 380  Java_gnu_java_awt_peer_gtk_GtkClipboard_ Line 380  Java_gnu_java_awt_peer_gtk_GtkClipboard_
380      }      }
381    else if (owner)    else if (owner)
382      {      {
383        gtk_clipboard_clear (clipboard);        gtk_clipboard_clear (cp_gtk_clipboard);
384        owner = 0;        owner = 0;
385      }      }
386    
387    gtk_target_list_unref (target_list);    gtk_target_list_unref (target_list);
388    gdk_threads_leave ();    gdk_threads_leave ();
389  }  }
   
   
 /* GtkSelection native methods. Put here for convenience since they  
    need access to the current clipboard. */  
   
 static jmethodID mimeTypesAvailableID;  
   
 /* Note this is actually just a GtkClipboardReceivedFunc, not a real  
    GtkClipboardTargetsReceivedFunc, see requestMimeTypes. */  
 static void  
 cp_gtk_clipboard_targets_received (GtkClipboard *clipboard  
                                    __attribute__((unused)),  
                                    GtkSelectionData *target_data,  
                                    gpointer selection)  
 {  
   GdkAtom *targets = NULL;  
   gint targets_len = 0;  
   gchar **target_strings = NULL;  
   jobjectArray strings = NULL;  
   int strings_len = 0;  
   gboolean include_text = FALSE;  
   gboolean include_image = FALSE;  
   gboolean include_uris = FALSE;  
   jobject selection_obj = (jobject) selection;  
   JNIEnv *env = cp_gtk_gdk_env ();  
   
   if (target_data != NULL && target_data->length > 0)  
     {  
       include_text = gtk_selection_data_targets_include_text (target_data);  
       include_image = gtk_selection_data_targets_include_image (target_data,  
                                                                 TRUE);  
       if (gtk_selection_data_get_targets (target_data, &targets, &targets_len))  
         {  
           int i;  
           GdkAtom uri_list_atom = gdk_atom_intern ("text/uri-list", FALSE);  
           target_strings = g_new (gchar*, targets_len);  
           if (target_strings != NULL)  
             for (i = 0; i < targets_len; i++)  
               {  
                 gchar *name =  gdk_atom_name (targets[i]);  
                 if (strchr (name, '/') != NULL)  
                   {  
                     target_strings[i] = name;  
                     strings_len++;  
                     if (! include_uris && targets[i] == uri_list_atom)  
                       include_uris = TRUE;  
                   }  
                 else  
                   target_strings[i] = NULL;  
               }  
         }  
   
       if (target_strings != NULL)  
         {  
           int i = 0, j = 0;  
           jclass stringClass;  
             
           if (include_text)  
             strings_len++;  
           if (include_image)  
             strings_len++;  
           if (include_uris)  
             strings_len++;  
             
           stringClass = (*env)->FindClass (env, "java/lang/String");  
           strings = (*env)->NewObjectArray (env, strings_len, stringClass,  
                                             NULL);  
           if (strings != NULL)  
             {  
               if (include_text)  
                 (*env)->SetObjectArrayElement (env, strings, i++,  
                                                stringTarget);  
               if (include_image)  
                 (*env)->SetObjectArrayElement (env, strings, i++,  
                                                imageTarget);  
               if (include_uris)  
                 (*env)->SetObjectArrayElement (env, strings, i++,  
                                                filesTarget);  
                 
               while(i < strings_len)  
                 {  
                   if (target_strings[j] == NULL)  
                     j++;  
                   else  
                     {  
                       jstring string;  
                       string = (*env)->NewStringUTF (env,  
                                                      target_strings[j++]);  
                       if (string == NULL)  
                         break;  
                       (*env)->SetObjectArrayElement (env, strings, i++,  
                                                      string);  
                     }  
                 }  
             }  
   
           for (i = 0; i < targets_len; i++)  
             g_free (target_strings[i]);  
           g_free (target_strings);  
         }  
     }  
   
   (*env)->CallVoidMethod (env, selection_obj,  
                           mimeTypesAvailableID,  
                           strings);  
   (*env)->DeleteGlobalRef (env, selection_obj);  
 }  
   
 JNIEXPORT void JNICALL  
 Java_gnu_java_awt_peer_gtk_GtkSelection_requestMimeTypes  
 (JNIEnv *env, jobject selection)  
 {  
   jobject selection_obj;  
   selection_obj = (*env)->NewGlobalRef(env, selection);  
   if (selection_obj == NULL)  
     return;  
   
   if (mimeTypesAvailableID == NULL)  
     {  
       jclass gtk_selection_class;  
       gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);  
       mimeTypesAvailableID = (*env)->GetMethodID (env, gtk_selection_class,  
                                                 "mimeTypesAvailable",  
                                                 "([Ljava/lang/String;)V");  
       if (mimeTypesAvailableID == NULL)  
         return;  
     }  
   
   /* We would have liked to call gtk_clipboard_request_targets ()  
      since that is more general. But the result of that, an array of  
      GdkAtoms, cannot be used with the  
      gtk_selection_data_targets_include_<x> functions (despite what  
      the name suggests). */  
   gdk_threads_enter ();  
   gtk_clipboard_request_contents (clipboard,  
                                   gdk_atom_intern ("TARGETS", FALSE),  
                                   cp_gtk_clipboard_targets_received,  
                                   (gpointer) selection_obj);  
   gdk_threads_leave ();  
 }  
   
   
 static jmethodID textAvailableID;  
   
 static void  
 cp_gtk_clipboard_text_received (GtkClipboard *clipboard  
                                 __attribute__((unused)),  
                                 const gchar *text,  
                                 gpointer selection)  
 {  
   jstring string;  
   jobject selection_obj = (jobject) selection;  
   
   JNIEnv *env = cp_gtk_gdk_env ();  
   if (text != NULL)  
     string = (*env)->NewStringUTF (env, text);  
   else  
     string = NULL;  
   
   (*env)->CallVoidMethod (env, selection_obj,  
                           textAvailableID,  
                           string);  
   (*env)->DeleteGlobalRef (env, selection_obj);  
 }  
   
 JNIEXPORT void JNICALL  
 Java_gnu_java_awt_peer_gtk_GtkSelection_requestText  
 (JNIEnv *env, jobject selection)  
 {  
   jobject selection_obj;  
   selection_obj = (*env)->NewGlobalRef(env, selection);  
   if (selection_obj == NULL)  
     return;  
   
   if (textAvailableID == NULL)  
     {  
       jclass gtk_selection_class;  
       gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);  
       textAvailableID = (*env)->GetMethodID (env, gtk_selection_class,  
                                              "textAvailable",  
                                              "(Ljava/lang/String;)V");  
       if (textAvailableID == NULL)  
         return;  
     }  
   
   gdk_threads_enter ();  
   gtk_clipboard_request_text (clipboard,  
                               cp_gtk_clipboard_text_received,  
                               (gpointer) selection_obj);  
   gdk_threads_leave ();  
 }  
   
 static jmethodID imageAvailableID;  
   
 static void  
 cp_gtk_clipboard_image_received (GtkClipboard *clipboard  
                                  __attribute__((unused)),  
                                  GdkPixbuf *pixbuf,  
                                  gpointer selection)  
 {  
   jobject pointer = NULL;  
   jobject selection_obj = (jobject) selection;  
   JNIEnv *env = cp_gtk_gdk_env ();  
   
   if (pixbuf != NULL)  
     {  
       g_object_ref (pixbuf);  
       pointer = JCL_NewRawDataObject (env, (void *) pixbuf);  
     }  
   
   (*env)->CallVoidMethod (env, selection_obj,  
                           imageAvailableID,  
                           pointer);  
   (*env)->DeleteGlobalRef (env, selection_obj);  
 }  
   
 JNIEXPORT void JNICALL  
 Java_gnu_java_awt_peer_gtk_GtkSelection_requestImage (JNIEnv *env, jobject obj)  
 {  
   jobject selection_obj;  
   selection_obj = (*env)->NewGlobalRef(env, obj);  
   if (selection_obj == NULL)  
     return;  
   
   if (imageAvailableID == NULL)  
     {  
       jclass gtk_selection_class;  
       gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);  
       imageAvailableID = (*env)->GetMethodID (env, gtk_selection_class,  
                                              "imageAvailable",  
                                              "(Lgnu/classpath/Pointer;)V");  
       if (imageAvailableID == NULL)  
         return;  
     }  
   
   gdk_threads_enter ();  
   gtk_clipboard_request_image (clipboard,  
                                cp_gtk_clipboard_image_received,  
                                (gpointer) selection_obj);  
   gdk_threads_leave ();  
 }  
   
 static jmethodID urisAvailableID;  
   
 static void  
 cp_gtk_clipboard_uris_received (GtkClipboard *clipboard  
                                 __attribute__((unused)),  
                                 GtkSelectionData *uri_data,  
                                 gpointer selection)  
 {  
   gchar **uris = NULL;  
   jobjectArray strings = NULL;  
   jobject selection_obj = (jobject) selection;  
   JNIEnv *env = cp_gtk_gdk_env ();  
   
   if (uri_data != NULL)  
     uris = gtk_selection_data_get_uris (uri_data);  
     
   if (uris != NULL)  
     {  
       int len, i;  
       gchar **count = uris;  
       jclass stringClass = (*env)->FindClass (env, "java/lang/String");  
   
       len = 0;  
       while (count[len])  
         len++;  
   
       strings = (*env)->NewObjectArray (env, len, stringClass, NULL);  
       if (strings != NULL)  
         {  
           for (i = 0; i < len; i++)  
             {  
               jstring string = (*env)->NewStringUTF (env, uris[i]);  
               if (string == NULL)  
                 break;  
               (*env)->SetObjectArrayElement (env, strings, i, string);  
             }  
         }  
       g_strfreev (uris);  
     }  
   
   (*env)->CallVoidMethod (env, selection_obj,  
                           urisAvailableID,  
                           strings);  
   (*env)->DeleteGlobalRef (env, selection_obj);  
 }  
   
 JNIEXPORT void JNICALL  
 Java_gnu_java_awt_peer_gtk_GtkSelection_requestURIs (JNIEnv *env, jobject obj)  
 {  
   GdkAtom uri_atom;  
   jobject selection_obj;  
   selection_obj = (*env)->NewGlobalRef(env, obj);  
   if (selection_obj == NULL)  
     return;  
   
   if (urisAvailableID == NULL)  
     {  
       jclass gtk_selection_class;  
       gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);  
       urisAvailableID = (*env)->GetMethodID (env, gtk_selection_class,  
                                              "urisAvailable",  
                                              "([Ljava/lang/String;)V");  
       if (urisAvailableID == NULL)  
         return;  
     }  
   
   /* There is no real request_uris so we have to make one ourselves. */  
   gdk_threads_enter ();  
   uri_atom = gdk_atom_intern ("text/uri-list", FALSE);  
   gtk_clipboard_request_contents (clipboard,  
                                   uri_atom,  
                                   cp_gtk_clipboard_uris_received,  
                                   (gpointer) selection_obj);  
   gdk_threads_leave ();  
 }  
   
 static jmethodID bytesAvailableID;  
   
 static void  
 cp_gtk_clipboard_bytes_received (GtkClipboard *clipboard  
                                  __attribute__((unused)),  
                                  GtkSelectionData *selection_data,  
                                  gpointer selection)  
 {  
   jbyteArray bytes = NULL;  
   jobject selection_obj = (jobject) selection;  
   JNIEnv *env = cp_gtk_gdk_env ();  
   
    if (selection_data != NULL && selection_data->length > 0)  
     {  
       bytes = (*env)->NewByteArray (env, selection_data->length);  
       if (bytes != NULL)  
         (*env)->SetByteArrayRegion(env, bytes, 0, selection_data->length,  
                                    (jbyte *) selection_data->data);  
     }  
   
   (*env)->CallVoidMethod (env, selection_obj,  
                           bytesAvailableID,  
                           bytes);  
   (*env)->DeleteGlobalRef (env, selection_obj);  
 }  
   
 JNIEXPORT void JNICALL  
 Java_gnu_java_awt_peer_gtk_GtkSelection_requestBytes (JNIEnv *env,  
                                                       jobject obj,  
                                                       jstring target_string)  
 {  
   int len;  
   const gchar *target_text;  
   GdkAtom target_atom;  
   jobject selection_obj;  
   selection_obj = (*env)->NewGlobalRef(env, obj);  
   if (selection_obj == NULL)  
     return;  
   
   if (bytesAvailableID == NULL)  
     {  
       jclass gtk_selection_class;  
       gtk_selection_class = (*env)->GetObjectClass (env, selection_obj);  
       bytesAvailableID = (*env)->GetMethodID (env, gtk_selection_class,  
                                               "bytesAvailable",  
                                               "([B)V");  
       if (bytesAvailableID == NULL)  
         return;  
     }  
   
   len = (*env)->GetStringUTFLength (env, target_string);  
   if (len == -1)  
     return;  
   target_text = (*env)->GetStringUTFChars (env, target_string, NULL);  
   if (target_text == NULL)  
     return;  
   
   gdk_threads_enter ();  
   target_atom = gdk_atom_intern (target_text, FALSE);  
   gtk_clipboard_request_contents (clipboard,  
                                   target_atom,  
                                   cp_gtk_clipboard_bytes_received,  
                                   (gpointer) selection_obj);  
   gdk_threads_leave ();  
   
   (*env)->ReleaseStringUTFChars (env, target_string, target_text);  
 }  

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15

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