Fix almost all accesses to ->window
[obnox/wireshark/wip.git] / gtk / expert_comp_dlg.c
1 /* expert_comp_dlg.c
2  * expert_comp_dlg   2005 Greg Morris
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
31 #endif
32 #include <string.h>
33
34 #include <gtk/gtk.h>
35
36 #include <epan/packet_info.h>
37 #include <epan/tap.h>
38 #include <epan/stat_cmd_args.h>
39 #include <epan/prefs.h>
40
41 #include "../simple_dialog.h"
42 #include "../stat_menu.h"
43
44 #include "gtk/gui_utils.h"
45 #include "gtk/dlg_utils.h"
46 #include "gtk/expert_comp_table.h"
47 #include "gtk/gui_stat_menu.h"
48 #include "gtk/help_dlg.h"
49 #include "gtk/expert_comp_dlg.h"
50 #include "gtk/stock_icons.h"
51 #include "gtk/main.h"
52
53 #include "gtk/main_proto_draw.h"
54
55 #include "gtk/old-gtk-compat.h"
56
57 enum
58 {
59     NO_COLUMN,
60     SEVERITY_COLUMN,
61     GROUP_COLUMN,
62     PROTOCOL_COLUMN,
63     SUMMARY_COLUMN,
64     FOREGROUND_COLOR_COL,
65     BACKGROUND_COLOR_COL,
66     N_COLUMNS
67 };
68
69 /* used to keep track of the statistics for an entire program interface */
70 typedef struct _expert_comp_dlg_t {
71     GtkWidget *win;
72     GtkWidget *chat_label;
73     GtkWidget *note_label;
74     GtkWidget *warn_label;
75     GtkWidget *error_label;
76     GtkWidget *all_label;
77     error_equiv_table chat_table;
78     error_equiv_table note_table;
79     error_equiv_table warn_table;
80     error_equiv_table error_table;
81     guint32 disp_events;
82     guint32 chat_events;
83     guint32 note_events;
84     guint32 warn_events;
85     guint32 error_events;
86 } expert_comp_dlg_t;
87
88 struct expert_tapdata_s {
89         GtkWidget       *win;
90         GtkWidget       *scrolled_window;
91         GtkTreeView *tree_view;
92         GtkWidget       *label;
93         guint32         disp_events;
94         guint32         chat_events;
95         guint32         note_events;
96         guint32         warn_events;
97         guint32         error_events;
98         int             severity_report_level;
99
100         GArray          *ei_array;      /* expert info items */
101         guint           first;
102         guint           last;
103         GStringChunk*   text;           /* summary text */
104 };
105
106 static GtkWidget  *expert_comp_dlg_w = NULL;
107
108 static void
109 select_row_cb(GtkTreeSelection *selection, gpointer *user_data _U_)
110 {
111     /*guint num = GPOINTER_TO_UINT(gtk_clist_get_row_data(clist, row));*/
112
113     /*cf_goto_frame(&cfile, num);*/
114
115     GtkTreeIter iter;
116     GtkTreeModel *model;
117     guint fnumber;
118
119     if (selection==NULL)
120         return;
121
122     if (gtk_tree_selection_get_selected (selection, &model, &iter)){
123         gtk_tree_model_get (model, &iter, NO_COLUMN, &fnumber, -1);
124         cf_goto_frame(&cfile, fnumber);
125     }
126
127 }
128
129 /* reset of display only, e.g. for filtering */
130 static void expert_dlg_display_reset(expert_tapdata_t * etd)
131 {
132     etd->disp_events = 0;
133     gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(etd->tree_view))));
134
135     gtk_window_set_title(GTK_WINDOW(etd->win), "Wireshark: ? Expert Infos");
136     if(etd->label) {
137         gtk_label_set_text(GTK_LABEL(etd->label), "Please wait ...");
138     }
139 }
140
141 /* complete reset, e.g. capture file closed */
142 static void
143 expert_dlg_reset(void *tapdata)
144 {
145     expert_tapdata_t * etd = tapdata;
146
147     etd->chat_events = 0;
148     etd->note_events = 0;
149     etd->warn_events = 0;
150     etd->error_events = 0;
151     etd->last = 0;
152     etd->first = 0;
153     /* g_string_chunk_clear() is introduced in glib 2.14 */
154     g_string_chunk_free(etd->text);
155     etd->text = g_string_chunk_new(100);
156     g_array_set_size(etd->ei_array, 0);
157
158     expert_dlg_display_reset(etd);
159 }
160
161 static int
162 expert_dlg_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pointer)
163 {
164     expert_info_t    *ei;
165     expert_tapdata_t *etd = tapdata;
166
167     g_array_append_val(etd->ei_array, *(expert_info_t *)pointer);
168     etd->last = etd->ei_array->len;
169     ei = &g_array_index(etd->ei_array, expert_info_t, etd->last -1); /* ugly */
170     ei->protocol = g_string_chunk_insert_const(etd->text, ei->protocol);
171     ei->summary = g_string_chunk_insert_const(etd->text, ei->summary);
172
173     switch(ei->severity) {
174     case(PI_CHAT):
175         etd->chat_events++;
176         break;
177     case(PI_NOTE):
178         etd->note_events++;
179         break;
180     case(PI_WARN):
181         etd->warn_events++;
182         break;
183     case(PI_ERROR):
184         etd->error_events++;
185         break;
186     default:
187         g_assert_not_reached();
188     }
189     if(ei->severity < etd->severity_report_level) {
190         return 0; /* draw not required */
191     } else {
192         return 1; /* draw required */
193     }
194 }
195 static void
196 error_set_title(expert_comp_dlg_t *ss)
197 {
198     char *title;
199
200     title = g_strdup_printf("Expert Info Composite: %s",
201         cf_get_display_name(&cfile));
202     gtk_window_set_title(GTK_WINDOW(ss->win), title);
203     g_free(title);
204 }
205
206 static void
207 error_reset(void *pss)
208 {
209     expert_comp_dlg_t *ss=(expert_comp_dlg_t *)pss;
210     gchar *buf;
211
212     ss->error_events = 0;
213     ss->warn_events = 0;
214     ss->note_events = 0;
215     ss->chat_events = 0;
216     ss->disp_events = 0;
217
218     reset_error_table_data(&ss->error_table);
219     buf = g_strdup_printf("Errors: %u (0)", ss->error_table.num_procs);
220     gtk_label_set_text( GTK_LABEL(ss->error_label), buf);
221     g_free(buf);
222
223     reset_error_table_data(&ss->warn_table);
224     buf = g_strdup_printf("Warnings: %u (0)", ss->warn_table.num_procs);
225     gtk_label_set_text( GTK_LABEL(ss->warn_label), buf);
226     g_free(buf);
227
228     reset_error_table_data(&ss->note_table);
229     buf = g_strdup_printf("Notes: %u (0)", ss->note_table.num_procs);
230     gtk_label_set_text( GTK_LABEL(ss->note_label), buf);
231     g_free(buf);
232
233     reset_error_table_data(&ss->chat_table);
234     buf = g_strdup_printf("Chats: %u (0)", ss->chat_table.num_procs);
235     gtk_label_set_text( GTK_LABEL(ss->chat_label), buf);
236     g_free(buf);
237
238     gtk_label_set_text( GTK_LABEL(ss->all_label), "Details: 0");
239     error_set_title(ss);
240 }
241
242 static gboolean
243 error_packet(void *pss, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *prv)
244 {
245     expert_comp_dlg_t *ss=(expert_comp_dlg_t *)pss;
246     const expert_info_t *error_pkt=prv;
247
248     /* if return value is 0 then no error */
249     if(error_pkt==NULL){
250         return FALSE;
251     }
252
253     switch (error_pkt->severity) {
254     case PI_ERROR:
255         ss->disp_events++;
256         ss->error_events++;
257         init_error_table_row(&ss->error_table, error_pkt);
258         break;
259     case PI_WARN:
260         ss->disp_events++;
261         ss->warn_events++;
262         init_error_table_row(&ss->warn_table, error_pkt);
263         break;
264     case PI_NOTE:
265         ss->disp_events++;
266         ss->note_events++;
267         init_error_table_row(&ss->note_table, error_pkt);
268         break;
269     case PI_CHAT:
270         ss->disp_events++;
271         ss->chat_events++;
272         init_error_table_row(&ss->chat_table, error_pkt);
273         break;
274     default:
275         return FALSE; /* Don't draw */
276     }
277     return TRUE; /* Draw */
278 }
279
280 static void
281 expert_comp_draw(void *data)
282 {
283     gchar *buf = NULL;
284
285     expert_comp_dlg_t *ss=(expert_comp_dlg_t *)data;
286
287     buf = g_strdup_printf("Errors: %u (%u)", ss->error_table.num_procs, ss->error_events);
288     gtk_label_set_text( GTK_LABEL(ss->error_label), buf);
289     g_free(buf);
290
291     buf = g_strdup_printf("Warnings: %u (%u)", ss->warn_table.num_procs, ss->warn_events);
292     gtk_label_set_text( GTK_LABEL(ss->warn_label), buf);
293     g_free(buf);
294
295     buf = g_strdup_printf("Notes: %u (%u)", ss->note_table.num_procs, ss->note_events);
296     gtk_label_set_text( GTK_LABEL(ss->note_label), buf);
297     g_free(buf);
298
299     buf = g_strdup_printf("Chats: %u (%u)", ss->chat_table.num_procs, ss->chat_events);
300     gtk_label_set_text( GTK_LABEL(ss->chat_label), buf);
301     g_free(buf);
302
303     buf = g_strdup_printf("Details: %u", ss->disp_events);
304     gtk_label_set_text( GTK_LABEL(ss->all_label), buf);
305     g_free(buf);
306
307 }
308
309 static void
310 win_destroy_cb(GtkWindow *win _U_, gpointer data)
311 {
312     expert_comp_dlg_t *ss=(expert_comp_dlg_t *)data;
313
314     protect_thread_critical_region();
315     remove_tap_listener(ss);
316     unprotect_thread_critical_region();
317
318     if (expert_comp_dlg_w != NULL) {
319         window_destroy(expert_comp_dlg_w);
320         expert_comp_dlg_w = NULL;
321     }
322
323     free_error_table_data(&ss->error_table);
324     free_error_table_data(&ss->warn_table);
325     free_error_table_data(&ss->note_table);
326     free_error_table_data(&ss->chat_table);
327     g_free(ss);
328
329 }
330
331 static void
332 expert_dlg_destroy_cb(GtkWindow *win _U_, gpointer data)
333 {
334     expert_tapdata_t *etd=(expert_tapdata_t *)data;
335
336     protect_thread_critical_region();
337     remove_tap_listener(etd);
338     unprotect_thread_critical_region();
339
340     /*free_srt_table_data(&etd->afp_srt_table);*/
341     g_array_free(etd->ei_array, TRUE);
342     g_string_chunk_free(etd->text);
343     g_free(etd);
344 }
345
346 static expert_tapdata_t * expert_dlg_new_table(void)
347 {
348     expert_tapdata_t * etd;
349     etd=g_malloc0(sizeof(expert_tapdata_t));
350
351     etd->ei_array = g_array_sized_new(FALSE, FALSE, sizeof(expert_info_t), 1000);
352     etd->text = g_string_chunk_new(100);
353     etd->severity_report_level = PI_CHAT;
354     return etd;
355 }
356
357 static void
358 expert_dlg_init_table(expert_tapdata_t * etd, GtkWidget *vbox)
359 {
360     GtkListStore *store;
361     GtkWidget *tree;
362     GtkTreeViewColumn *column;
363     GtkCellRenderer *renderer;
364     GtkTreeSortable *sortable;
365     GtkTreeSelection  *selection;
366
367     /* Create the store */
368     store = gtk_list_store_new(N_COLUMNS,        /* Total number of columns */
369                                G_TYPE_UINT,      /* No                   */
370                                G_TYPE_POINTER,   /* Severity           */
371                                G_TYPE_POINTER,   /* Group              */
372                                G_TYPE_POINTER,    /* Protocol           */
373                                G_TYPE_POINTER,    /* Summary            */
374                                G_TYPE_STRING,    /* forground          */
375                                G_TYPE_STRING);   /* Background         */
376
377     /* Create a view */
378     tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
379     etd->tree_view = GTK_TREE_VIEW(tree);
380     sortable = GTK_TREE_SORTABLE(store);
381
382     /* Speed up the list display */
383     gtk_tree_view_set_fixed_height_mode(etd->tree_view, TRUE);
384
385     /* Setup the sortable columns */
386     gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW (tree), FALSE);
387
388     /* The view now holds a reference.  We can get rid of our own reference */
389     g_object_unref (G_OBJECT (store));
390
391     /* Let the font be the default one to have the same look as the rest of the tabs
392          * Bug https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=4388
393          * gtk_widget_modify_font(GTK_WIDGET (etd->tree_view), user_font_get_regular());
394          */
395
396     /* Create a cell renderer */
397     renderer = gtk_cell_renderer_text_new ();
398     g_object_set(renderer, "ypad", 0, NULL);
399     g_object_set(renderer, "xalign", 1.0, NULL);
400
401     /* Create the first column, associating the "text" attribute of the
402      * cell_renderer to the first column of the model */
403     /* No */
404     column = gtk_tree_view_column_new_with_attributes ("No", renderer,
405         "text", NO_COLUMN,
406         "foreground", FOREGROUND_COLOR_COL,
407         "background", BACKGROUND_COLOR_COL,
408         NULL);
409     gtk_tree_view_column_set_sort_column_id(column, NO_COLUMN);
410     gtk_tree_view_column_set_resizable(column, TRUE);
411     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
412     gtk_tree_view_column_set_min_width(column, 80);
413     gtk_tree_view_append_column (etd->tree_view, column);
414
415     /* Severity */
416     renderer = gtk_cell_renderer_text_new ();
417     g_object_set(renderer, "ypad", 0, NULL);
418
419     column = gtk_tree_view_column_new_with_attributes ("Severity", renderer,
420         "foreground", FOREGROUND_COLOR_COL,
421         "background", BACKGROUND_COLOR_COL,
422         NULL);
423
424         gtk_tree_view_column_set_cell_data_func(column, renderer, str_ptr_data_func,
425                 GINT_TO_POINTER(SEVERITY_COLUMN), NULL);
426
427         gtk_tree_sortable_set_sort_func(sortable, SEVERITY_COLUMN, str_ptr_sort_func,
428                 GINT_TO_POINTER(SEVERITY_COLUMN), NULL);
429
430     gtk_tree_view_column_set_sort_column_id(column, SEVERITY_COLUMN);
431     gtk_tree_view_column_set_resizable(column, TRUE);
432     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
433     gtk_tree_view_column_set_min_width(column, 80);
434     /* Add the column to the view. */
435     gtk_tree_view_append_column (etd->tree_view, column);
436
437     /* Group */
438     renderer = gtk_cell_renderer_text_new ();
439     g_object_set(renderer, "ypad", 0, NULL);
440     column = gtk_tree_view_column_new_with_attributes ("Group", renderer,
441         "foreground", FOREGROUND_COLOR_COL,
442         "background", BACKGROUND_COLOR_COL,
443         NULL);
444
445         gtk_tree_view_column_set_cell_data_func(column, renderer, str_ptr_data_func,
446                 GINT_TO_POINTER(GROUP_COLUMN), NULL);
447
448         gtk_tree_sortable_set_sort_func(sortable, GROUP_COLUMN, str_ptr_sort_func,
449                 GINT_TO_POINTER(GROUP_COLUMN), NULL);
450
451     gtk_tree_view_column_set_sort_column_id(column, GROUP_COLUMN);
452     gtk_tree_view_column_set_resizable(column, TRUE);
453     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
454     gtk_tree_view_column_set_min_width(column, 80);
455     /* Add the column to the view. */
456     gtk_tree_view_append_column (etd->tree_view, column);
457
458     /* Protocol. */
459     renderer = gtk_cell_renderer_text_new ();
460     g_object_set(renderer, "ypad", 0, NULL);
461     column = gtk_tree_view_column_new_with_attributes ("Protocol", renderer,
462         "foreground", FOREGROUND_COLOR_COL,
463         "background", BACKGROUND_COLOR_COL,
464         NULL);
465         gtk_tree_view_column_set_cell_data_func(column, renderer, str_ptr_data_func,
466                 GINT_TO_POINTER(PROTOCOL_COLUMN), NULL);
467
468         gtk_tree_sortable_set_sort_func(sortable, PROTOCOL_COLUMN, str_ptr_sort_func,
469                 GINT_TO_POINTER(PROTOCOL_COLUMN), NULL);
470
471     gtk_tree_view_column_set_sort_column_id(column, PROTOCOL_COLUMN);
472     gtk_tree_view_column_set_resizable(column, TRUE);
473     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
474     gtk_tree_view_column_set_min_width(column, 80);
475     gtk_tree_view_append_column (etd->tree_view, column);
476
477     /* Summary. */
478     renderer = gtk_cell_renderer_text_new ();
479     g_object_set(renderer, "ypad", 0, NULL);
480     column = gtk_tree_view_column_new_with_attributes ("Summary", renderer,
481         "foreground", FOREGROUND_COLOR_COL,
482         "background", BACKGROUND_COLOR_COL,
483         NULL);
484         gtk_tree_view_column_set_cell_data_func(column, renderer, str_ptr_data_func,
485                 GINT_TO_POINTER(SUMMARY_COLUMN), NULL);
486
487         gtk_tree_sortable_set_sort_func(sortable, SUMMARY_COLUMN, str_ptr_sort_func,
488                 GINT_TO_POINTER(SUMMARY_COLUMN), NULL);
489
490     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
491     gtk_tree_view_column_set_min_width(column, 90);
492     gtk_tree_view_column_set_sort_column_id(column, SUMMARY_COLUMN);
493     gtk_tree_view_column_set_resizable(column, TRUE);
494     gtk_tree_view_append_column (etd->tree_view, column);
495
496
497     gtk_tree_view_set_search_column (etd->tree_view, SUMMARY_COLUMN); /* Allow searching the summary */
498     gtk_tree_view_set_reorderable (etd->tree_view, TRUE);   /* Allow user to reorder data with drag n drop */
499
500     /* Now enable the sorting of each column */
501     gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(etd->tree_view), TRUE);
502     gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(etd->tree_view), TRUE);
503
504     /* Setup the selection handler */
505     selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(etd->tree_view));
506     gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
507
508     g_signal_connect (G_OBJECT (selection), "changed", /* select_row */
509                   G_CALLBACK (select_row_cb),
510                   NULL);
511
512     etd->scrolled_window=scrolled_window_new(NULL, NULL);
513     gtk_container_add(GTK_CONTAINER(etd->scrolled_window), GTK_WIDGET (etd->tree_view));
514
515     gtk_box_pack_start(GTK_BOX(vbox), etd->scrolled_window, TRUE, TRUE, 0);
516 }
517
518 static void
519 expert_dlg_draw(void *data)
520 {
521     expert_tapdata_t *etd = data;
522     expert_info_t *ei;
523     gchar *title;
524     const char *entries[2];   /**< column entries */
525     GtkListStore *list_store;
526     GtkTreeIter iter;
527     gchar *color_str = NULL;
528     guint packet_no = 0;
529         const gchar *group_str;
530         const gchar *severity_str;
531
532
533     if(etd->label) {
534         if(etd->last - etd->first) {
535             title = g_strdup_printf("Adding: %u new messages",etd->last - etd->first);
536             gtk_label_set_text(GTK_LABEL(etd->label), title);
537             g_free(title);
538         }
539     }
540
541     /* append new events (remove from new list, append to displayed list and clist) */
542     while(etd->first < etd->last){
543         ei = &g_array_index(etd->ei_array, expert_info_t, etd->first);
544         etd->first++;
545
546         if(ei->severity < etd->severity_report_level) {
547             continue;
548         }
549         etd->disp_events++;
550
551         /* packet number */
552         if(ei->packet_num) {
553             packet_no = ei->packet_num;
554         }
555
556         /*  match_strval return a static string or NULL
557             severity */
558                 severity_str = match_strval(ei->severity, expert_severity_vals);
559         /* group */
560                 group_str = match_strval(ei->group, expert_group_vals);
561
562         /* protocol */
563         if(ei->protocol) {
564             entries[0] = ei->protocol;
565         } else {
566             entries[0] = "-";
567         }
568
569         /* summary */
570         entries[1] = ei->summary;
571
572         /* set rows background color depending on severity */
573         switch(ei->severity) {
574         case(PI_CHAT):
575             color_str = expert_color_chat_str;
576             break;
577         case(PI_NOTE):
578             color_str = expert_color_note_str;
579             break;
580         case(PI_WARN):
581             color_str = expert_color_warn_str;
582             break;
583         case(PI_ERROR):
584             color_str = expert_color_error_str;
585             break;
586         default:
587             g_assert_not_reached();
588         }
589
590         list_store = GTK_LIST_STORE(gtk_tree_view_get_model(etd->tree_view)); /* Get store */
591
592         /* Creates a new row at position. iter will be changed to point to this new row.
593          * If position is larger than the number of rows on the list, then the new row will be appended to the list.
594          * The row will be filled with the values given to this function.
595          * :
596          * should generally be preferred when inserting rows in a sorted list store.
597          */
598         gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT,
599                     NO_COLUMN, packet_no,
600                     SEVERITY_COLUMN, severity_str,
601                     GROUP_COLUMN, group_str,
602                     PROTOCOL_COLUMN, entries[0],
603                     SUMMARY_COLUMN, entries[1],
604                     FOREGROUND_COLOR_COL, expert_color_foreground_str,
605                     BACKGROUND_COLOR_COL, color_str,
606                     -1);
607     }
608
609     if(etd->label) {
610         title = g_strdup_printf("Errors: %u Warnings: %u Notes: %u Chats: %u",
611                                 etd->error_events, etd->warn_events,
612                                 etd->note_events, etd->chat_events);
613         gtk_label_set_text(GTK_LABEL(etd->label), title);
614         g_free(title);
615     }
616
617     title = g_strdup_printf("Wireshark: %u Expert Info%s",
618                             etd->disp_events,
619                             plurality(etd->disp_events, "", "s"));
620     gtk_window_set_title(GTK_WINDOW(etd->win), title);
621     g_free(title);
622 }
623
624 static void
625 expert_comp_init(const char *optarg _U_, void* userdata _U_)
626 {
627     expert_comp_dlg_t *ss;
628     const char *filter=NULL;
629     GString *error_string;
630     GtkWidget *temp_page;
631     GtkWidget *main_nb;
632     GtkWidget *vbox;
633     GtkWidget *hbox;
634     GtkWidget *bbox;
635     GtkWidget *close_bt;
636     GtkWidget *help_bt;
637     expert_tapdata_t *etd;
638  
639     ss=g_malloc(sizeof(expert_comp_dlg_t));
640
641     ss->disp_events = 0;
642     ss->chat_events = 0;
643     ss->note_events = 0;
644     ss->warn_events = 0;
645     ss->error_events = 0;
646
647     expert_comp_dlg_w = ss->win=dlg_window_new("err");  /* transient_for top_level */
648     gtk_window_set_destroy_with_parent (GTK_WINDOW(ss->win), TRUE);
649     gtk_window_set_default_size(GTK_WINDOW(ss->win), 700, 300);
650
651     error_set_title(ss);
652
653     vbox=gtk_vbox_new(FALSE, 3);
654     gtk_container_add(GTK_CONTAINER(ss->win), vbox);
655     gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
656
657     main_nb = gtk_notebook_new();
658     gtk_box_pack_start(GTK_BOX(vbox), main_nb, TRUE, TRUE, 0);
659
660     /* We must display TOP LEVEL Widget before calling init_table() */
661     gtk_widget_show_all(ss->win);
662
663     /* Errors */
664     temp_page = gtk_vbox_new(FALSE, 6);
665     ss->error_label = gtk_label_new("Errors: 0/y");
666     gtk_widget_show(ss->error_label);
667     hbox = gtk_hbox_new(FALSE, 3);
668     gtk_container_add(GTK_CONTAINER(hbox), ss->error_label);
669     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
670     init_error_table(&ss->error_table, 0, temp_page);
671
672     /* Warnings */
673     temp_page = gtk_vbox_new(FALSE, 6);
674     ss->warn_label = gtk_label_new("Warnings: 0/y");
675     gtk_widget_show(ss->warn_label);
676     hbox = gtk_hbox_new(FALSE, 3);
677     gtk_container_add(GTK_CONTAINER(hbox), ss->warn_label);
678     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
679     init_error_table(&ss->warn_table, 0, temp_page);
680
681     /* Notes */
682     temp_page = gtk_vbox_new(FALSE, 6);
683     ss->note_label = gtk_label_new("Notes: 0/y");
684     gtk_widget_show(ss->note_label);
685     hbox = gtk_hbox_new(FALSE, 3);
686     gtk_container_add(GTK_CONTAINER(hbox), ss->note_label);
687     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
688     init_error_table(&ss->note_table, 0, temp_page);
689
690     /* Chat */
691     temp_page = gtk_vbox_new(FALSE, 6);
692     ss->chat_label = gtk_label_new("Chats: 0/y");
693     gtk_widget_show(ss->chat_label);
694     hbox = gtk_hbox_new(FALSE, 3);
695     gtk_container_add(GTK_CONTAINER(hbox), ss->chat_label);
696     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
697     init_error_table(&ss->chat_table, 0, temp_page);
698
699     /* Details */
700     temp_page = gtk_vbox_new(FALSE, 6);
701     ss->all_label = gtk_label_new("Details: 0");
702     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, ss->all_label);
703
704     etd = expert_dlg_new_table();
705     etd->label=gtk_label_new("Please wait ...");
706     gtk_misc_set_alignment(GTK_MISC(etd->label), 0.0f, 0.5f);
707
708     etd->win=ss->win;
709     expert_dlg_init_table(etd, temp_page);
710
711     /* Add tap listener functions for expert details, From expert_dlg.c*/
712     error_string=register_tap_listener("expert", etd, NULL /* fstring */,
713                                        TL_REQUIRES_PROTO_TREE,
714                                        expert_dlg_reset,
715                                        expert_dlg_packet,
716                                        expert_dlg_draw);
717     if(error_string){
718         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
719         g_string_free(error_string, TRUE);
720         g_free(etd);
721         return;
722     }
723
724     g_signal_connect(etd->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
725     g_signal_connect(etd->win, "destroy", G_CALLBACK(expert_dlg_destroy_cb), etd);
726
727     /* Register the tap listener */
728
729     error_string=register_tap_listener("expert", ss, filter, 0, error_reset, error_packet, expert_comp_draw);
730     if(error_string){
731         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
732         g_string_free(error_string, TRUE);
733         g_free(ss);
734         return;
735     }
736
737     /* Button row. */
738     bbox = dlg_button_row_new(GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL);
739     gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
740
741     close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
742     window_set_cancel_button(ss->win, close_bt, window_cancel_button_cb);
743
744     help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
745     g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_EXPERT_INFO_DIALOG);
746     gtk_widget_set_tooltip_text (help_bt, "Show topic specific help");
747
748     g_signal_connect(ss->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
749     g_signal_connect(ss->win, "destroy", G_CALLBACK(win_destroy_cb), ss);
750
751     gtk_widget_show_all(ss->win);
752     window_present(ss->win);
753
754     /*
755      * At least at present, the only information the tap listener appears
756      * to care about is available regardless of whether the protocol tree
757      * is being built, so we don't appear to need to have the protocol
758      * tree built.
759      *
760      * This means we can use cf_retap_packets(), even though it will only
761      * build the protocol tree if at least one tap has a filter in place.
762      * cf_retap_packets() is faster than cf_redissect_packets(), as it
763      * assumes we didn't change anything that would cause any packets to
764      * dissect differently, and thus doesn't redo the packet display.
765      */
766     cf_retap_packets(&cfile);
767
768     /* This will bring up the progress bar
769      * Put our window back in front
770      */
771     gdk_window_raise(gtk_widget_get_window(ss->win));
772     /* Set the lable text */
773     expert_comp_draw(ss);
774 }
775
776 void
777 expert_comp_dlg_launch(void)
778 {
779     if (expert_comp_dlg_w) {
780         reactivate_window(expert_comp_dlg_w);
781     } else {
782         expert_comp_init("", NULL);
783     }
784 }
785
786 void
787 register_tap_listener_expert_comp(void)
788 {
789     register_stat_cmd_arg("expert_comp", expert_comp_init,NULL);
790 #ifdef MAIN_MENU_USE_UIMANAGER
791 #else
792     register_stat_menu_item_stock("Expert Info _Composite",
793         REGISTER_ANALYZE_GROUP_UNSORTED, WIRESHARK_STOCK_EXPERT_INFO,
794         expert_comp_dlg_launch, NULL, NULL, NULL);
795 #endif
796 }