Clean up indentation.
[metze/wireshark/wip.git] / ui / gtk / main.c
1 /* main.c
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * Richard Sharpe, 13-Feb-1999, added support for initializing structures
8  *                              needed by dissect routines
9  * Jeff Foster,    2001/03/12,  added support tabbed hex display windowss
10  *
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  */
26
27 #include <config.h>
28
29 #include <gtk/gtk.h>
30 #include <gdk/gdkkeysyms.h>
31 #if GTK_CHECK_VERSION(3,0,0)
32 # include <gdk/gdkkeysyms-compat.h>
33 #endif
34
35 #include <stdio.h>
36 #include <string.h>
37 #include <locale.h>
38
39 #ifdef HAVE_GETOPT_H
40 #include <getopt.h>
41 #endif
42
43 #ifdef HAVE_EXTCAP
44 #include <extcap.h>
45 #endif
46
47 #ifdef HAVE_LIBPORTAUDIO
48 #include <portaudio.h>
49 #endif /* HAVE_LIBPORTAUDIO */
50
51 #include <wsutil/copyright_info.h>
52 #include <wsutil/crash_info.h>
53 #include <wsutil/filesystem.h>
54 #include <wsutil/file_util.h>
55 #include <wsutil/privileges.h>
56 #include <wsutil/report_err.h>
57 #include <ws_version_info.h>
58
59 #include <wiretap/merge.h>
60
61 #include <epan/addr_resolv.h>
62 #include <epan/column.h>
63 #include <epan/disabled_protos.h>
64 #include <epan/epan.h>
65 #include <epan/decode_as.h>
66 #include <epan/proto.h>
67 #include <epan/epan_dissect.h>
68 #include <epan/dfilter/dfilter.h>
69 #include <epan/strutil.h>
70 #include <epan/ex-opt.h>
71 #include <epan/funnel.h>
72 #include <epan/expert.h>
73 #include <epan/prefs.h>
74 #include <epan/prefs-int.h>
75 #include <epan/tap.h>
76 #include <epan/stat_tap_ui.h>
77 #include <epan/uat.h>
78 #include <epan/print.h>
79 #include <epan/timestamp.h>
80 #include <epan/conversation_table.h>
81
82 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
83 #include <epan/asn1.h>
84 #include <epan/dissectors/packet-kerberos.h>
85 #endif
86
87 #include <wsutil/cmdarg_err.h>
88 #include <wsutil/plugins.h>
89
90 /* general (not GTK specific) */
91 #include "../../file.h"
92 #include "../../frame_tvbuff.h"
93 #include "../../summary.h"
94 #include <epan/color_filters.h>
95 #include "../../register.h"
96 #include "../../ringbuffer.h"
97 #include "../../log.h"
98
99 #include "gtk_iface_monitor.h"
100
101 #include "ui/alert_box.h"
102 #include "ui/console.h"
103 #include "ui/decode_as_utils.h"
104 #include "filter_files.h"
105 #include "ui/main_statusbar.h"
106 #include "ui/persfilepath_opt.h"
107 #include "ui/preference_utils.h"
108 #include "ui/recent.h"
109 #include "ui/recent_utils.h"
110 #include "ui/software_update.h"
111 #include "ui/ui_util.h"
112 #include "ui/util.h"
113 #include "ui/dissect_opts.h"
114 #include "ui/commandline.h"
115
116 #ifdef HAVE_LIBPCAP
117 #include "ui/capture_ui_utils.h"
118 #include "ui/capture_globals.h"
119 #include "ui/iface_lists.h"
120 #endif
121
122 #include "codecs/codecs.h"
123
124 #include "caputils/capture-pcap-util.h"
125
126 #ifdef HAVE_LIBPCAP
127 #include "caputils/capture_ifinfo.h"
128 #include "ui/capture.h"
129 #include <capchild/capture_sync.h>
130 #endif
131
132 #ifdef _WIN32
133 #include "caputils/capture-wpcap.h"
134 #include "caputils/capture_wpcap_packet.h"
135 #include <tchar.h> /* Needed for Unicode */
136 #include <wsutil/os_version_info.h>
137 #include <wsutil/unicode-utils.h>
138 #include <commctrl.h>
139 #include <shellapi.h>
140 #endif /* _WIN32 */
141
142 /* GTK related */
143 #include "ui/gtk/file_dlg.h"
144 #include "ui/gtk/gtkglobals.h"
145 #include "ui/gtk/color_utils.h"
146 #include "ui/gtk/gui_utils.h"
147 #include "ui/gtk/color_dlg.h"
148 #include "ui/gtk/filter_dlg.h"
149 #include "ui/gtk/fileset_dlg.h"
150 #include "ui/gtk/uat_gui.h"
151 #include "ui/gtk/main.h"
152 #include "ui/gtk/main_80211_toolbar.h"
153 #include "ui/gtk/main_airpcap_toolbar.h"
154 #include "ui/gtk/main_filter_toolbar.h"
155 #include "ui/gtk/main_titlebar.h"
156 #include "ui/gtk/menus.h"
157 #include "ui/gtk/main_menubar_private.h"
158 #include "ui/gtk/macros_dlg.h"
159 #include "ui/gtk/main_statusbar_private.h"
160 #include "ui/gtk/main_toolbar.h"
161 #include "ui/gtk/main_toolbar_private.h"
162 #include "ui/gtk/main_welcome.h"
163 #include "ui/gtk/main_welcome_private.h"
164 #include "ui/gtk/drag_and_drop.h"
165 #include "ui/gtk/capture_file_dlg.h"
166 #include "ui/gtk/packet_panes.h"
167 #include "ui/gtk/keys.h"
168 #include "ui/gtk/packet_win.h"
169 #include "ui/gtk/stock_icons.h"
170 #include "ui/gtk/find_dlg.h"
171 #include "ui/gtk/font_utils.h"
172 #include "ui/gtk/about_dlg.h"
173 #include "ui/gtk/help_dlg.h"
174 #include "ui/gtk/decode_as_dlg.h"
175 #include "ui/gtk/webbrowser.h"
176 #include "ui/gtk/capture_dlg.h"
177 #include "ui/gtk/capture_if_dlg.h"
178 #include "ui/gtk/tap_param_dlg.h"
179 #include "ui/gtk/prefs_column.h"
180 #include "ui/gtk/prefs_dlg.h"
181 #include "ui/gtk/packet_list.h"
182 #include "ui/gtk/filter_expression_save_dlg.h"
183 #include "ui/gtk/conversations_table.h"
184 #include "ui/gtk/hostlist_table.h"
185 #include "ui/gtk/service_response_time_table.h"
186 #include "ui/gtk/response_time_delay_table.h"
187 #include "ui/gtk/simple_stattable.h"
188 #include "simple_dialog.h"
189 #ifdef HAVE_GDK_GRESOURCE
190 #include "wireshark-gresources.h"
191 #else
192 #include "ui/gtk/pixbuf-csource.h"
193 #endif
194
195 #include "ui/gtk/old-gtk-compat.h"
196
197 #ifdef HAVE_AIRPCAP
198 #include <caputils/airpcap.h>
199 #include <caputils/airpcap_loader.h>
200 #include "airpcap_dlg.h"
201 #include "airpcap_gui_utils.h"
202 #endif
203
204 #include <epan/crypt/airpdcap_ws.h>
205
206
207 #ifdef HAVE_GTKOSXAPPLICATION
208 #include <gtkmacintegration/gtkosxapplication.h>
209 #endif
210
211 /*
212  * Files under personal and global preferences directories in which
213  * GTK settings for Wireshark are stored.
214  */
215 #define RC_FILE "gtkrc"
216
217 #ifdef HAVE_LIBPCAP
218 capture_session global_capture_session;
219 info_data_t global_info_data;
220 #endif
221
222 capture_file cfile;
223
224 static gboolean capture_stopping;
225
226 /* "exported" main widgets */
227 GtkWidget   *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
228
229 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
230 static GtkWidget   *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
231 static GtkWidget   *main_first_pane, *main_second_pane;
232
233 /* internally used widgets */
234 static GtkWidget   *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
235
236 GtkWidget *wireless_tb;
237 #ifdef HAVE_AIRPCAP
238 int    airpcap_dll_ret_val = -1;
239 #endif
240
241 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
242
243 static guint  tap_update_timer_id;
244
245 static void create_main_window(gint, gint, gint, e_prefs*);
246 static void show_main_window(gboolean);
247 static void main_save_window_geometry(GtkWidget *widget);
248
249
250 /* Match selected byte pattern */
251 static void
252 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
253 {
254     char       *cur_filter, *new_filter;
255
256     if ((!text) || (0 == strlen(text))) {
257         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
258         return;
259     }
260
261     g_assert(filter_te);
262
263     cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
264
265     switch (action&MATCH_SELECTED_MASK) {
266
267     case MATCH_SELECTED_REPLACE:
268         new_filter = g_strdup(text);
269         break;
270
271     case MATCH_SELECTED_AND:
272         if ((!cur_filter) || (0 == strlen(cur_filter)))
273             new_filter = g_strdup(text);
274         else
275             new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
276         break;
277
278     case MATCH_SELECTED_OR:
279         if ((!cur_filter) || (0 == strlen(cur_filter)))
280             new_filter = g_strdup(text);
281         else
282             new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
283         break;
284
285     case MATCH_SELECTED_NOT:
286         new_filter = g_strconcat("!(", text, ")", NULL);
287         break;
288
289     case MATCH_SELECTED_AND_NOT:
290         if ((!cur_filter) || (0 == strlen(cur_filter)))
291             new_filter = g_strconcat("!(", text, ")", NULL);
292         else
293             new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
294         break;
295
296     case MATCH_SELECTED_OR_NOT:
297         if ((!cur_filter) || (0 == strlen(cur_filter)))
298             new_filter = g_strconcat("!(", text, ")", NULL);
299         else
300             new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
301         break;
302
303     default:
304         g_assert_not_reached();
305         new_filter = NULL;
306         break;
307     }
308
309     /* Free up the copy we got of the old filter text. */
310     g_free(cur_filter);
311
312     /* Don't change the current display filter if we only want to copy the filter */
313     if (action&MATCH_SELECTED_COPY_ONLY) {
314         GString *gtk_text_str = g_string_new("");
315         g_string_append(gtk_text_str, new_filter);
316         copy_to_clipboard(gtk_text_str);
317         g_string_free(gtk_text_str, TRUE);
318     } else {
319         /* create a new one and set the display filter entry accordingly */
320         gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
321
322         /* Run the display filter so it goes in effect. */
323         if (action&MATCH_SELECTED_APPLY_NOW)
324             main_filter_packets(&cfile, new_filter, FALSE);
325     }
326
327     /* Free up the new filter text. */
328     g_free(new_filter);
329 }
330
331 void
332 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
333 {
334     char *filter = NULL;
335
336     if (cfile.finfo_selected) {
337         filter = proto_construct_match_selected_string(cfile.finfo_selected,
338                                                        cfile.edt);
339         match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
340         wmem_free(NULL, filter);
341     }
342 }
343
344 void
345 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
346 {
347     char *filter = NULL;
348     gchar *err_msg = NULL;
349
350     if (cfile.finfo_selected) {
351         filter = proto_construct_match_selected_string(cfile.finfo_selected,
352                                                        cfile.edt);
353         if ((!filter) || (0 == strlen(filter))) {
354             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
355                 "Could not acquire information to build a filter!\n"
356                 "Try expanding or choosing another item.");
357             return;
358         }
359
360         if (filt_nr==0) {
361             color_display_with_filter(filter);
362         } else {
363             if (filt_nr==255) {
364                 if (!color_filters_reset_tmp(&err_msg)) {
365                     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
366                     g_free(err_msg);
367                 }
368             } else {
369                 if (!color_filters_set_tmp(filt_nr,filter, FALSE, &err_msg)) {
370                     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
371                     g_free(err_msg);
372                 }
373
374             }
375             packet_list_colorize_packets();
376         }
377         wmem_free(NULL, filter);
378     }
379 }
380
381
382 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
383 {
384     gchar *selected_proto_url;
385     gchar *proto_abbrev = (gchar *)data;
386
387
388     switch(btn) {
389     case(ESD_BTN_OK):
390         if (cfile.finfo_selected) {
391             /* open wiki page using the protocol abbreviation */
392             selected_proto_url = g_strdup_printf("https://wiki.wireshark.org/Protocols/%s", proto_abbrev);
393             browser_open_url(selected_proto_url);
394             g_free(selected_proto_url);
395         }
396         break;
397     case(ESD_BTN_CANCEL):
398         break;
399     default:
400         g_assert_not_reached();
401     }
402 }
403
404
405 void
406 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
407 {
408     int field_id;
409     const gchar *proto_abbrev;
410     gpointer  dialog;
411
412
413     if (cfile.finfo_selected) {
414         /* convert selected field to protocol abbreviation */
415         /* XXX - could this conversion be simplified? */
416         field_id = cfile.finfo_selected->hfinfo->id;
417         /* if the selected field isn't a protocol, get its parent */
418         if(!proto_registrar_is_protocol(field_id)) {
419             field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
420         }
421
422         proto_abbrev = proto_registrar_get_abbrev(field_id);
423
424         /* ask the user if the wiki page really should be opened */
425         dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
426                 "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
427                 "\n"
428                 "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
429                 "\n"
430                 "The Wireshark Wiki is a collaborative approach to provide information "
431                 "about Wireshark in several ways (not limited to protocol specifics).\n"
432                 "\n"
433                 "This Wiki is new, so the page of the selected protocol "
434                 "may not exist and/or may not contain valuable information.\n"
435                 "\n"
436                 "As everyone can edit the Wiki and add new content (or extend existing), "
437                 "you are encouraged to add information if you can.\n"
438                 "\n"
439                 "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
440                 "\n"
441                 "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
442                 "which will save you a lot of editing and will give a consistent look over the pages.",
443                 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
444         simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
445     }
446 }
447
448 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
449 {
450     gchar *selected_proto_url;
451     gchar *proto_abbrev = (gchar *)data;
452
453     switch(btn) {
454     case(ESD_BTN_OK):
455         if (cfile.finfo_selected) {
456             /* open reference page using the protocol abbreviation */
457             selected_proto_url = g_strdup_printf("https://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
458             browser_open_url(selected_proto_url);
459             g_free(selected_proto_url);
460         }
461         break;
462     case(ESD_BTN_CANCEL):
463         break;
464     default:
465         g_assert_not_reached();
466     }
467 }
468
469 void
470 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
471 {
472     int field_id;
473     const gchar *proto_abbrev;
474     gpointer  dialog;
475
476
477     if (cfile.finfo_selected) {
478         /* convert selected field to protocol abbreviation */
479         /* XXX - could this conversion be simplified? */
480         field_id = cfile.finfo_selected->hfinfo->id;
481         /* if the selected field isn't a protocol, get its parent */
482         if(!proto_registrar_is_protocol(field_id)) {
483             field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
484         }
485
486         proto_abbrev = proto_registrar_get_abbrev(field_id);
487
488         /* ask the user if the wiki page really should be opened */
489         dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
490                 "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
491                 "\n"
492                 "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
493                 "\n",
494                 simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
495         simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
496     }
497 }
498
499 static gboolean
500 is_address_column (gint column)
501 {
502     if (((cfile.cinfo.columns[column].col_fmt == COL_DEF_SRC) ||
503          (cfile.cinfo.columns[column].col_fmt == COL_RES_SRC) ||
504          (cfile.cinfo.columns[column].col_fmt == COL_DEF_DST) ||
505          (cfile.cinfo.columns[column].col_fmt == COL_RES_DST)) &&
506         strlen(cfile.cinfo.col_expr.col_expr_val[column]))
507     {
508         return TRUE;
509     }
510
511     return FALSE;
512 }
513
514 GList *
515 get_ip_address_list_from_packet_list_row(gpointer data)
516 {
517     gint    row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
518     gint    column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
519     gint    col;
520     frame_data *fdata;
521     GList      *addr_list = NULL;
522
523     fdata = (frame_data *) packet_list_get_row_data(row);
524
525     if (fdata != NULL) {
526         epan_dissect_t edt;
527
528         if (!cf_read_record(&cfile, fdata))
529             return NULL; /* error reading the frame */
530
531         epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
532         col_custom_prime_edt(&edt, &cfile.cinfo);
533
534         epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
535             frame_tvbuff_new_buffer(fdata, &cfile.buf), fdata, &cfile.cinfo);
536         epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
537
538         /* First check selected column */
539         if (is_address_column (column)) {
540             addr_list = g_list_append (addr_list, g_strdup(cfile.cinfo.col_expr.col_expr_val[column]));
541         }
542
543         for (col = 0; col < cfile.cinfo.num_cols; col++) {
544             /* Then check all columns except the selected */
545             if ((col != column) && (is_address_column (col))) {
546                 addr_list = g_list_append (addr_list, g_strdup(cfile.cinfo.col_expr.col_expr_val[col]));
547             }
548         }
549
550         epan_dissect_cleanup(&edt);
551     }
552
553     return addr_list;
554 }
555
556 static gchar *
557 get_filter_from_packet_list_row_and_column(gpointer data)
558 {
559     gint    row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
560     gint    column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
561     frame_data *fdata;
562     gchar      *buf=NULL;
563
564     fdata = (frame_data *) packet_list_get_row_data(row);
565
566     if (fdata != NULL) {
567         epan_dissect_t edt;
568
569         if (!cf_read_record(&cfile, fdata))
570             return NULL; /* error reading the record */
571         /* proto tree, visible. We need a proto tree if there's custom columns */
572         epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
573         col_custom_prime_edt(&edt, &cfile.cinfo);
574
575         epan_dissect_run(&edt, cfile.cd_t, &cfile.phdr,
576                          frame_tvbuff_new_buffer(fdata, &cfile.buf),
577                          fdata, &cfile.cinfo);
578         epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
579
580         if ((cfile.cinfo.columns[column].col_custom_occurrence) ||
581             (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
582         {
583             /* Only construct the filter when a single occurrence is displayed
584              * otherwise we might end up with a filter like "ip.proto==1,6".
585              *
586              * Or do we want to be able to filter on multiple occurrences so that
587              * the filter might be calculated as "ip.proto==1 && ip.proto==6"
588              * instead?
589              */
590             if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
591                 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
592                 /* leak a little; is there a safe wmem_ scope here? */
593                 if (cfile.cinfo.columns[column].col_fmt == COL_CUSTOM) {
594                     header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.columns[column].col_custom_fields);
595                     if (hfi && hfi->parent == -1) {
596                         /* Protocol only */
597                         buf = g_strdup(cfile.cinfo.col_expr.col_expr[column]);
598                     } else if (hfi && IS_FT_STRING(hfi->type)) {
599                         /* Custom string, add quotes */
600                         buf = g_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
601                                                cfile.cinfo.col_expr.col_expr_val[column]);
602                     }
603                 }
604                 if (buf == NULL) {
605                     buf = g_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
606                                            cfile.cinfo.col_expr.col_expr_val[column]);
607                 }
608             }
609         }
610
611         epan_dissect_cleanup(&edt);
612     }
613
614     return buf;
615 }
616
617 void
618 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
619 {
620     char *filter;
621
622     filter = get_filter_from_packet_list_row_and_column((GtkWidget *)data);
623
624     match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
625         action, filter);
626
627     g_free(filter);
628 }
629
630 /* This function allows users to right click in the details window and copy the text
631  * information to the operating systems clipboard.
632  *
633  * We first check to see if a string representation is setup in the tree and then
634  * read the string. If not available then we try to grab the value. If all else
635  * fails we display a message to the user to indicate the copy could not be completed.
636  */
637 void
638 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
639 {
640     GString *gtk_text_str = g_string_new("");
641     char labelstring[ITEM_LABEL_LENGTH];
642     char *stringpointer = labelstring;
643
644     switch(action)
645     {
646     case COPY_SELECTED_DESCRIPTION:
647         if (cfile.finfo_selected->rep &&
648             strlen(cfile.finfo_selected->rep->representation) > 0) {
649             g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
650         }
651         break;
652     case COPY_SELECTED_FIELDNAME:
653         if (cfile.finfo_selected->hfinfo->abbrev != 0) {
654             g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
655         }
656         break;
657     case COPY_SELECTED_VALUE:
658         if (cfile.edt !=0 ) {
659             gchar* field_str = get_node_field_value(cfile.finfo_selected, cfile.edt);
660             g_string_append(gtk_text_str, field_str);
661             g_free(field_str);
662         }
663         break;
664     default:
665         break;
666     }
667
668     if (gtk_text_str->len == 0) {
669         /* If no representation then... Try to read the value */
670         proto_item_fill_label(cfile.finfo_selected, stringpointer);
671         g_string_append(gtk_text_str, stringpointer);
672     }
673
674     if (gtk_text_str->len == 0) {
675         /* Could not get item so display error msg */
676         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
677     } else {
678         /* Copy string to clipboard */
679         copy_to_clipboard(gtk_text_str);
680     }
681     g_string_free(gtk_text_str, TRUE);                       /* Free the memory */
682 }
683
684
685 /* mark as reference time frame */
686 void
687 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
688     if (row == -1)
689         return;
690     if (set) {
691         frame->flags.ref_time=1;
692         cfile.ref_time_count++;
693     } else {
694         frame->flags.ref_time=0;
695         cfile.ref_time_count--;
696     }
697     cf_reftime_packets(&cfile);
698     if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
699         packet_list_freeze();
700         cfile.displayed_count--;
701         packet_list_recreate_visible_rows();
702         packet_list_thaw();
703     }
704     packet_list_queue_draw();
705 }
706
707
708 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
709 {
710     switch(btn) {
711     case(ESD_BTN_YES):
712         timestamp_set_type(TS_RELATIVE);
713         recent.gui_time_format  = TS_RELATIVE;
714         cf_timestamp_auto_precision(&cfile);
715         packet_list_queue_draw();
716         break;
717     case(ESD_BTN_NO):
718         break;
719     default:
720         g_assert_not_reached();
721     }
722
723     if (cfile.current_frame) {
724       set_frame_reftime(!cfile.current_frame->flags.ref_time,
725       cfile.current_frame, cfile.current_row);
726     }
727 }
728
729
730 void
731 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
732 {
733     static GtkWidget *reftime_dialog = NULL;
734
735     switch(action){
736     case REFTIME_TOGGLE:
737         if (cfile.current_frame) {
738             if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
739                 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
740                     "%sSwitch to the appropriate Time Display Format?%s\n\n"
741                     "Time References don't work well with the currently selected Time Display Format.\n\n"
742                     "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
743                     simple_dialog_primary_start(), simple_dialog_primary_end());
744                 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
745             } else {
746                 set_frame_reftime(!cfile.current_frame->flags.ref_time,
747                                   cfile.current_frame, cfile.current_row);
748             }
749         }
750         break;
751     case REFTIME_FIND_NEXT:
752         cf_find_packet_time_reference(&cfile, SD_FORWARD);
753         break;
754     case REFTIME_FIND_PREV:
755         cf_find_packet_time_reference(&cfile, SD_BACKWARD);
756         break;
757     }
758 }
759
760 void
761 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
762 {
763     cf_find_packet_marked(&cfile, SD_FORWARD);
764 }
765
766 void
767 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
768 {
769     cf_find_packet_marked(&cfile, SD_BACKWARD);
770 }
771
772 static void
773 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
774 {
775     field_info   *finfo;
776     gchar         len_str[2+10+1+5+1]; /* ", {N} bytes\0",
777                                           N < 4294967296 */
778     gboolean      has_blurb = FALSE;
779     guint         length = 0, byte_len;
780     GtkWidget    *byte_view;
781     const guint8 *byte_data;
782     gint          finfo_length;
783     GtkTreeModel *model;
784     GtkTreeIter   iter;
785
786     /* if nothing is selected */
787     if (!gtk_tree_selection_get_selected(sel, &model, &iter))
788     {
789         /*
790          * Which byte view is displaying the current protocol tree
791          * row's data?
792          */
793         byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
794         if (byte_view == NULL)
795             return; /* none */
796
797         byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
798         if (byte_data == NULL)
799             return; /* none */
800
801         cf_unselect_field(&cfile);
802         packet_hex_print(byte_view, byte_data,
803                          cfile.current_frame, NULL, byte_len);
804         return;
805     }
806     gtk_tree_model_get(model, &iter, 1, &finfo, -1);
807     if (!finfo) return;
808
809     set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
810
811     byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
812     byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
813     g_assert(byte_data != NULL);
814
815     cfile.finfo_selected = finfo;
816     set_menus_for_selected_tree_row(&cfile);
817
818     if (finfo->hfinfo) {
819         if (finfo->hfinfo->blurb != NULL &&
820             finfo->hfinfo->blurb[0] != '\0') {
821             has_blurb = TRUE;
822             length = (guint) strlen(finfo->hfinfo->blurb);
823         } else {
824             length = (guint) strlen(finfo->hfinfo->name);
825         }
826         finfo_length = finfo->length + finfo->appendix_length;
827
828         if (finfo_length == 0) {
829             len_str[0] = '\0';
830         } else if (finfo_length == 1) {
831             g_strlcpy (len_str, ", 1 byte", sizeof len_str);
832         } else {
833             g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
834         }
835         statusbar_pop_field_msg(); /* get rid of current help msg */
836         if (length) {
837             statusbar_push_field_msg(" %s (%s)%s",
838                     (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
839                     finfo->hfinfo->abbrev, len_str);
840         } else {
841             /*
842              * Don't show anything if the field name is zero-length;
843              * the pseudo-field for text-only items is such
844              * a field, and we don't want "Text (text)" showing up
845              * on the status line if you've selected such a field.
846              *
847              * XXX - there are zero-length fields for which we *do*
848              * want to show the field name.
849              *
850              * XXX - perhaps the name and abbrev field should be null
851              * pointers rather than null strings for that pseudo-field,
852              * but we'd have to add checks for null pointers in some
853              * places if we did that.
854              *
855              * Or perhaps text-only items should have -1 as the field
856              * index, with no pseudo-field being used, but that might
857              * also require special checks for -1 to be added.
858              */
859             statusbar_push_field_msg("%s", "");
860         }
861     }
862     packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
863                      byte_len);
864 }
865
866 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_)
867 {
868     if (cfile.edt->tree)
869         collapse_all_tree(cfile.edt->tree, tree_view_gbl);
870 }
871
872 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_)
873 {
874     if (cfile.edt->tree)
875         expand_all_tree(cfile.edt->tree, tree_view_gbl);
876 }
877
878 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
879 {
880     if (cfile.finfo_selected) {
881         column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
882                                 cfile.finfo_selected->hfinfo->abbrev,0);
883         /* Recreate the packet list according to new preferences */
884         packet_list_recreate ();
885         if (!prefs.gui_use_pref_save) {
886             prefs_main_write();
887         }
888         cfile.columns_changed = FALSE; /* Reset value */
889     }
890 }
891
892 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
893 {
894     GtkTreePath  *path;
895
896     path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
897     if(path) {
898         /* the mouse position is at an entry, expand that one */
899         gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
900         gtk_tree_path_free(path);
901     }
902 }
903
904 void collapse_tree_cb(GtkWidget *widget _U_, gpointer data _U_)
905 {
906     GtkTreePath  *path;
907
908     path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
909     if(path) {
910         /* the mouse position is at an entry, expand that one */
911
912         tree_collapse_path_all(GTK_TREE_VIEW(tree_view_gbl), path);
913         gtk_tree_path_free(path);
914     }
915 }
916
917 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_)
918 {
919     static const e_addr_resolve resolv_flags = {
920         TRUE,   /* mac_name */
921         TRUE,   /* network_name */
922         TRUE,   /* transport_name */
923         TRUE,   /* dns_pkt_addr_resolution */
924         TRUE,   /* use_external_net_name_resolver */
925         FALSE,  /* load_hosts_file_from_profile_only */
926         FALSE,  /* vlan_name */
927         FALSE,  /* ss7pc_name */
928     };
929
930     if (cfile.edt->tree) {
931         proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
932     }
933 }
934
935 /* Update main window items based on whether there's a capture in progress. */
936 static void
937 main_set_for_capture_in_progress(gboolean capture_in_progress)
938 {
939     set_menus_for_capture_in_progress(capture_in_progress);
940
941 #ifdef HAVE_LIBPCAP
942     set_toolbar_for_capture_in_progress(capture_in_progress);
943
944     set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
945 #endif
946 }
947
948 /* Update main window items based on whether we have a capture file. */
949 static void
950 main_set_for_capture_file(gboolean have_capture_file_in)
951 {
952     have_capture_file = have_capture_file_in;
953
954     main_widgets_show_or_hide();
955 }
956
957 /* Update main window items based on whether we have captured packets. */
958 static void
959 main_set_for_captured_packets(gboolean have_captured_packets)
960 {
961     set_menus_for_captured_packets(have_captured_packets);
962     set_toolbar_for_captured_packets(have_captured_packets);
963 }
964
965 /* Update main window items based on whether we have a packet history. */
966 void
967 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
968 {
969     set_menus_for_packet_history(back_history, forward_history);
970     set_toolbar_for_packet_history(back_history, forward_history);
971 }
972
973 gboolean
974 main_do_quit(void)
975 {
976     /* get the current geometry, before writing it to disk */
977     main_save_window_geometry(top_level);
978
979     /* write user's recent file to disk
980      * It is no problem to write this file, even if we do not quit */
981     write_profile_recent();
982     write_recent();
983
984     /* XXX - should we check whether the capture file is an
985        unsaved temporary file for a live capture and, if so,
986        pop up a "do you want to exit without saving the capture
987        file?" dialog, and then just return, leaving said dialog
988        box to forcibly quit if the user clicks "OK"?
989
990        If so, note that this should be done in a subroutine that
991        returns TRUE if we do so, and FALSE otherwise, and if it
992        returns TRUE we should return TRUE without nuking anything.
993
994        Note that, if we do that, we might also want to check if
995        an "Update list of packets in real time" capture is in
996        progress and, if so, ask whether they want to terminate
997        the capture and discard it, and return TRUE, before nuking
998        any child capture, if they say they don't want to do so. */
999
1000 #ifdef HAVE_LIBPCAP
1001     /* Nuke any child capture in progress. */
1002     capture_kill_child(&global_capture_session);
1003 #endif
1004
1005     /* Are we in the middle of reading a capture? */
1006     if (cfile.state == FILE_READ_IN_PROGRESS) {
1007         /* Yes, so we can't just close the file and quit, as
1008            that may yank the rug out from under the read in
1009            progress; instead, just set the state to
1010            "FILE_READ_ABORTED" and return - the code doing the read
1011            will check for that and, if it sees that, will clean
1012            up and quit. */
1013         cfile.state = FILE_READ_ABORTED;
1014
1015         /* Say that the window should *not* be deleted;
1016            that'll be done by the code that cleans up. */
1017         return TRUE;
1018     } else {
1019         /* Close any capture file we have open; on some OSes, you
1020            can't unlink a temporary capture file if you have it
1021            open.
1022            "cf_close()" will unlink it after closing it if
1023            it's a temporary file.
1024
1025            We do this here, rather than after the main loop returns,
1026            as, after the main loop returns, the main window may have
1027            been destroyed (if this is called due to a "destroy"
1028            even on the main window rather than due to the user
1029            selecting a menu item), and there may be a crash
1030            or other problem when "cf_close()" tries to
1031            clean up stuff in the main window.
1032
1033            XXX - is there a better place to put this?
1034            Or should we have a routine that *just* closes the
1035            capture file, and doesn't do anything with the UI,
1036            which we'd call here, and another routine that
1037            calls that routine and also cleans up the UI, which
1038            we'd call elsewhere? */
1039         cf_close(&cfile);
1040
1041         /* Exit by leaving the main loop, so that any quit functions
1042            we registered get called. */
1043         gtk_main_quit();
1044
1045         /* Say that the window should be deleted. */
1046         return FALSE;
1047     }
1048 }
1049
1050 static gboolean
1051 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1052 {
1053     /* If we're in the middle of stopping a capture, don't do anything;
1054        the user can try deleting the window after the capture stops. */
1055     if (capture_stopping)
1056         return TRUE;
1057
1058     /* If there's unsaved data, let the user save it first.
1059        If they cancel out of it, don't quit. */
1060     if (do_file_close(&cfile, TRUE, " before quitting"))
1061         return main_do_quit();
1062     else
1063         return TRUE; /* will this keep the window from being deleted? */
1064 }
1065
1066
1067 static void
1068 main_pane_load_window_geometry(void)
1069 {
1070     if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1071         gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1072     if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1073         gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1074     }
1075 }
1076
1077
1078 static void
1079 main_load_window_geometry(GtkWidget *widget)
1080 {
1081     window_geometry_t geom;
1082
1083     geom.set_pos        = prefs.gui_geometry_save_position;
1084     geom.x              = recent.gui_gtk_geometry_main_x;
1085     geom.y              = recent.gui_gtk_geometry_main_y;
1086     geom.set_size       = prefs.gui_geometry_save_size;
1087     geom.set_maximized  = FALSE;
1088     if (recent.gui_geometry_main_width > 0 &&
1089         recent.gui_geometry_main_height > 0) {
1090         geom.width          = recent.gui_geometry_main_width;
1091         geom.height         = recent.gui_geometry_main_height;
1092         geom.set_maximized  = prefs.gui_geometry_save_maximized;
1093     } else {
1094         /* We assume this means the width and height weren't set in
1095            the "recent" file (or that there is no "recent" file),
1096            and weren't set to a default value, so we don't set the
1097            size.  (The "recent" file code rejects non-positive width
1098            and height values.) */
1099        geom.set_size = FALSE;
1100     }
1101     geom.maximized      = recent.gui_geometry_main_maximized;
1102
1103     window_set_geometry(widget, &geom);
1104
1105     main_pane_load_window_geometry();
1106     statusbar_load_window_geometry();
1107 }
1108
1109
1110 static void
1111 main_save_window_geometry(GtkWidget *widget)
1112 {
1113     window_geometry_t geom;
1114
1115     window_get_geometry(widget, &geom);
1116
1117     if (prefs.gui_geometry_save_position) {
1118         recent.gui_gtk_geometry_main_x = geom.x;
1119         recent.gui_gtk_geometry_main_y = geom.y;
1120     }
1121
1122     if (prefs.gui_geometry_save_size) {
1123         recent.gui_geometry_main_width  = geom.width;
1124         recent.gui_geometry_main_height = geom.height;
1125     }
1126
1127     if(prefs.gui_geometry_save_maximized) {
1128         recent.gui_geometry_main_maximized = geom.maximized;
1129     }
1130
1131     recent.gui_geometry_main_upper_pane     = gtk_paned_get_position(GTK_PANED(main_first_pane));
1132     recent.gui_geometry_main_lower_pane     = gtk_paned_get_position(GTK_PANED(main_second_pane));
1133     statusbar_save_window_geometry();
1134 }
1135
1136 void
1137 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1138 {
1139     /* If there's unsaved data, let the user save it first. */
1140     if (do_file_close(&cfile, TRUE, " before quitting"))
1141         main_do_quit();
1142 }
1143
1144 /*
1145  * Report an error in command-line arguments.
1146  * Creates a console on Windows.
1147  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1148  * terminal isn't the standard error?
1149  */
1150 static void
1151 wireshark_cmdarg_err(const char *fmt, va_list ap)
1152 {
1153 #ifdef _WIN32
1154     create_console();
1155 #endif
1156     fprintf(stderr, "wireshark: ");
1157     vfprintf(stderr, fmt, ap);
1158     fprintf(stderr, "\n");
1159 }
1160
1161 /*
1162  * Report additional information for an error in command-line arguments.
1163  * Creates a console on Windows.
1164  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1165  * terminal isn't the standard error?
1166  */
1167 static void
1168 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
1169 {
1170 #ifdef _WIN32
1171     create_console();
1172 #endif
1173     vfprintf(stderr, fmt, ap);
1174     fprintf(stderr, "\n");
1175 }
1176
1177 /*
1178    Once every 3 seconds we get a callback here which we use to update
1179    the tap extensions.
1180  */
1181 static gboolean
1182 tap_update_cb(gpointer data _U_)
1183 {
1184     draw_tap_listeners(FALSE);
1185     return TRUE;
1186 }
1187
1188 /*
1189  * Periodically process outstanding hostname lookups. If we have new items,
1190  * redraw the packet list and tree view.
1191  */
1192
1193 static gboolean
1194 resolv_update_cb(gpointer data _U_)
1195 {
1196     /* Anything new show up? */
1197     if (host_name_lookup_process()) {
1198         if (gtk_widget_get_window(pkt_scrollw))
1199             gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1200         if (gtk_widget_get_window(tv_scrollw))
1201             gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1202     }
1203
1204     /* Always check. Even if we don't do async lookups we could still get
1205         passive updates, e.g. from DNS packets. */
1206     return TRUE;
1207 }
1208
1209
1210 /* Update various parts of the main window for a capture file "unsaved
1211    changes" change - update the title to reflect whether there are
1212    unsaved changes or not, and update the menus and toolbar to
1213    enable or disable the "Save" operation. */
1214 void
1215 main_update_for_unsaved_changes(capture_file *cf)
1216 {
1217     set_titlebar_for_capture_file(cf);
1218     set_menus_for_capture_file(cf);
1219     set_toolbar_for_capture_file(cf);
1220 }
1221
1222 #ifdef HAVE_LIBPCAP
1223 void
1224 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1225 {
1226     /* Update menubar and toolbar */
1227     menu_auto_scroll_live_changed(auto_scroll_live_in);
1228     toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1229
1230     /* change auto scroll state */
1231     auto_scroll_live  = auto_scroll_live_in;
1232 }
1233 #endif
1234
1235 void
1236 main_colorize_changed(gboolean packet_list_colorize)
1237 {
1238     /* Update menubar and toolbar */
1239     menu_colorize_changed(packet_list_colorize);
1240     toolbar_colorize_changed(packet_list_colorize);
1241
1242     /* change colorization */
1243     if(packet_list_colorize != recent.packet_list_colorize) {
1244         recent.packet_list_colorize = packet_list_colorize;
1245         packet_list_enable_color(packet_list_colorize);
1246         packet_list_colorize_packets();
1247     }
1248 }
1249
1250 static GtkWidget           *close_dlg = NULL;
1251
1252 static void
1253 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1254 {
1255     recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1256 }
1257
1258 #ifdef _WIN32
1259 static void
1260 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1261 {
1262     recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1263 }
1264 #endif
1265
1266 static void
1267 main_cf_cb_file_closing(capture_file *cf)
1268 {
1269     /* if we have more than 10000 packets, show a splash screen while closing */
1270     /* XXX - don't know a better way to decide whether to show or not,
1271      * as most of the time is spend in various calls that destroy various
1272      * data structures, so it wouldn't be easy to use a progress bar,
1273      * rather than, say, a progress spinner, here! */
1274     if(cf->count > 10000) {
1275         close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1276                                   "%sClosing file!%s\n\nPlease wait ...",
1277                                   simple_dialog_primary_start(),
1278                                   simple_dialog_primary_end());
1279         gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1280     }
1281     /* Clear maunally resolved addresses */
1282     manually_resolve_cleanup();
1283     /* Destroy all windows that refer to the
1284        capture file we're closing. */
1285     destroy_packet_wins();
1286
1287     /* Update the titlebar to reflect the lack of a capture file. */
1288     set_titlebar_for_capture_file(NULL);
1289
1290     /* Disable all menu and toolbar items that make sense only if
1291        you have a capture. */
1292     set_menus_for_capture_file(NULL);
1293     set_toolbar_for_capture_file(NULL);
1294     main_set_for_captured_packets(FALSE);
1295     set_menus_for_selected_packet(cf);
1296     main_set_for_capture_in_progress(FALSE);
1297     set_capture_if_dialog_for_capture_in_progress(FALSE);
1298     set_menus_for_selected_tree_row(cf);
1299
1300     /* Set up main window for no capture file. */
1301     main_set_for_capture_file(FALSE);
1302
1303     main_window_update();
1304
1305 }
1306
1307 static void
1308 main_cf_cb_file_closed(capture_file *cf _U_)
1309 {
1310     if(close_dlg != NULL) {
1311         splash_destroy(close_dlg);
1312         close_dlg = NULL;
1313     }
1314 }
1315
1316
1317 static void
1318 main_cf_cb_file_read_started(capture_file *cf _U_)
1319 {
1320     tap_param_dlg_update();
1321
1322     /* Set up main window for a capture file. */
1323     main_set_for_capture_file(TRUE);
1324 }
1325
1326 static void
1327 main_cf_cb_file_read_finished(capture_file *cf)
1328 {
1329     gchar *dir_path;
1330
1331     if (!cf->is_tempfile && cf->filename) {
1332         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1333         add_menu_recent_capture_file(cf->filename);
1334
1335         /* Remember folder for next Open dialog and save it in recent */
1336         dir_path = g_strdup(cf->filename);
1337         set_last_open_dir(get_dirname(dir_path));
1338         g_free(dir_path);
1339     }
1340
1341     /* Update the appropriate parts of the main window. */
1342     main_update_for_unsaved_changes(cf);
1343
1344     /* Enable menu items that make sense if you have some captured packets. */
1345     main_set_for_captured_packets(TRUE);
1346 }
1347
1348 static void
1349 main_cf_cb_file_rescan_finished(capture_file *cf)
1350 {
1351     gchar *dir_path;
1352
1353     if (!cf->is_tempfile && cf->filename) {
1354         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1355         add_menu_recent_capture_file(cf->filename);
1356
1357         /* Remember folder for next Open dialog and save it in recent */
1358         dir_path = g_strdup(cf->filename);
1359         set_last_open_dir(get_dirname(dir_path));
1360         g_free(dir_path);
1361     }
1362
1363     /* Update the appropriate parts of the main window. */
1364     main_update_for_unsaved_changes(cf);
1365 }
1366
1367 #ifdef HAVE_LIBPCAP
1368 static GList *icon_list_create(
1369 #ifdef HAVE_GDK_GRESOURCE
1370     const gchar *icon16_path,
1371     const gchar *icon32_path,
1372     const gchar *icon48_path,
1373     const gchar *icon64_path)
1374 #else
1375     const guint8 *icon16_pb,
1376     const guint8 *icon32_pb,
1377     const guint8 *icon48_pb,
1378     const guint8 *icon64_pb)
1379 #endif
1380 {
1381     GList *icon_list = NULL;
1382     GdkPixbuf *pixbuf16 = NULL;
1383     GdkPixbuf *pixbuf32 = NULL;
1384     GdkPixbuf *pixbuf48 = NULL;
1385     GdkPixbuf *pixbuf64 = NULL;
1386
1387 #ifdef HAVE_GDK_GRESOURCE
1388     if (icon16_path != NULL)
1389         pixbuf16 = ws_gdk_pixbuf_new_from_resource(icon16_path);
1390     if (icon32_path != NULL)
1391         pixbuf32 = ws_gdk_pixbuf_new_from_resource(icon32_path);
1392     if (icon48_path != NULL)
1393         pixbuf48 = ws_gdk_pixbuf_new_from_resource(icon48_path);
1394     if (icon64_path != NULL)
1395         pixbuf64 = ws_gdk_pixbuf_new_from_resource(icon64_path);
1396 #else
1397     if (icon16_pb != NULL)
1398         pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1399     if (icon32_pb != NULL)
1400         pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1401     if (icon48_pb != NULL)
1402         pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1403     if (icon64_pb != NULL)
1404         pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1405 #endif
1406
1407     if (pixbuf16 != NULL)
1408         icon_list = g_list_append(icon_list, pixbuf16);
1409     if (pixbuf32 != NULL)
1410         icon_list = g_list_append(icon_list, pixbuf32);
1411     if (pixbuf48 != NULL)
1412         icon_list = g_list_append(icon_list, pixbuf48);
1413     if (pixbuf64 != NULL)
1414         icon_list = g_list_append(icon_list, pixbuf64);
1415
1416     return icon_list;
1417 }
1418
1419 static void
1420 main_capture_cb_capture_prepared(capture_session *cap_session)
1421 {
1422     static GList *icon_list = NULL;
1423
1424     set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1425
1426     if(icon_list == NULL) {
1427 #ifdef HAVE_GDK_GRESOURCE
1428         icon_list = icon_list_create("/org/wireshark/image/wsiconcap16.png",
1429                                         "/org/wireshark/image/wsiconcap32.png",
1430                                         "/org/wireshark/image/wsiconcap48.png",
1431                                         "/org/wireshark/image/wsiconcap64.png");
1432 #else
1433         icon_list = icon_list_create(wsiconcap_16_pb_data,
1434                                         wsiconcap_32_pb_data,
1435                                         wsiconcap_48_pb_data,
1436                                         wsiconcap_64_pb_data);
1437 #endif
1438     }
1439     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1440
1441     /* Disable menu items that make no sense if you're currently running
1442        a capture. */
1443     main_set_for_capture_in_progress(TRUE);
1444     set_capture_if_dialog_for_capture_in_progress(TRUE);
1445
1446     /* Don't set up main window for a capture file. */
1447     main_set_for_capture_file(FALSE);
1448 }
1449
1450 static void
1451 main_capture_cb_capture_update_started(capture_session *cap_session)
1452 {
1453     /* We've done this in "prepared" above, but it will be cleared while
1454        switching to the next multiple file. */
1455     set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1456
1457     main_set_for_capture_in_progress(TRUE);
1458     set_capture_if_dialog_for_capture_in_progress(TRUE);
1459
1460     /* Enable menu items that make sense if you have some captured
1461        packets (yes, I know, we don't have any *yet*). */
1462     main_set_for_captured_packets(TRUE);
1463
1464     /* Set up main window for a capture file. */
1465     main_set_for_capture_file(TRUE);
1466 }
1467
1468 static void
1469 main_capture_cb_capture_update_finished(capture_session *cap_session)
1470 {
1471     capture_file *cf = (capture_file *)cap_session->cf;
1472     static GList *icon_list = NULL;
1473
1474     /* The capture isn't stopping any more - it's stopped. */
1475     capture_stopping = FALSE;
1476
1477     if (!cf->is_tempfile && cf->filename) {
1478         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1479         add_menu_recent_capture_file(cf->filename);
1480     }
1481
1482     /* Enable menu items that make sense if you're not currently running
1483      a capture. */
1484     main_set_for_capture_in_progress(FALSE);
1485     set_capture_if_dialog_for_capture_in_progress(FALSE);
1486
1487     /* Update the main window as appropriate. This has to occur AFTER
1488      * main_set_for_capture_in_progress() or else some of the menus are
1489      * incorrectly disabled (see bug
1490      * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1491     main_update_for_unsaved_changes(cf);
1492
1493     /* Set up main window for a capture file. */
1494     main_set_for_capture_file(TRUE);
1495
1496     if(icon_list == NULL) {
1497 #ifdef HAVE_GDK_GRESOURCE
1498         icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1499                                         "/org/wireshark/image/wsicon32.png",
1500                                         "/org/wireshark/image/wsicon48.png",
1501                                         "/org/wireshark/image/wsicon64.png");
1502 #else
1503         icon_list = icon_list_create(wsicon_16_pb_data,
1504                                         wsicon_32_pb_data,
1505                                         wsicon_48_pb_data,
1506                                         wsicon_64_pb_data);
1507 #endif
1508     }
1509     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1510
1511     if(global_commandline_info.quit_after_cap) {
1512         /* command line asked us to quit after the capture */
1513         /* don't pop up a dialog to ask for unsaved files etc. */
1514         main_do_quit();
1515     }
1516 }
1517
1518 static void
1519 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1520 {
1521     /* Don't set up main window for a capture file. */
1522     main_set_for_capture_file(FALSE);
1523 }
1524
1525 static void
1526 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1527 {
1528 #if 0
1529     capture_file *cf = (capture_file *)cap_session->cf;
1530 #endif
1531     static GList *icon_list = NULL;
1532
1533     /* The capture isn't stopping any more - it's stopped. */
1534     capture_stopping = FALSE;
1535
1536     /*set_titlebar_for_capture_file(cf);*/
1537
1538     /* Enable menu items that make sense if you're not currently running
1539      a capture. */
1540     main_set_for_capture_in_progress(FALSE);
1541     set_capture_if_dialog_for_capture_in_progress(FALSE);
1542
1543     /* Restore the standard title bar message */
1544     /* (just in case we have trouble opening the capture file). */
1545     set_titlebar_for_capture_file(NULL);
1546
1547     if(icon_list == NULL) {
1548 #ifdef HAVE_GDK_GRESOURCE
1549         icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1550                                         "/org/wireshark/image/wsicon32.png",
1551                                         "/org/wireshark/image/wsicon48.png",
1552                                         "/org/wireshark/image/wsicon64.png");
1553 #else
1554         icon_list = icon_list_create(wsicon_16_pb_data,
1555                                         wsicon_32_pb_data,
1556                                         wsicon_48_pb_data,
1557                                         wsicon_64_pb_data);
1558 #endif
1559     }
1560     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1561
1562     /* We don't have loaded the capture file, this will be done later.
1563      * For now we still have simply a blank screen. */
1564
1565     if(global_commandline_info.quit_after_cap) {
1566         /* command line asked us to quit after the capture */
1567         /* don't pop up a dialog to ask for unsaved files etc. */
1568         main_do_quit();
1569     }
1570 }
1571
1572 static void
1573 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1574 {
1575     capture_stopping = TRUE;
1576     set_menus_for_capture_stopping();
1577 #ifdef HAVE_LIBPCAP
1578     set_toolbar_for_capture_stopping();
1579
1580     set_capture_if_dialog_for_capture_stopping();
1581 #endif
1582 }
1583
1584 static void
1585 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1586 {
1587     static GList *icon_list = NULL;
1588
1589     /* Capture isn't stopping any more. */
1590     capture_stopping = FALSE;
1591
1592     /* the capture failed before the first packet was captured
1593        reset title, menus and icon */
1594     set_titlebar_for_capture_file(NULL);
1595
1596     main_set_for_capture_in_progress(FALSE);
1597     set_capture_if_dialog_for_capture_in_progress(FALSE);
1598
1599     main_set_for_capture_file(FALSE);
1600
1601     if(icon_list == NULL) {
1602 #ifdef HAVE_GDK_GRESOURCE
1603         icon_list = icon_list_create("/org/wireshark/image/wsicon16.png",
1604                                         "/org/wireshark/image/wsicon32.png",
1605                                         "/org/wireshark/image/wsicon48.png",
1606                                         "/org/wireshark/image/wsicon64.png");
1607 #else
1608         icon_list = icon_list_create(wsicon_16_pb_data,
1609                                         wsicon_32_pb_data,
1610                                         wsicon_48_pb_data,
1611                                         wsicon_64_pb_data);
1612 #endif
1613     }
1614     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1615
1616
1617     if(global_commandline_info.quit_after_cap) {
1618         /* command line asked us to quit after the capture */
1619         /* don't pop up a dialog to ask for unsaved files etc. */
1620         main_do_quit();
1621     }
1622 }
1623 #endif  /* HAVE_LIBPCAP */
1624
1625 static void
1626 main_cf_cb_packet_selected(gpointer data)
1627 {
1628     capture_file *cf = (capture_file *)data;
1629
1630     /* Display the GUI protocol tree and packet bytes.
1631       XXX - why do we dump core if we call "proto_tree_draw()"
1632       before calling "add_byte_views()"? */
1633     add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1634     proto_tree_draw(cf->edt->tree, tree_view_gbl);
1635
1636     /* Note: Both string and hex value searches in the packet data produce a non-zero
1637        search_pos if successful */
1638     if(cf->search_in_progress &&
1639       (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1640         highlight_field(cf->edt->tvb, cf->search_pos,
1641                         (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1642     }
1643
1644     /* A packet is selected. */
1645     set_menus_for_selected_packet(cf);
1646 }
1647
1648 static void
1649 main_cf_cb_packet_unselected(capture_file *cf)
1650 {
1651     /* No packet is being displayed; clear the hex dump pane by getting
1652        rid of all the byte views. */
1653     while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1654         gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1655
1656     /* Add a placeholder byte view so that there's at least something
1657        displayed in the byte view notebook. */
1658     add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1659
1660     /* And clear the protocol tree display as well. */
1661     proto_tree_draw(NULL, tree_view_gbl);
1662
1663     /* No packet is selected. */
1664     set_menus_for_selected_packet(cf);
1665 }
1666
1667 static void
1668 main_cf_cb_field_unselected(capture_file *cf)
1669 {
1670     set_menus_for_selected_tree_row(cf);
1671 }
1672
1673 static void
1674 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1675 {
1676     capture_file *cf = (capture_file *)data;
1677     switch(event) {
1678     case(cf_cb_file_opened):
1679         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1680         fileset_file_opened(cf);
1681         break;
1682     case(cf_cb_file_closing):
1683         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1684         main_cf_cb_file_closing(cf);
1685         break;
1686     case(cf_cb_file_closed):
1687         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1688         main_cf_cb_file_closed(cf);
1689         fileset_file_closed();
1690         break;
1691     case(cf_cb_file_read_started):
1692         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1693         main_cf_cb_file_read_started(cf);
1694         break;
1695     case(cf_cb_file_read_finished):
1696         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1697         main_cf_cb_file_read_finished(cf);
1698         break;
1699     case(cf_cb_file_reload_started):
1700         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1701         main_cf_cb_file_read_started(cf);
1702         break;
1703     case(cf_cb_file_reload_finished):
1704         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1705         main_cf_cb_file_read_finished(cf);
1706         break;
1707     case(cf_cb_file_rescan_started):
1708         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1709         break;
1710     case(cf_cb_file_rescan_finished):
1711         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1712         main_cf_cb_file_rescan_finished(cf);
1713         break;
1714     case(cf_cb_file_retap_started):
1715         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap started");
1716         break;
1717     case(cf_cb_file_retap_finished):
1718         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Retap finished");
1719         break;
1720     case(cf_cb_file_fast_save_finished):
1721         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1722         main_cf_cb_file_rescan_finished(cf);
1723         break;
1724     case(cf_cb_packet_selected):
1725         main_cf_cb_packet_selected(cf);
1726         break;
1727     case(cf_cb_packet_unselected):
1728         main_cf_cb_packet_unselected(cf);
1729         break;
1730     case(cf_cb_field_unselected):
1731         main_cf_cb_field_unselected(cf);
1732         break;
1733     case(cf_cb_file_save_started):
1734         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1735         break;
1736     case(cf_cb_file_save_finished):
1737         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1738         break;
1739     case(cf_cb_file_save_failed):
1740         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1741         break;
1742     case(cf_cb_file_save_stopped):
1743         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1744         break;
1745     case(cf_cb_file_export_specified_packets_started):
1746         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1747         break;
1748     case(cf_cb_file_export_specified_packets_finished):
1749         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1750         break;
1751     case(cf_cb_file_export_specified_packets_failed):
1752         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1753         break;
1754     case(cf_cb_file_export_specified_packets_stopped):
1755         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1756         break;
1757     default:
1758         g_warning("main_cf_callback: event %u unknown", event);
1759         g_assert_not_reached();
1760     }
1761 }
1762
1763 #ifdef HAVE_LIBPCAP
1764 static void
1765 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1766 {
1767 #ifdef HAVE_GTKOSXAPPLICATION
1768     GtkosxApplication *theApp;
1769 #endif
1770     switch(event) {
1771     case(capture_cb_capture_prepared):
1772         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1773         main_capture_cb_capture_prepared(cap_session);
1774         break;
1775     case(capture_cb_capture_update_started):
1776         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1777         main_capture_cb_capture_update_started(cap_session);
1778 #ifdef HAVE_GTKOSXAPPLICATION
1779         theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1780 #ifdef HAVE_GDK_GRESOURCE
1781         gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon48.png"));
1782 #else
1783         gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_48_pb_data, FALSE, NULL));
1784 #endif
1785 #endif
1786         break;
1787     case(capture_cb_capture_update_continue):
1788         /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1789         break;
1790     case(capture_cb_capture_update_finished):
1791         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1792         main_capture_cb_capture_update_finished(cap_session);
1793         break;
1794     case(capture_cb_capture_fixed_started):
1795         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1796         main_capture_cb_capture_fixed_started(cap_session);
1797         break;
1798     case(capture_cb_capture_fixed_continue):
1799         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1800         break;
1801     case(capture_cb_capture_fixed_finished):
1802         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1803         main_capture_cb_capture_fixed_finished(cap_session);
1804         break;
1805     case(capture_cb_capture_stopping):
1806         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1807         /* Beware: this state won't be called, if the capture child
1808          * closes the capturing on its own! */
1809 #ifdef HAVE_GTKOSXAPPLICATION
1810         theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1811 #ifdef HAVE_GDK_GRESOURCE
1812         gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
1813 #else
1814         gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1815 #endif
1816 #endif
1817         main_capture_cb_capture_stopping(cap_session);
1818         break;
1819     case(capture_cb_capture_failed):
1820         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1821         main_capture_cb_capture_failed(cap_session);
1822         break;
1823     default:
1824         g_warning("main_capture_callback: event %u unknown", event);
1825         g_assert_not_reached();
1826     }
1827 }
1828 #endif
1829
1830 void
1831 get_wireshark_gtk_compiled_info(GString *str)
1832 {
1833     g_string_append(str, "with ");
1834     g_string_append_printf(str,
1835 #ifdef GTK_MAJOR_VERSION
1836                            "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1837                            GTK_MICRO_VERSION);
1838 #else
1839                            "GTK+ (version unknown)");
1840 #endif
1841
1842     /* Cairo */
1843     g_string_append(str, ", with Cairo ");
1844     g_string_append(str, CAIRO_VERSION_STRING);
1845
1846     /* Pango */
1847     g_string_append(str, ", with Pango ");
1848     g_string_append(str, PANGO_VERSION_STRING);
1849
1850     /* Capture libraries */
1851     g_string_append(str, ", ");
1852     get_compiled_caplibs_version(str);
1853 }
1854
1855 void
1856 get_gui_compiled_info(GString *str)
1857 {
1858     epan_get_compiled_version_info(str);
1859
1860     g_string_append(str, ", ");
1861 #ifdef HAVE_LIBPORTAUDIO
1862 #ifdef PORTAUDIO_API_1
1863     g_string_append(str, "with PortAudio <= V18");
1864 #else /* PORTAUDIO_API_1 */
1865     g_string_append(str, "with ");
1866     g_string_append(str, Pa_GetVersionText());
1867 #endif /* PORTAUDIO_API_1 */
1868 #else /* HAVE_LIBPORTAUDIO */
1869     g_string_append(str, "without PortAudio");
1870 #endif /* HAVE_LIBPORTAUDIO */
1871
1872     g_string_append(str, ", ");
1873 #ifdef HAVE_AIRPCAP
1874     get_compiled_airpcap_version(str);
1875 #else
1876     g_string_append(str, "without AirPcap");
1877 #endif
1878
1879     codec_get_compiled_version_info(str);
1880 }
1881
1882 void
1883 get_wireshark_runtime_info(GString *str)
1884 {
1885 #ifdef HAVE_LIBPCAP
1886     /* Capture libraries */
1887     g_string_append(str, ", ");
1888     get_runtime_caplibs_version(str);
1889 #endif
1890
1891     /* stuff used by libwireshark */
1892     epan_get_runtime_version_info(str);
1893
1894 #ifdef HAVE_AIRPCAP
1895     g_string_append(str, ", ");
1896     get_runtime_airpcap_version(str);
1897 #endif
1898 }
1899
1900 static e_prefs *
1901 read_configuration_files(char **gdp_path, char **dp_path)
1902 {
1903     int                  gpf_open_errno, gpf_read_errno;
1904     int                  cf_open_errno, df_open_errno;
1905     int                  gdp_open_errno, gdp_read_errno;
1906     int                  dp_open_errno, dp_read_errno;
1907     char                *gpf_path, *pf_path;
1908     char                *cf_path, *df_path;
1909     int                  pf_open_errno, pf_read_errno;
1910     e_prefs             *prefs_p;
1911
1912     /* load the decode as entries of this profile */
1913     load_decode_as_entries();
1914
1915     /* Read the preference files. */
1916     prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1917                          &pf_open_errno, &pf_read_errno, &pf_path);
1918
1919     if (gpf_path != NULL) {
1920         if (gpf_open_errno != 0) {
1921             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1922                           "Could not open global preferences file\n\"%s\": %s.",
1923                           gpf_path, g_strerror(gpf_open_errno));
1924         }
1925         if (gpf_read_errno != 0) {
1926             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1927                           "I/O error reading global preferences file\n\"%s\": %s.",
1928                           gpf_path, g_strerror(gpf_read_errno));
1929         }
1930     }
1931     if (pf_path != NULL) {
1932         if (pf_open_errno != 0) {
1933             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1934                           "Could not open your preferences file\n\"%s\": %s.",
1935                           pf_path, g_strerror(pf_open_errno));
1936         }
1937         if (pf_read_errno != 0) {
1938             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1939                           "I/O error reading your preferences file\n\"%s\": %s.",
1940                           pf_path, g_strerror(pf_read_errno));
1941         }
1942         g_free(pf_path);
1943         pf_path = NULL;
1944     }
1945
1946 #ifdef _WIN32
1947     /* if the user wants a console to be always there, well, we should open one for him */
1948     if (prefs_p->gui_console_open == console_open_always) {
1949         create_console();
1950     }
1951 #endif
1952
1953     /* Read the capture filter file. */
1954     read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1955     if (cf_path != NULL) {
1956         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1957                       "Could not open your capture filter file\n\"%s\": %s.",
1958                       cf_path, g_strerror(cf_open_errno));
1959         g_free(cf_path);
1960     }
1961
1962     /* Read the display filter file. */
1963     read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1964     if (df_path != NULL) {
1965         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1966                       "Could not open your display filter file\n\"%s\": %s.",
1967                       df_path, g_strerror(df_open_errno));
1968         g_free(df_path);
1969     }
1970
1971     /* Read the disabled protocols file. */
1972     read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1973                               dp_path, &dp_open_errno, &dp_read_errno);
1974     read_enabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1975                               dp_path, &dp_open_errno, &dp_read_errno);
1976     read_disabled_heur_dissector_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
1977                               dp_path, &dp_open_errno, &dp_read_errno);
1978     if (*gdp_path != NULL) {
1979         if (gdp_open_errno != 0) {
1980             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1981                           "Could not open global disabled protocols file\n\"%s\": %s.",
1982                           *gdp_path, g_strerror(gdp_open_errno));
1983         }
1984         if (gdp_read_errno != 0) {
1985             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1986                           "I/O error reading global disabled protocols file\n\"%s\": %s.",
1987                           *gdp_path, g_strerror(gdp_read_errno));
1988         }
1989         g_free(*gdp_path);
1990         *gdp_path = NULL;
1991     }
1992     if (*dp_path != NULL) {
1993         if (dp_open_errno != 0) {
1994             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1995                           "Could not open your disabled protocols file\n\"%s\": %s.",
1996                           *dp_path, g_strerror(dp_open_errno));
1997         }
1998         if (dp_read_errno != 0) {
1999             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2000                           "I/O error reading your disabled protocols file\n\"%s\": %s.",
2001                           *dp_path, g_strerror(dp_read_errno));
2002         }
2003         g_free(*dp_path);
2004         *dp_path = NULL;
2005     }
2006
2007     return prefs_p;
2008 }
2009
2010 /*  Check if there's something important to tell the user during startup.
2011  *  We want to do this *after* showing the main window so that any windows
2012  *  we pop up will be above the main window.
2013  */
2014 static void
2015 #ifdef _WIN32
2016 check_and_warn_user_startup(gchar *cf_name)
2017 #else
2018 check_and_warn_user_startup(gchar *cf_name _U_)
2019 #endif
2020 {
2021     gchar               *cur_user, *cur_group;
2022     gpointer             priv_warning_dialog;
2023
2024     /* Tell the user not to run as root. */
2025     if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2026         cur_user = get_cur_username();
2027         cur_group = get_cur_groupname();
2028         priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2029         "Running as user \"%s\" and group \"%s\".\n"
2030         "This could be dangerous.\n\n"
2031         "If you're running Wireshark this way in order to perform live capture, "
2032         "you may want to be aware that there is a better way documented at\n"
2033         "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2034         g_free(cur_user);
2035         g_free(cur_group);
2036         simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2037         simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2038     }
2039
2040 #ifdef _WIN32
2041     /* Warn the user if npf.sys isn't loaded. */
2042     if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
2043         priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2044         "The NPF driver isn't running.  You may have trouble\n"
2045         "capturing or listing interfaces.");
2046         simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2047         simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2048     }
2049 #endif
2050
2051 }
2052
2053 /* And now our feature presentation... [ fade to music ] */
2054 int
2055 main(int argc, char *argv[])
2056 {
2057     char                *init_progfile_dir_error;
2058     char                *s;
2059
2060     extern int           info_update_freq;  /* Found in about_dlg.c. */
2061     const gchar         *filter;
2062
2063 #ifdef _WIN32
2064     WSADATA              wsaData;
2065 #endif  /* _WIN32 */
2066
2067     char                *rf_path;
2068     int                  rf_open_errno;
2069     char                *gdp_path, *dp_path;
2070     int                  err;
2071 #ifdef HAVE_LIBPCAP
2072     gchar               *err_str;
2073     int                  status;
2074 #else
2075 #ifdef _WIN32
2076 #ifdef HAVE_AIRPCAP
2077     gchar               *err_str;
2078 #endif
2079 #endif
2080 #endif
2081     gint                 pl_size = 280, tv_size = 95, bv_size = 75;
2082     gchar               *rc_file;
2083     dfilter_t           *rfcode = NULL;
2084     gchar               *err_msg = NULL;
2085     gboolean             rfilter_parse_failed = FALSE;
2086     GtkWidget           *splash_win = NULL;
2087     dfilter_t           *jump_to_filter = NULL;
2088     unsigned int         in_file_type = WTAP_TYPE_AUTO;
2089 #ifdef HAVE_GTKOSXAPPLICATION
2090     GtkosxApplication   *theApp;
2091 #endif
2092     GString             *comp_info_str = NULL;
2093     GString             *runtime_info_str = NULL;
2094
2095 #ifdef HAVE_GDK_GRESOURCE
2096     main_register_resource();
2097 #endif
2098
2099     cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
2100
2101     /* Set the current locale according to the program environment.
2102      * We haven't localized anything, but some GTK widgets are localized
2103      * (the file selection dialogue, for example).
2104      * This also sets the C-language locale to the native environment. */
2105     setlocale(LC_ALL, "");
2106 #ifdef _WIN32
2107     arg_list_utf_16to8(argc, argv);
2108     create_app_running_mutex();
2109 #endif /* _WIN32 */
2110
2111     /*
2112      * Get credential information for later use, and drop privileges
2113      * before doing anything else.
2114      * Let the user know if anything happened.
2115      */
2116     init_process_policies();
2117     relinquish_special_privs_perm();
2118
2119     /*
2120      * Attempt to get the pathname of the directory containing the
2121      * executable file.
2122      */
2123     init_progfile_dir_error = init_progfile_dir(argv[0], main);
2124
2125     /* initialize the funnel mini-api */
2126     initialize_funnel_ops();
2127
2128     AirPDcapInitContext(&airpdcap_ctx);
2129
2130 #ifdef _WIN32
2131     /* Load wpcap if possible. Do this before collecting the run-time version information */
2132     load_wpcap();
2133
2134     /* ... and also load the packet.dll from wpcap */
2135     wpcap_packet_load();
2136
2137 #ifdef HAVE_AIRPCAP
2138     /* Load the airpcap.dll.  This must also be done before collecting
2139      * run-time version information. */
2140     airpcap_dll_ret_val = load_airpcap();
2141
2142     switch (airpcap_dll_ret_val) {
2143         case AIRPCAP_DLL_OK:
2144             /* load the airpcap interfaces */
2145             g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2146
2147             if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
2148                 if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2149                     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2150                     g_free(err_str);
2151                 }
2152             airpcap_if_active = NULL;
2153
2154             } else {
2155
2156                 /* select the first ad default (THIS SHOULD BE CHANGED) */
2157                 airpcap_if_active = airpcap_get_default_if(g_airpcap_if_list);
2158             }
2159         break;
2160 #if 0
2161         /*
2162          * XXX - Maybe we need to warn the user if one of the following happens???
2163          */
2164         case AIRPCAP_DLL_OLD:
2165             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2166         break;
2167
2168         case AIRPCAP_DLL_ERROR:
2169             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2170         break;
2171
2172         case AIRPCAP_DLL_NOT_FOUND:
2173             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2174         break;
2175 #endif
2176     }
2177 #endif /* HAVE_AIRPCAP */
2178 #endif  /* _WIN32 */
2179
2180     /* Get the compile-time version information string */
2181     comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
2182                                               get_gui_compiled_info);
2183
2184     /* Get the run-time version information string */
2185     runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
2186
2187     /* Add it to the information to be reported on a crash. */
2188     ws_add_crash_info("Wireshark %s\n"
2189         "\n"
2190         "%s"
2191         "\n"
2192         "%s",
2193         get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
2194
2195 #ifdef _WIN32
2196     /* Start windows sockets */
2197     WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2198 #endif  /* _WIN32 */
2199
2200     profile_store_persconffiles (TRUE);
2201
2202     /* Read the profile independent recent file.  We have to do this here so we can */
2203     /* set the profile before it can be set from the command line parameter */
2204     recent_read_static(&rf_path, &rf_open_errno);
2205     if (rf_path != NULL && rf_open_errno != 0) {
2206         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2207                       "Could not open common recent file\n\"%s\": %s.",
2208                       rf_path, g_strerror(rf_open_errno));
2209     }
2210
2211     commandline_early_options(argc, argv, comp_info_str, runtime_info_str);
2212
2213     /* Init the "Open file" dialog directory */
2214     /* (do this after the path settings are processed) */
2215
2216     /* Read the profile dependent (static part) of the recent file. */
2217     /* Only the static part of it will be read, as we don't have the gui now to fill the */
2218     /* recent lists which is done in the dynamic part. */
2219     /* We have to do this already here, so command line parameters can overwrite these values. */
2220     if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
2221         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2222                       "Could not open recent file\n\"%s\": %s.",
2223                       rf_path, g_strerror(rf_open_errno));
2224         g_free(rf_path);
2225     }
2226
2227     if (recent.gui_fileopen_remembered_dir &&
2228         test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2229         set_last_open_dir(recent.gui_fileopen_remembered_dir);
2230     } else {
2231         set_last_open_dir(get_persdatafile_dir());
2232     }
2233
2234 #if !GLIB_CHECK_VERSION(2,31,0)
2235     g_thread_init(NULL);
2236 #endif
2237
2238     /* Disable liboverlay scrollbar which broke Wireshark on Ubuntu */
2239 #if !GTK_CHECK_VERSION(3,16,0)
2240     if (NULL == g_getenv("LIBOVERLAY_SCROLLBAR")) {
2241         g_setenv("LIBOVERLAY_SCROLLBAR", "0", FALSE);
2242     }
2243 #endif
2244
2245     /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2246     gtk_init (&argc, &argv);
2247
2248     cf_callback_add(main_cf_callback, NULL);
2249 #ifdef HAVE_LIBPCAP
2250     capture_callback_add(main_capture_callback, NULL);
2251 #endif
2252
2253     cf_callback_add(statusbar_cf_callback, NULL);
2254 #ifdef HAVE_LIBPCAP
2255     capture_callback_add(statusbar_capture_callback, NULL);
2256 #endif
2257
2258     cf_callback_add(welcome_cf_callback, NULL);
2259 #ifdef HAVE_LIBPCAP
2260     capture_callback_add(welcome_capture_callback, NULL);
2261 #endif
2262
2263     set_console_log_handler();
2264
2265 #ifdef HAVE_LIBPCAP
2266     /* Set the initial values in the capture options. This might be overwritten
2267        by preference settings and then again by the command line parameters. */
2268     capture_opts_init(&global_capture_opts);
2269
2270     capture_session_init(&global_capture_session, &cfile);
2271 #endif
2272
2273     init_report_err(vfailure_alert_box, open_failure_alert_box,
2274                     read_failure_alert_box, write_failure_alert_box);
2275
2276     /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2277     filter = get_conn_cfilter();
2278     if ( *filter != '\0' ) {
2279         info_update_freq = 1000;  /* Milliseconds */
2280     }
2281
2282     /* We won't come till here, if we had a "console only" command line parameter. */
2283     splash_win = splash_new("Loading Wireshark ...");
2284     if (init_progfile_dir_error != NULL) {
2285         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2286                       "Can't get pathname of directory containing Wireshark: %s.\n"
2287                       "It won't be possible to capture traffic.\n"
2288                       "Report this to the Wireshark developers.",
2289                       init_progfile_dir_error);
2290         g_free(init_progfile_dir_error);
2291     }
2292
2293     wtap_init();
2294
2295 #ifdef HAVE_PLUGINS
2296     /* Register all the plugin types we have. */
2297     epan_register_plugin_types(); /* Types known to libwireshark */
2298     codec_register_plugin_types(); /* Types known to libwscodecs */
2299
2300     /* Scan for plugins.  This does *not* call their registration routines;
2301        that's done later. */
2302     scan_plugins(REPORT_LOAD_FAILURE);
2303
2304     /* Register all libwiretap plugin modules. */
2305     register_all_wiretap_modules();
2306 #endif
2307
2308     /* Register all audio codec plugins. */
2309     register_all_codecs();
2310
2311     splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2312
2313     /* Register all dissectors; we must do this before checking for the
2314        "-G" flag, as the "-G" flag dumps information registered by the
2315        dissectors, and we must do it before we read the preferences, in
2316        case any dissectors register preferences. */
2317     if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
2318                    splash_update, (gpointer) splash_win))
2319       return 2;
2320
2321     splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2322
2323     /* Register all tap listeners; we do this before we parse the arguments,
2324        as the "-z" argument can specify a registered tap. */
2325
2326     /* we register the plugin taps before the other taps because
2327        stats_tree taps plugins will be registered as tap listeners
2328        by stats_tree_stat.c and need to registered before that */
2329
2330 #ifdef HAVE_PLUGINS
2331     register_all_plugin_tap_listeners();
2332 #endif
2333
2334     register_all_tap_listeners();
2335     conversation_table_set_gui_info(init_conversation_table);
2336     hostlist_table_set_gui_info(init_hostlist_table);
2337     srt_table_iterate_tables(register_service_response_tables, NULL);
2338     rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
2339     new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
2340
2341 #ifdef HAVE_EXTCAP
2342     splash_update(RA_EXTCAP, NULL, (gpointer)splash_win);
2343     extcap_register_preferences();
2344 #endif
2345
2346     splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2347
2348     global_commandline_info.prefs_p = read_configuration_files (&gdp_path, &dp_path);
2349     /* Removed thread code:
2350      * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2351      */
2352
2353     splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2354     cap_file_init(&cfile);
2355
2356     /* Fill in capture options with values from the preferences */
2357     prefs_to_capture_opts();
2358
2359 /*#ifdef HAVE_LIBPCAP
2360     fill_in_local_interfaces();
2361 #endif*/
2362
2363     /* Now get our args */
2364     commandline_other_options(argc, argv, TRUE);
2365
2366 #ifdef HAVE_LIBPCAP
2367     splash_update(RA_INTERFACES, NULL, (gpointer)splash_win);
2368
2369     fill_in_local_interfaces(main_window_update);
2370
2371     if (global_commandline_info.start_capture || global_commandline_info.list_link_layer_types) {
2372         /* We're supposed to do a live capture or get a list of link-layer
2373            types for a live capture device; if the user didn't specify an
2374            interface to use, pick a default. */
2375         status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2376         ((global_commandline_info.prefs_p->capture_device) && (*global_commandline_info.prefs_p->capture_device != '\0')) ? get_if_name(global_commandline_info.prefs_p->capture_device) : NULL);
2377         if (status != 0) {
2378             exit(status);
2379         }
2380     }
2381
2382     if (global_commandline_info.list_link_layer_types) {
2383         /* Get the list of link-layer types for the capture devices. */
2384         if_capabilities_t *caps;
2385         guint i;
2386         interface_t device;
2387         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2388
2389             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2390             if (device.selected) {
2391                 gchar* auth_str = NULL;
2392 #ifdef HAVE_PCAP_REMOTE
2393                 if (device.remote_opts.remote_host_opts.auth_type == CAPTURE_AUTH_PWD) {
2394                     auth_str = g_strdup_printf("%s:%s", device.remote_opts.remote_host_opts.auth_username,
2395                                                device.remote_opts.remote_host_opts.auth_password);
2396                 }
2397 #endif
2398 #if defined(HAVE_PCAP_CREATE)
2399                 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, auth_str, &err_str, main_window_update);
2400 #else
2401                 caps = capture_get_if_capabilities(device.name, FALSE, auth_str, &err_str,main_window_update);
2402 #endif
2403                 g_free(auth_str);
2404                 if (caps == NULL) {
2405                     cmdarg_err("%s", err_str);
2406                     g_free(err_str);
2407                     exit(2);
2408                 }
2409                 if (caps->data_link_types == NULL) {
2410                     cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2411                     exit(2);
2412                 }
2413 #ifdef _WIN32
2414                 create_console();
2415 #endif /* _WIN32 */
2416 #if defined(HAVE_PCAP_CREATE)
2417                 capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2418 #else
2419                 capture_opts_print_if_capabilities(caps, device.name, FALSE);
2420 #endif
2421 #ifdef _WIN32
2422                 destroy_console();
2423 #endif /* _WIN32 */
2424                 free_if_capabilities(caps);
2425             }
2426         }
2427         exit(0);
2428     }
2429     capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2430     capture_opts_trim_ring_num_files(&global_capture_opts);
2431 #endif /* HAVE_LIBPCAP */
2432
2433     /* Notify all registered modules that have had any of their preferences
2434        changed either from one of the preferences file or from the command
2435        line that their preferences have changed. */
2436     prefs_apply_all();
2437
2438 #ifdef HAVE_LIBPCAP
2439     if ((global_capture_opts.num_selected == 0) &&
2440         ((prefs.capture_device != NULL) &&
2441          (global_commandline_info.prefs_p != NULL) &&
2442          (*global_commandline_info.prefs_p->capture_device != '\0'))) {
2443         guint i;
2444         interface_t device;
2445         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2446             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2447             if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2448                 device.selected = TRUE;
2449                 global_capture_opts.num_selected++;
2450                 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2451                 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2452                 break;
2453             }
2454         }
2455     }
2456     if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
2457         interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
2458         device.selected = TRUE;
2459         global_capture_opts.num_selected++;
2460         global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
2461         g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
2462     }
2463 #endif
2464
2465     /* disabled protocols as per configuration file */
2466     if (gdp_path == NULL && dp_path == NULL) {
2467         set_disabled_protos_list();
2468         set_enabled_protos_list();
2469         set_disabled_heur_dissector_list();
2470     }
2471
2472     if(global_dissect_options.disable_protocol_slist) {
2473         GSList *proto_disable;
2474         for (proto_disable = global_dissect_options.disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
2475         {
2476             proto_disable_proto_by_name((char*)proto_disable->data);
2477         }
2478     }
2479
2480     if(global_dissect_options.enable_protocol_slist) {
2481         GSList *proto_enable;
2482         for (proto_enable = global_dissect_options.enable_protocol_slist; proto_enable != NULL; proto_enable = g_slist_next(proto_enable))
2483         {
2484             proto_enable_proto_by_name((char*)proto_enable->data);
2485         }
2486     }
2487
2488     if(global_dissect_options.disable_heur_slist) {
2489         GSList *heur_enable;
2490         for (heur_enable = global_dissect_options.disable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
2491         {
2492             proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
2493         }
2494     }
2495
2496     if(global_dissect_options.disable_heur_slist) {
2497         GSList *heur_disable;
2498         for (heur_disable = global_dissect_options.disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
2499         {
2500             proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
2501         }
2502     }
2503
2504     build_column_format_array(&cfile.cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
2505
2506     /* read in rc file from global and personal configuration paths. */
2507     rc_file = get_datafile_path(RC_FILE);
2508 #if GTK_CHECK_VERSION(3,0,0)
2509     /* XXX resolve later */
2510 #else
2511     gtk_rc_parse(rc_file);
2512     g_free(rc_file);
2513     rc_file = get_persconffile_path(RC_FILE, FALSE);
2514     gtk_rc_parse(rc_file);
2515 #endif
2516     g_free(rc_file);
2517
2518     font_init();
2519
2520     macros_init();
2521
2522     stock_icons_init();
2523
2524     /* close the splash screen, as we are going to open the main window now */
2525     splash_destroy(splash_win);
2526
2527     /************************************************************************/
2528     /* Everything is prepared now, preferences and command line was read in */
2529
2530     /* Pop up the main window. */
2531     create_main_window(pl_size, tv_size, bv_size, global_commandline_info.prefs_p);
2532
2533     /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2534     if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
2535         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2536                       "Could not open recent file\n\"%s\": %s.",
2537                       rf_path, g_strerror(rf_open_errno));
2538         g_free(rf_path);
2539     }
2540
2541     packet_list_enable_color(recent.packet_list_colorize);
2542
2543     /* rearrange all the widgets as we now have all recent settings ready for this */
2544     main_widgets_rearrange();
2545
2546     /* Fill in column titles.  This must be done after the top level window
2547      is displayed.
2548
2549      XXX - is that still true, with fixed-width columns? */
2550
2551     menu_recent_read_finished();
2552 #ifdef HAVE_LIBPCAP
2553     main_auto_scroll_live_changed(auto_scroll_live);
2554 #endif
2555
2556     switch (user_font_apply()) {
2557         case FA_SUCCESS:
2558             break;
2559         case FA_ZOOMED_TOO_FAR:
2560             /* The zoom level is too big for this font; turn off zooming. */
2561             recent.gui_zoom_level = 0;
2562             break;
2563         case FA_FONT_NOT_AVAILABLE:
2564             /* XXX - did we successfully load the un-zoomed version earlier?
2565              If so, this *probably* means the font is available, but not at
2566              this particular zoom level, but perhaps some other failure
2567              occurred; I'm not sure you can determine which is the case,
2568              however. */
2569             /* turn off zooming - zoom level is unavailable */
2570         default:
2571             /* in any other case than FA_SUCCESS, turn off zooming */
2572             recent.gui_zoom_level = 0;
2573             /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2574             break;
2575     }
2576
2577     dnd_init(top_level);
2578
2579     if (!color_filters_init(&err_msg, color_filter_add_cb)) {
2580         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
2581         g_free(err_msg);
2582     }
2583 #ifdef HAVE_LIBPCAP
2584     capture_filter_init();
2585 #endif
2586
2587     /* the window can be sized only, if it's not already shown, so do it now! */
2588     main_load_window_geometry(top_level);
2589
2590     g_timeout_add(info_update_freq, resolv_update_cb, NULL);
2591
2592     /* this is to keep tap extensions updating once every 3 seconds */
2593     tap_update_timer_id = g_timeout_add(global_commandline_info.prefs_p->tap_update_interval, tap_update_cb, NULL);
2594
2595     /* If we were given the name of a capture file, read it in now;
2596      we defer it until now, so that, if we can't open it, and pop
2597      up an alert box, the alert box is more likely to come up on
2598      top of the main window - but before the preference-file-error
2599      alert box, so, if we get one of those, it's more likely to come
2600      up on top of us. */
2601     if (global_commandline_info.cf_name) {
2602         show_main_window(TRUE);
2603         check_and_warn_user_startup(global_commandline_info.cf_name);
2604         if (global_commandline_info.rfilter != NULL) {
2605             if (!dfilter_compile(global_commandline_info.rfilter, &rfcode, &err_msg)) {
2606                 bad_dfilter_alert_box(top_level, global_commandline_info.rfilter, err_msg);
2607                 g_free(err_msg);
2608                 rfilter_parse_failed = TRUE;
2609             }
2610         }
2611         if (ex_opt_count("read_format") > 0) {
2612             in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
2613         }
2614         if (!rfilter_parse_failed) {
2615             if (cf_open(&cfile, global_commandline_info.cf_name, in_file_type, FALSE, &err) == CF_OK) {
2616                 /* "cf_open()" succeeded, so it closed the previous
2617                  capture file, and thus destroyed any previous read filter
2618                  attached to "cf". */
2619
2620                 cfile.rfcode = rfcode;
2621                 /* Open stat windows; we do so after creating the main window,
2622                    to avoid GTK warnings, and after successfully opening the
2623                    capture file, so we know we have something to compute stats
2624                    on, and after registering all dissectors, so that MATE will
2625                    have registered its field array and we can have a tap filter
2626                    with one of MATE's late-registered fields as part of the
2627                    filter. */
2628                 start_requested_stats();
2629
2630                 /* Read the capture file. */
2631                 switch (cf_read(&cfile, FALSE)) {
2632
2633                     case CF_READ_OK:
2634                     case CF_READ_ERROR:
2635                         /* Just because we got an error, that doesn't mean we were unable
2636                            to read any of the file; we handle what we could get from the
2637                            file. */
2638                         /* if the user told us to jump to a specific packet, do it now */
2639                         if(global_commandline_info.go_to_packet != 0) {
2640                             /* Jump to the specified frame number, kept for backward
2641                                compatibility. */
2642                             cf_goto_frame(&cfile, global_commandline_info.go_to_packet);
2643                         } else if (global_commandline_info.jfilter != NULL) {
2644                             /* try to compile given filter */
2645                             if (!dfilter_compile(global_commandline_info.jfilter, &jump_to_filter, &err_msg)) {
2646                                 bad_dfilter_alert_box(top_level, global_commandline_info.jfilter, err_msg);
2647                                 g_free(err_msg);
2648                             } else {
2649                             /* Filter ok, jump to the first packet matching the filter
2650                                conditions. Default search direction is forward, but if
2651                                option d was given, search backwards */
2652                             cf_find_packet_dfilter(&cfile, jump_to_filter, global_commandline_info.jump_backwards);
2653                             }
2654                         }
2655                         break;
2656
2657                     case CF_READ_ABORTED:
2658                         /* Exit now. */
2659                         exit(0);
2660                         break;
2661                 }
2662
2663                 /* If the filename is not the absolute path, prepend the current dir. This happens
2664                    when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
2665                 if (!g_path_is_absolute(global_commandline_info.cf_name)) {
2666                     char *old_cf_name = global_commandline_info.cf_name;
2667                     char *pwd = g_get_current_dir();
2668                     global_commandline_info.cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, global_commandline_info.cf_name);
2669                     g_free(old_cf_name);
2670                     g_free(pwd);
2671                 }
2672
2673                 /* Save the name of the containing directory specified in the
2674                    path name, if any; we can write over cf_name, which is a
2675                    good thing, given that "get_dirname()" does write over its
2676                    argument. */
2677                 s = get_dirname(global_commandline_info.cf_name);
2678                 set_last_open_dir(s);
2679                 g_free(global_commandline_info.cf_name);
2680                 global_commandline_info.cf_name = NULL;
2681             } else {
2682                 if (rfcode != NULL)
2683                     dfilter_free(rfcode);
2684                 cfile.rfcode = NULL;
2685                 show_main_window(FALSE);
2686                 /* Don't call check_and_warn_user_startup(): we did it above */
2687                 main_set_for_capture_in_progress(FALSE);
2688                 set_capture_if_dialog_for_capture_in_progress(FALSE);
2689             }
2690         }
2691     } else {
2692 #ifdef HAVE_LIBPCAP
2693         if (global_commandline_info.start_capture) {
2694             if (global_capture_opts.save_file != NULL) {
2695                 /* Save the directory name for future file dialogs. */
2696                 /* (get_dirname overwrites filename) */
2697                 s = g_strdup(global_capture_opts.save_file);
2698                 set_last_open_dir(get_dirname(s));
2699                 g_free(s);
2700             }
2701             /* "-k" was specified; start a capture. */
2702             show_main_window(FALSE);
2703             check_and_warn_user_startup(global_commandline_info.cf_name);
2704
2705             /* If no user interfaces were specified on the command line,
2706                copy the list of selected interfaces to the set of interfaces
2707                to use for this capture. */
2708             if (global_capture_opts.ifaces->len == 0)
2709                 collect_ifaces(&global_capture_opts);
2710             if (capture_start(&global_capture_opts, &global_capture_session, &global_info_data,main_window_update)) {
2711                 /* The capture started.  Open stat windows; we do so after creating
2712                    the main window, to avoid GTK warnings, and after successfully
2713                    opening the capture file, so we know we have something to compute
2714                    stats on, and after registering all dissectors, so that MATE will
2715                    have registered its field array and we can have a tap filter with
2716                    one of MATE's late-registered fields as part of the filter. */
2717                 start_requested_stats();
2718             }
2719         } else {
2720             show_main_window(FALSE);
2721             check_and_warn_user_startup(global_commandline_info.cf_name);
2722             main_set_for_capture_in_progress(FALSE);
2723             set_capture_if_dialog_for_capture_in_progress(FALSE);
2724         }
2725     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
2726         if (!global_commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
2727             global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
2728         }
2729 #else /* HAVE_LIBPCAP */
2730         show_main_window(FALSE);
2731         check_and_warn_user_startup(global_commandline_info.cf_name);
2732         main_set_for_capture_in_progress(FALSE);
2733         set_capture_if_dialog_for_capture_in_progress(FALSE);
2734 #endif /* HAVE_LIBPCAP */
2735     }
2736
2737     if (global_commandline_info.dfilter) {
2738         GtkWidget *filter_te;
2739         filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
2740         gtk_entry_set_text(GTK_ENTRY(filter_te), global_commandline_info.dfilter);
2741
2742         /* Run the display filter so it goes in effect. */
2743         main_filter_packets(&cfile, global_commandline_info.dfilter, FALSE);
2744     }
2745
2746     profile_store_persconffiles (FALSE);
2747
2748 #ifdef HAVE_GTKOSXAPPLICATION
2749     theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
2750 #ifdef HAVE_GDK_GRESOURCE
2751     gtkosx_application_set_dock_icon_pixbuf(theApp, ws_gdk_pixbuf_new_from_resource("/org/wireshark/image/wsicon64.png"));
2752 #else
2753     gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
2754 #endif
2755     gtkosx_application_ready(theApp);
2756 #endif
2757
2758     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
2759
2760 #ifdef HAVE_LIBPCAP
2761     gtk_iface_mon_start();
2762 #endif
2763
2764     software_update_init();
2765
2766     /* we'll enter the GTK loop now and hand the control over to GTK ... */
2767     gtk_main();
2768     /* ... back from GTK, we're going down now! */
2769
2770 #ifdef HAVE_LIBPCAP
2771     gtk_iface_mon_stop();
2772 #endif
2773
2774     epan_cleanup();
2775
2776 #ifdef HAVE_EXTCAP
2777     extcap_cleanup();
2778 #endif
2779
2780     AirPDcapDestroyContext(&airpdcap_ctx);
2781
2782 #ifdef HAVE_GTKOSXAPPLICATION
2783     g_object_unref(theApp);
2784 #endif
2785
2786 #ifdef _WIN32
2787     /* hide the (unresponsive) main window, while asking the user to close the console window */
2788     if (G_IS_OBJECT(top_level))
2789         gtk_widget_hide(top_level);
2790
2791     software_update_cleanup();
2792
2793     /* Shutdown windows sockets */
2794     WSACleanup();
2795
2796     /* For some unknown reason, the "atexit()" call in "create_console()"
2797        doesn't arrange that "destroy_console()" be called when we exit,
2798        so we call it here if a console was created. */
2799     destroy_console();
2800 #endif
2801
2802 #ifdef HAVE_GDK_GRESOURCE
2803     main_unregister_resource();
2804 #endif
2805
2806     exit(0);
2807 }
2808
2809 #ifdef _WIN32
2810
2811 /* We build this as a GUI subsystem application on Win32, so
2812    "WinMain()", not "main()", gets called.
2813
2814    Hack shamelessly stolen from the Win32 port of the GIMP. */
2815 #ifdef __GNUC__
2816 #define _stdcall  __attribute__((stdcall))
2817 #endif
2818
2819 int _stdcall
2820 WinMain (struct HINSTANCE__ *hInstance,
2821          struct HINSTANCE__ *hPrevInstance,
2822          char               *lpszCmdLine,
2823          int                 nCmdShow)
2824 {
2825     INITCOMMONCONTROLSEX comm_ctrl;
2826
2827     /*
2828      * Initialize our DLL search path. MUST be called before LoadLibrary
2829      * or g_module_open.
2830      */
2831     ws_init_dll_search_path();
2832
2833     /* Initialize our controls. Required for native Windows file dialogs. */
2834     memset (&comm_ctrl, 0, sizeof(comm_ctrl));
2835     comm_ctrl.dwSize = sizeof(comm_ctrl);
2836     /* Includes the animate, header, hot key, list view, progress bar,
2837      * status bar, tab, tooltip, toolbar, trackbar, tree view, and
2838      * up-down controls
2839      */
2840     comm_ctrl.dwICC = ICC_WIN95_CLASSES;
2841     InitCommonControlsEx(&comm_ctrl);
2842
2843     /* RichEd20.DLL is needed for native file dialog filter entries. */
2844     ws_load_library("riched20.dll");
2845
2846     set_has_console(FALSE);
2847     set_console_wait(FALSE);
2848     return main (__argc, __argv);
2849 }
2850
2851 #endif /* _WIN32 */
2852
2853
2854
2855
2856 /*
2857  * Helper for main_widgets_rearrange()
2858  */
2859 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
2860     gtk_container_remove(GTK_CONTAINER(data), widget);
2861 }
2862
2863 static GtkWidget *main_widget_layout(gint layout_content)
2864 {
2865     switch(layout_content) {
2866     case(layout_pane_content_none):
2867         return NULL;
2868     case(layout_pane_content_plist):
2869         return pkt_scrollw;
2870     case(layout_pane_content_pdetails):
2871         return tv_scrollw;
2872     case(layout_pane_content_pbytes):
2873         return byte_nb_ptr_gbl;
2874     default:
2875         g_assert_not_reached();
2876         return NULL;
2877     }
2878 }
2879
2880 /*
2881  * Rearrange the main window widgets
2882  */
2883 void main_widgets_rearrange(void) {
2884     GtkWidget *first_pane_widget1, *first_pane_widget2;
2885     GtkWidget *second_pane_widget1, *second_pane_widget2;
2886     gboolean split_top_left = FALSE;
2887
2888     /* be a bit faster */
2889     gtk_widget_hide(main_vbox);
2890
2891     /* be sure we don't lose a widget while rearranging */
2892     g_object_ref(G_OBJECT(menubar));
2893     g_object_ref(G_OBJECT(main_tb));
2894     g_object_ref(G_OBJECT(filter_tb));
2895     g_object_ref(G_OBJECT(wireless_tb));
2896     g_object_ref(G_OBJECT(pkt_scrollw));
2897     g_object_ref(G_OBJECT(tv_scrollw));
2898     g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
2899     g_object_ref(G_OBJECT(statusbar));
2900     g_object_ref(G_OBJECT(main_pane_v1));
2901     g_object_ref(G_OBJECT(main_pane_v2));
2902     g_object_ref(G_OBJECT(main_pane_h1));
2903     g_object_ref(G_OBJECT(main_pane_h2));
2904     g_object_ref(G_OBJECT(welcome_pane));
2905
2906     /* empty all containers participating */
2907     gtk_container_foreach(GTK_CONTAINER(main_vbox),     foreach_remove_a_child, main_vbox);
2908     gtk_container_foreach(GTK_CONTAINER(main_pane_v1),  foreach_remove_a_child, main_pane_v1);
2909     gtk_container_foreach(GTK_CONTAINER(main_pane_v2),  foreach_remove_a_child, main_pane_v2);
2910     gtk_container_foreach(GTK_CONTAINER(main_pane_h1),  foreach_remove_a_child, main_pane_h1);
2911     gtk_container_foreach(GTK_CONTAINER(main_pane_h2),  foreach_remove_a_child, main_pane_h2);
2912
2913     statusbar_widgets_emptying(statusbar);
2914
2915     /* add the menubar always at the top */
2916     gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
2917
2918     /* main toolbar */
2919     gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
2920
2921     /* filter toolbar in toolbar area */
2922     if (!prefs.filter_toolbar_show_in_statusbar) {
2923         gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
2924     }
2925
2926     /* airpcap toolbar */
2927     gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
2928
2929     /* fill the main layout panes */
2930     switch(prefs.gui_layout_type) {
2931     case(layout_type_5):
2932         main_first_pane  = main_pane_v1;
2933         main_second_pane = main_pane_v2;
2934         split_top_left = FALSE;
2935         break;
2936     case(layout_type_2):
2937         main_first_pane  = main_pane_v1;
2938         main_second_pane = main_pane_h1;
2939         split_top_left = FALSE;
2940         break;
2941     case(layout_type_1):
2942         main_first_pane  = main_pane_v1;
2943         main_second_pane = main_pane_h1;
2944         split_top_left = TRUE;
2945         break;
2946     case(layout_type_4):
2947         main_first_pane  = main_pane_h1;
2948         main_second_pane = main_pane_v1;
2949         split_top_left = FALSE;
2950         break;
2951     case(layout_type_3):
2952         main_first_pane  = main_pane_h1;
2953         main_second_pane = main_pane_v1;
2954         split_top_left = TRUE;
2955         break;
2956     case(layout_type_6):
2957         main_first_pane  = main_pane_h1;
2958         main_second_pane = main_pane_h2;
2959         split_top_left = FALSE;
2960         break;
2961     default:
2962         main_first_pane = NULL;
2963         main_second_pane = NULL;
2964         g_assert_not_reached();
2965     }
2966     if (split_top_left) {
2967         first_pane_widget1 = main_second_pane;
2968         second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2969         second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
2970         first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2971     } else {
2972         first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
2973         first_pane_widget2 = main_second_pane;
2974         second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
2975         second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
2976     }
2977     if (first_pane_widget1 != NULL)
2978         gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
2979     if (first_pane_widget2 != NULL)
2980         gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
2981     if (second_pane_widget1 != NULL)
2982         gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
2983     if (second_pane_widget2 != NULL)
2984         gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
2985
2986     gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
2987
2988     /* welcome pane */
2989     gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
2990
2991     /* statusbar */
2992     gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
2993
2994     /* filter toolbar in statusbar hbox */
2995     if (prefs.filter_toolbar_show_in_statusbar) {
2996         gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
2997     }
2998
2999     /* statusbar widgets */
3000     statusbar_widgets_pack(statusbar);
3001
3002     /* hide widgets on users recent settings */
3003     main_widgets_show_or_hide();
3004
3005     gtk_widget_show(main_vbox);
3006 }
3007
3008 static void
3009 is_widget_visible(GtkWidget *widget, gpointer data)
3010 {
3011     gboolean *is_visible = ( gboolean *)data;
3012
3013     if (!*is_visible) {
3014         if (gtk_widget_get_visible(widget))
3015             *is_visible = TRUE;
3016     }
3017 }
3018
3019
3020 void
3021 main_widgets_show_or_hide(void)
3022 {
3023     gboolean main_second_pane_show;
3024
3025     if (recent.main_toolbar_show) {
3026         gtk_widget_show(main_tb);
3027     } else {
3028         gtk_widget_hide(main_tb);
3029     }
3030
3031     statusbar_widgets_show_or_hide(statusbar);
3032
3033     if (recent.filter_toolbar_show) {
3034         gtk_widget_show(filter_tb);
3035     } else {
3036         gtk_widget_hide(filter_tb);
3037     }
3038
3039     if (recent.wireless_toolbar_show) {
3040         gtk_widget_show(wireless_tb);
3041     } else {
3042         gtk_widget_hide(wireless_tb);
3043     }
3044
3045     if (recent.packet_list_show && have_capture_file) {
3046         gtk_widget_show(pkt_scrollw);
3047     } else {
3048         gtk_widget_hide(pkt_scrollw);
3049     }
3050
3051     if (recent.tree_view_show && have_capture_file) {
3052         gtk_widget_show(tv_scrollw);
3053     } else {
3054         gtk_widget_hide(tv_scrollw);
3055     }
3056
3057     if (recent.byte_view_show && have_capture_file) {
3058         gtk_widget_show(byte_nb_ptr_gbl);
3059     } else {
3060         gtk_widget_hide(byte_nb_ptr_gbl);
3061     }
3062
3063     if (have_capture_file) {
3064         gtk_widget_show(main_first_pane);
3065     } else {
3066         gtk_widget_hide(main_first_pane);
3067     }
3068
3069     /*
3070      * Is anything in "main_second_pane" visible?
3071      * If so, show it, otherwise hide it.
3072      */
3073     main_second_pane_show = FALSE;
3074     gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3075                           &main_second_pane_show);
3076     if (main_second_pane_show) {
3077         gtk_widget_show(main_second_pane);
3078     } else {
3079         gtk_widget_hide(main_second_pane);
3080     }
3081
3082     if (!have_capture_file) {
3083         if(welcome_pane) {
3084             gtk_widget_show(welcome_pane);
3085         }
3086     } else {
3087         gtk_widget_hide(welcome_pane);
3088     }
3089 }
3090
3091
3092 /* called, when the window state changes (minimized, maximized, ...) */
3093 static gboolean
3094 window_state_event_cb (GtkWidget *widget _U_,
3095                        GdkEvent *event,
3096                        gpointer  data _U_)
3097 {
3098     GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3099
3100     if( (event->type) == (GDK_WINDOW_STATE)) {
3101         if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3102             /* we might have dialogs popped up while we where iconified,
3103                show em now */
3104             display_queued_messages();
3105         }
3106     }
3107     return FALSE;
3108 }
3109
3110
3111
3112 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3113 static gboolean
3114 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3115 {
3116     if (event->keyval == GDK_F8) {
3117         packet_list_next();
3118         return TRUE;
3119     } else if (event->keyval == GDK_F7) {
3120         packet_list_prev();
3121         return TRUE;
3122     } else if (event->state & NO_SHIFT_MOD_MASK) {
3123         return FALSE; /* Skip control, alt, and other modifiers */
3124     /*
3125      * A comment in gdkkeysyms.h says that it's autogenerated from
3126      * freedesktop.org/x.org's keysymdef.h.  Although the GDK docs
3127      * don't explicitly say so, g_ascii_isprint() should work as expected
3128      * for values < 127.
3129      */
3130     } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3131         /* Forward the keypress on to the display filter entry */
3132         if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3133             gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3134             gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3135         }
3136         return FALSE;
3137     }
3138     return FALSE;
3139 }
3140
3141 static void
3142 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3143 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3144                     _U_
3145 #endif
3146                     )
3147 {
3148     GtkAccelGroup *accel;
3149
3150     /* Main window */
3151     top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3152     set_titlebar_for_capture_file(NULL);
3153
3154     gtk_widget_set_name(top_level, "main window");
3155     g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3156                    NULL);
3157     g_signal_connect(G_OBJECT(top_level), "window_state_event",
3158                          G_CALLBACK(window_state_event_cb), NULL);
3159     g_signal_connect(G_OBJECT(top_level), "key-press-event",
3160                          G_CALLBACK(top_level_key_pressed_cb), NULL );
3161
3162     /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3163     main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3164
3165     gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3166     gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3167     gtk_widget_show(main_vbox);
3168
3169     /* Menu bar */
3170     menubar = main_menu_new(&accel);
3171
3172 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3173     /* Mac OS X native menus are created and displayed by main_menu_new() */
3174     if(!prefs_p->gui_macosx_style) {
3175 #endif
3176     gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3177     gtk_widget_show(menubar);
3178 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3179     } else {
3180     gtk_widget_hide(menubar);
3181     }
3182 #endif
3183
3184     /* Main Toolbar */
3185     main_tb = toolbar_new();
3186     gtk_widget_show (main_tb);
3187
3188     /* Filter toolbar */
3189     filter_tb = filter_toolbar_new();
3190
3191     /* Packet list */
3192     pkt_scrollw = packet_list_create();
3193     gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3194     gtk_widget_show_all(pkt_scrollw);
3195
3196     /* Tree view */
3197     tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3198     gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3199     gtk_widget_show(tv_scrollw);
3200
3201     g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3202                    "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3203     g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3204                    g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3205     gtk_widget_show(tree_view_gbl);
3206
3207     /* Byte view. */
3208     byte_nb_ptr_gbl = byte_view_new();
3209     gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3210     gtk_widget_show(byte_nb_ptr_gbl);
3211
3212     g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3213                    g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3214
3215     /* Panes for the packet list, tree, and byte view */
3216     main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3217     gtk_widget_show(main_pane_v1);
3218     main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3219     gtk_widget_show(main_pane_v2);
3220     main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3221     gtk_widget_show(main_pane_h1);
3222     main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3223     gtk_widget_show(main_pane_h2);
3224 #ifdef HAVE_AIRPCAP
3225     wireless_tb = airpcap_toolbar_new();
3226 #else
3227     wireless_tb = ws80211_toolbar_new();
3228 #endif
3229     gtk_widget_show(wireless_tb);
3230
3231     /* status bar */
3232     statusbar = statusbar_new();
3233     gtk_widget_show(statusbar);
3234
3235     /* Pane for the welcome screen */
3236     welcome_pane = welcome_new();
3237     gtk_widget_show(welcome_pane);
3238 }
3239
3240 static void
3241 show_main_window(gboolean doing_work)
3242 {
3243     main_set_for_capture_file(doing_work);
3244
3245     /*** we have finished all init things, show the main window ***/
3246     gtk_widget_show(top_level);
3247
3248     /* the window can be maximized only, if it's visible, so do it after show! */
3249     main_load_window_geometry(top_level);
3250
3251     /* process all pending GUI events before continue */
3252     while (gtk_events_pending()) gtk_main_iteration();
3253
3254     /* Pop up any queued-up alert boxes. */
3255     display_queued_messages();
3256
3257     /* Move the main window to the front, in case it isn't already there */
3258     gdk_window_raise(gtk_widget_get_window(top_level));
3259
3260 #ifdef HAVE_AIRPCAP
3261     airpcap_toolbar_show(wireless_tb);
3262 #endif /* HAVE_AIRPCAP */
3263 }
3264
3265 static void copy_global_profile (const gchar *profile_name)
3266 {
3267     char  *pf_dir_path, *pf_dir_path2, *pf_filename;
3268
3269     if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3270         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3271             "Can't create directory\n\"%s\":\n%s.",
3272             pf_dir_path, g_strerror(errno));
3273
3274         g_free(pf_dir_path);
3275     }
3276
3277     if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3278             &pf_dir_path, &pf_dir_path2) == -1) {
3279         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3280             "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3281             pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3282
3283         g_free(pf_filename);
3284         g_free(pf_dir_path);
3285         g_free(pf_dir_path2);
3286     }
3287 }
3288
3289 /* Change configuration profile */
3290 void change_configuration_profile (const gchar *profile_name)
3291 {
3292     char  *gdp_path, *dp_path;
3293     char  *rf_path;
3294     int    rf_open_errno;
3295     gchar* err_msg = NULL;
3296
3297     /* First check if profile exists */
3298     if (!profile_exists(profile_name, FALSE)) {
3299         if (profile_exists(profile_name, TRUE)) {
3300            /* Copy from global profile */
3301             copy_global_profile (profile_name);
3302         } else {
3303             /* No personal and no global profile exists */
3304             return;
3305         }
3306     }
3307
3308     /* Then check if changing to another profile */
3309     if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3310         return;
3311     }
3312
3313     /* Get the current geometry, before writing it to disk */
3314     main_save_window_geometry(top_level);
3315
3316     if (profile_exists(get_profile_name(), FALSE)) {
3317         /* Write recent file for profile we are leaving, if it still exists */
3318         write_profile_recent();
3319     }
3320
3321     /* Set profile name and update the status bar */
3322     set_profile_name (profile_name);
3323     profile_bar_update ();
3324
3325     /* Reset current preferences and apply the new */
3326     prefs_reset();
3327     menu_prefs_reset();
3328
3329     (void) read_configuration_files (&gdp_path, &dp_path);
3330
3331     if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
3332         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3333             "Could not open common recent file\n\"%s\": %s.",
3334             rf_path, g_strerror(rf_open_errno));
3335         g_free(rf_path);
3336     }
3337     if (recent.gui_fileopen_remembered_dir &&
3338         test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3339         set_last_open_dir(recent.gui_fileopen_remembered_dir);
3340     }
3341     timestamp_set_type (recent.gui_time_format);
3342     timestamp_set_seconds_type (recent.gui_seconds_format);
3343     packet_list_enable_color(recent.packet_list_colorize);
3344
3345     prefs_to_capture_opts();
3346     prefs_apply_all();
3347 #ifdef HAVE_LIBPCAP
3348     update_local_interfaces();
3349 #endif
3350     macros_post_update();
3351
3352     /* Update window view and redraw the toolbar */
3353     main_titlebar_update();
3354     filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3355     toolbar_redraw_all();
3356
3357     /* Enable all protocols and disable from the disabled list */
3358     proto_enable_all();
3359     if (gdp_path == NULL && dp_path == NULL) {
3360         set_disabled_protos_list();
3361         set_enabled_protos_list();
3362         set_disabled_heur_dissector_list();
3363     }
3364
3365     /* Reload color filters */
3366     if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
3367         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
3368         g_free(err_msg);
3369     }
3370
3371     /* Reload list of interfaces on welcome page */
3372     welcome_if_panel_reload();
3373
3374     /* Recreate the packet list according to new preferences */
3375     packet_list_recreate ();
3376     cfile.columns_changed = FALSE; /* Reset value */
3377     user_font_apply();
3378
3379     /* Update menus with new recent values */
3380     menu_recent_read_finished();
3381
3382     /* Reload pane geometry, must be done after recreating the list */
3383     main_pane_load_window_geometry();
3384 }
3385
3386 void
3387 main_fields_changed (void)
3388 {
3389     gchar* err_msg = NULL;
3390
3391     /* Reload color filters */
3392     if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
3393         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
3394         g_free(err_msg);
3395     }
3396
3397     /* Syntax check filter */
3398     filter_te_syntax_check_cb(main_display_filter_widget, NULL);
3399     if (cfile.dfilter) {
3400         /* Check if filter is still valid */
3401         dfilter_t *dfp = NULL;
3402         if (!dfilter_compile(cfile.dfilter, &dfp, NULL)) {
3403             /* Not valid.  Enable 'Apply' button and remove dfilter. */
3404             g_signal_emit_by_name(G_OBJECT(main_display_filter_widget), "changed");
3405             g_free(cfile.dfilter);
3406             cfile.dfilter = NULL;
3407         }
3408         dfilter_free(dfp);
3409     }
3410
3411     if (have_custom_cols(&cfile.cinfo)) {
3412         /* Recreate packet list according to new/changed/deleted fields */
3413         packet_list_recreate();
3414     } else if (cfile.state != FILE_CLOSED) {
3415         /* Redissect packets if we have any */
3416         redissect_packets();
3417     }
3418     destroy_packet_wins(); /* TODO: close windows until we can recreate */
3419
3420     proto_free_deregistered_fields();
3421 }
3422
3423 /** redissect packets and update UI */
3424 void redissect_packets(void)
3425 {
3426     cf_redissect_packets(&cfile);
3427     status_expert_update();
3428 }
3429
3430 #ifdef HAVE_SOFTWARE_UPDATE
3431 /** Check to see if Wireshark can shut down safely (e.g. offer to save the
3432  *  current capture).
3433  * Dummy.
3434  */
3435 int software_update_can_shutdown_callback(void) {
3436     return FALSE;
3437 }
3438
3439 /** Shut down Wireshark in preparation for an upgrade.
3440  * Dummy.
3441  */
3442 void software_update_shutdown_request_callback(void) {
3443 }
3444 #endif
3445
3446 /*
3447  * Editor modelines
3448  *
3449  * Local Variables:
3450  * c-basic-offset: 4
3451  * tab-width: 8
3452  * indent-tabs-mode: nil
3453  * End:
3454  *
3455  * ex: set shiftwidth=4 tabstop=8 expandtab:
3456  * :indentSize=4:tabSize=8:noTabs=true:
3457  */