Add GCC-style printf annotation to the routines that now take a format
[obnox/wireshark/wip.git] / gtk / main_statusbar.c
index b3247862f9abc18f8bc12171cee8fef616d58d0b..315c21b63c18cfc5ee5bbf7302c536ab66872248 100644 (file)
@@ -6,7 +6,6 @@
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
 
 
 #ifdef HAVE_CONFIG_H
-# include "config.h"
+#include "config.h"
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
 #endif
 
 #include <gtk/gtk.h>
 #include <epan/expert.h>
 #include <epan/prefs.h>
 
-#include "cfile.h"
-#include "file.h"
-#include "capture_opts.h"
-#include "capture_ui_utils.h"
-#include "recent.h"
-#include "main.h"
-#include "main_statusbar.h"
-#include "gui_utils.h"
-#include "gtkglobals.h"
-#include "expert_comp_dlg.h"
+#include "../cfile.h"
+#include "../file.h"
+#ifdef HAVE_LIBPCAP
+#include "../capture_opts.h"
+#include "../capture_ui_utils.h"
+#include "../capture.h"
+#endif
+
+#include "gtk/recent.h"
+#include "gtk/main.h"
+#include "gtk/main_statusbar_private.h"
+#include "gtk/gui_utils.h"
+#include "gtk/gtkglobals.h"
+#include "gtk/expert_comp_dlg.h"
+#include "gtk/profile_dlg.h"
+#include "gtk/main_welcome.h"
+#include "gtk/expert_indicators.h"
+#include "gtk/keys.h"
+#include "gtk/menus.h"
 
-#include "../image/expert_error.xpm"
-#include "../image/expert_warn.xpm"
-#include "../image/expert_note.xpm"
-#include "../image/expert_chat.xpm"
-#include "../image/expert_none.xpm"
+#include "main_statusbar.h"
 
 /*
  * The order below defines the priority of info bar contexts.
@@ -71,30 +79,41 @@ typedef enum {
 #endif
 
 
-GtkWidget    *status_pane_left, *status_pane_right;
-GtkWidget    *info_bar, *packets_bar, *profile_bar;
-GtkWidget    *expert_info_error, *expert_info_warn, *expert_info_note;
-GtkWidget    *expert_info_chat, *expert_info_none;
+static GtkWidget    *status_pane_left, *status_pane_right;
+static GtkWidget    *info_bar, *info_bar_event, *packets_bar, *profile_bar, *profile_bar_event;
+static GtkWidget    *expert_info_error, *expert_info_warn, *expert_info_note;
+static GtkWidget    *expert_info_chat, *expert_info_none;
 
-static guint        main_ctx, file_ctx, help_ctx, filter_ctx, packets_ctx, profile_ctx;
-static guint        status_levels[NUM_STATUS_LEVELS];
+static guint         main_ctx, file_ctx, help_ctx, filter_ctx, packets_ctx, profile_ctx;
+static guint         status_levels[NUM_STATUS_LEVELS];
 static gchar        *packets_str = NULL;
 static gchar        *profile_str = NULL;
 
 
-GtkWidget *info_bar_new(void);
-GtkWidget *packets_bar_new(void);
-GtkWidget *profile_bar_new(void);
-void status_expert_new(void);
+static void info_bar_new(void);
+static void packets_bar_new(void);
+static void profile_bar_new(void);
+static void status_expert_new(void);
 
+/* Temporary message timeouts */
+#define TEMPORARY_MSG_TIMEOUT (7 * 1000)
+#define TEMPORARY_FLASH_TIMEOUT (1 * 1000)
+#define TEMPORARY_FLASH_INTERVAL (TEMPORARY_FLASH_TIMEOUT / 4)
+static gint flash_time;
+static gboolean flash_highlight = FALSE;
 
+static void
+statusbar_push_file_msg(const gchar *msg_format, ...)
+    G_GNUC_PRINTF(1, 2);
 
 /*
- * Push a message referring to file access onto the statusbar.
+ * Push a formatted message referring to file access onto the statusbar.
  */
 static void
-statusbar_push_file_msg(const gchar *msg)
+statusbar_push_file_msg(const gchar *msg_format, ...)
 {
+    va_list ap;
+    gchar *msg;
     int i;
 
     /*g_warning("statusbar_push: %s", msg);*/
@@ -103,7 +122,13 @@ statusbar_push_file_msg(const gchar *msg)
             return;
     }
     status_levels[STATUS_LEVEL_FILE]++;
+
+    va_start(ap, msg_format);
+    msg = g_strdup_vprintf(msg_format, ap);
+    va_end(ap);
+
     gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, msg);
+    g_free(msg);
 }
 
 /*
@@ -120,11 +145,14 @@ statusbar_pop_file_msg(void)
 }
 
 /*
- * Push a message referring to the currently-selected field onto the statusbar.
+ * Push a formatted message referring to the currently-selected field onto
+ * the statusbar.
  */
 void
-statusbar_push_field_msg(const gchar *msg)
+statusbar_push_field_msg(const gchar *msg_format, ...)
 {
+    va_list ap;
+    gchar *msg;
     int i;
 
     for (i = STATUS_LEVEL_HELP + 1; i < NUM_STATUS_LEVELS; i++) {
@@ -133,7 +161,12 @@ statusbar_push_field_msg(const gchar *msg)
     }
     status_levels[STATUS_LEVEL_HELP]++;
 
+    va_start(ap, msg_format);
+    msg = g_strdup_vprintf(msg_format, ap);
+    va_end(ap);
+
     gtk_statusbar_push(GTK_STATUSBAR(info_bar), help_ctx, msg);
+    g_free(msg);
 }
 
 /*
@@ -149,11 +182,13 @@ statusbar_pop_field_msg(void)
 }
 
 /*
- * Push a message referring to the current filter onto the statusbar.
+ * Push a formatted message referring to the current filter onto the statusbar.
  */
 void
-statusbar_push_filter_msg(const gchar *msg)
+statusbar_push_filter_msg(const gchar *msg_format, ...)
 {
+    va_list ap;
+    gchar *msg;
     int i;
 
     for (i = STATUS_LEVEL_FILTER + 1; i < NUM_STATUS_LEVELS; i++) {
@@ -162,7 +197,12 @@ statusbar_push_filter_msg(const gchar *msg)
     }
     status_levels[STATUS_LEVEL_FILTER]++;
 
+    va_start(ap, msg_format);
+    msg = g_strdup_vprintf(msg_format, ap);
+    va_end(ap);
+
     gtk_statusbar_push(GTK_STATUSBAR(info_bar), filter_ctx, msg);
+    g_free(msg);
 }
 
 /*
@@ -177,32 +217,91 @@ statusbar_pop_filter_msg(void)
     gtk_statusbar_pop(GTK_STATUSBAR(info_bar), filter_ctx);
 }
 
+/*
+ * Timeout callbacks for statusbar_push_temporary_msg
+ */
+static gboolean
+statusbar_remove_temporary_msg(gpointer data)
+{
+    guint msg_id = GPOINTER_TO_UINT(data);
+
+    gtk_statusbar_remove(GTK_STATUSBAR(info_bar), main_ctx, msg_id);
+
+    return FALSE;
+}
+
+static gboolean
+statusbar_flash_temporary_msg(gpointer data _U_)
+{
+    gboolean retval = TRUE;
+
+    if (flash_time > 0) {
+        flash_highlight = !flash_highlight;
+    } else {
+        flash_highlight = FALSE;
+        retval = FALSE;
+    }
+
+    /*
+     * As of 2.18.3 gtk_drag_highlight just draws a border around the widget
+     * so we can abuse it here.
+     */
+    if (flash_highlight) {
+        gtk_drag_highlight(info_bar);
+    } else {
+        gtk_drag_unhighlight(info_bar);
+    }
+
+    flash_time -= TEMPORARY_FLASH_INTERVAL;
+
+    return retval;
+}
+
+/*
+ * Push a formatted temporary message onto the statusbar.
+ */
+void
+statusbar_push_temporary_msg(const gchar *msg_format, ...)
+{
+    va_list ap;
+    gchar *msg;
+    guint msg_id;
+
+    va_start(ap, msg_format);
+    msg = g_strdup_vprintf(msg_format, ap);
+    va_end(ap);
+
+    msg_id = gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, msg);
+    g_free(msg);
+
+    flash_time = TEMPORARY_FLASH_TIMEOUT - 1;
+    g_timeout_add(TEMPORARY_FLASH_INTERVAL, statusbar_flash_temporary_msg, NULL);
+
+    g_timeout_add(TEMPORARY_MSG_TIMEOUT, statusbar_remove_temporary_msg, GUINT_TO_POINTER(msg_id));
+}
+
 
 GtkWidget *
 statusbar_new(void)
 {
     GtkWidget *status_hbox;
 
+    /* Status hbox */
+    status_hbox = gtk_hbox_new(FALSE, 1);
+    gtk_container_set_border_width(GTK_CONTAINER(status_hbox), 0);
+
     /* info (main) statusbar */
-    info_bar = info_bar_new();
-    gtk_widget_show(info_bar);
+    info_bar_new();
 
     /* packets statusbar */
-    packets_bar = packets_bar_new();
-    gtk_widget_show(packets_bar);
+    packets_bar_new();
 
     /* profile statusbar */
-    profile_bar = profile_bar_new();
-    gtk_widget_show(profile_bar);
+    profile_bar_new();
 
     /* expert info indicator */
     status_expert_new();
 
-    /* Filter/status hbox */
-    status_hbox = gtk_hbox_new(FALSE, 1);
-    gtk_container_border_width(GTK_CONTAINER(status_hbox), 0);
-    gtk_widget_show(status_hbox);
-
     /* Pane for the statusbar */
     status_pane_left = gtk_hpaned_new();
     gtk_widget_show(status_pane_left);
@@ -240,16 +339,18 @@ foreach_remove_a_child(GtkWidget *widget, gpointer data) {
 void
 statusbar_widgets_emptying(GtkWidget *statusbar)
 {
-    gtk_widget_ref(info_bar);
-    gtk_widget_ref(packets_bar);
-    gtk_widget_ref(profile_bar);
-    gtk_widget_ref(status_pane_left);
-    gtk_widget_ref(status_pane_right);
-    gtk_widget_ref(expert_info_error);
-    gtk_widget_ref(expert_info_warn);
-    gtk_widget_ref(expert_info_note);
-    gtk_widget_ref(expert_info_chat);
-    gtk_widget_ref(expert_info_none);
+    g_object_ref(G_OBJECT(info_bar));
+    g_object_ref(G_OBJECT(info_bar_event));
+    g_object_ref(G_OBJECT(packets_bar));
+    g_object_ref(G_OBJECT(profile_bar));
+    g_object_ref(G_OBJECT(profile_bar_event));
+    g_object_ref(G_OBJECT(status_pane_left));
+    g_object_ref(G_OBJECT(status_pane_right));
+    g_object_ref(G_OBJECT(expert_info_error));
+    g_object_ref(G_OBJECT(expert_info_warn));
+    g_object_ref(G_OBJECT(expert_info_note));
+    g_object_ref(G_OBJECT(expert_info_chat));
+    g_object_ref(G_OBJECT(expert_info_none));
 
     /* empty all containers participating */
     gtk_container_foreach(GTK_CONTAINER(statusbar),     foreach_remove_a_child, statusbar);
@@ -260,16 +361,16 @@ statusbar_widgets_emptying(GtkWidget *statusbar)
 void
 statusbar_widgets_pack(GtkWidget *statusbar)
 {
-    gtk_box_pack_start(GTK_BOX(statusbar), expert_info_error, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(statusbar), expert_info_warn, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(statusbar), expert_info_note, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(statusbar), expert_info_chat, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(statusbar), expert_info_none, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(statusbar), expert_info_error, FALSE, FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(statusbar), expert_info_warn, FALSE, FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(statusbar), expert_info_note, FALSE, FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(statusbar), expert_info_chat, FALSE, FALSE, 2);
+    gtk_box_pack_start(GTK_BOX(statusbar), expert_info_none, FALSE, FALSE, 2);
     gtk_box_pack_start(GTK_BOX(statusbar), status_pane_left, TRUE, TRUE, 0);
-    gtk_paned_pack1(GTK_PANED(status_pane_left), info_bar, FALSE, FALSE);
+    gtk_paned_pack1(GTK_PANED(status_pane_left), info_bar_event, FALSE, FALSE);
     gtk_paned_pack2(GTK_PANED(status_pane_left), status_pane_right, TRUE, FALSE);
     gtk_paned_pack1(GTK_PANED(status_pane_right), packets_bar, TRUE, FALSE);
-    gtk_paned_pack2(GTK_PANED(status_pane_right), profile_bar, FALSE, FALSE);
+    gtk_paned_pack2(GTK_PANED(status_pane_right), profile_bar_event, FALSE, FALSE);
 }
 
 void
@@ -300,13 +401,14 @@ statusbar_widgets_show_or_hide(GtkWidget *statusbar)
 }
 
 
-static GtkWidget *
+static void
 info_bar_new(void)
 {
     int i;
 
-    /* tip: tooltips don't work on statusbars! */
+    info_bar_event = gtk_event_box_new();
     info_bar = gtk_statusbar_new();
+    gtk_container_add(GTK_CONTAINER(info_bar_event), info_bar);
     main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
     file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");
     help_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "help");
@@ -318,10 +420,11 @@ info_bar_new(void)
         status_levels[i] = 0;
     }
 
-    return info_bar;
+    gtk_widget_show(info_bar);
+    gtk_widget_show(info_bar_event);
 }
 
-static GtkWidget *
+static void
 packets_bar_new(void)
 {
     /* tip: tooltips don't work on statusbars! */
@@ -330,43 +433,67 @@ packets_bar_new(void)
     packets_bar_update();
     gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(packets_bar), FALSE);
 
-    return packets_bar;
+    gtk_widget_show(packets_bar);
 }
 
-static GtkWidget *
+static void
 profile_bar_new(void)
 {
-    /* tip: tooltips don't work on statusbars! */
+    GtkTooltips   *tooltips;
+
+    tooltips = gtk_tooltips_new();
+
+    profile_bar_event = gtk_event_box_new();
     profile_bar = gtk_statusbar_new();
+    gtk_container_add(GTK_CONTAINER(profile_bar_event), profile_bar);
+    g_signal_connect(profile_bar_event, "button_press_event", G_CALLBACK(profile_show_popup_cb), NULL);
+    g_signal_connect(profile_bar_event, "button_press_event", G_CALLBACK(popup_menu_handler),
+                    g_object_get_data(G_OBJECT(popup_menu_object), PM_STATUSBAR_PROFILES_KEY));
     profile_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(profile_bar), "profile");
+    gtk_tooltips_set_tip (tooltips, profile_bar_event,
+                          "Click to change configuration profile", NULL);
     profile_bar_update();
 
-    return profile_bar;
+    gtk_widget_show(profile_bar);
+    gtk_widget_show(profile_bar_event);
 }
 
 
 /*
- * update the packets statusbar to the current values
+ * Update the packets statusbar to the current values
  */
-void 
+void
 packets_bar_update(void)
 {
-
     if(packets_bar) {
-        /* remove old status */
+        /* Remove old status */
         if(packets_str) {
             g_free(packets_str);
             gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
         }
 
-        /* do we have any packets? */
+        /* Do we have any packets? */
         if(cfile.count) {
             if(cfile.drops_known) {
                 packets_str = g_strdup_printf(" Packets: %u Displayed: %u Marked: %u Dropped: %u",
                     cfile.count, cfile.displayed_count, cfile.marked_count, cfile.drops);
+            } else if (cfile.ignored_count > 0) {
+                packets_str = g_strdup_printf(" Packets: %u Displayed: %u Marked: %u Ignored: %u",
+                    cfile.count, cfile.displayed_count, cfile.marked_count, cfile.ignored_count);
             } else {
-                packets_str = g_strdup_printf(" Packets: %u Displayed: %u Marked: %u",
-                    cfile.count, cfile.displayed_count, cfile.marked_count);
+                if(cfile.is_tempfile){
+                    /* Live capture */
+                    packets_str = g_strdup_printf(" Packets: %u Displayed: %u Marked: %u",
+                                                  cfile.count, cfile.displayed_count, cfile.marked_count);
+                }else{
+                    /* Loading an existing file */
+                    gulong computed_elapsed = cf_get_computed_elapsed();
+                    packets_str = g_strdup_printf(" Packets: %u Displayed: %u Marked: %u Load time: %lu:%02lu.%03lu",
+                                                  cfile.count, cfile.displayed_count, cfile.marked_count,
+                                                  computed_elapsed/60000,
+                                                  computed_elapsed%60000/1000,
+                                                  computed_elapsed%1000);
+                }
             }
         } else {
             packets_str = g_strdup(" No Packets");
@@ -376,7 +503,7 @@ packets_bar_update(void)
 }
 
 /*
- * update the packets statusbar to the current values
+ * Update the packets statusbar to the current values
  */
 void
 profile_bar_update(void)
@@ -388,12 +515,19 @@ profile_bar_update(void)
             gtk_statusbar_pop(GTK_STATUSBAR(profile_bar), profile_ctx);
         }
 
-       profile_str = g_strdup_printf (" Profile: %s", get_profile_name ());
-
+        profile_str = g_strdup_printf (" Profile: %s", get_profile_name ());
         gtk_statusbar_push(GTK_STATUSBAR(profile_bar), profile_ctx, profile_str);
+
+        set_menus_for_profiles(is_default_profile());
     }
 }
 
+static gboolean
+expert_comp_dlg_event_cb(GtkWidget *w _U_, GdkEventButton *event _U_, gpointer user_data _U_)
+{
+    expert_comp_dlg_launch();
+    return TRUE;
+}
 
 static void
 status_expert_new(void)
@@ -403,40 +537,40 @@ status_expert_new(void)
 
     tooltips = gtk_tooltips_new();
 
-    expert_image = xpm_to_widget_from_parent(top_level, expert_error_xpm);
+    expert_image = pixbuf_to_widget(expert_error_pb_data);
     gtk_tooltips_set_tip(tooltips, expert_image, "ERROR is the highest expert info level", NULL);
     gtk_widget_show(expert_image);
     expert_info_error = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(expert_info_error), expert_image);
-    g_signal_connect(expert_info_error, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
+    g_signal_connect(expert_info_error, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
 
-    expert_image = xpm_to_widget_from_parent(top_level, expert_warn_xpm);
+    expert_image = pixbuf_to_widget(expert_warn_pb_data);
     gtk_tooltips_set_tip(tooltips, expert_image, "WARNING is the highest expert info level", NULL);
     gtk_widget_show(expert_image);
     expert_info_warn = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(expert_info_warn), expert_image);
-    g_signal_connect(expert_info_warn, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
+    g_signal_connect(expert_info_warn, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
 
-    expert_image = xpm_to_widget_from_parent(top_level, expert_note_xpm);
+    expert_image = pixbuf_to_widget(expert_note_pb_data);
     gtk_tooltips_set_tip(tooltips, expert_image, "NOTE is the highest expert info level", NULL);
     gtk_widget_show(expert_image);
     expert_info_note = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(expert_info_note), expert_image);
-    g_signal_connect(expert_info_note, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
+    g_signal_connect(expert_info_note, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
 
-    expert_image = xpm_to_widget_from_parent(top_level, expert_chat_xpm);
+    expert_image = pixbuf_to_widget(expert_chat_pb_data);
     gtk_tooltips_set_tip(tooltips, expert_image, "CHAT is the highest expert info level", NULL);
     gtk_widget_show(expert_image);
     expert_info_chat = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(expert_info_chat), expert_image);
-    g_signal_connect(expert_info_chat, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
+    g_signal_connect(expert_info_chat, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
 
-    expert_image = xpm_to_widget_from_parent(top_level, expert_none_xpm);
+    expert_image = pixbuf_to_widget(expert_none_pb_data);
     gtk_tooltips_set_tip(tooltips, expert_image, "No expert info", NULL);
     gtk_widget_show(expert_image);
     expert_info_none = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(expert_info_none), expert_image);
-    g_signal_connect(expert_info_none, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
+    g_signal_connect(expert_info_none, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
     gtk_widget_show(expert_info_none);
 }
 
@@ -451,25 +585,25 @@ status_expert_hide(void)
     gtk_widget_hide(expert_info_none);
 }
 
-static void
+void
 status_expert_update(void)
 {
     status_expert_hide();
 
     switch(expert_get_highest_severity()) {
-        case(PI_ERROR):
+    case(PI_ERROR):
         gtk_widget_show(expert_info_error);
         break;
-        case(PI_WARN):
+    case(PI_WARN):
         gtk_widget_show(expert_info_warn);
         break;
-        case(PI_NOTE):
+    case(PI_NOTE):
         gtk_widget_show(expert_info_note);
         break;
-        case(PI_CHAT):
+    case(PI_CHAT):
         gtk_widget_show(expert_info_chat);
         break;
-        default:
+    default:
         gtk_widget_show(expert_info_none);
         break;
     }
@@ -478,35 +612,32 @@ status_expert_update(void)
 static void
 statusbar_set_filename(const char *file_name, gint64 file_length, nstime_t *file_elapsed_time)
 {
-  gchar       *size_str;
-  gchar       *status_msg;
+    gchar       *size_str;
 
-  /* expert info indicator */
-  status_expert_update();
+    /* expert info indicator */
+    status_expert_update();
 
-  /* statusbar */
-  /* convert file size */
-  if (file_length/1024/1024 > 10) {
-    size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d MB", file_length/1024/1024);
-  } else if (file_length/1024 > 10) {
-    size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d KB", file_length/1024);
-  } else {
-    size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d Bytes", file_length);
-  }
+    /* statusbar */
+    /* convert file size */
+    if (file_length/1024/1024 > 10) {
+        size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d MB", file_length/1024/1024);
+    } else if (file_length/1024 > 10) {
+        size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d KB", file_length/1024);
+    } else {
+        size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d Bytes", file_length);
+    }
 
-  status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu",
-    (file_name) ? file_name : "", size_str,
-    (long)file_elapsed_time->secs/3600,
-    (long)file_elapsed_time->secs%3600/60,
-    (long)file_elapsed_time->secs%60);
-  g_free(size_str);
-  statusbar_push_file_msg(status_msg);
-  g_free(status_msg);
+    statusbar_push_file_msg(" File: \"%s\" %s %02lu:%02lu:%02lu",
+                            (file_name) ? file_name : "", size_str,
+                            (long)file_elapsed_time->secs/3600,
+                            (long)file_elapsed_time->secs%3600/60,
+                            (long)file_elapsed_time->secs%60);
+    g_free(size_str);
 }
 
 
 static void
-statusbar_cf_file_closing_cb(capture_file *cf)
+statusbar_cf_file_closing_cb(capture_file *cf _U_)
 {
     /* Clear any file-related status bar messages.
        XXX - should be "clear *ALL* file-related status bar messages;
@@ -522,25 +653,22 @@ statusbar_cf_file_closing_cb(capture_file *cf)
 static void
 statusbar_cf_file_closed_cb(capture_file *cf _U_)
 {
-  /* go back to "No packets" */
-  packets_bar_update();
+    /* go back to "No packets" */
+    packets_bar_update();
 }
 
 
 static void
-statusbar_cf_file_read_start_cb(capture_file *cf)
+statusbar_cf_file_read_started_cb(capture_file *cf)
 {
-  const gchar *name_ptr;
-  gchar       *load_msg;
+    const gchar *name_ptr;
 
-  /* Ensure we pop any previous loaded filename */
-  statusbar_pop_file_msg();
+    /* Ensure we pop any previous loaded filename */
+    statusbar_pop_file_msg();
 
-  name_ptr = get_basename(cf->filename);
+    name_ptr = get_basename(cf->filename);
 
-  load_msg = g_strdup_printf(" Loading: %s", name_ptr);
-  statusbar_push_file_msg(load_msg);
-  g_free(load_msg);
+    statusbar_push_file_msg(" Loading: %s", name_ptr);
 }
 
 
@@ -554,92 +682,83 @@ statusbar_cf_file_read_finished_cb(capture_file *cf)
 
 #ifdef HAVE_LIBPCAP
 static void
-statusbar_cf_live_capture_prepared_cb(capture_options *capture_opts)
+statusbar_capture_prepared_cb(capture_options *capture_opts _U_)
 {
-    statusbar_push_file_msg(" Waiting for capture input data ...");
+    static const gchar msg[] = " Waiting for capture input data ...";
+    statusbar_push_file_msg(msg);
+    welcome_header_push_msg(msg);
 }
 
 static void
-statusbar_cf_live_capture_update_started_cb(capture_options *capture_opts)
+statusbar_capture_update_started_cb(capture_options *capture_opts)
 {
-    gchar *capture_msg;
-
-
     statusbar_pop_file_msg();
+    welcome_header_pop_msg();
 
     if(capture_opts->iface) {
-        capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
-                                     get_iface_description(capture_opts),
-                                     (capture_opts->save_file) ? capture_opts->save_file : "");
+        statusbar_push_file_msg(" %s: <live capture in progress> to file: %s",
+                                get_iface_description(capture_opts),
+                                (capture_opts->save_file) ? capture_opts->save_file : "");
     } else {
-        capture_msg = g_strdup_printf(" <live capture in progress> to file: %s",
-            (capture_opts->save_file) ? capture_opts->save_file : "");
+        statusbar_push_file_msg(" <live capture in progress> to file: %s",
+                                (capture_opts->save_file) ? capture_opts->save_file : "");
     }
-
-    statusbar_push_file_msg(capture_msg);
-
-    g_free(capture_msg);
 }
 
 static void
-statusbar_cf_live_capture_update_continue_cb(capture_file *cf)
+statusbar_capture_update_continue_cb(capture_options *capture_opts)
 {
-    gchar *capture_msg;
-
+    capture_file *cf = capture_opts->cf;
 
     status_expert_update();
 
     statusbar_pop_file_msg();
 
     if (cf->f_datalen/1024/1024 > 10) {
-        capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d MB",
-                                     get_iface_description(capture_opts),
-                                     capture_opts->save_file,
-                                     cf->f_datalen/1024/1024);
+        statusbar_push_file_msg(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d MB",
+                                get_iface_description(capture_opts),
+                                capture_opts->save_file,
+                                cf->f_datalen/1024/1024);
     } else if (cf->f_datalen/1024 > 10) {
-        capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d KB",
-                                     get_iface_description(capture_opts),
-                                     capture_opts->save_file,
-                                     cf->f_datalen/1024);
+        statusbar_push_file_msg(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d KB",
+                                get_iface_description(capture_opts),
+                                capture_opts->save_file,
+                                cf->f_datalen/1024);
     } else {
-        capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d Bytes",
-                                     get_iface_description(capture_opts),
-                                     capture_opts->save_file,
-                                     cf->f_datalen);
+        statusbar_push_file_msg(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d Bytes",
+                                get_iface_description(capture_opts),
+                                capture_opts->save_file,
+                                cf->f_datalen);
     }
-
-    statusbar_push_file_msg(capture_msg);
 }
 
 static void
-statusbar_cf_live_capture_update_finished_cb(capture_file *cf)
+statusbar_capture_update_finished_cb(capture_options *capture_opts)
 {
+    capture_file *cf = capture_opts->cf;
+
     /* Pop the "<live capture in progress>" message off the status bar. */
     statusbar_pop_file_msg();
     statusbar_set_filename(cf->filename, cf->f_datalen, &(cf->elapsed_time));
+    packets_bar_update();
 }
 
 static void
-statusbar_cf_live_capture_fixed_started_cb(capture_options *capture_opts)
+statusbar_capture_fixed_started_cb(capture_options *capture_opts)
 {
-    gchar *capture_msg;
-
-
     statusbar_pop_file_msg();
 
-    capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
-                                 get_iface_description(capture_opts),
-                                 (capture_opts->save_file) ? capture_opts->save_file : "");
+    statusbar_push_file_msg(" %s: <live capture in progress> to file: %s",
+                            get_iface_description(capture_opts),
+                            (capture_opts->save_file) ? capture_opts->save_file : "");
 
-    statusbar_push_file_msg(capture_msg);
     gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, " Packets: 0");
-
-    g_free(capture_msg);
 }
 
 static void
-statusbar_cf_live_capture_fixed_continue_cb(capture_file *cf)
+statusbar_capture_fixed_continue_cb(capture_options *capture_opts)
 {
+    capture_file *cf = capture_opts->cf;
     gchar *capture_msg;
 
 
@@ -651,10 +770,15 @@ statusbar_cf_live_capture_fixed_continue_cb(capture_file *cf)
 
 
 static void
-statusbar_cf_live_capture_fixed_finished_cb(capture_file *cf _U_)
+statusbar_capture_fixed_finished_cb(capture_options *capture_opts _U_)
 {
+#if 0
+    capture_file *cf = capture_opts->cf;
+#endif
+
     /* Pop the "<live capture in progress>" message off the status bar. */
     statusbar_pop_file_msg();
+    welcome_header_pop_msg();
 
     /* Pop the "<capturing>" message off the status bar */
     gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
@@ -664,30 +788,35 @@ statusbar_cf_live_capture_fixed_finished_cb(capture_file *cf _U_)
 
 
 static void
-statusbar_cf_field_unselected_cb(capture_file *cf)
+statusbar_cf_field_unselected_cb(capture_file *cf _U_)
 {
     statusbar_pop_field_msg();
 }
 
 static void
-statusbar_cf_file_safe_started_cb(gchar * filename)
+statusbar_cf_file_save_started_cb(gchar *filename)
 {
-    gchar        *save_msg;
-
-    save_msg = g_strdup_printf(" Saving: %s...", get_basename(filename));
-    statusbar_push_file_msg(save_msg);
-    g_free(save_msg);
+    statusbar_pop_file_msg();
+    statusbar_push_file_msg(" Saving: %s...", get_basename(filename));
 }
 
 static void
-statusbar_cf_file_safe_finished_cb(gpointer data _U_)
+statusbar_cf_file_save_finished_cb(gpointer data _U_)
 {
     /* Pop the "Saving:" message off the status bar. */
     statusbar_pop_file_msg();
 }
 
 static void
-statusbar_cf_file_safe_failed_cb(gpointer data _U_)
+statusbar_cf_file_reload_finished_cb(capture_file *cf)
+{
+    statusbar_pop_file_msg();
+    statusbar_set_filename(cf->filename, cf->f_datalen, &(cf->elapsed_time));
+}
+
+
+static void
+statusbar_cf_file_save_failed_cb(gpointer data _U_)
 {
     /* Pop the "Saving:" message off the status bar. */
     statusbar_pop_file_msg();
@@ -705,60 +834,71 @@ statusbar_cf_callback(gint event, gpointer data, gpointer user_data _U_)
     case(cf_cb_file_closed):
         statusbar_cf_file_closed_cb(data);
         break;
-    case(cf_cb_file_read_start):
-        statusbar_cf_file_read_start_cb(data);
+    case(cf_cb_file_read_started):
+        statusbar_cf_file_read_started_cb(data);
         break;
     case(cf_cb_file_read_finished):
         statusbar_cf_file_read_finished_cb(data);
         break;
-#ifdef HAVE_LIBPCAP
-    case(cf_cb_live_capture_prepared):
-        statusbar_cf_live_capture_prepared_cb(data);
+    case(cf_cb_packet_selected):
         break;
-    case(cf_cb_live_capture_update_started):
-        statusbar_cf_live_capture_update_started_cb(data);
+    case(cf_cb_packet_unselected):
         break;
-    case(cf_cb_live_capture_update_continue):
-        statusbar_cf_live_capture_update_continue_cb(data);
+    case(cf_cb_field_unselected):
+        statusbar_cf_field_unselected_cb(data);
         break;
-    case(cf_cb_live_capture_update_finished):
-        statusbar_cf_live_capture_update_finished_cb(data);
+    case(cf_cb_file_save_started):
+        statusbar_cf_file_save_started_cb(data);
         break;
-    case(cf_cb_live_capture_fixed_started):
-        statusbar_cf_live_capture_fixed_started_cb(data);
+    case(cf_cb_file_save_finished):
+        statusbar_cf_file_save_finished_cb(data);
         break;
-    case(cf_cb_live_capture_fixed_continue):
-        statusbar_cf_live_capture_fixed_continue_cb(data);
+    case(cf_cb_file_save_reload_finished):
+        statusbar_cf_file_reload_finished_cb(data);
         break;
-    case(cf_cb_live_capture_fixed_finished):
-        statusbar_cf_live_capture_fixed_finished_cb(data);
+    case(cf_cb_file_save_failed):
+        statusbar_cf_file_save_failed_cb(data);
         break;
-    case(cf_cb_live_capture_stopping):
-        /* Beware: this state won't be called, if the capture child
-         * closes the capturing on it's own! */
+    default:
+        g_warning("statusbar_cf_callback: event %u unknown", event);
+        g_assert_not_reached();
+    }
+}
+
+#ifdef HAVE_LIBPCAP
+void
+statusbar_capture_callback(gint event, capture_options *capture_opts,
+                           gpointer user_data _U_)
+{
+    switch(event) {
+    case(capture_cb_capture_prepared):
+        statusbar_capture_prepared_cb(capture_opts);
         break;
-#endif
-    case(cf_cb_packet_selected):
+    case(capture_cb_capture_update_started):
+        statusbar_capture_update_started_cb(capture_opts);
         break;
-    case(cf_cb_packet_unselected):
+    case(capture_cb_capture_update_continue):
+        statusbar_capture_update_continue_cb(capture_opts);
         break;
-    case(cf_cb_field_unselected):
-        statusbar_cf_field_unselected_cb(data);
+    case(capture_cb_capture_update_finished):
+        statusbar_capture_update_finished_cb(capture_opts);
         break;
-    case(cf_cb_file_safe_started):
-        statusbar_cf_file_safe_started_cb(data);
+    case(capture_cb_capture_fixed_started):
+        statusbar_capture_fixed_started_cb(capture_opts);
         break;
-    case(cf_cb_file_safe_finished):
-        statusbar_cf_file_safe_finished_cb(data);
+    case(capture_cb_capture_fixed_continue):
+        statusbar_capture_fixed_continue_cb(capture_opts);
         break;
-    case(cf_cb_file_safe_reload_finished):
+    case(capture_cb_capture_fixed_finished):
+        statusbar_capture_fixed_finished_cb(capture_opts);
         break;
-    case(cf_cb_file_safe_failed):
-        statusbar_cf_file_safe_failed_cb(data);
+    case(capture_cb_capture_stopping):
+        /* Beware: this state won't be called, if the capture child
+         * closes the capturing on it's own! */
         break;
     default:
-        g_warning("statusbar_cf_callback: event %u unknown", event);
+        g_warning("statusbar_capture_callback: event %u unknown", event);
         g_assert_not_reached();
     }
 }
-
+#endif