OSDN Git Service

Imported Classpath 0.18.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkImage.c
index 86cad14..fdc73cc 100644 (file)
@@ -35,6 +35,7 @@ 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_GtkImage.h"
 #include <gdk-pixbuf/gdk-pixbuf.h>
@@ -96,6 +97,67 @@ Java_gnu_java_awt_peer_gtk_GtkImage_loadPixbuf
   return JNI_TRUE;
 }
 
+/*
+ * Creates the image from an array of java bytes.
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_loadImageFromData
+  (JNIEnv *env, jobject obj, jbyteArray data)
+{
+  jbyte *src;
+  GdkPixbuf* pixbuf;
+  GdkPixbufLoader* loader;
+  int len;
+  int width;
+  int height;
+
+  gdk_threads_enter ();
+
+  src = (*env)->GetByteArrayElements (env, data, NULL);
+  len = (*env)->GetArrayLength (env, data);
+
+  loader = gdk_pixbuf_loader_new ();
+
+  gdk_pixbuf_loader_write (loader, (guchar *)src, len, NULL);
+  gdk_pixbuf_loader_close (loader, NULL);
+
+  (*env)->ReleaseByteArrayElements (env, data, src, 0);
+
+  pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+  if (pixbuf == NULL)
+    {
+      createRawData (env, obj, NULL);
+
+      gdk_threads_leave ();
+
+      return JNI_FALSE;
+    }
+
+  width =  gdk_pixbuf_get_width (pixbuf);
+  height = gdk_pixbuf_get_height (pixbuf);
+
+  createRawData (env, obj, pixbuf);
+  setWidthHeight(env, obj, width, height);
+
+  gdk_threads_leave ();
+
+  return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_createFromPixbuf
+(JNIEnv *env, jobject obj)
+{
+  int width, heigth;
+  GdkPixbuf *pixbuf = (GdkPixbuf *) getData (env, obj);
+  gdk_threads_enter ();
+  width =  gdk_pixbuf_get_width (pixbuf);
+  heigth = gdk_pixbuf_get_height (pixbuf);
+  gdk_threads_leave ();
+  setWidthHeight(env, obj, width, heigth);
+}
+
 /**
  * Returns a copy of the pixel data as a java array.
  */
@@ -116,15 +178,8 @@ Java_gnu_java_awt_peer_gtk_GtkImage_getPixels(JNIEnv *env, jobject obj)
   height = gdk_pixbuf_get_height (pixbuf);
   rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 
-  /* Must release the GDK lock before allocating memory through the
-     JVM, since some JVMs use the same lock for allocations and
-     finalization.  Deadlock can occur on those JVMs. */
-  gdk_threads_leave ();
-
   result_array = (*env)->NewIntArray (env, (width * height));
 
-  gdk_threads_enter ();
-
   dst = result_array_iter = 
     (*env)->GetIntArrayElements (env, result_array, NULL);
 
@@ -307,10 +362,16 @@ Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaled
 
   gdk_threads_enter ();
   
+  if (width <= 0 || height <= 0)
+    {
+      gdk_threads_leave ();
+      return;
+    }
+
   bgColor = ((bg_red & 0xFF) << 16) |
     ((bg_green & 0xFF) << 8) | (bg_blue & 0xFF);
     
-  g = (struct graphics *) NSA_GET_PTR (env, gc_obj);
+  g = (struct graphics *) NSA_GET_G_PTR (env, gc_obj);
   
   if (!g || !GDK_IS_DRAWABLE (g->drawable))
     {
@@ -368,7 +429,12 @@ JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaledFlipped 
 (JNIEnv *env, jobject obj, jobject gc_obj,
  jint bg_red, jint bg_green, jint bg_blue, 
+#if GTK_MINOR_VERSION > 4
  jboolean flipx, jboolean flipy,
+#else
+ jboolean flipx __attribute__((unused)),
+ jboolean flipy __attribute__((unused)),
+#endif
  jint srcx, jint srcy, jint srcwidth, jint srcheight, 
  jint dstx, jint dsty, jint dstwidth, jint dstheight, 
  jboolean composite)
@@ -380,10 +446,17 @@ Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaledFlipped
 
   gdk_threads_enter ();
   
+  if (srcwidth <= 0 || srcheight <= 0
+      || dstwidth <= 0 || dstheight <= 0)
+    {
+      gdk_threads_leave ();
+      return;
+    }
+
   bgColor = ((bg_red & 0xFF) << 16) |
     ((bg_green & 0xFF) << 8) | (bg_blue & 0xFF);
     
-  g = (struct graphics *) NSA_GET_PTR (env, gc_obj);
+  g = (struct graphics *) NSA_GET_G_PTR (env, gc_obj);
   
   if (!g || !GDK_IS_DRAWABLE (g->drawable))
     {
@@ -573,24 +646,15 @@ static void
 createRawData (JNIEnv * env, jobject obj, void *ptr)
 {
   jclass cls;
-  jmethodID method;
   jobject data;
   jfieldID data_fid;
 
   cls = (*env)->GetObjectClass (env, obj);
   data_fid = (*env)->GetFieldID (env, cls, "pixmap", 
-                                "Lgnu/classpath/RawData;");
+                                "Lgnu/classpath/Pointer;");
   g_assert (data_fid != 0);
 
-#if SIZEOF_VOID_P == 8
-  cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
-  method = (*env)->GetMethodID (env, cls, "<init>", "(J)V");
-  data = (*env)->NewObject (env, cls, method, (jlong) ptr);
-#else
-  cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
-  method = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
-  data = (*env)->NewObject (env, cls, method, (jint) ptr);
-#endif
+  data = JCL_NewRawDataObject (env, ptr);
 
   (*env)->SetObjectField (env, obj, data_fid, data);
 }
@@ -599,23 +663,14 @@ static void *
 getData (JNIEnv * env, jobject obj)
 {
   jclass cls;
-  jfieldID field;
   jfieldID data_fid;
   jobject data;
 
   cls = (*env)->GetObjectClass (env, obj);
   data_fid = (*env)->GetFieldID (env, cls, "pixmap", 
-                                "Lgnu/classpath/RawData;");
+                                "Lgnu/classpath/Pointer;");
   g_assert (data_fid != 0);
   data = (*env)->GetObjectField (env, obj, data_fid);
 
-#if SIZEOF_VOID_P == 8
-  cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
-  field = (*env)->GetFieldID (env, cls, "data", "J");
-  return (void *) (*env)->GetLongField (env, data, field);
-#else
-  cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
-  field = (*env)->GetFieldID (env, cls, "data", "I");
-  return (void *) (*env)->GetIntField (env, data, field);
-#endif
+  return JCL_GetRawData (env, data);
 }