5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #ifdef HAVE_SYS_TYPES_H
29 #include <sys/types.h>
35 #include <epan/prefs.h>
40 #include "capture-pcap-util.h"
41 #include "capture_opts.h"
42 #include "capture_ui_utils.h"
44 #include "simple_dialog.h"
45 #include <wsutil/file_util.h>
47 #include "gtk/gui_utils.h"
48 #include "gtk/color_utils.h"
49 #include "gtk/recent.h"
50 #include "gtk/gtkglobals.h"
52 #include "gtk/menus.h"
53 #include "gtk/main_welcome.h"
54 #include "gtk/help_dlg.h"
55 #include "gtk/capture_file_dlg.h"
56 #include "gtk/stock_icons.h"
57 #include "gtk/utf8_entities.h"
59 #include "gtk/capture_dlg.h"
60 #include "gtk/capture_if_dlg.h"
61 #include "gtk/capture_globals.h"
63 #include "../image/wssplash-dev.xpm"
64 #include "../version_info.h"
73 #include "airpcap_loader.h"
74 #include "airpcap_gui_utils.h"
76 #if defined(HAVE_AIRPCAP)
77 #include "../image/toolbar/capture_airpcap_16.xpm"
79 #if defined(HAVE_PCAP_REMOTE)
80 #include "gtk/remote_icons.h"
84 extern gint if_list_comparator_alph (const void *first_arg, const void *second_arg);
86 static GtkWidget *welcome_hb = NULL;
87 static GtkWidget *header_lb = NULL;
88 /* Foreground colors are set using Pango markup */
89 #if GTK_CHECK_VERSION(3,0,0)
90 static GdkRGBA rgba_welcome_bg = {0.901, 0.901, 0.901, 1.0 };
91 static GdkRGBA rgba_header_bar_bg = { 0.094, 0.360, 0.792, 1.0 };
92 static GdkRGBA rgba_topic_header_bg = { 0.004, 0.224, 0.745, 1.0 };
93 static GdkRGBA rgba_topic_content_bg = { 1, 1, 1, 1.0 };
94 static GdkRGBA rgba_topic_item_idle_bg;
95 static GdkRGBA rgba_topic_item_entered_bg = { 0.827, 0.847, 0.854, 1.0 };
97 static GdkColor welcome_bg = { 0, 0xe6e6, 0xe6e6, 0xe6e6 };
98 static GdkColor header_bar_bg = { 0, 0x1818, 0x5c5c, 0xcaca };
99 static GdkColor topic_header_bg = { 0, 0x0101, 0x3939, 0xbebe };
100 static GdkColor topic_content_bg = { 0, 0xffff, 0xffff, 0xffff };
101 static GdkColor topic_item_idle_bg;
102 static GdkColor topic_item_entered_bg = { 0, 0xd3d3, 0xd8d8, 0xdada };
104 static GtkWidget *welcome_file_panel_vb = NULL;
106 static GtkWidget *welcome_if_panel_vb = NULL;
107 static GtkWidget *if_view = NULL;
108 static GtkWidget *swindow;
109 static GArray *interfaces = NULL;
112 static GSList *status_messages = NULL;
115 static GMutex *recent_mtx = NULL;
118 /* The "scroll box dynamic" is a (complicated) pseudo widget to */
119 /* place a vertically list of widgets in (currently the interfaces and recent files). */
120 /* Once this list get's higher than a specified amount, */
121 /* it is moved into a scrolled_window. */
122 /* This is all complicated, the scrolled window is a bit ugly, */
123 /* the sizes might not be the same on all systems, ... */
124 /* ... but that's the best what we currently have */
125 #define SCROLL_BOX_CHILD_BOX "ScrollBoxDynamic_ChildBox"
126 #define SCROLL_BOX_MAX_CHILDS "ScrollBoxDynamic_MaxChilds"
127 #define SCROLL_BOX_SCROLLW_Y_SIZE "ScrollBoxDynamic_Scrollw_Y_Size"
128 #define SCROLL_BOX_SCROLLW "ScrollBoxDynamic_Scrollw"
129 #define TREE_VIEW_INTERFACES "TreeViewInterfaces"
132 scroll_box_dynamic_new(GtkWidget *child_box, guint max_childs, guint scrollw_y_size) {
133 GtkWidget * parent_box;
136 parent_box = gtk_vbox_new(FALSE, 0);
137 gtk_box_pack_start(GTK_BOX(parent_box), GTK_WIDGET(child_box), TRUE, TRUE, 0);
138 g_object_set_data(G_OBJECT(parent_box), SCROLL_BOX_CHILD_BOX, child_box);
139 g_object_set_data(G_OBJECT(parent_box), SCROLL_BOX_MAX_CHILDS, GINT_TO_POINTER(max_childs));
140 g_object_set_data(G_OBJECT(parent_box), SCROLL_BOX_SCROLLW_Y_SIZE, GINT_TO_POINTER(scrollw_y_size));
141 gtk_widget_show_all(parent_box);
148 scroll_box_dynamic_add(GtkWidget *parent_box)
150 GtkWidget *child_box;
154 guint scrollw_y_size;
157 child_box = g_object_get_data(G_OBJECT(parent_box), SCROLL_BOX_CHILD_BOX);
158 max_cnt = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(parent_box), SCROLL_BOX_MAX_CHILDS));
160 /* get the current number of children */
161 childs = gtk_container_get_children(GTK_CONTAINER(child_box));
162 curr_cnt = g_list_length(childs);
165 /* have we just reached the max? */
166 if(curr_cnt == max_cnt) {
167 /* create the scrolled window */
168 /* XXX - there's no way to get rid of the shadow frame - except for creating an own widget :-( */
169 scrollw = scrolled_window_new(NULL, NULL);
170 scrollw_y_size = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(parent_box), SCROLL_BOX_SCROLLW_Y_SIZE));
171 gtk_widget_set_size_request(scrollw, -1, scrollw_y_size);
173 g_object_set_data(G_OBJECT(parent_box), SCROLL_BOX_SCROLLW, scrollw);
174 gtk_box_pack_start(GTK_BOX(parent_box), scrollw, TRUE, TRUE, 0);
176 /* move child_box from parent_box into scrolled window */
177 g_object_ref(child_box);
178 gtk_container_remove(GTK_CONTAINER(parent_box), child_box);
179 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollw),
181 gtk_widget_show_all(scrollw);
189 scroll_box_dynamic_reset(GtkWidget *parent_box)
191 GtkWidget *child_box, *scrollw;
194 child_box = g_object_get_data(G_OBJECT(parent_box), SCROLL_BOX_CHILD_BOX);
195 scrollw = g_object_get_data(G_OBJECT(parent_box), SCROLL_BOX_SCROLLW);
197 if(scrollw != NULL) {
198 /* move the child_box back from scrolled window into the parent_box */
199 g_object_ref(child_box);
200 gtk_container_remove(GTK_CONTAINER(parent_box), scrollw);
201 g_object_set_data(G_OBJECT(parent_box), SCROLL_BOX_SCROLLW, NULL);
202 gtk_box_pack_start(GTK_BOX(parent_box), child_box, TRUE, TRUE, 0);
209 /* mouse entered this widget - change background color */
211 welcome_item_enter_cb(GtkWidget *eb, GdkEventCrossing *event _U_, gpointer user_data _U_)
213 #if GTK_CHECK_VERSION(3,0,0)
214 gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_entered_bg);
216 gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_entered_bg);
222 /* mouse has left this widget - change background color */
224 welcome_item_leave_cb(GtkWidget *eb, GdkEventCrossing *event _U_, gpointer user_data _U_)
226 #if GTK_CHECK_VERSION(3,0,0)
227 gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg);
229 gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg);
235 typedef gboolean (*welcome_button_callback_t) (GtkWidget *widget,
236 GdkEventButton *event,
239 /* create a "button widget" */
241 welcome_button(const gchar *stock_item,
242 const gchar *title, const gchar *subtitle, const gchar *tooltip,
243 welcome_button_callback_t welcome_button_callback, gpointer welcome_button_callback_data)
245 GtkWidget *eb, *w, *item_hb, *text_vb;
246 gchar *formatted_text;
248 item_hb = gtk_hbox_new(FALSE, 1);
250 /* event box (for background color and events) */
251 eb = gtk_event_box_new();
252 gtk_container_add(GTK_CONTAINER(eb), item_hb);
253 #if GTK_CHECK_VERSION(3,0,0)
254 gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg);
256 gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg);
258 if(tooltip != NULL) {
259 gtk_widget_set_tooltip_text(eb, tooltip);
262 g_signal_connect(eb, "enter-notify-event", G_CALLBACK(welcome_item_enter_cb), NULL);
263 g_signal_connect(eb, "leave-notify-event", G_CALLBACK(welcome_item_leave_cb), NULL);
264 g_signal_connect(eb, "button-release-event", G_CALLBACK(welcome_button_callback), welcome_button_callback_data);
267 w = gtk_image_new_from_stock(stock_item, GTK_ICON_SIZE_LARGE_TOOLBAR);
268 gtk_box_pack_start(GTK_BOX(item_hb), w, FALSE, FALSE, 5);
270 text_vb = gtk_vbox_new(FALSE, 3);
273 w = gtk_label_new(title);
274 gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.5f);
275 formatted_text = g_strdup_printf("<span weight=\"bold\" size=\"x-large\" foreground=\"black\">%s</span>", title);
276 gtk_label_set_markup(GTK_LABEL(w), formatted_text);
277 g_free(formatted_text);
278 gtk_box_pack_start(GTK_BOX(text_vb), w, FALSE, FALSE, 1);
281 w = gtk_label_new(subtitle);
282 gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.5f);
283 formatted_text = g_strdup_printf("<span size=\"small\" foreground=\"black\">%s</span>", subtitle);
284 gtk_label_set_markup(GTK_LABEL(w), formatted_text);
285 g_free(formatted_text);
286 gtk_box_pack_start(GTK_BOX(text_vb), w, FALSE, FALSE, 1);
288 gtk_box_pack_start(GTK_BOX(item_hb), text_vb, TRUE, TRUE, 5);
294 /* Hack to handle welcome-button "button-release-event" callback */
295 /* 1. Dispatch to desired actual callback */
296 /* 2. Return TRUE for the event callback. */
297 /* user_data: actual (no arg) callback fcn to be invoked. */
299 welcome_button_callback_helper(GtkWidget *w, GdkEventButton *event _U_, gpointer user_data)
301 void (*funct)(GtkWidget *, gpointer) = user_data;
308 welcome_header_set_message(gchar *msg) {
310 time_t secs = time(NULL);
311 struct tm *now = localtime(&secs);
313 message = g_string_new("<span weight=\"bold\" size=\"x-large\" foreground=\"white\">");
316 g_string_append(message, msg);
317 } else { /* Use our default header */
318 if ((now->tm_mon == 3 && now->tm_mday == 1) || (now->tm_mon == 6 && now->tm_mday == 14)) {
319 g_string_append(message, "Sniffing the glue that holds the Internet together");
321 g_string_append(message, prefs.gui_start_title);
324 if (prefs.gui_version_in_start_page) {
325 g_string_append_printf(message, "</span>\n<span size=\"large\" foreground=\"white\">Version " VERSION "%s",
326 wireshark_svnversion);
330 g_string_append(message, "</span>");
332 gtk_label_set_markup(GTK_LABEL(header_lb), message->str);
333 g_string_free(message, TRUE);
337 /* create the banner "above our heads" */
339 welcome_header_new(void)
346 item_vb = gtk_vbox_new(FALSE, 0);
349 eb = gtk_event_box_new();
350 gtk_container_add(GTK_CONTAINER(eb), item_vb);
351 #if GTK_CHECK_VERSION(3,0,0)
352 gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_header_bar_bg);
354 gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &header_bar_bg);
356 item_hb = gtk_hbox_new(FALSE, 0);
357 gtk_box_pack_start(GTK_BOX(item_vb), item_hb, FALSE, FALSE, 10);
359 /*icon = xpm_to_widget_from_parent(top_level, wssplash_xpm);*/
360 icon = xpm_to_widget(wssplash_xpm);
361 gtk_box_pack_start(GTK_BOX(item_hb), icon, FALSE, FALSE, 10);
363 header_lb = gtk_label_new(NULL);
364 welcome_header_set_message(NULL);
365 gtk_label_set_selectable(GTK_LABEL(header_lb), TRUE);
366 gtk_misc_set_alignment(GTK_MISC(header_lb), 0.0f, 0.5f);
367 gtk_box_pack_start(GTK_BOX(item_hb), header_lb, TRUE, TRUE, 5);
369 gtk_widget_show_all(eb);
376 welcome_header_push_msg(const gchar *msg) {
377 gchar *msg_copy = g_strdup(msg);
379 status_messages = g_slist_append(status_messages, msg_copy);
381 welcome_header_set_message(msg_copy);
383 gtk_widget_hide(welcome_hb);
388 welcome_header_pop_msg(void) {
391 if (status_messages) {
392 g_free(status_messages->data);
393 status_messages = g_slist_delete_link(status_messages, status_messages);
396 if (status_messages) {
397 msg = status_messages->data;
400 welcome_header_set_message(msg);
402 if (!status_messages) {
403 gtk_widget_show(welcome_hb);
408 /* create a "topic header widget" */
410 welcome_topic_header_new(const char *header)
414 gchar *formatted_message;
417 w = gtk_label_new(header);
418 formatted_message = g_strdup_printf("<span weight=\"bold\" size=\"x-large\" foreground=\"white\">%s</span>", header);
419 gtk_label_set_markup(GTK_LABEL(w), formatted_message);
420 g_free(formatted_message);
423 eb = gtk_event_box_new();
424 gtk_container_add(GTK_CONTAINER(eb), w);
425 #if GTK_CHECK_VERSION(3,0,0)
426 gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_header_bg);
428 gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_header_bg);
434 /* create a "topic widget" */
436 welcome_topic_new(const char *header, GtkWidget **to_fill)
439 GtkWidget *layout_vb;
441 GtkWidget *topic_header;
444 topic_vb = gtk_vbox_new(FALSE, 0);
446 topic_header = welcome_topic_header_new(header);
447 gtk_box_pack_start(GTK_BOX(topic_vb), topic_header, FALSE, FALSE, 0);
449 layout_vb = gtk_vbox_new(FALSE, 5);
450 gtk_container_set_border_width(GTK_CONTAINER(layout_vb), 10);
451 gtk_box_pack_start(GTK_BOX(topic_vb), layout_vb, FALSE, FALSE, 0);
453 /* colorize vbox (we need an event box for this!) */
454 topic_eb = gtk_event_box_new();
455 gtk_container_add(GTK_CONTAINER(topic_eb), topic_vb);
456 #if GTK_CHECK_VERSION(3,0,0)
457 gtk_widget_override_background_color(topic_eb, GTK_STATE_NORMAL, &rgba_topic_content_bg);
459 gtk_widget_modify_bg(topic_eb, GTK_STATE_NORMAL, &topic_content_bg);
461 *to_fill = layout_vb;
467 /* a file link was pressed */
469 welcome_filename_link_press_cb(GtkWidget *widget _U_, GdkEventButton *event _U_, gpointer data)
471 menu_open_filename(data);
476 typedef struct _recent_item_status {
484 } recent_item_status;
487 * Fetch the status of a file.
488 * This function might be called as a thread. We can't use any drawing
489 * routines here: http://developer.gnome.org/gdk/2.24/gdk-Threads.html
491 static void *get_recent_item_status(void *data)
493 recent_item_status *ri_stat = (recent_item_status *) data;
502 * Add file size. We use binary prefixes instead of IEC because that's what
505 err = ws_stat64(ri_stat->filename, &stat_buf);
507 g_mutex_lock(recent_mtx);
511 if (stat_buf.st_size/1024/1024/1024 > 10) {
512 g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d GB)", (gint64) (stat_buf.st_size/1024/1024/1024));
513 } else if (stat_buf.st_size/1024/1024 > 10) {
514 g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d MB)", (gint64) (stat_buf.st_size/1024/1024));
515 } else if (stat_buf.st_size/1024 > 10) {
516 g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d KB)", (gint64) (stat_buf.st_size/1024));
518 g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d Bytes)", (gint64) (stat_buf.st_size));
520 /* pango format string */
521 g_string_prepend(ri_stat->str, "<span foreground='blue'>");
522 g_string_append(ri_stat->str, "</span>");
524 g_string_append(ri_stat->str, " [not found]");
527 if (!ri_stat->label) { /* The widget went away while we were busy. */
528 g_free(ri_stat->filename);
529 g_string_free(ri_stat->str, TRUE);
532 ri_stat->stat_done = TRUE;
535 g_mutex_unlock(recent_mtx);
541 /* Timeout callback for recent items */
543 update_recent_items(gpointer data)
545 recent_item_status *ri_stat = (recent_item_status *) data;
546 gboolean again = TRUE;
553 g_mutex_lock(recent_mtx);
555 if (ri_stat->stat_done) {
557 gtk_label_set_markup(GTK_LABEL(ri_stat->label), ri_stat->str->str);
558 if (ri_stat->err == 0) {
559 gtk_widget_set_sensitive(ri_stat->label, TRUE);
560 gtk_action_set_sensitive((GtkAction *) ri_stat->menu_item, TRUE);
564 /* Else append some sort of Unicode or ASCII animation to the label? */
566 g_mutex_unlock(recent_mtx);
571 static void welcome_filename_destroy_cb(GtkWidget *w _U_, gpointer data) {
572 recent_item_status *ri_stat = (recent_item_status *) data;
579 g_mutex_lock(recent_mtx);
581 if (ri_stat->timer) {
582 g_source_remove(ri_stat->timer);
586 g_object_unref(ri_stat->menu_item);
588 if (ri_stat->stat_done) {
589 g_free(ri_stat->filename);
590 g_string_free(ri_stat->str, TRUE);
593 ri_stat->label = NULL;
596 g_mutex_unlock(recent_mtx);
600 /* create a "file link widget" */
602 welcome_filename_link_new(const gchar *filename, GtkWidget **label, GObject *menu_item)
609 gsize uni_start, uni_end;
610 const glong max = 60;
611 recent_item_status *ri_stat;
614 str = g_string_new(filename);
615 uni_len = g_utf8_strlen(str->str, str->len);
617 /* cut max filename length */
619 uni_start = g_utf8_offset_to_pointer(str->str, 20) - str->str;
620 uni_end = g_utf8_offset_to_pointer(str->str, uni_len - max) - str->str;
621 g_string_erase(str, uni_start, uni_end);
622 g_string_insert(str, uni_start, " " UTF8_HORIZONTAL_ELLIPSIS " ");
625 /* escape the possibly shortened filename before adding pango language */
626 str_escaped=g_markup_escape_text(str->str, -1);
627 g_string_free(str, TRUE);
630 w = gtk_label_new(str_escaped);
632 gtk_misc_set_padding(GTK_MISC(w), 5, 2);
633 gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.0f);
634 gtk_widget_set_sensitive(w, FALSE);
636 ri_stat = g_malloc(sizeof(recent_item_status));
637 ri_stat->filename = g_strdup(filename);
639 ri_stat->menu_item = menu_item;
640 ri_stat->str = g_string_new(str_escaped);
641 ri_stat->stat_done = FALSE;
643 g_object_ref(G_OBJECT(menu_item));
644 g_signal_connect(w, "destroy", G_CALLBACK(welcome_filename_destroy_cb), ri_stat);
648 g_thread_create(get_recent_item_status, ri_stat, FALSE, NULL);
649 ri_stat->timer = g_timeout_add(200, update_recent_items, ri_stat);
651 get_recent_item_status(ri_stat);
652 update_recent_items(ri_stat);
656 eb = gtk_event_box_new();
657 #if GTK_CHECK_VERSION(3,0,0)
658 gtk_widget_override_background_color(eb, GTK_STATE_NORMAL, &rgba_topic_item_idle_bg);
660 gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg);
662 gtk_container_add(GTK_CONTAINER(eb), w);
663 gtk_widget_set_tooltip_text(eb, filename);
665 g_signal_connect(eb, "enter-notify-event", G_CALLBACK(welcome_item_enter_cb), w);
666 g_signal_connect(eb, "leave-notify-event", G_CALLBACK(welcome_item_leave_cb), w);
667 g_signal_connect(eb, "button-press-event", G_CALLBACK(welcome_filename_link_press_cb), (gchar *) filename);
673 /* reset the list of recent files */
675 main_welcome_reset_recent_capture_files(void)
677 GtkWidget *child_box;
679 GList* child_list_item;
682 if(welcome_file_panel_vb) {
683 child_box = scroll_box_dynamic_reset(welcome_file_panel_vb);
684 child_list = gtk_container_get_children(GTK_CONTAINER(child_box));
685 child_list_item = child_list;
687 while(child_list_item) {
688 gtk_container_remove(GTK_CONTAINER(child_box), child_list_item->data);
689 child_list_item = g_list_next(child_list_item);
692 g_list_free(child_list);
697 /* add a new file to the list of recent files */
699 main_welcome_add_recent_capture_file(const char *widget_cf_name, GObject *menu_item)
702 GtkWidget *child_box;
706 w = welcome_filename_link_new(widget_cf_name, &label, menu_item);
707 child_box = scroll_box_dynamic_add(welcome_file_panel_vb);
708 gtk_box_pack_start(GTK_BOX(child_box), w, FALSE, FALSE, 0);
709 gtk_widget_show_all(w);
710 gtk_widget_show_all(child_box);
714 static gboolean select_current_ifaces(GtkTreeModel *model,
721 gboolean found = FALSE;
723 GtkTreeSelection *selection = (GtkTreeSelection *)userdata;
724 gtk_tree_model_get (model, iter, IFACE_NAME, &if_name, -1);
725 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
726 if (strcmp(g_array_index(global_capture_opts.ifaces, interface_options, i).name, if_name) == 0) {
727 if (!gtk_tree_selection_path_is_selected(selection, path)) {
728 gtk_tree_selection_select_iter(selection, iter);
735 gtk_tree_selection_unselect_iter(selection, iter);
740 gboolean on_selection_changed(GtkTreeSelection *selection _U_,
743 gboolean path_currently_selected,
748 interface_options interface_opts;
750 cap_settings_t cap_settings;
751 gboolean found = FALSE;
752 displayed_interface d_interface;
754 d_interface.name = NULL;
755 d_interface.descr = NULL;
756 gtk_tree_model_get_iter (model, &iter, path);
757 gtk_tree_model_get (model, &iter, IFACE_NAME, &if_name, -1);
758 if (global_capture_opts.ifaces->len > 0) {
759 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
760 if (strcmp(g_array_index(global_capture_opts.ifaces, interface_options, i).name, if_name) == 0) {
762 if (path_currently_selected) {
763 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
764 global_capture_opts.ifaces = g_array_remove_index(global_capture_opts.ifaces, i);
765 if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && interfaces_dialog_window_present()) {
766 update_selected_interface(g_strdup(interface_opts.name), FALSE);
768 if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && dlg_window_present()) {
769 enable_selected_interface(interface_opts.name, FALSE);
771 g_free(interface_opts.name);
772 g_free(interface_opts.descr);
773 g_free(interface_opts.cfilter);
774 #ifdef HAVE_PCAP_REMOTE
775 g_free(interface_opts.remote_host);
776 g_free(interface_opts.remote_port);
777 g_free(interface_opts.auth_username);
778 g_free(interface_opts.auth_password);
785 if (!found && !path_currently_selected) {
786 for (j = 0; j < interfaces->len; j++) {
787 d_interface = g_array_index(interfaces, displayed_interface, j);
788 if (strcmp(d_interface.name, if_name) == 0) {
789 interface_opts.name = g_strdup(d_interface.name);
790 interface_opts.descr = g_strdup(d_interface.descr);
791 interface_opts.linktype = capture_dev_user_linktype_find(interface_opts.name);
792 interface_opts.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
793 interface_opts.has_snaplen = global_capture_opts.default_options.has_snaplen;
794 interface_opts.snaplen = global_capture_opts.default_options.snaplen;
795 cap_settings = capture_get_cap_settings (interface_opts.name);;
796 interface_opts.promisc_mode = global_capture_opts.default_options.promisc_mode;
797 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
798 interface_opts.buffer_size = global_capture_opts.default_options.buffer_size;
800 interface_opts.monitor_mode = cap_settings.monitor_mode;
801 #ifdef HAVE_PCAP_REMOTE
802 if (d_interface.remote_opts.src_type == CAPTURE_IFREMOTE) {
803 interface_opts.src_type = d_interface.remote_opts.src_type;
804 interface_opts.remote_host = g_strdup(d_interface.remote_opts.remote_host_opts.remote_host);
805 interface_opts.remote_port = g_strdup(d_interface.remote_opts.remote_host_opts.remote_port);
806 interface_opts.auth_type = d_interface.remote_opts.remote_host_opts.auth_type;
807 interface_opts.auth_username = g_strdup(d_interface.remote_opts.remote_host_opts.auth_username);
808 interface_opts.auth_password = g_strdup(d_interface.remote_opts.remote_host_opts.auth_password);
809 interface_opts.datatx_udp = d_interface.remote_opts.remote_host_opts.datatx_udp;
810 interface_opts.nocap_rpcap = d_interface.remote_opts.remote_host_opts.nocap_rpcap;
811 interface_opts.nocap_local = d_interface.remote_opts.remote_host_opts.nocap_local;
812 #ifdef HAVE_PCAP_SETSAMPLING
813 interface_opts.sampling_method = d_interface.remote_opts.sampling_method;
814 interface_opts.sampling_param = d_interface.remote_opts.sampling_param;
817 interface_opts.src_type = global_capture_opts.default_options.src_type;
818 interface_opts.remote_host = g_strdup(global_capture_opts.default_options.remote_host);
819 interface_opts.remote_port = g_strdup(global_capture_opts.default_options.remote_port);
820 interface_opts.auth_type = global_capture_opts.default_options.auth_type;
821 interface_opts.auth_username = g_strdup(global_capture_opts.default_options.auth_username);
822 interface_opts.auth_password = g_strdup(global_capture_opts.default_options.auth_password);
823 interface_opts.datatx_udp = global_capture_opts.default_options.datatx_udp;
824 interface_opts.nocap_rpcap = global_capture_opts.default_options.nocap_rpcap;
825 interface_opts.nocap_local = global_capture_opts.default_options.nocap_local;
826 #ifdef HAVE_PCAP_SETSAMPLING
827 interface_opts.sampling_method = global_capture_opts.default_options.sampling_method;
828 interface_opts.sampling_param = global_capture_opts.default_options.sampling_param;
833 g_array_append_val(global_capture_opts.ifaces, interface_opts);
834 if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && interfaces_dialog_window_present()) {
835 update_selected_interface(g_strdup(interface_opts.name), TRUE);
837 if (gtk_widget_is_focus(g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES)) && dlg_window_present()) {
838 enable_selected_interface(interface_opts.name, TRUE);
847 static gboolean activate_ifaces(GtkTreeModel *model,
848 GtkTreePath *path _U_,
854 GtkTreeSelection *selection;
855 selected_name_t *entry = (selected_name_t *)userdata;
857 view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES);
858 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
859 gtk_tree_model_get (model, iter, IFACE_NAME, &if_name, -1);
860 if (strcmp(if_name, entry->name) == 0) {
861 if (entry->activate) {
862 gtk_tree_selection_select_iter(selection, iter);
864 gtk_tree_selection_unselect_iter(selection, iter);
871 void change_interface_selection(gchar* name, gboolean activate)
875 selected_name_t entry;
877 view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES);
878 model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
879 entry.name = g_strdup(name);
880 entry.activate = activate;
881 gtk_tree_model_foreach(GTK_TREE_MODEL(model), (GtkTreeModelForeachFunc)(activate_ifaces), (gpointer) &entry);
884 void change_selection_for_all(gboolean enable)
889 for (i = 0; i < interfaces->len; i++) {
890 change_interface_selection(g_array_index(interfaces, displayed_interface, i).name, enable);
902 GtkTreeSelection *entry;
904 if (global_capture_opts.ifaces->len > 0 && swindow) {
905 view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES);
906 model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
907 entry = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
908 gtk_tree_model_foreach(GTK_TREE_MODEL(model), select_current_ifaces, (gpointer) entry);
909 gtk_widget_grab_focus(view);
914 #ifdef HAVE_PCAP_REMOTE
916 add_interface_to_list(gchar *name, gchar *descr, remote_options *remote_opts)
918 GtkWidget *view, *icon;
923 displayed_interface d_interface;
925 d_interface.name = g_strdup(name);
926 d_interface.descr = g_strdup(descr);
927 d_interface.remote_opts.src_type = remote_opts->src_type;
928 d_interface.remote_opts.remote_host_opts.remote_host = g_strdup(remote_opts->remote_host_opts.remote_host);
929 d_interface.remote_opts.remote_host_opts.remote_port = g_strdup(remote_opts->remote_host_opts.remote_port);
930 d_interface.remote_opts.remote_host_opts.auth_type = remote_opts->remote_host_opts.auth_type;
931 d_interface.remote_opts.remote_host_opts.auth_username = g_strdup(remote_opts->remote_host_opts.auth_username);
932 d_interface.remote_opts.remote_host_opts.auth_password = g_strdup(remote_opts->remote_host_opts.auth_password);
933 d_interface.remote_opts.remote_host_opts.datatx_udp = remote_opts->remote_host_opts.datatx_udp;
934 d_interface.remote_opts.remote_host_opts.nocap_rpcap = remote_opts->remote_host_opts.nocap_rpcap;
935 d_interface.remote_opts.remote_host_opts.nocap_local = remote_opts->remote_host_opts.nocap_local;
936 #ifdef HAVE_PCAP_SETSAMPLING
937 d_interface.remote_opts.sampling_method = remote_opts->sampling_method;
938 d_interface.remote_opts.sampling_param = remote_opts->sampling_param;
940 icon = pixbuf_to_widget(remote_sat_pb_data);
941 d_interface.icon = icon;
942 view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES);
943 model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
944 size = gtk_tree_model_iter_n_children(model, NULL);
945 lines = g_strdup_printf("%d", size-1);
946 g_array_append_val(interfaces, d_interface);
947 if (gtk_tree_model_get_iter_from_string(model, &iter, lines)) {
948 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
949 gtk_list_store_set(GTK_LIST_STORE(model), &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, descr, IFACE_NAME, name, -1);
954 /* list the interfaces */
956 welcome_if_tree_load(void)
963 gchar *err_str = NULL;
966 GtkListStore *store = NULL;
968 GtkWidget *icon, *view;
969 GtkTreeSelection *entry;
970 displayed_interface d_interface;
972 view = g_object_get_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES);
973 entry = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
974 gtk_tree_selection_unselect_all(entry);
975 store = gtk_list_store_new(NUMCOLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
977 /* LOAD THE INTERFACES */
978 if (interfaces && interfaces->len > 0) {
979 for (i = 0; i < interfaces->len; i++) {
980 d_interface = g_array_index(interfaces, displayed_interface, i);
981 gtk_list_store_append (store, &iter);
982 gtk_list_store_set (store, &iter, ICON, d_interface.icon, IFACE_DESCR, d_interface.descr, IFACE_NAME, d_interface.name, -1);
985 interfaces = g_array_new(TRUE, TRUE, sizeof(displayed_interface));
986 if_list = capture_interface_list(&err, &err_str);
987 if_list = g_list_sort (if_list, if_list_comparator_alph);
988 if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
989 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
992 } else if (err_str) {
995 if (g_list_length(if_list) > 0) {
996 /* List the interfaces */
997 for (curr = g_list_first(if_list); curr; curr = g_list_next(curr)) {
998 if_info = curr->data;
999 /* Continue if capture device is hidden */
1000 if (prefs_is_capture_device_hidden(if_info->name)) {
1003 gtk_list_store_append (store, &iter);
1004 d_interface.name = g_strdup(if_info->name);
1005 #ifdef HAVE_PCAP_REMOTE
1006 d_interface.remote_opts.src_type = CAPTURE_IFLOCAL;
1009 if (get_airpcap_if_from_name(airpcap_if_list,if_info->name) != NULL)
1010 icon = xpm_to_widget(capture_airpcap_16_xpm);
1012 icon = capture_get_if_icon(if_info);
1014 icon = capture_get_if_icon(if_info);
1016 d_interface.icon = icon;
1017 user_descr = capture_dev_user_descr_find(if_info->name);
1020 gchar *comment = user_descr;
1021 user_descr = g_strdup_printf("%s (%s)", comment, if_info->name);
1024 gtk_list_store_set(store, &iter, ICON, gtk_image_get_pixbuf(GTK_IMAGE(icon)), IFACE_DESCR, user_descr, IFACE_NAME, if_info->name, -1);
1025 d_interface.descr = g_strdup(user_descr);
1026 g_free (user_descr);
1027 } else if (if_info->description) {
1028 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);
1029 d_interface.descr = g_strdup(if_info->description);
1031 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);
1032 d_interface.descr = g_strdup(if_info->name);
1034 g_array_append_val(interfaces, d_interface);
1037 free_interface_list(if_list);
1038 gtk_tree_view_set_model(GTK_TREE_VIEW(if_view), GTK_TREE_MODEL (store));
1039 if (global_capture_opts.ifaces->len > 0) {
1040 gtk_tree_model_foreach(GTK_TREE_MODEL(store), select_current_ifaces, (gpointer) entry);
1041 gtk_widget_grab_focus(view);
1043 gtk_tree_selection_set_select_function(entry, on_selection_changed, NULL, NULL);
1045 #endif /* HAVE_LIBPCAP */
1049 /* reload the list of interfaces */
1051 welcome_if_panel_reload(void)
1054 GtkWidget *child_box;
1056 GList* child_list_item;
1058 if(welcome_if_panel_vb) {
1059 child_box = scroll_box_dynamic_reset(welcome_if_panel_vb);
1060 child_list = gtk_container_get_children(GTK_CONTAINER(child_box));
1061 child_list_item = child_list;
1063 while(child_list_item) {
1064 gtk_container_remove(GTK_CONTAINER(child_box), child_list_item->data);
1065 child_list_item = g_list_next(child_list_item);
1068 g_list_free(child_list);
1069 welcome_if_tree_load();
1070 gtk_widget_show_all(welcome_if_panel_vb);
1072 #endif /* HAVE_LIBPCAP */
1076 static void capture_if_start(GtkWidget *w _U_, gpointer data _U_)
1079 interface_options interface_opts;
1082 if (global_capture_opts.ifaces->len == 0) {
1083 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1084 "You didn't specify an interface on which to capture packets.");
1088 if (global_capture_opts.ifaces->len > 1) {
1089 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1090 "You specified multiple interfaces for capturing which this version of Wireshark doesn't support.");
1095 /* XXX - remove this? */
1096 if (global_capture_opts.save_file) {
1097 g_free(global_capture_opts.save_file);
1098 global_capture_opts.save_file = NULL;
1101 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, 0);
1102 airpcap_if_active = get_airpcap_if_from_name(airpcap_if_list, interface_opts.name);
1103 airpcap_if_selected = airpcap_if_active;
1104 airpcap_set_toolbar_start_capture(airpcap_if_active);
1106 capture_start_cb(NULL, NULL);
1110 /* create the welcome page */
1114 GtkWidget *welcome_scrollw;
1115 GtkWidget *welcome_eb;
1116 GtkWidget *welcome_vb;
1117 GtkWidget *column_vb;
1121 GtkWidget *topic_vb;
1122 GtkWidget *topic_to_fill;
1123 GtkWidget *file_child_box;
1127 DWORD chimney_enabled = 0;
1128 DWORD ce_size = sizeof(chimney_enabled);
1131 GtkTreeSelection *selection;
1132 GtkCellRenderer *renderer;
1133 GtkTreeViewColumn *column;
1136 gchar *err_str = NULL;
1139 /* prepare colors */
1141 /* Allocating collor isn't necessary? */
1143 /* "page" background */
1144 get_color(&welcome_bg);
1146 /* header bar background color */
1147 get_color(&header_bar_bg);
1149 /* topic header background color */
1150 get_color(&topic_header_bg);
1152 /* topic content background color */
1153 get_color(&topic_content_bg);
1155 #if GTK_CHECK_VERSION(3,0,0)
1156 rgba_topic_item_idle_bg = rgba_topic_content_bg;
1158 topic_item_idle_bg = topic_content_bg;
1161 /* Allocating collor isn't necessary? */
1162 /* topic item entered color */
1163 get_color(&topic_item_entered_bg);
1165 welcome_scrollw = scrolled_window_new(NULL, NULL);
1167 welcome_vb = gtk_vbox_new(FALSE, 0);
1169 welcome_eb = gtk_event_box_new();
1170 gtk_container_add(GTK_CONTAINER(welcome_eb), welcome_vb);
1171 #if GTK_CHECK_VERSION(3,0,0)
1172 gtk_widget_override_background_color(welcome_eb, GTK_STATE_NORMAL, &rgba_welcome_bg);
1174 gtk_widget_modify_bg(welcome_eb, GTK_STATE_NORMAL, &welcome_bg);
1177 header = welcome_header_new();
1178 gtk_box_pack_start(GTK_BOX(welcome_vb), header, FALSE, FALSE, 0);
1181 welcome_hb = gtk_hbox_new(FALSE, 10);
1182 gtk_container_set_border_width(GTK_CONTAINER(welcome_hb), 10);
1183 gtk_box_pack_start(GTK_BOX(welcome_vb), welcome_hb, TRUE, TRUE, 0);
1186 /* column capture */
1187 column_vb = gtk_vbox_new(FALSE, 10);
1188 #if GTK_CHECK_VERSION(3,0,0)
1189 gtk_widget_override_background_color(column_vb, GTK_STATE_NORMAL, &rgba_welcome_bg);
1191 gtk_widget_modify_bg(column_vb, GTK_STATE_NORMAL, &welcome_bg);
1193 gtk_box_pack_start(GTK_BOX(welcome_hb), column_vb, TRUE, TRUE, 0);
1196 topic_vb = welcome_topic_new("Capture", &topic_to_fill);
1197 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
1200 if_list = capture_interface_list(&err, &err_str);
1201 if (g_list_length(if_list) > 0) {
1202 item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_INTERFACES,
1204 "Live list of the capture interfaces\n(counts incoming packets)",
1205 "Same as Capture/Interfaces menu or toolbar item",
1206 welcome_button_callback_helper, capture_if_cb);
1207 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1209 swindow = gtk_scrolled_window_new (NULL, NULL);
1210 gtk_widget_set_size_request(swindow, FALSE, 100);
1211 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_IN);
1212 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1214 if_view = gtk_tree_view_new ();
1215 g_object_set(G_OBJECT(if_view), "headers-visible", FALSE, NULL);
1216 g_signal_connect(if_view, "row-activated", G_CALLBACK(options_interface_cb), (gpointer)welcome_hb);
1217 g_object_set_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES, if_view);
1218 renderer = gtk_cell_renderer_pixbuf_new();
1219 column = gtk_tree_view_column_new_with_attributes ("",
1220 GTK_CELL_RENDERER(renderer),
1223 gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column);
1224 renderer = gtk_cell_renderer_text_new();
1225 column = gtk_tree_view_column_new_with_attributes ("",
1226 GTK_CELL_RENDERER(renderer),
1227 "text", IFACE_DESCR,
1229 gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column);
1230 gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(if_view), 0), TRUE);
1231 renderer = gtk_cell_renderer_text_new();
1232 column = gtk_tree_view_column_new_with_attributes ("",
1233 GTK_CELL_RENDERER(renderer),
1236 gtk_tree_view_append_column(GTK_TREE_VIEW(if_view), column);
1237 gtk_tree_view_column_set_visible(column, FALSE);
1238 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(if_view));
1239 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
1241 item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_START,
1243 "Choose one or more interfaces to capture from, then <b>Start</b>",
1244 "Same as Capture/Interfaces with default options",
1245 (welcome_button_callback_t)capture_if_start, (gpointer)if_view);
1247 item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_START,
1249 "Choose exactly one interface to capture from, then <b>Start</b>",
1250 "Same as Capture/Interfaces with default options",
1251 (welcome_button_callback_t)capture_if_start, (gpointer)if_view);
1253 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1254 welcome_if_tree_load();
1255 gtk_container_add (GTK_CONTAINER (swindow), if_view);
1256 gtk_container_add(GTK_CONTAINER(topic_to_fill), swindow);
1258 item_hb = welcome_button(WIRESHARK_STOCK_CAPTURE_OPTIONS,
1260 "Start a capture with detailed options",
1261 "Same as Capture/Options menu or toolbar item",
1262 welcome_button_callback_helper, capture_prep_cb);
1263 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1265 /* Check for chimney offloading */
1266 reg_ret = RegQueryValueEx(HKEY_LOCAL_MACHINE,
1267 _T("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\EnableTCPChimney"),
1268 NULL, NULL, (LPBYTE) &chimney_enabled, &ce_size);
1269 if (reg_ret == ERROR_SUCCESS && chimney_enabled) {
1270 item_hb = welcome_button(WIRESHARK_STOCK_WIKI,
1271 "Offloading Detected",
1272 "TCP Chimney offloading is enabled. You \nmight not capture much data.",
1273 topic_online_url(ONLINEPAGE_CHIMNEY),
1274 topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_CHIMNEY));
1275 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1279 label_text = g_strdup("No interface can be used for capturing in\n"
1280 "this system with the current configuration.\n\n"
1281 "See Capture Help below for details.");
1282 w = gtk_label_new(label_text);
1283 gtk_label_set_markup(GTK_LABEL(w), label_text);
1284 g_free (label_text);
1285 gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.0f);
1286 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5);
1289 free_interface_list(if_list);
1291 /* capture help topic */
1292 topic_vb = welcome_topic_new("Capture Help", &topic_to_fill);
1293 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
1295 item_hb = welcome_button(WIRESHARK_STOCK_WIKI,
1297 "Step by step to a successful capture setup",
1298 topic_online_url(ONLINEPAGE_CAPTURE_SETUP),
1299 topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_CAPTURE_SETUP));
1300 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1302 item_hb = welcome_button(WIRESHARK_STOCK_WIKI,
1304 "Specific information for capturing on:\nEthernet, WLAN, ...",
1305 topic_online_url(ONLINEPAGE_NETWORK_MEDIA),
1306 topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_NETWORK_MEDIA));
1307 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1309 label_text = g_strdup("<span foreground=\"black\">Capturing is not compiled into\nthis version of Wireshark!</span>");
1310 w = gtk_label_new(label_text);
1311 gtk_label_set_markup(GTK_LABEL(w), label_text);
1312 g_free (label_text);
1313 gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.0f);
1314 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5);
1315 #endif /* HAVE_LIBPCAP */
1317 /* fill bottom space */
1318 w = gtk_label_new("");
1319 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
1323 topic_vb = welcome_topic_new("Files", &topic_to_fill);
1324 gtk_box_pack_start(GTK_BOX(welcome_hb), topic_vb, TRUE, TRUE, 0);
1326 item_hb = welcome_button(GTK_STOCK_OPEN,
1328 "Open a previously captured file",
1329 "Same as File/Open menu or toolbar item",
1330 welcome_button_callback_helper, file_open_cmd_cb);
1331 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1333 /* prepare list of recent files (will be filled in later) */
1334 label_text = g_strdup("<span foreground=\"black\">Open Recent:</span>");
1335 w = gtk_label_new(label_text);
1336 gtk_label_set_markup(GTK_LABEL(w), label_text);
1337 g_free (label_text);
1338 gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.0f);
1339 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5);
1341 file_child_box = gtk_vbox_new(FALSE, 1);
1342 /* 17 file items or 300 pixels height is about the size */
1343 /* that still fits on a screen of about 1000*700 */
1344 welcome_file_panel_vb = scroll_box_dynamic_new(GTK_WIDGET(file_child_box), 17, 300);
1345 gtk_box_pack_start(GTK_BOX(topic_to_fill), welcome_file_panel_vb, FALSE, FALSE, 0);
1347 item_hb = welcome_button(WIRESHARK_STOCK_WIKI,
1349 "A rich assortment of example capture files on the wiki",
1350 topic_online_url(ONLINEPAGE_SAMPLE_CAPTURES),
1351 topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_SAMPLE_CAPTURES));
1352 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1354 /* fill bottom space */
1355 w = gtk_label_new("");
1356 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
1360 column_vb = gtk_vbox_new(FALSE, 10);
1361 gtk_box_pack_start(GTK_BOX(welcome_hb), column_vb, TRUE, TRUE, 0);
1364 topic_vb = welcome_topic_new("Online", &topic_to_fill);
1365 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
1367 item_hb = welcome_button(GTK_STOCK_HOME,
1369 "Visit the project's website",
1370 topic_online_url(ONLINEPAGE_HOME),
1371 topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_HOME));
1372 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1375 item_hb = welcome_button(GTK_STOCK_HELP,
1378 "(local version, if installed)",
1379 "Locally installed (if installed) otherwise online version",
1380 topic_menu_cb, GINT_TO_POINTER(HELP_CONTENT));
1382 item_hb = welcome_button(GTK_STOCK_HELP,
1386 topic_online_url(ONLINEPAGE_USERGUIDE),
1387 topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
1389 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1391 item_hb = welcome_button(WIRESHARK_STOCK_WIKI,
1393 "Work with Wireshark as securely as possible",
1394 topic_online_url(ONLINEPAGE_SECURITY),
1395 topic_menu_cb, GINT_TO_POINTER(ONLINEPAGE_SECURITY));
1396 gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
1399 /* XXX - add this, once the Windows update functionality is implemented */
1401 topic_vb = welcome_topic_new("Updates", &topic_to_fill);
1402 gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
1404 label_text = g_strdup("<span foreground=\"black\">No updates available!</span>");
1405 w = gtk_label_new(label_text);
1406 gtk_label_set_markup(GTK_LABEL(w), label_text);
1407 g_free (label_text);
1408 gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
1413 gtk_widget_show_all(welcome_eb);
1415 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(welcome_scrollw),
1417 gtk_widget_show_all(welcome_scrollw);
1420 recent_mtx = g_mutex_new();
1423 return welcome_scrollw;
1426 GtkWidget* get_welcome_window(void)
1432 displayed_interface get_interface_data(gint index)
1434 return g_array_index(interfaces, displayed_interface, index);