Fix build (automake) error: WIRESHARK_CUSTOM_HEADERS is ng but WIRESHARK_CUSTOM_HDRS...
[obnox/wireshark/wip.git] / gtk / dissector_tables_dlg.c
1 /* dissector_tables_dlg.c
2  * dissector_tables_dlg   2010 Anders Broman
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 <glib.h>
35
36 #include <epan/packet.h>
37
38 #include <gtk/gtk.h>
39 #include "gtk/gui_utils.h"
40 #include "gtk/dlg_utils.h"
41 #include "gtk/dissector_tables_dlg.h"
42
43 static GtkWidget  *dissector_tables_dlg_w = NULL;
44
45 /* The columns */
46 enum
47 {
48     TABLE_UI_NAME_COL,
49     TABLE_SHORT_NAME_COL,
50     N_COLUMNS
51 };
52
53 static void
54 win_destroy_cb(GtkWindow *win _U_, gpointer data _U_)
55 {
56
57     if (dissector_tables_dlg_w != NULL) {
58         window_destroy(dissector_tables_dlg_w);
59         dissector_tables_dlg_w = NULL;
60     }
61
62
63 }
64
65 /*
66  * For a dissector table, put
67  * its short name and its
68  * descriptive name in the treeview.
69  */
70
71 struct dissector_tables_tree_info {
72     GtkWidget       *tree;
73     GtkTreeIter     iter;
74     GtkTreeIter     new_iter;
75 };
76
77 typedef struct dissector_tables_tree_info dissector_tables_tree_info_t;
78
79 static gint
80 ui_sort_func(GtkTreeModel *model,
81              GtkTreeIter  *a,
82              GtkTreeIter  *b,
83              gpointer      user_data)
84 {
85     gchar *stra, *strb;
86
87     /* The col to get data from is in userdata */
88     gint data_column = GPOINTER_TO_INT(user_data);
89
90     gtk_tree_model_get(model, a, data_column, &stra, -1);
91     gtk_tree_model_get(model, b, data_column, &strb, -1);
92
93     return strcmp(stra, strb);
94 }
95
96
97 /*
98  * Struct to hold the pointer to the trees
99  * for dissector tables.
100  */
101 struct dissector_tables_trees {
102     GtkWidget       *str_tree_wgt;
103     GtkWidget       *uint_tree_wgt;
104 };
105
106 typedef struct dissector_tables_trees dissector_tables_trees_t;
107
108 static void
109 proto_add_to_list(dissector_tables_tree_info_t *tree_info,
110                   GtkTreeStore *store,
111                   gchar        *str,
112                   const gchar  *proto_name)
113 {
114     gtk_tree_store_insert_with_values(store, &tree_info->new_iter, &tree_info->iter, G_MAXINT,
115                                       TABLE_UI_NAME_COL,    str,
116                                       TABLE_SHORT_NAME_COL, proto_name,
117                                       -1);
118 }
119
120 static void
121 decode_proto_add_to_list (const gchar *table_name _U_, ftenum_t selector_type _U_,
122                           gpointer key, gpointer value _U_, gpointer user_data)
123 {
124     GtkTreeStore       *store;
125     const gchar        *proto_name;
126     dtbl_entry_t       *dtbl_entry;
127     dissector_handle_t  handle;
128     guint32             port;
129     gchar              *str;
130     dissector_tables_tree_info_t *tree_info;
131
132     tree_info = user_data;
133     dtbl_entry = value;
134     handle = dtbl_entry_get_handle(dtbl_entry);
135     proto_name = dissector_handle_get_short_name(handle);
136
137     store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_info->tree)));
138
139     switch (selector_type) {
140
141     case FT_UINT8:
142     case FT_UINT16:
143     case FT_UINT24:
144     case FT_UINT32:
145         port = GPOINTER_TO_UINT(key);
146         /* Hack: Use fixed width rj str so alpha sort (strcmp) will sort field numerically */
147         str = g_strdup_printf ("%10d", port);
148         proto_add_to_list(tree_info, store, str, proto_name);
149         g_free (str);
150         break;
151
152     case FT_STRING:
153     case FT_STRINGZ:
154         str = (gchar*) key;
155         proto_add_to_list(tree_info, store, str, proto_name);
156         break;
157
158     default:
159         g_assert_not_reached();
160     }
161
162 }
163
164 static void
165 table_name_add_to_list(dissector_tables_tree_info_t  *tree_info,
166                        GtkWidget  *tree_view,
167                        const char *table_name,
168                        const char *ui_name)
169 {
170     GtkTreeStore *store;
171
172     tree_info->tree = tree_view;
173     store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view))); /* Get store */
174
175     gtk_tree_store_insert_with_values(store, &tree_info->iter, NULL, G_MAXINT,
176                                       TABLE_UI_NAME_COL,    ui_name,
177                                       TABLE_SHORT_NAME_COL, table_name,
178                                       -1);
179 }
180
181 static void
182 display_dissector_table_names(const char *table_name, const char *ui_name,
183                               gpointer w)
184 {
185     dissector_tables_trees_t      *dis_tbl_trees;
186     dissector_tables_tree_info_t  *tree_info;
187     ftenum_t                       selector_type = get_dissector_table_selector_type(table_name);
188
189     tree_info = g_new(dissector_tables_tree_info_t, 1);
190     dis_tbl_trees = w;
191
192     switch (selector_type) {
193         case FT_UINT8:
194         case FT_UINT16:
195         case FT_UINT24:
196         case FT_UINT32:
197             table_name_add_to_list(tree_info, dis_tbl_trees->uint_tree_wgt, table_name, ui_name);
198             break;
199         case FT_STRING:
200         case FT_STRINGZ:
201             table_name_add_to_list(tree_info, dis_tbl_trees->str_tree_wgt, table_name, ui_name);
202             break;
203         default:
204             break;
205     }
206     dissector_table_foreach(table_name, decode_proto_add_to_list, tree_info);
207
208     g_free(tree_info);
209 }
210
211 static GtkWidget*
212 init_table(void)
213 {
214     GtkTreeStore      *store;
215     GtkWidget         *tree;
216     GtkTreeView       *tree_view;
217     GtkTreeViewColumn *column;
218     GtkCellRenderer   *renderer;
219     GtkTreeSortable   *sortable;
220
221     /* Create the store */
222     store = gtk_tree_store_new (N_COLUMNS,      /* Total number of columns */
223                                G_TYPE_STRING,   /* Table              */
224                                G_TYPE_STRING);  /* Table              */
225
226     /* Create a view */
227     tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
228     tree_view = GTK_TREE_VIEW(tree);
229     sortable = GTK_TREE_SORTABLE(store);
230
231     /* Speed up the list display */
232     gtk_tree_view_set_fixed_height_mode(tree_view, TRUE);
233
234     /* Setup the sortable columns */
235     gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW (tree), FALSE);
236
237     /* The view now holds a reference.  We can get rid of our own reference */
238     g_object_unref (G_OBJECT (store));
239
240     /* Create the first column, associating the "text" attribute of the
241      * cell_renderer to the first column of the model */
242     renderer = gtk_cell_renderer_text_new ();
243     column = gtk_tree_view_column_new_with_attributes ("UI name", renderer, "text", TABLE_UI_NAME_COL, NULL);
244     gtk_tree_sortable_set_sort_func(sortable, TABLE_UI_NAME_COL,
245                                     ui_sort_func, GINT_TO_POINTER(TABLE_UI_NAME_COL), NULL);
246     gtk_tree_view_column_set_sort_column_id(column, TABLE_UI_NAME_COL);
247     gtk_tree_view_column_set_resizable(column, TRUE);
248     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
249     gtk_tree_view_column_set_min_width(column, 80);
250     gtk_tree_view_column_set_fixed_width(column, 330);
251     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
252
253     renderer = gtk_cell_renderer_text_new ();
254     column = gtk_tree_view_column_new_with_attributes ("Short name", renderer, "text", TABLE_SHORT_NAME_COL, NULL);
255     gtk_tree_sortable_set_sort_func(sortable, TABLE_SHORT_NAME_COL,
256                                     ui_sort_func, GINT_TO_POINTER(TABLE_SHORT_NAME_COL), NULL);
257     gtk_tree_view_column_set_sort_column_id(column, TABLE_SHORT_NAME_COL);
258     gtk_tree_view_column_set_resizable(column, TRUE);
259     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
260     gtk_tree_view_column_set_min_width(column, 80);
261     gtk_tree_view_column_set_fixed_width(column, 100);
262     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
263
264     return tree;
265
266 }
267
268 static void
269 dissector_tables_dlg_init(void)
270 {
271     dissector_tables_trees_t dis_tbl_trees;
272     GtkWidget       *vbox;
273     GtkWidget       *hbox;
274     GtkWidget       *main_nb;
275     GtkWidget       *scrolled_window;
276     GtkTreeSortable *sortable;
277     GtkWidget       *temp_page, *tmp;
278
279     dissector_tables_dlg_w = dlg_window_new("Dissector tables");  /* transient_for top_level */
280     gtk_window_set_destroy_with_parent (GTK_WINDOW(dissector_tables_dlg_w), TRUE);
281     gtk_window_set_default_size(GTK_WINDOW(dissector_tables_dlg_w), 700, 300);
282
283     vbox=gtk_vbox_new(FALSE, 3);
284     gtk_container_add(GTK_CONTAINER(dissector_tables_dlg_w), vbox);
285     gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
286
287     main_nb = gtk_notebook_new();
288     gtk_box_pack_start(GTK_BOX(vbox), main_nb, TRUE, TRUE, 0);
289
290     /* String tables */
291     temp_page = gtk_vbox_new(FALSE, 6);
292     tmp = gtk_label_new("String tables");
293     gtk_widget_show(tmp);
294     hbox = gtk_hbox_new(FALSE, 3);
295     gtk_container_add(GTK_CONTAINER(hbox), tmp);
296     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
297
298     scrolled_window = scrolled_window_new(NULL, NULL);
299     dis_tbl_trees.str_tree_wgt = init_table();
300     gtk_widget_show(dis_tbl_trees.str_tree_wgt);
301     gtk_container_add(GTK_CONTAINER(scrolled_window), dis_tbl_trees.str_tree_wgt);
302     gtk_box_pack_start(GTK_BOX(temp_page), scrolled_window, TRUE, TRUE, 0);
303     gtk_widget_show(scrolled_window);
304
305     /* uint tables */
306     temp_page = gtk_vbox_new(FALSE, 6);
307     tmp = gtk_label_new("Integer tables");
308     gtk_widget_show(tmp);
309     hbox = gtk_hbox_new(FALSE, 3);
310     gtk_container_add(GTK_CONTAINER(hbox), tmp);
311     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
312
313     scrolled_window = scrolled_window_new(NULL, NULL);
314     dis_tbl_trees.uint_tree_wgt = init_table();
315     gtk_widget_show(dis_tbl_trees.uint_tree_wgt);
316     gtk_container_add(GTK_CONTAINER(scrolled_window), dis_tbl_trees.uint_tree_wgt);
317     gtk_box_pack_start(GTK_BOX(temp_page), scrolled_window, TRUE, TRUE, 0);
318     gtk_widget_show(scrolled_window);
319
320     /* We must display TOP LEVEL Widget before calling init_table() */
321     gtk_widget_show_all(dissector_tables_dlg_w);
322     g_signal_connect(dissector_tables_dlg_w, "destroy", G_CALLBACK(win_destroy_cb), NULL);
323
324     /* Fill the table with data */
325     dissector_all_tables_foreach_table(display_dissector_table_names, (gpointer)&dis_tbl_trees);
326
327     sortable = GTK_TREE_SORTABLE(gtk_tree_view_get_model(GTK_TREE_VIEW(dis_tbl_trees.str_tree_wgt)));
328     gtk_tree_sortable_set_sort_column_id(sortable, TABLE_UI_NAME_COL, GTK_SORT_ASCENDING);
329
330     sortable = GTK_TREE_SORTABLE(gtk_tree_view_get_model(GTK_TREE_VIEW(dis_tbl_trees.uint_tree_wgt)));
331     gtk_tree_sortable_set_sort_column_id(sortable, TABLE_UI_NAME_COL, GTK_SORT_ASCENDING);
332
333 }
334
335 void
336 dissector_tables_dlg_cb(GtkWidget *w _U_, gpointer d _U_)
337 {
338     if (dissector_tables_dlg_w) {
339           reactivate_window(dissector_tables_dlg_w);
340     } else {
341           dissector_tables_dlg_init();
342     }
343 }