def851b0dcc162d2c9aa4343ac9e911cfc95d907
[obnox/wireshark/wip.git] / gtk / main_statusbar.c
1 /* main_statusbar.c
2  *
3  * $Id$
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  */
23
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #include <gtk/gtk.h>
34
35 #include <epan/epan.h>
36 #include <epan/filesystem.h>
37 #include <epan/epan_dissect.h>
38 #include <epan/expert.h>
39 #include <epan/prefs.h>
40
41 #include "../cfile.h"
42 #include "../file.h"
43 #include "../capture_opts.h"
44 #include "../capture_ui_utils.h"
45 #ifdef HAVE_LIBPCAP
46 #include "../capture.h"
47 #endif
48
49 #include "gtk/recent.h"
50 #include "gtk/main.h"
51 #include "gtk/main_statusbar.h"
52 #include "gtk/main_statusbar_private.h"
53 #include "gtk/gui_utils.h"
54 #include "gtk/gtkglobals.h"
55 #include "gtk/expert_comp_dlg.h"
56 #include "gtk/profile_dlg.h"
57
58 #include "../image/expert_error.xpm"
59 #include "../image/expert_warn.xpm"
60 #include "../image/expert_note.xpm"
61 #include "../image/expert_chat.xpm"
62 #include "../image/expert_none.xpm"
63
64 /*
65  * The order below defines the priority of info bar contexts.
66  */
67 typedef enum {
68     STATUS_LEVEL_MAIN,
69     STATUS_LEVEL_FILE,
70     STATUS_LEVEL_FILTER,
71     STATUS_LEVEL_HELP,
72     NUM_STATUS_LEVELS
73 } status_level_e;
74
75
76 #ifdef HAVE_LIBPCAP
77 #define DEF_READY_MESSAGE " Ready to load or capture"
78 #else
79 #define DEF_READY_MESSAGE " Ready to load file"
80 #endif
81
82
83 static GtkWidget    *status_pane_left, *status_pane_right;
84 static GtkWidget    *info_bar, *packets_bar, *profile_bar, *profile_bar_event;
85 static GtkWidget    *expert_info_error, *expert_info_warn, *expert_info_note;
86 static GtkWidget    *expert_info_chat, *expert_info_none;
87
88 static guint        main_ctx, file_ctx, help_ctx, filter_ctx, packets_ctx, profile_ctx;
89 static guint        status_levels[NUM_STATUS_LEVELS];
90 static gchar        *packets_str = NULL;
91 static gchar        *profile_str = NULL;
92
93
94 static void info_bar_new(void);
95 static void packets_bar_new(void);
96 static void profile_bar_new(void);
97 static void status_expert_new(void);
98
99
100
101 /*
102  * Push a message referring to file access onto the statusbar.
103  */
104 static void
105 statusbar_push_file_msg(const gchar *msg)
106 {
107     int i;
108
109     /*g_warning("statusbar_push: %s", msg);*/
110     for (i = STATUS_LEVEL_FILE + 1; i < NUM_STATUS_LEVELS; i++) {
111         if (status_levels[i])
112             return;
113     }
114     status_levels[STATUS_LEVEL_FILE]++;
115     gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, msg);
116 }
117
118 /*
119  * Pop a message referring to file access off the statusbar.
120  */
121 static void
122 statusbar_pop_file_msg(void)
123 {
124     /*g_warning("statusbar_pop");*/
125     if (status_levels[STATUS_LEVEL_FILE] > 0) {
126         status_levels[STATUS_LEVEL_FILE]--;
127     }
128     gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
129 }
130
131 /*
132  * Push a message referring to the currently-selected field onto the statusbar.
133  */
134 void
135 statusbar_push_field_msg(const gchar *msg)
136 {
137     int i;
138
139     for (i = STATUS_LEVEL_HELP + 1; i < NUM_STATUS_LEVELS; i++) {
140         if (status_levels[i])
141             return;
142     }
143     status_levels[STATUS_LEVEL_HELP]++;
144
145     gtk_statusbar_push(GTK_STATUSBAR(info_bar), help_ctx, msg);
146 }
147
148 /*
149  * Pop a message referring to the currently-selected field off the statusbar.
150  */
151 void
152 statusbar_pop_field_msg(void)
153 {
154     if (status_levels[STATUS_LEVEL_HELP] > 0) {
155         status_levels[STATUS_LEVEL_HELP]--;
156     }
157     gtk_statusbar_pop(GTK_STATUSBAR(info_bar), help_ctx);
158 }
159
160 /*
161  * Push a message referring to the current filter onto the statusbar.
162  */
163 void
164 statusbar_push_filter_msg(const gchar *msg)
165 {
166     int i;
167
168     for (i = STATUS_LEVEL_FILTER + 1; i < NUM_STATUS_LEVELS; i++) {
169         if (status_levels[i])
170             return;
171     }
172     status_levels[STATUS_LEVEL_FILTER]++;
173
174     gtk_statusbar_push(GTK_STATUSBAR(info_bar), filter_ctx, msg);
175 }
176
177 /*
178  * Pop a message referring to the current filter off the statusbar.
179  */
180 void
181 statusbar_pop_filter_msg(void)
182 {
183     if (status_levels[STATUS_LEVEL_FILTER] > 0) {
184         status_levels[STATUS_LEVEL_FILTER]--;
185     }
186     gtk_statusbar_pop(GTK_STATUSBAR(info_bar), filter_ctx);
187 }
188
189
190 GtkWidget *
191 statusbar_new(void)
192 {
193     GtkWidget *status_hbox;
194
195     /* Sstatus hbox */
196     status_hbox = gtk_hbox_new(FALSE, 1);
197     gtk_container_set_border_width(GTK_CONTAINER(status_hbox), 0);
198
199     /* info (main) statusbar */
200     info_bar_new();
201
202     /* packets statusbar */
203     packets_bar_new();
204
205     /* profile statusbar */
206     profile_bar_new();
207
208     /* expert info indicator */
209     status_expert_new();
210
211     /* Pane for the statusbar */
212     status_pane_left = gtk_hpaned_new();
213     gtk_widget_show(status_pane_left);
214     status_pane_right = gtk_hpaned_new();
215     gtk_widget_show(status_pane_right);
216
217     return status_hbox;
218 }
219
220 void
221 statusbar_load_window_geometry(void)
222 {
223     if (recent.has_gui_geometry_status_pane && recent.gui_geometry_status_pane_left)
224         gtk_paned_set_position(GTK_PANED(status_pane_left), recent.gui_geometry_status_pane_left);
225     if (recent.has_gui_geometry_status_pane && recent.gui_geometry_status_pane_right)
226         gtk_paned_set_position(GTK_PANED(status_pane_right), recent.gui_geometry_status_pane_right);
227 }
228
229 void
230 statusbar_save_window_geometry(void)
231 {
232     recent.gui_geometry_status_pane_left    = gtk_paned_get_position(GTK_PANED(status_pane_left));
233     recent.gui_geometry_status_pane_right   = gtk_paned_get_position(GTK_PANED(status_pane_right));
234 }
235
236
237 /*
238  * Helper for statusbar_widgets_emptying()
239  */
240 static void
241 foreach_remove_a_child(GtkWidget *widget, gpointer data) {
242     gtk_container_remove(GTK_CONTAINER(data), widget);
243 }
244
245 void
246 statusbar_widgets_emptying(GtkWidget *statusbar)
247 {
248     g_object_ref(G_OBJECT(info_bar));
249     g_object_ref(G_OBJECT(packets_bar));
250     g_object_ref(G_OBJECT(profile_bar));
251     g_object_ref(G_OBJECT(profile_bar_event));
252     g_object_ref(G_OBJECT(status_pane_left));
253     g_object_ref(G_OBJECT(status_pane_right));
254     g_object_ref(G_OBJECT(expert_info_error));
255     g_object_ref(G_OBJECT(expert_info_warn));
256     g_object_ref(G_OBJECT(expert_info_note));
257     g_object_ref(G_OBJECT(expert_info_chat));
258     g_object_ref(G_OBJECT(expert_info_none));
259
260     /* empty all containers participating */
261     gtk_container_foreach(GTK_CONTAINER(statusbar),     foreach_remove_a_child, statusbar);
262     gtk_container_foreach(GTK_CONTAINER(status_pane_left),   foreach_remove_a_child, status_pane_left);
263     gtk_container_foreach(GTK_CONTAINER(status_pane_right),   foreach_remove_a_child, status_pane_right);
264 }
265
266 void
267 statusbar_widgets_pack(GtkWidget *statusbar)
268 {
269     gtk_box_pack_start(GTK_BOX(statusbar), expert_info_error, FALSE, FALSE, 0);
270     gtk_box_pack_start(GTK_BOX(statusbar), expert_info_warn, FALSE, FALSE, 0);
271     gtk_box_pack_start(GTK_BOX(statusbar), expert_info_note, FALSE, FALSE, 0);
272     gtk_box_pack_start(GTK_BOX(statusbar), expert_info_chat, FALSE, FALSE, 0);
273     gtk_box_pack_start(GTK_BOX(statusbar), expert_info_none, FALSE, FALSE, 0);
274     gtk_box_pack_start(GTK_BOX(statusbar), status_pane_left, TRUE, TRUE, 0);
275     gtk_paned_pack1(GTK_PANED(status_pane_left), info_bar, FALSE, FALSE);
276     gtk_paned_pack2(GTK_PANED(status_pane_left), status_pane_right, TRUE, FALSE);
277     gtk_paned_pack1(GTK_PANED(status_pane_right), packets_bar, TRUE, FALSE);
278     gtk_paned_pack2(GTK_PANED(status_pane_right), profile_bar_event, FALSE, FALSE);
279 }
280
281 void
282 statusbar_widgets_show_or_hide(GtkWidget *statusbar)
283 {
284     /*
285      * Show the status hbox if either:
286      *
287      *    1) we're showing the filter toolbar and we want it in the status
288      *       line
289      *
290      * or
291      *
292      *    2) we're showing the status bar.
293      */
294     if ((recent.filter_toolbar_show && prefs.filter_toolbar_show_in_statusbar) ||
295          recent.statusbar_show) {
296         gtk_widget_show(statusbar);
297     } else {
298         gtk_widget_hide(statusbar);
299     }
300
301     if (recent.statusbar_show) {
302         gtk_widget_show(status_pane_left);
303     } else {
304         gtk_widget_hide(status_pane_left);
305     }
306 }
307
308
309 static void
310 info_bar_new(void)
311 {
312     int i;
313
314     /* tip: tooltips don't work on statusbars! */
315     info_bar = gtk_statusbar_new();
316     main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
317     file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");
318     help_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "help");
319     filter_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "filter");
320     gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(info_bar), FALSE);
321     gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, DEF_READY_MESSAGE);
322
323     for (i = 0; i < NUM_STATUS_LEVELS; i++) {
324         status_levels[i] = 0;
325     }
326
327     gtk_widget_show(info_bar);
328 }
329
330 static void
331 packets_bar_new(void)
332 {
333     /* tip: tooltips don't work on statusbars! */
334     packets_bar = gtk_statusbar_new();
335     packets_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(packets_bar), "packets");
336     packets_bar_update();
337     gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(packets_bar), FALSE);
338
339     gtk_widget_show(packets_bar);
340 }
341
342 static void
343 profile_bar_new(void)
344 {
345     GtkTooltips   *tooltips;
346
347     tooltips = gtk_tooltips_new();
348
349     profile_bar_event = gtk_event_box_new();
350     profile_bar = gtk_statusbar_new();
351     gtk_container_add(GTK_CONTAINER(profile_bar_event), profile_bar);
352     g_signal_connect(profile_bar_event, "button_press_event", G_CALLBACK(profile_show_popup_cb), NULL);
353     profile_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(profile_bar), "profile");
354     gtk_tooltips_set_tip (tooltips, profile_bar_event,
355                           "Click to change configuration profile", NULL);
356     profile_bar_update();
357
358     gtk_widget_show(profile_bar);
359     gtk_widget_show(profile_bar_event);
360 }
361
362
363 /*
364  * update the packets statusbar to the current values
365  */
366 void 
367 packets_bar_update(void)
368 {
369
370     if(packets_bar) {
371         /* remove old status */
372         if(packets_str) {
373             g_free(packets_str);
374             gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
375         }
376
377         /* do we have any packets? */
378         if(cfile.count) {
379             if(cfile.drops_known) {
380                 packets_str = g_strdup_printf(" Packets: %u Displayed: %u Marked: %u Dropped: %u",
381                     cfile.count, cfile.displayed_count, cfile.marked_count, cfile.drops);
382             } else {
383                 packets_str = g_strdup_printf(" Packets: %u Displayed: %u Marked: %u",
384                     cfile.count, cfile.displayed_count, cfile.marked_count);
385             }
386         } else {
387             packets_str = g_strdup(" No Packets");
388         }
389         gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, packets_str);
390     }
391 }
392
393 /*
394  * update the packets statusbar to the current values
395  */
396 void
397 profile_bar_update(void)
398 {
399     if (profile_bar) {
400         /* remove old status */
401         if(profile_str) {
402             g_free(profile_str);
403             gtk_statusbar_pop(GTK_STATUSBAR(profile_bar), profile_ctx);
404         }
405
406         profile_str = g_strdup_printf (" Profile: %s", get_profile_name ());
407
408         gtk_statusbar_push(GTK_STATUSBAR(profile_bar), profile_ctx, profile_str);
409     }
410 }
411
412
413 static void
414 status_expert_new(void)
415 {
416     GtkWidget *expert_image;
417     GtkTooltips   *tooltips;
418
419     tooltips = gtk_tooltips_new();
420
421     expert_image = xpm_to_widget_from_parent(top_level, expert_error_xpm);
422     gtk_tooltips_set_tip(tooltips, expert_image, "ERROR is the highest expert info level", NULL);
423     gtk_widget_show(expert_image);
424     expert_info_error = gtk_event_box_new();
425     gtk_container_add(GTK_CONTAINER(expert_info_error), expert_image);
426     g_signal_connect(expert_info_error, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
427
428     expert_image = xpm_to_widget_from_parent(top_level, expert_warn_xpm);
429     gtk_tooltips_set_tip(tooltips, expert_image, "WARNING is the highest expert info level", NULL);
430     gtk_widget_show(expert_image);
431     expert_info_warn = gtk_event_box_new();
432     gtk_container_add(GTK_CONTAINER(expert_info_warn), expert_image);
433     g_signal_connect(expert_info_warn, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
434
435     expert_image = xpm_to_widget_from_parent(top_level, expert_note_xpm);
436     gtk_tooltips_set_tip(tooltips, expert_image, "NOTE is the highest expert info level", NULL);
437     gtk_widget_show(expert_image);
438     expert_info_note = gtk_event_box_new();
439     gtk_container_add(GTK_CONTAINER(expert_info_note), expert_image);
440     g_signal_connect(expert_info_note, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
441
442     expert_image = xpm_to_widget_from_parent(top_level, expert_chat_xpm);
443     gtk_tooltips_set_tip(tooltips, expert_image, "CHAT is the highest expert info level", NULL);
444     gtk_widget_show(expert_image);
445     expert_info_chat = gtk_event_box_new();
446     gtk_container_add(GTK_CONTAINER(expert_info_chat), expert_image);
447     g_signal_connect(expert_info_chat, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
448
449     expert_image = xpm_to_widget_from_parent(top_level, expert_none_xpm);
450     gtk_tooltips_set_tip(tooltips, expert_image, "No expert info", NULL);
451     gtk_widget_show(expert_image);
452     expert_info_none = gtk_event_box_new();
453     gtk_container_add(GTK_CONTAINER(expert_info_none), expert_image);
454     g_signal_connect(expert_info_none, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
455     gtk_widget_show(expert_info_none);
456 }
457
458 static void
459 status_expert_hide(void)
460 {
461     /* reset expert info indicator */
462     gtk_widget_hide(expert_info_error);
463     gtk_widget_hide(expert_info_warn);
464     gtk_widget_hide(expert_info_note);
465     gtk_widget_hide(expert_info_chat);
466     gtk_widget_hide(expert_info_none);
467 }
468
469 void
470 status_expert_update(void)
471 {
472     status_expert_hide();
473
474     switch(expert_get_highest_severity()) {
475         case(PI_ERROR):
476         gtk_widget_show(expert_info_error);
477         break;
478         case(PI_WARN):
479         gtk_widget_show(expert_info_warn);
480         break;
481         case(PI_NOTE):
482         gtk_widget_show(expert_info_note);
483         break;
484         case(PI_CHAT):
485         gtk_widget_show(expert_info_chat);
486         break;
487         default:
488         gtk_widget_show(expert_info_none);
489         break;
490     }
491 }
492
493 static void
494 statusbar_set_filename(const char *file_name, gint64 file_length, nstime_t *file_elapsed_time)
495 {
496   gchar       *size_str;
497   gchar       *status_msg;
498
499   /* expert info indicator */
500   status_expert_update();
501
502   /* statusbar */
503   /* convert file size */
504   if (file_length/1024/1024 > 10) {
505     size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d MB", file_length/1024/1024);
506   } else if (file_length/1024 > 10) {
507     size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d KB", file_length/1024);
508   } else {
509     size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d Bytes", file_length);
510   }
511
512   status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu",
513     (file_name) ? file_name : "", size_str,
514     (long)file_elapsed_time->secs/3600,
515     (long)file_elapsed_time->secs%3600/60,
516     (long)file_elapsed_time->secs%60);
517   g_free(size_str);
518   statusbar_push_file_msg(status_msg);
519   g_free(status_msg);
520 }
521
522
523 static void
524 statusbar_cf_file_closing_cb(capture_file *cf _U_)
525 {
526     /* Clear any file-related status bar messages.
527        XXX - should be "clear *ALL* file-related status bar messages;
528        will there ever be more than one on the stack? */
529     statusbar_pop_file_msg();
530
531     /* reset expert info indicator */
532     status_expert_hide();
533     gtk_widget_show(expert_info_none);
534 }
535
536
537 static void
538 statusbar_cf_file_closed_cb(capture_file *cf _U_)
539 {
540   /* go back to "No packets" */
541   packets_bar_update();
542 }
543
544
545 static void
546 statusbar_cf_file_read_start_cb(capture_file *cf)
547 {
548   const gchar *name_ptr;
549   gchar       *load_msg;
550
551   /* Ensure we pop any previous loaded filename */
552   statusbar_pop_file_msg();
553
554   name_ptr = get_basename(cf->filename);
555
556   load_msg = g_strdup_printf(" Loading: %s", name_ptr);
557   statusbar_push_file_msg(load_msg);
558   g_free(load_msg);
559 }
560
561
562 static void
563 statusbar_cf_file_read_finished_cb(capture_file *cf)
564 {
565     statusbar_pop_file_msg();
566     statusbar_set_filename(cf->filename, cf->f_datalen, &(cf->elapsed_time));
567 }
568
569
570 #ifdef HAVE_LIBPCAP
571 static void
572 statusbar_capture_prepared_cb(capture_options *capture_opts _U_)
573 {
574     statusbar_push_file_msg(" Waiting for capture input data ...");
575 }
576
577 static void
578 statusbar_capture_update_started_cb(capture_options *capture_opts)
579 {
580     gchar *capture_msg;
581
582
583     statusbar_pop_file_msg();
584
585     if(capture_opts->iface) {
586         capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
587                                       get_iface_description(capture_opts),
588                                       (capture_opts->save_file) ? capture_opts->save_file : "");
589     } else {
590         capture_msg = g_strdup_printf(" <live capture in progress> to file: %s",
591             (capture_opts->save_file) ? capture_opts->save_file : "");
592     }
593
594     statusbar_push_file_msg(capture_msg);
595
596     g_free(capture_msg);
597 }
598
599 static void
600 statusbar_capture_update_continue_cb(capture_options *capture_opts)
601 {
602     capture_file *cf = capture_opts->cf;
603     gchar *capture_msg;
604
605
606     status_expert_update();
607
608     statusbar_pop_file_msg();
609
610     if (cf->f_datalen/1024/1024 > 10) {
611         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d MB",
612                                       get_iface_description(capture_opts),
613                                       capture_opts->save_file,
614                                       cf->f_datalen/1024/1024);
615     } else if (cf->f_datalen/1024 > 10) {
616         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d KB",
617                                       get_iface_description(capture_opts),
618                                       capture_opts->save_file,
619                                       cf->f_datalen/1024);
620     } else {
621         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d Bytes",
622                                       get_iface_description(capture_opts),
623                                       capture_opts->save_file,
624                                       cf->f_datalen);
625     }
626
627     statusbar_push_file_msg(capture_msg);
628 }
629
630 static void
631 statusbar_capture_update_finished_cb(capture_options *capture_opts)
632 {
633     capture_file *cf = capture_opts->cf;
634
635     /* Pop the "<live capture in progress>" message off the status bar. */
636     statusbar_pop_file_msg();
637     statusbar_set_filename(cf->filename, cf->f_datalen, &(cf->elapsed_time));
638 }
639
640 static void
641 statusbar_capture_fixed_started_cb(capture_options *capture_opts)
642 {
643     gchar *capture_msg;
644
645
646     statusbar_pop_file_msg();
647
648     capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
649                                   get_iface_description(capture_opts),
650                                   (capture_opts->save_file) ? capture_opts->save_file : "");
651
652     statusbar_push_file_msg(capture_msg);
653     gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, " Packets: 0");
654
655     g_free(capture_msg);
656 }
657
658 static void
659 statusbar_capture_fixed_continue_cb(capture_options *capture_opts)
660 {
661     capture_file *cf = capture_opts->cf;
662     gchar *capture_msg;
663
664
665     gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
666     capture_msg = g_strdup_printf(" Packets: %u", cf_get_packet_count(cf));
667     gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, capture_msg);
668     g_free(capture_msg);
669 }
670
671
672 static void
673 statusbar_capture_fixed_finished_cb(capture_options *capture_opts _U_)
674 {
675 #if 0
676     capture_file *cf = capture_opts->cf;
677 #endif
678
679     /* Pop the "<live capture in progress>" message off the status bar. */
680     statusbar_pop_file_msg();
681
682     /* Pop the "<capturing>" message off the status bar */
683     gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
684 }
685
686 #endif /* HAVE_LIBPCAP */
687
688
689 static void
690 statusbar_cf_field_unselected_cb(capture_file *cf _U_)
691 {
692     statusbar_pop_field_msg();
693 }
694
695 static void
696 statusbar_cf_file_safe_started_cb(gchar * filename)
697 {
698     gchar        *save_msg;
699
700     save_msg = g_strdup_printf(" Saving: %s...", get_basename(filename));
701     statusbar_push_file_msg(save_msg);
702     g_free(save_msg);
703 }
704
705 static void
706 statusbar_cf_file_safe_finished_cb(gpointer data _U_)
707 {
708     /* Pop the "Saving:" message off the status bar. */
709     statusbar_pop_file_msg();
710 }
711
712 static void
713 statusbar_cf_file_safe_failed_cb(gpointer data _U_)
714 {
715     /* Pop the "Saving:" message off the status bar. */
716     statusbar_pop_file_msg();
717 }
718
719
720
721 void
722 statusbar_cf_callback(gint event, gpointer data, gpointer user_data _U_)
723 {
724     switch(event) {
725     case(cf_cb_file_closing):
726         statusbar_cf_file_closing_cb(data);
727         break;
728     case(cf_cb_file_closed):
729         statusbar_cf_file_closed_cb(data);
730         break;
731     case(cf_cb_file_read_start):
732         statusbar_cf_file_read_start_cb(data);
733         break;
734     case(cf_cb_file_read_finished):
735         statusbar_cf_file_read_finished_cb(data);
736         break;
737     case(cf_cb_packet_selected):
738         break;
739     case(cf_cb_packet_unselected):
740         break;
741     case(cf_cb_field_unselected):
742         statusbar_cf_field_unselected_cb(data);
743         break;
744     case(cf_cb_file_safe_started):
745         statusbar_cf_file_safe_started_cb(data);
746         break;
747     case(cf_cb_file_safe_finished):
748         statusbar_cf_file_safe_finished_cb(data);
749         break;
750     case(cf_cb_file_safe_reload_finished):
751         break;
752     case(cf_cb_file_safe_failed):
753         statusbar_cf_file_safe_failed_cb(data);
754         break;
755     default:
756         g_warning("statusbar_cf_callback: event %u unknown", event);
757         g_assert_not_reached();
758     }
759 }
760
761 #ifdef HAVE_LIBPCAP
762 void
763 statusbar_capture_callback(gint event, capture_options *capture_opts,
764                            gpointer user_data _U_)
765 {
766     switch(event) {
767     case(capture_cb_capture_prepared):
768         statusbar_capture_prepared_cb(capture_opts);
769         break;
770     case(capture_cb_capture_update_started):
771         statusbar_capture_update_started_cb(capture_opts);
772         break;
773     case(capture_cb_capture_update_continue):
774         statusbar_capture_update_continue_cb(capture_opts);
775         break;
776     case(capture_cb_capture_update_finished):
777         statusbar_capture_update_finished_cb(capture_opts);
778         break;
779     case(capture_cb_capture_fixed_started):
780         statusbar_capture_fixed_started_cb(capture_opts);
781         break;
782     case(capture_cb_capture_fixed_continue):
783         statusbar_capture_fixed_continue_cb(capture_opts);
784         break;
785     case(capture_cb_capture_fixed_finished):
786         statusbar_capture_fixed_finished_cb(capture_opts);
787         break;
788     case(capture_cb_capture_stopping):
789         /* Beware: this state won't be called, if the capture child
790          * closes the capturing on it's own! */
791         break;
792     default:
793         g_warning("statusbar_capture_callback: event %u unknown", event);
794         g_assert_not_reached();
795     }
796 }
797 #endif