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