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