Don't enable "Save As" if you don't have an unsaved live capture file
[jlayton/wireshark.git] / gtk / main.c
1 /* main.c
2  *
3  * $Id$
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * Richard Sharpe, 13-Feb-1999, added support for initializing structures
10  *                              needed by dissect routines
11  * Jeff Foster,    2001/03/12,  added support tabbed hex display windowss
12  *
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <gtk/gtk.h>
34 #include <gdk/gdkkeysyms.h>
35
36 #include <string.h>
37 #include <ctype.h>
38
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42
43 #ifdef NEED_STRERROR_H
44 #include "strerror.h"
45 #endif
46
47 #ifdef NEED_GETOPT_H
48 #include "getopt.h"
49 #endif
50
51 #ifdef _WIN32 /* Needed for console I/O */
52 #include <fcntl.h>
53 #include <conio.h>
54 #endif
55
56 #ifdef HAVE_LIBPORTAUDIO
57 #include <portaudio.h>
58 #endif /* HAVE_LIBPORTAUDIO */
59
60 #include <epan/epan.h>
61 #include <epan/filesystem.h>
62 #include <epan/privileges.h>
63 #include <epan/epan_dissect.h>
64 #include <epan/timestamp.h>
65 #include <epan/packet.h>
66 #include <epan/plugins.h>
67 #include <epan/dfilter/dfilter.h>
68 #include <epan/strutil.h>
69 #include <epan/addr_resolv.h>
70 #include <epan/emem.h>
71 #include <epan/ex-opt.h>
72 #include <epan/funnel.h>
73 #include <epan/expert.h>
74
75 /* general (not GTK specific) */
76 #include "file.h"
77 #include "summary.h"
78 #include "filters.h"
79 #include "disabled_protos.h"
80 #include <epan/prefs.h>
81 #include "filter_dlg.h"
82 #include "layout_prefs.h"
83 #include "color.h"
84 #include "color_filters.h"
85 #include "print.h"
86 #include "simple_dialog.h"
87 #include "register.h"
88 #include <epan/prefs-int.h>
89 #include "ringbuffer.h"
90 #include "../ui_util.h"
91 #include <epan/tap.h>
92 #include <epan/stat_cmd_args.h>
93 #include "util.h"
94 #include "clopts_common.h"
95 #include "cmdarg_err.h"
96 #include "version_info.h"
97 #include "merge.h"
98 #include "u3.h"
99 #include "uat_gui.h"
100
101
102 #ifdef HAVE_LIBPCAP
103 #include "capture-pcap-util.h"
104 #include "capture.h"
105 #include "capture_sync.h"
106 #endif
107
108 #ifdef _WIN32
109 #include "capture-wpcap.h"
110 #include "capture_wpcap_packet.h"
111 #include <tchar.h> /* Needed for Unicode */
112 #if GTK_MAJOR_VERSION >= 2
113 #include <commctrl.h>
114 #endif /* GTK_MAJOR_VERSION >= 2 */
115 #endif /* _WIN32 */
116
117 #if GTK_MAJOR_VERSION < 2 && GTK_MINOR_VERSION < 3
118 #include "ethclist.h"
119 #endif
120
121 /* GTK related */
122 #include "statusbar.h"
123 #include "alert_box.h"
124 #if 0
125 #include "dlg_utils.h"
126 #endif
127 #include "file_dlg.h"
128 #include "gtkglobals.h"
129 #include "colors.h"
130 #include "gui_utils.h"
131 #include "compat_macros.h"
132
133 #include "main.h"
134 #include "menu.h"
135 #include "../main_window.h"
136 #include "../menu.h"
137 #include "capture_file_dlg.h"
138 #include <epan/column.h>
139 #include "proto_draw.h"
140 #include "keys.h"
141 #include "packet_win.h"
142 #include "toolbar.h"
143 #include "find_dlg.h"
144 #include "packet_list.h"
145 #include "recent.h"
146 #include "follow_dlg.h"
147 #include "font_utils.h"
148 #include "about_dlg.h"
149 #include "help_dlg.h"
150 #include "decode_as_dlg.h"
151 #include "webbrowser.h"
152 #include "capture_dlg.h"
153 #include "capture_ui_utils.h"
154 #include "log.h"
155 #include "../epan/emem.h"
156 #include "file_util.h"
157 #include "../image/wsicon16.xpm"
158 #include "../image/wsicon32.xpm"
159 #include "../image/wsicon48.xpm"
160 #include "../image/wsicon64.xpm"
161 #include "../image/wsiconcap16.xpm"
162 #include "../image/wsiconcap32.xpm"
163 #include "../image/wsiconcap48.xpm"
164 #ifdef SHOW_WELCOME_PAGE
165 #include "../image/wssplash.xpm"
166 #endif
167
168 #ifdef HAVE_AIRPCAP
169 #include <airpcap.h>
170 #include "airpcap_loader.h"
171 #include "airpcap_dlg.h"
172 #include "airpcap_gui_utils.h"
173
174 #include "./gtk/toolbar.h"
175
176 #include "./image/toolbar/wep_closed_24.xpm"
177 #endif
178
179 #ifdef  HAVE_AIRPDCAP
180 /*      Davide Schiera (2006-11-22): including AirPDcap project                                                 */
181 #include <epan/crypt/airpdcap_ws.h>
182 /* Davide Schiera (2006-11-22) ----------------------------------------------   */
183 #endif
184
185 /*
186  * Files under personal and global preferences directories in which
187  * GTK settings for Wireshark are stored.
188  */
189 #define RC_FILE "gtkrc"
190
191 #ifdef HAVE_LIBPCAP
192 #define DEF_READY_MESSAGE " Ready to load or capture"
193 #else
194 #define DEF_READY_MESSAGE " Ready to load file"
195 #endif
196
197 capture_file cfile;
198 GtkWidget   *main_display_filter_widget=NULL;
199 GtkWidget   *top_level = NULL, *tree_view, *byte_nb_ptr, *tv_scrollw;
200 static GtkWidget   *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
201 static GtkWidget   *main_first_pane, *main_second_pane;
202 static GtkWidget   *status_pane;
203 static GtkWidget   *menubar, *main_vbox, *main_tb, *pkt_scrollw, *stat_hbox, *filter_tb;
204
205 #ifdef HAVE_AIRPCAP
206 GtkWidget *airpcap_tb;
207 static GtkWidget *driver_warning_dialog;
208 static int    airpcap_dll_ret_val = -1;
209 #endif
210
211 static GtkWidget        *info_bar;
212 static GtkWidget    *packets_bar = NULL;
213 static GtkWidget    *welcome_pane;
214 static guint            main_ctx, file_ctx, help_ctx;
215 static guint        packets_ctx;
216 static gchar        *packets_str = NULL;
217 GString *comp_info_str, *runtime_info_str;
218 gboolean have_capture_file = FALSE; /* XXX - is there an aquivalent in cfile? */
219
220 #ifdef _WIN32
221 static gboolean has_console;    /* TRUE if app has console */
222 static void destroy_console(void);
223 #endif
224 static void console_log_handler(const char *log_domain,
225     GLogLevelFlags log_level, const char *message, gpointer user_data);
226
227 #ifdef HAVE_LIBPCAP
228 static gboolean list_link_layer_types;
229 capture_options global_capture_opts;
230 capture_options *capture_opts = &global_capture_opts;
231 #endif
232
233 gboolean block_toolbar_signals = FALSE;
234
235 static void create_main_window(gint, gint, gint, e_prefs*);
236 static void show_main_window(gboolean);
237 static void file_quit_answered_cb(gpointer dialog, gint btn, gpointer data);
238 static void main_save_window_geometry(GtkWidget *widget);
239
240 #define E_DFILTER_CM_KEY          "display_filter_combo"
241 #define E_DFILTER_FL_KEY          "display_filter_list"
242
243 /* Match selected byte pattern */
244 static void
245 match_selected_cb_do(gpointer data, int action, gchar *text)
246 {
247     GtkWidget           *filter_te;
248     char                *cur_filter, *new_filter;
249
250     if ((!text) || (0 == strlen(text))) {
251         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
252         return;
253     }
254
255     g_assert(data);
256     filter_te = OBJECT_GET_DATA(data, E_DFILTER_TE_KEY);
257     g_assert(filter_te);
258
259     cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
260
261     switch (action&MATCH_SELECTED_MASK) {
262
263     case MATCH_SELECTED_REPLACE:
264         new_filter = g_strdup(text);
265         break;
266
267     case MATCH_SELECTED_AND:
268         if ((!cur_filter) || (0 == strlen(cur_filter)))
269             new_filter = g_strdup(text);
270         else
271             new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
272         break;
273
274     case MATCH_SELECTED_OR:
275         if ((!cur_filter) || (0 == strlen(cur_filter)))
276             new_filter = g_strdup(text);
277         else
278             new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
279         break;
280
281     case MATCH_SELECTED_NOT:
282         new_filter = g_strconcat("!(", text, ")", NULL);
283         break;
284
285     case MATCH_SELECTED_AND_NOT:
286         if ((!cur_filter) || (0 == strlen(cur_filter)))
287             new_filter = g_strconcat("!(", text, ")", NULL);
288         else
289             new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
290         break;
291
292     case MATCH_SELECTED_OR_NOT:
293         if ((!cur_filter) || (0 == strlen(cur_filter)))
294             new_filter = g_strconcat("!(", text, ")", NULL);
295         else
296             new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
297         break;
298
299     default:
300         g_assert_not_reached();
301         new_filter = NULL;
302         break;
303     }
304
305     /* Free up the copy we got of the old filter text. */
306     g_free(cur_filter);
307
308     /* Don't change the current display filter if we only want to copy the filter */
309     if (action&MATCH_SELECTED_COPY_ONLY) {
310         GString *gtk_text_str = g_string_new("");
311         g_string_sprintfa(gtk_text_str, "%s", new_filter);
312         copy_to_clipboard(gtk_text_str);
313         g_string_free(gtk_text_str, TRUE);
314     } else {
315         /* create a new one and set the display filter entry accordingly */
316         gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
317
318         /* Run the display filter so it goes in effect. */
319         if (action&MATCH_SELECTED_APPLY_NOW)
320             main_filter_packets(&cfile, new_filter, FALSE);
321     }
322
323     /* Free up the new filter text. */
324     g_free(new_filter);
325 }
326
327 void
328 match_selected_ptree_cb(GtkWidget *w, gpointer data, MATCH_SELECTED_E action)
329 {
330     char *filter;
331
332     if (cfile.finfo_selected) {
333         filter = proto_construct_match_selected_string(cfile.finfo_selected,
334                                                        cfile.edt);
335         match_selected_cb_do((data ? data : w), action, filter);
336     }
337 }
338
339
340 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
341 {
342     gchar *selected_proto_url;
343     gchar *proto_abbrev = data;
344
345
346     switch(btn) {
347     case(ESD_BTN_OK):
348         if (cfile.finfo_selected) {
349             /* open wiki page using the protocol abbreviation */
350             selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
351             browser_open_url(selected_proto_url);
352             g_free(selected_proto_url);
353         }
354         break;
355     case(ESD_BTN_CANCEL):
356         break;
357     default:
358         g_assert_not_reached();
359     }
360 }
361
362
363 void
364 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
365 {
366     int field_id;
367     const gchar *proto_abbrev;
368     gpointer  dialog;
369
370
371     if (cfile.finfo_selected) {
372         /* convert selected field to protocol abbreviation */
373         /* XXX - could this conversion be simplified? */
374         field_id = cfile.finfo_selected->hfinfo->id;
375         /* if the selected field isn't a protocol, get it's parent */
376         if(!proto_registrar_is_protocol(field_id)) {
377             field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
378         }
379
380         proto_abbrev = proto_registrar_get_abbrev(field_id);
381
382         /* ask the user if the wiki page really should be opened */
383         dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
384                     PRIMARY_TEXT_START "Open Wireshark Wiki page of protocol \"%s\"?" PRIMARY_TEXT_END "\n"
385                     "\n"
386                     "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
387                     "\n"
388                     "The Wireshark Wiki is a collaborative approach to provide information\n"
389                     "about Wireshark in several ways (not limited to protocol specifics).\n"
390                     "\n"
391                     "This Wiki is new, so the page of the selected protocol\n"
392                     "may not exist and/or may not contain valuable information.\n"
393                     "\n"
394                     "As everyone can edit the Wiki and add new content (or extend existing),\n"
395                     "you are encouraged to add information if you can.\n"
396                     "\n"
397                     "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
398                     "\n"
399                     "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate,\n"
400                     "which will save you a lot of editing and will give a consistent look over the pages.",
401                     proto_abbrev, proto_abbrev);
402         simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer) proto_abbrev);
403     }
404 }
405
406
407 void
408 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
409 {
410     int field_id;
411     const gchar *proto_abbrev;
412     gchar *selected_proto_url;
413
414
415     if (cfile.finfo_selected) {
416         /* convert selected field to protocol abbreviation */
417         /* XXX - could this conversion be simplified? */
418         field_id = cfile.finfo_selected->hfinfo->id;
419         /* if the selected field isn't a protocol, get it's parent */
420         if(!proto_registrar_is_protocol(field_id)) {
421             field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
422         }
423
424         proto_abbrev = proto_registrar_get_abbrev(field_id);
425
426         /* open reference page using the protocol abbreviation */
427         selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s.html", proto_abbrev[0], proto_abbrev);
428         browser_open_url(selected_proto_url);
429         g_free(selected_proto_url);
430     }
431 }
432
433 static gchar *
434 get_text_from_packet_list(gpointer data)
435 {
436     gint        row = GPOINTER_TO_INT(OBJECT_GET_DATA(data, E_MPACKET_LIST_ROW_KEY));
437     gint        column = GPOINTER_TO_INT(OBJECT_GET_DATA(data, E_MPACKET_LIST_COL_KEY));
438     frame_data *fdata = (frame_data *)packet_list_get_row_data(row);
439     epan_dissect_t *edt;
440     gchar      *buf=NULL;
441     int         len;
442     int         err;
443     gchar       *err_info;
444
445     if (fdata != NULL) {
446         if (!wtap_seek_read(cfile.wth, fdata->file_off, &cfile.pseudo_header,
447                        cfile.pd, fdata->cap_len, &err, &err_info)) {
448             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
449                           cf_read_error_message(err, err_info), cfile.filename);
450             return NULL;
451         }
452
453         edt = epan_dissect_new(FALSE, FALSE);
454         epan_dissect_run(edt, &cfile.pseudo_header, cfile.pd, fdata,
455                          &cfile.cinfo);
456         epan_dissect_fill_in_columns(edt);
457
458         if (strlen(cfile.cinfo.col_expr[column]) != 0 &&
459             strlen(cfile.cinfo.col_expr_val[column]) != 0) {
460             len = strlen(cfile.cinfo.col_expr[column]) +
461                   strlen(cfile.cinfo.col_expr_val[column]) + 5;
462             buf = ep_alloc0(len);
463             g_snprintf(buf, len, "%s == %s", cfile.cinfo.col_expr[column],
464                      cfile.cinfo.col_expr_val[column]);
465         }
466
467         epan_dissect_free(edt);
468     }
469
470     return buf;
471 }
472
473 void
474 match_selected_plist_cb(GtkWidget *w _U_, gpointer data, MATCH_SELECTED_E action)
475 {
476     match_selected_cb_do(data,
477         action,
478         get_text_from_packet_list(data));
479 }
480
481 /* This function allows users to right click in the details window and copy the text
482  * information to the operating systems clipboard.
483  *
484  * We first check to see if a string representation is setup in the tree and then
485  * read the string. If not available then we try to grab the value. If all else
486  * fails we display a message to the user to indicate the copy could not be completed.
487  */
488 void
489 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_)
490 {
491         GString *gtk_text_str = g_string_new("");
492     char labelstring[256];
493     char *stringpointer = labelstring;
494
495     if (cfile.finfo_selected->rep->representation != 0) {
496         g_string_sprintfa(gtk_text_str, "%s", cfile.finfo_selected->rep->representation);   /* Get the represented data */
497     }
498     if (gtk_text_str->len == 0) {                                                           /* If no representation then... */
499         proto_item_fill_label(cfile.finfo_selected, stringpointer);                         /* Try to read the value */
500         g_string_sprintfa(gtk_text_str, "%s", stringpointer);
501     }
502     if (gtk_text_str->len == 0) {                                                           /* Could not get item so display error msg */
503         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
504     }
505     else
506     {
507         copy_to_clipboard(gtk_text_str);                     /* Copy string to clipboard */
508     }
509     g_string_free(gtk_text_str, TRUE);                       /* Free the memory */
510 }
511
512
513 /* XXX: use a preference for this setting! */
514 static guint dfilter_combo_max_recent = 10;
515
516 /* add a display filter to the combo box */
517 /* Note: a new filter string will replace an old identical one */
518 static gboolean
519 dfilter_combo_add(GtkWidget *filter_cm, char *s) {
520   GList     *li;
521   GList     *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
522
523
524   /* GtkCombos don't let us get at their list contents easily, so we maintain
525      our own filter list, and feed it to gtk_combo_set_popdown_strings when
526      a new filter is added. */
527     li = g_list_first(dfilter_list);
528     while (li) {
529         /* If the filter is already in the list, remove the old one and
530                  * append the new one at the latest position (at g_list_append() below) */
531                 if (li->data && strcmp(s, li->data) == 0) {
532           dfilter_list = g_list_remove(dfilter_list, li->data);
533                   break;
534                 }
535       li = li->next;
536     }
537
538     dfilter_list = g_list_append(dfilter_list, s);
539     OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
540     gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), dfilter_list);
541     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(filter_cm)->entry), g_list_last(dfilter_list)->data);
542
543     return TRUE;
544 }
545
546
547 /* write all non empty display filters (until maximum count)
548  * of the combo box GList to the user's recent file */
549 void
550 dfilter_recent_combo_write_all(FILE *rf) {
551   GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
552   GList     *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
553   GList     *li;
554   guint      max_count = 0;
555
556
557   /* write all non empty display filter strings to the recent file (until max count) */
558   li = g_list_first(dfilter_list);
559   while ( li && (max_count++ <= dfilter_combo_max_recent) ) {
560     if (strlen(li->data)) {
561       fprintf (rf, RECENT_KEY_DISPLAY_FILTER ": %s\n", (char *)li->data);
562     }
563     li = li->next;
564   }
565 }
566
567 /* empty the combobox entry field */
568 void
569 dfilter_combo_add_empty(void) {
570   GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
571
572   gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(filter_cm)->entry), "");
573 }
574
575
576 /* add a display filter coming from the user's recent file to the dfilter combo box */
577 gboolean
578 dfilter_combo_add_recent(gchar *s) {
579   GtkWidget *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
580   char      *dup;
581
582   dup = g_strdup(s);
583   if (!dfilter_combo_add(filter_cm, dup)) {
584     g_free(dup);
585     return FALSE;
586   }
587
588   return TRUE;
589 }
590
591
592 /* call cf_filter_packets() and add this filter string to the recent filter list */
593 gboolean
594 main_filter_packets(capture_file *cf, const gchar *dftext, gboolean force)
595 {
596   GtkCombo  *filter_cm = OBJECT_GET_DATA(top_level, E_DFILTER_CM_KEY);
597   GList     *dfilter_list = OBJECT_GET_DATA(filter_cm, E_DFILTER_FL_KEY);
598   GList     *li;
599   gboolean   add_filter = TRUE;
600   gboolean   free_filter = TRUE;
601   char      *s;
602   cf_status_t cf_status;
603
604   /* we'll crash later on if dftext is NULL */
605   g_assert(dftext != NULL);
606
607   s = g_strdup(dftext);
608
609   /* GtkCombos don't let us get at their list contents easily, so we maintain
610      our own filter list, and feed it to gtk_combo_set_popdown_strings when
611      a new filter is added. */
612   cf_status = cf_filter_packets(cf, s, force);
613   if (cf_status == CF_OK) {
614     li = g_list_first(dfilter_list);
615     while (li) {
616       if (li->data && strcmp(s, li->data) == 0)
617         add_filter = FALSE;
618       li = li->next;
619     }
620
621     if (add_filter) {
622       /* trim list size first */
623       while (g_list_length(dfilter_list) >= dfilter_combo_max_recent) {
624         dfilter_list = g_list_remove(dfilter_list, g_list_first(dfilter_list)->data);
625       }
626
627       free_filter = FALSE;
628       dfilter_list = g_list_append(dfilter_list, s);
629       OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
630       gtk_combo_set_popdown_strings(filter_cm, dfilter_list);
631       gtk_entry_set_text(GTK_ENTRY(filter_cm->entry), g_list_last(dfilter_list)->data);
632     }
633   }
634   if (free_filter)
635     g_free(s);
636
637   return (cf_status == CF_OK);
638 }
639
640
641 /* Run the current display filter on the current packet set, and
642    redisplay. */
643 static void
644 filter_activate_cb(GtkWidget *w _U_, gpointer data)
645 {
646   const char *s;
647
648   s = gtk_entry_get_text(GTK_ENTRY(data));
649
650   main_filter_packets(&cfile, s, FALSE);
651 }
652
653 /* redisplay with no display filter */
654 static void
655 filter_reset_cb(GtkWidget *w, gpointer data _U_)
656 {
657   GtkWidget *filter_te = NULL;
658
659   if ((filter_te = OBJECT_GET_DATA(w, E_DFILTER_TE_KEY))) {
660     gtk_entry_set_text(GTK_ENTRY(filter_te), "");
661   }
662   main_filter_packets(&cfile, "", FALSE);
663 }
664
665 /* mark as reference time frame */
666 static void
667 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
668   if (row == -1)
669     return;
670   if (set) {
671     frame->flags.ref_time=1;
672   } else {
673     frame->flags.ref_time=0;
674   }
675   cf_reftime_packets(&cfile);
676 }
677
678
679 GtkWidget *reftime_dialog = NULL;
680
681 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
682 {
683     switch(btn) {
684     case(ESD_BTN_YES):
685         timestamp_set_type(TS_RELATIVE);
686         recent.gui_time_format  = TS_RELATIVE;
687         cf_change_time_formats(&cfile);
688         break;
689     case(ESD_BTN_NO):
690         break;
691     default:
692         g_assert_not_reached();
693     }
694
695     if (cfile.current_frame) {
696       /* XXX hum, should better have a "cfile->current_row" here ... */
697       set_frame_reftime(!cfile.current_frame->flags.ref_time,
698                      cfile.current_frame,
699                      packet_list_find_row_from_data(cfile.current_frame));
700     }
701 }
702
703
704 void
705 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
706 {
707
708   switch(action){
709   case REFTIME_TOGGLE:
710     if (cfile.current_frame) {
711         if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
712             reftime_dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
713                 PRIMARY_TEXT_START "Switch to the appropriate Time Display Format?" PRIMARY_TEXT_END "\n\n"
714                 "Time References don't work well with the currently selected Time Display Format.\n\n"
715                 "Do you want to switch to \"Seconds Since Beginning of Capture\" now?");
716             simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
717         } else {
718             /* XXX hum, should better have a "cfile->current_row" here ... */
719             set_frame_reftime(!cfile.current_frame->flags.ref_time,
720                               cfile.current_frame,
721                               packet_list_find_row_from_data(cfile.current_frame));
722         }
723     }
724     break;
725   case REFTIME_FIND_NEXT:
726     find_previous_next_frame_with_filter("frame.ref_time", FALSE);
727     break;
728   case REFTIME_FIND_PREV:
729     find_previous_next_frame_with_filter("frame.ref_time", TRUE);
730     break;
731   }
732 }
733
734 void
735 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
736 {
737     find_previous_next_frame_with_filter("frame.marked == TRUE", FALSE);
738 }
739
740 void
741 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
742 {
743     find_previous_next_frame_with_filter("frame.marked == TRUE", TRUE);
744 }
745
746 #if GTK_MAJOR_VERSION < 2
747 static void
748 tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column _U_,
749                         gpointer user_data _U_)
750 #else
751 static void
752 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
753 #endif
754 {
755     field_info   *finfo;
756     gchar        *help_str = NULL;
757     gchar         len_str[2+10+1+5+1]; /* ", {N} bytes\0",
758                                           N < 4294967296 */
759     gboolean      has_blurb = FALSE;
760     guint         length = 0, byte_len;
761     GtkWidget    *byte_view;
762     const guint8 *byte_data;
763 #if GTK_MAJOR_VERSION >= 2
764     GtkTreeModel *model;
765     GtkTreeIter   iter;
766 #endif
767
768 #if GTK_MAJOR_VERSION >= 2
769     /* if nothing is selected */
770     if (!gtk_tree_selection_get_selected(sel, &model, &iter))
771     {
772         /*
773          * Which byte view is displaying the current protocol tree
774          * row's data?
775          */
776         byte_view = get_notebook_bv_ptr(byte_nb_ptr);
777         if (byte_view == NULL)
778             return;     /* none */
779
780         byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
781         if (byte_data == NULL)
782             return;     /* none */
783
784         cf_unselect_field(&cfile);
785         packet_hex_print(byte_view, byte_data,
786                          cfile.current_frame, NULL, byte_len);
787         return;
788     }
789     gtk_tree_model_get(model, &iter, 1, &finfo, -1);
790 #else
791     g_assert(node);
792     finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
793 #endif
794     if (!finfo) return;
795
796     set_notebook_page(byte_nb_ptr, finfo->ds_tvb);
797
798     byte_view = get_notebook_bv_ptr(byte_nb_ptr);
799     byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
800     g_assert(byte_data != NULL);
801
802     cfile.finfo_selected = finfo;
803     set_menus_for_selected_tree_row(&cfile);
804
805     if (finfo->hfinfo) {
806         if (finfo->hfinfo->blurb != NULL &&
807             finfo->hfinfo->blurb[0] != '\0') {
808             has_blurb = TRUE;
809             length = strlen(finfo->hfinfo->blurb);
810         } else {
811             length = strlen(finfo->hfinfo->name);
812         }
813         if (finfo->length == 0) {
814             len_str[0] = '\0';
815         } else if (finfo->length == 1) {
816             strcpy (len_str, ", 1 byte");
817         } else {
818             g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo->length);
819         }
820         statusbar_pop_field_msg();      /* get rid of current help msg */
821         if (length) {
822             help_str = g_strdup_printf("%s (%s)%s",
823                     (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
824                     finfo->hfinfo->abbrev, len_str);
825             statusbar_push_field_msg(help_str);
826             g_free(help_str);
827         } else {
828             /*
829              * Don't show anything if the field name is zero-length;
830              * the pseudo-field for "proto_tree_add_text()" is such
831              * a field, and we don't want "Text (text)" showing up
832              * on the status line if you've selected such a field.
833              *
834              * XXX - there are zero-length fields for which we *do*
835              * want to show the field name.
836              *
837              * XXX - perhaps the name and abbrev field should be null
838              * pointers rather than null strings for that pseudo-field,
839              * but we'd have to add checks for null pointers in some
840              * places if we did that.
841              *
842              * Or perhaps protocol tree items added with
843              * "proto_tree_add_text()" should have -1 as the field index,
844              * with no pseudo-field being used, but that might also
845              * require special checks for -1 to be added.
846              */
847             statusbar_push_field_msg("");
848         }
849     }
850
851     packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
852                      byte_len);
853 }
854
855 #if GTK_MAJOR_VERSION < 2
856 static void
857 tree_view_unselect_row_cb(GtkCTree *ctree _U_, GList *node _U_, gint column _U_,
858                           gpointer user_data _U_)
859 {
860         GtkWidget       *byte_view;
861         const guint8    *data;
862         guint           len;
863
864         /*
865          * Which byte view is displaying the current protocol tree
866          * row's data?
867          */
868         byte_view = get_notebook_bv_ptr(byte_nb_ptr);
869         if (byte_view == NULL)
870                 return; /* none */
871
872         data = get_byte_view_data_and_length(byte_view, &len);
873         if (data == NULL)
874                 return; /* none */
875
876         cf_unselect_field(&cfile);
877         packet_hex_print(byte_view, data, cfile.current_frame, NULL, len);
878 }
879 #endif
880
881 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
882   if (cfile.edt->tree)
883     collapse_all_tree(cfile.edt->tree, tree_view);
884 }
885
886 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
887   if (cfile.edt->tree)
888     expand_all_tree(cfile.edt->tree, tree_view);
889 }
890
891 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
892 #if GTK_MAJOR_VERSION < 2
893   GtkCTreeNode *node;
894 #else
895   GtkTreePath  *path;
896 #endif
897
898 #if GTK_MAJOR_VERSION < 2
899   node = gtk_ctree_find_by_row_data(GTK_CTREE(tree_view), NULL, cfile.finfo_selected);
900   if(node) {
901     /* the mouse position is at an entry, expand that one */
902   gtk_ctree_expand_recursive(GTK_CTREE(tree_view), node);
903   }
904 #else
905   path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view), cfile.finfo_selected);
906   if(path) {
907     /* the mouse position is at an entry, expand that one */
908   gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view), path, TRUE);
909   gtk_tree_path_free(path);
910   }
911 #endif
912 }
913
914 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
915   if (cfile.edt->tree) {
916     guint32 tmp = g_resolv_flags;
917     g_resolv_flags = RESOLV_ALL;
918     proto_tree_draw(cfile.edt->tree, tree_view);
919     g_resolv_flags = tmp;
920   }
921 }
922
923 /*
924  * Push a message referring to file access onto the statusbar.
925  */
926 void
927 statusbar_push_file_msg(gchar *msg)
928 {
929     /*g_warning("statusbar_push: %s", msg);*/
930         gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, msg);
931 }
932
933 /*
934  * Pop a message referring to file access off the statusbar.
935  */
936 void
937 statusbar_pop_file_msg(void)
938 {
939     /*g_warning("statusbar_pop");*/
940         gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
941 }
942
943 /*
944  * XXX - do we need multiple statusbar contexts?
945  */
946
947 /*
948  * Push a message referring to the currently-selected field onto the statusbar.
949  */
950 void
951 statusbar_push_field_msg(gchar *msg)
952 {
953         gtk_statusbar_push(GTK_STATUSBAR(info_bar), help_ctx, msg);
954 }
955
956 /*
957  * Pop a message referring to the currently-selected field off the statusbar.
958  */
959 void
960 statusbar_pop_field_msg(void)
961 {
962         gtk_statusbar_pop(GTK_STATUSBAR(info_bar), help_ctx);
963 }
964
965 /*
966  * update the packets statusbar to the current values
967  */
968 void packets_bar_update(void)
969 {
970
971     if(packets_bar) {
972         /* remove old status */
973         if(packets_str) {
974             g_free(packets_str);
975                 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
976         }
977
978         /* do we have any packets? */
979         if(cfile.count) {
980             if(cfile.drops_known) {
981                 packets_str = g_strdup_printf(" P: %u D: %u M: %u Drops: %u",
982                     cfile.count, cfile.displayed_count, cfile.marked_count, cfile.drops);
983             } else {
984                 packets_str = g_strdup_printf(" P: %u D: %u M: %u",
985                     cfile.count, cfile.displayed_count, cfile.marked_count);
986             }
987         } else {
988             packets_str = g_strdup(" No Packets");
989         }
990             gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, packets_str);
991     }
992 }
993
994 void
995 main_set_for_capture_file(gboolean have_capture_file_in)
996 {
997     have_capture_file = have_capture_file_in;
998
999     main_widgets_show_or_hide();
1000 }
1001
1002 gboolean
1003 main_do_quit(void)
1004 {
1005         /* get the current geometry, before writing it to disk */
1006         main_save_window_geometry(top_level);
1007
1008         /* write user's recent file to disk
1009          * It is no problem to write this file, even if we do not quit */
1010         write_recent();
1011
1012         /* XXX - should we check whether the capture file is an
1013            unsaved temporary file for a live capture and, if so,
1014            pop up a "do you want to exit without saving the capture
1015            file?" dialog, and then just return, leaving said dialog
1016            box to forcibly quit if the user clicks "OK"?
1017
1018            If so, note that this should be done in a subroutine that
1019            returns TRUE if we do so, and FALSE otherwise, and if it
1020            returns TRUE we should return TRUE without nuking anything.
1021
1022            Note that, if we do that, we might also want to check if
1023            an "Update list of packets in real time" capture is in
1024            progress and, if so, ask whether they want to terminate
1025            the capture and discard it, and return TRUE, before nuking
1026            any child capture, if they say they don't want to do so. */
1027
1028 #ifdef HAVE_LIBPCAP
1029         /* Nuke any child capture in progress. */
1030         capture_kill_child(capture_opts);
1031 #endif
1032
1033         /* Are we in the middle of reading a capture? */
1034         if (cfile.state == FILE_READ_IN_PROGRESS) {
1035                 /* Yes, so we can't just close the file and quit, as
1036                    that may yank the rug out from under the read in
1037                    progress; instead, just set the state to
1038                    "FILE_READ_ABORTED" and return - the code doing the read
1039                    will check for that and, if it sees that, will clean
1040                    up and quit. */
1041                 cfile.state = FILE_READ_ABORTED;
1042
1043                 /* Say that the window should *not* be deleted;
1044                    that'll be done by the code that cleans up. */
1045                 return TRUE;
1046         } else {
1047                 /* Close any capture file we have open; on some OSes, you
1048                    can't unlink a temporary capture file if you have it
1049                    open.
1050                    "cf_close()" will unlink it after closing it if
1051                    it's a temporary file.
1052
1053                    We do this here, rather than after the main loop returns,
1054                    as, after the main loop returns, the main window may have
1055                    been destroyed (if this is called due to a "destroy"
1056                    even on the main window rather than due to the user
1057                    selecting a menu item), and there may be a crash
1058                    or other problem when "cf_close()" tries to
1059                    clean up stuff in the main window.
1060
1061                    XXX - is there a better place to put this?
1062                    Or should we have a routine that *just* closes the
1063                    capture file, and doesn't do anything with the UI,
1064                    which we'd call here, and another routine that
1065                    calls that routine and also cleans up the UI, which
1066                    we'd call elsewhere? */
1067                 cf_close(&cfile);
1068
1069                 /* Exit by leaving the main loop, so that any quit functions
1070                    we registered get called. */
1071                 gtk_main_quit();
1072
1073                 /* Say that the window should be deleted. */
1074                 return FALSE;
1075         }
1076 }
1077
1078 static gboolean
1079 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1080 {
1081   gpointer dialog;
1082
1083   if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1084 #if GTK_MAJOR_VERSION >= 2
1085     gtk_window_present(GTK_WINDOW(top_level));
1086 #endif
1087     /* user didn't saved his current file, ask him */
1088     dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
1089                 PRIMARY_TEXT_START "Save capture file before program quit?" PRIMARY_TEXT_END "\n\n"
1090                 "If you quit the program without saving, your capture data will be discarded.");
1091     simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1092     return TRUE;
1093   } else {
1094     /* unchanged file, just exit */
1095     /* "main_do_quit()" indicates whether the main window should be deleted. */
1096     return main_do_quit();
1097   }
1098 }
1099
1100
1101
1102 static void
1103 main_load_window_geometry(GtkWidget *widget)
1104 {
1105     window_geometry_t geom;
1106
1107     geom.set_pos        = prefs.gui_geometry_save_position;
1108     geom.x              = recent.gui_geometry_main_x;
1109     geom.y              = recent.gui_geometry_main_y;
1110     geom.set_size       = prefs.gui_geometry_save_size;
1111     if (recent.gui_geometry_main_width > 0 &&
1112         recent.gui_geometry_main_height > 0) {
1113         geom.width          = recent.gui_geometry_main_width;
1114         geom.height         = recent.gui_geometry_main_height;
1115         geom.set_maximized  = prefs.gui_geometry_save_maximized;
1116     } else {
1117         /* We assume this means the width and height weren't set in
1118            the "recent" file (or that there is no "recent" file),
1119            and weren't set to a default value, so we don't set the
1120            size.  (The "recent" file code rejects non-positive width
1121            and height values.) */
1122        geom.set_size = FALSE;
1123     }
1124     geom.maximized      = recent.gui_geometry_main_maximized;
1125
1126     window_set_geometry(widget, &geom);
1127
1128     if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1129         gtk_paned_set_position(GTK_PANED(main_first_pane),  recent.gui_geometry_main_upper_pane);
1130     if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane)
1131         gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1132     if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_status_pane)
1133         gtk_paned_set_position(GTK_PANED(status_pane),      recent.gui_geometry_status_pane);
1134 }
1135
1136
1137 static void
1138 main_save_window_geometry(GtkWidget *widget)
1139 {
1140     window_geometry_t geom;
1141
1142     window_get_geometry(widget, &geom);
1143
1144     if (prefs.gui_geometry_save_position) {
1145         recent.gui_geometry_main_x = geom.x;
1146             recent.gui_geometry_main_y = geom.y;
1147     }
1148
1149     if (prefs.gui_geometry_save_size) {
1150         recent.gui_geometry_main_width  = geom.width,
1151         recent.gui_geometry_main_height = geom.height;
1152     }
1153
1154 #if GTK_MAJOR_VERSION >= 2
1155     if(prefs.gui_geometry_save_maximized) {
1156         recent.gui_geometry_main_maximized = geom.maximized;
1157     }
1158
1159     recent.gui_geometry_main_upper_pane     = gtk_paned_get_position(GTK_PANED(main_first_pane));
1160     recent.gui_geometry_main_lower_pane     = gtk_paned_get_position(GTK_PANED(main_second_pane));
1161     recent.gui_geometry_status_pane         = gtk_paned_get_position(GTK_PANED(status_pane));
1162 #endif
1163 }
1164
1165 static void file_quit_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1166 {
1167     switch(btn) {
1168     case(ESD_BTN_SAVE):
1169         /* save file first */
1170         file_save_as_cmd(after_save_exit, NULL);
1171         break;
1172     case(ESD_BTN_DONT_SAVE):
1173         main_do_quit();
1174         break;
1175     case(ESD_BTN_CANCEL):
1176         break;
1177     default:
1178         g_assert_not_reached();
1179     }
1180 }
1181
1182 void
1183 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1184 {
1185   gpointer dialog;
1186
1187   if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1188     /* user didn't saved his current file, ask him */
1189     dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_SAVE_DONTSAVE_CANCEL,
1190                 PRIMARY_TEXT_START "Save capture file before program quit?" PRIMARY_TEXT_END "\n\n"
1191                 "If you quit the program without saving, your capture data will be discarded.");
1192     simple_dialog_set_cb(dialog, file_quit_answered_cb, NULL);
1193   } else {
1194     /* unchanged file, just exit */
1195     main_do_quit();
1196   }
1197 }
1198
1199 static void
1200 print_usage(gboolean print_ver) {
1201
1202   FILE *output;
1203
1204 #ifdef _WIN32
1205   create_console();
1206 #endif
1207
1208   if (print_ver) {
1209     output = stdout;
1210     fprintf(output, "Wireshark " VERSION "%s\n"
1211         "Interactively dump and analyze network traffic.\n"
1212         "See http://www.wireshark.org for more information.\n"
1213         "\n"
1214         "%s",
1215         wireshark_svnversion, get_copyright_info());
1216   } else {
1217     output = stderr;
1218   }
1219   fprintf(output, "\n");
1220   fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1221   fprintf(output, "\n");
1222
1223 #ifdef HAVE_LIBPCAP
1224   fprintf(output, "Capture interface:\n");
1225   fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
1226   fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
1227   fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
1228   fprintf(output, "  -p                       don't capture in promiscuous mode\n");
1229   fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
1230   fprintf(output, "  -Q                       quit Wireshark after capturing\n");
1231   fprintf(output, "  -S                       update packet display when new packets are captured\n");
1232   fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
1233 #ifdef _WIN32
1234   fprintf(output, "  -B <buffer size>         size of kernel buffer (def: 1MB)\n");
1235 #endif
1236   fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
1237   fprintf(output, "  -D                       print list of interfaces and exit\n");
1238   fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
1239   fprintf(output, "\n");
1240   fprintf(output, "Capture stop conditions:\n");
1241   fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
1242   fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
1243   fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
1244   fprintf(output, "                              files:NUM - stop after NUM files\n");
1245   /*fprintf(output, "\n");*/
1246   fprintf(output, "Capture output:\n");
1247   fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1248   fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
1249   fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
1250 #endif  /* HAVE_LIBPCAP */
1251
1252   /*fprintf(output, "\n");*/
1253   fprintf(output, "Input file:\n");
1254   fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
1255
1256   fprintf(output, "\n");
1257   fprintf(output, "Processing:\n");
1258   fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
1259   fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
1260   fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mntC\"\n");
1261
1262   fprintf(output, "\n");
1263   fprintf(output, "User interface:\n");
1264   fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
1265   fprintf(output, "  -m <font>                set the font name used for most text\n");
1266   fprintf(output, "  -t ad|a|r|d|e            output format of time stamps (def: r: rel. to first)\n");
1267   fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
1268   fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
1269
1270   fprintf(output, "\n");
1271   fprintf(output, "Output:\n");
1272   fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
1273
1274   fprintf(output, "\n");
1275   fprintf(output, "Miscellaneous:\n");
1276   fprintf(output, "  -h                       display this help and exit\n");
1277   fprintf(output, "  -v                       display version info and exit\n");
1278   fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
1279 #ifndef _WIN32
1280   fprintf(output, "  --display=DISPLAY        X display to use\n");
1281 #endif
1282
1283 #ifdef _WIN32
1284   destroy_console();
1285 #endif
1286 }
1287
1288 static void
1289 show_version(void)
1290 {
1291 #ifdef _WIN32
1292   create_console();
1293 #endif
1294
1295   printf(PACKAGE " " VERSION "%s\n"
1296          "\n"
1297          "%s"
1298          "\n"
1299          "%s"
1300          "\n"
1301          "%s",
1302       wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1303       runtime_info_str->str);
1304
1305 #ifdef _WIN32
1306   destroy_console();
1307 #endif
1308 }
1309
1310 /*
1311  * Report an error in command-line arguments.
1312  * Creates a console on Windows.
1313  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1314  * terminal isn't the standard error?
1315  */
1316 void
1317 cmdarg_err(const char *fmt, ...)
1318 {
1319   va_list ap;
1320
1321 #ifdef _WIN32
1322   create_console();
1323 #endif
1324   va_start(ap, fmt);
1325   fprintf(stderr, "wireshark: ");
1326   vfprintf(stderr, fmt, ap);
1327   fprintf(stderr, "\n");
1328   va_end(ap);
1329 }
1330
1331 /*
1332  * Report additional information for an error in command-line arguments.
1333  * Creates a console on Windows.
1334  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1335  * terminal isn't the standard error?
1336  */
1337 void
1338 cmdarg_err_cont(const char *fmt, ...)
1339 {
1340   va_list ap;
1341
1342 #ifdef _WIN32
1343   create_console();
1344 #endif
1345   va_start(ap, fmt);
1346   vfprintf(stderr, fmt, ap);
1347   fprintf(stderr, "\n");
1348   va_end(ap);
1349 }
1350
1351 #if defined(_WIN32) || GTK_MAJOR_VERSION < 2 || ! defined USE_THREADS
1352 /*
1353    Once every 3 seconds we get a callback here which we use to update
1354    the tap extensions. Since Gtk1 is single threaded we dont have to
1355    worry about any locking or critical regions.
1356  */
1357 static gint
1358 update_cb(gpointer data _U_)
1359 {
1360         draw_tap_listeners(FALSE);
1361         return 1;
1362 }
1363 #else
1364
1365 /* if these three functions are copied to gtk1 Wireshark, since gtk1 does not
1366    use threads all updte_thread_mutex can be dropped and protect/unprotect
1367    would just be empty functions.
1368
1369    This allows gtk2-rpcstat.c and friends to be copied unmodified to
1370    gtk1-wireshark and it will just work.
1371  */
1372 static GStaticMutex update_thread_mutex = G_STATIC_MUTEX_INIT;
1373 gpointer
1374 update_thread(gpointer data _U_)
1375 {
1376     while(1){
1377         GTimeVal tv1, tv2;
1378         g_get_current_time(&tv1);
1379         g_static_mutex_lock(&update_thread_mutex);
1380         gdk_threads_enter();
1381         draw_tap_listeners(FALSE);
1382         gdk_threads_leave();
1383         g_static_mutex_unlock(&update_thread_mutex);
1384         g_thread_yield();
1385         g_get_current_time(&tv2);
1386         if( ((tv1.tv_sec + 2) * 1000000 + tv1.tv_usec) >
1387             (tv2.tv_sec * 1000000 + tv2.tv_usec) ){
1388             g_usleep(((tv1.tv_sec + 2) * 1000000 + tv1.tv_usec) -
1389                      (tv2.tv_sec * 1000000 + tv2.tv_usec));
1390         }
1391     }
1392     return NULL;
1393 }
1394 #endif
1395 void
1396 protect_thread_critical_region(void)
1397 {
1398 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined USE_THREADS
1399     g_static_mutex_lock(&update_thread_mutex);
1400 #endif
1401 }
1402 void
1403 unprotect_thread_critical_region(void)
1404 {
1405 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined USE_THREADS
1406     g_static_mutex_unlock(&update_thread_mutex);
1407 #endif
1408 }
1409
1410 /* Set the file name in the status line, in the name for the main window,
1411    and in the name for the main window's icon. */
1412 static void
1413 set_display_filename(capture_file *cf)
1414 {
1415   const gchar *name_ptr;
1416   gchar       *status_msg;
1417   gchar       *size_str;
1418   gchar       *win_name;
1419
1420   name_ptr = cf_get_display_name(cf);
1421
1422   if (!cf->is_tempfile && cf->filename) {
1423     /* Add this filename to the list of recent files in the "Recent Files" submenu */
1424     add_menu_recent_capture_file(cf->filename);
1425   }
1426
1427   /* convert file size */
1428   if (cf->f_datalen/1024/1024 > 10) {
1429     size_str = g_strdup_printf("%lld MB", cf->f_datalen/1024/1024);
1430   } else if (cf->f_datalen/1024 > 10) {
1431     size_str = g_strdup_printf("%lld KB", cf->f_datalen/1024);
1432   } else {
1433     size_str = g_strdup_printf("%lld Bytes", cf->f_datalen);
1434   }
1435
1436   /* statusbar */
1437 #if 0
1438   /* XXX - don't show the highest expert level unless the TCP checksum offloading is "solved" */
1439   status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu [Expert: %s]",
1440     (cf->filename) ? cf->filename : "", size_str,
1441     (long)cf->elapsed_time.secs/3600,
1442     (long)cf->elapsed_time.secs%3600/60,
1443     (long)cf->elapsed_time.secs%60,
1444     val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1445 #endif
1446   status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu",
1447     (cf->filename) ? cf->filename : "", size_str,
1448     (long)cf->elapsed_time.secs/3600,
1449     (long)cf->elapsed_time.secs%3600/60,
1450     (long)cf->elapsed_time.secs%60);
1451   g_free(size_str);
1452   statusbar_push_file_msg(status_msg);
1453   g_free(status_msg);
1454
1455   /* window title */
1456   win_name = g_strdup_printf("%s - Wireshark", name_ptr);
1457   set_main_window_name(win_name);
1458   g_free(win_name);
1459 }
1460
1461 GtkWidget           *close_dlg = NULL;
1462
1463 static void
1464 main_cf_cb_file_closing(capture_file *cf)
1465 {
1466
1467     /* if we have more than 10000 packets, show a splash screen while closing */
1468     /* XXX - don't know a better way to decide wether to show or not,
1469      * as most of the time is spend in a single eth_clist_clear function,
1470      * so we can't use a progress bar here! */
1471     if(cf->count > 10000) {
1472         close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1473                                   "%sClosing file!%s\n\nPlease wait ...",
1474                                   simple_dialog_primary_start(),
1475                                   simple_dialog_primary_end());
1476 #if GTK_MAJOR_VERSION >= 2
1477         gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1478 #else
1479         gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER);
1480 #endif
1481     }
1482
1483     /* Destroy all windows, which refer to the
1484        capture file we're closing. */
1485     destroy_packet_wins();
1486     file_save_as_destroy();
1487
1488     /* Clear any file-related status bar messages.
1489        XXX - should be "clear *ALL* file-related status bar messages;
1490        will there ever be more than one on the stack? */
1491     statusbar_pop_file_msg();
1492
1493     /* Restore the standard title bar message. */
1494     set_main_window_name("The Wireshark Network Analyzer");
1495
1496     /* Disable all menu items that make sense only if you have a capture. */
1497     set_menus_for_capture_file(NULL);
1498     set_menus_for_captured_packets(FALSE);
1499     set_menus_for_selected_packet(cf);
1500     set_menus_for_capture_in_progress(FALSE);
1501     set_menus_for_selected_tree_row(cf);
1502
1503     /* Set up main window for no capture file. */
1504     main_set_for_capture_file(FALSE);
1505
1506     main_window_update();
1507 }
1508
1509 static void
1510 main_cf_cb_file_closed(capture_file *cf _U_)
1511 {
1512   if(close_dlg != NULL) {
1513     splash_destroy(close_dlg);
1514     close_dlg = NULL;
1515   }
1516
1517   /* go back to "No packets" */
1518   packets_bar_update();
1519 }
1520
1521 static void
1522 main_cf_cb_file_read_start(capture_file *cf)
1523 {
1524   const gchar *name_ptr;
1525   gchar       *load_msg;
1526
1527   name_ptr = get_basename(cf->filename);
1528
1529   load_msg = g_strdup_printf(" Loading: %s", name_ptr);
1530   statusbar_push_file_msg(load_msg);
1531   g_free(load_msg);
1532
1533   /* Set up main window for a capture file. */
1534   main_set_for_capture_file(TRUE);
1535 }
1536
1537 static void
1538 main_cf_cb_file_read_finished(capture_file *cf)
1539 {
1540     statusbar_pop_file_msg();
1541     set_display_filename(cf);
1542
1543     /* Enable menu items that make sense if you have a capture file you've
1544        finished reading. */
1545     set_menus_for_capture_file(cf);
1546
1547     /* Enable menu items that make sense if you have some captured packets. */
1548     set_menus_for_captured_packets(TRUE);
1549 }
1550
1551 #if GTK_MAJOR_VERSION >= 2
1552 GList *icon_list_create(
1553     const char **icon16_xpm,
1554     const char **icon32_xpm,
1555     const char **icon48_xpm,
1556     const char **icon64_xpm)
1557 {
1558   GList *icon_list = NULL;
1559   GdkPixbuf * pixbuf16;
1560   GdkPixbuf * pixbuf32;
1561   GdkPixbuf * pixbuf48;
1562   GdkPixbuf * pixbuf64;
1563
1564
1565   if(icon16_xpm != NULL) {
1566       pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1567       g_assert(pixbuf16);
1568       icon_list = g_list_append(icon_list, pixbuf16);
1569   }
1570
1571   if(icon32_xpm != NULL) {
1572       pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1573       g_assert(pixbuf32);
1574       icon_list = g_list_append(icon_list, pixbuf32);
1575   }
1576
1577   if(icon48_xpm != NULL) {
1578       pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1579       g_assert(pixbuf48);
1580       icon_list = g_list_append(icon_list, pixbuf48);
1581   }
1582
1583   if(icon64_xpm != NULL) {
1584       pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1585       g_assert(pixbuf64);
1586       icon_list = g_list_append(icon_list, pixbuf64);
1587   }
1588
1589   return icon_list;
1590 }
1591 #endif
1592
1593 #ifdef HAVE_LIBPCAP
1594 static void
1595 main_cf_cb_live_capture_prepared(capture_options *capture_opts)
1596 {
1597     gchar *title;
1598 #if GTK_MAJOR_VERSION >= 2
1599     static GList *icon_list = NULL;
1600 #endif
1601
1602
1603     if(capture_opts->iface) {
1604         title = g_strdup_printf("%s: Capturing - Wireshark",
1605                             get_interface_descriptive_name(capture_opts->iface));
1606     } else {
1607         title = g_strdup_printf("Capturing - Wireshark");
1608     }
1609     set_main_window_name(title);
1610     g_free(title);
1611
1612 #if GTK_MAJOR_VERSION >= 2
1613     if(icon_list == NULL) {
1614         icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1615     }
1616     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1617 #endif
1618
1619     /* Disable menu items that make no sense if you're currently running
1620        a capture. */
1621     set_menus_for_capture_in_progress(TRUE);
1622
1623     /* update statusbar */
1624     statusbar_push_file_msg("Waiting for capture input data ...");
1625
1626     /* Don't set up main window for a capture file. */
1627     main_set_for_capture_file(FALSE);
1628 }
1629
1630 static void
1631 main_cf_cb_live_capture_update_started(capture_options *capture_opts)
1632 {
1633     gchar *capture_msg;
1634     gchar *title;
1635
1636     /* We've done this in "prepared" above, but it will be cleared while
1637        switching to the next multiple file. */
1638     if(capture_opts->iface) {
1639         title = g_strdup_printf("%s: Capturing - Wireshark",
1640                             get_interface_descriptive_name(capture_opts->iface));
1641     } else {
1642         title = g_strdup_printf("Capturing - Wireshark");
1643     }
1644     set_main_window_name(title);
1645     g_free(title);
1646
1647     set_menus_for_capture_in_progress(TRUE);
1648
1649     /* Enable menu items that make sense if you have some captured
1650        packets (yes, I know, we don't have any *yet*). */
1651     set_menus_for_captured_packets(TRUE);
1652
1653     statusbar_pop_file_msg();
1654
1655     if(capture_opts->iface) {
1656         capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
1657             get_interface_descriptive_name(capture_opts->iface),
1658             (capture_opts->save_file) ? capture_opts->save_file : "");
1659     } else {
1660         capture_msg = g_strdup_printf(" <live capture in progress> to file: %s",
1661             (capture_opts->save_file) ? capture_opts->save_file : "");
1662     }
1663
1664     statusbar_push_file_msg(capture_msg);
1665
1666     g_free(capture_msg);
1667
1668     /* Set up main window for a capture file. */
1669     main_set_for_capture_file(TRUE);
1670 }
1671
1672 static void
1673 main_cf_cb_live_capture_update_continue(capture_file *cf)
1674 {
1675     gchar *capture_msg;
1676
1677
1678     statusbar_pop_file_msg();
1679
1680 #if 0
1681     /* XXX - don't show the highest expert level unless the TCP checksum offloading is "solved" */
1682     if (cf->f_datalen/1024/1024 > 10) {
1683         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld MB [Expert: %s]",
1684             get_interface_descriptive_name(capture_opts->iface),
1685             capture_opts->save_file,
1686             cf->f_datalen/1024/1024,
1687             val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1688     } else if (cf->f_datalen/1024 > 10) {
1689         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld KB [Expert: %s]",
1690             get_interface_descriptive_name(capture_opts->iface),
1691             capture_opts->save_file,
1692             cf->f_datalen/1024,
1693             val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1694     } else {
1695         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld Bytes [Expert: %s]",
1696             get_interface_descriptive_name(capture_opts->iface),
1697             capture_opts->save_file,
1698             cf->f_datalen,
1699             val_to_str(expert_get_highest_severity(), expert_severity_vals, "Unknown (%u)"));
1700     }
1701 #endif
1702     if (cf->f_datalen/1024/1024 > 10) {
1703         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld MB",
1704             get_interface_descriptive_name(capture_opts->iface),
1705             capture_opts->save_file,
1706             cf->f_datalen/1024/1024);
1707     } else if (cf->f_datalen/1024 > 10) {
1708         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld KB",
1709             get_interface_descriptive_name(capture_opts->iface),
1710             capture_opts->save_file,
1711             cf->f_datalen/1024);
1712     } else {
1713         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %lld Bytes",
1714             get_interface_descriptive_name(capture_opts->iface),
1715             capture_opts->save_file,
1716             cf->f_datalen);
1717     }
1718
1719     statusbar_push_file_msg(capture_msg);
1720 }
1721
1722 GtkWidget * stop_dlg = NULL;
1723
1724 static void
1725 main_cf_cb_live_capture_update_finished(capture_file *cf)
1726 {
1727 #if GTK_MAJOR_VERSION >= 2
1728     static GList *icon_list = NULL;
1729 #endif
1730
1731     if(stop_dlg != NULL) {
1732                 simple_dialog_close(stop_dlg);
1733                 stop_dlg = NULL;
1734         }
1735
1736     /* Pop the "<live capture in progress>" message off the status bar. */
1737     statusbar_pop_file_msg();
1738
1739     set_display_filename(cf);
1740
1741     /* Enable menu items that make sense if you're not currently running
1742      a capture. */
1743     set_menus_for_capture_in_progress(FALSE);
1744
1745     /* Enable menu items that make sense if you have a capture file
1746        you've finished reading. */
1747     set_menus_for_capture_file(cf);
1748
1749     /* Set up main window for a capture file. */
1750     main_set_for_capture_file(TRUE);
1751
1752 #if GTK_MAJOR_VERSION >= 2
1753     if(icon_list == NULL) {
1754         icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1755     }
1756     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1757 #endif
1758
1759     if(capture_opts->quit_after_cap) {
1760         /* command line asked us to quit after the capture */
1761         /* don't pop up a dialog to ask for unsaved files etc. */
1762         main_do_quit();
1763     }
1764 }
1765
1766 static void
1767 main_cf_cb_live_capture_fixed_started(capture_options *capture_opts)
1768 {
1769     gchar *capture_msg;
1770
1771
1772     /* Enable menu items that make sense if you have some captured
1773        packets (yes, I know, we don't have any *yet*). */
1774     /*set_menus_for_captured_packets(TRUE);*/
1775
1776     statusbar_pop_file_msg();
1777
1778     capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
1779         get_interface_descriptive_name(capture_opts->iface),
1780         (capture_opts->save_file) ? capture_opts->save_file : "");
1781
1782     statusbar_push_file_msg(capture_msg);
1783     gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, " P: 0");
1784
1785     g_free(capture_msg);
1786
1787     /* Don't set up main window for a capture file. */
1788     main_set_for_capture_file(FALSE);
1789 }
1790
1791 static void
1792 main_cf_cb_live_capture_fixed_continue(capture_file *cf)
1793 {
1794     gchar *capture_msg;
1795
1796
1797         gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
1798
1799     capture_msg = g_strdup_printf(" P: %u",
1800         cf_get_packet_count(cf));
1801
1802     gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, capture_msg);
1803
1804     g_free(capture_msg);
1805 }
1806
1807 static void
1808 main_cf_cb_live_capture_fixed_finished(capture_file *cf _U_)
1809 {
1810 #if GTK_MAJOR_VERSION >= 2
1811     static GList *icon_list = NULL;
1812 #endif
1813
1814     if(stop_dlg != NULL) {
1815                 simple_dialog_close(stop_dlg);
1816                 stop_dlg = NULL;
1817         }
1818
1819     /* Pop the "<live capture in progress>" message off the status bar. */
1820     statusbar_pop_file_msg();
1821
1822     /* Pop the "<capturing>" message off the status bar */
1823         gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
1824
1825     /*set_display_filename(cf);*/
1826
1827     /* Enable menu items that make sense if you're not currently running
1828      a capture. */
1829     set_menus_for_capture_in_progress(FALSE);
1830
1831     /* Restore the standard title bar message */
1832     /* (just in case we have trouble opening the capture file). */
1833     set_main_window_name("The Wireshark Network Analyzer");
1834
1835 #if GTK_MAJOR_VERSION >= 2
1836     if(icon_list == NULL) {
1837         icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1838     }
1839     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1840 #endif
1841
1842     /* We don't have loaded the capture file, this will be done later.
1843      * For now we still have simply a blank screen. */
1844
1845     if(capture_opts->quit_after_cap) {
1846         /* command line asked us to quit after the capture */
1847         /* don't pop up a dialog to ask for unsaved files etc. */
1848         main_do_quit();
1849     }
1850 }
1851
1852 static void
1853 main_cf_cb_live_capture_stopping(capture_file *cf _U_)
1854 {
1855     /* Beware: this state won't be called, if the capture child
1856      * closes the capturing on it's own! */
1857 #if 0
1858     /* XXX - the time to stop the capture has been reduced (this was only a
1859      * problem on Win32 because of the capture piping), so showing a splash
1860      * isn't really necessary any longer. Unfortunately, the GTKClist packet
1861      * list seems to have problems updating after the dialog is closed, so
1862      * this was disabled here. */
1863     stop_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE, "%sCapture stop!%s\n\nPlease wait ...",
1864                 simple_dialog_primary_start(), simple_dialog_primary_end());
1865 #if GTK_MAJOR_VERSION >= 2
1866     gtk_window_set_position(GTK_WINDOW(stop_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1867 #else
1868     gtk_window_set_position(GTK_WINDOW(stop_dlg), GTK_WIN_POS_CENTER);
1869 #endif
1870 #endif
1871 }
1872
1873 #endif
1874
1875 static void
1876 main_cf_cb_packet_selected(gpointer data)
1877 {
1878     capture_file *cf = data;
1879
1880     /* Display the GUI protocol tree and hex dump.
1881       XXX - why do we dump core if we call "proto_tree_draw()"
1882       before calling "add_byte_views()"? */
1883     add_main_byte_views(cf->edt);
1884     main_proto_tree_draw(cf->edt->tree);
1885
1886     /* The user is searching for a string in the data or a hex value,
1887      * highlight the field that is found in the tree and hex displays. */
1888 #if GTK_MAJOR_VERSION < 2
1889     if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1890             highlight_field(cf->edt->tvb, cfile.search_pos,
1891                                     (GtkCTree *)tree_view, cf->edt->tree);
1892 #else
1893     if((cfile.string || cfile.hex) && cfile.search_pos != 0) {
1894             highlight_field(cf->edt->tvb, cfile.search_pos,
1895                                     (GtkTreeView *)tree_view, cf->edt->tree);
1896 #endif
1897                     cfile.search_pos = 0; /* Reset the position */
1898     }
1899
1900     /* A packet is selected. */
1901     set_menus_for_selected_packet(cf);
1902 }
1903
1904 static void
1905 main_cf_cb_packet_unselected(capture_file *cf)
1906 {
1907     /* Clear out the display of that packet. */
1908     clear_tree_and_hex_views();
1909
1910     /* No packet is selected. */
1911     set_menus_for_selected_packet(cf);
1912 }
1913
1914 static void
1915 main_cf_cb_field_unselected(capture_file *cf)
1916 {
1917     statusbar_pop_field_msg();
1918     set_menus_for_selected_tree_row(cf);
1919 }
1920
1921 static void
1922 main_cf_cb_file_safe_started(gchar * filename)
1923 {
1924     const gchar  *name_ptr;
1925     gchar        *save_msg;
1926
1927     name_ptr = get_basename(filename);
1928
1929     save_msg = g_strdup_printf(" Saving: %s...", name_ptr);
1930
1931     statusbar_push_file_msg(save_msg);
1932     g_free(save_msg);
1933 }
1934
1935 static void
1936 main_cf_cb_file_safe_finished(gpointer data _U_)
1937 {
1938     /* Pop the "Saving:" message off the status bar. */
1939     statusbar_pop_file_msg();
1940 }
1941
1942 static void
1943 main_cf_cb_file_safe_failed(gpointer data _U_)
1944 {
1945     /* Pop the "Saving:" message off the status bar. */
1946     statusbar_pop_file_msg();
1947 }
1948
1949 static void
1950 main_cf_cb_file_safe_reload_finished(gpointer data _U_)
1951 {
1952     set_menus_for_capture_file(&cfile);
1953 }
1954
1955 static void main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1956 {
1957     switch(event) {
1958     case(cf_cb_file_closing):
1959         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1960         main_cf_cb_file_closing(data);
1961         break;
1962     case(cf_cb_file_closed):
1963         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1964         main_cf_cb_file_closed(data);
1965         break;
1966     case(cf_cb_file_read_start):
1967         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read start");
1968         main_cf_cb_file_read_start(data);
1969         break;
1970     case(cf_cb_file_read_finished):
1971         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1972         main_cf_cb_file_read_finished(data);
1973         break;
1974 #ifdef HAVE_LIBPCAP
1975     case(cf_cb_live_capture_prepared):
1976         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1977         main_cf_cb_live_capture_prepared(data);
1978         break;
1979     case(cf_cb_live_capture_update_started):
1980         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1981         main_cf_cb_live_capture_update_started(data);
1982         break;
1983     case(cf_cb_live_capture_update_continue):
1984         /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1985         main_cf_cb_live_capture_update_continue(data);
1986         break;
1987     case(cf_cb_live_capture_update_finished):
1988         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1989         main_cf_cb_live_capture_update_finished(data);
1990         break;
1991     case(cf_cb_live_capture_fixed_started):
1992         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1993         main_cf_cb_live_capture_fixed_started(data);
1994         break;
1995     case(cf_cb_live_capture_fixed_continue):
1996         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");
1997         main_cf_cb_live_capture_fixed_continue(data);
1998         break;
1999     case(cf_cb_live_capture_fixed_finished):
2000         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
2001         main_cf_cb_live_capture_fixed_finished(data);
2002         break;
2003     case(cf_cb_live_capture_stopping):
2004         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
2005         main_cf_cb_live_capture_stopping(data);
2006         break;
2007 #endif
2008     case(cf_cb_packet_selected):
2009         main_cf_cb_packet_selected(data);
2010         break;
2011     case(cf_cb_packet_unselected):
2012         main_cf_cb_packet_unselected(data);
2013         break;
2014     case(cf_cb_field_unselected):
2015         main_cf_cb_field_unselected(data);
2016         break;
2017     case(cf_cb_file_safe_started):
2018         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe started");
2019         main_cf_cb_file_safe_started(data);
2020         break;
2021     case(cf_cb_file_safe_finished):
2022         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe finished");
2023         main_cf_cb_file_safe_finished(data);
2024         break;
2025     case(cf_cb_file_safe_reload_finished):
2026         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: reload finished");
2027         main_cf_cb_file_safe_reload_finished(data);
2028         break;
2029     case(cf_cb_file_safe_failed):
2030         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: safe failed");
2031         main_cf_cb_file_safe_failed(data);
2032         break;
2033     default:
2034         g_warning("main_cf_callback: event %u unknown", event);
2035         g_assert_not_reached();
2036     }
2037 }
2038
2039 static void
2040 get_gui_compiled_info(GString *str)
2041 {
2042   get_epan_compiled_version_info(str);
2043
2044   g_string_append(str, ", ");
2045 #ifdef HAVE_LIBPORTAUDIO
2046 #ifdef PORTAUDIO_API_1
2047   g_string_append(str, "with PortAudio <= V18");
2048 #else /* PORTAUDIO_API_1 */
2049   g_string_append(str, "with PortAudio ");
2050   g_string_append(str, Pa_GetVersionText());
2051 #endif /* PORTAUDIO_API_1 */
2052 #else /* HAVE_LIBPORTAUDIO */
2053   g_string_append(str, "without PortAudio");
2054 #endif /* HAVE_LIBPORTAUDIO */
2055
2056   g_string_append(str, ", ");
2057 #ifdef HAVE_AIRPCAP
2058   get_compiled_airpcap_version(str);
2059 #else
2060   g_string_append(str, "without AirPcap");
2061 #endif
2062 }
2063
2064 static void
2065 get_gui_runtime_info(GString *str
2066 #ifndef HAVE_AIRPCAP
2067         _U_
2068 #endif
2069 )
2070 {
2071 #ifdef HAVE_AIRPCAP
2072   g_string_append(str, ", ");
2073   get_runtime_airpcap_version(str);
2074 #endif
2075
2076   if(u3_active()) {
2077     g_string_append(str, ", ");
2078     u3_runtime_info(str);
2079   }
2080
2081 }
2082
2083 /* And now our feature presentation... [ fade to music ] */
2084 int
2085 main(int argc, char *argv[])
2086 {
2087   char                *init_progfile_dir_error;
2088   char                *s;
2089   int                  i;
2090   int                  opt;
2091   extern char         *optarg;
2092   gboolean             arg_error = FALSE;
2093
2094 #ifdef _WIN32
2095   WSADATA              wsaData;
2096 #endif  /* _WIN32 */
2097
2098   char                *rf_path;
2099   int                  rf_open_errno;
2100   char                *gpf_path, *pf_path;
2101   char                *cf_path, *df_path;
2102   char                *gdp_path, *dp_path;
2103   int                  gpf_open_errno, gpf_read_errno;
2104   int                  pf_open_errno, pf_read_errno;
2105   int                  cf_open_errno, df_open_errno;
2106   int                  gdp_open_errno, gdp_read_errno;
2107   int                  dp_open_errno, dp_read_errno;
2108   int                  err;
2109 #ifdef HAVE_LIBPCAP
2110   gboolean             start_capture = FALSE;
2111 #else
2112   gboolean             capture_option_specified = FALSE;
2113 #endif
2114   gint                 pl_size = 280, tv_size = 95, bv_size = 75;
2115   gchar               *rc_file, *cf_name = NULL, *rfilter = NULL;
2116   dfilter_t           *rfcode = NULL;
2117   gboolean             rfilter_parse_failed = FALSE;
2118   e_prefs             *prefs;
2119   char                 badopt;
2120   GtkWidget           *splash_win = NULL;
2121   GLogLevelFlags       log_flags;
2122   guint                go_to_packet = 0;
2123   int                  optind_initial;
2124   int                  status;
2125
2126 #ifdef HAVE_AIRPCAP
2127   char                  *err_str;
2128   /*gchar                       *cant_get_if_list_errstr;*/
2129 #endif
2130
2131 #define OPTSTRING_INIT "a:b:c:Df:g:Hhi:klLm:nN:o:P:pQr:R:Ss:t:vw:X:y:z:"
2132
2133 #if defined HAVE_LIBPCAP && defined _WIN32
2134 #define OPTSTRING_WIN32 "B:"
2135 #else
2136 #define OPTSTRING_WIN32 ""
2137 #endif
2138
2139   char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_WIN32) - 1] =
2140     OPTSTRING_INIT OPTSTRING_WIN32;
2141
2142 #ifdef  HAVE_AIRPDCAP
2143         /*      Davide Schiera (2006-11-18): init AirPDcap context                                                              */
2144         AirPDcapInitContext(&airpdcap_ctx);
2145         /* Davide Schiera (2006-11-18) -------------------------------------------      */
2146 #endif
2147
2148   /*
2149    * Attempt to get the pathname of the executable file.
2150    */
2151   init_progfile_dir_error = init_progfile_dir(argv[0]);
2152
2153   /*
2154    * Get credential information for later use.
2155    */
2156   get_credential_info();
2157
2158   /*
2159    * Now attempt to get the pathname of the plugins.
2160    */
2161   init_plugin_dir();
2162
2163   /* initialize the funnel mini-api */
2164   initialize_funnel_ops();
2165
2166 #ifdef _WIN32
2167   /* Load wpcap if possible. Do this before collecting the run-time version information */
2168   load_wpcap();
2169
2170   /* ... and also load the packet.dll from wpcap */
2171   wpcap_packet_load();
2172
2173 #ifdef HAVE_AIRPCAP
2174   /* Load the airpcap.dll.  This must also be done before collecting
2175    * run-time version information. */
2176   airpcap_dll_ret_val = load_airpcap();
2177
2178   switch (airpcap_dll_ret_val) {
2179   case AIRPCAP_DLL_OK:
2180     /* load the airpcap interfaces */
2181     airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2182
2183     if (airpcap_if_list == NULL && err == CANT_GET_AIRPCAP_INTERFACE_LIST) {
2184       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_str);
2185       g_free(err_str);
2186     }
2187     /* select the first ad default (THIS SHOULD BE CHANGED) */
2188     airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2189     break;
2190
2191 #if 0
2192     /*
2193      * XXX - Maybe we need to warn the user if one of the following happens???
2194      */
2195     case AIRPCAP_DLL_OLD:
2196       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2197       break;
2198
2199     case AIRPCAP_DLL_ERROR:
2200       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2201       break;
2202
2203     case AIRPCAP_DLL_NOT_FOUND:
2204       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2205       break;
2206 #endif
2207   }
2208 #endif /* HAVE_AIRPCAP */
2209
2210   /* Start windows sockets */
2211   WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2212 #endif  /* _WIN32 */
2213
2214   /* Assemble the compile-time version information string */
2215   comp_info_str = g_string_new("Compiled ");
2216
2217   g_string_append(comp_info_str, "with ");
2218   g_string_sprintfa(comp_info_str,
2219 #ifdef GTK_MAJOR_VERSION
2220                     "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
2221                     GTK_MICRO_VERSION);
2222 #else
2223                     "GTK+ (version unknown)");
2224 #endif
2225   g_string_append(comp_info_str, ", ");
2226
2227   get_compiled_version_info(comp_info_str, get_gui_compiled_info);
2228
2229   /* Assemble the run-time version information string */
2230   runtime_info_str = g_string_new("Running ");
2231   get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2232
2233
2234   /* "pre-scan" the command line parameters, if we have "console only"
2235      parameters.  We do this so we don't start GTK+ if we're only showing
2236      command-line help or version information.
2237
2238      XXX - this pre-scan is doen before we start GTK+, so we haven't
2239      run gtk_init() on the arguments.  That means that GTK+ arguments
2240      have not been removed from the argument list; those arguments
2241      begin with "--", and will be treated as an error by getopt().
2242
2243      We thus ignore errors - *and* set "opterr" to 0 to suppress the
2244      error messages. */
2245   opterr = 0;
2246   optind_initial = optind;
2247   while ((opt = getopt(argc, argv, optstring)) != -1) {
2248     switch (opt) {
2249       case 'h':        /* Print help and exit */
2250         print_usage(TRUE);
2251         exit(0);
2252         break;
2253       case 'P':        /* Path settings - change these before the Preferences and alike are processed */
2254         status = filesystem_opt(opt, optarg);
2255         if(status != 0) {
2256             cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2257             exit(status);
2258         }
2259         break;
2260       case 'v':        /* Show version and exit */
2261         show_version();
2262         exit(0);
2263         break;
2264       case 'X':
2265         /*
2266          *  Extension command line options have to be processed before
2267          *  we call epan_init() as they are supposed to be used by dissectors
2268          *  or taps very early in the registration process.
2269          */
2270         ex_opt_add(optarg);
2271         break;
2272       case '?':        /* Ignore errors - the "real" scan will catch them. */
2273         break;
2274     }
2275   }
2276
2277   /* Init the "Open file" dialog directory */
2278   /* (do this after the path settings are processed) */
2279   set_last_open_dir(get_persdatafile_dir());
2280
2281   /* Set getopt index back to initial value, so it will start with the
2282      first command line parameter again.  Also reset opterr to 1, so that
2283      error messages are printed by getopt().
2284
2285      XXX - this seems to work on most platforms, but time will tell.
2286      The Single UNIX Specification says "The getopt() function need
2287      not be reentrant", so this isn't guaranteed to work.  The Mac
2288      OS X 10.4[.x] getopt() man page says
2289
2290        In order to use getopt() to evaluate multiple sets of arguments, or to
2291        evaluate a single set of arguments multiple times, the variable optreset
2292        must be set to 1 before the second and each additional set of calls to
2293        getopt(), and the variable optind must be reinitialized.
2294
2295            ...
2296
2297        The optreset variable was added to make it possible to call the getopt()
2298        function multiple times.  This is an extension to the IEEE Std 1003.2
2299        (``POSIX.2'') specification.
2300
2301      which I think comes from one of the other BSDs.
2302
2303      XXX - if we want to control all the command-line option errors, so
2304      that we can display them where we choose (e.g., in a window), we'd
2305      want to leave opterr as 0, and produce our own messages using optopt.
2306      We'd have to check the value of optopt to see if it's a valid option
2307      letter, in which case *presumably* the error is "this option requires
2308      an argument but none was specified", or not a valid option letter,
2309      in which case *presumably* the error is "this option isn't valid".
2310      Some versions of getopt() let you supply a option string beginning
2311      with ':', which means that getopt() will return ':' rather than '?'
2312      for "this option requires an argument but none was specified", but
2313      not all do. */
2314   optind = optind_initial;
2315   opterr = 1;
2316
2317   /* Set the current locale according to the program environment.
2318    * We haven't localized anything, but some GTK widgets are localized
2319    * (the file selection dialogue, for example).
2320    * This also sets the C-language locale to the native environment. */
2321   gtk_set_locale();
2322
2323   /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2324   gtk_init (&argc, &argv);
2325
2326   cf_callback_add(main_cf_callback, NULL);
2327
2328 #if GTK_MAJOR_VERSION < 2 && GTK_MINOR_VERSION < 3
2329   /* initialize our GTK eth_clist_type */
2330   init_eth_clist_type();
2331 #endif
2332
2333   /* Arrange that if we have no console window, and a GLib message logging
2334      routine is called to log a message, we pop up a console window.
2335
2336      We do that by inserting our own handler for all messages logged
2337      to the default domain; that handler pops up a console if necessary,
2338      and then calls the default handler. */
2339
2340   /* We might want to have component specific log levels later ... */
2341
2342   log_flags =
2343                     G_LOG_LEVEL_ERROR|
2344                     G_LOG_LEVEL_CRITICAL|
2345                     G_LOG_LEVEL_WARNING|
2346                     G_LOG_LEVEL_MESSAGE|
2347                     G_LOG_LEVEL_INFO|
2348                     G_LOG_LEVEL_DEBUG|
2349                     G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2350
2351   g_log_set_handler(NULL,
2352                     log_flags,
2353                     console_log_handler, NULL /* user_data */);
2354   g_log_set_handler(LOG_DOMAIN_MAIN,
2355                     log_flags,
2356                     console_log_handler, NULL /* user_data */);
2357
2358 #ifdef HAVE_LIBPCAP
2359   g_log_set_handler(LOG_DOMAIN_CAPTURE,
2360                     log_flags,
2361                     console_log_handler, NULL /* user_data */);
2362   g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2363                     log_flags,
2364                     console_log_handler, NULL /* user_data */);
2365
2366   /* Set the initial values in the capture_opts. This might be overwritten
2367      by preference settings and then again by the command line parameters. */
2368   capture_opts_init(capture_opts, &cfile);
2369
2370   capture_opts->snaplen             = MIN_PACKET_SIZE;
2371   capture_opts->has_ring_num_files  = TRUE;
2372 #endif
2373
2374   /* We won't come till here, if we had a "console only" command line parameter. */
2375   splash_win = splash_new("Loading Wireshark ...");
2376   if (init_progfile_dir_error != NULL) {
2377     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2378         "Can't get pathname of Wireshark: %s.\n"
2379         "It won't be possible to capture traffic.\n"
2380         "Report this to the Wireshark developers.",
2381         init_progfile_dir_error);
2382     g_free(init_progfile_dir_error);
2383   }
2384
2385   splash_update(splash_win, "Init dissectors ...");
2386
2387   /* Register all dissectors; we must do this before checking for the
2388      "-G" flag, as the "-G" flag dumps information registered by the
2389      dissectors, and we must do it before we read the preferences, in
2390      case any dissectors register preferences. */
2391   epan_init(register_all_protocols,register_all_protocol_handoffs,
2392             failure_alert_box,open_failure_alert_box,read_failure_alert_box);
2393
2394   splash_update(splash_win, "Init tap listeners ...");
2395
2396   /* Register all tap listeners; we do this before we parse the arguments,
2397      as the "-z" argument can specify a registered tap. */
2398
2399   /* we register the plugin taps before the other taps because
2400           stats_tree taps plugins will be registered as tap listeners
2401           by stats_tree_stat.c and need to registered before that */
2402
2403 #ifdef HAVE_PLUGINS
2404   register_all_plugin_tap_listeners();
2405 #endif
2406
2407   register_all_tap_listeners();
2408
2409   splash_update(splash_win, "Loading module preferences ...");
2410
2411   /* Now register the preferences for any non-dissector modules.
2412      We must do that before we read the preferences as well. */
2413   prefs_register_modules();
2414
2415   /* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
2416 #if !defined(_WIN32) && GTK_MAJOR_VERSION >= 2 && defined(G_THREADS_ENABLED) && defined USE_THREADS
2417   {
2418       GThread *ut;
2419       g_thread_init(NULL);
2420       gdk_threads_init();
2421       ut=g_thread_create(update_thread, NULL, FALSE, NULL);
2422       g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
2423   }
2424 #else  /* _WIN32 || GTK1.2 || !G_THREADS_ENABLED || !USE_THREADS */
2425   /* this is to keep tap extensions updating once every 3 seconds */
2426   gtk_timeout_add(3000, (GtkFunction)update_cb,(gpointer)NULL);
2427 #endif /* !_WIN32 && GTK2 && G_THREADS_ENABLED */
2428
2429 #if HAVE_GNU_ADNS
2430   gtk_timeout_add(750, (GtkFunction) host_name_lookup_process, NULL);
2431 #endif
2432
2433   splash_update(splash_win, "Loading configuration files ...");
2434
2435   /* Read the preference files. */
2436   prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2437                      &pf_open_errno, &pf_read_errno, &pf_path);
2438
2439   if (gpf_path != NULL) {
2440     if (gpf_open_errno != 0) {
2441       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2442         "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2443         strerror(gpf_open_errno));
2444     }
2445     if (gpf_read_errno != 0) {
2446       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2447         "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2448         strerror(gpf_read_errno));
2449     }
2450   }
2451   if (pf_path != NULL) {
2452     if (pf_open_errno != 0) {
2453       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2454         "Could not open your preferences file\n\"%s\": %s.", pf_path,
2455         strerror(pf_open_errno));
2456     }
2457     if (pf_read_errno != 0) {
2458       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2459         "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2460         strerror(pf_read_errno));
2461     }
2462     g_free(pf_path);
2463     pf_path = NULL;
2464   }
2465
2466 #ifdef _WIN32
2467   /* if the user wants a console to be always there, well, we should open one for him */
2468   if (prefs->gui_console_open == console_open_always) {
2469     create_console();
2470   }
2471 #endif
2472
2473   /* Fill in capture options with values from the preferences */
2474   prefs_to_capture_opts();
2475
2476   /* Read the capture filter file. */
2477   read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2478   if (cf_path != NULL) {
2479       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2480         "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2481         strerror(cf_open_errno));
2482       g_free(cf_path);
2483   }
2484
2485   /* Read the display filter file. */
2486   read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2487   if (df_path != NULL) {
2488       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2489         "Could not open your display filter file\n\"%s\": %s.", df_path,
2490         strerror(df_open_errno));
2491       g_free(df_path);
2492   }
2493
2494   /* Read the disabled protocols file. */
2495   read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
2496                             &dp_path, &dp_open_errno, &dp_read_errno);
2497   if (gdp_path != NULL) {
2498     if (gdp_open_errno != 0) {
2499       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2500         "Could not open global disabled protocols file\n\"%s\": %s.",
2501         gdp_path, strerror(gdp_open_errno));
2502     }
2503     if (gdp_read_errno != 0) {
2504       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2505         "I/O error reading global disabled protocols file\n\"%s\": %s.",
2506         gdp_path, strerror(gdp_read_errno));
2507     }
2508     g_free(gdp_path);
2509   }
2510   if (dp_path != NULL) {
2511     if (dp_open_errno != 0) {
2512       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2513         "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
2514         strerror(dp_open_errno));
2515     }
2516     if (dp_read_errno != 0) {
2517       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2518         "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
2519         strerror(dp_read_errno));
2520     }
2521     g_free(dp_path);
2522   }
2523
2524   /* Read the (static part) of the recent file. Only the static part of it will be read, */
2525   /* as we don't have the gui now to fill the recent lists which is done in the dynamic part. */
2526   /* We have to do this already here, so command line parameters can overwrite these values. */
2527   recent_read_static(&rf_path, &rf_open_errno);
2528
2529   init_cap_file(&cfile);
2530
2531   /* Now get our args */
2532   while ((opt = getopt(argc, argv, optstring)) != -1) {
2533     switch (opt) {
2534       /*** capture option specific ***/
2535       case 'a':        /* autostop criteria */
2536       case 'b':        /* Ringbuffer option */
2537       case 'c':        /* Capture xxx packets */
2538       case 'f':        /* capture filter */
2539       case 'k':        /* Start capture immediately */
2540       case 'H':        /* Hide capture info dialog box */
2541       case 'i':        /* Use interface xxx */
2542       case 'p':        /* Don't capture in promiscuous mode */
2543       case 'Q':        /* Quit after capture (just capture to file) */
2544       case 's':        /* Set the snapshot (capture) length */
2545       case 'S':        /* "Sync" mode: used for following file ala tail -f */
2546       case 'w':        /* Write to capture file xxx */
2547       case 'y':        /* Set the pcap data link type */
2548 #ifdef _WIN32
2549       case 'B':        /* Buffer size */
2550 #endif /* _WIN32 */
2551 #ifdef HAVE_LIBPCAP
2552         status = capture_opts_add_opt(capture_opts, opt, optarg, &start_capture);
2553         if(status != 0) {
2554             exit(status);
2555         }
2556 #else
2557         capture_option_specified = TRUE;
2558         arg_error = TRUE;
2559 #endif
2560         break;
2561
2562       /*** all non capture option specific ***/
2563       case 'D':        /* Print a list of capture devices and exit */
2564 #ifdef HAVE_LIBPCAP
2565         capture_opts_list_interfaces();
2566         exit(0);
2567 #else
2568         capture_option_specified = TRUE;
2569         arg_error = TRUE;
2570 #endif
2571         break;
2572       case 'g':        /* Go to packet */
2573         go_to_packet = get_positive_int(optarg, "go to packet");
2574         break;
2575       case 'l':        /* Automatic scrolling in live capture mode */
2576 #ifdef HAVE_LIBPCAP
2577         auto_scroll_live = TRUE;
2578 #else
2579         capture_option_specified = TRUE;
2580         arg_error = TRUE;
2581 #endif
2582         break;
2583       case 'L':        /* Print list of link-layer types and exit */
2584 #ifdef HAVE_LIBPCAP
2585         list_link_layer_types = TRUE;
2586 #else
2587         capture_option_specified = TRUE;
2588         arg_error = TRUE;
2589 #endif
2590         break;
2591       case 'm':        /* Fixed-width font for the display */
2592         if (prefs->PREFS_GUI_FONT_NAME != NULL)
2593           g_free(prefs->PREFS_GUI_FONT_NAME);
2594         prefs->PREFS_GUI_FONT_NAME = g_strdup(optarg);
2595         break;
2596       case 'n':        /* No name resolution */
2597         g_resolv_flags = RESOLV_NONE;
2598         break;
2599       case 'N':        /* Select what types of addresses/port #s to resolve */
2600         if (g_resolv_flags == RESOLV_ALL)
2601           g_resolv_flags = RESOLV_NONE;
2602         badopt = string_to_name_resolve(optarg, &g_resolv_flags);
2603         if (badopt != '\0') {
2604           cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2605                         badopt);
2606           exit(1);
2607         }
2608         break;
2609       case 'o':        /* Override preference from command line */
2610         switch (prefs_set_pref(optarg)) {
2611         case PREFS_SET_OK:
2612           break;
2613         case PREFS_SET_SYNTAX_ERR:
2614           cmdarg_err("Invalid -o flag \"%s\"", optarg);
2615           exit(1);
2616           break;
2617         case PREFS_SET_NO_SUCH_PREF:
2618           /* not a preference, might be a recent setting */
2619           switch (recent_set_arg(optarg)) {
2620             case PREFS_SET_OK:
2621               break;
2622             case PREFS_SET_SYNTAX_ERR:
2623               /* shouldn't happen, checked already above */
2624               cmdarg_err("Invalid -o flag \"%s\"", optarg);
2625               exit(1);
2626               break;
2627             case PREFS_SET_NO_SUCH_PREF:
2628             case PREFS_SET_OBSOLETE:
2629               cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2630                     optarg);
2631               exit(1);
2632               break;
2633             default:
2634               g_assert_not_reached();
2635             }
2636           break;
2637         case PREFS_SET_OBSOLETE:
2638           cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2639                         optarg);
2640           exit(1);
2641           break;
2642         default:
2643           g_assert_not_reached();
2644         }
2645         break;
2646       case 'P':
2647         /* Path settings were already processed just ignore them this time*/
2648                 break;
2649       case 'r':        /* Read capture file xxx */
2650         /* We may set "last_open_dir" to "cf_name", and if we change
2651            "last_open_dir" later, we free the old value, so we have to
2652            set "cf_name" to something that's been allocated. */
2653 #if defined _WIN32 && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
2654         /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2655         cf_name = g_locale_to_utf8(optarg, -1, NULL, NULL, NULL);
2656 #else
2657         cf_name = g_strdup(optarg);
2658 #endif
2659         break;
2660       case 'R':        /* Read file filter */
2661         rfilter = optarg;
2662         break;
2663       case 't':        /* Time stamp type */
2664         if (strcmp(optarg, "r") == 0)
2665           timestamp_set_type(TS_RELATIVE);
2666         else if (strcmp(optarg, "a") == 0)
2667           timestamp_set_type(TS_ABSOLUTE);
2668         else if (strcmp(optarg, "ad") == 0)
2669           timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2670         else if (strcmp(optarg, "d") == 0)
2671           timestamp_set_type(TS_DELTA);
2672         else if (strcmp(optarg, "e") == 0)
2673           timestamp_set_type(TS_EPOCH);
2674         else {
2675           cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2676           cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2677           cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2678           exit(1);
2679         }
2680         break;
2681       case 'X':
2682           /* ext ops were already processed just ignore them this time*/
2683           break;
2684       case 'z':
2685         /* We won't call the init function for the stat this soon
2686            as it would disallow MATE's fields (which are registered
2687            by the preferences set callback) from being used as
2688            part of a tap filter.  Instead, we just add the argument
2689            to a list of stat arguments. */
2690         if (!process_stat_cmd_arg(optarg)) {
2691           cmdarg_err("Invalid -z argument.");
2692           cmdarg_err_cont("  -z argument must be one of :");
2693           list_stat_cmd_args();
2694           exit(1);
2695         }
2696         break;
2697       default:
2698       case '?':        /* Bad flag - print usage message */
2699         arg_error = TRUE;
2700         break;
2701     }
2702   }
2703   argc -= optind;
2704   argv += optind;
2705   if (argc >= 1) {
2706     if (cf_name != NULL) {
2707       /*
2708        * Input file name specified with "-r" *and* specified as a regular
2709        * command-line argument.
2710        */
2711       cmdarg_err("File name specified both with -r and regular argument");
2712       arg_error = TRUE;
2713     } else {
2714       /*
2715        * Input file name not specified with "-r", and a command-line argument
2716        * was specified; treat it as the input file name.
2717        *
2718        * Yes, this is different from tshark, where non-flag command-line
2719        * arguments are a filter, but this works better on GUI desktops
2720        * where a command can be specified to be run to open a particular
2721        * file - yes, you could have "-r" as the last part of the command,
2722        * but that's a bit ugly.
2723        */
2724 #if defined _WIN32 && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
2725       /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
2726       cf_name = g_locale_to_utf8(argv[0], -1, NULL, NULL, NULL);
2727 #else
2728       cf_name = g_strdup(argv[0]);
2729 #endif
2730     }
2731     argc--;
2732     argv++;
2733   }
2734
2735
2736
2737   if (argc != 0) {
2738     /*
2739      * Extra command line arguments were specified; complain.
2740      */
2741     cmdarg_err("Invalid argument: %s", argv[0]);
2742     arg_error = TRUE;
2743   }
2744
2745   if (arg_error) {
2746 #ifndef HAVE_LIBPCAP
2747     if (capture_option_specified) {
2748       cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2749     }
2750 #endif
2751     print_usage(FALSE);
2752     exit(1);
2753   }
2754
2755 #ifdef HAVE_LIBPCAP
2756   if (start_capture && list_link_layer_types) {
2757     /* Specifying *both* is bogus. */
2758     cmdarg_err("You can't specify both -L and a live capture.");
2759     exit(1);
2760   }
2761
2762   if (list_link_layer_types) {
2763     /* We're supposed to list the link-layer types for an interface;
2764        did the user also specify a capture file to be read? */
2765     if (cf_name) {
2766       /* Yes - that's bogus. */
2767       cmdarg_err("You can't specify -L and a capture file to be read.");
2768       exit(1);
2769     }
2770     /* No - did they specify a ring buffer option? */
2771     if (capture_opts->multi_files_on) {
2772       cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2773       exit(1);
2774     }
2775   } else {
2776     /* We're supposed to do a live capture; did the user also specify
2777        a capture file to be read? */
2778     if (start_capture && cf_name) {
2779       /* Yes - that's bogus. */
2780       cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2781       exit(1);
2782     }
2783
2784     /* No - was the ring buffer option specified and, if so, does it make
2785        sense? */
2786     if (capture_opts->multi_files_on) {
2787       /* Ring buffer works only under certain conditions:
2788          a) ring buffer does not work with temporary files;
2789          b) real_time_mode and multi_files_on are mutually exclusive -
2790             real_time_mode takes precedence;
2791          c) it makes no sense to enable the ring buffer if the maximum
2792             file size is set to "infinite". */
2793       if (capture_opts->save_file == NULL) {
2794         cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2795         capture_opts->multi_files_on = FALSE;
2796       }
2797 /*      if (capture_opts->real_time_mode) {
2798         cmdarg_err("Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.");
2799         capture_opts->multi_files_on = FALSE;
2800       }*/
2801       if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) {
2802         cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2803 /* XXX - this must be redesigned as the conditions changed */
2804 /*      capture_opts->multi_files_on = FALSE;*/
2805       }
2806     }
2807   }
2808
2809   if (start_capture || list_link_layer_types) {
2810     /* Did the user specify an interface to use? */
2811     if (!capture_opts_trim_iface(capture_opts,
2812         (prefs->capture_device) ? get_if_name(prefs->capture_device) : NULL)) {
2813         exit(2);
2814     }
2815   }
2816
2817   if (list_link_layer_types) {
2818     status = capture_opts_list_link_layer_types(capture_opts);
2819     exit(status);
2820   }
2821
2822   capture_opts_trim_snaplen(capture_opts, MIN_PACKET_SIZE);
2823   capture_opts_trim_ring_num_files(capture_opts);
2824 #endif /* HAVE_LIBPCAP */
2825
2826   /* Notify all registered modules that have had any of their preferences
2827      changed either from one of the preferences file or from the command
2828      line that their preferences have changed. */
2829   prefs_apply_all();
2830
2831   /* disabled protocols as per configuration file */
2832   if (gdp_path == NULL && dp_path == NULL) {
2833     set_disabled_protos_list();
2834   }
2835
2836   /* Build the column format array */
2837   col_setup(&cfile.cinfo, prefs->num_cols);
2838   for (i = 0; i < cfile.cinfo.num_cols; i++) {
2839     cfile.cinfo.col_fmt[i] = get_column_format(i);
2840     cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
2841     cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
2842       NUM_COL_FMTS);
2843     get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
2844     cfile.cinfo.col_data[i] = NULL;
2845     if (cfile.cinfo.col_fmt[i] == COL_INFO)
2846       cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
2847     else
2848       cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2849     cfile.cinfo.col_fence[i] = 0;
2850     cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2851     cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
2852   }
2853
2854   for (i = 0; i < cfile.cinfo.num_cols; i++) {
2855       int j;
2856
2857       for (j = 0; j < NUM_COL_FMTS; j++) {
2858          if (!cfile.cinfo.fmt_matx[i][j])
2859              continue;
2860
2861          if (cfile.cinfo.col_first[j] == -1)
2862              cfile.cinfo.col_first[j] = i;
2863          cfile.cinfo.col_last[j] = i;
2864       }
2865   }
2866
2867   /* read in rc file from global and personal configuration paths. */
2868   rc_file = get_datafile_path(RC_FILE);
2869   gtk_rc_parse(rc_file);
2870   rc_file = get_persconffile_path(RC_FILE, FALSE);
2871   gtk_rc_parse(rc_file);
2872
2873   font_init();
2874
2875   /* close the splash screen, as we are going to open the main window now */
2876   splash_destroy(splash_win);
2877
2878   /************************************************************************/
2879   /* Everything is prepared now, preferences and command line was read in */
2880
2881   /* Pop up the main window. */
2882   create_main_window(pl_size, tv_size, bv_size, prefs);
2883
2884   /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2885   recent_read_dynamic(&rf_path, &rf_open_errno);
2886   color_filters_enable(recent.packet_list_colorize);
2887
2888   /* rearrange all the widgets as we now have all recent settings ready for this */
2889   main_widgets_rearrange();
2890
2891   /* Fill in column titles.  This must be done after the top level window
2892      is displayed.
2893
2894      XXX - is that still true, with fixed-width columns? */
2895   packet_list_set_column_titles();
2896
2897   menu_recent_read_finished();
2898
2899   switch (user_font_apply()) {
2900   case FA_SUCCESS:
2901       break;
2902   case FA_FONT_NOT_RESIZEABLE:
2903       /* "user_font_apply()" popped up an alert box. */
2904       /* turn off zooming - font can't be resized */
2905   case FA_FONT_NOT_AVAILABLE:
2906       /* XXX - did we successfully load the un-zoomed version earlier?
2907       If so, this *probably* means the font is available, but not at
2908       this particular zoom level, but perhaps some other failure
2909       occurred; I'm not sure you can determine which is the case,
2910       however. */
2911       /* turn off zooming - zoom level is unavailable */
2912   default:
2913       /* in any other case than FA_SUCCESS, turn off zooming */
2914       recent.gui_zoom_level = 0;
2915       /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
2916   }
2917
2918   dnd_init(top_level);
2919
2920   colors_init();
2921   color_filters_init();
2922   decode_as_init();
2923
2924   /* the window can be sized only, if it's not already shown, so do it now! */
2925   main_load_window_geometry(top_level);
2926
2927   /* If we were given the name of a capture file, read it in now;
2928      we defer it until now, so that, if we can't open it, and pop
2929      up an alert box, the alert box is more likely to come up on
2930      top of the main window - but before the preference-file-error
2931      alert box, so, if we get one of those, it's more likely to come
2932      up on top of us. */
2933   if (cf_name) {
2934     show_main_window(TRUE);
2935     if (rfilter != NULL) {
2936       if (!dfilter_compile(rfilter, &rfcode)) {
2937         bad_dfilter_alert_box(rfilter);
2938         rfilter_parse_failed = TRUE;
2939       }
2940     }
2941     if (!rfilter_parse_failed) {
2942       if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
2943         /* "cf_open()" succeeded, so it closed the previous
2944            capture file, and thus destroyed any previous read filter
2945            attached to "cf". */
2946
2947         cfile.rfcode = rfcode;
2948         /* Open stat windows; we do so after creating the main window,
2949            to avoid GTK warnings, and after successfully opening the
2950            capture file, so we know we have something to compute stats
2951            on, and after registering all dissectors, so that MATE will
2952            have registered its field array and we can have a tap filter
2953            with one of MATE's late-registered fields as part of the
2954            filter. */
2955         start_requested_stats();
2956
2957         /* Read the capture file. */
2958         switch (cf_read(&cfile)) {
2959
2960         case CF_READ_OK:
2961         case CF_READ_ERROR:
2962           /* Just because we got an error, that doesn't mean we were unable
2963              to read any of the file; we handle what we could get from the
2964              file. */
2965           /* if the user told us to jump to a specific packet, do it now */
2966           if(go_to_packet != 0) {
2967             cf_goto_frame(&cfile, go_to_packet);
2968           }
2969           break;
2970
2971         case CF_READ_ABORTED:
2972           /* Exit now. */
2973           gtk_exit(0);
2974           break;
2975         }
2976         /* Save the name of the containing directory specified in the
2977            path name, if any; we can write over cf_name, which is a
2978            good thing, given that "get_dirname()" does write over its
2979            argument. */
2980         s = get_dirname(cf_name);
2981         set_last_open_dir(s);
2982         g_free(cf_name);
2983         cf_name = NULL;
2984       } else {
2985         if (rfcode != NULL)
2986           dfilter_free(rfcode);
2987         cfile.rfcode = NULL;
2988     show_main_window(FALSE);
2989         set_menus_for_capture_in_progress(FALSE);
2990       }
2991     }
2992   } else {
2993 #ifdef HAVE_LIBPCAP
2994     if (start_capture) {
2995       if (capture_opts->save_file != NULL) {
2996         /* Save the directory name for future file dialogs. */
2997         /* (get_dirname overwrites filename) */
2998         s = get_dirname(g_strdup(capture_opts->save_file));
2999         set_last_open_dir(s);
3000         g_free(s);
3001       }
3002       /* "-k" was specified; start a capture. */
3003       show_main_window(TRUE);
3004       if (capture_start(capture_opts)) {
3005         /* The capture started.  Open stat windows; we do so after creating
3006            the main window, to avoid GTK warnings, and after successfully
3007            opening the capture file, so we know we have something to compute
3008            stats on, and after registering all dissectors, so that MATE will
3009            have registered its field array and we can have a tap filter with
3010            one of MATE's late-registered fields as part of the filter. */
3011         start_requested_stats();
3012       }
3013     }
3014     else {
3015       show_main_window(FALSE);
3016       set_menus_for_capture_in_progress(FALSE);
3017     }
3018
3019     /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
3020     if (!start_capture && strlen(capture_opts->cfilter) == 0) {
3021       g_free(capture_opts->cfilter);
3022       capture_opts->cfilter = g_strdup(get_conn_cfilter());
3023     }
3024 #else /* HAVE_LIBPCAP */
3025     show_main_window(FALSE);
3026     set_menus_for_capture_in_progress(FALSE);
3027 #endif /* HAVE_LIBPCAP */
3028   }
3029
3030   /* register our pid if we are being run from a U3 device */
3031   u3_register_pid();
3032
3033   /* we'll enter the GTK loop now and hand the control over to GTK ... */
3034   gtk_main();
3035   /* ... back from GTK, we're going down now! */
3036
3037   /* deregister our pid */
3038   u3_deregister_pid();
3039
3040   epan_cleanup();
3041   g_free(rc_file);
3042
3043 #ifdef  HAVE_AIRPDCAP
3044         /*      Davide Schiera (2006-11-18): destroy AirPDcap context                                                   */
3045         AirPDcapDestroyContext(&airpdcap_ctx);
3046         /* Davide Schiera (2006-11-18) -------------------------------------------      */
3047 #endif
3048
3049 #ifdef _WIN32
3050   /* hide the (unresponsive) main window, while asking the user to close the console window */
3051   gtk_widget_hide(top_level);
3052
3053   /* Shutdown windows sockets */
3054   WSACleanup();
3055
3056   /* For some unknown reason, the "atexit()" call in "create_console()"
3057      doesn't arrange that "destroy_console()" be called when we exit,
3058      so we call it here if a console was created. */
3059   destroy_console();
3060 #endif
3061
3062   gtk_exit(0);
3063
3064   /* This isn't reached, but we need it to keep GCC from complaining
3065      that "main()" returns without returning a value - it knows that
3066      "exit()" never returns, but it doesn't know that "gtk_exit()"
3067      doesn't, as GTK+ doesn't declare it with the attribute
3068      "noreturn". */
3069   return 0;     /* not reached */
3070 }
3071
3072 #ifdef _WIN32
3073
3074 /* We build this as a GUI subsystem application on Win32, so
3075    "WinMain()", not "main()", gets called.
3076
3077    Hack shamelessly stolen from the Win32 port of the GIMP. */
3078 #ifdef __GNUC__
3079 #define _stdcall  __attribute__((stdcall))
3080 #endif
3081
3082 int _stdcall
3083 WinMain (struct HINSTANCE__ *hInstance,
3084          struct HINSTANCE__ *hPrevInstance,
3085          char               *lpszCmdLine,
3086          int                 nCmdShow)
3087 {
3088 #if GTK_MAJOR_VERSION >= 2
3089   INITCOMMONCONTROLSEX comm_ctrl;
3090
3091   /* Initialize our controls. Required for native Windows file dialogs. */
3092   memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3093   comm_ctrl.dwSize = sizeof(comm_ctrl);
3094   /* Includes the animate, header, hot key, list view, progress bar,
3095    * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3096    * up-down controls
3097    */
3098   comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3099   InitCommonControlsEx(&comm_ctrl);
3100
3101   /* RichEd20.DLL is needed for filter entries. */
3102   LoadLibrary(_T("riched20.dll"));
3103 #endif /* GTK_MAJOR_VERSION >= 2 */
3104
3105   has_console = FALSE;
3106   return main (__argc, __argv);
3107 }
3108
3109 /*
3110  * If this application has no console window to which its standard output
3111  * would go, create one.
3112  */
3113 void
3114 create_console(void)
3115 {
3116   if (!has_console) {
3117     /* We have no console to which to print the version string, so
3118        create one and make it the standard input, output, and error. */
3119     if (!AllocConsole())
3120       return;   /* couldn't create console */
3121     eth_freopen("CONIN$", "r", stdin);
3122     eth_freopen("CONOUT$", "w", stdout);
3123     eth_freopen("CONOUT$", "w", stderr);
3124
3125     /* Well, we have a console now. */
3126     has_console = TRUE;
3127
3128     /* Now register "destroy_console()" as a routine to be called just
3129        before the application exits, so that we can destroy the console
3130        after the user has typed a key (so that the console doesn't just
3131        disappear out from under them, giving the user no chance to see
3132        the message(s) we put in there). */
3133     atexit(destroy_console);
3134
3135     SetConsoleTitle(_T("Wireshark Debug Console"));
3136   }
3137 }
3138
3139 static void
3140 destroy_console(void)
3141 {
3142   if (has_console) {
3143     printf("\n\nPress any key to exit\n");
3144     _getch();
3145     FreeConsole();
3146   }
3147 }
3148 #endif /* _WIN32 */
3149
3150
3151 /* This routine should not be necessary, at least as I read the GLib
3152    source code, as it looks as if GLib is, on Win32, *supposed* to
3153    create a console window into which to display its output.
3154
3155    That doesn't happen, however.  I suspect there's something completely
3156    broken about that code in GLib-for-Win32, and that it may be related
3157    to the breakage that forces us to just call "printf()" on the message
3158    rather than passing the message on to "g_log_default_handler()"
3159    (which is the routine that does the aforementioned non-functional
3160    console window creation). */
3161 static void
3162 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3163                     const char *message, gpointer user_data _U_)
3164 {
3165   time_t curr;
3166   struct tm *today;
3167   const char *level;
3168
3169
3170   /* ignore log message, if log_level isn't interesting.
3171      If preferences aren't loaded yet, display message anyway */
3172   if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3173      prefs.console_log_level != 0) {
3174     return;
3175   }
3176
3177   /* create a "timestamp" */
3178   time(&curr);
3179   today = localtime(&curr);
3180
3181 #ifdef _WIN32
3182   if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3183     /* the user wants a console or the application will terminate immediately */
3184     create_console();
3185   }
3186   if (has_console) {
3187     /* For some unknown reason, the above doesn't appear to actually cause
3188        anything to be sent to the standard output, so we'll just splat the
3189        message out directly, just to make sure it gets out. */
3190 #endif
3191     switch(log_level & G_LOG_LEVEL_MASK) {
3192     case G_LOG_LEVEL_ERROR:
3193         level = "Err ";
3194         break;
3195     case G_LOG_LEVEL_CRITICAL:
3196         level = "Crit";
3197         break;
3198     case G_LOG_LEVEL_WARNING:
3199         level = "Warn";
3200         break;
3201     case G_LOG_LEVEL_MESSAGE:
3202         level = "Msg ";
3203         break;
3204     case G_LOG_LEVEL_INFO:
3205         level = "Info";
3206         break;
3207     case G_LOG_LEVEL_DEBUG:
3208         level = "Dbg ";
3209         break;
3210     default:
3211         fprintf(stderr, "unknown log_level %u\n", log_level);
3212         level = NULL;
3213         g_assert_not_reached();
3214     }
3215
3216     fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3217             today->tm_hour, today->tm_min, today->tm_sec,
3218             log_domain != NULL ? log_domain : "",
3219             level, message);
3220 #ifdef _WIN32
3221     if(log_level & G_LOG_LEVEL_ERROR) {
3222         /* wait for a key press before the following error handler will terminate the program
3223            this way the user at least can read the error message */
3224         printf("\n\nPress any key to exit\n");
3225         _getch();
3226     }
3227   } else {
3228     g_log_default_handler(log_domain, log_level, message, user_data);
3229   }
3230 #endif
3231 }
3232
3233
3234 static GtkWidget *info_bar_new(void)
3235 {
3236     /* tip: tooltips don't work on statusbars! */
3237     info_bar = gtk_statusbar_new();
3238     main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
3239     file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");
3240     help_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "help");
3241 #if GTK_MAJOR_VERSION >= 2
3242     gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(info_bar), FALSE);
3243 #endif
3244     gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, DEF_READY_MESSAGE);
3245
3246     return info_bar;
3247 }
3248
3249 static GtkWidget *packets_bar_new(void)
3250 {
3251     /* tip: tooltips don't work on statusbars! */
3252     packets_bar = gtk_statusbar_new();
3253     packets_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(packets_bar), "packets");
3254     packets_bar_update();
3255
3256     return packets_bar;
3257 }
3258
3259
3260 /*
3261  * Helper for main_widgets_rearrange()
3262  */
3263 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3264     gtk_container_remove(GTK_CONTAINER(data), widget);
3265 }
3266
3267 static GtkWidget *main_widget_layout(gint layout_content)
3268 {
3269     switch(layout_content) {
3270     case(layout_pane_content_none):
3271         return NULL;
3272         break;
3273     case(layout_pane_content_plist):
3274         return pkt_scrollw;
3275         break;
3276     case(layout_pane_content_pdetails):
3277         return tv_scrollw;
3278         break;
3279     case(layout_pane_content_pbytes):
3280         return byte_nb_ptr;
3281         break;
3282     default:
3283         g_assert_not_reached();
3284         return NULL;
3285     }
3286 }
3287
3288
3289 /*
3290  * Rearrange the main window widgets
3291  */
3292 void main_widgets_rearrange(void) {
3293     GtkWidget *first_pane_widget1, *first_pane_widget2;
3294     GtkWidget *second_pane_widget1, *second_pane_widget2;
3295     gboolean split_top_left;
3296
3297     /* be a bit faster */
3298     gtk_widget_hide(main_vbox);
3299
3300     /* be sure, we don't loose a widget while rearranging */
3301     gtk_widget_ref(menubar);
3302     gtk_widget_ref(main_tb);
3303     gtk_widget_ref(filter_tb);
3304
3305 #ifdef HAVE_AIRPCAP
3306     gtk_widget_ref(airpcap_tb);
3307 #endif
3308
3309     gtk_widget_ref(pkt_scrollw);
3310     gtk_widget_ref(tv_scrollw);
3311     gtk_widget_ref(byte_nb_ptr);
3312     gtk_widget_ref(stat_hbox);
3313     gtk_widget_ref(info_bar);
3314     gtk_widget_ref(packets_bar);
3315     gtk_widget_ref(status_pane);
3316     gtk_widget_ref(main_pane_v1);
3317     gtk_widget_ref(main_pane_v2);
3318     gtk_widget_ref(main_pane_h1);
3319     gtk_widget_ref(main_pane_h2);
3320     gtk_widget_ref(welcome_pane);
3321
3322     /* empty all containers participating */
3323     gtk_container_foreach(GTK_CONTAINER(main_vbox),     foreach_remove_a_child, main_vbox);
3324     gtk_container_foreach(GTK_CONTAINER(stat_hbox),     foreach_remove_a_child, stat_hbox);
3325     gtk_container_foreach(GTK_CONTAINER(status_pane),   foreach_remove_a_child, status_pane);
3326     gtk_container_foreach(GTK_CONTAINER(main_pane_v1),  foreach_remove_a_child, main_pane_v1);
3327     gtk_container_foreach(GTK_CONTAINER(main_pane_v2),  foreach_remove_a_child, main_pane_v2);
3328     gtk_container_foreach(GTK_CONTAINER(main_pane_h1),  foreach_remove_a_child, main_pane_h1);
3329     gtk_container_foreach(GTK_CONTAINER(main_pane_h2),  foreach_remove_a_child, main_pane_h2);
3330
3331     /* add the menubar always at the top */
3332     gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3333
3334     /* main toolbar */
3335     gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3336
3337     /* filter toolbar in toolbar area */
3338     if (!prefs.filter_toolbar_show_in_statusbar) {
3339         gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3340     }
3341
3342 #ifdef HAVE_AIRPCAP
3343     /* airpcap toolbar */
3344     gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3345 #endif
3346
3347     /* fill the main layout panes */
3348     switch(prefs.gui_layout_type) {
3349     case(layout_type_5):
3350         main_first_pane  = main_pane_v1;
3351         main_second_pane = main_pane_v2;
3352         split_top_left = FALSE;
3353         break;
3354     case(layout_type_2):
3355         main_first_pane  = main_pane_v1;
3356         main_second_pane = main_pane_h1;
3357         split_top_left = FALSE;
3358         break;
3359     case(layout_type_1):
3360         main_first_pane  = main_pane_v1;
3361         main_second_pane = main_pane_h1;
3362         split_top_left = TRUE;
3363         break;
3364     case(layout_type_4):
3365         main_first_pane  = main_pane_h1;
3366         main_second_pane = main_pane_v1;
3367         split_top_left = FALSE;
3368         break;
3369     case(layout_type_3):
3370         main_first_pane  = main_pane_h1;
3371         main_second_pane = main_pane_v1;
3372         split_top_left = TRUE;
3373         break;
3374     case(layout_type_6):
3375         main_first_pane  = main_pane_h1;
3376         main_second_pane = main_pane_h2;
3377         split_top_left = FALSE;
3378         break;
3379     default:
3380         main_first_pane = NULL;
3381         main_second_pane = NULL;
3382         split_top_left = FALSE;
3383         g_assert_not_reached();
3384     }
3385     if (split_top_left) {
3386         first_pane_widget1 = main_second_pane;
3387         second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3388         second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3389         first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3390     } else {
3391         first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3392         first_pane_widget2 = main_second_pane;
3393         second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3394         second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3395     }
3396     if (first_pane_widget1 != NULL)
3397         gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3398     if (first_pane_widget2 != NULL)
3399         gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3400     if (second_pane_widget1 != NULL)
3401         gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3402     if (second_pane_widget2 != NULL)
3403         gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3404
3405     gtk_container_add(GTK_CONTAINER(main_vbox), main_first_pane);
3406
3407     /* welcome pane */
3408     gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3409
3410     /* statusbar hbox */
3411     gtk_box_pack_start(GTK_BOX(main_vbox), stat_hbox, FALSE, TRUE, 0);
3412
3413     /* filter toolbar in statusbar hbox */
3414     if (prefs.filter_toolbar_show_in_statusbar) {
3415         gtk_box_pack_start(GTK_BOX(stat_hbox), filter_tb, FALSE, TRUE, 1);
3416     }
3417
3418 #ifdef HAVE_AIRPCAP
3419     /* airpcap toolbar */
3420     gtk_box_pack_start(GTK_BOX(main_vbox), airpcap_tb, FALSE, TRUE, 1);
3421 #endif
3422
3423     /* statusbar */
3424     gtk_box_pack_start(GTK_BOX(stat_hbox), status_pane, TRUE, TRUE, 0);
3425     gtk_paned_pack1(GTK_PANED(status_pane), info_bar, FALSE, FALSE);
3426     gtk_paned_pack2(GTK_PANED(status_pane), packets_bar, FALSE, FALSE);
3427
3428     /* hide widgets on users recent settings */
3429     main_widgets_show_or_hide();
3430
3431     gtk_widget_show(main_vbox);
3432 }
3433
3434 static void
3435 is_widget_visible(GtkWidget *widget, gpointer data)
3436 {
3437     gboolean *is_visible = data;
3438
3439     if (!*is_visible) {
3440         if (GTK_WIDGET_VISIBLE(widget))
3441             *is_visible = TRUE;
3442     }
3443 }
3444
3445 /*#define SHOW_WELCOME_PAGE*/
3446 #ifdef SHOW_WELCOME_PAGE
3447 /* XXX - There seems to be some disagreement about if and how this feature should be implemented.
3448    As I currently don't have the time to continue this, it's temporarily disabled. - ULFL */
3449 GtkWidget *
3450 welcome_item(const gchar *stock_item, const gchar * label, const gchar * message, const gchar * tooltip, 
3451                          GtkSignalFunc callback, void *callback_data)
3452 {
3453     GtkWidget *w, *item_hb;
3454 #if GTK_MAJOR_VERSION >= 2
3455     gchar *formatted_message;
3456         GtkTooltips *tooltips;
3457
3458         tooltips = gtk_tooltips_new();
3459 #endif
3460
3461     item_hb = gtk_hbox_new(FALSE, 1);
3462
3463     w = BUTTON_NEW_FROM_STOCK(stock_item);
3464     WIDGET_SET_SIZE(w, 80, 40);
3465 #if GTK_MAJOR_VERSION >= 2
3466     gtk_button_set_label(GTK_BUTTON(w), label);
3467         gtk_tooltips_set_tip(tooltips, w, tooltip, NULL);
3468 #endif
3469     gtk_box_pack_start(GTK_BOX(item_hb), w, FALSE, FALSE, 0);
3470     SIGNAL_CONNECT(w, "clicked", callback, callback_data);
3471
3472     w = gtk_label_new(message);
3473         gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5);
3474 #if GTK_MAJOR_VERSION >= 2
3475     formatted_message = g_strdup_printf("<span weight=\"bold\" size=\"x-large\">%s</span>", message);
3476     gtk_label_set_markup(GTK_LABEL(w), formatted_message);
3477     g_free(formatted_message);
3478 #endif
3479
3480     gtk_box_pack_start(GTK_BOX(item_hb), w, FALSE, FALSE, 10);
3481
3482     return item_hb;
3483 }
3484
3485
3486 GtkWidget *
3487 welcome_header_new(void)
3488 {
3489         GtkWidget *item_vb;
3490         GtkWidget *item_hb;
3491         GtkWidget *eb;
3492         GdkColor bg;
3493     GtkWidget *icon;
3494     gchar *message;
3495         GtkWidget *w;
3496
3497
3498         /* background color of the header bar */
3499         bg.pixel = 0;
3500         bg.red = 154 * 255;
3501         bg.green = 210 * 255;
3502         bg.blue = 229 * 255;
3503
3504     item_vb = gtk_vbox_new(FALSE, 0);
3505
3506         /* colorize vbox */
3507         get_color(&bg);
3508         eb = gtk_event_box_new();
3509         gtk_container_add(GTK_CONTAINER(eb), item_vb);
3510 #if GTK_MAJOR_VERSION >= 2
3511         gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &bg);
3512 #endif
3513
3514     item_hb = gtk_hbox_new(FALSE, 0);
3515     gtk_box_pack_start(GTK_BOX(item_vb), item_hb, FALSE, FALSE, 10);
3516
3517         icon = xpm_to_widget_from_parent(top_level, wssplash_xpm);
3518     /*icon = xpm_to_widget_from_parent(top_level, wsicon64_xpm);*/
3519     gtk_box_pack_start(GTK_BOX(item_hb), icon, FALSE, FALSE, 10);
3520
3521 #if GTK_MAJOR_VERSION < 2
3522     message = "The World's Most Popular Network Protocol Analyzer";
3523 #else
3524     message = "<span weight=\"bold\" size=\"x-large\">" "The World's Most Popular Network Protocol Analyzer" "</span>";
3525 #endif
3526     w = gtk_label_new(message);
3527 #if GTK_MAJOR_VERSION >= 2
3528     gtk_label_set_markup(GTK_LABEL(w), message);
3529 #endif
3530     gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.5);
3531     gtk_box_pack_start(GTK_BOX(item_hb), w, TRUE, TRUE, 5);
3532
3533     gtk_widget_show_all(eb);
3534
3535         return eb;
3536 }
3537
3538 GtkWidget *
3539 welcome_topic_header_new(const char *header)
3540 {
3541         GtkWidget *w;
3542         GdkColor bg;
3543     GtkWidget *eb;
3544 #if GTK_MAJOR_VERSION >= 2
3545     gchar *formatted_message;
3546 #endif
3547
3548
3549     w = gtk_label_new(header);
3550 #if GTK_MAJOR_VERSION >= 2
3551     formatted_message = g_strdup_printf("<span weight=\"bold\" size=\"x-large\">%s</span>", header);
3552     gtk_label_set_markup(GTK_LABEL(w), formatted_message);
3553     g_free(formatted_message);
3554 #endif
3555
3556         /* topic header background color */
3557         bg.pixel = 0;
3558         bg.red = 24 * 255;
3559         bg.green = 151 * 255;
3560         bg.blue = 192 * 255;
3561
3562         /* colorize vbox */
3563         get_color(&bg);
3564         eb = gtk_event_box_new();
3565         gtk_container_add(GTK_CONTAINER(eb), w);
3566 #if GTK_MAJOR_VERSION >= 2
3567         gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &bg);
3568 #endif
3569
3570         return eb;
3571 }
3572
3573
3574 GtkWidget *
3575 welcome_topic_new(const char *header, GtkWidget **to_fill)
3576 {
3577         GtkWidget *topic_vb;
3578         GtkWidget *layout_vb;
3579         GtkWidget *topic_eb;
3580         GtkWidget *topic_header;
3581         GdkColor bg;
3582
3583         topic_vb = gtk_vbox_new(FALSE, 0);
3584
3585         /* topic content background color */
3586         bg.pixel = 0;
3587         bg.red = 221 * 255;
3588         bg.green = 226 * 255;
3589         bg.blue = 228 * 255;
3590
3591         topic_header = welcome_topic_header_new(header);
3592     gtk_box_pack_start(GTK_BOX(topic_vb), topic_header, FALSE, FALSE, 0);
3593
3594         layout_vb = gtk_vbox_new(FALSE, 5);
3595         gtk_container_border_width(GTK_CONTAINER(layout_vb), 10);
3596     gtk_box_pack_start(GTK_BOX(topic_vb), layout_vb, FALSE, FALSE, 0);
3597
3598         /* colorize vbox (we need an event box for this!) */
3599         get_color(&bg);
3600         topic_eb = gtk_event_box_new();
3601         gtk_container_add(GTK_CONTAINER(topic_eb), topic_vb);
3602 #if GTK_MAJOR_VERSION >= 2
3603         gtk_widget_modify_bg(topic_eb, GTK_STATE_NORMAL, &bg);
3604 #endif
3605         *to_fill = layout_vb;
3606
3607         return topic_eb;
3608 }
3609
3610
3611 #if GTK_MAJOR_VERSION >= 2
3612 static gboolean
3613 welcome_link_enter_cb(GtkWidget *widget _U_, GdkEventCrossing *event _U_, gpointer user_data)
3614 {
3615     gchar *message;
3616     GtkWidget *w = user_data;
3617         
3618         message = g_strdup_printf("<span foreground='blue' underline='single'>%s</span>", OBJECT_GET_DATA(w,"TEXT"));
3619 #if GTK_MAJOR_VERSION >= 2
3620     gtk_label_set_markup(GTK_LABEL(w), message);
3621 #endif
3622         g_free(message);
3623
3624         return FALSE;
3625 }
3626
3627 static gboolean
3628 welcome_link_leave_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer user_data)
3629 {       
3630     gchar *message;
3631     GtkWidget *w = user_data;
3632         
3633         message = g_strdup_printf("<span foreground='blue'>%s</span>", OBJECT_GET_DATA(w,"TEXT"));
3634 #if GTK_MAJOR_VERSION >= 2
3635     gtk_label_set_markup(GTK_LABEL(w), message);
3636 #endif
3637         g_free(message);
3638
3639         return FALSE;
3640 }
3641 #endif
3642
3643
3644 static gboolean
3645 welcome_link_press_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_) {
3646         
3647         g_warning("TBD: link pressed");
3648
3649         return FALSE;
3650 }
3651
3652 GtkWidget *
3653 welcome_link_new(const gchar *text, GtkWidget **label /*, void *callback, void *private_data */)
3654 {
3655     gchar *message;
3656     GtkWidget *w;
3657     GtkWidget *eb;
3658
3659 #if GTK_MAJOR_VERSION < 2
3660     message = g_strdup(text);
3661 #else
3662         message = g_strdup_printf("<span foreground='blue'>%s</span>", text);
3663 #endif
3664         w = gtk_label_new(message);
3665         *label = w;
3666 #if GTK_MAJOR_VERSION >= 2
3667     gtk_label_set_markup(GTK_LABEL(w), message);
3668 #endif
3669         g_free(message);
3670
3671         /* event box */
3672         eb = gtk_event_box_new();
3673         gtk_container_add(GTK_CONTAINER(eb), w);
3674
3675 #if GTK_MAJOR_VERSION >= 2
3676     SIGNAL_CONNECT(eb, "enter-notify-event", welcome_link_enter_cb, w);
3677     SIGNAL_CONNECT(eb, "leave-notify-event", welcome_link_leave_cb, w);
3678 #endif
3679     SIGNAL_CONNECT(eb, "button-press-event", welcome_link_press_cb, w);
3680
3681         /* XXX - memleak */
3682         OBJECT_SET_DATA(w, "TEXT", g_strdup(text));
3683
3684         return eb;
3685 }
3686
3687 GtkWidget *
3688 welcome_filename_link_new(const char *filename, GtkWidget **label)
3689 {
3690         GString         *str;
3691         GtkWidget       *w;
3692         const unsigned int max = 60;
3693
3694
3695         str = g_string_new(filename);
3696
3697         if(str->len > max) {
3698                 g_string_erase(str, 0, str->len-max /*cut*/);
3699                 g_string_prepend(str, "... ");
3700         }
3701
3702         w = welcome_link_new(str->str, label);
3703
3704         g_string_free(str, TRUE);
3705
3706         return w;
3707 }
3708
3709
3710 GtkWidget *
3711 welcome_if_new(const char *if_name, GdkColor *topic_bg, gboolean active)
3712 {
3713         GtkWidget *interface_hb;
3714         GtkWidget *w;
3715     GtkWidget *label;
3716         GtkTooltips *tooltips;
3717         GString   *message;
3718
3719
3720         tooltips = gtk_tooltips_new();
3721
3722         interface_hb = gtk_hbox_new(FALSE, 5);
3723
3724         w = welcome_link_new("START", &label);
3725         gtk_tooltips_set_tip(tooltips, w, "Immediately start a capture on this interface", NULL);
3726 #if GTK_MAJOR_VERSION >= 2
3727         gtk_widget_modify_bg(w, GTK_STATE_NORMAL, topic_bg);
3728 #endif
3729         gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3730     gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0);
3731
3732         w = welcome_link_new("OPTIONS", &label);
3733         gtk_tooltips_set_tip(tooltips, w, "Show the capture options of this interface", NULL);
3734 #if GTK_MAJOR_VERSION >= 2
3735         gtk_widget_modify_bg(w, GTK_STATE_NORMAL, topic_bg);
3736 #endif
3737         gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3738     gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0);
3739
3740         w = welcome_link_new("DETAILS", &label);
3741         gtk_tooltips_set_tip(tooltips, w, "Show detailed information about this interface", NULL);
3742 #if GTK_MAJOR_VERSION >= 2
3743         gtk_widget_modify_bg(w, GTK_STATE_NORMAL, topic_bg);
3744 #endif
3745         gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3746     gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0);
3747
3748         message = g_string_new(if_name);
3749
3750         /* truncate string if it's too long */
3751         if(message->len > 38) {
3752                 g_string_truncate(message, 35);
3753                 g_string_append  (message, " ...");
3754         }
3755 #if GTK_MAJOR_VERSION >= 2
3756         /* if this is the "active" interface, display it bold */
3757         if(active) {
3758                 g_string_prepend(message, "<span weight=\"bold\">");
3759                 g_string_append (message, "</span>");
3760         }
3761 #endif
3762         w = gtk_label_new(message->str);
3763 #if GTK_MAJOR_VERSION >= 2
3764     gtk_label_set_markup(GTK_LABEL(w), message->str);
3765 #endif
3766         g_string_free(message, TRUE);
3767
3768         gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0);
3769     gtk_box_pack_start(GTK_BOX(interface_hb), w, FALSE, FALSE, 0);
3770
3771         return interface_hb;
3772 }
3773
3774 /* XXX - the layout has to be improved */
3775 GtkWidget *
3776 welcome_new(void)
3777 {
3778     GtkWidget *welcome_scrollw;
3779         GtkWidget *welcome_vb;
3780         GtkWidget *welcome_hb;
3781         GtkWidget *column_vb;
3782         GtkWidget *item_hb;
3783     GtkWidget *w;
3784     GtkWidget *label;
3785         GtkWidget *header;
3786         GtkWidget *topic_vb;
3787         GtkWidget *topic_to_fill;
3788         GtkWidget *interface_hb;
3789         GdkColor  topic_bg;
3790
3791
3792         /* topic content background color */
3793         topic_bg.pixel = 0;
3794         topic_bg.red = 221 * 255;
3795         topic_bg.green = 226 * 255;
3796         topic_bg.blue = 228 * 255;
3797
3798     welcome_scrollw = scrolled_window_new(NULL, NULL);
3799
3800     welcome_vb = gtk_vbox_new(FALSE, 0);
3801
3802         /* header */
3803         header = welcome_header_new();
3804     gtk_box_pack_start(GTK_BOX(welcome_vb), header, FALSE, FALSE, 0);
3805
3806         /* content */
3807     welcome_hb = gtk_hbox_new(FALSE, 10);
3808         gtk_container_border_width(GTK_CONTAINER(welcome_hb), 10);
3809     gtk_box_pack_start(GTK_BOX(welcome_vb), welcome_hb, TRUE, TRUE, 0);
3810
3811         /* column capture */
3812         column_vb = gtk_vbox_new(FALSE, 10);
3813     gtk_box_pack_start(GTK_BOX(welcome_hb), column_vb, TRUE, TRUE, 0);
3814
3815         /* capture topic */
3816         topic_vb = welcome_topic_new("Capture", &topic_to_fill);
3817     gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3818
3819 #ifdef HAVE_LIBPCAP
3820     item_hb = welcome_item(WIRESHARK_STOCK_CAPTURE_INTERFACES,
3821         "Interfaces...",
3822         "Interface Life List",
3823                 "Show a life list of the available capture interfaces",
3824         GTK_SIGNAL_FUNC(capture_if_cb), NULL);
3825     gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3826 #endif
3827
3828         w = gtk_label_new("Available Interfaces:");
3829         gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0);
3830     gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5);
3831
3832         interface_hb = welcome_if_new("Generic dialup adapter", &topic_bg, FALSE);
3833     gtk_box_pack_start(GTK_BOX(topic_to_fill), interface_hb, FALSE, FALSE, 0);
3834
3835         /* Marvell interface (currently "active") */
3836         interface_hb = welcome_if_new("Marvell Gigabit Ethernet Controller", &topic_bg, TRUE);
3837     gtk_box_pack_start(GTK_BOX(topic_to_fill), interface_hb, FALSE, FALSE, 0);
3838
3839         /* Wireless interface */
3840         interface_hb = welcome_if_new("Intel(R) PRO/Wireless 3945ABG Network Connection", &topic_bg, FALSE);
3841     gtk_box_pack_start(GTK_BOX(topic_to_fill), interface_hb, FALSE, FALSE, 0);
3842
3843
3844         /* capture help topic */
3845         topic_vb = welcome_topic_new("Capture Help", &topic_to_fill);
3846     gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3847
3848 #ifdef HAVE_LIBPCAP
3849     item_hb = welcome_item(WIRESHARK_STOCK_CAPTURE_START,
3850         "Setup",
3851                 "How To: Setup a Capture",
3852                 "How To: Setup a Capture (online from the Wiki)",
3853         GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3854     gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3855
3856     item_hb = welcome_item(WIRESHARK_STOCK_CAPTURE_START,
3857         "Examples",
3858                 "Capture Filter Examples",
3859                 "Capture Filter Examples (online from the Wiki)",
3860         GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3861     gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3862 #endif
3863
3864         /* fill bottom space */
3865     w = gtk_label_new("");
3866     gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
3867
3868
3869         /* column files */
3870         topic_vb = welcome_topic_new("Files", &topic_to_fill);
3871     gtk_box_pack_start(GTK_BOX(welcome_hb), topic_vb, TRUE, TRUE, 0);
3872
3873     item_hb = welcome_item(GTK_STOCK_OPEN,
3874         "Open...",
3875         "Open a Capture File",
3876                 "Open a previously captured file",
3877         GTK_SIGNAL_FUNC(file_open_cmd_cb), NULL);
3878     gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3879
3880     item_hb = welcome_item(GTK_STOCK_OPEN,
3881         "Examples",
3882         "Download Examples",
3883                 "Download Example Capture Files (from the Wiki)",
3884         GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3885     gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3886
3887         w = gtk_label_new("Recent Files:");
3888         gtk_misc_set_alignment (GTK_MISC(w), 0.0, 0.0);
3889     gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5);
3890
3891         w = welcome_link_new("C:\\Testfiles\\hello.pcap", &label);
3892 #if GTK_MAJOR_VERSION >= 2
3893         gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_bg);
3894 #endif
3895         gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3896     gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 0);
3897
3898         w = welcome_filename_link_new("C:\\Testfiles\\hello2.pcap", &label);
3899 #if GTK_MAJOR_VERSION >= 2
3900         gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_bg);
3901 #endif
3902         gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3903     gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 0);
3904
3905         w = welcome_filename_link_new(
3906                 "C:\\Testfiles\\to avoid screen garbage\\Unfortunately this is a very long filename which had to be truncated.pcap", 
3907                 &label);
3908 #if GTK_MAJOR_VERSION >= 2
3909         gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_bg);
3910 #endif
3911         gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.0);
3912     gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 0);
3913
3914     w = gtk_label_new("");
3915     gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
3916
3917
3918         /* column online */
3919         column_vb = gtk_vbox_new(FALSE, 10);
3920     gtk_box_pack_start(GTK_BOX(welcome_hb), column_vb, TRUE, TRUE, 0);
3921
3922         /* topic online */
3923         topic_vb = welcome_topic_new("Online", &topic_to_fill);
3924     gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3925
3926 #if (GLIB_MAJOR_VERSION >= 2)
3927     item_hb = welcome_item(WIRESHARK_STOCK_WEB_SUPPORT,
3928         "Help",
3929         "Show the User's Guide",
3930                 "Show the User's Guide (local version, if available)",
3931         GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_USERGUIDE));
3932     gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3933
3934     item_hb = welcome_item(GTK_STOCK_HOME,
3935         "Home",
3936         "Projects Home Page",
3937                 "Visit www.wireshark.org, the project's home page",
3938         GTK_SIGNAL_FUNC(topic_cb), GINT_TO_POINTER(ONLINEPAGE_HOME));
3939     gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
3940 #endif
3941
3942         /* topic updates */
3943         topic_vb = welcome_topic_new("Updates", &topic_to_fill);
3944     gtk_box_pack_start(GTK_BOX(column_vb), topic_vb, TRUE, TRUE, 0);
3945
3946     w = gtk_label_new("No updates available!");
3947     gtk_box_pack_start(GTK_BOX(topic_to_fill), w, TRUE, TRUE, 0);
3948
3949
3950     /* the end */
3951     gtk_widget_show_all(welcome_vb);
3952
3953     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(welcome_scrollw),
3954                                           welcome_vb);
3955     gtk_widget_show_all(welcome_scrollw);
3956
3957         return welcome_scrollw;
3958 }
3959 #else
3960 static GtkWidget *
3961 welcome_new(void)
3962 {
3963     /* this is just a dummy to fill up window space, simply showing nothing */
3964     return scrolled_window_new(NULL, NULL);
3965 }
3966 #endif
3967
3968
3969
3970 /*
3971  * XXX - this doesn't appear to work with the paned widgets in
3972  * GTK+ 1.2[.x]; if you hide one of the panes, the splitter remains
3973  * and the other pane doesn't grow to take up the rest of the pane.
3974  * It does appear to work with GTK+ 2.x.
3975  */
3976 void
3977 main_widgets_show_or_hide(void)
3978 {
3979     gboolean main_second_pane_show;
3980
3981     if (recent.main_toolbar_show) {
3982         gtk_widget_show(main_tb);
3983     } else {
3984         gtk_widget_hide(main_tb);
3985     }
3986
3987     /*
3988      * Show the status hbox if either:
3989      *
3990      *    1) we're showing the filter toolbar and we want it in the status
3991      *       line
3992      *
3993      * or
3994      *
3995      *    2) we're showing the status bar.
3996      */
3997     if ((recent.filter_toolbar_show && prefs.filter_toolbar_show_in_statusbar) ||
3998          recent.statusbar_show) {
3999         gtk_widget_show(stat_hbox);
4000     } else {
4001         gtk_widget_hide(stat_hbox);
4002     }
4003
4004     if (recent.statusbar_show) {
4005         gtk_widget_show(status_pane);
4006     } else {
4007         gtk_widget_hide(status_pane);
4008     }
4009
4010     if (recent.filter_toolbar_show) {
4011         gtk_widget_show(filter_tb);
4012     } else {
4013         gtk_widget_hide(filter_tb);
4014     }
4015
4016 #ifdef HAVE_AIRPCAP
4017     if (recent.airpcap_toolbar_show) {
4018         gtk_widget_show(airpcap_tb);
4019     } else {
4020         gtk_widget_hide(airpcap_tb);
4021     }
4022 #endif
4023
4024     if (recent.packet_list_show && have_capture_file) {
4025         gtk_widget_show(pkt_scrollw);
4026     } else {
4027         gtk_widget_hide(pkt_scrollw);
4028     }
4029
4030     if (recent.tree_view_show && have_capture_file) {
4031         gtk_widget_show(tv_scrollw);
4032     } else {
4033         gtk_widget_hide(tv_scrollw);
4034     }
4035
4036     if (recent.byte_view_show && have_capture_file) {
4037         gtk_widget_show(byte_nb_ptr);
4038     } else {
4039         gtk_widget_hide(byte_nb_ptr);
4040     }
4041
4042     if (have_capture_file) {
4043         gtk_widget_show(main_first_pane);
4044     } else {
4045         gtk_widget_hide(main_first_pane);
4046     }
4047
4048     /*
4049      * Is anything in "main_second_pane" visible?
4050      * If so, show it, otherwise hide it.
4051      */
4052     main_second_pane_show = FALSE;
4053     gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
4054                           &main_second_pane_show);
4055     if (main_second_pane_show) {
4056         gtk_widget_show(main_second_pane);
4057     } else {
4058         gtk_widget_hide(main_second_pane);
4059     }
4060
4061     if (!have_capture_file) {
4062         if(welcome_pane) {
4063             gtk_widget_show(welcome_pane);
4064         }
4065     } else {
4066         gtk_widget_hide(welcome_pane);
4067     }
4068
4069     /* workaround for bug in GtkCList to ensure packet list scrollbar is updated */
4070     packet_list_freeze ();
4071     packet_list_thaw ();
4072 }
4073
4074
4075 #if GTK_MAJOR_VERSION >= 2
4076 /* called, when the window state changes (minimized, maximized, ...) */
4077 static int
4078 window_state_event_cb (GtkWidget *widget _U_,
4079                        GdkEvent *event,
4080                        gpointer  data _U_)
4081 {
4082     GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
4083
4084     if( (event->type) == (GDK_WINDOW_STATE)) {
4085         if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
4086             /* we might have dialogs popped up while we where iconified,
4087                show em now */
4088             display_queued_messages();
4089         }
4090     }
4091     return FALSE;
4092 }
4093 #endif
4094
4095 #ifdef HAVE_AIRPCAP
4096 /*
4097  * Changed callback for the channel combobox
4098  */
4099 static void
4100 airpcap_toolbar_channel_changed_cb(GtkWidget *w _U_, gpointer data)
4101 {
4102   gchar ebuf[AIRPCAP_ERRBUF_SIZE];
4103   PAirpcapHandle ad;
4104   const gchar *s;
4105   int ch_num;
4106
4107   s = gtk_entry_get_text(GTK_ENTRY(data));
4108
4109   if ((data != NULL) && (w != NULL) ) {
4110     s = gtk_entry_get_text(GTK_ENTRY(data));
4111     if ((g_strcasecmp("",s))) {
4112       sscanf(s,"%d",&ch_num);
4113       if (airpcap_if_active != NULL) {
4114         ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list, airpcap_if_active->description), ebuf);
4115
4116         if(ad) {
4117           airpcap_if_set_device_channel(ad,ch_num);
4118           airpcap_if_active->channel = ch_num;
4119           airpcap_if_close(ad);
4120         }
4121       }
4122     }
4123   }
4124 }
4125
4126 /*
4127  * Callback for the wrong crc combo
4128  */
4129 static void
4130 airpcap_toolbar_wrong_crc_combo_cb(GtkWidget *entry, gpointer user_data)
4131 {
4132   gchar ebuf[AIRPCAP_ERRBUF_SIZE];
4133   PAirpcapHandle ad;
4134
4135   if( !block_toolbar_signals && (airpcap_if_active != NULL)) {
4136     ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,airpcap_if_active->description), ebuf);
4137
4138     if (ad) {
4139       airpcap_if_active->CrcValidationOn = airpcap_get_validation_type(gtk_entry_get_text(GTK_ENTRY(entry)));
4140       airpcap_if_set_fcs_validation(ad,airpcap_if_active->CrcValidationOn);
4141       /* Save configuration */
4142       if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
4143         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Cannot save configuration!!!\nRemember that in order to store the configuration in the registry you have to:\n\n- Close all the airpcap-based applications.\n- Be sure to have administrative privileges.");
4144       }
4145       airpcap_if_close(ad);
4146     }
4147   }
4148 }
4149
4150 void
4151 airpcap_toolbar_encryption_cb(GtkWidget *entry, gpointer user_data)
4152 {
4153   /* We need to directly access the .ddl functions here... */
4154   gchar ebuf[AIRPCAP_ERRBUF_SIZE];
4155   PAirpcapHandle ad;
4156
4157  gint n = 0;
4158   gint i = 0;
4159   airpcap_if_info_t* curr_if = NULL;
4160
4161   /* Apply changes to the current adapter */
4162   if( (airpcap_if_active != NULL)) {
4163     ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,airpcap_if_active->description), ebuf);
4164
4165     if(ad) {
4166       if(airpcap_if_active->DecryptionOn == AIRPCAP_DECRYPTION_ON) {
4167         airpcap_if_active->DecryptionOn = AIRPCAP_DECRYPTION_OFF;
4168         airpcap_if_set_decryption_state(ad,airpcap_if_active->DecryptionOn);
4169         /* Save configuration */
4170         if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
4171           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Cannot save configuration!!!\nRemember that in order to store the configuration in the registry you have to:\n\n- Close all the airpcap-based applications.\n- Be sure to have administrative privileges.");
4172         }
4173         airpcap_if_close(ad);
4174       } else {
4175         airpcap_if_active->DecryptionOn = AIRPCAP_DECRYPTION_ON;
4176         airpcap_if_set_decryption_state(ad,airpcap_if_active->DecryptionOn);
4177         /* Save configuration */
4178         if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
4179           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Cannot save configuration!!!\nRemember that in order to store the configuration in the registry you have to:\n\n- Close all the airpcap-based applications.\n- Be sure to have administrative privileges.");
4180         }
4181         airpcap_if_close(ad);
4182       }
4183     }
4184   } else {
4185     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No active AirPcap Adapter selected!");
4186     return;
4187   }
4188
4189   n = g_list_length(airpcap_if_list);
4190
4191   /* The same kind of settings should be propagated to all the adapters */
4192   /* Apply this change to all the adapters !!! */
4193   for(i = 0; i < n; i++) {
4194     curr_if = (airpcap_if_info_t*)g_list_nth_data(airpcap_if_list,i);
4195
4196     if( (curr_if != NULL) && (curr_if != airpcap_if_selected) ) {
4197       ad = airpcap_if_open(get_airpcap_name_from_description(airpcap_if_list,curr_if->description), ebuf);
4198       if(ad) {
4199         curr_if->DecryptionOn = airpcap_if_selected->DecryptionOn;
4200         airpcap_if_set_decryption_state(ad,curr_if->DecryptionOn);
4201         /* Save configuration for the curr_if */
4202         if(!airpcap_if_store_cur_config_as_adapter_default(ad)) {
4203           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Cannot save configuration!!!\nRemember that in order to store the configuration in the registry you have to:\n\n- Close all the airpcap-based applications.\n- Be sure to have administrative privileges.");
4204         }
4205         airpcap_if_close(ad);
4206       }
4207     }
4208   }
4209 }
4210
4211 /*
4212  * Callback for the Advanced Wireless Settings button
4213  */
4214 static void
4215 toolbar_display_airpcap_advanced_cb(GtkWidget *w, gpointer data)
4216 {
4217     int *from_widget;
4218
4219     from_widget = (gint*)g_malloc(sizeof(gint));
4220     *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
4221     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_ADVANCED_FROM_KEY,from_widget);
4222
4223     display_airpcap_advanced_cb(w,data);
4224 }
4225
4226 /*
4227  * Callback for the Decryption Key Management button
4228  */
4229 static void
4230 toolbar_display_airpcap_key_management_cb(GtkWidget *w, gpointer data)
4231 {
4232     int *from_widget;
4233
4234     from_widget = (gint*)g_malloc(sizeof(gint));
4235     *from_widget = AIRPCAP_ADVANCED_FROM_TOOLBAR;
4236     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_ADVANCED_FROM_KEY,from_widget);
4237
4238     display_airpcap_key_management_cb(w,data);
4239 }
4240 #endif /* HAVE_AIRPCAP */
4241
4242 #if GTK_MAJOR_VERSION >= 2
4243 static int
4244 top_level_key_pressed_cb(GtkCTree *ctree _U_, GdkEventKey *event, gpointer user_data _U_)
4245 {
4246     if (event->keyval == GDK_F8) {
4247         packet_list_next();
4248         return TRUE;
4249     } else if (event->keyval == GDK_F7) {
4250         packet_list_prev();
4251         return TRUE;
4252     /*
4253      * A comment in gdkkeysyms.h says that it's autogenerated from
4254      * freedesktop.org/x.org's keysymdef.h.  Although the GDK docs
4255      * don't explicitly say so, isprint() should work as expected
4256      * for values < 127.
4257      */
4258     } else if (isascii(event->keyval) && isprint(event->keyval)) {
4259         /* Forward the keypress on to the display filter entry */
4260         if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
4261             gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
4262             gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
4263         }
4264         return FALSE;
4265     }
4266     return FALSE;
4267 }
4268 #endif
4269
4270 static void
4271 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
4272 {
4273     GtkWidget
4274                   *filter_bt, *filter_cm, *filter_te,
4275                   *filter_add_expr_bt,
4276                   *filter_apply,
4277                   *filter_reset;
4278     GList         *dfilter_list = NULL;
4279     GtkTooltips   *tooltips;
4280
4281     GtkAccelGroup *accel;
4282     gchar         *title;
4283
4284 #ifdef HAVE_AIRPCAP
4285     GtkWidget *advanced_bt,
4286                   *key_management_bt,
4287                   *interface_lb,
4288                   *channel_lb,
4289                   *channel_cm,
4290                   *wrong_crc_lb,
4291                   *wrong_crc_cm;
4292
4293     GtkWidget *enable_decryption_lb;
4294     GtkWidget *enable_decryption_cb;
4295     GList     *enable_decryption_cb_items = NULL;
4296     GtkWidget *enable_decryption_en;
4297
4298     GList         *channel_list = NULL;
4299     GList         *linktype_list = NULL;
4300     GList         *link_list = NULL;
4301     GtkTooltips   *airpcap_tooltips;
4302     gchar         *if_label_text;
4303     gint          *from_widget = NULL;
4304 #endif
4305
4306     /* Display filter construct dialog has an Apply button, and "OK" not
4307        only sets our text widget, it activates it (i.e., it causes us to
4308        filter the capture). */
4309     static construct_args_t args = {
4310         "Wireshark: Display Filter",
4311         TRUE,
4312         TRUE,
4313         FALSE
4314     };
4315
4316     /* use user-defined title if preference is set */
4317     title = create_user_window_title("The Wireshark Network Analyzer");
4318
4319     /* Main window */
4320     top_level = window_new(GTK_WINDOW_TOPLEVEL, title);
4321     g_free(title);
4322
4323     tooltips = gtk_tooltips_new();
4324
4325 #ifdef HAVE_AIRPCAP
4326     airpcap_tooltips = gtk_tooltips_new();
4327 #endif
4328
4329 #ifdef _WIN32
4330 #if GTK_MAJOR_VERSION < 2
4331     /* has to be done, after top_level window is created */
4332     app_font_gtk1_init(top_level);
4333 #endif
4334 #endif
4335
4336     gtk_widget_set_name(top_level, "main window");
4337     SIGNAL_CONNECT(top_level, "delete_event", main_window_delete_event_cb,
4338                    NULL);
4339 #if GTK_MAJOR_VERSION >= 2
4340     SIGNAL_CONNECT(GTK_OBJECT(top_level), "window_state_event",
4341                          G_CALLBACK (window_state_event_cb), NULL);
4342     SIGNAL_CONNECT(GTK_OBJECT(top_level), "key-press-event",
4343                          G_CALLBACK (top_level_key_pressed_cb), NULL );
4344 #endif
4345
4346     gtk_window_set_policy(GTK_WINDOW(top_level), TRUE, TRUE, FALSE);
4347
4348     /* Container for menu bar, toolbar(s), paned windows and progress/info box */
4349     main_vbox = gtk_vbox_new(FALSE, 1);
4350     gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
4351     gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
4352     gtk_widget_show(main_vbox);
4353
4354     /* Menu bar */
4355     menubar = main_menu_new(&accel);
4356     gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
4357     gtk_widget_show(menubar);
4358
4359     /* Main Toolbar */
4360     main_tb = toolbar_new();
4361     gtk_widget_show (main_tb);
4362
4363     /* Packet list */
4364     pkt_scrollw = packet_list_new(prefs);
4365     WIDGET_SET_SIZE(packet_list, -1, pl_size);
4366     gtk_widget_show(pkt_scrollw);
4367
4368     /* Tree view */
4369     tv_scrollw = main_tree_view_new(prefs, &tree_view);
4370     WIDGET_SET_SIZE(tv_scrollw, -1, tv_size);
4371     gtk_widget_show(tv_scrollw);
4372
4373 #if GTK_MAJOR_VERSION < 2
4374     SIGNAL_CONNECT(tree_view, "tree-select-row", tree_view_select_row_cb, NULL);
4375     SIGNAL_CONNECT(tree_view, "tree-unselect-row", tree_view_unselect_row_cb,
4376                    NULL);
4377 #else
4378     SIGNAL_CONNECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
4379                    "changed", tree_view_selection_changed_cb, NULL);
4380 #endif
4381     SIGNAL_CONNECT(tree_view, "button_press_event", popup_menu_handler,
4382                    OBJECT_GET_DATA(popup_menu_object, PM_TREE_VIEW_KEY));
4383     gtk_widget_show(tree_view);
4384
4385     /* Byte view. */
4386     byte_nb_ptr = byte_view_new();
4387     WIDGET_SET_SIZE(byte_nb_ptr, -1, bv_size);
4388     gtk_widget_show(byte_nb_ptr);
4389
4390     SIGNAL_CONNECT(byte_nb_ptr, "button_press_event", popup_menu_handler,
4391                    OBJECT_GET_DATA(popup_menu_object, PM_HEXDUMP_KEY));
4392
4393
4394     /* Panes for the packet list, tree, and byte view */
4395     main_pane_v1 = gtk_vpaned_new();
4396     gtk_widget_show(main_pane_v1);
4397     main_pane_v2 = gtk_vpaned_new();
4398     gtk_widget_show(main_pane_v2);
4399     main_pane_h1 = gtk_hpaned_new();
4400     gtk_widget_show(main_pane_h1);
4401     main_pane_h2 = gtk_hpaned_new();
4402     gtk_widget_show(main_pane_h2);
4403
4404 #ifdef HAVE_AIRPCAP
4405     /* airpcap toolbar */
4406 #if GTK_MAJOR_VERSION < 2
4407     airpcap_tb = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
4408                                GTK_TOOLBAR_BOTH);
4409 #else
4410     airpcap_tb = gtk_toolbar_new();
4411     gtk_toolbar_set_orientation(GTK_TOOLBAR(airpcap_tb),
4412                                 GTK_ORIENTATION_HORIZONTAL);
4413 #endif /* GTK_MAJOR_VERSION */
4414     gtk_widget_show(airpcap_tb);
4415
4416     /* Interface Label */
4417     if(airpcap_if_active != NULL) {
4418         if_label_text = g_strdup_printf("%s %s\t","Current Wireless Interface: #",airpcap_get_if_string_number(airpcap_if_active));
4419         interface_lb = gtk_label_new(if_label_text);
4420         g_free(if_label_text);
4421     } else {
4422         interface_lb = gtk_label_new("No Wireless Interface Found  ");
4423     }
4424
4425     /* Add the label to the toolbar */
4426     gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), interface_lb,
4427                               "Current Wireless Interface", "Private");
4428     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_INTERFACE_KEY,interface_lb);
4429     gtk_widget_show(interface_lb);
4430     gtk_toolbar_insert_space(GTK_TOOLBAR(airpcap_tb),1);
4431
4432
4433     /* Create the "802.11 Channel:" label */
4434     channel_lb = gtk_label_new(" 802.11 Channel: ");
4435     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_LABEL_KEY,channel_lb);
4436     gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_lb,
4437                               "Current 802.11 Channel", "Private");
4438     gtk_widget_show(channel_lb);
4439
4440     WIDGET_SET_SIZE(channel_lb, 100, 28);
4441
4442     /* Create the channel combo box */
4443     channel_cm = gtk_combo_new();
4444     gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(channel_cm)->entry),FALSE);
4445     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_CHANNEL_KEY,channel_cm);
4446
4447     channel_list = g_list_append(channel_list, "1 (2412MHz)");
4448     channel_list = g_list_append(channel_list, "2 (2417MHz)");
4449     channel_list = g_list_append(channel_list, "3 (2422MHz)");
4450     channel_list = g_list_append(channel_list, "4 (2427MHz)");
4451     channel_list = g_list_append(channel_list, "5 (2432MHz)");
4452     channel_list = g_list_append(channel_list, "6 (2437MHz)");
4453     channel_list = g_list_append(channel_list, "7 (2442MHz)");
4454     channel_list = g_list_append(channel_list, "8 (2447MHz)");
4455     channel_list = g_list_append(channel_list, "9 (2452MHz)");
4456     channel_list = g_list_append(channel_list, "10 (2457MHz)");
4457     channel_list = g_list_append(channel_list, "11 (2462MHz)");
4458     channel_list = g_list_append(channel_list, "12 (2467MHz)");
4459     channel_list = g_list_append(channel_list, "13 (2472MHz)");
4460     channel_list = g_list_append(channel_list, "14 (2484MHz)");
4461
4462     gtk_combo_set_popdown_strings( GTK_COMBO(channel_cm), channel_list) ;
4463
4464     gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(channel_cm)->entry),
4465                 "Change the 802.11 RF channel", NULL);
4466
4467     WIDGET_SET_SIZE(channel_cm, 100, 28);
4468
4469     if(airpcap_if_active != NULL)
4470         gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_cm)->entry), airpcap_get_channel_name(airpcap_if_active->channel));
4471     else
4472         gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(channel_cm)->entry),"");
4473
4474     /* callback for channel combo box */
4475     SIGNAL_CONNECT(GTK_COMBO(channel_cm)->entry,"changed",airpcap_toolbar_channel_changed_cb,GTK_COMBO(channel_cm)->entry);
4476     gtk_widget_show(channel_cm);
4477
4478     gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), channel_cm,
4479                               "802.11 Channel", "Private");
4480
4481     gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4482
4483     /* Wrong CRC Label */
4484     wrong_crc_lb = gtk_label_new(" FCS Filter: ");
4485     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_LABEL_KEY,wrong_crc_lb);
4486     gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_lb,
4487                               "", "Private");
4488     gtk_widget_show(wrong_crc_lb);
4489
4490     /* Wrong CRC combo */
4491     wrong_crc_cm = gtk_combo_new();
4492     gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(wrong_crc_cm)->entry),FALSE);
4493     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_FCS_FILTER_KEY,wrong_crc_cm);
4494     gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), wrong_crc_cm,
4495                               "", "Private");
4496
4497     WIDGET_SET_SIZE(wrong_crc_cm, 100, -1);
4498
4499     linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_ALL);
4500     linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRECT);
4501     linktype_list = g_list_append(linktype_list, AIRPCAP_VALIDATION_TYPE_NAME_CORRUPT);
4502
4503     gtk_combo_set_popdown_strings( GTK_COMBO(wrong_crc_cm), linktype_list) ;
4504     gtk_tooltips_set_tip(airpcap_tooltips, GTK_WIDGET(GTK_COMBO(wrong_crc_cm)->entry),
4505         "Select the 802.11 FCS filter that the wireless adapter will apply.",
4506         NULL);
4507
4508     if(airpcap_if_active != NULL)
4509         gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wrong_crc_cm)->entry), airpcap_get_validation_name(airpcap_if_active->CrcValidationOn));
4510     else
4511         gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(wrong_crc_cm)->entry),"");
4512
4513     SIGNAL_CONNECT(GTK_COMBO(wrong_crc_cm)->entry,"changed",airpcap_toolbar_wrong_crc_combo_cb,airpcap_tb);
4514     gtk_widget_show(wrong_crc_cm);
4515
4516     gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4517
4518     /* Decryption mode combo box */
4519     enable_decryption_lb = gtk_label_new ("Decryption Mode: ");
4520     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_LABEL_KEY,enable_decryption_lb);
4521     gtk_widget_set_name (enable_decryption_lb, "enable_decryption_lb");
4522     gtk_widget_show (enable_decryption_lb);
4523     gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_lb,
4524     NULL, "Private");
4525
4526     enable_decryption_cb = gtk_combo_new ();
4527     gtk_widget_set_name (enable_decryption_cb, "enable_decryption_cb");
4528     gtk_widget_show (enable_decryption_cb);
4529     WIDGET_SET_SIZE (enable_decryption_cb, 83, -1);
4530     update_decryption_mode_list(enable_decryption_cb);
4531
4532     enable_decryption_en = GTK_COMBO (enable_decryption_cb)->entry;
4533     gtk_widget_set_name (enable_decryption_en, "enable_decryption_en");
4534     gtk_widget_show (enable_decryption_en);
4535     gtk_editable_set_editable (GTK_EDITABLE (enable_decryption_en), FALSE);
4536     GTK_WIDGET_UNSET_FLAGS (enable_decryption_en, GTK_CAN_FOCUS);
4537
4538     gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), enable_decryption_cb,
4539         "Choose a Decryption Mode", "Private");
4540
4541     /* Set current decryption mode!!!! */
4542     update_decryption_mode_cm(enable_decryption_cb);
4543     SIGNAL_CONNECT (enable_decryption_en, "changed",on_enable_decryption_en_changed, airpcap_tb);
4544     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_DECRYPTION_KEY,enable_decryption_cb);
4545
4546     gtk_toolbar_append_space(GTK_TOOLBAR(airpcap_tb));
4547
4548     /* Advanced button */
4549     advanced_bt = gtk_button_new_with_label("Wireless Settings...");
4550     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_ADVANCED_KEY,advanced_bt);
4551
4552     SIGNAL_CONNECT(advanced_bt, "clicked", toolbar_display_airpcap_advanced_cb, airpcap_tb);
4553     gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), advanced_bt,
4554         "Set Advanced Wireless Settings", "Private");
4555     gtk_widget_show(advanced_bt);
4556
4557     /* Key Management button */
4558     key_management_bt = gtk_button_new_with_label("Decryption Keys...");
4559     OBJECT_SET_DATA(airpcap_tb,AIRPCAP_TOOLBAR_KEY_MANAGEMENT_KEY,key_management_bt);
4560
4561     SIGNAL_CONNECT(key_management_bt, "clicked", toolbar_display_airpcap_key_management_cb, airpcap_tb);
4562     gtk_toolbar_append_widget(GTK_TOOLBAR(airpcap_tb), key_management_bt,
4563                               "Manage Decryption Keys", "Private");
4564     gtk_widget_show(key_management_bt);
4565
4566     /* select the default interface */
4567     airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
4568
4569     /* If no airpcap interface is present, gray everything */
4570     if(airpcap_if_active == NULL) {
4571         if(airpcap_if_list == NULL) {
4572             /*No airpcap device found */
4573                         airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
4574                         /* recent.airpcap_toolbar_show = TRUE; */
4575         } else {
4576             /* default adapter is not airpcap... or is airpcap but is not found*/
4577             airpcap_set_toolbar_stop_capture(airpcap_if_active);
4578                         airpcap_enable_toolbar_widgets(airpcap_tb,FALSE);
4579                         /* recent.airpcap_toolbar_show = TRUE; */
4580         }
4581     } else {
4582         airpcap_set_toolbar_stop_capture(airpcap_if_active);
4583                 /* recent.airpcap_toolbar_show = TRUE; */
4584     }
4585 #endif
4586
4587     /* filter toolbar */
4588 #if GTK_MAJOR_VERSION < 2
4589     filter_tb = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
4590                                GTK_TOOLBAR_BOTH);
4591 #else
4592     filter_tb = gtk_toolbar_new();
4593     gtk_toolbar_set_orientation(GTK_TOOLBAR(filter_tb),
4594                                 GTK_ORIENTATION_HORIZONTAL);
4595 #endif /* GTK_MAJOR_VERSION */
4596     gtk_widget_show(filter_tb);
4597
4598     /* Create the "Filter:" button */
4599     filter_bt = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY);
4600     SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &args);
4601     gtk_widget_show(filter_bt);
4602     OBJECT_SET_DATA(top_level, E_FILT_BT_PTR_KEY, filter_bt);
4603
4604     gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_bt,
4605         "Open the \"Display Filter\" dialog, to edit/apply filters", "Private");
4606
4607     /* Create the filter combobox */
4608     filter_cm = gtk_combo_new();
4609     dfilter_list = NULL;
4610     gtk_combo_disable_activate(GTK_COMBO(filter_cm));
4611     gtk_combo_set_case_sensitive(GTK_COMBO(filter_cm), TRUE);
4612     OBJECT_SET_DATA(filter_cm, E_DFILTER_FL_KEY, dfilter_list);
4613     filter_te = GTK_COMBO(filter_cm)->entry;
4614     main_display_filter_widget=filter_te;
4615     OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_te);
4616     OBJECT_SET_DATA(filter_te, E_DFILTER_CM_KEY, filter_cm);
4617     OBJECT_SET_DATA(top_level, E_DFILTER_CM_KEY, filter_cm);
4618     SIGNAL_CONNECT(filter_te, "activate", filter_activate_cb, filter_te);
4619     SIGNAL_CONNECT(filter_te, "changed", filter_te_syntax_check_cb, NULL);
4620     WIDGET_SET_SIZE(filter_cm, 400, -1);
4621     gtk_widget_show(filter_cm);
4622     gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_cm,
4623         NULL, NULL);
4624     /* setting a tooltip for a combobox will do nothing, so add it to the corresponding text entry */
4625     gtk_tooltips_set_tip(tooltips, filter_te,
4626         "Enter a display filter, or choose one of your recently used filters. "
4627         "The background color of this field is changed by a continuous syntax check (green is valid, red is invalid).",
4628         NULL);
4629
4630     /* Create the "Add Expression..." button, to pop up a dialog
4631        for constructing filter comparison expressions. */
4632     filter_add_expr_bt = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_ADD_EXPRESSION);
4633     OBJECT_SET_DATA(filter_tb, E_FILT_FILTER_TE_KEY, filter_te);
4634     SIGNAL_CONNECT(filter_add_expr_bt, "clicked", filter_add_expr_bt_cb, filter_tb);
4635     gtk_widget_show(filter_add_expr_bt);
4636     gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_add_expr_bt,
4637         "Add an expression to this filter string", "Private");
4638
4639     /* Create the "Clear" button */
4640     filter_reset = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLEAR);
4641     OBJECT_SET_DATA(filter_reset, E_DFILTER_TE_KEY, filter_te);
4642     SIGNAL_CONNECT(filter_reset, "clicked", filter_reset_cb, NULL);
4643     gtk_widget_show(filter_reset);
4644     gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_reset,
4645         "Clear this filter string and update the display", "Private");
4646
4647     /* Create the "Apply" button */
4648     filter_apply = BUTTON_NEW_FROM_STOCK(GTK_STOCK_APPLY);
4649     OBJECT_SET_DATA(filter_apply, E_DFILTER_CM_KEY, filter_cm);
4650     SIGNAL_CONNECT(filter_apply, "clicked", filter_activate_cb, filter_te);
4651     gtk_widget_show(filter_apply);
4652     gtk_toolbar_append_widget(GTK_TOOLBAR(filter_tb), filter_apply,
4653         "Apply this filter string to the display", "Private");
4654
4655     /* Sets the text entry widget pointer as the E_DILTER_TE_KEY data
4656      * of any widget that ends up calling a callback which needs
4657      * that text entry pointer */
4658     set_menu_object_data("/File/Open...", E_DFILTER_TE_KEY, filter_te);
4659     set_menu_object_data("/Edit/Copy/As Filter", E_DFILTER_TE_KEY,
4660                          filter_te);
4661     set_menu_object_data("/Analyze/Display Filters...", E_FILT_TE_PTR_KEY,
4662                          filter_te);
4663     set_menu_object_data("/Analyze/Follow TCP Stream", E_DFILTER_TE_KEY,
4664                          filter_te);
4665     set_menu_object_data("/Analyze/Follow SSL Stream", E_DFILTER_TE_KEY,
4666                          filter_te);
4667     set_menu_object_data("/Analyze/Apply as Filter/Selected", E_DFILTER_TE_KEY,
4668                          filter_te);
4669     set_menu_object_data("/Analyze/Apply as Filter/Not Selected", E_DFILTER_TE_KEY,
4670                          filter_te);
4671     set_menu_object_data("/Analyze/Apply as Filter/... and Selected", E_DFILTER_TE_KEY,
4672                          filter_te);
4673     set_menu_object_data("/Analyze/Apply as Filter/... or Selected", E_DFILTER_TE_KEY,
4674                          filter_te);
4675     set_menu_object_data("/Analyze/Apply as Filter/... and not Selected", E_DFILTER_TE_KEY,
4676                          filter_te);
4677     set_menu_object_data("/Analyze/Apply as Filter/... or not Selected", E_DFILTER_TE_KEY,
4678                          filter_te);
4679     set_menu_object_data("/Analyze/Prepare a Filter/Selected", E_DFILTER_TE_KEY,
4680                          filter_te);
4681     set_menu_object_data("/Analyze/Prepare a Filter/Not Selected", E_DFILTER_TE_KEY,
4682                          filter_te);
4683     set_menu_object_data("/Analyze/Prepare a Filter/... and Selected", E_DFILTER_TE_KEY,
4684                          filter_te);
4685     set_menu_object_data("/Analyze/Prepare a Filter/... or Selected", E_DFILTER_TE_KEY,
4686                          filter_te);
4687     set_menu_object_data("/Analyze/Prepare a Filter/... and not Selected", E_DFILTER_TE_KEY,
4688                          filter_te);
4689     set_menu_object_data("/Analyze/Prepare a Filter/... or not Selected", E_DFILTER_TE_KEY,
4690                          filter_te);
4691     set_menu_object_data("/Conversation Filter/Ethernet", E_DFILTER_TE_KEY,
4692                          filter_te);
4693     set_menu_object_data("/Conversation Filter/IP", E_DFILTER_TE_KEY,
4694                          filter_te);
4695     set_menu_object_data("/Conversation Filter/TCP", E_DFILTER_TE_KEY,
4696                          filter_te);
4697     set_menu_object_data("/Conversation Filter/UDP", E_DFILTER_TE_KEY,
4698                          filter_te);
4699     set_menu_object_data("/Conversation Filter/PN-CBA Server", E_DFILTER_TE_KEY,
4700                          filter_te);
4701     set_toolbar_object_data(E_DFILTER_TE_KEY, filter_te);
4702     OBJECT_SET_DATA(popup_menu_object, E_DFILTER_TE_KEY, filter_te);
4703     OBJECT_SET_DATA(popup_menu_object, E_MPACKET_LIST_KEY, packet_list);
4704
4705     /* info (main) statusbar */
4706     info_bar = info_bar_new();
4707     gtk_widget_show(info_bar);
4708
4709     /* packets statusbar */
4710     packets_bar = packets_bar_new();
4711     gtk_widget_show(packets_bar);
4712
4713     /* Filter/status hbox */
4714     stat_hbox = gtk_hbox_new(FALSE, 1);
4715     gtk_container_border_width(GTK_CONTAINER(stat_hbox), 0);
4716     gtk_widget_show(stat_hbox);
4717
4718     /* Pane for the statusbar */
4719     status_pane = gtk_hpaned_new();
4720     gtk_widget_show(status_pane);
4721
4722     /* Pane for the welcome screen */
4723     welcome_pane = welcome_new();
4724     gtk_widget_show(welcome_pane);
4725 }
4726
4727 #ifdef HAVE_AIRPCAP
4728 static void
4729 driver_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
4730 {
4731     gboolean r;
4732
4733     r = simple_dialog_check_get(dialog);
4734     recent.airpcap_driver_check_show = !r;
4735 }
4736 #endif
4737
4738 static void
4739 show_main_window(gboolean doing_work)
4740 {
4741   main_set_for_capture_file(doing_work);
4742
4743   /*** we have finished all init things, show the main window ***/
4744   gtk_widget_show(top_level);
4745
4746   /* the window can be maximized only, if it's visible, so do it after show! */
4747   main_load_window_geometry(top_level);
4748
4749   /* process all pending GUI events before continue */
4750   while (gtk_events_pending()) gtk_main_iteration();
4751
4752   /* Pop up any queued-up alert boxes. */
4753   display_queued_messages();
4754
4755 #ifdef HAVE_AIRPCAP
4756   /*
4757    * This will read the decryption keys from the preferences file, and will
4758    * store them into the registry...
4759    */
4760   if(!airpcap_check_decryption_keys(airpcap_if_list)) {
4761     /* Ask the user what to do ...*/
4762     airpcap_keys_check_w(NULL,NULL);
4763   } else {
4764     /* Keys from lists are equals, or wireshark has got no keys */
4765     airpcap_load_decryption_keys(airpcap_if_list);
4766   }
4767
4768   switch (airpcap_dll_ret_val) {
4769
4770   case AIRPCAP_DLL_OK:
4771     break;
4772
4773   case AIRPCAP_DLL_OLD:
4774     if(recent.airpcap_driver_check_show) {
4775       driver_warning_dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s",
4776                         "WARNING: The version of AirPcap on this system\n"
4777                         "does not support driver-level decryption.  Please\n"
4778                         "download a more recent version from\n" "http://www.cacetech.com/support/downloads.htm \n");
4779       simple_dialog_check_set(driver_warning_dialog,"Don't show this message again.");
4780       simple_dialog_set_cb(driver_warning_dialog, driver_warning_dialog_cb, (gpointer) driver_warning_dialog);
4781     }
4782     break;
4783
4784 #if 0
4785   /*
4786    * XXX - Maybe we need to warn the user if one of the following happens???
4787    */
4788   case AIRPCAP_DLL_ERROR:
4789     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
4790     break;
4791
4792   case AIRPCAP_DLL_NOT_FOUND:
4793     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
4794     break;
4795 #endif
4796   }
4797 #endif /* HAVE_AIRPCAP */
4798 }
4799
4800 /* Fill in capture options with values from the preferences */
4801 void
4802 prefs_to_capture_opts(void)
4803 {
4804 #ifdef HAVE_LIBPCAP
4805   /* Set promiscuous mode from the preferences setting. */
4806   /* the same applies to other preferences settings as well. */
4807     capture_opts->promisc_mode   = prefs.capture_prom_mode;
4808     capture_opts->show_info      = prefs.capture_show_info;
4809     capture_opts->real_time_mode = prefs.capture_real_time;
4810     auto_scroll_live             = prefs.capture_auto_scroll;
4811 #endif /* HAVE_LIBPCAP */
4812
4813   /* Set the name resolution code's flags from the preferences. */
4814   g_resolv_flags = prefs.name_resolve;
4815 }