64
65 #define G_TYPE_FUNDAMENTAL_SHIFT (2)
66 #define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
67 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
68
69 #define CONV_BUFFER_SIZE 128
70
71 #define NO_SYMBOL_EXCEPTION 1
72
73 /* SynthConstants */
74 const gint ENABLED = 1 << 0;
75 const gint MOUSE_OVER = 1 << 1;
76 const gint PRESSED = 1 << 2;
77 const gint DISABLED = 1 << 3;
78 const gint FOCUSED = 1 << 8;
79 const gint SELECTED = 1 << 9;
80 const gint DEFAULT = 1 << 10;
81
82 static void *gtk2_libhandle = NULL;
83 static void *gthread_libhandle = NULL;
84 static gboolean flag_g_thread_get_initialized = FALSE;
85 static jmp_buf j;
86
87 /* Widgets */
88 static GtkWidget *gtk2_widget = NULL;
89 static GtkWidget *gtk2_window = NULL;
90 static GtkFixed *gtk2_fixed = NULL;
91
92 /* Paint system */
93 static GdkPixmap *gtk2_white_pixmap = NULL;
94 static GdkPixmap *gtk2_black_pixmap = NULL;
95 static GdkPixbuf *gtk2_white_pixbuf = NULL;
96 static GdkPixbuf *gtk2_black_pixbuf = NULL;
97 static int gtk2_pixbuf_width = 0;
98 static int gtk2_pixbuf_height = 0;
99
100 /* Static buffer for conversion from java.lang.String to UTF-8 */
101 static char convertionBuffer[CONV_BUFFER_SIZE];
102
103 static gboolean new_combo = TRUE;
104 const char ENV_PREFIX[] = "GTK_MODULES=";
485 "gtk_file_chooser_set_filename");
486 fp_gtk_file_chooser_set_current_name = dl_symbol(
487 "gtk_file_chooser_set_current_name");
488 fp_gtk_file_filter_add_custom = dl_symbol("gtk_file_filter_add_custom");
489 fp_gtk_file_chooser_set_filter = dl_symbol("gtk_file_chooser_set_filter");
490 fp_gtk_file_chooser_get_type = dl_symbol("gtk_file_chooser_get_type");
491 fp_gtk_file_filter_new = dl_symbol("gtk_file_filter_new");
492 if (fp_gtk_check_version(2, 8, 0) == NULL) {
493 fp_gtk_file_chooser_set_do_overwrite_confirmation = dl_symbol(
494 "gtk_file_chooser_set_do_overwrite_confirmation");
495 }
496 fp_gtk_file_chooser_set_select_multiple = dl_symbol(
497 "gtk_file_chooser_set_select_multiple");
498 fp_gtk_file_chooser_get_current_folder = dl_symbol(
499 "gtk_file_chooser_get_current_folder");
500 fp_gtk_file_chooser_get_filenames = dl_symbol(
501 "gtk_file_chooser_get_filenames");
502 fp_gtk_g_slist_length = dl_symbol("g_slist_length");
503 }
504
505 gboolean gtk2_load()
506 {
507 gboolean result;
508 int i;
509 int (*handler)();
510 int (*io_handler)();
511 char *gtk_modules_env;
512
513 gtk2_libhandle = dlopen(GTK2_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
514 if (gtk2_libhandle == NULL) {
515 gtk2_libhandle = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL);
516 if (gtk2_libhandle == NULL)
517 return FALSE;
518 }
519
520 gthread_libhandle = dlopen(GTHREAD_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
521 if (gthread_libhandle == NULL) {
522 gthread_libhandle = dlopen(GTHREAD_LIB, RTLD_LAZY | RTLD_LOCAL);
523 if (gthread_libhandle == NULL)
524 return FALSE;
525 }
526
527 if (setjmp(j) == 0)
528 {
529 fp_gtk_check_version = dl_symbol("gtk_check_version");
530 /* Check for GTK 2.2+ */
531 if (fp_gtk_check_version(2, 2, 0)) {
532 longjmp(j, NO_SYMBOL_EXCEPTION);
533 }
534
535 /* GLib */
536 fp_g_free = dl_symbol("g_free");
537 fp_g_object_unref = dl_symbol("g_object_unref");
538
539 fp_g_main_context_iteration =
540 dl_symbol("g_main_context_iteration");
541
542 fp_g_value_init = dl_symbol("g_value_init");
543 fp_g_type_is_a = dl_symbol("g_type_is_a");
544
545 fp_g_value_get_boolean = dl_symbol("g_value_get_boolean");
546 fp_g_value_get_char = dl_symbol("g_value_get_char");
547 fp_g_value_get_uchar = dl_symbol("g_value_get_uchar");
548 fp_g_value_get_int = dl_symbol("g_value_get_int");
549 fp_g_value_get_uint = dl_symbol("g_value_get_uint");
550 fp_g_value_get_long = dl_symbol("g_value_get_long");
551 fp_g_value_get_ulong = dl_symbol("g_value_get_ulong");
552 fp_g_value_get_int64 = dl_symbol("g_value_get_int64");
553 fp_g_value_get_uint64 = dl_symbol("g_value_get_uint64");
554 fp_g_value_get_float = dl_symbol("g_value_get_float");
555 fp_g_value_get_double = dl_symbol("g_value_get_double");
691 fp_gtk_settings_get_default =
692 dl_symbol("gtk_settings_get_default");
693 fp_gtk_widget_get_settings =
694 dl_symbol("gtk_widget_get_settings");
695 fp_gtk_border_get_type = dl_symbol("gtk_border_get_type");
696 fp_gtk_arrow_set = dl_symbol("gtk_arrow_set");
697 fp_gtk_widget_size_request =
698 dl_symbol("gtk_widget_size_request");
699 fp_gtk_range_get_adjustment =
700 dl_symbol("gtk_range_get_adjustment");
701
702 fp_gtk_widget_hide = dl_symbol("gtk_widget_hide");
703 fp_gtk_main_quit = dl_symbol("gtk_main_quit");
704 fp_g_signal_connect_data = dl_symbol("g_signal_connect_data");
705 fp_gtk_widget_show = dl_symbol("gtk_widget_show");
706 fp_gtk_main = dl_symbol("gtk_main");
707
708 /**
709 * GLib thread system
710 */
711 fp_g_thread_init = dl_symbol_gthread("g_thread_init");
712 fp_gdk_threads_init = dl_symbol("gdk_threads_init");
713 fp_gdk_threads_enter = dl_symbol("gdk_threads_enter");
714 fp_gdk_threads_leave = dl_symbol("gdk_threads_leave");
715
716 /**
717 * Functions for sun_awt_X11_GtkFileDialogPeer.c
718 */
719 if (fp_gtk_check_version(2, 4, 0) == NULL) {
720 // The current GtkFileChooser is available from GTK+ 2.4
721 gtk2_file_chooser_load();
722 }
723
724 /* Some functions may be missing in pre-2.4 GTK.
725 We handle them specially here.
726 */
727 fp_gtk_combo_box_new = dlsym(gtk2_libhandle, "gtk_combo_box_new");
728 if (fp_gtk_combo_box_new == NULL) {
729 fp_gtk_combo_box_new = dl_symbol("gtk_combo_new");
730 }
793 }
794 }
795 putenv (new_env);
796 free (new_env);
797 free (tmp_env);
798 }
799 }
800
801 /*
802 * GTK should be initialized with gtk_init_check() before use.
803 *
804 * gtk_init_check installs its own error handlers. It is critical that
805 * we preserve error handler set from AWT. Otherwise we'll crash on
806 * BadMatch errors which we would normally ignore. The IO error handler
807 * is preserved here, too, just for consistency.
808 */
809 handler = XSetErrorHandler(NULL);
810 io_handler = XSetIOErrorHandler(NULL);
811
812 if (fp_gtk_check_version(2, 2, 0) == NULL) {
813 // Init the thread system to use GLib in a thread-safe mode
814 if (!flag_g_thread_get_initialized) {
815 flag_g_thread_get_initialized = TRUE;
816
817 fp_g_thread_init(NULL);
818
819 //According the GTK documentation, gdk_threads_init() should be
820 //called before gtk_init() or gtk_init_check()
821 fp_gdk_threads_init();
822 }
823 }
824 result = (*fp_gtk_init_check)(NULL, NULL);
825
826 XSetErrorHandler(handler);
827 XSetIOErrorHandler(io_handler);
828
829 /* Initialize widget array. */
830 for (i = 0; i < _GTK_WIDGET_TYPE_SIZE; i++)
831 {
832 gtk2_widgets[i] = NULL;
833 }
834
835 return result;
836 }
837
838 int gtk2_unload()
839 {
840 int i;
841 char *gtk2_error;
842
|
64
65 #define G_TYPE_FUNDAMENTAL_SHIFT (2)
66 #define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
67 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
68
69 #define CONV_BUFFER_SIZE 128
70
71 #define NO_SYMBOL_EXCEPTION 1
72
73 /* SynthConstants */
74 const gint ENABLED = 1 << 0;
75 const gint MOUSE_OVER = 1 << 1;
76 const gint PRESSED = 1 << 2;
77 const gint DISABLED = 1 << 3;
78 const gint FOCUSED = 1 << 8;
79 const gint SELECTED = 1 << 9;
80 const gint DEFAULT = 1 << 10;
81
82 static void *gtk2_libhandle = NULL;
83 static void *gthread_libhandle = NULL;
84
85 static jmp_buf j;
86
87 /* Widgets */
88 static GtkWidget *gtk2_widget = NULL;
89 static GtkWidget *gtk2_window = NULL;
90 static GtkFixed *gtk2_fixed = NULL;
91
92 /* Paint system */
93 static GdkPixmap *gtk2_white_pixmap = NULL;
94 static GdkPixmap *gtk2_black_pixmap = NULL;
95 static GdkPixbuf *gtk2_white_pixbuf = NULL;
96 static GdkPixbuf *gtk2_black_pixbuf = NULL;
97 static int gtk2_pixbuf_width = 0;
98 static int gtk2_pixbuf_height = 0;
99
100 /* Static buffer for conversion from java.lang.String to UTF-8 */
101 static char convertionBuffer[CONV_BUFFER_SIZE];
102
103 static gboolean new_combo = TRUE;
104 const char ENV_PREFIX[] = "GTK_MODULES=";
485 "gtk_file_chooser_set_filename");
486 fp_gtk_file_chooser_set_current_name = dl_symbol(
487 "gtk_file_chooser_set_current_name");
488 fp_gtk_file_filter_add_custom = dl_symbol("gtk_file_filter_add_custom");
489 fp_gtk_file_chooser_set_filter = dl_symbol("gtk_file_chooser_set_filter");
490 fp_gtk_file_chooser_get_type = dl_symbol("gtk_file_chooser_get_type");
491 fp_gtk_file_filter_new = dl_symbol("gtk_file_filter_new");
492 if (fp_gtk_check_version(2, 8, 0) == NULL) {
493 fp_gtk_file_chooser_set_do_overwrite_confirmation = dl_symbol(
494 "gtk_file_chooser_set_do_overwrite_confirmation");
495 }
496 fp_gtk_file_chooser_set_select_multiple = dl_symbol(
497 "gtk_file_chooser_set_select_multiple");
498 fp_gtk_file_chooser_get_current_folder = dl_symbol(
499 "gtk_file_chooser_get_current_folder");
500 fp_gtk_file_chooser_get_filenames = dl_symbol(
501 "gtk_file_chooser_get_filenames");
502 fp_gtk_g_slist_length = dl_symbol("g_slist_length");
503 }
504
505 gboolean gtk2_load(JNIEnv *env)
506 {
507 gboolean result;
508 int i;
509 int (*handler)();
510 int (*io_handler)();
511 char *gtk_modules_env;
512
513 gtk2_libhandle = dlopen(GTK2_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
514 if (gtk2_libhandle == NULL) {
515 gtk2_libhandle = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL);
516 if (gtk2_libhandle == NULL)
517 return FALSE;
518 }
519
520 gthread_libhandle = dlopen(GTHREAD_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
521 if (gthread_libhandle == NULL) {
522 gthread_libhandle = dlopen(GTHREAD_LIB, RTLD_LAZY | RTLD_LOCAL);
523 if (gthread_libhandle == NULL)
524 return FALSE;
525 }
526
527 if (setjmp(j) == 0)
528 {
529 fp_gtk_check_version = dl_symbol("gtk_check_version");
530 /* Check for GTK 2.2+ */
531 if (fp_gtk_check_version(2, 2, 0)) {
532 longjmp(j, NO_SYMBOL_EXCEPTION);
533 }
534
535 /* GLib */
536 fp_glib_check_version = dl_symbol("glib_check_version");
537 fp_g_free = dl_symbol("g_free");
538 fp_g_object_unref = dl_symbol("g_object_unref");
539
540 fp_g_main_context_iteration =
541 dl_symbol("g_main_context_iteration");
542
543 fp_g_value_init = dl_symbol("g_value_init");
544 fp_g_type_is_a = dl_symbol("g_type_is_a");
545
546 fp_g_value_get_boolean = dl_symbol("g_value_get_boolean");
547 fp_g_value_get_char = dl_symbol("g_value_get_char");
548 fp_g_value_get_uchar = dl_symbol("g_value_get_uchar");
549 fp_g_value_get_int = dl_symbol("g_value_get_int");
550 fp_g_value_get_uint = dl_symbol("g_value_get_uint");
551 fp_g_value_get_long = dl_symbol("g_value_get_long");
552 fp_g_value_get_ulong = dl_symbol("g_value_get_ulong");
553 fp_g_value_get_int64 = dl_symbol("g_value_get_int64");
554 fp_g_value_get_uint64 = dl_symbol("g_value_get_uint64");
555 fp_g_value_get_float = dl_symbol("g_value_get_float");
556 fp_g_value_get_double = dl_symbol("g_value_get_double");
692 fp_gtk_settings_get_default =
693 dl_symbol("gtk_settings_get_default");
694 fp_gtk_widget_get_settings =
695 dl_symbol("gtk_widget_get_settings");
696 fp_gtk_border_get_type = dl_symbol("gtk_border_get_type");
697 fp_gtk_arrow_set = dl_symbol("gtk_arrow_set");
698 fp_gtk_widget_size_request =
699 dl_symbol("gtk_widget_size_request");
700 fp_gtk_range_get_adjustment =
701 dl_symbol("gtk_range_get_adjustment");
702
703 fp_gtk_widget_hide = dl_symbol("gtk_widget_hide");
704 fp_gtk_main_quit = dl_symbol("gtk_main_quit");
705 fp_g_signal_connect_data = dl_symbol("g_signal_connect_data");
706 fp_gtk_widget_show = dl_symbol("gtk_widget_show");
707 fp_gtk_main = dl_symbol("gtk_main");
708
709 /**
710 * GLib thread system
711 */
712 if (fp_glib_check_version(2, 20, 0) == NULL) {
713 fp_g_thread_get_initialized = dl_symbol_gthread("g_thread_get_initialized");
714 }
715 fp_g_thread_init = dl_symbol_gthread("g_thread_init");
716 fp_gdk_threads_init = dl_symbol("gdk_threads_init");
717 fp_gdk_threads_enter = dl_symbol("gdk_threads_enter");
718 fp_gdk_threads_leave = dl_symbol("gdk_threads_leave");
719
720 /**
721 * Functions for sun_awt_X11_GtkFileDialogPeer.c
722 */
723 if (fp_gtk_check_version(2, 4, 0) == NULL) {
724 // The current GtkFileChooser is available from GTK+ 2.4
725 gtk2_file_chooser_load();
726 }
727
728 /* Some functions may be missing in pre-2.4 GTK.
729 We handle them specially here.
730 */
731 fp_gtk_combo_box_new = dlsym(gtk2_libhandle, "gtk_combo_box_new");
732 if (fp_gtk_combo_box_new == NULL) {
733 fp_gtk_combo_box_new = dl_symbol("gtk_combo_new");
734 }
797 }
798 }
799 putenv (new_env);
800 free (new_env);
801 free (tmp_env);
802 }
803 }
804
805 /*
806 * GTK should be initialized with gtk_init_check() before use.
807 *
808 * gtk_init_check installs its own error handlers. It is critical that
809 * we preserve error handler set from AWT. Otherwise we'll crash on
810 * BadMatch errors which we would normally ignore. The IO error handler
811 * is preserved here, too, just for consistency.
812 */
813 handler = XSetErrorHandler(NULL);
814 io_handler = XSetIOErrorHandler(NULL);
815
816 if (fp_gtk_check_version(2, 2, 0) == NULL) {
817 jclass clazz = (*env)->FindClass(env, "sun/misc/GThreadHelper");
818 jmethodID mid_getInitStateAndInitialize = (*env)->GetStaticMethodID(env, clazz, "getInitStateAndInitialize", "()Z");
819 jmethodID mid_lock = (*env)->GetStaticMethodID(env, clazz, "lock", "()V");
820 jmethodID mid_unlock = (*env)->GetStaticMethodID(env, clazz, "unlock", "()V");
821
822 // Init the thread system to use GLib in a thread-safe mode
823 (*env)->CallStaticVoidMethod(env, clazz, mid_lock);
824
825 // Calling g_thread_init() multiple times leads to crash on GLib < 2.24
826 // We can use g_thread_get_initialized () but it is available only for
827 // GLib >= 2.20. We rely on GThreadHelper for GLib < 2.20.
828 gboolean is_g_thread_get_initialized = FALSE;
829 if (fp_glib_check_version(2, 20, 0) == NULL) {
830 is_g_thread_get_initialized = fp_g_thread_get_initialized();
831 }
832
833 if (!(*env)->CallStaticBooleanMethod(env, clazz, mid_getInitStateAndInitialize)
834 && !is_g_thread_get_initialized) {
835 fp_g_thread_init(NULL);
836
837 //According the GTK documentation, gdk_threads_init() should be
838 //called before gtk_init() or gtk_init_check()
839 fp_gdk_threads_init();
840 }
841 (*env)->CallStaticVoidMethod(env, clazz, mid_unlock);
842 }
843 result = (*fp_gtk_init_check)(NULL, NULL);
844
845 XSetErrorHandler(handler);
846 XSetIOErrorHandler(io_handler);
847
848 /* Initialize widget array. */
849 for (i = 0; i < _GTK_WIDGET_TYPE_SIZE; i++)
850 {
851 gtk2_widgets[i] = NULL;
852 }
853
854 return result;
855 }
856
857 int gtk2_unload()
858 {
859 int i;
860 char *gtk2_error;
861
|