classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] [gui] GdkPixbufDecoder JNIEnv fix proposal (PR/16824)


From: Mark Wielaard
Subject: [cp-patches] [gui] GdkPixbufDecoder JNIEnv fix proposal (PR/16824)
Date: Sun, 08 Aug 2004 17:30:01 +0200

Hi,

The following is a proposal to fix http://gcc.gnu.org/PR16824
"GdkPixbufDecoder crashes with image loading programs"

I decided to make it standalone and not depend on any of the other gtk
peer classes since it seems that it has to be useful even when no
GtkToolkit has been initialized. So it adds a static local JavaVM
reference to the file which is used in all funtions/callbacks that need
to access a JNI environment.

2004-08-08  Mark Wielaard  <address@hidden>

        * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c:
        #include gdk.h, not gtk.h. #include jni.h, native_state.h, string.h
        and stdlib.h, not gtkpeer.h.
        (*vm): New static variable.
        (areaPreparedID): Make static.
        (areaUpdatedID): Likewise.
        (area_prepared): Get and use JNIEnv through stored JavaVM *vm.
        (area_prepared): Likewise.
        (area_updated): Likewise.
        (closed): Likewise.
        (initStaticState): Initialize *vm javaVM.
        (pumpBytes): Use given env, not global gdk_env.

With this the new Frame.setIcon() and the mauve test for
gnu.testlet.java.awt.image.PixelGrabber.SimpleGrabber work much more
reliable.

The only issue is that gcc 3+ complains loudly about the following:

../../../../classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c:
 In function `area_prepared':
../../../../classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c:86:
 warning: dereferencing type-punned pointer will break strict-aliasing rules
../../../../classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c:
 In function `area_updated':
../../../../classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c:124:
 warning: dereferencing type-punned pointer will break strict-aliasing rules
../../../../classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c:
 In function `closed':
../../../../classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c:167:
 warning: dereferencing type-punned pointer will break strict-aliasing rules

Does anybody know what the correct way to solve this is?
Any comments on the general idea of the patch?

Cheers,

Mark
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c
===================================================================
RCS file: 
/cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c,v
retrieving revision 1.5
diff -u -r1.5 gnu_java_awt_peer_gtk_GdkPixbufDecoder.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c        26 Jun 
2004 16:07:03 -0000      1.5
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c        8 Aug 
2004 15:17:58 -0000
@@ -1,5 +1,5 @@
 /* gdkpixbufdecoder.c
-   Copyright (C) 1999, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GNU Classpath.
    
@@ -35,14 +35,17 @@
    obligated to do so.  If you do not wish to do so, delete this
    exception statement from your version. */
 
-
-#include <gtk/gtk.h>
+#include <gdk/gdk.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gdk-pixbuf/gdk-pixbuf-loader.h>
 
-#include "gtkpeer.h"
+#include <jni.h>
+#include "native_state.h"
 #include "gnu_java_awt_peer_gtk_GdkPixbufDecoder.h"
 
+#include <string.h>
+#include <stdlib.h>
+
 struct state_table *native_pixbufdecoder_state_table;
 
 #define NSA_PB_INIT(env, clazz) \
@@ -57,14 +60,16 @@
 #define NSA_DEL_PB_PTR(env, obj) \
   remove_state_slot (env, obj, native_pixbufdecoder_state_table)
 
+static JavaVM *vm;
 
-jmethodID areaPreparedID;
-jmethodID areaUpdatedID;
+static jmethodID areaPreparedID;
+static jmethodID areaUpdatedID;
 
 static void
 area_prepared (GdkPixbufLoader *loader, 
               jobject *decoder)
 {
+  JNIEnv *env;
   jint width, height;
 
   GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
@@ -78,11 +83,12 @@
 
   g_assert (decoder != NULL);
 
-  (*gdk_env)->CallVoidMethod (gdk_env,
-                             *decoder,
-                             areaPreparedID,
-                             width, height);
-
+  (*vm)->GetEnv (vm, (void **) &env, JNI_VERSION_1_1);
+  (*env)->CallVoidMethod (env,
+                         *decoder,
+                         areaPreparedID,
+                         width, height);
+  
   gdk_threads_enter ();
 }
 
@@ -92,6 +98,7 @@
              gint width, gint height,
              jobject *decoder)
 {
+  JNIEnv *env;
   jint stride_bytes, stride_pixels, n_channels, n_pixels;
   int i, px;
   jintArray jpixels;  
@@ -114,8 +121,9 @@
   n_pixels = height * stride_pixels;
   gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
 
-  jpixels = (*gdk_env)->NewIntArray (gdk_env, n_pixels);
-  java_pixels = (*gdk_env)->GetIntArrayElements (gdk_env, jpixels, NULL);
+  (*vm)->GetEnv (vm, (void **) &env, JNI_VERSION_1_1);
+  jpixels = (*env)->NewIntArray (env, n_pixels);
+  java_pixels = (*env)->GetIntArrayElements (env, jpixels, NULL);
 
   memcpy (java_pixels, 
          gdk_pixels + (y * stride_bytes), 
@@ -141,22 +149,25 @@
 
   gdk_threads_leave ();
 
-  (*gdk_env)->ReleaseIntArrayElements (gdk_env, jpixels, java_pixels, 0);
-  (*gdk_env)->CallVoidMethod (gdk_env, 
-                             *decoder, 
-                             areaUpdatedID,
-                             (jint) x, (jint) y,
-                             (jint) width, (jint) height,
-                             jpixels,
-                             stride_pixels);
+  (*env)->ReleaseIntArrayElements (env, jpixels, java_pixels, 0);
+  (*env)->CallVoidMethod (env, 
+                         *decoder, 
+                         areaUpdatedID,
+                         (jint) x, (jint) y,
+                         (jint) width, (jint) height,
+                         jpixels,
+                         stride_pixels);
   gdk_threads_enter ();
 }
 
 static void
 closed (GdkPixbufLoader *loader __attribute__((unused)), jobject *decoder)
 {
+  JNIEnv *env;
+  (*vm)->GetEnv (vm, (void **) &env, JNI_VERSION_1_1);
+
   gdk_threads_leave ();
-  (*gdk_env)->DeleteGlobalRef (gdk_env, *decoder); 
+  (*env)->DeleteGlobalRef (env, *decoder); 
   free (decoder);
   gdk_threads_enter ();
 }
@@ -187,6 +198,8 @@
 JNIEXPORT void JNICALL 
Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_initStaticState 
   (JNIEnv *env, jclass clazz)
 {
+  (*env)->GetJavaVM(env, &vm);
+
   areaPreparedID = (*env)->GetMethodID (env, clazz, 
                                        "areaPrepared", 
                                        "(II)V");
@@ -223,14 +236,14 @@
   if (len < 1)
     return;
 
-  bytes = (*gdk_env)->GetByteArrayElements (gdk_env, jarr, NULL);
+  bytes = (*env)->GetByteArrayElements (env, jarr, NULL);
   g_assert (bytes != NULL);
   loader = (GdkPixbufLoader *)NSA_GET_PB_PTR (env, obj);
   g_assert (loader != NULL);
 
   gdk_threads_enter ();
-  gdk_pixbuf_loader_write (loader, bytes, len, NULL);
+  gdk_pixbuf_loader_write (loader, (const guchar *) bytes, len, NULL);
   gdk_threads_leave ();
 
-  (*gdk_env)->ReleaseByteArrayElements (gdk_env, jarr, bytes, 0);
+  (*env)->ReleaseByteArrayElements (env, jarr, bytes, 0);
 }

Attachment: signature.asc
Description: This is a digitally signed message part


reply via email to

[Prev in Thread] Current Thread [Next in Thread]