src/solaris/native/sun/awt/gtk2_interface.c

Print this page

        

@@ -30,10 +30,11 @@
 #include <string.h>
 #include "gtk2_interface.h"
 #include "java_awt_Transparency.h"
 
 #define GTK2_LIB "libgtk-x11-2.0.so.0"
+#define GTHREAD_LIB "libgthread-2.0.so.0"
 
 #define G_TYPE_INVALID                  G_TYPE_MAKE_FUNDAMENTAL (0)
 #define G_TYPE_NONE                     G_TYPE_MAKE_FUNDAMENTAL (1)
 #define G_TYPE_INTERFACE                G_TYPE_MAKE_FUNDAMENTAL (2)
 #define G_TYPE_CHAR                     G_TYPE_MAKE_FUNDAMENTAL (3)

@@ -73,10 +74,11 @@
 const gint FOCUSED    = 1 << 8;
 const gint SELECTED   = 1 << 9;
 const gint DEFAULT    = 1 << 10;
 
 static void *gtk2_libhandle = NULL;
+static void *gthread_libhandle = NULL;
 static jmp_buf j;
 
 /* Widgets */
 static GtkWidget *gtk2_widget = NULL;
 static GtkWidget *gtk2_window = NULL;

@@ -148,11 +150,10 @@
 static GtkWidget *gtk2_widgets[_GTK_WIDGET_TYPE_SIZE];
 
 /*************************
  * Glib function pointers
  *************************/
-static void     (*fp_g_free)(gpointer mem);
 
 static gboolean (*fp_g_main_context_iteration)(GMainContext *context,
                                              gboolean may_block);
 
 static GValue*      (*fp_g_value_init)(GValue *value, GType g_type);

@@ -202,13 +203,10 @@
         gint* width, gint* height);
 
 /************************
  * Gtk function pointers
  ************************/
-static gchar*   (*fp_gtk_check_version)(guint required_major,
-                                        guint required_minor,
-                                        guint required_micro);
 static gboolean (*fp_gtk_init_check)(int* argc, char** argv);
 
 /* Painting */
 static void (*fp_gtk_paint_hline)(GtkStyle* style, GdkWindow* window,
         GtkStateType state_type, GdkRectangle* area, GtkWidget* widget,

@@ -328,11 +326,10 @@
 static void (*fp_gtk_menu_shell_append)(GtkMenuShell *menu_shell,
         GtkWidget *child);
 static void (*fp_gtk_menu_item_set_submenu)(GtkMenuItem *menu_item,
         GtkWidget *submenu);
 static void (*fp_gtk_widget_realize)(GtkWidget *widget);
-static void (*fp_gtk_widget_destroy)(GtkWidget *widget);
 static GdkPixbuf* (*fp_gtk_widget_render_icon)(GtkWidget *widget,
         const gchar *stock_id, GtkIconSize size, const gchar *detail);
 static void (*fp_gtk_widget_set_name)(GtkWidget *widget, const gchar *name);
 static void (*fp_gtk_widget_set_parent)(GtkWidget *widget, GtkWidget *parent);
 static void (*fp_gtk_widget_set_direction)(GtkWidget *widget,

@@ -386,10 +383,19 @@
         longjmp(j, NO_SYMBOL_EXCEPTION);
 
     return result;
 }
 
+static void* dl_symbol_gthread(const char* name)
+{
+    void* result = dlsym(gthread_libhandle, name);
+    if (!result)
+        longjmp(j, NO_SYMBOL_EXCEPTION);
+
+    return result;
+}
+
 gboolean gtk2_check_version()
 {
     if (gtk2_libhandle != NULL) {
         /* We've already successfully opened the GTK libs, so return true. */
         return TRUE;

@@ -412,20 +418,49 @@
 
         return result;
     }
 }
 
+/**
+ * Functions for sun_awt_X11_GtkFileDialogPeer.c
+ */
+void gtk2_file_chooser_load()
+{
+        fp_gtk_file_chooser_get_filename = dl_symbol(
+                        "gtk_file_chooser_get_filename");
+        fp_gtk_file_chooser_dialog_new = dl_symbol("gtk_file_chooser_dialog_new");
+        fp_gtk_file_chooser_set_current_folder = dl_symbol(
+                        "gtk_file_chooser_set_current_folder");
+        fp_gtk_file_chooser_set_filename = dl_symbol(
+                        "gtk_file_chooser_set_filename");
+        fp_gtk_file_filter_add_custom = dl_symbol("gtk_file_filter_add_custom");
+        fp_gtk_file_chooser_set_filter = dl_symbol("gtk_file_chooser_set_filter");
+        fp_gtk_file_chooser_get_type = dl_symbol("gtk_file_chooser_get_type");
+        fp_gtk_file_filter_new = dl_symbol("gtk_file_filter_new");
+        fp_gtk_file_chooser_set_do_overwrite_confirmation = dl_symbol(
+                        "gtk_file_chooser_set_do_overwrite_confirmation");
+        fp_gtk_file_chooser_set_select_multiple = dl_symbol(
+                        "gtk_file_chooser_set_select_multiple");
+        fp_gtk_file_chooser_get_current_folder = dl_symbol(
+                        "gtk_file_chooser_get_current_folder");
+        fp_gtk_file_chooser_get_filenames = dl_symbol(
+                        "gtk_file_chooser_get_filenames");
+        fp_gtk_g_slist_length = dl_symbol("g_slist_length");
+}
+
 gboolean gtk2_load()
 {
     gboolean result;
     int i;
     int (*handler)();
     int (*io_handler)();
     char *gtk_modules_env;
 
     gtk2_libhandle = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL);
-    if (gtk2_libhandle == NULL)
+    gthread_libhandle = dlopen(GTHREAD_LIB, RTLD_LAZY | RTLD_LOCAL);
+
+    if (gtk2_libhandle == NULL || gthread_libhandle == NULL)
         return FALSE;
 
     if (setjmp(j) == 0)
     {
         fp_gtk_check_version = dl_symbol("gtk_check_version");

@@ -595,10 +630,33 @@
         fp_gtk_widget_size_request =
             dl_symbol("gtk_widget_size_request");
         fp_gtk_range_get_adjustment =
             dl_symbol("gtk_range_get_adjustment");
 
+        fp_gtk_widget_hide = dl_symbol("gtk_widget_hide");
+        fp_gtk_main_quit = dl_symbol("gtk_main_quit");
+        fp_g_signal_connect_data = dl_symbol("g_signal_connect_data");
+        fp_gtk_widget_show = dl_symbol("gtk_widget_show");
+        fp_gtk_main = dl_symbol("gtk_main");
+
+        /**
+         * GLib thread system
+         */
+        fp_g_thread_get_initialized = dl_symbol_gthread("g_thread_get_initialized");
+        fp_g_thread_init = dl_symbol_gthread("g_thread_init");
+        fp_gdk_threads_init = dl_symbol("gdk_threads_init");
+        fp_gdk_threads_enter = dl_symbol("gdk_threads_enter");
+        fp_gdk_threads_leave = dl_symbol("gdk_threads_leave");
+
+        /**
+         * Functions for sun_awt_X11_GtkFileDialogPeer.c
+         */
+        if (fp_gtk_check_version(2, 4, 0) == NULL) {
+                // The current GtkFileChooser is available from GTK+ 2.4
+                gtk2_file_chooser_load();
+        }
+
         /* Some functions may be missing in pre-2.4 GTK.
            We handle them specially here.
          */
         fp_gtk_combo_box_new = dlsym(gtk2_libhandle, "gtk_combo_box_new");
         if (fp_gtk_combo_box_new == NULL) {

@@ -624,10 +682,14 @@
      */
     else
     {
         dlclose(gtk2_libhandle);
         gtk2_libhandle = NULL;
+
+        dlclose(gthread_libhandle);
+        gthread_libhandle = NULL;
+        
         return FALSE;
     }
 
     /*
      * Strip the AT-SPI GTK_MODULEs if present

@@ -676,10 +738,23 @@
      * BadMatch errors which we would normally ignore. The IO error handler
      * is preserved here, too, just for consistency.
     */
     handler = XSetErrorHandler(NULL);
     io_handler = XSetIOErrorHandler(NULL);
+
+    if (fp_gtk_check_version(2, 2, 0) == NULL)
+    {
+        // Init the thread system to use GLib in a thread-safe mode
+        if (!fp_g_thread_get_initialized())
+        {
+                fp_g_thread_init(NULL);
+
+                //According the GTK documentation, gdk_threads_init() should be
+                //called before gtk_init() or gtk_init_check()
+                fp_gdk_threads_init();
+        }
+    }
     result = (*fp_gtk_init_check)(NULL, NULL);
 
     XSetErrorHandler(handler);
     XSetIOErrorHandler(io_handler);
 

@@ -720,10 +795,11 @@
         gtk2_window = NULL;
     }
 
     dlerror();
     dlclose(gtk2_libhandle);
+    dlclose(gthread_libhandle);
     if ((gtk2_error = dlerror()) != NULL)
     {
         return FALSE;
     }
     return TRUE;