--- src/interfaces/gtk/ec_gtk.c 2005-06-06 14:07:06 +0000 +++ src/interfaces/gtk/ec_gtk.c 2010-08-08 02:56:21 +0000 @@ -20,6 +20,8 @@ $Id: ec_gtk.c,v 1.39 2004/12/21 11:24:02 alor Exp $ */ +#include + #include #include @@ -45,7 +47,10 @@ static GtkTextBuffer *msgbuffer = NULL; static GtkTextMark *endmark = NULL; static GtkAccelGroup *accel_group = NULL; + static gboolean progress_cancelled = FALSE; +static GtkWidget *progress_dialog = NULL; +static GtkWidget *progress_bar = NULL; /* proto */ @@ -64,7 +69,7 @@ static void gtkui_error(const char *msg); static void gtkui_fatal_error(const char *msg); static gboolean gtkui_flush_msg(gpointer data); -static int gtkui_progress(char *title, int value, int max); +static void gtkui_progress(char *title, int value, int max); static void gtkui_setup(void); @@ -102,6 +107,134 @@ static void gtkui_page_defocus_tabs(void); #endif +/* wrapper functions which inject the real function call into the main + idle loop, ensuring only the main thread performs GTK operations +*/ + +static gboolean gtkui_cleanup_shim(gpointer data) { + gtkui_cleanup(); + return FALSE; +} + +static void gtkui_cleanup_wrap(void) { + g_idle_add(gtkui_cleanup_shim, NULL); +} + +static gboolean gtkui_msg_shim(gpointer data) { + gtkui_msg(data); + free(data); + return FALSE; +} + +static void gtkui_msg_wrap(const char *msg) { + + char *copy = strdup(msg); + if (msg) { + g_idle_add(gtkui_msg_shim, copy); + } else { + FATAL_ERROR("out of memory"); + } +} + +static gboolean gtkui_error_shim(gpointer data) { + gtkui_error(data); + free(data); + return FALSE; +} + +static void gtkui_error_wrap(const char *msg) { + + char *copy = strdup(msg); + if (msg) { + g_idle_add(gtkui_error_shim, copy); + } else { + FATAL_ERROR("out of memory"); + } +} + +static gboolean gtkui_fatal_error_shim(gpointer data) { + gtkui_fatal_error(data); + free(data); + return FALSE; +} + +static void gtkui_fatal_error_wrap(const char *msg) { + + char *copy = strdup(msg); + if (msg) { + g_idle_add(gtkui_fatal_error_shim, copy); + } else { + FATAL_ERROR("out of memory"); + } +} + +struct gtkui_input_data { + const char *title; + char *input; + size_t n; + void (*callback)(void); +}; + +static gboolean gtkui_input_shim(gpointer data) { + + struct gtkui_input_data *gid = data; + gtkui_input(gid->title, gid->input, gid->n, gid->callback); + free(gid); + return FALSE; +} + +static void gtkui_input_wrap(const char *title, char *input, size_t n, void (*callback)(void)) { + + struct gtkui_input_data *gid = malloc(sizeof *gid); + if (gid) { + gid->title = title; + gid->input = input; + gid->n = n; + gid->callback = callback; + g_idle_add(gtkui_input_shim, gid); + } else { + FATAL_ERROR("out of memory"); + } +} + +struct gtkui_progress_data { + char *title; + int value; + int max; +}; + +static gboolean gtkui_progress_shim(gpointer data) { + + struct gtkui_progress_data *gpd = data; + gtkui_progress(gpd->title, gpd->value, gpd->max); + free(gpd); + return FALSE; +} + +static int gtkui_progress_wrap(char *title, int value, int max) { + + struct gtkui_progress_data *gpd; + + if (progress_cancelled == TRUE) { + progress_cancelled = FALSE; + return UI_PROGRESS_INTERRUPTED; + } + + gpd = malloc(sizeof *gpd); + if (gpd) { + gpd->title = title; + gpd->value = value; + gpd->max = max; + g_idle_add(gtkui_progress_shim, gpd); + } else { + FATAL_ERROR("out of memory"); + } + + return value == max + ? UI_PROGRESS_FINISHED + : UI_PROGRESS_UPDATED; +} + /***#****************************************/ void set_gtk_interface(void) @@ -114,12 +247,12 @@ /* register the functions */ ops.init = >kui_init; ops.start = >kui_start; - ops.cleanup = >kui_cleanup; - ops.msg = >kui_msg; - ops.error = >kui_error; - ops.fatal_error = >kui_fatal_error; - ops.input = >kui_input; - ops.progress = >kui_progress; + ops.cleanup = >kui_cleanup_wrap; + ops.msg = >kui_msg_wrap; + ops.error = >kui_error_wrap; + ops.fatal_error = >kui_fatal_error_wrap; + ops.input = >kui_input_wrap; + ops.progress = >kui_progress_wrap; ops.type = UI_GTK; ui_register(&ops); @@ -134,7 +267,6 @@ DEBUG_MSG("gtk_init"); g_thread_init(NULL); - gdk_threads_init(); if(!gtk_init_check(0, NULL)) { FATAL_ERROR("GTK+ failed to initialize. Is X running?"); @@ -148,9 +280,7 @@ /* gui init loop, calling gtk_main_quit will cause * this to exit so we can proceed to the main loop * later. */ - gdk_threads_enter(); gtk_main(); - gdk_threads_leave(); /* remove the keyboard shortcuts for the setup menus */ gtk_window_remove_accel_group(GTK_WINDOW (window), accel_group); @@ -311,29 +441,10 @@ /* * show or update the progress bar */ -static int gtkui_progress(char *title, int value, int max) +static void gtkui_progress(char *title, int value, int max) { - static GtkWidget *progress_dialog = NULL; - static GtkWidget *progress_bar = NULL; static GtkWidget *hbox, *button; -#ifndef OS_MINGW - /* FIXME: try to understand why it does not work under mingw. - * (look even in ec_scan.c - */ - gdk_threads_enter(); -#endif - - if (progress_cancelled == TRUE) { - progress_dialog = NULL; - progress_bar = NULL; - progress_cancelled = FALSE; -#ifndef OS_MINGW - gdk_threads_leave(); -#endif - return UI_PROGRESS_INTERRUPTED; - } - /* the first time, create the object */ if (progress_bar == NULL) { progress_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); @@ -363,14 +474,10 @@ gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progress_bar), title); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (progress_bar), (gdouble)((gdouble)value / (gdouble)max)); -#ifndef OS_MINGW - gdk_threads_leave(); -#else /* a nasty little loop that lets gtk update the progress bar immediately */ while (gtk_events_pending ()) gtk_main_iteration (); -#endif - + /* * when 100%, destroy it */ @@ -378,21 +485,18 @@ gtk_widget_destroy(progress_dialog); progress_dialog = NULL; progress_bar = NULL; -#ifndef OS_MINGW - gdk_threads_leave(); -#endif - return UI_PROGRESS_FINISHED; } - - return UI_PROGRESS_UPDATED; } static gboolean gtkui_progress_cancel(GtkWidget *window, gpointer data) { progress_cancelled = TRUE; /* the progress dialog must be manually destroyed if the cancel button is used */ - if(data != NULL && GTK_IS_WIDGET(data)) - gtk_widget_destroy(data); + if(data != NULL && GTK_IS_WIDGET(data)) { + gtk_widget_destroy(data); + progress_dialog = NULL; + progress_bar = NULL; + } return(FALSE); } @@ -437,9 +541,7 @@ gtkui_sniff_live(); /* the main gui loop, once this exits the gui will be destroyed */ - gdk_threads_enter(); gtk_main(); - gdk_threads_leave(); gtk_timeout_remove(idle_flush); } --- src/interfaces/gtk/ec_gtk_view_connections.c 2005-06-06 14:07:06 +0000 +++ src/interfaces/gtk/ec_gtk_view_connections.c 2010-08-08 02:53:30 +0000 @@ -900,12 +900,10 @@ ret = GBL_FORMAT(po->DATA.disp_data, po->DATA.disp_len, dispbuf); dispbuf[ret] = 0; - gdk_threads_enter(); if (!ip_addr_cmp(&po->L3.src, &curr_conn->L3_addr1)) gtkui_data_print(1, dispbuf, 0); else gtkui_data_print(2, dispbuf, 0); - gdk_threads_leave(); } /* @@ -1066,13 +1064,11 @@ /* format the data */ ret = GBL_FORMAT(po->DATA.disp_data, po->DATA.disp_len, dispbuf); dispbuf[ret] = 0; - - gdk_threads_enter(); + if (!ip_addr_cmp(&po->L3.src, &curr_conn->L3_addr1)) gtkui_data_print(3, dispbuf, 1); else gtkui_data_print(3, dispbuf, 2); - gdk_threads_leave(); } /*