X-Git-Url: http://git.samba.org/samba.git/?p=obnox%2Fwireshark%2Fwip.git;a=blobdiff_plain;f=gtk%2Fmain_welcome.c;h=a47ae9e203f29e9758df877428702b216755cbea;hp=95b6494ea77ca2fc81347007051371a4efd5c395;hb=1c8f4c4a6482dc1e7eed0e5704735a04fc20cb0a;hpb=bdf13df58cd96f68222524b3e14956b2c9c9684e;ds=sidebyside diff --git a/gtk/main_welcome.c b/gtk/main_welcome.c index 95b6494ea7..a47ae9e203 100644 --- a/gtk/main_welcome.c +++ b/gtk/main_welcome.c @@ -35,10 +35,12 @@ #include #include "../color.h" +#ifdef HAVE_LIBPCAP #include "capture.h" #include "capture-pcap-util.h" #include "capture_opts.h" #include "capture_ui_utils.h" +#endif #include "simple_dialog.h" #include @@ -47,38 +49,56 @@ #include "gtk/recent.h" #include "gtk/gtkglobals.h" #include "gtk/main.h" -#include "gtk/main_menu.h" +#include "gtk/menus.h" #include "gtk/main_welcome.h" -#include "gtk/capture_dlg.h" -#include "gtk/capture_if_dlg.h" -#include "gtk/capture_file_dlg.h" #include "gtk/help_dlg.h" +#include "gtk/capture_file_dlg.h" #include "gtk/stock_icons.h" +#include "gtk/utf8_entities.h" +#ifdef HAVE_LIBPCAP +#include "gtk/capture_dlg.h" +#include "gtk/capture_if_dlg.h" #include "gtk/capture_globals.h" +#endif #include "../image/wssplash-dev.xpm" #include "../version_info.h" +#ifdef _WIN32 +#include +#include +#endif + #ifdef HAVE_AIRPCAP #include "airpcap.h" #include "airpcap_loader.h" #include "airpcap_gui_utils.h" +#include "../image/toolbar/capture_airpcap_16.xpm" #endif /* XXX */ extern gint if_list_comparator_alph (const void *first_arg, const void *second_arg); - -static GdkColor header_bar_bg; -static GdkColor topic_header_bg; -static GdkColor topic_content_bg; +static GtkWidget *welcome_hb = NULL; +static GtkWidget *header_lb = NULL; +/* Foreground colors are set using Pango markup */ +static GdkColor welcome_bg = { 0, 0xe6e6, 0xe6e6, 0xe6e6 }; +static GdkColor header_bar_bg = { 0, 0x1818, 0x5c5c, 0xcaca }; +static GdkColor topic_header_bg = { 0, 0x0101, 0x3939, 0xbebe }; +static GdkColor topic_content_bg = { 0, 0xffff, 0xffff, 0xffff }; static GdkColor topic_item_idle_bg; -static GdkColor topic_item_entered_bg; +static GdkColor topic_item_entered_bg = { 0, 0xd3d3, 0xd8d8, 0xdada }; static GtkWidget *welcome_file_panel_vb = NULL; #ifdef HAVE_LIBPCAP static GtkWidget *welcome_if_panel_vb = NULL; +static GtkWidget *if_view = NULL; #endif +static GSList *status_messages = NULL; + +#ifdef USE_THREADS +static GMutex *recent_mtx = NULL; +#endif /* The "scroll box dynamic" is a (complicated) pseudo widget to */ /* place a vertically list of widgets in (currently the interfaces and recent files). */ @@ -91,10 +111,10 @@ static GtkWidget *welcome_if_panel_vb = NULL; #define SCROLL_BOX_MAX_CHILDS "ScrollBoxDynamic_MaxChilds" #define SCROLL_BOX_SCROLLW_Y_SIZE "ScrollBoxDynamic_Scrollw_Y_Size" #define SCROLL_BOX_SCROLLW "ScrollBoxDynamic_Scrollw" - +#define TREE_VIEW_INTERFACES "TreeViewInterfaces" static GtkWidget * -scroll_box_dynamic_new(GtkBox *child_box, guint max_childs, guint scrollw_y_size) { +scroll_box_dynamic_new(GtkWidget *child_box, guint max_childs, guint scrollw_y_size) { GtkWidget * parent_box; @@ -108,6 +128,7 @@ scroll_box_dynamic_new(GtkBox *child_box, guint max_childs, guint scrollw_y_size return parent_box; } + static GtkWidget * scroll_box_dynamic_add(GtkWidget *parent_box) { @@ -118,7 +139,6 @@ scroll_box_dynamic_add(GtkWidget *parent_box) guint scrollw_y_size; GList *childs; - child_box = g_object_get_data(G_OBJECT(parent_box), SCROLL_BOX_CHILD_BOX); max_cnt = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(parent_box), SCROLL_BOX_MAX_CHILDS)); @@ -133,13 +153,13 @@ scroll_box_dynamic_add(GtkWidget *parent_box) /* XXX - there's no way to get rid of the shadow frame - except for creating an own widget :-( */ scrollw = scrolled_window_new(NULL, NULL); scrollw_y_size = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(parent_box), SCROLL_BOX_SCROLLW_Y_SIZE)); - gtk_widget_set_usize(scrollw, -1, scrollw_y_size); + gtk_widget_set_size_request(scrollw, -1, scrollw_y_size); g_object_set_data(G_OBJECT(parent_box), SCROLL_BOX_SCROLLW, scrollw); gtk_box_pack_start(GTK_BOX(parent_box), scrollw, TRUE, TRUE, 0); /* move child_box from parent_box into scrolled window */ - gtk_widget_ref(child_box); + g_object_ref(child_box); gtk_container_remove(GTK_CONTAINER(parent_box), child_box); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollw), child_box); @@ -149,6 +169,7 @@ scroll_box_dynamic_add(GtkWidget *parent_box) return child_box; } + static GtkWidget * scroll_box_dynamic_reset(GtkWidget *parent_box) { @@ -160,7 +181,7 @@ scroll_box_dynamic_reset(GtkWidget *parent_box) if(scrollw != NULL) { /* move the child_box back from scrolled window into the parent_box */ - gtk_widget_ref(child_box); + g_object_ref(child_box); gtk_container_remove(GTK_CONTAINER(parent_box), scrollw); g_object_set_data(G_OBJECT(parent_box), SCROLL_BOX_SCROLLW, NULL); gtk_box_pack_start(GTK_BOX(parent_box), child_box, TRUE, TRUE, 0); @@ -170,8 +191,6 @@ scroll_box_dynamic_reset(GtkWidget *parent_box) } - - /* mouse entered this widget - change background color */ static gboolean welcome_item_enter_cb(GtkWidget *eb, GdkEventCrossing *event _U_, gpointer user_data _U_) @@ -181,9 +200,10 @@ welcome_item_enter_cb(GtkWidget *eb, GdkEventCrossing *event _U_, gpointer user_ return FALSE; } + /* mouse has left this widget - change background color */ static gboolean -welcome_item_leave_cb(GtkWidget *eb, GdkEvent *event _U_, gpointer user_data _U_) +welcome_item_leave_cb(GtkWidget *eb, GdkEventCrossing *event _U_, gpointer user_data _U_) { gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg); @@ -191,18 +211,18 @@ welcome_item_leave_cb(GtkWidget *eb, GdkEvent *event _U_, gpointer user_data _U_ } +typedef gboolean (*welcome_button_callback_t) (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + /* create a "button widget" */ static GtkWidget * welcome_button(const gchar *stock_item, - const gchar * title, const gchar * subtitle, const gchar *tooltip, - GtkSignalFunc callback, void *callback_data) + const gchar *title, const gchar *subtitle, const gchar *tooltip, + welcome_button_callback_t welcome_button_callback, gpointer welcome_button_callback_data) { GtkWidget *eb, *w, *item_hb, *text_vb; gchar *formatted_text; - GtkTooltips *tooltips; - - - tooltips = gtk_tooltips_new(); item_hb = gtk_hbox_new(FALSE, 1); @@ -211,12 +231,12 @@ welcome_button(const gchar *stock_item, gtk_container_add(GTK_CONTAINER(eb), item_hb); gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg); if(tooltip != NULL) { - gtk_tooltips_set_tip(tooltips, eb, tooltip, ""); + gtk_widget_set_tooltip_text(eb, tooltip); } g_signal_connect(eb, "enter-notify-event", G_CALLBACK(welcome_item_enter_cb), NULL); g_signal_connect(eb, "leave-notify-event", G_CALLBACK(welcome_item_leave_cb), NULL); - g_signal_connect(eb, "button-press-event", G_CALLBACK(callback), callback_data); + g_signal_connect(eb, "button-release-event", G_CALLBACK(welcome_button_callback), welcome_button_callback_data); /* icon */ w = gtk_image_new_from_stock(stock_item, GTK_ICON_SIZE_LARGE_TOOLBAR); @@ -226,7 +246,7 @@ welcome_button(const gchar *stock_item, /* title */ w = gtk_label_new(title); - gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5); + gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.5f); formatted_text = g_strdup_printf("%s", title); gtk_label_set_markup(GTK_LABEL(w), formatted_text); g_free(formatted_text); @@ -234,7 +254,7 @@ welcome_button(const gchar *stock_item, /* subtitle */ w = gtk_label_new(subtitle); - gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5); + gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.5f); formatted_text = g_strdup_printf("%s", subtitle); gtk_label_set_markup(GTK_LABEL(w), formatted_text); g_free(formatted_text); @@ -246,6 +266,49 @@ welcome_button(const gchar *stock_item, } +/* Hack to handle welcome-button "button-release-event" callback */ +/* 1. Dispatch to desired actual callback */ +/* 2. Return TRUE for the event callback. */ +/* user_data: actual (no arg) callback fcn to be invoked. */ +static gboolean +welcome_button_callback_helper(GtkWidget *w, GdkEventButton *event _U_, gpointer user_data) +{ + void (*funct)(GtkWidget *, gpointer) = user_data; + (*funct)(w, NULL); + return TRUE; +} + + +void +welcome_header_set_message(gchar *msg) { + GString *message; + time_t secs = time(NULL); + struct tm *now = localtime(&secs); + + message = g_string_new(""); + + if (msg) { + g_string_append(message, msg); + } else { /* Use our default header */ + if ((now->tm_mon == 3 && now->tm_mday == 1) || (now->tm_mon == 6 && now->tm_mday == 14)) { + g_string_append(message, "Sniffing the glue that holds the Internet together"); + } else { + g_string_append(message, prefs.gui_start_title); + } + + if (prefs.gui_version_in_start_page) { + g_string_append_printf(message, "\nVersion " VERSION "%s", + wireshark_svnversion); + } + } + + g_string_append(message, ""); + + gtk_label_set_markup(GTK_LABEL(header_lb), message->str); + g_string_free(message, TRUE); +} + + /* create the banner "above our heads" */ static GtkWidget * welcome_header_new(void) @@ -254,10 +317,6 @@ welcome_header_new(void) GtkWidget *item_hb; GtkWidget *eb; GtkWidget *icon; - GString *message; - GtkWidget *w; - time_t secs = time(NULL); - struct tm *now = localtime(&secs); item_vb = gtk_vbox_new(FALSE, 0); @@ -272,28 +331,48 @@ welcome_header_new(void) icon = xpm_to_widget_from_parent(top_level, wssplash_xpm); gtk_box_pack_start(GTK_BOX(item_hb), icon, FALSE, FALSE, 10); - message = g_string_new(""); - if ((now->tm_mon == 3 && now->tm_mday == 1) || (now->tm_mon == 6 && now->tm_mday == 14)) { - g_string_append(message, "Sniffing the glue that holds the Internet together"); - } else { - g_string_append(message, prefs.gui_start_title); - } - g_string_append(message, ""); + header_lb = gtk_label_new(NULL); + welcome_header_set_message(NULL); + gtk_label_set_selectable(GTK_LABEL(header_lb), TRUE); + gtk_misc_set_alignment(GTK_MISC(header_lb), 0.0f, 0.5f); + gtk_box_pack_start(GTK_BOX(item_hb), header_lb, TRUE, TRUE, 5); + + gtk_widget_show_all(eb); + + return eb; +} + + +void +welcome_header_push_msg(const gchar *msg) { + gchar *msg_copy = g_strdup(msg); + + status_messages = g_slist_append(status_messages, msg_copy); - if (prefs.gui_version_in_start_page) { - g_string_append_printf(message, "\nVersion " VERSION "%s", - wireshark_svnversion); + welcome_header_set_message(msg_copy); + + gtk_widget_hide(welcome_hb); +} + + +void +welcome_header_pop_msg(void) { + gchar *msg = NULL; + + if (status_messages) { + g_free(status_messages->data); + status_messages = g_slist_delete_link(status_messages, status_messages); } - w = gtk_label_new(message->str); - gtk_label_set_markup(GTK_LABEL(w), message->str); - g_string_free(message, TRUE); - gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5); - gtk_box_pack_start(GTK_BOX(item_hb), w, TRUE, TRUE, 5); + if (status_messages) { + msg = status_messages->data; + } - gtk_widget_show_all(eb); + welcome_header_set_message(msg); - return eb; + if (!status_messages) { + gtk_widget_show(welcome_hb); + } } @@ -307,7 +386,7 @@ welcome_topic_header_new(const char *header) w = gtk_label_new(header); - formatted_message = g_strdup_printf("%s", header); + formatted_message = g_strdup_printf("%s", header); gtk_label_set_markup(GTK_LABEL(w), formatted_message); g_free(formatted_message); @@ -351,78 +430,206 @@ welcome_topic_new(const char *header, GtkWidget **to_fill) /* a file link was pressed */ static gboolean -welcome_filename_link_press_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data) +welcome_filename_link_press_cb(GtkWidget *widget _U_, GdkEventButton *event _U_, gpointer data) { menu_open_filename(data); return FALSE; } - -/* create a "file link widget" */ -static GtkWidget * -welcome_filename_link_new(const gchar *filename, GtkWidget **label) +typedef struct _recent_item_status { + gchar *filename; + GtkWidget *label; + GObject *menu_item; + GString *str; + gboolean stat_done; + int err; + guint timer; +} recent_item_status; + +/* + * Fetch the status of a file. + * This function might be called as a thread. We can't use any drawing + * routines here: http://developer.gnome.org/gdk/2.24/gdk-Threads.html + */ +static void *get_recent_item_status(void *data) { - GtkWidget *w; - GtkWidget *eb; - GString *str; - const unsigned int max = 60; + recent_item_status *ri_stat = (recent_item_status *) data; + ws_statb64 stat_buf; int err; - struct stat stat_buf; - GtkTooltips *tooltips; - - - tooltips = gtk_tooltips_new(); - /* filename */ - str = g_string_new(filename); - - /* cut max filename length */ - if( (str->len > max) && (str->len-(max) > 5) ) { - g_string_erase(str, 20, str->len-(max+5)); - g_string_insert(str, 20, " ... "); + if (!ri_stat) { + return NULL; } - /* add file size */ - err = ws_stat(filename, &stat_buf); + /* + * Add file size. We use binary prefixes instead of IEC because that's what + * most OSes use. + */ + err = ws_stat64(ri_stat->filename, &stat_buf); +#ifdef USE_THREADS + g_mutex_lock(recent_mtx); +#endif + ri_stat->err = err; if(err == 0) { - if (stat_buf.st_size/1024/1024 > 10) { - g_string_append_printf(str, " %" G_GINT64_MODIFIER "dMB", (gint64) (stat_buf.st_size/1024/1024)); + if (stat_buf.st_size/1024/1024/1024 > 10) { + g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d GB)", (gint64) (stat_buf.st_size/1024/1024/1024)); + } else if (stat_buf.st_size/1024/1024 > 10) { + g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d MB)", (gint64) (stat_buf.st_size/1024/1024)); } else if (stat_buf.st_size/1024 > 10) { - g_string_append_printf(str, " %" G_GINT64_MODIFIER "dKB", (gint64) (stat_buf.st_size/1024)); + g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d KB)", (gint64) (stat_buf.st_size/1024)); } else { - g_string_append_printf(str, " %" G_GINT64_MODIFIER "d Bytes", (gint64) (stat_buf.st_size)); + g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d Bytes)", (gint64) (stat_buf.st_size)); } + /* pango format string */ + g_string_prepend(ri_stat->str, ""); + g_string_append(ri_stat->str, ""); } else { - g_string_append(str, " [not found]"); + g_string_append(ri_stat->str, " [not found]"); } - /* pango format string */ - if(err == 0) { - g_string_prepend(str, ""); - g_string_append(str, ""); + if (!ri_stat->label) { /* The widget went away while we were busy. */ + g_free(ri_stat->filename); + g_string_free(ri_stat->str, TRUE); + g_free(ri_stat); + } else { + ri_stat->stat_done = TRUE; + } +#ifdef USE_THREADS + g_mutex_unlock(recent_mtx); +#endif + + return NULL; +} + +/* Timeout callback for recent items */ +static gboolean +update_recent_items(gpointer data) +{ + recent_item_status *ri_stat = (recent_item_status *) data; + gboolean again = TRUE; + + if (!ri_stat) { + return FALSE; + } + +#ifdef USE_THREADS + g_mutex_lock(recent_mtx); +#endif + if (ri_stat->stat_done) { + again = FALSE; + gtk_label_set_markup(GTK_LABEL(ri_stat->label), ri_stat->str->str); + if (ri_stat->err == 0) { + gtk_widget_set_sensitive(ri_stat->label, TRUE); +#ifdef MAIN_MENU_USE_UIMANAGER + gtk_action_set_sensitive((GtkAction *) ri_stat->menu_item, TRUE); +#else + gtk_widget_set_sensitive(GTK_WIDGET(ri_stat->menu_item), TRUE); +#endif + } + ri_stat->timer = 0; + } + /* Else append some sort of Unicode or ASCII animation to the label? */ +#ifdef USE_THREADS + g_mutex_unlock(recent_mtx); +#endif + return again; +} + +static void welcome_filename_destroy_cb(GtkWidget *w _U_, gpointer data) { + recent_item_status *ri_stat = (recent_item_status *) data; + + if (!ri_stat) { + return; + } + +#ifdef USE_THREADS + g_mutex_lock(recent_mtx); +#endif + if (ri_stat->timer) { + g_source_remove(ri_stat->timer); + ri_stat->timer = 0; + } + + g_object_unref(ri_stat->menu_item); + + if (ri_stat->stat_done) { + g_free(ri_stat->filename); + g_string_free(ri_stat->str, TRUE); + g_free(ri_stat); + } else { + ri_stat->label = NULL; + } +#ifdef USE_THREADS + g_mutex_unlock(recent_mtx); +#endif +} + +/* create a "file link widget" */ +static GtkWidget * +welcome_filename_link_new(const gchar *filename, GtkWidget **label, GObject *menu_item) +{ + GtkWidget *w; + GtkWidget *eb; + GString *str; + gchar *str_escaped; + glong uni_len; + gsize uni_start, uni_end; + const glong max = 60; + recent_item_status *ri_stat; + + /* filename */ + str = g_string_new(filename); + uni_len = g_utf8_strlen(str->str, str->len); + + /* cut max filename length */ + if (uni_len > max) { + uni_start = g_utf8_offset_to_pointer(str->str, 20) - str->str; + uni_end = g_utf8_offset_to_pointer(str->str, uni_len - max) - str->str; + g_string_erase(str, uni_start, uni_end); + g_string_insert(str, uni_start, " " UTF8_HORIZONTAL_ELLIPSIS " "); } + /* escape the possibly shortened filename before adding pango language */ + str_escaped=g_markup_escape_text(str->str, -1); + g_string_free(str, TRUE); + /* label */ - w = gtk_label_new(str->str); + w = gtk_label_new(str_escaped); *label = w; - gtk_label_set_markup(GTK_LABEL(w), str->str); gtk_misc_set_padding(GTK_MISC(w), 5, 2); + gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.0f); + gtk_widget_set_sensitive(w, FALSE); + + ri_stat = g_malloc(sizeof(recent_item_status)); + ri_stat->filename = g_strdup(filename); + ri_stat->label = w; + ri_stat->menu_item = menu_item; + ri_stat->str = g_string_new(str_escaped); + ri_stat->stat_done = FALSE; + ri_stat->timer = 0; + g_object_ref(G_OBJECT(menu_item)); + g_signal_connect(w, "destroy", G_CALLBACK(welcome_filename_destroy_cb), ri_stat); + g_free(str_escaped); + +#ifdef USE_THREADS + g_thread_create(get_recent_item_status, ri_stat, FALSE, NULL); + ri_stat->timer = g_timeout_add(200, update_recent_items, ri_stat); +#else + get_recent_item_status(ri_stat); + update_recent_items(ri_stat); +#endif - /* event box */ + /* event box */ eb = gtk_event_box_new(); + gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg); gtk_container_add(GTK_CONTAINER(eb), w); - gtk_tooltips_set_tip(tooltips, eb, filename, ""); - if(err != 0) { - gtk_widget_set_sensitive(w, FALSE); - } + gtk_widget_set_tooltip_text(eb, filename); g_signal_connect(eb, "enter-notify-event", G_CALLBACK(welcome_item_enter_cb), w); g_signal_connect(eb, "leave-notify-event", G_CALLBACK(welcome_item_leave_cb), w); g_signal_connect(eb, "button-press-event", G_CALLBACK(welcome_filename_link_press_cb), (gchar *) filename); - g_string_free(str, TRUE); - return eb; } @@ -453,162 +660,250 @@ main_welcome_reset_recent_capture_files(void) /* add a new file to the list of recent files */ void -main_welcome_add_recent_capture_files(const char *widget_cf_name) +main_welcome_add_recent_capture_file(const char *widget_cf_name, GObject *menu_item) { GtkWidget *w; GtkWidget *child_box; GtkWidget *label; - w = welcome_filename_link_new(widget_cf_name, &label); - gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_item_idle_bg); - gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0); + w = welcome_filename_link_new(widget_cf_name, &label, menu_item); child_box = scroll_box_dynamic_add(welcome_file_panel_vb); gtk_box_pack_start(GTK_BOX(child_box), w, FALSE, FALSE, 0); gtk_widget_show_all(w); gtk_widget_show_all(child_box); } - #ifdef HAVE_LIBPCAP -/* user clicked on an interface button */ -static gboolean -welcome_if_press_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data) +static gboolean select_current_ifaces(GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer userdata) { - if (global_capture_opts.iface) - g_free(global_capture_opts.iface); - if (global_capture_opts.iface_descr) - g_free(global_capture_opts.iface_descr); - - global_capture_opts.iface = g_strdup(data); - global_capture_opts.iface_descr = NULL; - /* XXX - fix this */ - /*global_capture_opts.iface_descr = get_interface_descriptive_name(global_capture_opts.iface);*/ - - /* XXX - remove this? */ - if (global_capture_opts.save_file) { - g_free(global_capture_opts.save_file); - global_capture_opts.save_file = NULL; + guint i; + gchar *if_name; + gboolean found = FALSE; + + GtkTreeSelection *selection = (GtkTreeSelection *)userdata; + gtk_tree_model_get (model, iter, IFACE_NAME, &if_name, -1); + for (i = 0; i < global_capture_opts.ifaces->len; i++) { + if (strcmp(g_array_index(global_capture_opts.ifaces, interface_options, i).name, if_name) == 0) { + if (!gtk_tree_selection_path_is_selected(selection, path)) { + gtk_tree_selection_select_iter(selection, iter); + } + found = TRUE; + break; + } + } + if (!found) { + gtk_tree_selection_unselect_iter(selection, iter); } - -#ifdef HAVE_AIRPCAP - airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, global_capture_opts.iface); - airpcap_if_selected = airpcap_if_active; - airpcap_set_toolbar_start_capture(airpcap_if_active); -#endif - - capture_start_cb(NULL, NULL); - return FALSE; } - -/* create a single interface entry */ -static GtkWidget * -welcome_if_new(const if_info_t *if_info, const gchar *user_descr, GdkColor *topic_bg _U_, gpointer interf) +gboolean on_selection_changed(GtkTreeSelection *selection _U_, + GtkTreeModel *model, + GtkTreePath *path, + gboolean path_currently_selected, + gpointer data _U_) { - GtkWidget *interface_hb; - GtkWidget *w; - GString *message; - GtkWidget *eb; - - - /* event box */ - eb = gtk_event_box_new(); - gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg); - - g_signal_connect(eb, "enter-notify-event", G_CALLBACK(welcome_item_enter_cb), NULL); - g_signal_connect(eb, "leave-notify-event", G_CALLBACK(welcome_item_leave_cb), NULL); - g_signal_connect(eb, "button-press-event", G_CALLBACK(welcome_if_press_cb), interf); - - interface_hb = gtk_hbox_new(FALSE, 5); - gtk_container_add(GTK_CONTAINER(eb), interface_hb); - - /* icon */ - w = capture_get_if_icon(if_info); - gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 5); - - if (user_descr != NULL) - message = g_string_new(user_descr); - else if (if_info->description != NULL) - message = g_string_new(if_info->description); - else - message = g_string_new(if_info->name); - - /* truncate string if it's too long */ - /* (the number of chars is a bit arbitrary, though) */ - if(message->len > 48) { - g_string_truncate(message, 45); - g_string_append (message, " ..."); + GtkTreeIter iter; + gchar *if_name; + interface_options interface_opts; + guint i; + cap_settings_t cap_settings; + gboolean found = FALSE; + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, IFACE_NAME, &if_name, -1); + for (i = 0; i < global_capture_opts.ifaces->len; i++) { + if (strcmp(g_array_index(global_capture_opts.ifaces, interface_options, i).name, if_name) == 0) { + found = TRUE; + if (path_currently_selected) { + interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i); + global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i); + if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && get_interfaces_dialog_window()) { + update_selected_interface(strdup(interface_opts.name), FALSE); + } + g_free(interface_opts.name); + g_free(interface_opts.descr); + g_free(interface_opts.cfilter); +#ifdef HAVE_PCAP_REMOTE + g_free(interface_opts.remote_host); + g_free(interface_opts.remote_port); + g_free(interface_opts.auth_username); + g_free(interface_opts.auth_password); +#endif + break; + } + } + } + if (!found && !path_currently_selected) { + interface_opts.name = g_strdup(if_name); + interface_opts.descr = get_interface_descriptive_name(interface_opts.name); + interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name); + interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter); + interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen; + interface_opts.snaplen = global_capture_opts.default_options.snaplen; + cap_settings = capture_get_cap_settings (interface_opts.name);; + interface_opts.promisc_mode = global_capture_opts.default_options.promisc_mode; +#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + interface_opts.buffer_size = global_capture_opts.default_options.buffer_size; +#endif + interface_opts.monitor_mode = cap_settings.monitor_mode; +#ifdef HAVE_PCAP_REMOTE + interface_opts.src_type = global_capture_opts.default_options.src_type; + interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host); + interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port); + interface_opts.auth_type = global_capture_opts.default_options.auth_type; + interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username); + interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password); + interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp; + interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap; + interface_opts.nocap_local = global_capture_opts.default_options.nocap_local; +#endif +#ifdef HAVE_PCAP_SETSAMPLING + interface_opts.sampling_method = global_capture_opts.default_options.sampling_method; + interface_opts.sampling_param = global_capture_opts.default_options.sampling_param; +#endif + g_array_append_val(global_capture_opts.ifaces, interface_opts); + if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && get_interfaces_dialog_window()) { + update_selected_interface(strdup(interface_opts.name), TRUE); + } } - g_string_prepend(message, ""); - g_string_append (message, ""); - w = gtk_label_new(message->str); - gtk_label_set_markup(GTK_LABEL(w), message->str); - g_string_free(message, TRUE); - - gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0); - gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0); - - return eb; + return TRUE; } - -/* load the list of interfaces */ -static void -welcome_if_panel_load(void) +static gboolean activate_ifaces(GtkTreeModel *model, + GtkTreePath *path _U_, + GtkTreeIter *iter, + gpointer userdata) { - GtkWidget *child_box; - GtkWidget *interface_hb; - - if_info_t *if_info; - GList *if_list; - int err; - gchar *err_str; - int ifs; - GList *curr; - gchar *user_descr; - - - /* LOAD THE INTERFACES */ - if_list = capture_interface_list(&err, &err_str); - if_list = g_list_sort (if_list, if_list_comparator_alph); - if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); - g_free(err_str); - return; + gchar *if_name; + GtkWidget *view; + GtkTreeSelection *selection; + selected_name_t *entry = (selected_name_t *)userdata; + + view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES); + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); + gtk_tree_model_get (model, iter, IFACE_NAME, &if_name, -1); + if (strcmp(if_name, entry->name) == 0) { + if (entry->activate) { + gtk_tree_selection_select_iter(selection, iter); + } else { + gtk_tree_selection_unselect_iter(selection, iter); + } + return TRUE; } + return FALSE; +} - /* List the interfaces */ - for(ifs = 0; (curr = g_list_nth(if_list, ifs)); ifs++) { - /*g_string_assign(if_tool_str, "");*/ - if_info = curr->data; +void change_interface_selection(gchar* name, gboolean activate) +{ + GtkWidget *view; + GtkTreeModel *model; + selected_name_t entry; + + view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES); + model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); + entry.name = strdup(name); + entry.activate = activate; + gtk_tree_model_foreach(GTK_TREE_MODEL(model), (GtkTreeModelForeachFunc)(activate_ifaces), (gpointer) &entry); +} +#endif - /* Continue if capture device is hidden */ - if (prefs_is_capture_device_hidden(if_info->name)) { - continue; - } +void +select_ifaces(void) +{ +#ifdef HAVE_LIBPCAP + GtkWidget *view; + GtkTreeModel *model; + GtkTreeSelection *entry; + + if (global_capture_opts.ifaces->len > 0) { + view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES); + model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); + entry = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); + gtk_tree_model_foreach(GTK_TREE_MODEL(model), select_current_ifaces, (gpointer) entry); + gtk_widget_grab_focus(view); + } +#endif +} - user_descr = capture_dev_user_descr_find(if_info->name); - if (user_descr) { -#ifndef _WIN32 - gchar *comment = user_descr; - user_descr = g_strdup_printf("%s (%s)", comment, if_info->name); - g_free (comment); -#endif - interface_hb = welcome_if_new(if_info, user_descr, &topic_content_bg, g_strdup(if_info->name)); - g_free (user_descr); - } else { - interface_hb = welcome_if_new(if_info, NULL, &topic_content_bg, g_strdup(if_info->name)); - } - - child_box = scroll_box_dynamic_add(welcome_if_panel_vb); - gtk_box_pack_start(GTK_BOX(child_box), interface_hb, FALSE, FALSE, 1); - } +/* list the interfaces */ +void +welcome_if_tree_load(void) +{ +#ifdef HAVE_LIBPCAP + if_info_t *if_info; + GList *if_list; + int err; + gchar *err_str = NULL; + GList *curr; + gchar *user_descr; + GtkListStore *store = NULL; + GtkTreeIter iter; + GtkWidget *icon, *view; + GtkTreeSelection *entry; + + /* LOAD THE INTERFACES */ + if_list = capture_interface_list(&err, &err_str); + if_list = g_list_sort (if_list, if_list_comparator_alph); + if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str); + g_free(err_str); + return; + } else if (err_str) { + g_free(err_str); + } + if (g_list_length(if_list) > 0) { + view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES); + entry = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); + gtk_tree_selection_unselect_all(entry); + store = gtk_list_store_new(NUMCOLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); + /* List the interfaces */ + for (curr = g_list_first(if_list); curr; curr = g_list_next(curr)) { + if_info = curr->data; + /* Continue if capture device is hidden */ + if (prefs_is_capture_device_hidden(if_info->name)) { + continue; + } + gtk_list_store_append (store, &iter); - free_interface_list(if_list); -} +#ifdef HAVE_AIRPCAP + if (get_airpcap_if_from_name(airpcap_if_list,if_info->name) != NULL) + icon = xpm_to_widget(capture_airpcap_16_xpm); + else + icon = capture_get_if_icon(if_info); +#else + icon = capture_get_if_icon(if_info); +#endif + user_descr = capture_dev_user_descr_find(if_info->name); + if (user_descr) { +#ifndef _WIN32 + gchar *comment = user_descr; + user_descr = g_strdup_printf("%s (%s)", comment, if_info->name); + g_free (comment); +#endif + gtk_list_store_set(store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, user_descr, IFACE_NAME, if_info->name, -1); + g_free (user_descr); + } else if (if_info->description) { + gtk_list_store_set (store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, if_info->description, IFACE_NAME, if_info->name, -1); + } else { + gtk_list_store_set (store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, if_info->name, IFACE_NAME, if_info->name, -1); + } + } + gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store)); + if (global_capture_opts.ifaces->len > 0) { + gtk_tree_model_foreach(GTK_TREE_MODEL(store), select_current_ifaces, (gpointer) entry); + gtk_widget_grab_focus(view); + } + gtk_tree_selection_set_select_function(entry, on_selection_changed, NULL, NULL); + } + free_interface_list(if_list); #endif /* HAVE_LIBPCAP */ +} + /* reload the list of interfaces */ void @@ -619,7 +914,6 @@ welcome_if_panel_reload(void) GList* child_list; GList* child_list_item; - if(welcome_if_panel_vb) { child_box = scroll_box_dynamic_reset(welcome_if_panel_vb); child_list = gtk_container_get_children(GTK_CONTAINER(child_box)); @@ -631,89 +925,104 @@ welcome_if_panel_reload(void) } g_list_free(child_list); - - welcome_if_panel_load(); - gtk_widget_show_all(welcome_if_panel_vb); + welcome_if_tree_load(); + gtk_widget_show_all(welcome_if_panel_vb); } #endif /* HAVE_LIBPCAP */ } +#ifdef HAVE_LIBPCAP +static void capture_if_start(GtkWidget *w _U_, gpointer data _U_) +{ +#ifdef HAVE_AIRPCAP + interface_options interface_opts; +#endif + + if (global_capture_opts.ifaces->len == 0) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "You didn't specify an interface on which to capture packets."); + return; + } +#ifndef USE_THREADS + if (global_capture_opts.ifaces->len > 1) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "You specified multiple interfaces for capturing which this version of Wireshark doesn't support."); + return; + } +#endif + + /* XXX - remove this? */ + if (global_capture_opts.save_file) { + g_free(global_capture_opts.save_file); + global_capture_opts.save_file = NULL; + } +#ifdef HAVE_AIRPCAP + interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, 0); + airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, interface_opts.name); + airpcap_if_selected = airpcap_if_active; + airpcap_set_toolbar_start_capture(airpcap_if_active); +#endif + capture_start_cb(NULL, NULL); +} +#endif /* create the welcome page */ GtkWidget * welcome_new(void) { GtkWidget *welcome_scrollw; + GtkWidget *welcome_eb; GtkWidget *welcome_vb; - GtkWidget *welcome_hb; GtkWidget *column_vb; GtkWidget *item_hb; GtkWidget *w; GtkWidget *header; GtkWidget *topic_vb; GtkWidget *topic_to_fill; -#ifdef HAVE_LIBPCAP - GtkWidget *if_child_box; -#endif /* HAVE_LIBPCAP */ GtkWidget *file_child_box; gchar *label_text; - +#ifdef _WIN32 + LONG reg_ret; + DWORD chimney_enabled = 0; + DWORD ce_size = sizeof(chimney_enabled); +#endif +#ifdef HAVE_LIBPCAP + GtkWidget *swindow; + GtkTreeSelection *selection; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GList *if_list; + int err; + gchar *err_str = NULL; +#endif /* prepare colors */ + + /* "page" background */ + get_color(&welcome_bg); + /* header bar background color */ - header_bar_bg.pixel = 0; - header_bar_bg.red = 154 * 255; - header_bar_bg.green = 210 * 255; - header_bar_bg.blue = 229 * 255; get_color(&header_bar_bg); /* topic header background color */ - topic_header_bg.pixel = 0; - topic_header_bg.red = 24 * 255; - topic_header_bg.green = 151 * 255; - topic_header_bg.blue = 192 * 255; get_color(&topic_header_bg); /* topic content background color */ - topic_content_bg.pixel = 0; - topic_content_bg.red = 221 * 255; - topic_content_bg.green = 226 * 255; - topic_content_bg.blue = 228 * 255; get_color(&topic_content_bg); - /* topic item idle background color */ - /*topic_item_idle_bg.pixel = 0; - topic_item_idle_bg.red = 216 * 255; - topic_item_idle_bg.green = 221 * 255; - topic_item_idle_bg.blue = 223 * 255; - get_color(&topic_item_idle_bg);*/ - topic_item_idle_bg = topic_content_bg; /* topic item entered color */ - topic_item_entered_bg.pixel = 0; - topic_item_entered_bg.red = 211 * 255; - topic_item_entered_bg.green = 216 * 255; - topic_item_entered_bg.blue = 218 * 255; get_color(&topic_item_entered_bg); - /*topic_item_entered_bg.pixel = 0; - topic_item_entered_bg.red = 216 * 255; - topic_item_entered_bg.green = 221 * 255; - topic_item_entered_bg.blue = 223 * 255; - get_color(&topic_item_entered_bg);*/ - - /*topic_item_entered_bg.pixel = 0; - topic_item_entered_bg.red = 154 * 255; - topic_item_entered_bg.green = 210 * 255; - topic_item_entered_bg.blue = 229 * 255; - get_color(&topic_item_entered_bg);*/ - - welcome_scrollw = scrolled_window_new(NULL, NULL); welcome_vb = gtk_vbox_new(FALSE, 0); + welcome_eb = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(welcome_eb), welcome_vb); + gtk_widget_modify_bg(welcome_eb, GTK_STATE_NORMAL, &welcome_bg); + /* header */ header = welcome_header_new(); gtk_box_pack_start(GTK_BOX(welcome_vb), header, FALSE, FALSE, 0); @@ -726,6 +1035,7 @@ welcome_new(void) /* column capture */ column_vb = gtk_vbox_new(FALSE, 10); + gtk_widget_modify_bg(column_vb, GTK_STATE_NORMAL, &welcome_bg); gtk_box_pack_start(GTK_BOX(welcome_hb), column_vb, TRUE, TRUE, 0); /* capture topic */ @@ -733,57 +1043,119 @@ welcome_new(void) gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0); #ifdef HAVE_LIBPCAP - item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_INTERFACES, - "Interface List", - "Live list of the capture interfaces (counts incoming packets)", - "Same as Capture/Interfaces menu or toolbar item", - GTK_SIGNAL_FUNC(capture_if_cb), NULL); - gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); - - label_text = g_strdup_printf("Start capture on interface:"); - w = gtk_label_new(label_text); - gtk_label_set_markup(GTK_LABEL(w), label_text); - g_free (label_text); - gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0); - gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5); + if_list = capture_interface_list(&err, &err_str); + if (g_list_length(if_list) > 0) { + item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_INTERFACES, + "Interface List", + "Live list of the capture interfaces\n(counts incoming packets)", + "Same as Capture/Interfaces menu or toolbar item", + welcome_button_callback_helper, capture_if_cb); + gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); + + swindow = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_set_size_request(swindow, FALSE, 100); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_IN); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + if_view = gtk_tree_view_new (); + g_object_set(GTK_OBJECT(if_view), "headers-visible", FALSE, NULL); + g_object_set_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES, if_view); + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes ("", + GTK_CELL_RENDERER(renderer), + "pixbuf", ICON, + NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column); + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes ("", + GTK_CELL_RENDERER(renderer), + "text", IFACE_DESCR, + NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column); + gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(if_view), 0), TRUE); + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes ("", + GTK_CELL_RENDERER(renderer), + "text", IFACE_NAME, + NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column); + gtk_tree_view_column_set_visible(column, FALSE); + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(if_view)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); +#ifdef USE_THREADS + item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_START, + "Start", + "Choose one or more interfaces to capture from, then Start", + "Same as Capture/Interfaces with default options", + (welcome_button_callback_t)capture_if_start, (gpointer)if_view); +#else + item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_START, + "Start", + "Choose exactly one interface to capture from, then Start", + "Same as Capture/Interfaces with default options", + (welcome_button_callback_t)capture_if_start, (gpointer)if_view); +#endif + gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); + welcome_if_tree_load(); + gtk_container_add (GTK_CONTAINER (swindow), if_view); + gtk_container_add(GTK_CONTAINER(topic_to_fill), swindow); + + item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_OPTIONS, + "Capture Options", + "Start a capture with detailed options", + "Same as Capture/Options menu or toolbar item", + welcome_button_callback_helper, capture_prep_cb); + gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); +#ifdef _WIN32 + /* Check for chimney offloading */ + reg_ret = RegQueryValueEx(HKEY_LOCAL_MACHINE, + _T("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\EnableTCPChimney"), + NULL, NULL, (LPBYTE) &chimney_enabled, &ce_size); + if (reg_ret == ERROR_SUCCESS && chimney_enabled) { + item_hb = welcome_button(WIRESHARK_STOCK_WIKI, + "Offloading Detected", + "TCP Chimney offloading is enabled. You \nmight not capture much data.", + topic_online_url(ONLINEPAGE_CHIMNEY), + topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_CHIMNEY)); + gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); + } +#endif /* _WIN32 */ + } else { + label_text = g_strdup("No interface can be used for capturing in\n" + "this system with the current configuration.\n\n" + "See Capture Help below for details."); + w = gtk_label_new(label_text); + gtk_label_set_markup(GTK_LABEL(w), label_text); + g_free (label_text); + gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.0f); + gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5); + } - if_child_box = gtk_vbox_new(FALSE, 0); - /* 8 capture interfaces or 150 pixels height is about the size */ - /* that still fits on a screen of about 1000*700 */ - welcome_if_panel_vb = scroll_box_dynamic_new(GTK_BOX(if_child_box), 8, 150); - gtk_box_pack_start(GTK_BOX(topic_to_fill), welcome_if_panel_vb, FALSE, FALSE, 0); - welcome_if_panel_load(); - - item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_OPTIONS, - "Capture Options", - "Start a capture with detailed options", - "Same as Capture/Options menu or toolbar item", - GTK_SIGNAL_FUNC(capture_prep_cb), NULL); - gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); + free_interface_list(if_list); /* capture help topic */ topic_vb = welcome_topic_new("Capture Help", &topic_to_fill); gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0); item_hb = welcome_button(WIRESHARK_STOCK_WIKI, - "How to Capture", - "Step by step to a successful capture setup", + "How to Capture", + "Step by step to a successful capture setup", topic_online_url(ONLINEPAGE_CAPTURE_SETUP), - GTK_SIGNAL_FUNC(topic_menu_cb), GINT_TO_POINTER(ONLINEPAGE_CAPTURE_SETUP)); + topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_CAPTURE_SETUP)); gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); item_hb = welcome_button(WIRESHARK_STOCK_WIKI, - "Network Media", - "Specific information for capturing on: Ethernet, WLAN, ...", + "Network Media", + "Specific information for capturing on:\nEthernet, WLAN, ...", topic_online_url(ONLINEPAGE_NETWORK_MEDIA), - GTK_SIGNAL_FUNC(topic_menu_cb), GINT_TO_POINTER(ONLINEPAGE_NETWORK_MEDIA)); + topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_NETWORK_MEDIA)); gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); #else - label_text = g_strdup_printf("Capturing is not compiled into this version of Wireshark!"); + label_text = g_strdup("Capturing is not compiled into this version of Wireshark!"); w = gtk_label_new(label_text); gtk_label_set_markup(GTK_LABEL(w), label_text); g_free (label_text); - gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0); + gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.0f); gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5); #endif /* HAVE_LIBPCAP */ @@ -798,30 +1170,30 @@ welcome_new(void) item_hb = welcome_button(GTK_STOCK_OPEN, "Open", - "Open a previously captured file", + "Open a previously captured file", "Same as File/Open menu or toolbar item", - GTK_SIGNAL_FUNC(file_open_cmd_cb), NULL); + welcome_button_callback_helper, file_open_cmd_cb); gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); /* prepare list of recent files (will be filled in later) */ - label_text = g_strdup_printf("Open Recent:"); + label_text = g_strdup("Open Recent:"); w = gtk_label_new(label_text); gtk_label_set_markup(GTK_LABEL(w), label_text); g_free (label_text); - gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0); + gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.0f); gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5); file_child_box = gtk_vbox_new(FALSE, 1); /* 17 file items or 300 pixels height is about the size */ /* that still fits on a screen of about 1000*700 */ - welcome_file_panel_vb = scroll_box_dynamic_new(GTK_BOX(file_child_box), 17, 300); + welcome_file_panel_vb = scroll_box_dynamic_new(GTK_WIDGET(file_child_box), 17, 300); gtk_box_pack_start(GTK_BOX(topic_to_fill), welcome_file_panel_vb, FALSE, FALSE, 0); item_hb = welcome_button(WIRESHARK_STOCK_WIKI, "Sample Captures", - "A rich assortment of example capture files on the wiki", + "A rich assortment of example capture files on the wiki", topic_online_url(ONLINEPAGE_SAMPLE_CAPTURES), - GTK_SIGNAL_FUNC(topic_menu_cb), GINT_TO_POINTER(ONLINEPAGE_SAMPLE_CAPTURES)); + topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_SAMPLE_CAPTURES)); gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); /* fill bottom space */ @@ -839,23 +1211,33 @@ welcome_new(void) item_hb = welcome_button(GTK_STOCK_HOME, "Website", - "Visit the project's website", + "Visit the project's website", topic_online_url(ONLINEPAGE_HOME), - GTK_SIGNAL_FUNC(topic_menu_cb), GINT_TO_POINTER(ONLINEPAGE_HOME)); + topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_HOME)); gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); +#ifdef HHC_DIR item_hb = welcome_button(GTK_STOCK_HELP, "User's Guide", - "The User's Guide (local version, if installed)", + "The User's Guide " + "(local version, if installed)", "Locally installed (if installed) otherwise online version", - GTK_SIGNAL_FUNC(topic_menu_cb), GINT_TO_POINTER(HELP_CONTENT)); + topic_menu_cb, GINT_TO_POINTER(HELP_CONTENT)); +#else + item_hb = welcome_button(GTK_STOCK_HELP, + "User's Guide", + "The User's Guide " + "(online version)", + topic_online_url(ONLINEPAGE_USERGUIDE), + topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_USERGUIDE)); +#endif gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); item_hb = welcome_button(WIRESHARK_STOCK_WIKI, "Security", - "Work with Wireshark as securely as possible", + "Work with Wireshark as securely as possible", topic_online_url(ONLINEPAGE_SECURITY), - GTK_SIGNAL_FUNC(topic_menu_cb), GINT_TO_POINTER(ONLINEPAGE_SECURITY)); + topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_SECURITY)); gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5); #if 0 @@ -864,7 +1246,7 @@ welcome_new(void) topic_vb = welcome_topic_new("Updates", &topic_to_fill); gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0); - label_text = g_strdup_printf("No updates available!"); + label_text = g_strdup("No updates available!"); w = gtk_label_new(label_text); gtk_label_set_markup(GTK_LABEL(w), label_text); g_free (label_text); @@ -873,12 +1255,21 @@ welcome_new(void) /* the end */ - gtk_widget_show_all(welcome_vb); + gtk_widget_show_all(welcome_eb); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(welcome_scrollw), - welcome_vb); + welcome_eb); gtk_widget_show_all(welcome_scrollw); +#ifdef USE_THREADS + recent_mtx = g_mutex_new(); +#endif + return welcome_scrollw; } +GtkWidget* get_welcome_window(void) +{ + return welcome_hb; +} +