From a3c6efb539d7d82d4b0eb2d109096aca82b45174 Mon Sep 17 00:00:00 2001 From: PerryWerneck Date: Sat, 17 Dec 2016 04:20:14 -0200 Subject: [PATCH] Reimplementando módulo JNI --- configure.ac | 4 ++-- pw3270-java.cbp | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/jni/Makefile.in | 15 ++++++++++----- src/jni/actions.cc | 17 ++++++++--------- src/jni/call.cc | 165 --------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/jni/clipboard.cc | 1 - src/jni/connect.cc | 4 ++-- src/jni/cursor.cc | 6 +++--- src/jni/dialog.cc | 4 ++-- src/jni/field.cc | 10 +++++----- src/jni/getset.cc | 20 ++++++++++---------- src/jni/info.cc | 8 ++++---- src/jni/keyboard.cc | 6 +++--- src/jni/main.cc | 24 ++++++++++-------------- src/jni/private.h | 41 +++++++++++++++++++++++++++++++++++++++++ src/jni/startstop.cc | 419 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/plugin/call.cc | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/plugin/startstop.cc | 419 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 18 files changed, 743 insertions(+), 644 deletions(-) create mode 100644 pw3270-java.cbp delete mode 100644 src/jni/call.cc create mode 100644 src/jni/private.h delete mode 100644 src/jni/startstop.cc create mode 100644 src/plugin/call.cc create mode 100644 src/plugin/startstop.cc diff --git a/configure.ac b/configure.ac index 8aa8c9a..d2654b6 100644 --- a/configure.ac +++ b/configure.ac @@ -249,6 +249,7 @@ else fi +CXXFLAGS="$CXXFLAGS -I$JDK_HOME/include -I$jniinc" AC_SUBST(JVM_LIBS,$jvm_libs) @@ -263,7 +264,6 @@ AC_SUBST(JAR) AC_SUBST(jvm_arch) AC_SUBST(JDK_HOME) AC_SUBST(JRE_HOME) -AC_SUBST(JNI_CPPFLAGS,"-I$JDK_HOME/include -I$jniinc") dnl --------------------------------------------------------------------------- @@ -408,7 +408,7 @@ AC_ARG_ENABLE([pic], ]) if test "$app_cv_pic" == "yes"; then - CFLAGS="$CFLAGS -fPIC" + CXXFLAGS="$CXXFLAGS -fPIC" fi dnl --------------------------------------------------------------------------- diff --git a/pw3270-java.cbp b/pw3270-java.cbp new file mode 100644 index 0000000..7924cc2 --- /dev/null +++ b/pw3270-java.cbp @@ -0,0 +1,59 @@ + + + + + + diff --git a/src/jni/Makefile.in b/src/jni/Makefile.in index 11959c8..d8015ab 100644 --- a/src/jni/Makefile.in +++ b/src/jni/Makefile.in @@ -25,9 +25,9 @@ # SOURCES=actions.cc clipboard.cc cursor.cc field.cc info.cc main.cc \ - call.cc connect.cc dialog.cc getset.cc keyboard.cc startstop.cc + connect.cc dialog.cc getset.cc keyboard.cc -LIBNAME=lib3270-java@DLLEXT@ +LIBNAME=jni3270@DLLEXT@ #---[ Configuration values ]------------------------------------------------------------- @@ -68,7 +68,7 @@ JAVAH=@JAVAH@ JAVAC=@JAVAC@ LIBS=-lpw3270cpp @LIBS@ @LIBICONV@ -CXXFLAGS=@CXXFLAGS@ @JNI_CPPFLAGS@ +CXXFLAGS=@CXXFLAGS@ LDFLAGS=@LDFLAGS@ #---[ Rules ]---------------------------------------------------------------------------- @@ -82,7 +82,7 @@ $(OBJDBG)/%.o: \ @echo $< ... @$(MKDIR) `dirname $@` - @$(CXX) $(CFLAGS) -fstack-check -DDEBUG=1 \ + @$(CXX) $(CXXFLAGS) -fstack-check -DDEBUG=1 \ -DBUILD_DATE=`date +"0x%Y%m%d"`\ -g -o $@ -c $< @@ -93,7 +93,7 @@ $(OBJRLS)/%.o: \ @echo $< ... @$(MKDIR) `dirname $@` - @$(CXX) $(CFLAGS) -DNDEBUG=1 \ + @$(CXX) $(CXXFLAGS) -DNDEBUG=1 \ -DBUILD_DATE=`date +"0x%Y%m%d"` \ -o $@ -c $< @@ -125,3 +125,8 @@ $(BINDBG)/$(LIBNAME): \ @$(MKDIR) `dirname $@` @$(LD) -shared -Wl,-soname,$(notdir $@) $(LDFLAGS) -o $@ $^ $(LIBS) +clean: + + @rm -f jni3270.h + @rm -fr $(BINDIR)/java + diff --git a/src/jni/actions.cc b/src/jni/actions.cc index bb07239..92145d6 100644 --- a/src/jni/actions.cc +++ b/src/jni/actions.cc @@ -27,8 +27,7 @@ * */ - #include "jni3270.h" - #include "private.h" +#include "private.h" /*---[ Implement ]----------------------------------------------------------------------------------*/ @@ -40,7 +39,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_quit(JNIEnv *env, jobject obj) { try { - rc = java::getHandle(env,obj)->quit(); + rc = getHandle(env,obj)->quit(); } catch(std::exception &e) { @@ -59,7 +58,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_erase_1eof(JNIEnv *env, jobject obj) try { - rc = java::getHandle(env,obj)->erase_eof(); + rc = getHandle(env,obj)->erase_eof(); } catch(std::exception &e) { @@ -78,7 +77,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_erase(JNIEnv *env, jobject obj) { try { - rc = java::getHandle(env,obj)->erase(); + rc = getHandle(env,obj)->erase(); } catch(std::exception &e) { @@ -96,7 +95,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_erase_1eol(JNIEnv *env, jobject obj) try { - rc = java::getHandle(env,obj)->erase_eol(); + rc = getHandle(env,obj)->erase_eol(); } catch(std::exception &e) { @@ -115,7 +114,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_erase_1input(JNIEnv *env, jobject ob try { - rc = java::getHandle(env,obj)->erase_input(); + rc = getHandle(env,obj)->erase_input(); } catch(std::exception &e) { @@ -135,7 +134,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_print(JNIEnv *env, jobject obj) { try { - rc = java::getHandle(env,obj)->print(); + rc = getHandle(env,obj)->print(); } catch(std::exception &e) { @@ -155,7 +154,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_action(JNIEnv *env, jobject obj, jst try { - rc = java::getHandle(env,obj)->action(name); + rc = getHandle(env,obj)->action(name); } catch(std::exception &e) { diff --git a/src/jni/call.cc b/src/jni/call.cc deleted file mode 100644 index cb93b20..0000000 --- a/src/jni/call.cc +++ /dev/null @@ -1,165 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA, 02111-1307, USA - * - * Este programa está nomeado como call.cc e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - - - #include "private.h" - #include - #include - #include - - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - -namespace PW3270_NAMESPACE { - - - void java::call(GtkWidget *widget, const char *classname) { - - debug("%s(%s)",__FUNCTION__,classname); - - if(!trylock()) { - - failed(widget, _( "Can't access java virtual machine" ), "%s", strerror(EBUSY)); - return; - - } - - if(jvm || load_jvm(widget)) { - - v3270_set_script(widget,'J',TRUE); - - try { - - jclass cls; - jmethodID mid; - - /* - - DONT WORK!! - http://stackoverflow.com/questions/271506/why-cant-system-setproperty-change-the-classpath-at-runtime - - // Atualizar o classpath - cls = env->FindClass("java/lang/System"); - if(!cls) { - throw exception( _( "Can't find class %s" ), "java/lang/System"); - } - - mid = env->GetStaticMethodID(cls, "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); - if(!mid) { - throw exception( _( "Can't find method %s/%s" ), "java/lang/System","setProperty"); - } - - lib3270_trace_event(v3270_get_session(widget),"java.class.path=%s\n",classpath); - - jstring name = env->NewStringUTF("java.class.path"); - jstring path = env->NewStringUTF(classpath); - - jstring rc = (jstring) env->CallObjectMethod(cls,mid,name,path); - - env->DeleteLocalRef(name); - env->DeleteLocalRef(path); - env->DeleteLocalRef(rc); - */ - - // Get application entry point. - cls = env->FindClass(classname); - if(!cls) { - throw exception( _( "Can't find class %s" ), classname); - } - - mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); - if(!mid) { - throw exception( _( "Can't find method %s/%s" ), classname, "main"); - } - - // Build arguments - jobjectArray args = env->NewObjectArray(0, env->FindClass("java/lang/String"), env->NewStringUTF("")); - - // Call main() - env->CallStaticVoidMethod(cls, mid, args); - - // Check for exception - jthrowable exc = env->ExceptionOccurred(); - env->ExceptionClear(); - - if (exc) { - jclass throwable_class = env->FindClass("java/lang/Throwable"); - - jmethodID jni_getMessage = env->GetMethodID(throwable_class,"getMessage","()Ljava/lang/String;"); - jstring j_msg = (jstring) env->CallObjectMethod(exc,jni_getMessage); - - GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK_CANCEL, - _( "Java application \"%s\" has failed." ), classname ); - - gtk_window_set_title(GTK_WINDOW(dialog), _( "Java error" )); - - if(!env->IsSameObject(j_msg,NULL)) { - - const char * msg = env->GetStringUTFChars(j_msg, 0); - - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s",msg); - - env->ReleaseStringUTFChars( j_msg, msg); - } - - if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) - gtk_main_quit(); - gtk_widget_destroy(dialog); - - - } - - // And finish - env->DeleteLocalRef(args); - - } catch(std::exception &e) { - - failed(widget,_("Can't start java application"),"%s", e.what()); - - } - -/* - g_free(dirname); - g_free(classname); - g_free(classpath); -*/ - - v3270_set_script(widget,'J',FALSE); - - } - - unlock(); - - - } - -} diff --git a/src/jni/clipboard.cc b/src/jni/clipboard.cc index d94f3d6..de03535 100644 --- a/src/jni/clipboard.cc +++ b/src/jni/clipboard.cc @@ -33,7 +33,6 @@ /*---[ Implement ]----------------------------------------------------------------------------------*/ using namespace std; -using namespace PW3270_NAMESPACE::java; JNIEXPORT jint JNICALL Java_pw3270_terminal_set_1copy(JNIEnv *env, jobject obj, jstring j_str) { diff --git a/src/jni/connect.cc b/src/jni/connect.cc index fd4a5ba..92563ff 100644 --- a/src/jni/connect.cc +++ b/src/jni/connect.cc @@ -41,7 +41,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_connect(JNIEnv *env, jobject obj, js try { - rc = java::getHandle(env,obj)->connect(host,(time_t) seconds); + rc = getHandle(env,obj)->connect(host,(time_t) seconds); } catch(std::exception &e) { @@ -60,7 +60,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_disconnect(JNIEnv *env, jobject obj) try { - return (jint) java::getHandle(env,obj)->disconnect(); + return (jint) getHandle(env,obj)->disconnect(); } catch(std::exception &e) { diff --git a/src/jni/cursor.cc b/src/jni/cursor.cc index 2b75fc7..04a2072 100644 --- a/src/jni/cursor.cc +++ b/src/jni/cursor.cc @@ -40,7 +40,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_set_1cursor_1position(JNIEnv *env, j try { - rc = java::getHandle(env,obj)->set_cursor_position((int) row, (int) col); + rc = getHandle(env,obj)->set_cursor_position((int) row, (int) col); } catch(std::exception &e) { @@ -59,7 +59,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_set_1cursor_1addr(JNIEnv *env, jobje try { - rc = java::getHandle(env,obj)->set_cursor_addr((int) addr); + rc = getHandle(env,obj)->set_cursor_addr((int) addr); } catch(std::exception &e) { @@ -79,7 +79,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_get_1cursor_1addr(JNIEnv *env, jobje try { - rc = java::getHandle(env,obj)->get_cursor_addr(); + rc = getHandle(env,obj)->get_cursor_addr(); } catch(std::exception &e) { diff --git a/src/jni/dialog.cc b/src/jni/dialog.cc index cf92dc2..9b9bf57 100644 --- a/src/jni/dialog.cc +++ b/src/jni/dialog.cc @@ -43,7 +43,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_popup_1dialog(JNIEnv *env, jobject o try { - rc = (jint) java::getHandle(env,obj)->popup_dialog((LIB3270_NOTIFY) id, title, message, secondary); + rc = (jint) getHandle(env,obj)->popup_dialog((LIB3270_NOTIFY) id, title, message, secondary); } catch(std::exception &e) { @@ -71,7 +71,7 @@ JNIEXPORT jstring JNICALL Java_pw3270_terminal_file_1chooser_1dialog(JNIEnv *env try { - str = java::getHandle(env,obj)->file_chooser_dialog((int) action, title, extension, filename); + str = getHandle(env,obj)->file_chooser_dialog((int) action, title, extension, filename); } catch(std::exception &e) { diff --git a/src/jni/field.cc b/src/jni/field.cc index f486509..31e22b0 100644 --- a/src/jni/field.cc +++ b/src/jni/field.cc @@ -40,7 +40,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_get_1field_1start (JNIEnv *env, jobj try { - rc = java::getHandle(env,obj)->get_field_start((int) baddr); + rc = getHandle(env,obj)->get_field_start((int) baddr); } catch(std::exception &e) { @@ -59,7 +59,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_get_1field_1len (JNIEnv *env, jobjec try { - rc = java::getHandle(env,obj)->get_field_len((int) baddr); + rc = getHandle(env,obj)->get_field_len((int) baddr); } catch(std::exception &e) { @@ -78,7 +78,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_get_1next_1unprotected(JNIEnv *env, try { - rc = java::getHandle(env,obj)->get_next_unprotected((int) baddr); + rc = getHandle(env,obj)->get_next_unprotected((int) baddr); } catch(std::exception &e) { @@ -98,7 +98,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_get_1is_1protected(JNIEnv *env, jobj try { - rc = java::getHandle(env,obj)->get_is_protected((int) baddr); + rc = getHandle(env,obj)->get_is_protected((int) baddr); } catch(std::exception &e) { @@ -118,7 +118,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_get_1is_1protected_1at(JNIEnv *env, try { - rc = java::getHandle(env,obj)->get_is_protected_at((int) row, (int) col); + rc = getHandle(env,obj)->get_is_protected_at((int) row, (int) col); } catch(std::exception &e) { diff --git a/src/jni/getset.cc b/src/jni/getset.cc index 12ca130..e824ffb 100644 --- a/src/jni/getset.cc +++ b/src/jni/getset.cc @@ -41,7 +41,7 @@ JNIEXPORT jstring JNICALL Java_pw3270_terminal_toString(JNIEnv *env, jobject obj try { - str = java::getHandle(env,obj)->get_string(); + str = getHandle(env,obj)->get_string(); } catch(std::exception &e) { @@ -59,7 +59,7 @@ JNIEXPORT jstring JNICALL Java_pw3270_terminal_get_1string(JNIEnv *env, jobject try { - str = java::getHandle(env,obj)->get_string((int) baddr, (int) len); + str = getHandle(env,obj)->get_string((int) baddr, (int) len); } catch(std::exception &e) { @@ -78,7 +78,7 @@ JNIEXPORT jstring JNICALL Java_pw3270_terminal_get_1string_1at(JNIEnv *env, jobj try { - str = java::getHandle(env,obj)->get_string_at((int) row, (int) col, (int) sz); + str = getHandle(env,obj)->get_string_at((int) row, (int) col, (int) sz); } catch(std::exception &e) { @@ -98,7 +98,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_set_1string_1at(JNIEnv *env, jobject try { - rc = java::getHandle(env,obj)->set_string_at((int) row, (int) col, str); + rc = getHandle(env,obj)->set_string_at((int) row, (int) col, str); } catch(std::exception &e) { @@ -121,7 +121,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_cmp_1string_1at(JNIEnv *env, jobject try { - rc = java::getHandle(env,obj)->cmp_string_at((int) row, (int) col, str); + rc = getHandle(env,obj)->cmp_string_at((int) row, (int) col, str); } catch(std::exception &e) { @@ -145,7 +145,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_wait_1for_1string_1at(JNIEnv *env, j try { - rc = java::getHandle(env,obj)->wait_for_string_at((int) row, (int) col, str, timeout); + rc = getHandle(env,obj)->wait_for_string_at((int) row, (int) col, str, timeout); } catch(std::exception &e) { @@ -168,7 +168,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_input_1string(JNIEnv *env, jobject o try { - rc = java::getHandle(env,obj)->input_string(str); + rc = getHandle(env,obj)->input_string(str); } catch(std::exception &e) { @@ -189,7 +189,7 @@ JNIEXPORT jboolean JNICALL Java_pw3270_terminal_is_1connected(JNIEnv *env, jobje try { - rc = java::getHandle(env,obj)->is_connected(); + rc = getHandle(env,obj)->is_connected(); } catch(std::exception &e) { @@ -209,7 +209,7 @@ JNIEXPORT jboolean JNICALL Java_pw3270_terminal_is_1ready(JNIEnv *env, jobject o try { - rc = java::getHandle(env,obj)->is_ready(); + rc = getHandle(env,obj)->is_ready(); } catch(std::exception &e) { @@ -226,7 +226,7 @@ JNIEXPORT void JNICALL Java_pw3270_terminal_set_1unlock_1delay(JNIEnv *env, jobj try { - java::getHandle(env,obj)->set_unlock_delay((unsigned short) ms); + getHandle(env,obj)->set_unlock_delay((unsigned short) ms); } catch(std::exception &e) { diff --git a/src/jni/info.cc b/src/jni/info.cc index 9cd7f04..d53a552 100644 --- a/src/jni/info.cc +++ b/src/jni/info.cc @@ -37,21 +37,21 @@ using namespace PW3270_NAMESPACE; JNIEXPORT jstring JNICALL Java_pw3270_terminal_get_1version (JNIEnv *env, jobject obj) { - session *s = java::getHandle(env,obj); + session *s = getHandle(env,obj); return env->NewStringUTF(s->get_version().c_str()); } JNIEXPORT jstring JNICALL Java_pw3270_terminal_get_1revision(JNIEnv *env, jobject obj) { - session *s = java::getHandle(env,obj); + session *s = getHandle(env,obj); return env->NewStringUTF(s->get_revision().c_str()); } JNIEXPORT jstring JNICALL Java_pw3270_terminal_get_1encoding(JNIEnv *env, jobject obj) { - session *s = java::getHandle(env,obj); + session *s = getHandle(env,obj); return env->NewStringUTF(s->get_encoding()); } @@ -62,7 +62,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_get_1secure(JNIEnv *env, jobject obj try { - rc = java::getHandle(env,obj)->get_secure(); + rc = getHandle(env,obj)->get_secure(); } catch(std::exception &e) { diff --git a/src/jni/keyboard.cc b/src/jni/keyboard.cc index 2be700b..ee8ec78 100644 --- a/src/jni/keyboard.cc +++ b/src/jni/keyboard.cc @@ -40,7 +40,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_enter(JNIEnv *env, jobject obj) { try { - rc = java::getHandle(env,obj)->enter(); + rc = getHandle(env,obj)->enter(); } catch(std::exception &e) { @@ -59,7 +59,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_pfkey(JNIEnv *env, jobject obj, jint try { - rc = java::getHandle(env,obj)->pfkey((int) key); + rc = getHandle(env,obj)->pfkey((int) key); } catch(std::exception &e) { @@ -78,7 +78,7 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_pakey(JNIEnv *env, jobject obj, jint try { - rc = java::getHandle(env,obj)->pakey((int) key); + rc = getHandle(env,obj)->pakey((int) key); } catch(std::exception &e) { diff --git a/src/jni/main.cc b/src/jni/main.cc index c618e7d..f572c7d 100644 --- a/src/jni/main.cc +++ b/src/jni/main.cc @@ -30,25 +30,21 @@ #include "jni3270.h" #include "private.h" -/*---[ Implement ]----------------------------------------------------------------------------------*/ - -namespace PW3270_NAMESPACE { + using namespace PW3270_NAMESPACE; - jfieldID java::getHandleField(JNIEnv *env, jobject obj) { - jclass c = env->GetObjectClass(obj); - // J is the type signature for long: - return env->GetFieldID(c, "nativeHandle", "J"); - } - session * java::getHandle(JNIEnv *env, jobject obj) { - jlong handle = env->GetLongField(obj, getHandleField(env, obj)); - return reinterpret_cast(handle); - } +/*---[ Implement ]----------------------------------------------------------------------------------*/ +jfieldID getHandleField(JNIEnv *env, jobject obj) { + jclass c = env->GetObjectClass(obj); + // J is the type signature for long: + return env->GetFieldID(c, "nativeHandle", "J"); } -using namespace PW3270_NAMESPACE; -using namespace PW3270_NAMESPACE::java; +PW3270_NAMESPACE::session * getHandle(JNIEnv *env, jobject obj) { + jlong handle = env->GetLongField(obj, getHandleField(env, obj)); + return reinterpret_cast(handle); +} JNIEXPORT jint JNICALL Java_pw3270_terminal_init__(JNIEnv *env, jobject obj) { diff --git a/src/jni/private.h b/src/jni/private.h new file mode 100644 index 0000000..587b0a6 --- /dev/null +++ b/src/jni/private.h @@ -0,0 +1,41 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA, 02111-1307, USA + * + * Este programa está nomeado como private.h e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + #ifndef PRIVATE_H_INCLUDED + + #define PRIVATE_H_INCLUDED + + #include + #include + #include "jni3270.h" + + extern PW3270_NAMESPACE::session * getHandle(JNIEnv *env, jobject obj); + extern jfieldID getHandleField(JNIEnv *env, jobject obj); + +#endif // PRIVATE_H_INCLUDED diff --git a/src/jni/startstop.cc b/src/jni/startstop.cc deleted file mode 100644 index 67a75c6..0000000 --- a/src/jni/startstop.cc +++ /dev/null @@ -1,419 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA, 02111-1307, USA - * - * Este programa está nomeado como startstop.cc e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - -#if defined WIN32 - - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx - #ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS - #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 - #endif // LOAD_LIBRARY_SEARCH_DEFAULT_DIRS - - #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR - #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 - #endif // LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR - - #include - -#else - - #include - -#endif - - #include "private.h" - - #include - #include - #include - #include - #include - #include - #include - #include - #include - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - -using namespace PW3270_NAMESPACE::java; - -extern "C" { - - static void trace_cleanup(GtkWidget *widget, GtkWidget **window) { - *window = NULL; - } - - static jint JNICALL jni_vfprintf(FILE *fp, const char *fmt, va_list args) { - - char * msg = NULL; - static GtkWidget * trace = NULL; - - if(vasprintf(&msg,fmt,args) < 1) { - lib3270_write_log(lib3270_get_default_session_handle(),"java","vasprintf() error on \"%s\"",fmt); - return 0; - } - - fprintf(fp,"%s",msg); - lib3270_write_log(lib3270_get_default_session_handle(),"java","%s",msg); - - if(!trace) { - // Cria janela de trace. - trace = pw3270_trace_new(); - g_signal_connect(G_OBJECT(trace), "destroy",G_CALLBACK(trace_cleanup), &trace); - - pw3270_trace_set_destroy_on_close(trace,TRUE); - - // gtk_window_set_transient_for(GTK_WINDOW(trace),GTK_WINDOW(gtk_widget_get_toplevel(widget))); - gtk_window_set_destroy_with_parent(GTK_WINDOW(trace),TRUE); - - gtk_window_set_default_size(GTK_WINDOW(trace),590,430); - gtk_widget_show_all(trace); - - pw3270_trace_printf(trace,"%s",msg); - - free(msg); - } - - return 0; - } - - LIB3270_EXPORT void pw3270_action_java_activated(GtkAction *action, GtkWidget *widget) { - - gchar *classname = (gchar *) g_object_get_data(G_OBJECT(action),"src"); - - lib3270_trace_event(v3270_get_session(widget),"Action %s activated on widget %p\n",gtk_action_get_name(action),widget); - - if(classname) - { - // Has filename, call it directly - call(widget,classname); - } - else - { -/* - // No classname, ask user - filename = pw3270_file_chooser(GTK_FILE_CHOOSER_ACTION_OPEN, "java", _( "Select script to run" ), "", "class"); - - if(filename) - { - call(widget,filename); - g_free(filename); - } -*/ - } - - } - } - - - namespace PW3270_NAMESPACE { - - JavaVM * java::jvm = NULL; - JNIEnv * java::env = NULL; -#ifdef _WIN32 - HMODULE java::hModule = NULL; -#endif // _WIN32 - - void java::failed(GtkWidget *widget, const char *msg, const char *format, ...) { - - GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK_CANCEL, - "%s", msg ); - - gtk_window_set_title(GTK_WINDOW(dialog), _( "Java error" )); - - if(format) { - - va_list arg_ptr; - va_start(arg_ptr, format); - gchar *msg = g_strdup_vprintf(format,arg_ptr); - va_end(arg_ptr); - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s",msg); - g_free(msg); - - } - - if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) - gtk_main_quit(); - gtk_widget_destroy(dialog); - - } - - -#ifdef WIN32 - - bool java::load_jvm(GtkWidget *widget) { - - if(jvm != NULL) { - return true; - } - - // Dynamically load jvm library to avoid naming and path problems. - HMODULE kernel; - HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory); - BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie); - - struct _dlldir { - const gchar * env; - const gchar * path; - HANDLE cookie; - } dlldir[] = { - { "JRE_HOME", "bin\\client", 0 }, - { "JDK_HOME", "jre\\bin\\client", 0 } - }; - - kernel = LoadLibrary("kernel32.dll"); - - if(kernel) { - - AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory"); - if(AddDllDirectory) { - - // Acrescenta mais caminhos para achar a dll - for(size_t f = 0; f < G_N_ELEMENTS(dlldir); f++) { - - const char *env = getenv(dlldir[f].env); - - debug("%s=\"%s\"",dlldir[f].env,env); - - if(env) { - - gchar *p = g_build_filename(env,dlldir[f].path,NULL); - - lib3270_trace_event(v3270_get_session(widget),"Adding \"%s\" to DLL search path",p); - - wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t)); - mbstowcs(path, p, 4095); - dlldir[f].cookie = AddDllDirectory(path); - free(path); - - g_free(p); - - } - } - - } else { - - lib3270_trace_event(v3270_get_session(widget),"Can't find %s: %s","AddDllDirectory",session::win32_strerror(GetLastError()).c_str()); - - } - - } else { - - lib3270_trace_event(v3270_get_session(widget),"Can't load %s: %s\n","kernel32.dll",session::win32_strerror(GetLastError()).c_str()); - - } - - hModule = LoadLibrary("jvm.dll"); - if(!hModule) { - lib3270_trace_event(v3270_get_session(widget),"Can't load %s\n","jvm.dll",session::win32_strerror(GetLastError()).c_str()); - - for(size_t f = 0; !hModule && f < G_N_ELEMENTS(dlldir); f++) { - - const char *env = getenv(dlldir[f].env); - - debug("%s=\"%s\"",dlldir[f].env,env); - - if(env) { - - gchar *p = g_build_filename(env,dlldir[f].path,"jvm.dll",NULL); - hModule = LoadLibrary(p); - if(!hModule) { - lib3270_trace_event(v3270_get_session(widget),"Can't load %s: %s\n",p,session::win32_strerror(GetLastError()).c_str()); - } - g_free(p); - - } - } - } - - if(!hModule) { - failed(widget, _( "Can't load java virtual machine" ), "%s", session::win32_strerror(GetLastError()).c_str()); - } - - if(kernel) { - - RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory"); - if(RemoveDllDirectory) { - - for(size_t f = 0; f < G_N_ELEMENTS(dlldir); f++) { - - if(dlldir[f].cookie) { - - RemoveDllDirectory(dlldir[f].cookie); - - } - } - - } - - FreeLibrary(kernel); - - } - - if(!hModule) { - return false; - } - - // Consegui carregar a JVM, obtenho o método de controle - jint JNICALL (*CreateJavaVM)(JavaVM **, void **, void *) = (jint JNICALL (*)(JavaVM **, void **, void *)) GetProcAddress(hModule,"JNI_CreateJavaVM"); - - if(!CreateJavaVM) { - failed(widget, _( "Can't load java virtual machine creation method" ), "%s", session::win32_strerror(GetLastError()).c_str()); - return false; - } - - // Crio a JVM - JavaVMInitArgs vm_args; - JavaVMOption options[5]; - - jint rc = 0; - - memset(&vm_args,0,sizeof(vm_args)); - memset(options,0,sizeof(options)); - - vm_args.version = JNI_VERSION_1_4; - vm_args.nOptions = 0; - vm_args.options = options; - vm_args.ignoreUnrecognized = JNI_FALSE; - - options[vm_args.nOptions].optionString = g_strdup("vfprintf"); - options[vm_args.nOptions].extraInfo = (void *) jni_vfprintf; - vm_args.nOptions++; - - gchar * exports = NULL; - char buffer[1024]; - gchar * myDir; - - if(GetModuleFileName(NULL,buffer,sizeof(buffer)) < sizeof(buffer)) { - - gchar * ptr = strrchr(buffer,G_DIR_SEPARATOR); - if(ptr) { - *ptr = 0; - myDir = g_strdup(buffer); - } else { - myDir = g_strdup("."); - } - - - } else { - - myDir = g_strdup("."); - - } - - debug("myDir=%s",myDir); - - exports = g_build_filename(myDir,"jvm-exports",NULL); - g_mkdir_with_parents(exports,0777); - - lib3270_trace_event(v3270_get_session(widget),"java.class.path=%s",exports); - lib3270_trace_event(v3270_get_session(widget),"java.library.path=%s",myDir); - - options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.class.path=%s",exports); - options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.library.path=%s",myDir); - - g_free(myDir); - g_free(exports); - - rc = CreateJavaVM(&jvm,(void **)&env,&vm_args); - if(rc < 0) { - failed(widget, _( "Can't create java VM" ), _( "The error code was %d" ), (int) rc); - jvm = NULL; - } - - for(int f=0;f + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA, 02111-1307, USA + * + * Este programa está nomeado como call.cc e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + + #include "private.h" + #include + #include + #include + + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + +namespace PW3270_NAMESPACE { + + + void java::call(GtkWidget *widget, const char *classname) { + + debug("%s(%s)",__FUNCTION__,classname); + + if(!trylock()) { + + failed(widget, _( "Can't access java virtual machine" ), "%s", strerror(EBUSY)); + return; + + } + + if(jvm || load_jvm(widget)) { + + v3270_set_script(widget,'J',TRUE); + + try { + + jclass cls; + jmethodID mid; + + /* + + DONT WORK!! + http://stackoverflow.com/questions/271506/why-cant-system-setproperty-change-the-classpath-at-runtime + + // Atualizar o classpath + cls = env->FindClass("java/lang/System"); + if(!cls) { + throw exception( _( "Can't find class %s" ), "java/lang/System"); + } + + mid = env->GetStaticMethodID(cls, "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); + if(!mid) { + throw exception( _( "Can't find method %s/%s" ), "java/lang/System","setProperty"); + } + + lib3270_trace_event(v3270_get_session(widget),"java.class.path=%s\n",classpath); + + jstring name = env->NewStringUTF("java.class.path"); + jstring path = env->NewStringUTF(classpath); + + jstring rc = (jstring) env->CallObjectMethod(cls,mid,name,path); + + env->DeleteLocalRef(name); + env->DeleteLocalRef(path); + env->DeleteLocalRef(rc); + */ + + // Get application entry point. + cls = env->FindClass(classname); + if(!cls) { + throw exception( _( "Can't find class %s" ), classname); + } + + mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); + if(!mid) { + throw exception( _( "Can't find method %s/%s" ), classname, "main"); + } + + // Build arguments + jobjectArray args = env->NewObjectArray(0, env->FindClass("java/lang/String"), env->NewStringUTF("")); + + // Call main() + env->CallStaticVoidMethod(cls, mid, args); + + // Check for exception + jthrowable exc = env->ExceptionOccurred(); + env->ExceptionClear(); + + if (exc) { + jclass throwable_class = env->FindClass("java/lang/Throwable"); + + jmethodID jni_getMessage = env->GetMethodID(throwable_class,"getMessage","()Ljava/lang/String;"); + jstring j_msg = (jstring) env->CallObjectMethod(exc,jni_getMessage); + + GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK_CANCEL, + _( "Java application \"%s\" has failed." ), classname ); + + gtk_window_set_title(GTK_WINDOW(dialog), _( "Java error" )); + + if(!env->IsSameObject(j_msg,NULL)) { + + const char * msg = env->GetStringUTFChars(j_msg, 0); + + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s",msg); + + env->ReleaseStringUTFChars( j_msg, msg); + } + + if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) + gtk_main_quit(); + gtk_widget_destroy(dialog); + + + } + + // And finish + env->DeleteLocalRef(args); + + } catch(std::exception &e) { + + failed(widget,_("Can't start java application"),"%s", e.what()); + + } + +/* + g_free(dirname); + g_free(classname); + g_free(classpath); +*/ + + v3270_set_script(widget,'J',FALSE); + + } + + unlock(); + + + } + +} diff --git a/src/plugin/startstop.cc b/src/plugin/startstop.cc new file mode 100644 index 0000000..67a75c6 --- /dev/null +++ b/src/plugin/startstop.cc @@ -0,0 +1,419 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA, 02111-1307, USA + * + * Este programa está nomeado como startstop.cc e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +#if defined WIN32 + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx + #ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS + #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 + #endif // LOAD_LIBRARY_SEARCH_DEFAULT_DIRS + + #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR + #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 + #endif // LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR + + #include + +#else + + #include + +#endif + + #include "private.h" + + #include + #include + #include + #include + #include + #include + #include + #include + #include + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + +using namespace PW3270_NAMESPACE::java; + +extern "C" { + + static void trace_cleanup(GtkWidget *widget, GtkWidget **window) { + *window = NULL; + } + + static jint JNICALL jni_vfprintf(FILE *fp, const char *fmt, va_list args) { + + char * msg = NULL; + static GtkWidget * trace = NULL; + + if(vasprintf(&msg,fmt,args) < 1) { + lib3270_write_log(lib3270_get_default_session_handle(),"java","vasprintf() error on \"%s\"",fmt); + return 0; + } + + fprintf(fp,"%s",msg); + lib3270_write_log(lib3270_get_default_session_handle(),"java","%s",msg); + + if(!trace) { + // Cria janela de trace. + trace = pw3270_trace_new(); + g_signal_connect(G_OBJECT(trace), "destroy",G_CALLBACK(trace_cleanup), &trace); + + pw3270_trace_set_destroy_on_close(trace,TRUE); + + // gtk_window_set_transient_for(GTK_WINDOW(trace),GTK_WINDOW(gtk_widget_get_toplevel(widget))); + gtk_window_set_destroy_with_parent(GTK_WINDOW(trace),TRUE); + + gtk_window_set_default_size(GTK_WINDOW(trace),590,430); + gtk_widget_show_all(trace); + + pw3270_trace_printf(trace,"%s",msg); + + free(msg); + } + + return 0; + } + + LIB3270_EXPORT void pw3270_action_java_activated(GtkAction *action, GtkWidget *widget) { + + gchar *classname = (gchar *) g_object_get_data(G_OBJECT(action),"src"); + + lib3270_trace_event(v3270_get_session(widget),"Action %s activated on widget %p\n",gtk_action_get_name(action),widget); + + if(classname) + { + // Has filename, call it directly + call(widget,classname); + } + else + { +/* + // No classname, ask user + filename = pw3270_file_chooser(GTK_FILE_CHOOSER_ACTION_OPEN, "java", _( "Select script to run" ), "", "class"); + + if(filename) + { + call(widget,filename); + g_free(filename); + } +*/ + } + + } + } + + + namespace PW3270_NAMESPACE { + + JavaVM * java::jvm = NULL; + JNIEnv * java::env = NULL; +#ifdef _WIN32 + HMODULE java::hModule = NULL; +#endif // _WIN32 + + void java::failed(GtkWidget *widget, const char *msg, const char *format, ...) { + + GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK_CANCEL, + "%s", msg ); + + gtk_window_set_title(GTK_WINDOW(dialog), _( "Java error" )); + + if(format) { + + va_list arg_ptr; + va_start(arg_ptr, format); + gchar *msg = g_strdup_vprintf(format,arg_ptr); + va_end(arg_ptr); + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s",msg); + g_free(msg); + + } + + if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) + gtk_main_quit(); + gtk_widget_destroy(dialog); + + } + + +#ifdef WIN32 + + bool java::load_jvm(GtkWidget *widget) { + + if(jvm != NULL) { + return true; + } + + // Dynamically load jvm library to avoid naming and path problems. + HMODULE kernel; + HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory); + BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie); + + struct _dlldir { + const gchar * env; + const gchar * path; + HANDLE cookie; + } dlldir[] = { + { "JRE_HOME", "bin\\client", 0 }, + { "JDK_HOME", "jre\\bin\\client", 0 } + }; + + kernel = LoadLibrary("kernel32.dll"); + + if(kernel) { + + AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory"); + if(AddDllDirectory) { + + // Acrescenta mais caminhos para achar a dll + for(size_t f = 0; f < G_N_ELEMENTS(dlldir); f++) { + + const char *env = getenv(dlldir[f].env); + + debug("%s=\"%s\"",dlldir[f].env,env); + + if(env) { + + gchar *p = g_build_filename(env,dlldir[f].path,NULL); + + lib3270_trace_event(v3270_get_session(widget),"Adding \"%s\" to DLL search path",p); + + wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t)); + mbstowcs(path, p, 4095); + dlldir[f].cookie = AddDllDirectory(path); + free(path); + + g_free(p); + + } + } + + } else { + + lib3270_trace_event(v3270_get_session(widget),"Can't find %s: %s","AddDllDirectory",session::win32_strerror(GetLastError()).c_str()); + + } + + } else { + + lib3270_trace_event(v3270_get_session(widget),"Can't load %s: %s\n","kernel32.dll",session::win32_strerror(GetLastError()).c_str()); + + } + + hModule = LoadLibrary("jvm.dll"); + if(!hModule) { + lib3270_trace_event(v3270_get_session(widget),"Can't load %s\n","jvm.dll",session::win32_strerror(GetLastError()).c_str()); + + for(size_t f = 0; !hModule && f < G_N_ELEMENTS(dlldir); f++) { + + const char *env = getenv(dlldir[f].env); + + debug("%s=\"%s\"",dlldir[f].env,env); + + if(env) { + + gchar *p = g_build_filename(env,dlldir[f].path,"jvm.dll",NULL); + hModule = LoadLibrary(p); + if(!hModule) { + lib3270_trace_event(v3270_get_session(widget),"Can't load %s: %s\n",p,session::win32_strerror(GetLastError()).c_str()); + } + g_free(p); + + } + } + } + + if(!hModule) { + failed(widget, _( "Can't load java virtual machine" ), "%s", session::win32_strerror(GetLastError()).c_str()); + } + + if(kernel) { + + RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory"); + if(RemoveDllDirectory) { + + for(size_t f = 0; f < G_N_ELEMENTS(dlldir); f++) { + + if(dlldir[f].cookie) { + + RemoveDllDirectory(dlldir[f].cookie); + + } + } + + } + + FreeLibrary(kernel); + + } + + if(!hModule) { + return false; + } + + // Consegui carregar a JVM, obtenho o método de controle + jint JNICALL (*CreateJavaVM)(JavaVM **, void **, void *) = (jint JNICALL (*)(JavaVM **, void **, void *)) GetProcAddress(hModule,"JNI_CreateJavaVM"); + + if(!CreateJavaVM) { + failed(widget, _( "Can't load java virtual machine creation method" ), "%s", session::win32_strerror(GetLastError()).c_str()); + return false; + } + + // Crio a JVM + JavaVMInitArgs vm_args; + JavaVMOption options[5]; + + jint rc = 0; + + memset(&vm_args,0,sizeof(vm_args)); + memset(options,0,sizeof(options)); + + vm_args.version = JNI_VERSION_1_4; + vm_args.nOptions = 0; + vm_args.options = options; + vm_args.ignoreUnrecognized = JNI_FALSE; + + options[vm_args.nOptions].optionString = g_strdup("vfprintf"); + options[vm_args.nOptions].extraInfo = (void *) jni_vfprintf; + vm_args.nOptions++; + + gchar * exports = NULL; + char buffer[1024]; + gchar * myDir; + + if(GetModuleFileName(NULL,buffer,sizeof(buffer)) < sizeof(buffer)) { + + gchar * ptr = strrchr(buffer,G_DIR_SEPARATOR); + if(ptr) { + *ptr = 0; + myDir = g_strdup(buffer); + } else { + myDir = g_strdup("."); + } + + + } else { + + myDir = g_strdup("."); + + } + + debug("myDir=%s",myDir); + + exports = g_build_filename(myDir,"jvm-exports",NULL); + g_mkdir_with_parents(exports,0777); + + lib3270_trace_event(v3270_get_session(widget),"java.class.path=%s",exports); + lib3270_trace_event(v3270_get_session(widget),"java.library.path=%s",myDir); + + options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.class.path=%s",exports); + options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.library.path=%s",myDir); + + g_free(myDir); + g_free(exports); + + rc = CreateJavaVM(&jvm,(void **)&env,&vm_args); + if(rc < 0) { + failed(widget, _( "Can't create java VM" ), _( "The error code was %d" ), (int) rc); + jvm = NULL; + } + + for(int f=0;f