2 * Routines for popping a window to display current packet
4 * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 * - Add close button to bottom.
28 * - improve the window Title and allow user to config it
29 * - Add print support ? ( could be a mess)
30 * - Add button to have main window jump to this packet ?
42 #include <epan/epan.h>
44 #include <epan/timestamp.h>
45 #include <epan/packet.h>
48 #include <epan/prefs.h>
51 #include <epan/column.h>
53 #include <epan/addr_resolv.h>
54 #include "packet_win.h"
55 #include "simple_dialog.h"
56 #include "proto_draw.h"
58 #include "gtkglobals.h"
59 #include "gui_utils.h"
60 #include <epan/plugins.h>
61 #include <epan/epan_dissect.h>
62 #include "compat_macros.h"
64 #include "../ui_util.h"
66 /* Data structure holding information about a packet-detail window. */
67 struct PacketWinData {
68 frame_data *frame; /* The frame being displayed */
69 union wtap_pseudo_header pseudo_header; /* Pseudo-header for packet */
70 guint8 *pd; /* Data for packet */
72 GtkWidget *tv_scrollw;
75 field_info *finfo_selected;
79 /* List of all the packet-detail windows popped up. */
80 static GList *detail_windows;
82 #if GTK_MAJOR_VERSION < 2
83 static void new_tree_view_select_row_cb(GtkCTree *ctree, GList *node,
84 gint column, gpointer user_data);
86 static void new_tree_view_unselect_row_cb( GtkCTree *ctree, GList *node,
87 gint column, gpointer user_data);
89 static void new_tree_view_selection_changed_cb(GtkTreeSelection *sel,
94 static void destroy_new_window(GtkObject *object, gpointer user_data);
96 void new_window_cb(GtkWidget *w _U_)
98 #define NewWinTitleLen 1000
99 char Title[NewWinTitleLen] = "";
101 gint tv_size = 95, bv_size = 75;
102 GtkWidget *main_w, *main_vbox, *pane,
103 *tree_view, *tv_scrollw,
105 struct PacketWinData *DataPtr;
108 /* Allocate data structure to represent this window. */
109 DataPtr = (struct PacketWinData *) g_malloc(sizeof(struct PacketWinData));
111 DataPtr->frame = cfile.current_frame;
112 memcpy(&DataPtr->pseudo_header, &cfile.pseudo_header, sizeof DataPtr->pseudo_header);
113 DataPtr->pd = g_malloc(DataPtr->frame->cap_len);
114 memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len);
115 DataPtr->edt = epan_dissect_new(TRUE, TRUE);
116 epan_dissect_run(DataPtr->edt, &DataPtr->pseudo_header, DataPtr->pd,
117 DataPtr->frame, &cfile.cinfo);
118 epan_dissect_fill_in_columns(DataPtr->edt);
121 * Build title of window by getting column data constructed when the
122 * frame was dissected.
124 for (i = 0; i < cfile.cinfo.num_cols; ++i) {
125 TextPtr = cfile.cinfo.col_data[i];
126 if ((strlen(Title) + strlen(TextPtr)) < NewWinTitleLen - 1) {
127 strcat(Title, TextPtr);
132 main_w = window_new(GTK_WINDOW_TOPLEVEL, Title);
133 gtk_window_set_default_size(GTK_WINDOW(main_w), DEF_WIDTH, -1);
135 /* Container for paned windows */
136 main_vbox = gtk_vbox_new(FALSE, 1);
137 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
138 gtk_container_add(GTK_CONTAINER(main_w), main_vbox);
139 gtk_widget_show(main_vbox);
141 /* Panes for the tree and byte view */
142 pane = gtk_vpaned_new();
143 gtk_paned_gutter_size(GTK_PANED(pane), (GTK_PANED(pane))->handle_size);
144 gtk_container_add(GTK_CONTAINER(main_vbox), pane);
145 gtk_widget_show(pane);
148 tv_scrollw = main_tree_view_new(&prefs, &tree_view);
149 gtk_paned_pack1(GTK_PANED(pane), tv_scrollw, TRUE, TRUE);
150 WIDGET_SET_SIZE(tv_scrollw, -1, tv_size);
151 gtk_widget_show(tv_scrollw);
152 gtk_widget_show(tree_view);
155 bv_nb_ptr = byte_view_new();
156 gtk_paned_pack2(GTK_PANED(pane), bv_nb_ptr, FALSE, FALSE);
157 WIDGET_SET_SIZE(bv_nb_ptr, -1, bv_size);
158 gtk_widget_show(bv_nb_ptr);
160 DataPtr->main = main_w;
161 DataPtr->tv_scrollw = tv_scrollw;
162 DataPtr->tree_view = tree_view;
163 DataPtr->bv_nb_ptr = bv_nb_ptr;
164 detail_windows = g_list_append(detail_windows, DataPtr);
166 /* load callback handlers */
167 #if GTK_MAJOR_VERSION < 2
168 SIGNAL_CONNECT(tree_view, "tree-select-row", new_tree_view_select_row_cb,
171 SIGNAL_CONNECT(tree_view, "tree-unselect-row", new_tree_view_unselect_row_cb,
174 SIGNAL_CONNECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
175 "changed", new_tree_view_selection_changed_cb, DataPtr);
178 SIGNAL_CONNECT(main_w, "destroy", destroy_new_window, DataPtr);
180 /* draw the protocol tree & print hex data */
181 add_byte_views(DataPtr->edt, tree_view, DataPtr->bv_nb_ptr);
182 proto_tree_draw(DataPtr->edt->tree, tree_view);
184 DataPtr->finfo_selected = NULL;
185 gtk_widget_show(main_w);
189 destroy_new_window(GtkObject *object _U_, gpointer user_data)
191 struct PacketWinData *DataPtr = user_data;
193 detail_windows = g_list_remove(detail_windows, DataPtr);
194 epan_dissect_free(DataPtr->edt);
199 #if GTK_MAJOR_VERSION < 2
200 /* called when a tree row is selected in the popup packet window */
202 new_tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column _U_,
206 GtkWidget *byte_view;
210 struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
213 finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
216 set_notebook_page(DataPtr->bv_nb_ptr, finfo->ds_tvb);
217 byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
218 if ( !byte_view) /* exit if no hex window to write in */
221 data = get_byte_view_data_and_length(byte_view, &len);
224 len = DataPtr->frame->cap_len;
227 DataPtr->finfo_selected = finfo;
228 packet_hex_print(GTK_TEXT(byte_view), data,
229 DataPtr->frame, finfo, len);
232 /* called when a tree row is unselected in the popup packet window */
234 new_tree_view_unselect_row_cb(GtkCTree *ctree _U_, GList *node _U_,
235 gint column _U_, gpointer user_data)
237 GtkWidget* byte_view;
241 struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
243 DataPtr->finfo_selected = NULL;
245 byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
246 if ( !byte_view) /* exit if no hex window to write in */
249 data = get_byte_view_data_and_length(byte_view, &len);
250 g_assert(data != NULL);
251 packet_hex_reprint(GTK_TEXT(byte_view));
254 /* called when a tree row is (un)selected in the popup packet window */
256 new_tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data)
259 GtkWidget *byte_view;
265 struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
267 /* if something is selected */
268 if (gtk_tree_selection_get_selected(sel, &model, &iter))
270 gtk_tree_model_get(model, &iter, 1, &finfo, -1);
273 set_notebook_page(DataPtr->bv_nb_ptr, finfo->ds_tvb);
274 byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
275 if (!byte_view) /* exit if no hex window to write in */
278 data = get_byte_view_data_and_length(byte_view, &len);
281 len = DataPtr->frame->cap_len;
284 DataPtr->finfo_selected = finfo;
285 packet_hex_print(GTK_TEXT_VIEW(byte_view), data,
286 DataPtr->frame, finfo, len);
290 DataPtr->finfo_selected = NULL;
292 byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
293 if (!byte_view) /* exit if no hex window to write in */
296 data = get_byte_view_data_and_length(byte_view, &len);
297 g_assert(data != NULL);
298 packet_hex_reprint(GTK_TEXT_VIEW(byte_view));
303 /* Functions called from elsewhere to act on all popup packet windows. */
305 /* Destroy all popup packet windows. */
307 destroy_packet_wins(void)
309 struct PacketWinData *DataPtr;
311 /* Destroying a packet window causes it to be removed from
312 the list of packet windows, so we can't do a "g_list_foreach()"
313 to go through the list of all packet windows and destroy them
314 as we find them; instead, as long as the list is non-empty,
315 we destroy the first window on the list. */
316 while (detail_windows != NULL) {
317 DataPtr = (struct PacketWinData *)(detail_windows->data);
318 window_destroy(DataPtr->main);
323 redraw_hex_dump_cb(gpointer data, gpointer user_data _U_)
325 struct PacketWinData *DataPtr = (struct PacketWinData *)data;
327 redraw_hex_dump(DataPtr->bv_nb_ptr, DataPtr->frame, DataPtr->finfo_selected);
330 /* Redraw the hex dump part of all the popup packet windows. */
332 redraw_hex_dump_packet_wins(void)
334 g_list_foreach(detail_windows, redraw_hex_dump_cb, NULL);