[java-atk-wrapper] FIX SIGEV fatal error
- From: Magdalen Berns <mberns src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [java-atk-wrapper] FIX SIGEV fatal error
- Date: Sat, 17 Jan 2015 00:53:42 +0000 (UTC)
commit 5bf850ab5acb43c4e961e4a44a49cf7e23d3f085
Author: Magdalen Berns <m berns thismagpie com>
Date: Sat Jan 17 00:46:13 2015 +0000
FIX SIGEV fatal error
There was a SIGEV fatal error when running orca meaning
the J2SE-access-bridge script was not identified. This
was caused by some dodgy jni initialization and also a
configuration bug in the keymaps. Resolving the issues
allows the program to init but there is still some
locking up in the g_cond(wait) to resolve.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=742597
jni/src/AtkWrapper.c | 180 ++++++++++++++--------
jni/src/jawutil.c | 25 +++-
wrapper/org/GNOME/Accessibility/AtkKeyEvent.java | 8 +-
3 files changed, 138 insertions(+), 75 deletions(-)
---
diff --git a/jni/src/AtkWrapper.c b/jni/src/AtkWrapper.c
index dac74d8..ac45db9 100644
--- a/jni/src/AtkWrapper.c
+++ b/jni/src/AtkWrapper.c
@@ -21,7 +21,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
-#include <gmodule.h>
#include <atk-bridge.h>
#include <gdk/gdk.h>
#include <X11/Xlib.h>
@@ -30,6 +29,13 @@
#include "jawimpl.h"
#include "jawtoplevel.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define JNI_FALSE 0
+#define JNI_TRUE 1
+
#define KEY_DISPATCH_NOT_DISPATCHED 0
#define KEY_DISPATCH_CONSUMED 1
#define KEY_DISPATCH_NOT_CONSUMED 2
@@ -40,6 +46,7 @@
#define GDK_META_MASK (1 << 28)
typedef struct _DummyDispatch DummyDispatch;
+typedef enum _SignalType SignalType;
struct _DummyDispatch
{
@@ -56,24 +63,46 @@ GCond *atk_bridge_cond;
GMutex *key_dispatch_mutex;
GCond *key_dispatch_cond;
-static gint key_dispatch_result = KEY_DISPATCH_NOT_DISPATCHED;
+static gint key_dispatch_result;
static gboolean (*origin_g_idle_dispatch) (GSource*, GSourceFunc, gpointer);
+static GMainLoop* jni_main_loop;
-static GModule* module_atk_bridge = NULL;
+gpointer current_bridge_data = NULL;
+JavaVM* cachedJVM;
+JNIEnv *cachedEnv;
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *javaVM, void *reserve)
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserve)
{
JNIEnv *env;
- globalJvm = javaVM;
-
- if ((*javaVM)->GetEnv(javaVM, (void **)&env, JNI_VERSION_1_2))
- {
- return JNI_ERR; /* Not supported */
+ cachedJVM = jvm;
+ if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_8)) {
+ fprintf(stderr, "Attach failed\n");
+ return JNI_ERR; /* JNI version not supported */
}
- return JNI_VERSION_1_2;
+ g_assert(jvm != NULL);
+
+ return JNI_VERSION_1_8;
+}
+
+JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserve) {
}
-JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *javaVM, void *reserve) {
+gboolean jaw_accessibility_init (void *data)
+{
+ g_mutex_lock(atk_bridge_mutex);
+ atk_bridge_adaptor_init (NULL, NULL);
+ if (jaw_debug)
+ g_print ("Atk Accessibility bridge initialized\n");
+ g_cond_signal(atk_bridge_cond);
+ g_mutex_unlock(atk_bridge_mutex);
+
+ return TRUE;
+}
+
+void
+jaw_accessibility_shutdown (void)
+{
+ atk_bridge_adaptor_cleanup();
}
static gboolean
@@ -104,32 +133,16 @@ jaw_idle_dispatch (GSource *source,
return origin_g_idle_dispatch(source, callback, user_data);
}
-static void jaw_exit_func ()
-{
- _exit(0);
-}
-static gboolean
-jaw_load_atk_bridge (gpointer p)
+static
+void *jni_loop_callback(void *data)
{
- g_mutex_lock(atk_bridge_mutex);
- atk_bridge_adaptor_init (NULL, NULL);
-
+ char *message;
+ message = (char *)data;
if (jaw_debug)
- printf("ATK Bridge has been loaded successfully\n");
-
- atexit( jaw_exit_func );
-
- g_cond_signal(atk_bridge_cond);
- g_mutex_unlock(atk_bridge_mutex);
-
- return FALSE;
-}
-
-gpointer jni_main_loop(gpointer data)
-{
- g_main_loop_run( (GMainLoop*)data );
- return NULL;
+ printf("%s \n", message);
+ g_main_loop_quit (jni_main_loop);
+ return 0;
}
JNIEXPORT jboolean
@@ -164,15 +177,18 @@ JNICALL Java_org_GNOME_Accessibility_AtkWrapper_initNativeLibrary(JNIEnv *jniEnv
}
jaw_impl_init_mutex();
-
+ g_assert (atk_bridge_mutex == NULL);
atk_bridge_mutex = g_new(GMutex, 1);
g_mutex_init(atk_bridge_mutex);
+ g_assert (atk_bridge_mutex != NULL);
atk_bridge_cond = g_new(GCond, 1);
g_cond_init(atk_bridge_cond);
+ g_assert (key_dispatch_mutex == NULL);
key_dispatch_mutex = g_new(GMutex, 1);
g_mutex_init(key_dispatch_mutex);
+ g_assert (key_dispatch_mutex != NULL);
key_dispatch_cond = g_new(GCond, 1);
g_cond_init(key_dispatch_cond);
@@ -191,28 +207,31 @@ JNICALL Java_org_GNOME_Accessibility_AtkWrapper_loadAtkBridge(JNIEnv *jniEnv,
// Enable ATK Bridge so we can load it now
g_setenv("NO_AT_BRIDGE", "0", TRUE);
- const gchar *name = "loaded-bridge";
- GMainLoop *main_loop = g_main_loop_new( NULL, FALSE );
-
- g_idle_add(jaw_load_atk_bridge, NULL);
+ GThread *thread;
+ GError *err;
+ char * message;
+ message = "jni main loop";
+ err = NULL;
- // We need to wait for the completion of the loading of ATK Bridge
- // in order to ensure event listeners in ATK Bridge are properly
- // registered before any emission of AWT event.
- g_mutex_lock(atk_bridge_mutex);
-
- GThread *main_loop_thread = g_thread_new(name,
- jni_main_loop,
- (gpointer)main_loop);
+ jni_main_loop = g_main_loop_new (NULL, FALSE);
+ g_idle_add((GSourceFunc)jaw_accessibility_init, NULL);
- g_cond_wait(atk_bridge_cond, atk_bridge_mutex);
+ thread = g_thread_new(message, (GThreadFunc)jni_loop_callback, (void *)message);
+ if(thread == NULL)
+ {
+ if (jaw_debug)
+ {
+ printf("Thread create failed: %s!!\n", err->message );
+ g_error_free (err);
+ }
+ }
- g_mutex_unlock(atk_bridge_mutex);
- g_mutex_clear(atk_bridge_mutex);
- g_free(atk_bridge_mutex);
+ g_main_loop_run(jni_main_loop);
+ g_thread_join (thread);
+ g_main_loop_unref(jni_main_loop);
}
-typedef enum _SignalType {
+enum _SignalType {
Sig_Text_Caret_Moved = 0,
Sig_Text_Property_Changed_Insert = 1,
Sig_Text_Property_Changed_Delete = 2,
@@ -235,7 +254,7 @@ typedef enum _SignalType {
Sig_Object_Property_Change_Accessible_Table_Row_Description = 19,
Sig_Table_Model_Changed = 20,
Sig_Text_Property_Changed = 21
-}SignalType;
+};
typedef struct _CallbackPara {
jobject global_ac;
@@ -285,7 +304,7 @@ focus_notify_handler (gpointer p)
}
AtkObject* atk_obj = ATK_OBJECT(jaw_impl);
- atk_object_notify_state_change(atk_obj, ATK_STATE_FOCUSED, para->state_value);
+ atk_object_notify_state_change(atk_obj, ATK_STATE_FOCUSED, TRUE);
free_callback_para(para);
@@ -311,7 +330,7 @@ window_open_handler (gpointer p)
gboolean is_toplevel = para->is_toplevel;
JNIEnv *jniEnv = jaw_util_get_jni_env();
- JawImpl* jaw_impl = jaw_impl_find_instance(jniEnv, global_ac);
+ JawImpl* jaw_impl = jaw_impl_get_instance(jniEnv, global_ac);
AtkObject* atk_obj = ATK_OBJECT(jaw_impl);
if (!g_strcmp0(atk_role_get_name(atk_object_get_role(atk_obj)),
@@ -531,7 +550,7 @@ window_activate_handler (gpointer p)
jobject global_ac = para->global_ac;
JNIEnv *jniEnv = jaw_util_get_jni_env();
- JawImpl* jaw_impl = jaw_impl_find_instance(jniEnv, global_ac);
+ JawImpl* jaw_impl = jaw_impl_get_instance(jniEnv, global_ac);
if (jaw_impl == NULL)
{
@@ -598,6 +617,7 @@ window_state_change_handler (gpointer p)
jobject global_ac = para->global_ac;
JNIEnv *jniEnv = jaw_util_get_jni_env();
+
JawImpl* jaw_impl = jaw_impl_get_instance(jniEnv, global_ac);
if (jaw_impl == NULL)
@@ -787,10 +807,24 @@ signal_emit_handler (gpointer p)
gint newValue = get_int_value(jniEnv,
(*jniEnv)->GetObjectArrayElement(jniEnv, args, 1));
AtkPropertyValues values = { NULL };
+ // GValues must be initialized
+
+ g_assert (!G_VALUE_HOLDS_INT (&values.old_value));
g_value_init(&values.old_value, G_TYPE_INT);
+ g_assert (G_VALUE_HOLDS_INT (&values.old_value));
g_value_set_int(&values.old_value, oldValue);
+ if (jaw_debug)
+ printf ("%d\n", g_value_get_int(&values.old_value));
+ g_value_unset(&values.old_value);
+
+ g_assert (!G_VALUE_HOLDS_INT (&values.new_value));
g_value_init(&values.new_value, G_TYPE_INT);
+ g_assert (G_VALUE_HOLDS_INT (&values.old_value));
g_value_set_int(&values.new_value, newValue);
+ if (jaw_debug)
+ printf ("%d\n", g_value_get_int(&values.new_value));
+ g_value_unset(&values.new_value);
+
values.property_name = "accessible-actions";
g_signal_emit_by_name(atk_obj,
@@ -875,7 +909,7 @@ signal_emit_handler (gpointer p)
gint newValue = get_int_value(jniEnv,
(*jniEnv)->GetObjectArrayElement(jniEnv, args, 0));
- gint prevCount = *(gint*)g_hash_table_lookup(jaw_obj->storedData,
+ gint prevCount = (gint)g_hash_table_lookup(jaw_obj->storedData,
"Previous_Count");
gint curCount = atk_text_get_character_count(ATK_TEXT(jaw_obj));
@@ -1040,9 +1074,13 @@ static gboolean
key_dispatch_handler (gpointer p)
{
g_mutex_lock(key_dispatch_mutex);
+ JavaVM *jvm;
+ jvm = cachedJVM;
jobject jAtkKeyEvent = (jobject)p;
JNIEnv *jniEnv = jaw_util_get_jni_env();
+ key_dispatch_result = 0;
+ cachedEnv = jniEnv;
AtkKeyEventStruct *event = g_new0(AtkKeyEventStruct, 1);
jclass classAtkKeyEvent = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkKeyEvent");
@@ -1108,18 +1146,23 @@ key_dispatch_handler (gpointer p)
jfieldID jfidTimestamp = (*jniEnv)->GetFieldID(jniEnv, classAtkKeyEvent, "timestamp", "I");
event->timestamp = (guint32)(*jniEnv)->GetIntField(jniEnv, jAtkKeyEvent, jfidTimestamp);
+ if(jaw_debug)
+ printf("key_dispatch_result = %d\n ",key_dispatch_result);
gboolean b = jaw_util_dispatch_key_event (event);
+ if(jaw_debug)
+ printf("b = %s\n ",(char *)&b);
if (b) {
- key_dispatch_result = KEY_DISPATCH_CONSUMED;
+ key_dispatch_result = 1;
} else {
- key_dispatch_result = KEY_DISPATCH_NOT_CONSUMED;
+ key_dispatch_result = 2;
}
-
+ if(jaw_debug)
+ printf("key_dispatch_result = %d\n ",key_dispatch_result);
(*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, event->string);
g_free(event);
(*jniEnv)->DeleteGlobalRef(jniEnv, jAtkKeyEvent);
-
+ (*jvm)->DetachCurrentThread(jvm);
g_cond_signal(key_dispatch_cond);
g_mutex_unlock(key_dispatch_mutex);
return FALSE;
@@ -1131,17 +1174,20 @@ JNICALL Java_org_GNOME_Accessibility_AtkWrapper_dispatchKeyEvent(JNIEnv *jniEnv,
jobject jAtkKeyEvent)
{
jboolean key_consumed;
+ cachedEnv = jniEnv;
jobject global_key_event = (*jniEnv)->NewGlobalRef(jniEnv, jAtkKeyEvent);
g_mutex_lock(key_dispatch_mutex);
g_idle_add(key_dispatch_handler, (gpointer)global_key_event);
- while (key_dispatch_result == KEY_DISPATCH_NOT_DISPATCHED) {
+ if(jaw_debug)
+ printf("key_dispatch_result = %d\n ",key_dispatch_result);
+ while (key_dispatch_result == 0) {
g_cond_wait(key_dispatch_cond, key_dispatch_mutex);
}
- if (key_dispatch_result == KEY_DISPATCH_CONSUMED)
+ if (key_dispatch_result == 1)
{
key_consumed = JNI_TRUE;
} else
@@ -1149,12 +1195,14 @@ JNICALL Java_org_GNOME_Accessibility_AtkWrapper_dispatchKeyEvent(JNIEnv *jniEnv,
key_consumed = JNI_FALSE;
}
- key_dispatch_result = KEY_DISPATCH_NOT_DISPATCHED;
+ key_dispatch_result = 0;
g_mutex_unlock(key_dispatch_mutex);
- g_mutex_clear(key_dispatch_mutex);
- g_free(key_dispatch_mutex);
return key_consumed;
}
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/jni/src/jawutil.c b/jni/src/jawutil.c
index 3fe050d..e8241a3 100644
--- a/jni/src/jawutil.c
+++ b/jni/src/jawutil.c
@@ -57,8 +57,8 @@ struct _JawUtilListenerInfo
gulong hook_id;
};
-JavaVM *globalJvm = NULL;
-JNIEnv *globalEnv = NULL;
+JavaVM *cachedJVM;
+JNIEnv *cachedEnv;
GType
jaw_util_get_type(void)
@@ -398,11 +398,24 @@ jaw_util_is_same_jobject(gconstpointer a,
}
JNIEnv*
-jaw_util_get_jni_env()
+jaw_util_get_jni_env(void)
{
- (*globalJvm)->AttachCurrentThread( globalJvm, (void**)&globalEnv, NULL );
-
- return globalEnv;
+ JNIEnv *env;
+ JavaVM *jvm;
+ jvm = cachedJVM;
+ env = cachedEnv;
+ if (jvm == NULL) (*env)->GetJavaVM(globalEnv,&jvm);
+ int res;
+ #ifdef JNI_VERSION_1_8
+ res = (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL);
+ #else
+ (res*) = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
+ #endif
+ if (&res < 0) {
+ fprintf(stderr, "Attach failed\n");
+ }
+
+ return env;
}
static jobject
diff --git a/wrapper/org/GNOME/Accessibility/AtkKeyEvent.java
b/wrapper/org/GNOME/Accessibility/AtkKeyEvent.java
index 9bf6348..2db5911 100644
--- a/wrapper/org/GNOME/Accessibility/AtkKeyEvent.java
+++ b/wrapper/org/GNOME/Accessibility/AtkKeyEvent.java
@@ -25,7 +25,7 @@ import java.util.HashMap;
public class AtkKeyEvent {
- private static HashMap<Object,String> nonAlphaNumericMap=null;
+ private static HashMap nonAlphaNumericMap = null;
public static final int ATK_KEY_EVENT_PRESSED = 0;
public static final int ATK_KEY_EVENT_RELEASED = 1;
@@ -42,6 +42,7 @@ public class AtkKeyEvent {
static {
// Non-alphanumeric symbols that need to be mapped to X11 keysym names
+ nonAlphaNumericMap = new HashMap( 40 );
nonAlphaNumericMap.put("!", "exclam");
nonAlphaNumericMap.put("@", "at");
nonAlphaNumericMap.put("#", "numbersign");
@@ -135,7 +136,7 @@ public class AtkKeyEvent {
keycode = e.getKeyCode();
timestamp = (int)e.getWhen();
- String nonAlphaNumericString = nonAlphaNumericMap.get(string);
+ String nonAlphaNumericString = (String) nonAlphaNumericMap.get(string);
if (nonAlphaNumericString != null)
string = nonAlphaNumericString;
}
@@ -143,7 +144,7 @@ public class AtkKeyEvent {
class GNOMEKeyMapping {
- private static HashMap<Object,Object> keyMap = null;
+ private static HashMap keyMap = null;
public static final class GNOMEKeyInfo {
private int gdkKeyCode;
@@ -192,6 +193,7 @@ class GNOMEKeyMapping {
}
private static void initializeMap() {
+ keyMap = new HashMap( 146 ); // Currently only 110, so allocate 110 / 0.75
keyMap.put( new Integer(KeyEvent.VK_COLON), new GNOMEKeyInfo( 0x20a1, "ColonSign" ) ); //
GDK_ColonSign
keyMap.put( new Integer(KeyEvent.VK_EURO_SIGN), new GNOMEKeyInfo( 0x20ac, "EuroSign" ) ); //
GDK_EuroSign
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]