Commit 1ab298e60634a793d0ea633c422ac2fa028fb6a6
1 parent
5555ae85
Exists in
master
and in
5 other branches
Separando star/stop da jvm da classe de plugin para facilitar
Showing
5 changed files
with
592 additions
and
521 deletions
Show diff stats
src/java/Makefile.in
... | ... | @@ -26,7 +26,7 @@ |
26 | 26 | |
27 | 27 | PACKAGE_NAME=@PACKAGE_NAME@ |
28 | 28 | SOURCES=main.cc info.cc connect.cc getset.cc cursor.cc keyboard.cc actions.cc field.cc dialog.cc clipboard.cc |
29 | -PLUGIN_SRC=plugin.cc | |
29 | +PLUGIN_SRC=plugin.cc startstop.cc | |
30 | 30 | |
31 | 31 | #---[ Paths ]------------------------------------------------------------------ |
32 | 32 | ... | ... |
src/java/jni3270.cbp
src/java/plugin.cc
... | ... | @@ -325,528 +325,10 @@ |
325 | 325 | |
326 | 326 | extern "C" { |
327 | 327 | |
328 | - static session * factory(const char *name) { | |
328 | + session * factory(const char *name) { | |
329 | 329 | debug("---> %s",__FUNCTION__); |
330 | 330 | return new plugin(lib3270_get_default_session_handle()); |
331 | 331 | } |
332 | 332 | |
333 | - static void trace_cleanup(GtkWidget *widget, GtkWidget **window) { | |
334 | - *window = NULL; | |
335 | - } | |
336 | - | |
337 | - static jint JNICALL jni_vfprintf(FILE *fp, const char *fmt, va_list args) { | |
338 | - | |
339 | - char * msg = NULL; | |
340 | - static GtkWidget * trace = NULL; | |
341 | - | |
342 | - if(vasprintf(&msg,fmt,args) < 1) { | |
343 | - lib3270_write_log(lib3270_get_default_session_handle(),"java","vasprintf() error on \"%s\"",fmt); | |
344 | - return 0; | |
345 | - } | |
346 | - | |
347 | - fprintf(fp,"%s",msg); | |
348 | - lib3270_write_log(lib3270_get_default_session_handle(),"java","%s",msg); | |
349 | - | |
350 | - if(!trace) { | |
351 | - // Cria janela de trace. | |
352 | - trace = pw3270_trace_new(); | |
353 | - g_signal_connect(G_OBJECT(trace), "destroy",G_CALLBACK(trace_cleanup), &trace); | |
354 | - | |
355 | - pw3270_trace_set_destroy_on_close(trace,TRUE); | |
356 | - | |
357 | - // gtk_window_set_transient_for(GTK_WINDOW(trace),GTK_WINDOW(gtk_widget_get_toplevel(widget))); | |
358 | - gtk_window_set_destroy_with_parent(GTK_WINDOW(trace),TRUE); | |
359 | - | |
360 | - gtk_window_set_default_size(GTK_WINDOW(trace),590,430); | |
361 | - gtk_widget_show_all(trace); | |
362 | - | |
363 | - pw3270_trace_printf(trace,"%s",msg); | |
364 | - | |
365 | - free(msg); | |
366 | - } | |
367 | - | |
368 | - return 0; | |
369 | - } | |
370 | - | |
371 | -} | |
372 | - | |
373 | -#ifdef _WIN32 | |
374 | - /* | |
375 | - * Dynamically load jvm to avoid naming and path problems | |
376 | - * | |
377 | - */ | |
378 | - static void load_jvm(GtkWidget *widget, HMODULE &hModule) { | |
379 | - | |
380 | - // Dynamically load jvm library to avoid naming and path problems. | |
381 | - HMODULE kernel; | |
382 | - HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory); | |
383 | - BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie); | |
384 | - | |
385 | - struct _dlldir { | |
386 | - const gchar * env; | |
387 | - const gchar * path; | |
388 | - HANDLE cookie; | |
389 | - } dlldir[] = { | |
390 | - { "JRE_HOME", "bin\\client", 0 }, | |
391 | - { "JDK_HOME", "jre\\bin\\client", 0 } | |
392 | - }; | |
393 | - | |
394 | - kernel = LoadLibrary("kernel32.dll"); | |
395 | - | |
396 | - debug("---[ %s ]---------------------------------------------------",__FUNCTION__); | |
397 | - | |
398 | - AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory"); | |
399 | - if(AddDllDirectory) { | |
400 | - | |
401 | - // Acrescenta mais caminhos para achar a dll | |
402 | - for(size_t f = 0; f < G_N_ELEMENTS(dlldir); f++) { | |
403 | - | |
404 | - const char *env = getenv(dlldir[f].env); | |
405 | - | |
406 | - debug("%s=\"%s\"",dlldir[f].env,env); | |
407 | - | |
408 | - if(env) { | |
409 | - | |
410 | - gchar *p = g_build_filename(env,dlldir[f].path,NULL); | |
411 | - | |
412 | - debug("Adicionando diretório \"%s\"",p); | |
413 | - | |
414 | - wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t)); | |
415 | - mbstowcs(path, p, 4095); | |
416 | - dlldir[f].cookie = AddDllDirectory(path); | |
417 | - free(path); | |
418 | - | |
419 | - g_free(p); | |
420 | - | |
421 | - } | |
422 | - } | |
423 | - | |
424 | - } | |
425 | -#ifdef DEBUG | |
426 | - else { | |
427 | - debug("Can't get %s: %s","AddDllDirectory",session::win32_strerror(GetLastError()).c_str()) | |
428 | - } | |
429 | -#endif // DEBUG | |
430 | - | |
431 | - hModule = LoadLibrary("jvm.dll"); | |
432 | - | |
433 | - debug("hModule=%08lx",(long) hModule); | |
434 | - | |
435 | - if(!hModule) { | |
436 | - | |
437 | - DWORD err = GetLastError(); | |
438 | - | |
439 | - debug("%s",session::win32_strerror(err).c_str()); | |
440 | - | |
441 | - GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
442 | - GTK_DIALOG_DESTROY_WITH_PARENT, | |
443 | - GTK_MESSAGE_ERROR, | |
444 | - GTK_BUTTONS_CANCEL, | |
445 | - "%s", _( "Can't load java virtual machine" ) ); | |
446 | - | |
447 | - gtk_window_set_title(GTK_WINDOW(dialog),_( "JVM error" )); | |
448 | - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s", session::win32_strerror(err).c_str()); | |
449 | - | |
450 | - gtk_dialog_run(GTK_DIALOG (dialog)); | |
451 | - gtk_widget_destroy(dialog); | |
452 | - | |
453 | - } | |
454 | - | |
455 | - // Libera caminhos extras. | |
456 | - RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory"); | |
457 | - if(RemoveDllDirectory) { | |
458 | - | |
459 | - for(size_t f = 0; f < G_N_ELEMENTS(dlldir); f++) { | |
460 | - | |
461 | - if(dlldir[f].cookie) { | |
462 | - | |
463 | - RemoveDllDirectory(dlldir[f].cookie); | |
464 | - | |
465 | - } | |
466 | - } | |
467 | - | |
468 | - } | |
469 | -#ifdef DEBUG | |
470 | - else { | |
471 | - debug("Can't get %s: %s","RemoveDllDirectory",session::win32_strerror(GetLastError()).c_str()) | |
472 | - } | |
473 | -#endif // DEBUG | |
474 | - | |
475 | - FreeLibrary(kernel); | |
476 | - | |
477 | - } | |
478 | - | |
479 | - | |
480 | -#endif // _WIN32 | |
481 | - | |
482 | - | |
483 | - LIB3270_EXPORT int pw3270_plugin_start(GtkWidget *window) | |
484 | - { | |
485 | - trace("JAVA: %s",__FUNCTION__); | |
486 | -#if GTK_CHECK_VERSION(2,32,0) | |
487 | - g_mutex_init(&mutex); | |
488 | -#endif // GTK_CHECK_VERSION | |
489 | - set_java_session_factory(factory); | |
490 | - return 0; | |
491 | - } | |
492 | - | |
493 | - LIB3270_EXPORT int pw3270_plugin_stop(GtkWidget *window) | |
494 | - { | |
495 | -#if GTK_CHECK_VERSION(2,32,0) | |
496 | - g_mutex_clear(&mutex); | |
497 | -#endif // GTK_CHECK_VERSION | |
498 | - trace("JAVA: %s",__FUNCTION__); | |
499 | - return 0; | |
500 | - } | |
501 | - | |
502 | -extern "C" | |
503 | -{ | |
504 | - | |
505 | - void call_java_program(GtkAction *action, GtkWidget *widget, const gchar *filename) | |
506 | - { | |
507 | - | |
508 | -#if GTK_CHECK_VERSION(2,32,0) | |
509 | - if(!g_mutex_trylock(&mutex)) { | |
510 | -#else | |
511 | - if(!g_static_mutex_trylock(&mutex)) { | |
512 | -#endif // GTK_CHECK_VERSION | |
513 | - | |
514 | - GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
515 | - GTK_DIALOG_DESTROY_WITH_PARENT, | |
516 | - GTK_MESSAGE_ERROR, | |
517 | - GTK_BUTTONS_CANCEL, | |
518 | - _( "Can't start %s program" ), "java" ); | |
519 | - | |
520 | - gtk_window_set_title(GTK_WINDOW(dialog),_( "JVM busy" )); | |
521 | - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),_( "%s interpreter is busy" ), "java"); | |
522 | - | |
523 | - gtk_dialog_run(GTK_DIALOG (dialog)); | |
524 | - gtk_widget_destroy(dialog); | |
525 | - | |
526 | - return; | |
527 | - } | |
528 | - | |
529 | - v3270_set_script(widget,'J',TRUE); | |
530 | - | |
531 | -#ifdef _WIN32 | |
532 | - | |
533 | - HMODULE hJVM = 0; | |
534 | - | |
535 | - load_jvm(widget,hJVM); | |
536 | - | |
537 | - debug("hJVM=%p",hJVM); | |
538 | - | |
539 | - if(!hJVM) { | |
540 | - v3270_set_script(widget,'J',FALSE); | |
541 | - | |
542 | -#if GTK_CHECK_VERSION(2,32,0) | |
543 | - g_mutex_unlock(&mutex); | |
544 | -#else | |
545 | - g_static_mutex_unlock(&mutex); | |
546 | -#endif // GTK_CHECK_VERSION | |
547 | - | |
548 | - return; | |
549 | - | |
550 | - } | |
551 | - | |
552 | -#endif // _WIN32 | |
553 | - | |
554 | - debug("%s",__FUNCTION__); | |
555 | - | |
556 | - // Start JNI | |
557 | - JavaVMInitArgs vm_args; | |
558 | - JavaVMOption options[5]; | |
559 | - | |
560 | - JavaVM * jvm = NULL; | |
561 | - JNIEnv * env = NULL; | |
562 | - jint rc = 0; | |
563 | - | |
564 | - memset(&vm_args,0,sizeof(vm_args)); | |
565 | - memset(options,0,sizeof(options)); | |
566 | - | |
567 | - vm_args.version = JNI_VERSION_1_4; | |
568 | - vm_args.nOptions = 0; | |
569 | - vm_args.options = options; | |
570 | - vm_args.ignoreUnrecognized = JNI_FALSE; | |
571 | - | |
572 | - options[vm_args.nOptions].optionString = g_strdup("vfprintf"); | |
573 | - options[vm_args.nOptions].extraInfo = (void *) jni_vfprintf; | |
574 | - vm_args.nOptions++; | |
575 | - | |
576 | -//#ifdef DEBUG | |
577 | -// options[vm_args.nOptions++].optionString = g_strdup("-verbose"); | |
578 | -//#endif | |
579 | - | |
580 | - gchar * dirname = g_path_get_dirname(filename); | |
581 | - | |
582 | - debug("Dirname=%s",dirname); | |
583 | - | |
584 | -#if defined( WIN32 ) | |
585 | - | |
586 | - gchar * exports = NULL; | |
587 | - char buffer[1024]; | |
588 | - gchar * myDir; | |
589 | - | |
590 | - if(GetModuleFileName(NULL,buffer,sizeof(buffer)) < sizeof(buffer)) { | |
591 | - | |
592 | - gchar * ptr = strrchr(buffer,G_DIR_SEPARATOR); | |
593 | - if(ptr) { | |
594 | - *ptr = 0; | |
595 | - myDir = g_strdup(buffer); | |
596 | - } else { | |
597 | - myDir = g_strdup("."); | |
598 | - } | |
599 | - | |
600 | - | |
601 | - } else { | |
602 | - | |
603 | - myDir = g_strdup("."); | |
604 | - | |
605 | - } | |
606 | - | |
607 | - debug("myDir=%s",myDir); | |
608 | - | |
609 | - exports = g_build_filename(myDir,"jvm-exports",NULL); | |
610 | - g_mkdir_with_parents(exports,0777); | |
611 | - | |
612 | - lib3270_trace_event(v3270_get_session(widget),"java.class.path=%s;%s",dirname,exports); | |
613 | - lib3270_trace_event(v3270_get_session(widget),"java.library.path=%s",myDir); | |
614 | - | |
615 | - options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.library.path=%s",myDir); | |
616 | - options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.class.path=%s;%s",dirname,exports); | |
617 | - | |
618 | - g_free(myDir); | |
619 | - g_free(exports); | |
620 | - | |
621 | - // Windows, first find the method, then call it. | |
622 | - jint JNICALL (*CreateJavaVM)(JavaVM **, void **, void *) = (jint JNICALL (*)(JavaVM **, void **, void *)) GetProcAddress(hJVM,"JNI_CreateJavaVM"); | |
623 | - | |
624 | - if(!CreateJavaVM) { | |
625 | - rc = ENOENT; | |
626 | - } else { | |
627 | - debug("Calling %s","CreateJavaVM"); | |
628 | - rc = CreateJavaVM(&jvm,(void **)&env,&vm_args); | |
629 | - debug("%s exits with rc=%d","CreateJavaVM",rc); | |
630 | - } | |
631 | - | |
632 | -#else | |
633 | - | |
634 | -#if defined(DEBUG) | |
635 | - options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.library.path=%s:.bin/Debug:.bin/Debug/lib",JNIDIR); | |
636 | - options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.class.path=%s:%s:./src/java/.bin/java",JARDIR,dirname); | |
637 | -#else | |
638 | - options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.library.path=%s",JNIDIR); | |
639 | - options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.class.path=%s:%s",JARDIR,dirname); | |
640 | -#endif // JNIDIR | |
641 | - | |
642 | - // Linux, just create JVM | |
643 | - rc = JNI_CreateJavaVM(&jvm,(void **)&env,&vm_args); | |
644 | - | |
645 | -#endif // _WIn32 | |
646 | - | |
647 | - debug("JNI_CreateJavaVM exits with rc=%d",rc); | |
648 | - | |
649 | - g_free(dirname); | |
650 | - | |
651 | - | |
652 | - // Release options | |
653 | - for(int f=0;f<vm_args.nOptions;f++) { | |
654 | - trace("Releasing option %d: %s",f,options[f].optionString); | |
655 | - g_free(options[f].optionString); | |
656 | - } | |
657 | - | |
658 | - if(rc < 0) { | |
659 | - | |
660 | - GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
661 | - GTK_DIALOG_DESTROY_WITH_PARENT, | |
662 | - GTK_MESSAGE_ERROR, | |
663 | - GTK_BUTTONS_CANCEL, | |
664 | - "%s", _( "Can't create java VM" )); | |
665 | - | |
666 | - gtk_window_set_title(GTK_WINDOW(dialog), _( "Script startup failure" )); | |
667 | - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),_( "The error code was %d" ), (int) rc); | |
668 | - | |
669 | - gtk_dialog_run(GTK_DIALOG (dialog)); | |
670 | - gtk_widget_destroy(dialog); | |
671 | - | |
672 | - } else { | |
673 | - | |
674 | - gchar * classname = g_path_get_basename(filename); | |
675 | - | |
676 | - gchar * ptr = strchr(classname,'.'); | |
677 | - if(ptr) { | |
678 | - *ptr = 0; | |
679 | - } | |
680 | - | |
681 | - jclass cls = env->FindClass(classname); | |
682 | - | |
683 | - if(cls == 0) { | |
684 | - | |
685 | - GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
686 | - GTK_DIALOG_DESTROY_WITH_PARENT, | |
687 | - GTK_MESSAGE_ERROR, | |
688 | - GTK_BUTTONS_CANCEL, | |
689 | - _( "Can't find class %s" ), classname ); | |
690 | - | |
691 | - gtk_window_set_title(GTK_WINDOW(dialog), _( "Java error" )); | |
692 | - if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) | |
693 | - gtk_main_quit(); | |
694 | - gtk_widget_destroy(dialog); | |
695 | - | |
696 | - } else { | |
697 | - | |
698 | - jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); | |
699 | - | |
700 | - if(mid == 0) { | |
701 | - | |
702 | - GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
703 | - GTK_DIALOG_DESTROY_WITH_PARENT, | |
704 | - GTK_MESSAGE_ERROR, | |
705 | - GTK_BUTTONS_OK_CANCEL, | |
706 | - _( "Can't find class \"%s\"" ), classname ); | |
707 | - | |
708 | - gtk_window_set_title(GTK_WINDOW(dialog), _( "Java error" )); | |
709 | - | |
710 | - if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) | |
711 | - gtk_main_quit(); | |
712 | - gtk_widget_destroy(dialog); | |
713 | - | |
714 | - } else { | |
715 | - | |
716 | - jobjectArray args = env->NewObjectArray(0, env->FindClass("java/lang/String"), env->NewStringUTF("")); | |
717 | - | |
718 | - try { | |
719 | - | |
720 | - debug("%s: Calling CallStaticVoidMethod()",__FUNCTION__); | |
721 | - env->CallStaticVoidMethod(cls, mid, args); | |
722 | - debug("%s: CallStaticVoidMethod() has returned",__FUNCTION__); | |
723 | - | |
724 | - jthrowable exc = env->ExceptionOccurred(); | |
725 | - env->ExceptionClear(); | |
726 | - | |
727 | - if (exc) { | |
728 | - jclass throwable_class = env->FindClass("java/lang/Throwable"); | |
729 | - | |
730 | - jmethodID jni_getMessage = env->GetMethodID(throwable_class,"getMessage","()Ljava/lang/String;"); | |
731 | - jstring j_msg = (jstring) env->CallObjectMethod(exc,jni_getMessage); | |
732 | - | |
733 | - GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
734 | - GTK_DIALOG_DESTROY_WITH_PARENT, | |
735 | - GTK_MESSAGE_ERROR, | |
736 | - GTK_BUTTONS_OK_CANCEL, | |
737 | - _( "Java application \"%s\" has failed." ), classname ); | |
738 | - | |
739 | - gtk_window_set_title(GTK_WINDOW(dialog), _( "Java failure" )); | |
740 | - | |
741 | - if(!env->IsSameObject(j_msg,NULL)) { | |
742 | - | |
743 | - const char * msg = env->GetStringUTFChars(j_msg, 0); | |
744 | - | |
745 | - debug("jni_getMessage = %s",msg); | |
746 | - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s",msg); | |
747 | - | |
748 | - env->ReleaseStringUTFChars( j_msg, msg); | |
749 | - } | |
750 | - | |
751 | - if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) | |
752 | - gtk_main_quit(); | |
753 | - gtk_widget_destroy(dialog); | |
754 | - | |
755 | - | |
756 | - } | |
757 | - | |
758 | - } catch(std::exception &e) { | |
759 | - | |
760 | - debug("Java error: %s",e.what()); | |
761 | - trace("%s",e.what()); | |
762 | - } | |
763 | - | |
764 | - | |
765 | - } | |
766 | - | |
767 | - } | |
768 | - | |
769 | - g_free(classname); | |
770 | - | |
771 | - jvm->DestroyJavaVM(); | |
772 | - } | |
773 | - | |
774 | -#ifdef _WIN32 | |
775 | - if(hJVM) | |
776 | - FreeLibrary(hJVM); | |
777 | -#endif // _WIN32 | |
778 | - | |
779 | - // And release | |
780 | - v3270_set_script(widget,'J',FALSE); | |
781 | - | |
782 | -#if GTK_CHECK_VERSION(2,32,0) | |
783 | - g_mutex_unlock(&mutex); | |
784 | -#else | |
785 | - g_static_mutex_unlock(&mutex); | |
786 | -#endif // GTK_CHECK_VERSION | |
787 | - | |
788 | - | |
789 | - } | |
790 | - | |
791 | - LIB3270_EXPORT void pw3270_action_java_activated(GtkAction *action, GtkWidget *widget) | |
792 | - { | |
793 | - gchar *filename = (gchar *) g_object_get_data(G_OBJECT(action),"src"); | |
794 | - | |
795 | - lib3270_trace_event(v3270_get_session(widget),"Action %s activated on widget %p",gtk_action_get_name(action),widget); | |
796 | - | |
797 | -#if GTK_CHECK_VERSION(3,10,0) | |
798 | - g_simple_action_set_enabled(G_SIMPLE_ACTION(action),FALSE); | |
799 | -#else | |
800 | - gtk_action_set_sensitive(action,FALSE); | |
801 | -#endif // GTK(3,10) | |
802 | - | |
803 | - if(filename) | |
804 | - { | |
805 | - // Has filename, call it directly | |
806 | - call_java_program(action,widget,filename); | |
807 | - } | |
808 | - else | |
809 | - { | |
810 | - // No filename, ask user | |
811 | - static const struct _list | |
812 | - { | |
813 | - const gchar *name; | |
814 | - const gchar *pattern; | |
815 | - } list[] = | |
816 | - { | |
817 | - { N_( "Java class file" ), "*.class" } | |
818 | - }; | |
819 | - | |
820 | - GtkFileFilter * filter[G_N_ELEMENTS(list)+1]; | |
821 | - unsigned int f; | |
822 | - | |
823 | - memset(filter,0,sizeof(filter)); | |
824 | - | |
825 | - for(f=0;f<G_N_ELEMENTS(list);f++) | |
826 | - { | |
827 | - filter[f] = gtk_file_filter_new(); | |
828 | - gtk_file_filter_set_name(filter[f],gettext(list[f].name)); | |
829 | - gtk_file_filter_add_pattern(filter[f],list[f].pattern); | |
830 | - } | |
831 | - | |
832 | - filename = pw3270_get_filename(widget,"java","script",filter,_( "Select script to run" )); | |
833 | - | |
834 | - if(filename) | |
835 | - { | |
836 | - call_java_program(action,widget,filename); | |
837 | - g_free(filename); | |
838 | - } | |
839 | - | |
840 | - | |
841 | - } | |
842 | - | |
843 | -#if GTK_CHECK_VERSION(3,10,0) | |
844 | - g_simple_action_set_enabled(G_SIMPLE_ACTION(action),TRUE); | |
845 | -#else | |
846 | - gtk_action_set_sensitive(action,TRUE); | |
847 | -#endif // GTK(3,10) | |
848 | - | |
849 | - } | |
850 | - | |
851 | 333 | } |
852 | 334 | ... | ... |
src/java/private.h
... | ... | @@ -43,7 +43,8 @@ |
43 | 43 | |
44 | 44 | extern "C" { |
45 | 45 | |
46 | - LIB3270_EXPORT void set_java_session_factory(PW3270_NAMESPACE::session * (*factory)(const char *name)); | |
46 | + LIB3270_EXPORT void set_java_session_factory(PW3270_NAMESPACE::session * (*factory)(const char *name)); | |
47 | + extern session * factory(const char *name); | |
47 | 48 | |
48 | 49 | } |
49 | 50 | ... | ... |
... | ... | @@ -0,0 +1,587 @@ |
1 | +/* | |
2 | + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | |
3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | |
4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | |
5 | + * | |
6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | |
7 | + * | |
8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | |
9 | + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | |
10 | + * Free Software Foundation. | |
11 | + * | |
12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | |
13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | |
14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | |
15 | + * obter mais detalhes. | |
16 | + * | |
17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | |
18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 59 Temple | |
19 | + * Place, Suite 330, Boston, MA, 02111-1307, USA | |
20 | + * | |
21 | + * Este programa está nomeado como startstop.cc e possui - linhas de código. | |
22 | + * | |
23 | + * Contatos: | |
24 | + * | |
25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | |
26 | + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | |
27 | + * | |
28 | + */ | |
29 | + | |
30 | +#if defined WIN32 | |
31 | + | |
32 | + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx | |
33 | + #ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | |
34 | + #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 | |
35 | + #endif // LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | |
36 | + | |
37 | + #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | |
38 | + #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 | |
39 | + #endif // LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | |
40 | + | |
41 | + #include <windows.h> | |
42 | + | |
43 | +#else | |
44 | + | |
45 | + #include <dlfcn.h> | |
46 | + | |
47 | +#endif | |
48 | + | |
49 | + #include "private.h" | |
50 | + | |
51 | + #include <malloc.h> | |
52 | + #include <libintl.h> | |
53 | + #include <glib/gi18n.h> | |
54 | + #include <gtk/gtk.h> | |
55 | + | |
56 | + #include <pw3270.h> | |
57 | + #include <pw3270/plugin.h> | |
58 | + #include <pw3270/v3270.h> | |
59 | + #include <lib3270/actions.h> | |
60 | + #include <lib3270/log.h> | |
61 | + #include <lib3270/trace.h> | |
62 | + #include <lib3270/charset.h> | |
63 | + #include <pw3270/class.h> | |
64 | + #include <pw3270/trace.h> | |
65 | + | |
66 | +/*--[ Globals ]--------------------------------------------------------------------------------------*/ | |
67 | + | |
68 | +#if GTK_CHECK_VERSION(2,32,0) | |
69 | + static GMutex mutex; | |
70 | + | |
71 | + #define trylock() g_mutex_trylock(&mutex) | |
72 | + #define lock() g_mutex_lock(&mutex) | |
73 | + #define unlock() g_mutex_unlock(&mutex) | |
74 | + | |
75 | +#else | |
76 | + static GStaticMutex mutex = G_STATIC_MUTEX_INIT; | |
77 | + | |
78 | + #define trylock() g_static_mutex_trylock(&mutex) | |
79 | + #define lock() g_static_mutex_lock(&mutex) | |
80 | + #define unlock() g_static_mutex_unlock(&mutex) | |
81 | + | |
82 | +#endif // GTK_CHECK_VERSION | |
83 | + | |
84 | +/*---[ Implement ]----------------------------------------------------------------------------------*/ | |
85 | + | |
86 | +extern "C" { | |
87 | + | |
88 | + static void trace_cleanup(GtkWidget *widget, GtkWidget **window) { | |
89 | + *window = NULL; | |
90 | + } | |
91 | + | |
92 | + static jint JNICALL jni_vfprintf(FILE *fp, const char *fmt, va_list args) { | |
93 | + | |
94 | + char * msg = NULL; | |
95 | + static GtkWidget * trace = NULL; | |
96 | + | |
97 | + if(vasprintf(&msg,fmt,args) < 1) { | |
98 | + lib3270_write_log(lib3270_get_default_session_handle(),"java","vasprintf() error on \"%s\"",fmt); | |
99 | + return 0; | |
100 | + } | |
101 | + | |
102 | + fprintf(fp,"%s",msg); | |
103 | + lib3270_write_log(lib3270_get_default_session_handle(),"java","%s",msg); | |
104 | + | |
105 | + if(!trace) { | |
106 | + // Cria janela de trace. | |
107 | + trace = pw3270_trace_new(); | |
108 | + g_signal_connect(G_OBJECT(trace), "destroy",G_CALLBACK(trace_cleanup), &trace); | |
109 | + | |
110 | + pw3270_trace_set_destroy_on_close(trace,TRUE); | |
111 | + | |
112 | + // gtk_window_set_transient_for(GTK_WINDOW(trace),GTK_WINDOW(gtk_widget_get_toplevel(widget))); | |
113 | + gtk_window_set_destroy_with_parent(GTK_WINDOW(trace),TRUE); | |
114 | + | |
115 | + gtk_window_set_default_size(GTK_WINDOW(trace),590,430); | |
116 | + gtk_widget_show_all(trace); | |
117 | + | |
118 | + pw3270_trace_printf(trace,"%s",msg); | |
119 | + | |
120 | + free(msg); | |
121 | + } | |
122 | + | |
123 | + return 0; | |
124 | + } | |
125 | + | |
126 | +} | |
127 | + | |
128 | +#ifdef _WIN32 | |
129 | + /* | |
130 | + * Dynamically load jvm to avoid naming and path problems | |
131 | + * | |
132 | + */ | |
133 | + static void load_jvm(GtkWidget *widget, HMODULE &hModule) { | |
134 | + | |
135 | + // Dynamically load jvm library to avoid naming and path problems. | |
136 | + HMODULE kernel; | |
137 | + HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory); | |
138 | + BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie); | |
139 | + | |
140 | + struct _dlldir { | |
141 | + const gchar * env; | |
142 | + const gchar * path; | |
143 | + HANDLE cookie; | |
144 | + } dlldir[] = { | |
145 | + { "JRE_HOME", "bin\\client", 0 }, | |
146 | + { "JDK_HOME", "jre\\bin\\client", 0 } | |
147 | + }; | |
148 | + | |
149 | + kernel = LoadLibrary("kernel32.dll"); | |
150 | + | |
151 | + debug("---[ %s ]---------------------------------------------------",__FUNCTION__); | |
152 | + | |
153 | + AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory"); | |
154 | + if(AddDllDirectory) { | |
155 | + | |
156 | + // Acrescenta mais caminhos para achar a dll | |
157 | + for(size_t f = 0; f < G_N_ELEMENTS(dlldir); f++) { | |
158 | + | |
159 | + const char *env = getenv(dlldir[f].env); | |
160 | + | |
161 | + debug("%s=\"%s\"",dlldir[f].env,env); | |
162 | + | |
163 | + if(env) { | |
164 | + | |
165 | + gchar *p = g_build_filename(env,dlldir[f].path,NULL); | |
166 | + | |
167 | + debug("Adicionando diretório \"%s\"",p); | |
168 | + | |
169 | + wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t)); | |
170 | + mbstowcs(path, p, 4095); | |
171 | + dlldir[f].cookie = AddDllDirectory(path); | |
172 | + free(path); | |
173 | + | |
174 | + g_free(p); | |
175 | + | |
176 | + } | |
177 | + } | |
178 | + | |
179 | + } | |
180 | +#ifdef DEBUG | |
181 | + else { | |
182 | + debug("Can't get %s: %s","AddDllDirectory",session::win32_strerror(GetLastError()).c_str()) | |
183 | + } | |
184 | +#endif // DEBUG | |
185 | + | |
186 | + hModule = LoadLibrary("jvm.dll"); | |
187 | + | |
188 | + debug("hModule=%08lx",(long) hModule); | |
189 | + | |
190 | + if(!hModule) { | |
191 | + | |
192 | + DWORD err = GetLastError(); | |
193 | + | |
194 | + debug("%s",session::win32_strerror(err).c_str()); | |
195 | + | |
196 | + GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
197 | + GTK_DIALOG_DESTROY_WITH_PARENT, | |
198 | + GTK_MESSAGE_ERROR, | |
199 | + GTK_BUTTONS_CANCEL, | |
200 | + "%s", _( "Can't load java virtual machine" ) ); | |
201 | + | |
202 | + gtk_window_set_title(GTK_WINDOW(dialog),_( "JVM error" )); | |
203 | + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s", session::win32_strerror(err).c_str()); | |
204 | + | |
205 | + gtk_dialog_run(GTK_DIALOG (dialog)); | |
206 | + gtk_widget_destroy(dialog); | |
207 | + | |
208 | + } | |
209 | + | |
210 | + // Libera caminhos extras. | |
211 | + RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory"); | |
212 | + if(RemoveDllDirectory) { | |
213 | + | |
214 | + for(size_t f = 0; f < G_N_ELEMENTS(dlldir); f++) { | |
215 | + | |
216 | + if(dlldir[f].cookie) { | |
217 | + | |
218 | + RemoveDllDirectory(dlldir[f].cookie); | |
219 | + | |
220 | + } | |
221 | + } | |
222 | + | |
223 | + } | |
224 | +#ifdef DEBUG | |
225 | + else { | |
226 | + debug("Can't get %s: %s","RemoveDllDirectory",session::win32_strerror(GetLastError()).c_str()) | |
227 | + } | |
228 | +#endif // DEBUG | |
229 | + | |
230 | + FreeLibrary(kernel); | |
231 | + | |
232 | + } | |
233 | + | |
234 | + | |
235 | +#endif // _WIN32 | |
236 | + | |
237 | + | |
238 | + LIB3270_EXPORT int pw3270_plugin_start(GtkWidget *window) | |
239 | + { | |
240 | + trace("JAVA: %s",__FUNCTION__); | |
241 | +#if GTK_CHECK_VERSION(2,32,0) | |
242 | + g_mutex_init(&mutex); | |
243 | +#endif // GTK_CHECK_VERSION | |
244 | + set_java_session_factory(factory); | |
245 | + return 0; | |
246 | + } | |
247 | + | |
248 | + LIB3270_EXPORT int pw3270_plugin_stop(GtkWidget *window) | |
249 | + { | |
250 | +#if GTK_CHECK_VERSION(2,32,0) | |
251 | + g_mutex_clear(&mutex); | |
252 | +#endif // GTK_CHECK_VERSION | |
253 | + trace("JAVA: %s",__FUNCTION__); | |
254 | + return 0; | |
255 | + } | |
256 | + | |
257 | +extern "C" | |
258 | +{ | |
259 | + | |
260 | + void call_java_program(GtkAction *action, GtkWidget *widget, const gchar *filename) | |
261 | + { | |
262 | + | |
263 | + if(!trylock()) { | |
264 | + | |
265 | + GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
266 | + GTK_DIALOG_DESTROY_WITH_PARENT, | |
267 | + GTK_MESSAGE_ERROR, | |
268 | + GTK_BUTTONS_CANCEL, | |
269 | + _( "Can't start %s program" ), "java" ); | |
270 | + | |
271 | + gtk_window_set_title(GTK_WINDOW(dialog),_( "JVM busy" )); | |
272 | + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),_( "%s interpreter is busy" ), "java"); | |
273 | + | |
274 | + gtk_dialog_run(GTK_DIALOG (dialog)); | |
275 | + gtk_widget_destroy(dialog); | |
276 | + | |
277 | + return; | |
278 | + } | |
279 | + | |
280 | + v3270_set_script(widget,'J',TRUE); | |
281 | + | |
282 | +#ifdef _WIN32 | |
283 | + | |
284 | + HMODULE hJVM = 0; | |
285 | + | |
286 | + load_jvm(widget,hJVM); | |
287 | + | |
288 | + debug("hJVM=%p",hJVM); | |
289 | + | |
290 | + if(!hJVM) { | |
291 | + v3270_set_script(widget,'J',FALSE); | |
292 | + | |
293 | +#if GTK_CHECK_VERSION(2,32,0) | |
294 | + g_mutex_unlock(&mutex); | |
295 | +#else | |
296 | + g_static_mutex_unlock(&mutex); | |
297 | +#endif // GTK_CHECK_VERSION | |
298 | + | |
299 | + return; | |
300 | + | |
301 | + } | |
302 | + | |
303 | +#endif // _WIN32 | |
304 | + | |
305 | + debug("%s",__FUNCTION__); | |
306 | + | |
307 | + // Start JNI | |
308 | + JavaVMInitArgs vm_args; | |
309 | + JavaVMOption options[5]; | |
310 | + | |
311 | + JavaVM * jvm = NULL; | |
312 | + JNIEnv * env = NULL; | |
313 | + jint rc = 0; | |
314 | + | |
315 | + memset(&vm_args,0,sizeof(vm_args)); | |
316 | + memset(options,0,sizeof(options)); | |
317 | + | |
318 | + vm_args.version = JNI_VERSION_1_4; | |
319 | + vm_args.nOptions = 0; | |
320 | + vm_args.options = options; | |
321 | + vm_args.ignoreUnrecognized = JNI_FALSE; | |
322 | + | |
323 | + options[vm_args.nOptions].optionString = g_strdup("vfprintf"); | |
324 | + options[vm_args.nOptions].extraInfo = (void *) jni_vfprintf; | |
325 | + vm_args.nOptions++; | |
326 | + | |
327 | +//#ifdef DEBUG | |
328 | +// options[vm_args.nOptions++].optionString = g_strdup("-verbose"); | |
329 | +//#endif | |
330 | + | |
331 | + gchar * dirname = g_path_get_dirname(filename); | |
332 | + | |
333 | + debug("Dirname=%s",dirname); | |
334 | + | |
335 | +#if defined( WIN32 ) | |
336 | + | |
337 | + gchar * exports = NULL; | |
338 | + char buffer[1024]; | |
339 | + gchar * myDir; | |
340 | + | |
341 | + if(GetModuleFileName(NULL,buffer,sizeof(buffer)) < sizeof(buffer)) { | |
342 | + | |
343 | + gchar * ptr = strrchr(buffer,G_DIR_SEPARATOR); | |
344 | + if(ptr) { | |
345 | + *ptr = 0; | |
346 | + myDir = g_strdup(buffer); | |
347 | + } else { | |
348 | + myDir = g_strdup("."); | |
349 | + } | |
350 | + | |
351 | + | |
352 | + } else { | |
353 | + | |
354 | + myDir = g_strdup("."); | |
355 | + | |
356 | + } | |
357 | + | |
358 | + debug("myDir=%s",myDir); | |
359 | + | |
360 | + exports = g_build_filename(myDir,"jvm-exports",NULL); | |
361 | + g_mkdir_with_parents(exports,0777); | |
362 | + | |
363 | + lib3270_trace_event(v3270_get_session(widget),"java.class.path=%s;%s",dirname,exports); | |
364 | + lib3270_trace_event(v3270_get_session(widget),"java.library.path=%s",myDir); | |
365 | + | |
366 | + options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.library.path=%s",myDir); | |
367 | + options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.class.path=%s;%s",dirname,exports); | |
368 | + | |
369 | + g_free(myDir); | |
370 | + g_free(exports); | |
371 | + | |
372 | + // Windows, first find the method, then call it. | |
373 | + jint JNICALL (*CreateJavaVM)(JavaVM **, void **, void *) = (jint JNICALL (*)(JavaVM **, void **, void *)) GetProcAddress(hJVM,"JNI_CreateJavaVM"); | |
374 | + | |
375 | + if(!CreateJavaVM) { | |
376 | + rc = ENOENT; | |
377 | + } else { | |
378 | + debug("Calling %s","CreateJavaVM"); | |
379 | + rc = CreateJavaVM(&jvm,(void **)&env,&vm_args); | |
380 | + debug("%s exits with rc=%d","CreateJavaVM",rc); | |
381 | + } | |
382 | + | |
383 | +#else | |
384 | + | |
385 | +#if defined(DEBUG) | |
386 | + options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.library.path=%s:.bin/Debug:.bin/Debug/lib",JNIDIR); | |
387 | + options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.class.path=%s:%s:./src/java/.bin/java",JARDIR,dirname); | |
388 | +#else | |
389 | + options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.library.path=%s",JNIDIR); | |
390 | + options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.class.path=%s:%s",JARDIR,dirname); | |
391 | +#endif // JNIDIR | |
392 | + | |
393 | + // Linux, just create JVM | |
394 | + rc = JNI_CreateJavaVM(&jvm,(void **)&env,&vm_args); | |
395 | + | |
396 | +#endif // _WIn32 | |
397 | + | |
398 | + debug("JNI_CreateJavaVM exits with rc=%d",rc); | |
399 | + | |
400 | + g_free(dirname); | |
401 | + | |
402 | + | |
403 | + // Release options | |
404 | + for(int f=0;f<vm_args.nOptions;f++) { | |
405 | + trace("Releasing option %d: %s",f,options[f].optionString); | |
406 | + g_free(options[f].optionString); | |
407 | + } | |
408 | + | |
409 | + if(rc < 0) { | |
410 | + | |
411 | + GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
412 | + GTK_DIALOG_DESTROY_WITH_PARENT, | |
413 | + GTK_MESSAGE_ERROR, | |
414 | + GTK_BUTTONS_CANCEL, | |
415 | + "%s", _( "Can't create java VM" )); | |
416 | + | |
417 | + gtk_window_set_title(GTK_WINDOW(dialog), _( "Script startup failure" )); | |
418 | + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),_( "The error code was %d" ), (int) rc); | |
419 | + | |
420 | + gtk_dialog_run(GTK_DIALOG (dialog)); | |
421 | + gtk_widget_destroy(dialog); | |
422 | + | |
423 | + } else { | |
424 | + | |
425 | + gchar * classname = g_path_get_basename(filename); | |
426 | + | |
427 | + gchar * ptr = strchr(classname,'.'); | |
428 | + if(ptr) { | |
429 | + *ptr = 0; | |
430 | + } | |
431 | + | |
432 | + jclass cls = env->FindClass(classname); | |
433 | + | |
434 | + if(cls == 0) { | |
435 | + | |
436 | + GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
437 | + GTK_DIALOG_DESTROY_WITH_PARENT, | |
438 | + GTK_MESSAGE_ERROR, | |
439 | + GTK_BUTTONS_CANCEL, | |
440 | + _( "Can't find class %s" ), classname ); | |
441 | + | |
442 | + gtk_window_set_title(GTK_WINDOW(dialog), _( "Java error" )); | |
443 | + if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) | |
444 | + gtk_main_quit(); | |
445 | + gtk_widget_destroy(dialog); | |
446 | + | |
447 | + } else { | |
448 | + | |
449 | + jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); | |
450 | + | |
451 | + if(mid == 0) { | |
452 | + | |
453 | + GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
454 | + GTK_DIALOG_DESTROY_WITH_PARENT, | |
455 | + GTK_MESSAGE_ERROR, | |
456 | + GTK_BUTTONS_OK_CANCEL, | |
457 | + _( "Can't find class \"%s\"" ), classname ); | |
458 | + | |
459 | + gtk_window_set_title(GTK_WINDOW(dialog), _( "Java error" )); | |
460 | + | |
461 | + if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) | |
462 | + gtk_main_quit(); | |
463 | + gtk_widget_destroy(dialog); | |
464 | + | |
465 | + } else { | |
466 | + | |
467 | + jobjectArray args = env->NewObjectArray(0, env->FindClass("java/lang/String"), env->NewStringUTF("")); | |
468 | + | |
469 | + try { | |
470 | + | |
471 | + debug("%s: Calling CallStaticVoidMethod()",__FUNCTION__); | |
472 | + env->CallStaticVoidMethod(cls, mid, args); | |
473 | + debug("%s: CallStaticVoidMethod() has returned",__FUNCTION__); | |
474 | + | |
475 | + jthrowable exc = env->ExceptionOccurred(); | |
476 | + env->ExceptionClear(); | |
477 | + | |
478 | + if (exc) { | |
479 | + jclass throwable_class = env->FindClass("java/lang/Throwable"); | |
480 | + | |
481 | + jmethodID jni_getMessage = env->GetMethodID(throwable_class,"getMessage","()Ljava/lang/String;"); | |
482 | + jstring j_msg = (jstring) env->CallObjectMethod(exc,jni_getMessage); | |
483 | + | |
484 | + GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
485 | + GTK_DIALOG_DESTROY_WITH_PARENT, | |
486 | + GTK_MESSAGE_ERROR, | |
487 | + GTK_BUTTONS_OK_CANCEL, | |
488 | + _( "Java application \"%s\" has failed." ), classname ); | |
489 | + | |
490 | + gtk_window_set_title(GTK_WINDOW(dialog), _( "Java failure" )); | |
491 | + | |
492 | + if(!env->IsSameObject(j_msg,NULL)) { | |
493 | + | |
494 | + const char * msg = env->GetStringUTFChars(j_msg, 0); | |
495 | + | |
496 | + debug("jni_getMessage = %s",msg); | |
497 | + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s",msg); | |
498 | + | |
499 | + env->ReleaseStringUTFChars( j_msg, msg); | |
500 | + } | |
501 | + | |
502 | + if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) | |
503 | + gtk_main_quit(); | |
504 | + gtk_widget_destroy(dialog); | |
505 | + | |
506 | + | |
507 | + } | |
508 | + | |
509 | + } catch(std::exception &e) { | |
510 | + | |
511 | + debug("Java error: %s",e.what()); | |
512 | + trace("%s",e.what()); | |
513 | + } | |
514 | + | |
515 | + | |
516 | + } | |
517 | + | |
518 | + } | |
519 | + | |
520 | + g_free(classname); | |
521 | + | |
522 | + rc = jvm->DestroyJavaVM(); | |
523 | + debug("DestroyJavaVM=%d",(int) rc); | |
524 | + } | |
525 | + | |
526 | +#ifdef _WIN32 | |
527 | + if(hJVM) | |
528 | + FreeLibrary(hJVM); | |
529 | +#endif // _WIN32 | |
530 | + | |
531 | + // And release | |
532 | + v3270_set_script(widget,'J',FALSE); | |
533 | + | |
534 | + unlock(); | |
535 | + | |
536 | + } | |
537 | + | |
538 | + LIB3270_EXPORT void pw3270_action_java_activated(GtkAction *action, GtkWidget *widget) | |
539 | + { | |
540 | + gchar *filename = (gchar *) g_object_get_data(G_OBJECT(action),"src"); | |
541 | + | |
542 | + lib3270_trace_event(v3270_get_session(widget),"Action %s activated on widget %p",gtk_action_get_name(action),widget); | |
543 | + | |
544 | + if(filename) | |
545 | + { | |
546 | + // Has filename, call it directly | |
547 | + call_java_program(action,widget,filename); | |
548 | + } | |
549 | + else | |
550 | + { | |
551 | + // No filename, ask user | |
552 | + static const struct _list | |
553 | + { | |
554 | + const gchar *name; | |
555 | + const gchar *pattern; | |
556 | + } list[] = | |
557 | + { | |
558 | + { N_( "Java class file" ), "*.class" } | |
559 | + }; | |
560 | + | |
561 | + GtkFileFilter * filter[G_N_ELEMENTS(list)+1]; | |
562 | + unsigned int f; | |
563 | + | |
564 | + memset(filter,0,sizeof(filter)); | |
565 | + | |
566 | + for(f=0;f<G_N_ELEMENTS(list);f++) | |
567 | + { | |
568 | + filter[f] = gtk_file_filter_new(); | |
569 | + gtk_file_filter_set_name(filter[f],gettext(list[f].name)); | |
570 | + gtk_file_filter_add_pattern(filter[f],list[f].pattern); | |
571 | + } | |
572 | + | |
573 | + filename = pw3270_get_filename(widget,"java","script",filter,_( "Select script to run" )); | |
574 | + | |
575 | + if(filename) | |
576 | + { | |
577 | + call_java_program(action,widget,filename); | |
578 | + g_free(filename); | |
579 | + } | |
580 | + | |
581 | + | |
582 | + } | |
583 | + | |
584 | + } | |
585 | + | |
586 | +} | |
587 | + | ... | ... |