/* gtkclipboard.c
   Copyright (C) 1998, 1999, 2005, 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


#include "jcl.h"
#include "gtkpeer.h"
#include "gnu_java_awt_peer_gtk_GtkClipboard.h"

#define OBJECT_TARGET 1
#define TEXT_TARGET   2
#define IMAGE_TARGET  3
#define URI_TARGET    4

/* The clipboard and selection plus corresponding GtkClipboard objects. */
GtkClipboard *cp_gtk_clipboard;
GtkClipboard *cp_gtk_selection;

jobject cp_gtk_clipboard_instance;
jobject cp_gtk_selection_instance;

/* Standard (string targets) shared with GtkSelection. */
jstring cp_gtk_stringTarget;
jstring cp_gtk_imageTarget;
jstring cp_gtk_filesTarget;

static jclass gtk_clipboard_class;

static jmethodID setSystemContentsID;
static jmethodID provideContentID;
static jmethodID provideTextID;
static jmethodID provideImageID;
static jmethodID provideURIsID;

/* Called when clipboard owner changes. Used to update available targets. */
#if GTK_MINOR_VERSION > 4
static void
clipboard_owner_change_cb (GtkClipboard *clipboard,
			   GdkEvent *event __attribute__((unused)),
			   gpointer user_data __attribute__((unused)))
{
  JNIEnv *env = cp_gtk_gdk_env ();
  if (clipboard == cp_gtk_clipboard)
    (*env)->CallVoidMethod (env, cp_gtk_clipboard_instance,
			    setSystemContentsID, JNI_FALSE);
  else
    (*env)->CallVoidMethod (env, cp_gtk_selection_instance,
                            setSystemContentsID, JNI_FALSE);

}
#endif

JNIEXPORT jboolean JNICALL 
Java_gnu_java_awt_peer_gtk_GtkClipboard_initNativeState (JNIEnv *env,
							 jclass clz,
							 jobject gtkclipboard,
							 jobject gtkselection,
							 jstring string,
							 jstring image,
							 jstring files)
{
  GdkDisplay* display;
  jboolean can_cache;

  gtk_clipboard_class = clz;
  setSystemContentsID = (*env)->GetMethodID (env, gtk_clipboard_class,
					     "setSystemContents",
					     "(Z)V");
  if (setSystemContentsID == NULL)
    return JNI_FALSE;

  provideContentID = (*env)->GetMethodID (env, gtk_clipboard_class,
					  "provideContent",
					  "(Ljava/lang/String;)[B");
  if (provideContentID == NULL)
    return JNI_FALSE;
  
  provideTextID = (*env)->GetMethodID (env, gtk_clipboard_class,
				       "provideText",
				       "()Ljava/lang/String;");
  if (provideTextID == NULL)
    return JNI_FALSE;
  
  provideImageID = (*env)->GetMethodID (env, gtk_clipboard_class,
					"provideImage",
					"()Lgnu/java/awt/peer/gtk/GtkImage;");
  if (provideImageID == NULL)
    return JNI_FALSE;
  
  provideURIsID = (*env)->GetMethodID (env, gtk_clipboard_class,
				       "provideURIs",
				       "()[Ljava/lang/String;");
  if (provideURIsID == NULL)
    return JNI_FALSE;
  
  cp_gtk_clipboard_instance = (*env)->NewGlobalRef(env, gtkclipboard);
  cp_gtk_selection_instance = (*env)->NewGlobalRef(env, gtkselection);
  
  cp_gtk_stringTarget = (*env)->NewGlobalRef(env, string);
  cp_gtk_imageTarget = (*env)->NewGlobalRef(env, image);
  cp_gtk_filesTarget = (*env)->NewGlobalRef(env, files);

  gdk_threads_enter ();
  cp_gtk_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
  cp_gtk_selection = gtk_clipboard_get (GDK_SELECTION_PRIMARY);

  display = gtk_clipboard_get_display (cp_gtk_clipboard);
  /* Check for support for clipboard owner changes. */
#if GTK_MINOR_VERSION > 4
  if (gdk_display_supports_selection_notification (display))
    {
      g_signal_connect (cp_gtk_clipboard, "owner-change",
			G_CALLBACK (clipboard_owner_change_cb), NULL);
      g_signal_connect (cp_gtk_selection, "owner-change",
			G_CALLBACK (clipboard_owner_change_cb), NULL);
      gdk_display_request_selection_notification (display,
						  GDK_SELECTION_CLIPBOARD);
      gdk_display_request_selection_notification (display,
						  GDK_SELECTION_PRIMARY);
      can_cache = JNI_TRUE;
    }
  else
#endif
    can_cache = JNI_FALSE;

  gdk_threads_leave ();

  return can_cache;
}

static void
clipboard_get_func (GtkClipboard *clipboard,
		    GtkSelectionData *selection,
		    guint info,
		    gpointer user_data __attribute__((unused)))
{
  jobject gtk_clipboard_instance;
  JNIEnv *env = cp_gtk_gdk_env ();
  
  if (clipboard == cp_gtk_clipboard)
    gtk_clipboard_instance = cp_gtk_clipboard_instance;
  else
    gtk_clipboard_instance = cp_gtk_selection_instance;

  if (info == OBJECT_TARGET)
    {
      const gchar *target_name;
      jstring target_string;
      jbyteArray bytes;
      jint len;
      jbyte *barray;

      target_name = gdk_atom_name (selection->target);
      if (target_name == NULL)
	return;
      target_string = (*env)->NewStringUTF (env, target_name);
      if (target_string == NULL)
	return;
      bytes = (*env)->CallObjectMethod(env,
				       gtk_clipboard_instance,
				       provideContentID,
				       target_string);
      if (bytes == NULL)
	return;
      len = (*env)->GetArrayLength(env, bytes);
      if (len <= 0)
	return;
      barray = (*env)->GetByteArrayElements(env, bytes, NULL);
      if (barray == NULL)
	return;
      gtk_selection_data_set (selection, selection->target, 8,
			      (guchar *) barray, len);

      (*env)->ReleaseByteArrayElements(env, bytes, barray, 0);

    }
  else if (info == TEXT_TARGET)
    {
      jstring string;
      const gchar *text;
      int len;
      string = (*env)->CallObjectMethod(env,
					gtk_clipboard_instance,
					provideTextID);
      if (string == NULL)
	return;
      len = (*env)->GetStringUTFLength (env, string);
      if (len == -1)
	return;
      text = (*env)->GetStringUTFChars (env, string, NULL);
      if (text == NULL)
	return;

      gtk_selection_data_set_text (selection, text, len);
      (*env)->ReleaseStringUTFChars (env, string, text);
    }
  /* Images and URIs/Files support only available with gtk+2.6 or higher. */
#if GTK_MINOR_VERSION > 4
  else if (info == IMAGE_TARGET)
    {
      jobject gtkimage;
      GdkPixbuf *pixbuf = NULL;
      
      gtkimage = (*env)->CallObjectMethod(env,
					  gtk_clipboard_instance,
					  provideImageID);
      if (gtkimage == NULL)
	return;
      
      pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage);
      if (pixbuf != NULL)
	gtk_selection_data_set_pixbuf (selection, pixbuf);
    }
  else if (info == URI_TARGET)
    {
      jobjectArray uris;
      jint count;
      int i;
      gchar **list;

      uris = (*env)->CallObjectMethod(env,
				      gtk_clipboard_instance,
				      provideURIsID);
      if (uris == NULL)
	return;
      count = (*env)->GetArrayLength (env, uris);
      if (count <= 0)
	return;

      list = (gchar **) JCL_malloc (env, (count + 1) * sizeof (gchar *));
      for (i = 0; i < count; i++)
	{
	  const char *text;
	  jstring uri;
	  
	  /* Mark NULL in so case of some error we can find the end. */
	  list[i] = NULL;
	  uri = (*env)->GetObjectArrayElement (env, uris, i);
	  if (uri == NULL)
	    break;
	  text = (*env)->GetStringUTFChars (env, uri, NULL);
	  if (text == NULL)
	    break;
	  list[i] = strdup (text);
	  (*env)->ReleaseStringUTFChars (env, uri, text);
	}

      if (i == count)
	{
	  list[count] = NULL;
	  gtk_selection_data_set_uris (selection, list);
	}

      for (i = 0; list[i] != NULL; i++)
	free (list[i]);
      JCL_free (env, list);
    }
#endif
}

static void
clipboard_clear_func (GtkClipboard *clipboard,
		      gpointer user_data __attribute__((unused)))
{
  JNIEnv *env = cp_gtk_gdk_env();
  if (clipboard == cp_gtk_clipboard)
    (*env)->CallVoidMethod (env, cp_gtk_clipboard_instance,
			    setSystemContentsID, JNI_TRUE);
  else
    (*env)->CallVoidMethod (env, cp_gtk_selection_instance,
                            setSystemContentsID, JNI_TRUE);

}

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkClipboard_advertiseContent
(JNIEnv *env,
 jobject instance,
 jobjectArray mime_array,
#if GTK_MINOR_VERSION > 4
 jboolean add_text, jboolean add_images, jboolean add_uris)
#else
 jboolean add_text __attribute__((unused)),
 jboolean add_images __attribute__((unused)),
 jboolean add_uris __attribute__((unused)))
#endif
{
  GtkTargetList *target_list;
  GList *list;
  GtkTargetEntry *targets;
  gint n, i;

  gdk_threads_enter ();
  target_list = gtk_target_list_new (NULL, 0);

  if (mime_array != NULL)
    {
      n = (*env)->GetArrayLength (env, mime_array);
      for (i = 0; i < n; i++)
	{
	  const char *text;
	  jstring target;
	  GdkAtom atom;

	  target = (*env)->GetObjectArrayElement (env, mime_array, i);
	  if (target == NULL)
	    break;
	  text = (*env)->GetStringUTFChars (env, target, NULL);
	  if (text == NULL)
	    break;

	  atom = gdk_atom_intern (text, FALSE);
	  gtk_target_list_add (target_list, atom, 0, OBJECT_TARGET);

	  (*env)->ReleaseStringUTFChars (env, target, text);
	}
    }

  /* Add extra targets that gtk+ can provide/translate for us. */
#if GTK_MINOR_VERSION > 4
  if (add_text)
    gtk_target_list_add_text_targets (target_list, TEXT_TARGET);
  if (add_images)
    gtk_target_list_add_image_targets (target_list, IMAGE_TARGET, TRUE);
  if (add_uris)
    gtk_target_list_add_uri_targets (target_list, URI_TARGET);
#else
  if (add_text)
    gtk_target_list_add (target_list,
	                 gdk_atom_intern ("STRING", FALSE),
	                 0, TEXT_TARGET);
#endif


  /* Turn list into a target table. */
  n = g_list_length (target_list->list);
  if (n > 0)
    {
      targets = g_new (GtkTargetEntry, n);
      for (list = target_list->list, i = 0;
	   list != NULL;
	   list = list->next, i++)
	{
	  GtkTargetPair *pair = (GtkTargetPair *) list->data;
	  targets[i].target = gdk_atom_name (pair->target);
	  targets[i].flags = pair->flags;
	  targets[i].info = pair->info;
	}

      /* Set the targets plus callback functions and ask for the clipboard
	 to be stored when the application exists if supported. */
      if ((*env)->IsSameObject(env, instance, cp_gtk_clipboard_instance))
	{
	  if (gtk_clipboard_set_with_data (cp_gtk_clipboard, targets, n,
					   clipboard_get_func,
					   clipboard_clear_func,
					   NULL))
	    {
#if GTK_MINOR_VERSION > 4
	      gtk_clipboard_set_can_store (cp_gtk_clipboard, NULL, 0);
#endif
	    }
	}
      else
	{
	  if (gtk_clipboard_set_with_data (cp_gtk_selection, targets, n,
					   clipboard_get_func,
					   clipboard_clear_func,
					   NULL))
	    {
#if GTK_MINOR_VERSION > 4
	      gtk_clipboard_set_can_store (cp_gtk_selection, NULL, 0);
#endif
	    }
	}

      for (i = 0; i < n; i++)
	g_free (targets[i].target);
      g_free (targets);
    }

  gtk_target_list_unref (target_list);
  gdk_threads_leave ();
}
